[P1][Beta] Fix FormChangePhase being broken by EvolutionPhase refactor (#4795)

* [P1][Beta] Fix FormChangePhase being broken by EvolutionPhase refactor

* Apply suggested changes to added test
This commit is contained in:
PigeonBar 2024-11-05 09:19:20 -05:00 committed by GitHub
parent 13841765f1
commit 543a97076b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 79 additions and 13 deletions

View File

@ -39,8 +39,6 @@ export class EvolutionPhase extends Phase {
this.pokemon = pokemon;
this.evolution = evolution;
this.lastLevel = lastLevel;
this.evolutionBgm = this.scene.playSoundWithoutBgm("evolution");
this.preEvolvedPokemonName = getPokemonNameWithAffix(this.pokemon);
}
validate(): boolean {
@ -62,9 +60,9 @@ export class EvolutionPhase extends Phase {
this.scene.fadeOutBgm(undefined, false);
const evolutionHandler = this.scene.ui.getHandler() as EvolutionSceneHandler;
this.evolutionHandler = this.scene.ui.getHandler() as EvolutionSceneHandler;
this.evolutionContainer = evolutionHandler.evolutionContainer;
this.evolutionContainer = this.evolutionHandler.evolutionContainer;
this.evolutionBaseBg = this.scene.add.image(0, 0, "default_bg");
this.evolutionBaseBg.setOrigin(0, 0);
@ -117,14 +115,12 @@ export class EvolutionPhase extends Phase {
sprite.pipelineData[k] = this.pokemon.getSprite().pipelineData[k];
});
});
this.preEvolvedPokemonName = getPokemonNameWithAffix(this.pokemon);
this.doEvolution();
});
}
doEvolution(): void {
this.evolutionHandler = this.scene.ui.getHandler() as EvolutionSceneHandler;
this.scene.ui.showText(i18next.t("menu:evolving", { pokemonName: this.preEvolvedPokemonName }), null, () => {
this.pokemon.cry();
@ -145,6 +141,7 @@ export class EvolutionPhase extends Phase {
});
this.scene.time.delayedCall(1000, () => {
this.evolutionBgm = this.scene.playSoundWithoutBgm("evolution");
this.scene.tweens.add({
targets: this.evolutionBgOverlay,
alpha: 1,

View File

@ -0,0 +1,60 @@
import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { Type } from "#app/data/type";
import { generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { modifierTypes } from "#app/modifier/modifier-type";
describe("Form Change Phase", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([ Moves.SPLASH ])
.ability(Abilities.BALL_FETCH)
.battleType("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.enemyAbility(Abilities.BALL_FETCH)
.enemyMoveset(Moves.SPLASH);
});
it("Zacian should successfully change into Crowned form", async () => {
await game.classicMode.startBattle([ Species.ZACIAN ]);
// Before the form change: Should be Hero form
const zacian = game.scene.getPlayerParty()[0];
expect(zacian.getFormKey()).toBe("hero-of-many-battles");
expect(zacian.getTypes()).toStrictEqual([ Type.FAIRY ]);
expect(zacian.calculateBaseStats()).toStrictEqual([ 92, 120, 115, 80, 115, 138 ]);
// Give Zacian a Rusted Sword
const rustedSwordType = generateModifierType(game.scene, modifierTypes.RARE_FORM_CHANGE_ITEM)!;
const rustedSword = rustedSwordType.newModifier(zacian);
await game.scene.addModifier(rustedSword);
game.move.select(Moves.SPLASH);
await game.toNextTurn();
// After the form change: Should be Crowned form
expect(game.phaseInterceptor.log.includes("FormChangePhase")).toBe(true);
expect(zacian.getFormKey()).toBe("crowned");
expect(zacian.getTypes()).toStrictEqual([ Type.FAIRY, Type.STEEL ]);
expect(zacian.calculateBaseStats()).toStrictEqual([ 92, 150, 115, 80, 115, 148 ]);
});
});

View File

@ -35,7 +35,7 @@ export class ClassicModeHelper extends GameManagerHelper {
selectStarterPhase.initBattle(starters);
});
await this.game.phaseInterceptor.run(EncounterPhase);
await this.game.phaseInterceptor.to(EncounterPhase);
if (overrides.OPP_HELD_ITEMS_OVERRIDE.length === 0 && this.game.override.removeEnemyStartingItems) {
this.game.removeEnemyHeldItems();
}

View File

@ -12,6 +12,7 @@ import { EndEvolutionPhase } from "#app/phases/end-evolution-phase";
import { EnemyCommandPhase } from "#app/phases/enemy-command-phase";
import { EvolutionPhase } from "#app/phases/evolution-phase";
import { FaintPhase } from "#app/phases/faint-phase";
import { FormChangePhase } from "#app/phases/form-change-phase";
import { LearnMovePhase } from "#app/phases/learn-move-phase";
import { LevelCapPhase } from "#app/phases/level-cap-phase";
import { LoginPhase } from "#app/phases/login-phase";
@ -67,7 +68,6 @@ type PhaseClass =
| typeof LoginPhase
| typeof TitlePhase
| typeof SelectGenderPhase
| typeof EncounterPhase
| typeof NewBiomeEncounterPhase
| typeof SelectStarterPhase
| typeof PostSummonPhase
@ -102,6 +102,7 @@ type PhaseClass =
| typeof SwitchPhase
| typeof SwitchSummonPhase
| typeof PartyHealPhase
| typeof FormChangePhase
| typeof EvolutionPhase
| typeof EndEvolutionPhase
| typeof LevelCapPhase
@ -114,13 +115,13 @@ type PhaseClass =
| typeof PostMysteryEncounterPhase
| typeof ModifierRewardPhase
| typeof PartyExpPhase
| typeof ExpPhase;
| typeof ExpPhase
| typeof EncounterPhase;
type PhaseString =
| "LoginPhase"
| "TitlePhase"
| "SelectGenderPhase"
| "EncounterPhase"
| "NewBiomeEncounterPhase"
| "SelectStarterPhase"
| "PostSummonPhase"
@ -155,6 +156,7 @@ type PhaseString =
| "SwitchPhase"
| "SwitchSummonPhase"
| "PartyHealPhase"
| "FormChangePhase"
| "EvolutionPhase"
| "EndEvolutionPhase"
| "LevelCapPhase"
@ -167,7 +169,8 @@ type PhaseString =
| "PostMysteryEncounterPhase"
| "ModifierRewardPhase"
| "PartyExpPhase"
| "ExpPhase";
| "ExpPhase"
| "EncounterPhase";
type PhaseInterceptorPhase = PhaseClass | PhaseString;
@ -187,12 +190,16 @@ export default class PhaseInterceptor {
/**
* List of phases with their corresponding start methods.
*
* CAUTION: If a phase and its subclasses (if any) both appear in this list,
* make sure that this list contains said phase AFTER all of its subclasses.
* This way, the phase's `prototype.start` is properly preserved during
* `initPhases()` so that its subclasses can use `super.start()` properly.
*/
private PHASES = [
[ LoginPhase, this.startPhase ],
[ TitlePhase, this.startPhase ],
[ SelectGenderPhase, this.startPhase ],
[ EncounterPhase, this.startPhase ],
[ NewBiomeEncounterPhase, this.startPhase ],
[ SelectStarterPhase, this.startPhase ],
[ PostSummonPhase, this.startPhase ],
@ -227,6 +234,7 @@ export default class PhaseInterceptor {
[ SwitchPhase, this.startPhase ],
[ SwitchSummonPhase, this.startPhase ],
[ PartyHealPhase, this.startPhase ],
[ FormChangePhase, this.startPhase ],
[ EvolutionPhase, this.startPhase ],
[ EndEvolutionPhase, this.startPhase ],
[ LevelCapPhase, this.startPhase ],
@ -240,6 +248,7 @@ export default class PhaseInterceptor {
[ ModifierRewardPhase, this.startPhase ],
[ PartyExpPhase, this.startPhase ],
[ ExpPhase, this.startPhase ],
[ EncounterPhase, this.startPhase ],
];
private endBySetMode = [