pokerogue/src/phases/pokemon-transform-phase.ts
Sirz Benjie 48e911e03c
[Refactor] Remove circular deps 3 (#5959)
* Move game-mode to its own file

Reduces circular imports to 325

* Move battler-index to own file

Reduces circular deps to 314

* Move trainer-variant to own file

Reduces circ deps to 313

* Move enums in pokemon to their own file

* Move arena-tag-type to its own file

* Move pokemon-moves to its own file

* Move command to own file

* Move learnMoveType to own file

* Move form change item to own file

* Move battlerTagLapseType to own file

* Move anim enums to own shared file

* Move enums out of challenges

* Move species form change triggers to own file

Reduces circ imports to 291

* Update test importing pokemon move

* Replace move attribute imports with string names

* Untangle circular deps from game data

* Fix missing string call in switch summon phase

* Apply kev's suggestions from code review

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

* Ensure ChargeMove's is method calls super

* Use InstanceType for proper narrowing

* Apply kev's suggestions from code review

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>

---------

Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2025-06-09 16:24:13 -07:00

87 lines
2.8 KiB
TypeScript

import type { BattlerIndex } from "#enums/battler-index";
import { BattlerTagType } from "#enums/battler-tag-type";
import { MoveId } from "#enums/move-id";
import { EFFECTIVE_STATS, BATTLE_STATS } from "#enums/stat";
import { PokemonMove } from "#app/data/moves/pokemon-move";
import { globalScene } from "#app/global-scene";
import { PokemonPhase } from "./pokemon-phase";
import { getPokemonNameWithAffix } from "#app/messages";
import i18next from "i18next";
/**
* Transforms a Pokemon into another Pokemon on the field.
* Used for Transform (move) and Imposter (ability)
*/
export class PokemonTransformPhase extends PokemonPhase {
public readonly phaseName = "PokemonTransformPhase";
protected targetIndex: BattlerIndex;
private playSound: boolean;
constructor(userIndex: BattlerIndex, targetIndex: BattlerIndex, playSound = false) {
super(userIndex);
this.targetIndex = targetIndex;
this.playSound = playSound;
}
public override start(): void {
const user = this.getPokemon();
const target = globalScene.getField(true).find(p => p.getBattlerIndex() === this.targetIndex);
if (!target) {
return this.end();
}
user.summonData.speciesForm = target.getSpeciesForm();
user.summonData.ability = target.getAbility().id;
user.summonData.gender = target.getGender();
// Power Trick's effect is removed after using Transform
user.removeTag(BattlerTagType.POWER_TRICK);
// Copy all stats (except HP)
for (const s of EFFECTIVE_STATS) {
user.setStat(s, target.getStat(s, false), false);
}
// Copy all stat stages
for (const s of BATTLE_STATS) {
user.setStatStage(s, target.getStatStage(s));
}
user.summonData.moveset = target.getMoveset().map(m => {
if (m) {
// If PP value is less than 5, do nothing. If greater, we need to reduce the value to 5.
return new PokemonMove(m.moveId, 0, 0, false, Math.min(m.getMove().pp, 5));
}
console.warn(`Transform: somehow iterating over a ${m} value when copying moveset!`);
return new PokemonMove(MoveId.NONE);
});
user.summonData.types = target.getTypes();
const promises = [user.updateInfo()];
if (this.playSound) {
globalScene.playSound("battle_anims/PRSFX- Transform");
}
globalScene.phaseManager.queueMessage(
i18next.t("abilityTriggers:postSummonTransform", {
pokemonNameWithAffix: getPokemonNameWithAffix(user),
targetName: target.name,
}),
);
promises.push(
user.loadAssets(false).then(() => {
user.playAnim();
user.updateInfo();
// If the new ability activates immediately, it needs to happen after all the transform animations
user.setTempAbility(target.getAbility());
}),
);
Promise.allSettled(promises).then(() => this.end());
}
}