From a8c3f68e0b80ee2dc3432f20db1a9e3b8df3ca4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Marques?= Date: Sat, 15 Mar 2025 21:09:03 +0000 Subject: [PATCH] [BUG] Fix the bug where transformed pokemon failed to load sprite on reload if it was not the base form --- src/system/pokemon-data.ts | 27 +++++++++++++++++++++++---- test/abilities/imposter.test.ts | 26 ++++++++++++++++++++++++++ test/moves/transform.test.ts | 31 +++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/system/pokemon-data.ts b/src/system/pokemon-data.ts index b3119517102..76f5526e407 100644 --- a/src/system/pokemon-data.ts +++ b/src/system/pokemon-data.ts @@ -3,7 +3,7 @@ import { globalScene } from "#app/global-scene"; import type { Gender } from "../data/gender"; import type { Nature } from "#enums/nature"; import type { PokeballType } from "#enums/pokeball"; -import { getPokemonSpecies } from "../data/pokemon-species"; +import { getPokemonSpecies, getPokemonSpeciesForm } from "../data/pokemon-species"; import { Status } from "../data/status-effect"; import Pokemon, { EnemyPokemon, PokemonMove, PokemonSummonData } from "../field/pokemon"; import { TrainerSlot } from "../data/trainer-config"; @@ -14,6 +14,7 @@ import { Moves } from "#enums/moves"; import type { Species } from "#enums/species"; import { CustomPokemonData } from "#app/data/custom-pokemon-data"; import type { PokemonType } from "#enums/pokemon-type"; +import { getSpeciesFormChangeMessage } from "#app/data/pokemon-forms"; export default class PokemonData { public id: number; @@ -63,6 +64,7 @@ export default class PokemonData { public bossSegments?: number; public summonData: PokemonSummonData; + public summonDataSpeciesFormIndex: number; /** Data that can customize a Pokemon in non-standard ways from its Species */ public customPokemonData: CustomPokemonData; @@ -145,8 +147,9 @@ export default class PokemonData { this.moveset = sourcePokemon.moveset; if (!forHistory) { this.status = sourcePokemon.status; - if (this.player) { + if (this.player && sourcePokemon.summonData) { this.summonData = sourcePokemon.summonData; + this.summonDataSpeciesFormIndex = this.getSummonDataSpeciesFormIndex(); } } } else { @@ -171,6 +174,7 @@ export default class PokemonData { this.summonData.moveset = source.summonData.moveset?.map(m => PokemonMove.loadMove(m)); this.summonData.types = source.summonData.types; this.summonData.speciesForm = source.summonData.speciesForm; + this.summonDataSpeciesFormIndex = source.summonDataSpeciesFormIndex; if (source.summonData.tags) { this.summonData.tags = source.summonData.tags?.map(t => loadBattlerTag(t)); @@ -214,13 +218,28 @@ export default class PokemonData { this, ); if (this.summonData) { - // when loading from saved session, recover summonData.speciesFrom species object + // when loading from saved session, recover summonData.speciesFrom and form index species object // used to stay transformed on reload session if (this.summonData.speciesForm) { - this.summonData.speciesForm = getPokemonSpecies(this.summonData.speciesForm.speciesId); + this.summonData.speciesForm = getPokemonSpeciesForm( + this.summonData.speciesForm.speciesId, + this.summonDataSpeciesFormIndex, + ); } ret.primeSummonData(this.summonData); } return ret; } + + /** + * Method to save summon data species form index + * Necessary in case the pokemon is transformed + * to reload the correct form + */ + getSummonDataSpeciesFormIndex(): number { + if (this.summonData.speciesForm) { + return this.summonData.speciesForm.formIndex; + } + return 0; + } } diff --git a/test/abilities/imposter.test.ts b/test/abilities/imposter.test.ts index 46d342bd635..2c7302d04b7 100644 --- a/test/abilities/imposter.test.ts +++ b/test/abilities/imposter.test.ts @@ -160,4 +160,30 @@ describe("Abilities - Imposter", () => { expect(playerMoveset.length).toEqual(1); expect(playerMoveset[0]?.moveId).toEqual(Moves.SPLASH); }); + + it("should stay transformed with the correct form after reload", async () => { + game.override.moveset([Moves.ABSORB]); + game.override.enemySpecies(Species.UNOWN); + await game.classicMode.startBattle([Species.DITTO]); + + const enemy = game.scene.getEnemyPokemon()!; + + // change form + enemy.species.forms[5]; + enemy.species.formIndex = 5; + + game.move.select(Moves.SPLASH); + await game.doKillOpponents(); + await game.toNextWave(); + + expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase"); + expect(game.scene.currentBattle.waveIndex).toBe(2); + + await game.reload.reloadSession(); + + const playerReloaded = game.scene.getPlayerPokemon()!; + + expect(playerReloaded.getSpeciesForm().speciesId).toBe(enemy.getSpeciesForm().speciesId); + expect(playerReloaded.getSpeciesForm().formIndex).toBe(enemy.getSpeciesForm().formIndex); + }); }); diff --git a/test/moves/transform.test.ts b/test/moves/transform.test.ts index a2162af7569..d37decf28f4 100644 --- a/test/moves/transform.test.ts +++ b/test/moves/transform.test.ts @@ -164,4 +164,35 @@ describe("Moves - Transform", () => { expect(playerMoveset.length).toEqual(1); expect(playerMoveset[0]?.moveId).toEqual(Moves.MEMENTO); }); + + it("should stay transformed with the correct form after reload", async () => { + game.override.enemyMoveset([]).moveset([]); + game.override.enemySpecies(Species.DARMANITAN); + + await game.classicMode.startBattle([Species.DITTO]); + + const player = game.scene.getPlayerPokemon()!; + const enemy = game.scene.getEnemyPokemon()!; + + // change form + enemy.species.forms[1]; + enemy.species.formIndex = 1; + + game.move.changeMoveset(player, Moves.TRANSFORM); + game.move.changeMoveset(enemy, Moves.MEMENTO); + + game.move.select(Moves.TRANSFORM); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toNextWave(); + + expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase"); + expect(game.scene.currentBattle.waveIndex).toBe(2); + + await game.reload.reloadSession(); + + const playerReloaded = game.scene.getPlayerPokemon()!; + + expect(playerReloaded.getSpeciesForm().speciesId).toBe(enemy.getSpeciesForm().speciesId); + expect(playerReloaded.getSpeciesForm().formIndex).toBe(enemy.getSpeciesForm().formIndex); + }); });