diff --git a/src/battle-scene.ts b/src/battle-scene.ts index ecaffc5ed07..2ff5d718ede 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -151,7 +151,6 @@ import { NextEncounterPhase } from "#app/phases/next-encounter-phase"; import { PokemonAnimPhase } from "#app/phases/pokemon-anim-phase"; import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase"; import { ReturnPhase } from "#app/phases/return-phase"; -import { SelectBiomePhase } from "#app/phases/select-biome-phase"; import { ShowTrainerPhase } from "#app/phases/show-trainer-phase"; import { SummonPhase } from "#app/phases/summon-phase"; import { SwitchPhase } from "#app/phases/switch-phase"; @@ -1298,6 +1297,16 @@ export default class BattleScene extends SceneBase { return Math.max(doubleChance.value, 1); } + isNewBiome(currentBattle = this.currentBattle) { + const isWaveIndexMultipleOfTen = !(currentBattle.waveIndex % 10); + const isEndlessOrDaily = this.gameMode.hasShortBiomes || this.gameMode.isDaily; + const isEndlessFifthWave = this.gameMode.hasShortBiomes && currentBattle.waveIndex % 5 === 0; + const isWaveIndexMultipleOfFiftyMinusOne = currentBattle.waveIndex % 50 === 49; + const isNewBiome = + isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne); + return isNewBiome; + } + // TODO: ...this never actually returns `null`, right? newBattle( waveIndex?: number, @@ -1461,12 +1470,7 @@ export default class BattleScene extends SceneBase { } if (!waveIndex && lastBattle) { - const isWaveIndexMultipleOfTen = !(lastBattle.waveIndex % 10); - const isEndlessOrDaily = this.gameMode.hasShortBiomes || this.gameMode.isDaily; - const isEndlessFifthWave = this.gameMode.hasShortBiomes && lastBattle.waveIndex % 5 === 0; - const isWaveIndexMultipleOfFiftyMinusOne = lastBattle.waveIndex % 50 === 49; - const isNewBiome = - isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne); + const isNewBiome = this.isNewBiome(lastBattle); const resetArenaState = isNewBiome || [BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.currentBattle.battleType) || @@ -1515,7 +1519,6 @@ export default class BattleScene extends SceneBase { if (!this.gameMode.hasRandomBiomes && !isNewBiome) { this.pushPhase(new NextEncounterPhase()); } else { - this.pushPhase(new SelectBiomePhase()); this.pushPhase(new NewBiomeEncounterPhase()); const newMaxExpLevel = this.getMaxExpLevel(); diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index 53d024ac655..d8b648ebe82 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -72,6 +72,7 @@ import type { AbAttrCondition, PokemonDefendCondition, PokemonStatStageChangeCon import type { BattlerIndex } from "#app/battle"; import type Move from "#app/data/moves/move"; import type { ArenaTrapTag, SuppressAbilitiesTag } from "#app/data/arena-tag"; +import { SelectBiomePhase } from "#app/phases/select-biome-phase"; export class BlockRecoilDamageAttr extends AbAttr { constructor() { @@ -5483,6 +5484,11 @@ class ForceSwitchOutHelper { if (switchOutTarget.hp) { globalScene.pushPhase(new BattleEndPhase(false)); + + if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) { + globalScene.pushPhase(new SelectBiomePhase()); + } + globalScene.pushPhase(new NewBattlePhase()); } } diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 35d98f6f781..5d57bb6dc49 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -123,6 +123,7 @@ import { MoveEffectTrigger } from "#enums/MoveEffectTrigger"; import { MultiHitType } from "#enums/MultiHitType"; import { invalidAssistMoves, invalidCopycatMoves, invalidMetronomeMoves, invalidMirrorMoveMoves, invalidSleepTalkMoves } from "./invalid-moves"; import { TrainerVariant } from "#app/field/trainer"; +import { SelectBiomePhase } from "#app/phases/select-biome-phase"; type MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => boolean; type UserMoveConditionFunc = (user: Pokemon, move: Move) => boolean; @@ -6332,6 +6333,11 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { if (!allyPokemon?.isActive(true) && switchOutTarget.hp) { globalScene.pushPhase(new BattleEndPhase(false)); + + if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) { + globalScene.pushPhase(new SelectBiomePhase()); + } + globalScene.pushPhase(new NewBattlePhase()); } } diff --git a/src/phases/attempt-run-phase.ts b/src/phases/attempt-run-phase.ts index eed5c3c522e..274d3c40576 100644 --- a/src/phases/attempt-run-phase.ts +++ b/src/phases/attempt-run-phase.ts @@ -14,6 +14,7 @@ import { BattleEndPhase } from "./battle-end-phase"; import { NewBattlePhase } from "./new-battle-phase"; import { PokemonPhase } from "./pokemon-phase"; import { globalScene } from "#app/global-scene"; +import { SelectBiomePhase } from "./select-biome-phase"; export class AttemptRunPhase extends PokemonPhase { /** For testing purposes: this is to force the pokemon to fail and escape */ @@ -59,6 +60,11 @@ export class AttemptRunPhase extends PokemonPhase { }); globalScene.pushPhase(new BattleEndPhase(false)); + + if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) { + globalScene.pushPhase(new SelectBiomePhase()); + } + globalScene.pushPhase(new NewBattlePhase()); } else { playerPokemon.turnData.failedRunAway = true; diff --git a/src/phases/mystery-encounter-phases.ts b/src/phases/mystery-encounter-phases.ts index 100be47e4e9..011dd26db92 100644 --- a/src/phases/mystery-encounter-phases.ts +++ b/src/phases/mystery-encounter-phases.ts @@ -27,6 +27,7 @@ import { IvScannerModifier } from "../modifier/modifier"; import { Phase } from "../phase"; import { UiMode } from "#enums/ui-mode"; import { isNullOrUndefined, randSeedItem } from "#app/utils/common"; +import { SelectBiomePhase } from "./select-biome-phase"; /** * Will handle (in order): @@ -612,6 +613,10 @@ export class PostMysteryEncounterPhase extends Phase { */ continueEncounter() { const endPhase = () => { + if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) { + globalScene.pushPhase(new SelectBiomePhase()); + } + globalScene.pushPhase(new NewBattlePhase()); this.end(); }; diff --git a/src/phases/select-biome-phase.ts b/src/phases/select-biome-phase.ts index 0ea2841a2d3..4811c4e6b8f 100644 --- a/src/phases/select-biome-phase.ts +++ b/src/phases/select-biome-phase.ts @@ -14,9 +14,10 @@ export class SelectBiomePhase extends BattlePhase { super.start(); const currentBiome = globalScene.arena.biomeType; + const nextWaveIndex = globalScene.currentBattle.waveIndex + 1; const setNextBiome = (nextBiome: Biome) => { - if (globalScene.currentBattle.waveIndex % 10 === 1) { + if (nextWaveIndex % 10 === 1) { globalScene.applyModifiers(MoneyInterestModifier, true); globalScene.unshiftPhase(new PartyHealPhase(false)); } @@ -25,13 +26,13 @@ export class SelectBiomePhase extends BattlePhase { }; if ( - (globalScene.gameMode.isClassic && globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex + 9)) || - (globalScene.gameMode.isDaily && globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex)) || - (globalScene.gameMode.hasShortBiomes && !(globalScene.currentBattle.waveIndex % 50)) + (globalScene.gameMode.isClassic && globalScene.gameMode.isWaveFinal(nextWaveIndex + 9)) || + (globalScene.gameMode.isDaily && globalScene.gameMode.isWaveFinal(nextWaveIndex)) || + (globalScene.gameMode.hasShortBiomes && !(nextWaveIndex % 50)) ) { setNextBiome(Biome.END); } else if (globalScene.gameMode.hasRandomBiomes) { - setNextBiome(this.generateNextBiome()); + setNextBiome(this.generateNextBiome(nextWaveIndex)); } else if (Array.isArray(biomeLinks[currentBiome])) { const biomes: Biome[] = (biomeLinks[currentBiome] as (Biome | [Biome, number])[]) .filter(b => !Array.isArray(b) || !randSeedInt(b[1])) @@ -59,14 +60,14 @@ export class SelectBiomePhase extends BattlePhase { } else if (biomeLinks.hasOwnProperty(currentBiome)) { setNextBiome(biomeLinks[currentBiome] as Biome); } else { - setNextBiome(this.generateNextBiome()); + setNextBiome(this.generateNextBiome(nextWaveIndex)); } } - generateNextBiome(): Biome { - if (!(globalScene.currentBattle.waveIndex % 50)) { + generateNextBiome(waveIndex: number): Biome { + if (!(waveIndex % 50)) { return Biome.END; } - return globalScene.generateRandomBiome(globalScene.currentBattle.waveIndex); + return globalScene.generateRandomBiome(waveIndex); } } diff --git a/src/phases/switch-biome-phase.ts b/src/phases/switch-biome-phase.ts index 2dd2a642f43..f708830318e 100644 --- a/src/phases/switch-biome-phase.ts +++ b/src/phases/switch-biome-phase.ts @@ -19,6 +19,10 @@ export class SwitchBiomePhase extends BattlePhase { return this.end(); } + // Before switching biomes, make sure to set the last encounter for other phases that need it too. + globalScene.lastEnemyTrainer = globalScene.currentBattle?.trainer ?? null; + globalScene.lastMysteryEncounter = globalScene.currentBattle?.mysteryEncounter; + globalScene.tweens.add({ targets: [globalScene.arenaEnemy, globalScene.lastEnemyTrainer], x: "+=300", diff --git a/src/phases/victory-phase.ts b/src/phases/victory-phase.ts index 17b29f654e2..6e1837a4749 100644 --- a/src/phases/victory-phase.ts +++ b/src/phases/victory-phase.ts @@ -15,6 +15,7 @@ import { TrainerVictoryPhase } from "./trainer-victory-phase"; import { handleMysteryEncounterVictory } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { globalScene } from "#app/global-scene"; import { timedEventManager } from "#app/global-event-manager"; +import { SelectBiomePhase } from "./select-biome-phase"; export class VictoryPhase extends PokemonPhase { /** If true, indicates that the phase is intended for EXP purposes only, and not to continue a battle to next phase */ @@ -111,6 +112,11 @@ export class VictoryPhase extends PokemonPhase { globalScene.pushPhase(new AddEnemyBuffModifierPhase()); } } + + if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) { + globalScene.pushPhase(new SelectBiomePhase()); + } + globalScene.pushPhase(new NewBattlePhase()); } else { globalScene.currentBattle.battleType = BattleType.CLEAR; diff --git a/test/abilities/disguise.test.ts b/test/abilities/disguise.test.ts index aeaf8ea2363..0e62b8ad448 100644 --- a/test/abilities/disguise.test.ts +++ b/test/abilities/disguise.test.ts @@ -186,7 +186,7 @@ describe("Abilities - Disguise", () => { await game.toNextTurn(); game.move.select(Moves.SPLASH); await game.doKillOpponents(); - await game.phaseInterceptor.to("PartyHealPhase"); + await game.phaseInterceptor.to("QuietFormChangePhase"); expect(mimikyu1.formIndex).toBe(disguisedForm); });