diff --git a/src/battle-phases.ts b/src/battle-phases.ts index a2f0c1e34..1e2ac8091 100644 --- a/src/battle-phases.ts +++ b/src/battle-phases.ts @@ -98,7 +98,7 @@ export class SelectStarterPhase extends BattlePhase { start() { super.start(); - this.scene.sound.play('menu', { loop: true }); + this.scene.playSound('menu', { loop: true }); this.scene.ui.setMode(Mode.STARTER_SELECT, (starters: Starter[]) => { const party = this.scene.getParty(); @@ -619,7 +619,7 @@ export class SummonPhase extends PartyMemberPokemonPhase { angle: 1440, y: (this.player ? 132 : 86) + fpOffset[1], onComplete: () => { - this.scene.sound.play('pb_rel'); + this.scene.playSound('pb_rel'); pokeball.destroy(); this.scene.add.existing(pokemon); this.scene.field.add(pokemon); @@ -701,7 +701,7 @@ export class SwitchSummonPhase extends SummonPhase { this.scene.getEnemyField().forEach(enemyPokemon => enemyPokemon.removeTagsBySourceId(pokemon.id)); this.scene.ui.showText(this.player ? `Come back, ${pokemon.name}!` : `${this.scene.currentBattle.trainer.getName()}\nwithdrew ${pokemon.name}!`); - this.scene.sound.play('pb_rel'); + this.scene.playSound('pb_rel'); pokemon.hideInfo(); pokemon.tint(getPokeballTintColor(pokemon.pokeball), 1, 250, 'Sine.easeIn'); this.scene.tweens.add({ @@ -1708,7 +1708,7 @@ export class StatChangePhase extends PokemonPhase { statSprite.setScale(6); statSprite.setOrigin(0.5, 1); - this.scene.sound.play(`stat_${this.levels >= 1 ? 'up' : 'down'}`); + this.scene.playSound(`stat_${this.levels >= 1 ? 'up' : 'down'}`); statSprite.setMask(new Phaser.Display.Masks.BitmapMask(this.scene, pokemonMaskSprite)); @@ -1904,13 +1904,13 @@ export class DamagePhase extends PokemonPhase { switch (this.damageResult) { case HitResult.EFFECTIVE: - this.scene.sound.play('hit'); + this.scene.playSound('hit'); break; case HitResult.SUPER_EFFECTIVE: - this.scene.sound.play('hit_strong'); + this.scene.playSound('hit_strong'); break; case HitResult.NOT_VERY_EFFECTIVE: - this.scene.sound.play('hit_weak'); + this.scene.playSound('hit_weak'); break; } @@ -1974,7 +1974,7 @@ export class FaintPhase extends PokemonPhase { pokemon.faintCry(() => { pokemon.hideInfo(); - this.scene.sound.play('faint'); + this.scene.playSound('faint'); this.scene.tweens.add({ targets: pokemon, duration: 500, @@ -2189,7 +2189,7 @@ export class UnlockPhase extends BattlePhase { this.scene.time.delayedCall(2000, () => { this.scene.gameData.unlocks[this.unlockable] = true; this.scene.gameData.saveSystem(); - this.scene.sound.play('level_up_fanfare'); + this.scene.playSound('level_up_fanfare'); this.scene.ui.setMode(Mode.MESSAGE); this.scene.arenaBg.setVisible(false); this.scene.ui.fadeIn(250).then(() => { @@ -2536,7 +2536,7 @@ export class AttemptCapturePhase extends PokemonPhase { this.pokeball.setOrigin(0.5, 0.625); this.scene.field.add(this.pokeball); - this.scene.sound.play('pb_throw'); + this.scene.playSound('pb_throw'); this.scene.time.delayedCall(300, () => { this.scene.field.moveBelow(this.pokeball as Phaser.GameObjects.GameObject, pokemon); }); @@ -2548,7 +2548,7 @@ export class AttemptCapturePhase extends PokemonPhase { onComplete: () => { this.pokeball.setTexture('pb', `${pokeballAtlasKey}_opening`); this.scene.time.delayedCall(17, () => this.pokeball.setTexture('pb', `${pokeballAtlasKey}_open`)); - this.scene.sound.play('pb_rel'); + this.scene.playSound('pb_rel'); pokemon.tint(getPokeballTintColor(this.pokeballType)); this.scene.tweens.add({ targets: pokemon, @@ -2559,7 +2559,7 @@ export class AttemptCapturePhase extends PokemonPhase { onComplete: () => { this.pokeball.setTexture('pb', `${pokeballAtlasKey}_opening`); pokemon.setVisible(false); - this.scene.sound.play('pb_catch'); + this.scene.playSound('pb_catch'); this.scene.time.delayedCall(17, () => this.pokeball.setTexture('pb', `${pokeballAtlasKey}`)); const doShake = pokeballMultiplier > -1 ? () => { @@ -2587,13 +2587,13 @@ export class AttemptCapturePhase extends PokemonPhase { this.failCatch(shakeCount); } else if (shakeCount++ < 3) { if (Utils.randInt(65536) < y) - this.scene.sound.play('pb_move'); + this.scene.playSound('pb_move'); else { shakeCounter.stop(); this.failCatch(shakeCount); } } else - this.scene.sound.play('pb_lock') + this.scene.playSound('pb_lock') }, onComplete: () => this.catch() }); @@ -2609,7 +2609,7 @@ export class AttemptCapturePhase extends PokemonPhase { failCatch(shakeCount: integer) { const pokemon = this.getPokemon(); - this.scene.sound.play('pb_rel'); + this.scene.playSound('pb_rel'); pokemon.setY(this.originalY); pokemon.cry(); pokemon.tint(getPokeballTintColor(this.pokeballType)); @@ -2713,7 +2713,7 @@ export class AttemptRunPhase extends PokemonPhase { const escapeChance = (((playerPokemon.stats[Stat.SPD] * 128) / enemySpeed) + (30 * this.scene.currentBattle.escapeAttempts++)) % 256; if (Utils.randInt(256) < escapeChance) { - this.scene.sound.play('flee'); + this.scene.playSound('flee'); this.scene.queueMessage('You got away safely!', null, true, 500); this.scene.tweens.add({ @@ -2838,7 +2838,7 @@ export class PartyHealPhase extends BattlePhase { pokemon.updateInfo(true); } const healSong = this.scene.sound.add('heal'); - healSong.play(); + healSong.play({ volume: this.scene.gameVolume }); this.scene.time.delayedCall(healSong.totalDuration * 1000, () => { healSong.destroy(); if (this.resumeBgm && bgmPlaying) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 2151e5ccd..c7e126283 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -59,10 +59,11 @@ export interface PokeballCounts { export default class BattleScene extends Phaser.Scene { public auto: boolean; + public gameVolume: number = 0.5; public gameSpeed: integer = 1; public quickStart: boolean = quickStart; public finalWave: integer = 200; - + public gameData: GameData; private phaseQueue: BattlePhase[]; @@ -811,7 +812,7 @@ export default class BattleScene extends Phaser.Scene { if (this.bgm && bgmName === this.bgm.key) { if (!this.bgm.isPlaying) { this.bgm.play({ - volume: 1 + volume: this.gameVolume }); } return; @@ -827,14 +828,16 @@ export default class BattleScene extends Phaser.Scene { const playNewBgm = () => { if (bgmName === null && this.bgm && !this.bgm.pendingRemove) { this.bgm.play({ - volume: 1 + volume: this.gameVolume }); return; } if (this.bgm && !this.bgm.pendingRemove && this.bgm.isPlaying) this.bgm.stop(); this.bgm = this.sound.add(bgmName, { loop: true }); - this.bgm.play(); + this.bgm.play({ + volume: this.gameVolume + }); if (loopPoint) this.bgm.on('looped', () => this.bgm.play({ seek: loopPoint })); }; @@ -875,9 +878,20 @@ export default class BattleScene extends Phaser.Scene { SoundFade.fadeOut(this, bgm, duration, destroy); } + playSound(soundName: string, config?: object) { + if (config) { + if (config.hasOwnProperty('volume')) + config['volume'] *= this.gameVolume; + else + config['volume'] = this.gameVolume; + } else + config = { volume: this.gameVolume }; + this.sound.play(soundName, config); + } + playSoundWithoutBgm(soundName: string, pauseDuration?: integer): void { this.pauseBgm(); - this.sound.play(soundName); + this.playSound(soundName); const sound = this.sound.get(soundName); if (this.bgmResumeTimer) this.bgmResumeTimer.destroy(); @@ -976,7 +990,7 @@ export default class BattleScene extends Phaser.Scene { if (modifier instanceof PersistentModifier) { if ((modifier as PersistentModifier).add(this.modifiers, !!virtual)) { if (playSound && !this.sound.get(soundName)) - this.sound.play(soundName); + this.playSound(soundName); } else if (!virtual) { const defaultModifierType = getDefaultModifierTypeForTier(modifier.type.tier); this.addModifier(defaultModifierType.newModifier(), playSound).then(() => resolve()); @@ -988,7 +1002,7 @@ export default class BattleScene extends Phaser.Scene { this.updateModifiers().then(() => resolve()); } else if (modifier instanceof ConsumableModifier) { if (playSound && !this.sound.get(soundName)) - this.sound.play(soundName); + this.playSound(soundName); if (modifier instanceof ConsumablePokemonModifier) { for (let p in this.party) { diff --git a/src/data/battle-anims.ts b/src/data/battle-anims.ts index c6c6a0c8d..d1340be0e 100644 --- a/src/data/battle-anims.ts +++ b/src/data/battle-anims.ts @@ -236,7 +236,7 @@ class AnimTimedSoundEvent extends AnimTimedEvent { const soundConfig = { rate: (this.pitch * 0.01), volume: (this.volume * 0.01) }; if (this.resourceName) { try { - scene.sound.play(this.resourceName, soundConfig); + scene.playSound(this.resourceName, soundConfig); } catch (err) { console.error(err); } diff --git a/src/data/pokeball.ts b/src/data/pokeball.ts index 3b12da756..ca36287a6 100644 --- a/src/data/pokeball.ts +++ b/src/data/pokeball.ts @@ -88,7 +88,7 @@ export function doPokeballBounceAnim(scene: BattleScene, pokeball: Phaser.GameOb duration: bouncePower * baseBounceDuration, ease: 'Cubic.easeIn', onComplete: () => { - scene.sound.play('pb_bounce_1', { volume: bouncePower }); + scene.playSound('pb_bounce_1', { volume: bouncePower }); bouncePower = bouncePower > 0.01 ? bouncePower * 0.5 : 0; diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 03bf5aec3..729d2a15d 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -184,7 +184,7 @@ export abstract class PokemonSpeciesForm { } cry(scene: BattleScene, soundConfig?: Phaser.Types.Sound.SoundConfig): integer { - scene.sound.play(this.speciesId.toString(), soundConfig); + scene.playSound(this.speciesId.toString(), soundConfig); return scene.sound.get(this.speciesId.toString()).totalDuration * 1000; } } diff --git a/src/evolution-phase.ts b/src/evolution-phase.ts index ed049caae..1cf2004db 100644 --- a/src/evolution-phase.ts +++ b/src/evolution-phase.ts @@ -102,7 +102,7 @@ export class EvolutionPhase extends BattlePhase { this.scene.time.delayedCall(1000, () => { const evolutionBgm = this.scene.sound.add('evolution'); - evolutionBgm.play(); + evolutionBgm.play({ volume: this.scene.gameVolume }); this.scene.tweens.add({ targets: this.evolutionBgOverlay, alpha: 1, @@ -119,7 +119,7 @@ export class EvolutionPhase extends BattlePhase { this.evolutionBg.setVisible(true); this.evolutionBg.play(); }); - this.scene.sound.play('charge'); + this.scene.playSound('charge'); this.doSpiralUpward(); this.scene.tweens.addCounter({ from: 0, @@ -131,17 +131,17 @@ export class EvolutionPhase extends BattlePhase { onComplete: () => { this.pokemonSprite.setVisible(false); this.scene.time.delayedCall(1100, () => { - this.scene.sound.play('beam'); + this.scene.playSound('beam'); this.doArcDownward(); this.scene.time.delayedCall(1500, () => { this.pokemonEvoTintSprite.setScale(0.25); this.pokemonEvoTintSprite.setVisible(true); this.doCycle(1).then(() => { - this.scene.sound.play('sparkle'); + this.scene.playSound('sparkle'); this.pokemonEvoSprite.setVisible(true); this.doCircleInward(); this.scene.time.delayedCall(900, () => { - this.scene.sound.play('shine'); + this.scene.playSound('shine'); this.doSpray(); this.scene.tweens.add({ targets: this.evolutionOverlay, @@ -167,7 +167,7 @@ export class EvolutionPhase extends BattlePhase { this.scene.time.delayedCall(250, () => { pokemon.cry(); this.scene.time.delayedCall(1250, () => { - this.scene.sound.play('evolution_fanfare'); + this.scene.playSound('evolution_fanfare'); this.scene.ui.showText(`Congratulations! Your ${preName}\nevolved into ${pokemon.name}!`, null, () => this.end(), null, true, 3000); this.scene.time.delayedCall(new Utils.FixedInt(4250) as unknown as integer, () => this.scene.playBgm()); }); diff --git a/src/pokemon.ts b/src/pokemon.ts index 5ee8fb964..de07c2e53 100644 --- a/src/pokemon.ts +++ b/src/pokemon.ts @@ -874,9 +874,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { const key = this.species.speciesId.toString(); let i = 0; let rate = 0.85; - this.scene.sound.play(key, { - rate: rate - }); + this.scene.playSound(key, { rate: rate }); const sprite = this.getSprite(); const tintSprite = this.getTintSprite(); const delay = Math.max(this.scene.sound.get(key).totalDuration * 50, 25); @@ -903,7 +901,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { rate *= 0.99; crySound.play({ rate: rate, - seek: (i * delay * 0.001) * rate + seek: (i * delay * 0.001) * rate, + volume: this.scene.gameVolume }); } else { @@ -1060,7 +1059,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { sparkle(): void { if (this.shinySparkle) { this.shinySparkle.play('sparkle'); - this.scene.sound.play('sparkle'); + this.scene.playSound('sparkle'); } } diff --git a/src/ui/battle-info.ts b/src/ui/battle-info.ts index 88e96a442..70dee5f47 100644 --- a/src/ui/battle-info.ts +++ b/src/ui/battle-info.ts @@ -273,7 +273,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { } let duration = this.visible && !instant ? ((levelExp - this.lastLevelExp) / relLevelExp) * 1650 : 0; if (duration) - this.scene.sound.play('exp'); + (this.scene as BattleScene).playSound('exp'); this.scene.tweens.add({ targets: this.expBar, ease: 'Sine.easeIn', @@ -289,7 +289,7 @@ export default class BattleInfo extends Phaser.GameObjects.Container { if (ratio === 1) { this.lastLevelExp = 0; this.lastLevel++; - this.scene.sound.play('level_up'); + (this.scene as BattleScene).playSound('level_up'); this.setLevel(this.lastLevel); this.scene.time.delayedCall(500, () => { this.expBar.setScale(0, 1); diff --git a/src/ui/message-ui-handler.ts b/src/ui/message-ui-handler.ts index 397424836..bd183faaf 100644 --- a/src/ui/message-ui-handler.ts +++ b/src/ui/message-ui-handler.ts @@ -72,7 +72,7 @@ export default abstract class MessageUiHandler extends AwaitableUiHandler { this.message.setText(text.slice(0, charIndex)); const advance = () => { if (charSound) - this.scene.sound.play(charSound); + this.scene.playSound(charSound); if (callback && !this.textTimer.repeatCount) { if (callbackDelay && !prompt) { this.textCallbackTimer = this.scene.time.delayedCall(callbackDelay, () => { diff --git a/src/ui/modifier-select-ui-handler.ts b/src/ui/modifier-select-ui-handler.ts index 6d37c0de1..b7b599ec4 100644 --- a/src/ui/modifier-select-ui-handler.ts +++ b/src/ui/modifier-select-ui-handler.ts @@ -313,7 +313,7 @@ class ModifierOption extends Phaser.GameObjects.Container { return; const value = t.getValue(); if (!bounce && value > lastValue) { - this.scene.sound.play('pb_bounce_1', { volume: 1 / ++bounceCount }); + (this.scene as BattleScene).playSound('pb_bounce_1', { volume: 1 / ++bounceCount }); bounce = true; } else if (bounce && value < lastValue) bounce = false; @@ -323,7 +323,7 @@ class ModifierOption extends Phaser.GameObjects.Container { if (this.modifierTypeOption.upgraded) { this.scene.time.delayedCall(remainingDuration, () => { - this.scene.sound.play('upgrade'); + (this.scene as BattleScene).playSound('upgrade'); this.pbTint.setPosition(this.pb.x, this.pb.y); this.pbTint.setTintFill(0xFFFFFF); this.pbTint.setAlpha(0); @@ -354,7 +354,7 @@ class ModifierOption extends Phaser.GameObjects.Container { return; this.pb.setTexture('pb', `${this.getPbAtlasKey(false)}_open`); - this.scene.sound.play('pb_rel'); + (this.scene as BattleScene).playSound('pb_rel'); this.scene.tweens.add({ targets: this.pb, diff --git a/src/ui/pokeball-tray.ts b/src/ui/pokeball-tray.ts index 3f3a79dab..23a168d51 100644 --- a/src/ui/pokeball-tray.ts +++ b/src/ui/pokeball-tray.ts @@ -55,7 +55,7 @@ export default class PokeballTray extends Phaser.GameObjects.Container { ball.setFrame(ballFrame); }); - this.scene.sound.play('pb_tray_enter'); + (this.scene as BattleScene).playSound('pb_tray_enter'); this.scene.tweens.add({ targets: this, @@ -69,7 +69,7 @@ export default class PokeballTray extends Phaser.GameObjects.Container { x: `${this.player ? '-' : '+'}=104`, duration: b * 100, ease: 'Sine.easeIn', - onComplete: () => this.scene.sound.play(b < party.length ? 'pb_tray_ball' : 'pb_tray_empty') + onComplete: () => (this.scene as BattleScene).playSound(b < party.length ? 'pb_tray_ball' : 'pb_tray_empty') }); }); } diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index ff11c674a..5621a569b 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -325,7 +325,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (this.canCycleShiny) { this.setSpeciesDetails(this.lastSpecies, !this.shinyCursor, undefined, undefined, undefined); if (this.shinyCursor) - this.scene.sound.play('sparkle'); + this.scene.playSound('sparkle'); else success = true; } diff --git a/src/ui/ui.ts b/src/ui/ui.ts index 35982bcc6..4c155596d 100644 --- a/src/ui/ui.ts +++ b/src/ui/ui.ts @@ -129,11 +129,11 @@ export default class UI extends Phaser.GameObjects.Container { } playSelect(): void { - this.scene.sound.play('select'); + (this.scene as BattleScene).playSound('select'); } playError(): void { - this.scene.sound.play('error'); + (this.scene as BattleScene).playSound('error'); } fadeOut(duration: integer): Promise {