Replace instanceof phase with isXPhase

This commit is contained in:
Sirz Benjie 2025-05-22 19:03:29 -05:00
parent aef619a699
commit 86b59a0243
No known key found for this signature in database
GPG Key ID: 4A524B4D196C759E
21 changed files with 53 additions and 60 deletions

View File

@ -145,7 +145,7 @@ import { LoadingScene } from "#app/loading-scene";
import { LevelCapPhase } from "#app/phases/level-cap-phase"; import { LevelCapPhase } from "#app/phases/level-cap-phase";
import { LoginPhase } from "#app/phases/login-phase"; import { LoginPhase } from "#app/phases/login-phase";
import { MessagePhase } from "#app/phases/message-phase"; import { MessagePhase } from "#app/phases/message-phase";
import { MovePhase } from "#app/phases/move-phase"; import type { MovePhase } from "#app/phases/move-phase";
import { NewBiomeEncounterPhase } from "#app/phases/new-biome-encounter-phase"; import { NewBiomeEncounterPhase } from "#app/phases/new-biome-encounter-phase";
import { NextEncounterPhase } from "#app/phases/next-encounter-phase"; import { NextEncounterPhase } from "#app/phases/next-encounter-phase";
import { PokemonAnimPhase } from "#app/phases/pokemon-anim-phase"; import { PokemonAnimPhase } from "#app/phases/pokemon-anim-phase";
@ -153,7 +153,6 @@ import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
import { ReturnPhase } from "#app/phases/return-phase"; import { ReturnPhase } from "#app/phases/return-phase";
import { ShowTrainerPhase } from "#app/phases/show-trainer-phase"; import { ShowTrainerPhase } from "#app/phases/show-trainer-phase";
import { SummonPhase } from "#app/phases/summon-phase"; import { SummonPhase } from "#app/phases/summon-phase";
import { SwitchPhase } from "#app/phases/switch-phase";
import { TitlePhase } from "#app/phases/title-phase"; import { TitlePhase } from "#app/phases/title-phase";
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase"; import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
import { TurnInitPhase } from "#app/phases/turn-init-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase";
@ -901,7 +900,7 @@ export default class BattleScene extends SceneBase {
do { do {
targetingMovePhase = this.findPhase( targetingMovePhase = this.findPhase(
mp => mp =>
mp instanceof MovePhase && mp.isXPhase("MovePhase") &&
mp.targets.length === 1 && mp.targets.length === 1 &&
mp.targets[0] === removedPokemon.getBattlerIndex() && mp.targets[0] === removedPokemon.getBattlerIndex() &&
mp.pokemon.isPlayer() !== allyPokemon.isPlayer(), mp.pokemon.isPlayer() !== allyPokemon.isPlayer(),
@ -1450,7 +1449,7 @@ export default class BattleScene extends SceneBase {
} }
if (lastBattle?.double && !newDouble) { if (lastBattle?.double && !newDouble) {
this.tryRemovePhase(p => p instanceof SwitchPhase); this.tryRemovePhase((p: Phase) => p.isXPhase("SwitchPhase"));
for (const p of this.getPlayerField()) { for (const p of this.getPlayerField()) {
p.lapseTag(BattlerTagType.COMMANDED); p.lapseTag(BattlerTagType.COMMANDED);
} }

View File

@ -2828,7 +2828,7 @@ export class CommanderAbAttr extends AbAttr {
// Apply boosts from this effect to the ally Dondozo // Apply boosts from this effect to the ally Dondozo
pokemon.getAlly()?.addTag(BattlerTagType.COMMANDED, 0, MoveId.NONE, pokemon.id); pokemon.getAlly()?.addTag(BattlerTagType.COMMANDED, 0, MoveId.NONE, pokemon.id);
// Cancel the source Pokemon's next move (if a move is queued) // Cancel the source Pokemon's next move (if a move is queued)
globalScene.tryRemovePhase((phase) => phase instanceof MovePhase && phase.pokemon === pokemon); globalScene.tryRemovePhase((phase) => phase.isXPhase("MovePhase") && phase.pokemon === pokemon);
} }
} }
} }
@ -6897,7 +6897,7 @@ export function initAbilities() {
.ignorable(), .ignorable(),
new Ability(AbilityId.ANALYTIC, 5) new Ability(AbilityId.ANALYTIC, 5)
.attr(MovePowerBoostAbAttr, (user, target, move) => { .attr(MovePowerBoostAbAttr, (user, target, move) => {
const movePhase = globalScene.findPhase((phase) => phase instanceof MovePhase && phase.pokemon.id !== user?.id); const movePhase = globalScene.findPhase((phase) => phase.isXPhase("MovePhase") && phase.pokemon.id !== user?.id);
return isNullOrUndefined(movePhase); return isNullOrUndefined(movePhase);
}, 1.3), }, 1.3),
new Ability(AbilityId.ILLUSION, 5) new Ability(AbilityId.ILLUSION, 5)

View File

@ -383,7 +383,7 @@ const QuickGuardConditionFunc: ProtectConditionFunc = (_arena, moveId) => {
const move = allMoves[moveId]; const move = allMoves[moveId];
const effectPhase = globalScene.getCurrentPhase(); const effectPhase = globalScene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase) { if (effectPhase?.isXPhase("MoveEffectPhase")) {
const attacker = effectPhase.getUserPokemon(); const attacker = effectPhase.getUserPokemon();
if (attacker) { if (attacker) {
return move.getPriority(attacker) > 0; return move.getPriority(attacker) > 0;

View File

@ -28,7 +28,7 @@ import type Pokemon from "#app/field/pokemon";
import { HitResult, MoveResult } from "#app/field/pokemon"; import { HitResult, MoveResult } from "#app/field/pokemon";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { CommonAnimPhase } from "#app/phases/common-anim-phase"; import { CommonAnimPhase } from "#app/phases/common-anim-phase";
import { MoveEffectPhase } from "#app/phases/move-effect-phase"; import type { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { MovePhase } from "#app/phases/move-phase"; import { MovePhase } from "#app/phases/move-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import type { StatStageChangeCallback } from "#app/phases/stat-stage-change-phase"; import type { StatStageChangeCallback } from "#app/phases/stat-stage-change-phase";
@ -553,9 +553,9 @@ export class ShellTrapTag extends BattlerTag {
// Trap should only be triggered by opponent's Physical moves // Trap should only be triggered by opponent's Physical moves
if (phaseData?.move.category === MoveCategory.PHYSICAL && pokemon.isOpponent(phaseData.attacker)) { if (phaseData?.move.category === MoveCategory.PHYSICAL && pokemon.isOpponent(phaseData.attacker)) {
const shellTrapPhaseIndex = globalScene.phaseQueue.findIndex( const shellTrapPhaseIndex = globalScene.phaseQueue.findIndex(
phase => phase instanceof MovePhase && phase.pokemon === pokemon, phase => phase.isXPhase("MovePhase") && phase.pokemon === pokemon,
); );
const firstMovePhaseIndex = globalScene.phaseQueue.findIndex(phase => phase instanceof MovePhase); const firstMovePhaseIndex = globalScene.phaseQueue.findIndex(phase => phase.isXPhase("MovePhase"));
// Only shift MovePhase timing if it's not already next up // Only shift MovePhase timing if it's not already next up
if (shellTrapPhaseIndex !== -1 && shellTrapPhaseIndex !== firstMovePhaseIndex) { if (shellTrapPhaseIndex !== -1 && shellTrapPhaseIndex !== firstMovePhaseIndex) {
@ -1027,7 +1027,7 @@ export class PowderTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.PRE_MOVE) { if (lapseType === BattlerTagLapseType.PRE_MOVE) {
const movePhase = globalScene.getCurrentPhase(); const movePhase = globalScene.getCurrentPhase();
if (movePhase instanceof MovePhase) { if (movePhase?.isXPhase("MovePhase")) {
const move = movePhase.move.getMove(); const move = movePhase.move.getMove();
const weather = globalScene.arena.weather; const weather = globalScene.arena.weather;
if ( if (
@ -1183,13 +1183,13 @@ export class EncoreTag extends MoveRestrictionBattlerTag {
}), }),
); );
const movePhase = globalScene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon); const movePhase = globalScene.findPhase(m => m.isXPhase("MovePhase") && m.pokemon === pokemon);
if (movePhase) { if (movePhase) {
const movesetMove = pokemon.getMoveset().find(m => m.moveId === this.moveId); const movesetMove = pokemon.getMoveset().find(m => m.moveId === this.moveId);
if (movesetMove) { if (movesetMove) {
const lastMove = pokemon.getLastXMoves(1)[0]; const lastMove = pokemon.getLastXMoves(1)[0];
globalScene.tryReplacePhase( globalScene.tryReplacePhase(
m => m instanceof MovePhase && m.pokemon === pokemon, m => m.isXPhase("MovePhase") && m.pokemon === pokemon,
new MovePhase(pokemon, lastMove.targets ?? [], movesetMove), new MovePhase(pokemon, lastMove.targets ?? [], movesetMove),
); );
} }
@ -1624,7 +1624,7 @@ export class ProtectedTag extends BattlerTag {
// Stop multi-hit moves early // Stop multi-hit moves early
const effectPhase = globalScene.getCurrentPhase(); const effectPhase = globalScene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase) { if (effectPhase?.isXPhase("MoveEffectPhase")) {
effectPhase.stopMultiHit(pokemon); effectPhase.stopMultiHit(pokemon);
} }
return true; return true;
@ -2646,7 +2646,7 @@ export class GulpMissileTag extends BattlerTag {
} }
const moveEffectPhase = globalScene.getCurrentPhase(); const moveEffectPhase = globalScene.getCurrentPhase();
if (moveEffectPhase instanceof MoveEffectPhase) { if (moveEffectPhase?.isXPhase("MoveEffectPhase")) {
const attacker = moveEffectPhase.getUserPokemon(); const attacker = moveEffectPhase.getUserPokemon();
if (!attacker) { if (!attacker) {
@ -3004,7 +3004,7 @@ export class SubstituteTag extends BattlerTag {
/** If the Substitute redirects damage, queue a message to indicate it. */ /** If the Substitute redirects damage, queue a message to indicate it. */
onHit(pokemon: Pokemon): void { onHit(pokemon: Pokemon): void {
const moveEffectPhase = globalScene.getCurrentPhase(); const moveEffectPhase = globalScene.getCurrentPhase();
if (moveEffectPhase instanceof MoveEffectPhase) { if (moveEffectPhase?.isXPhase("MoveEffectPhase")) {
const attacker = moveEffectPhase.getUserPokemon(); const attacker = moveEffectPhase.getUserPokemon();
if (!attacker) { if (!attacker) {
return; return;
@ -3693,7 +3693,7 @@ export function loadBattlerTag(source: BattlerTag | any): BattlerTag {
*/ */
function getMoveEffectPhaseData(_pokemon: Pokemon): { phase: MoveEffectPhase; attacker: Pokemon; move: Move } | null { function getMoveEffectPhaseData(_pokemon: Pokemon): { phase: MoveEffectPhase; attacker: Pokemon; move: Move } | null {
const phase = globalScene.getCurrentPhase(); const phase = globalScene.getCurrentPhase();
if (phase instanceof MoveEffectPhase) { if (phase?.isXPhase("MoveEffectPhase")) {
return { return {
phase: phase, phase: phase,
attacker: phase.getPokemon(), attacker: phase.getPokemon(),

View File

@ -3109,7 +3109,7 @@ export class AwaitCombinedPledgeAttr extends OverrideMoveEffectAttr {
const overridden = args[0] as BooleanHolder; const overridden = args[0] as BooleanHolder;
const allyMovePhase = globalScene.findPhase<MovePhase>((phase) => phase instanceof MovePhase && phase.pokemon.isPlayer() === user.isPlayer()); const allyMovePhase = globalScene.findPhase<MovePhase>((phase) => phase.isXPhase("MovePhase") && phase.pokemon.isPlayer() === user.isPlayer());
if (allyMovePhase) { if (allyMovePhase) {
const allyMove = allyMovePhase.move.getMove(); const allyMove = allyMovePhase.move.getMove();
if (allyMove !== move && allyMove.hasAttr(AwaitCombinedPledgeAttr)) { if (allyMove !== move && allyMove.hasAttr(AwaitCombinedPledgeAttr)) {
@ -3123,7 +3123,7 @@ export class AwaitCombinedPledgeAttr extends OverrideMoveEffectAttr {
// Move the ally's MovePhase (if needed) so that the ally moves next // Move the ally's MovePhase (if needed) so that the ally moves next
const allyMovePhaseIndex = globalScene.phaseQueue.indexOf(allyMovePhase); const allyMovePhaseIndex = globalScene.phaseQueue.indexOf(allyMovePhase);
const firstMovePhaseIndex = globalScene.phaseQueue.findIndex((phase) => phase instanceof MovePhase); const firstMovePhaseIndex = globalScene.phaseQueue.findIndex((phase) => phase.isXPhase("MovePhase"));
if (allyMovePhaseIndex !== firstMovePhaseIndex) { if (allyMovePhaseIndex !== firstMovePhaseIndex) {
globalScene.prependToPhase(globalScene.phaseQueue.splice(allyMovePhaseIndex, 1)[0], MovePhase); globalScene.prependToPhase(globalScene.phaseQueue.splice(allyMovePhaseIndex, 1)[0], MovePhase);
} }
@ -4477,7 +4477,7 @@ export class CueNextRoundAttr extends MoveEffectAttr {
override apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean { override apply(user: Pokemon, target: Pokemon, move: Move, args?: any[]): boolean {
const nextRoundPhase = globalScene.findPhase<MovePhase>(phase => const nextRoundPhase = globalScene.findPhase<MovePhase>(phase =>
phase instanceof MovePhase && phase.move.moveId === MoveId.ROUND phase.isXPhase("MovePhase") && phase.move.moveId === MoveId.ROUND
); );
if (!nextRoundPhase) { if (!nextRoundPhase) {
@ -4486,7 +4486,7 @@ export class CueNextRoundAttr extends MoveEffectAttr {
// Update the phase queue so that the next Pokemon using Round moves next // Update the phase queue so that the next Pokemon using Round moves next
const nextRoundIndex = globalScene.phaseQueue.indexOf(nextRoundPhase); const nextRoundIndex = globalScene.phaseQueue.indexOf(nextRoundPhase);
const nextMoveIndex = globalScene.phaseQueue.findIndex(phase => phase instanceof MovePhase); const nextMoveIndex = globalScene.phaseQueue.findIndex(phase => phase.isXPhase("MovePhase"));
if (nextRoundIndex !== nextMoveIndex) { if (nextRoundIndex !== nextMoveIndex) {
globalScene.prependToPhase(globalScene.phaseQueue.splice(nextRoundIndex, 1)[0], MovePhase); globalScene.prependToPhase(globalScene.phaseQueue.splice(nextRoundIndex, 1)[0], MovePhase);
} }
@ -6177,7 +6177,7 @@ export class RevivalBlessingAttr extends MoveEffectAttr {
// Handle cases where revived pokemon needs to get switched in on same turn // Handle cases where revived pokemon needs to get switched in on same turn
if (allyPokemon.isFainted() || allyPokemon === pokemon) { if (allyPokemon.isFainted() || allyPokemon === pokemon) {
// Enemy switch phase should be removed and replaced with the revived pkmn switching in // Enemy switch phase should be removed and replaced with the revived pkmn switching in
globalScene.tryRemovePhase((phase: SwitchSummonPhase) => phase instanceof SwitchSummonPhase && phase.getPokemon() === pokemon); globalScene.tryRemovePhase((phase: SwitchSummonPhase) => phase.isXPhase("SwitchSummonPhase") && phase.getPokemon() === pokemon);
// If the pokemon being revived was alive earlier in the turn, cancel its move // If the pokemon being revived was alive earlier in the turn, cancel its move
// (revived pokemon can't move in the turn they're brought back) // (revived pokemon can't move in the turn they're brought back)
globalScene.findPhase((phase: MovePhase) => phase.pokemon === pokemon)?.cancel(); globalScene.findPhase((phase: MovePhase) => phase.pokemon === pokemon)?.cancel();
@ -7896,7 +7896,7 @@ export class ForceLastAttr extends MoveEffectAttr {
// Either the end of the turn or in front of another, slower move which has also been forced last // Either the end of the turn or in front of another, slower move which has also been forced last
const prependPhase = globalScene.findPhase((phase) => const prependPhase = globalScene.findPhase((phase) =>
[ MovePhase, MoveEndPhase ].every(cls => !(phase instanceof cls)) [ MovePhase, MoveEndPhase ].every(cls => !(phase instanceof cls))
|| (phase instanceof MovePhase) && phaseForcedSlower(phase, target, !!globalScene.arena.getTag(ArenaTagType.TRICK_ROOM)) || (phase.isXPhase("MovePhase")) && phaseForcedSlower(phase, target, !!globalScene.arena.getTag(ArenaTagType.TRICK_ROOM))
); );
if (prependPhase) { if (prependPhase) {
globalScene.phaseQueue.splice( globalScene.phaseQueue.splice(
@ -7942,7 +7942,7 @@ const userSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target:
const targetSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.status?.effect === StatusEffect.SLEEP || target.hasAbility(AbilityId.COMATOSE); const targetSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.status?.effect === StatusEffect.SLEEP || target.hasAbility(AbilityId.COMATOSE);
const failIfLastCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => globalScene.phaseQueue.find(phase => phase instanceof MovePhase) !== undefined; const failIfLastCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => globalScene.phaseQueue.find(phase => phase.isXPhase("MovePhase")) !== undefined;
const failIfLastInPartyCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => { const failIfLastInPartyCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => {
const party: Pokemon[] = user.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty(); const party: Pokemon[] = user.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty();

View File

@ -769,7 +769,7 @@ export function setEncounterRewards(
if (customShopRewards) { if (customShopRewards) {
globalScene.unshiftPhase(new SelectModifierPhase(0, undefined, customShopRewards)); globalScene.unshiftPhase(new SelectModifierPhase(0, undefined, customShopRewards));
} else { } else {
globalScene.tryRemovePhase(p => p instanceof SelectModifierPhase); globalScene.tryRemovePhase(p => p.isXPhase("MysteryEncounterRewardsPhase"));
} }
if (eggRewards) { if (eggRewards) {

View File

@ -1300,7 +1300,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
// During the Pokemon's MoveEffect phase, the offset is removed to put the Pokemon "in focus" // During the Pokemon's MoveEffect phase, the offset is removed to put the Pokemon "in focus"
const currentPhase = globalScene.getCurrentPhase(); const currentPhase = globalScene.getCurrentPhase();
if (currentPhase instanceof MoveEffectPhase && currentPhase.getPokemon() === this) { if (currentPhase?.isXPhase("MoveEffectPhase") && currentPhase.getPokemon() === this) {
return false; return false;
} }
return true; return true;
@ -4775,7 +4775,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
*/ */
if (effect === StatusEffect.SLEEP || effect === StatusEffect.FREEZE) { if (effect === StatusEffect.SLEEP || effect === StatusEffect.FREEZE) {
const currentPhase = globalScene.getCurrentPhase(); const currentPhase = globalScene.getCurrentPhase();
if (currentPhase instanceof MoveEffectPhase && currentPhase.getUserPokemon() === this) { if (currentPhase?.isXPhase("MoveEffectPhase") && currentPhase.getUserPokemon() === this) {
this.turnData.hitCount = 1; this.turnData.hitCount = 1;
this.turnData.hitsLeft = 1; this.turnData.hitsLeft = 1;
} }

View File

@ -20,7 +20,7 @@ export class BattleEndPhase extends BattlePhase {
// cull any extra `BattleEnd` phases from the queue. // cull any extra `BattleEnd` phases from the queue.
globalScene.phaseQueue = globalScene.phaseQueue.filter(phase => { globalScene.phaseQueue = globalScene.phaseQueue.filter(phase => {
if (phase instanceof BattleEndPhase) { if (phase.isXPhase("BattleEndPhase")) {
this.isVictory ||= phase.isVictory; this.isVictory ||= phase.isVictory;
return false; return false;
} }
@ -29,7 +29,7 @@ export class BattleEndPhase extends BattlePhase {
// `phaseQueuePrepend` is private, so we have to use this inefficient loop. // `phaseQueuePrepend` is private, so we have to use this inefficient loop.
while ( while (
globalScene.tryRemoveUnshiftedPhase(phase => { globalScene.tryRemoveUnshiftedPhase(phase => {
if (phase instanceof BattleEndPhase) { if (phase.isXPhase("BattleEndPhase")) {
this.isVictory ||= phase.isVictory; this.isVictory ||= phase.isVictory;
return true; return true;
} }

View File

@ -225,7 +225,7 @@ export class EggHatchPhase extends Phase {
} }
end() { end() {
if (globalScene.findPhase(p => p instanceof EggHatchPhase)) { if (globalScene.findPhase(p => p.isXPhase("EggHatchPhase"))) {
this.eggHatchHandler.clear(); this.eggHatchHandler.clear();
} else { } else {
globalScene.time.delayedCall(250, () => globalScene.setModifiersVisible(true)); globalScene.time.delayedCall(250, () => globalScene.setModifiersVisible(true));

View File

@ -12,7 +12,6 @@ import { UiMode } from "#enums/ui-mode";
import i18next from "i18next"; import i18next from "i18next";
import { PlayerPartyMemberPokemonPhase } from "#app/phases/player-party-member-pokemon-phase"; import { PlayerPartyMemberPokemonPhase } from "#app/phases/player-party-member-pokemon-phase";
import type Pokemon from "#app/field/pokemon"; import type Pokemon from "#app/field/pokemon";
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
export enum LearnMoveType { export enum LearnMoveType {
/** For learning a move via level-up, evolution, or other non-item-based event */ /** For learning a move via level-up, evolution, or other non-item-based event */
@ -196,7 +195,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
pokemon.usedTMs = []; pokemon.usedTMs = [];
} }
pokemon.usedTMs.push(this.moveId); pokemon.usedTMs.push(this.moveId);
globalScene.tryRemovePhase(phase => phase instanceof SelectModifierPhase); globalScene.tryRemovePhase(phase => phase.isXPhase("SelectModifierPhase"));
} else if (this.learnMoveType === LearnMoveType.MEMORY) { } else if (this.learnMoveType === LearnMoveType.MEMORY) {
if (this.cost !== -1) { if (this.cost !== -1) {
if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) { if (!Overrides.WAIVE_ROLL_FEE_OVERRIDE) {
@ -206,7 +205,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
} }
globalScene.playSound("se/buy"); globalScene.playSound("se/buy");
} else { } else {
globalScene.tryRemovePhase(phase => phase instanceof SelectModifierPhase); globalScene.tryRemovePhase(phase => phase.isXPhase("SelectModifierPhase"));
} }
} }
pokemon.setMove(index, this.moveId); pokemon.setMove(index, this.moveId);

View File

@ -9,7 +9,6 @@ import { BooleanHolder } from "#app/utils/common";
import { MovePhase } from "#app/phases/move-phase"; import { MovePhase } from "#app/phases/move-phase";
import { PokemonPhase } from "#app/phases/pokemon-phase"; import { PokemonPhase } from "#app/phases/pokemon-phase";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { MoveEndPhase } from "#app/phases/move-end-phase";
/** /**
* Phase for the "charging turn" of two-turn moves (e.g. Dig). * Phase for the "charging turn" of two-turn moves (e.g. Dig).
@ -63,7 +62,7 @@ export class MoveChargePhase extends PokemonPhase {
if (instantCharge.value) { if (instantCharge.value) {
// this MoveEndPhase will be duplicated by the queued MovePhase if not removed // this MoveEndPhase will be duplicated by the queued MovePhase if not removed
globalScene.tryRemovePhase(phase => phase instanceof MoveEndPhase && phase.getPokemon() === user); globalScene.tryRemovePhase(phase => phase.isXPhase("MoveEndPhase") && phase.getPokemon() === user);
// queue a new MovePhase for this move's attack phase // queue a new MovePhase for this move's attack phase
globalScene.unshiftPhase(new MovePhase(user, [this.targetIndex], this.move, false)); globalScene.unshiftPhase(new MovePhase(user, [this.targetIndex], this.move, false));
} else { } else {

View File

@ -6,7 +6,6 @@ import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-d
import { CheckSwitchPhase } from "#app/phases/check-switch-phase"; import { CheckSwitchPhase } from "#app/phases/check-switch-phase";
import { GameOverPhase } from "#app/phases/game-over-phase"; import { GameOverPhase } from "#app/phases/game-over-phase";
import { NewBattlePhase } from "#app/phases/new-battle-phase"; import { NewBattlePhase } from "#app/phases/new-battle-phase";
import { PostTurnStatusEffectPhase } from "#app/phases/post-turn-status-effect-phase";
import { ReturnPhase } from "#app/phases/return-phase"; import { ReturnPhase } from "#app/phases/return-phase";
import { ScanIvsPhase } from "#app/phases/scan-ivs-phase"; import { ScanIvsPhase } from "#app/phases/scan-ivs-phase";
import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
@ -248,8 +247,8 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
}); });
// Remove any status tick phases // Remove any status tick phases
while (globalScene.findPhase(p => p instanceof PostTurnStatusEffectPhase)) { while (globalScene.findPhase(p => p.isXPhase("PostTurnStatusEffectPhase"))) {
globalScene.tryRemovePhase(p => p instanceof PostTurnStatusEffectPhase); globalScene.tryRemovePhase(p => p.isXPhase("PostTurnStatusEffectPhase"));
} }
// The total number of Pokemon in the player's party that can legally fight // The total number of Pokemon in the player's party that can legally fight
@ -563,7 +562,7 @@ export class MysteryEncounterRewardsPhase extends Phase {
if (encounter.doEncounterRewards) { if (encounter.doEncounterRewards) {
encounter.doEncounterRewards(); encounter.doEncounterRewards();
} else if (this.addHealPhase) { } else if (this.addHealPhase) {
globalScene.tryRemovePhase(p => p instanceof SelectModifierPhase); globalScene.tryRemovePhase(p => p.isXPhase("SelectModifierPhase"));
globalScene.unshiftPhase( globalScene.unshiftPhase(
new SelectModifierPhase(0, undefined, { new SelectModifierPhase(0, undefined, {
fillRemaining: false, fillRemaining: false,

View File

@ -7,9 +7,9 @@ export class NewBattlePhase extends BattlePhase {
super.start(); super.start();
// cull any extra `NewBattle` phases from the queue. // cull any extra `NewBattle` phases from the queue.
globalScene.phaseQueue = globalScene.phaseQueue.filter(phase => !(phase instanceof NewBattlePhase)); globalScene.phaseQueue = globalScene.phaseQueue.filter(phase => !phase.isXPhase("NewBattlePhase"));
// `phaseQueuePrepend` is private, so we have to use this inefficient loop. // `phaseQueuePrepend` is private, so we have to use this inefficient loop.
while (globalScene.tryRemoveUnshiftedPhase(phase => phase instanceof NewBattlePhase)) {} while (globalScene.tryRemoveUnshiftedPhase(phase => phase.isXPhase("NewBattlePhase"))) {}
globalScene.newBattle(); globalScene.newBattle();

View File

@ -9,7 +9,7 @@ import type Pokemon from "#app/field/pokemon";
import { EnemyPokemon } from "#app/field/pokemon"; import { EnemyPokemon } from "#app/field/pokemon";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { BattlePhase } from "./battle-phase"; import { BattlePhase } from "./battle-phase";
import { MovePhase } from "./move-phase"; import type { MovePhase } from "./move-phase";
import { PokemonHealPhase } from "./pokemon-heal-phase"; import { PokemonHealPhase } from "./pokemon-heal-phase";
import { import {
applyAbAttrs, applyAbAttrs,
@ -169,7 +169,7 @@ export class QuietFormChangePhase extends BattlePhase {
this.pokemon.initBattleInfo(); this.pokemon.initBattleInfo();
this.pokemon.cry(); this.pokemon.cry();
const movePhase = globalScene.findPhase(p => p instanceof MovePhase && p.pokemon === this.pokemon) as MovePhase; const movePhase = globalScene.findPhase(p => p.isXPhase("MovePhase") && p.pokemon === this.pokemon) as MovePhase;
if (movePhase) { if (movePhase) {
movePhase.cancel(); movePhase.cancel();
} }

View File

@ -236,9 +236,9 @@ export class StatStageChangePhase extends PokemonPhase {
// Look for any other stat change phases; if this is the last one, do White Herb check // Look for any other stat change phases; if this is the last one, do White Herb check
const existingPhase = globalScene.findPhase( const existingPhase = globalScene.findPhase(
p => p instanceof StatStageChangePhase && p.battlerIndex === this.battlerIndex, p => p.isXPhase("StatStageChangePhase") && p.battlerIndex === this.battlerIndex,
); );
if (!(existingPhase instanceof StatStageChangePhase)) { if (!existingPhase?.isXPhase("StatStageChangePhase")) {
// Apply White Herb if needed // Apply White Herb if needed
const whiteHerb = globalScene.applyModifier( const whiteHerb = globalScene.applyModifier(
ResetNegativeStatStageModifier, ResetNegativeStatStageModifier,
@ -317,7 +317,7 @@ export class StatStageChangePhase extends PokemonPhase {
while ( while (
(existingPhase = globalScene.findPhase( (existingPhase = globalScene.findPhase(
p => p =>
p instanceof StatStageChangePhase && p.isXPhase("StatStageChangePhase") &&
p.battlerIndex === this.battlerIndex && p.battlerIndex === this.battlerIndex &&
p.stats.length === 1 && p.stats.length === 1 &&
p.stats[0] === this.stats[0] && p.stats[0] === this.stats[0] &&
@ -336,7 +336,7 @@ export class StatStageChangePhase extends PokemonPhase {
while ( while (
(existingPhase = globalScene.findPhase( (existingPhase = globalScene.findPhase(
p => p =>
p instanceof StatStageChangePhase && p.isXPhase("StatStageChangePhase") &&
p.battlerIndex === this.battlerIndex && p.battlerIndex === this.battlerIndex &&
p.selfTarget === this.selfTarget && p.selfTarget === this.selfTarget &&
accEva.some(s => p.stats.includes(s)) === isAccEva && accEva.some(s => p.stats.includes(s)) === isAccEva &&

View File

@ -3,7 +3,6 @@ import PartyUiHandler, { PartyOption, PartyUiMode } from "#app/ui/party-ui-handl
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import { SwitchType } from "#enums/switch-type"; import { SwitchType } from "#enums/switch-type";
import { BattlePhase } from "./battle-phase"; import { BattlePhase } from "./battle-phase";
import { PostSummonPhase } from "./post-summon-phase";
import { SwitchSummonPhase } from "./switch-summon-phase"; import { SwitchSummonPhase } from "./switch-summon-phase";
/** /**
@ -77,7 +76,9 @@ export class SwitchPhase extends BattlePhase {
if (slotIndex >= globalScene.currentBattle.getBattlerCount() && slotIndex < 6) { if (slotIndex >= globalScene.currentBattle.getBattlerCount() && slotIndex < 6) {
// Remove any pre-existing PostSummonPhase under the same field index. // Remove any pre-existing PostSummonPhase under the same field index.
// Pre-existing PostSummonPhases may occur when this phase is invoked during a prompt to switch at the start of a wave. // Pre-existing PostSummonPhases may occur when this phase is invoked during a prompt to switch at the start of a wave.
globalScene.tryRemovePhase(p => p instanceof PostSummonPhase && p.player && p.fieldIndex === this.fieldIndex); globalScene.tryRemovePhase(
p => p.isXPhase("PostSummonPhase") && p.player && p.fieldIndex === this.fieldIndex,
);
const switchType = option === PartyOption.PASS_BATON ? SwitchType.BATON_PASS : this.switchType; const switchType = option === PartyOption.PASS_BATON ? SwitchType.BATON_PASS : this.switchType;
globalScene.unshiftPhase(new SwitchSummonPhase(switchType, fieldIndex, slotIndex, this.doReturn)); globalScene.unshiftPhase(new SwitchSummonPhase(switchType, fieldIndex, slotIndex, this.doReturn));
} }

View File

@ -5,7 +5,7 @@ import UiHandler from "./ui-handler";
import i18next from "i18next"; import i18next from "i18next";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import { CommandPhase } from "#app/phases/command-phase"; import type { CommandPhase } from "#app/phases/command-phase";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
import { TerastallizeAccessModifier } from "#app/modifier/modifier"; import { TerastallizeAccessModifier } from "#app/modifier/modifier";
import { PokemonType } from "#enums/pokemon-type"; import { PokemonType } from "#enums/pokemon-type";
@ -75,7 +75,7 @@ export default class CommandUiHandler extends UiHandler {
let commandPhase: CommandPhase; let commandPhase: CommandPhase;
const currentPhase = globalScene.getCurrentPhase(); const currentPhase = globalScene.getCurrentPhase();
if (currentPhase instanceof CommandPhase) { if (currentPhase?.isXPhase("CommandPhase")) {
commandPhase = currentPhase; commandPhase = currentPhase;
} else { } else {
commandPhase = globalScene.getStandbyPhase() as CommandPhase; commandPhase = globalScene.getStandbyPhase() as CommandPhase;

View File

@ -1,7 +1,6 @@
import { UiMode } from "#enums/ui-mode"; import { UiMode } from "#enums/ui-mode";
import UiHandler from "./ui-handler"; import UiHandler from "./ui-handler";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import { EggHatchPhase } from "#app/phases/egg-hatch-phase";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
export default class EggHatchSceneHandler extends UiHandler { export default class EggHatchSceneHandler extends UiHandler {
@ -46,7 +45,7 @@ export default class EggHatchSceneHandler extends UiHandler {
processInput(button: Button): boolean { processInput(button: Button): boolean {
if (button === Button.ACTION || button === Button.CANCEL) { if (button === Button.ACTION || button === Button.CANCEL) {
const phase = globalScene.getCurrentPhase(); const phase = globalScene.getCurrentPhase();
if (phase instanceof EggHatchPhase && phase.trySkip()) { if (phase?.isXPhase("EggHatchPhase") && phase.trySkip()) {
return true; return true;
} }
} }

View File

@ -4,7 +4,6 @@ import MessageUiHandler from "./message-ui-handler";
import { getEggTierForSpecies } from "../data/egg"; import { getEggTierForSpecies } from "../data/egg";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import PokemonHatchInfoContainer from "./pokemon-hatch-info-container"; import PokemonHatchInfoContainer from "./pokemon-hatch-info-container";
import { EggSummaryPhase } from "#app/phases/egg-summary-phase";
import type { EggHatchData } from "#app/data/egg-hatch-data"; import type { EggHatchData } from "#app/data/egg-hatch-data";
import ScrollableGridUiHandler from "./scrollable-grid-handler"; import ScrollableGridUiHandler from "./scrollable-grid-handler";
import { HatchedPokemonContainer } from "./hatched-pokemon-container"; import { HatchedPokemonContainer } from "./hatched-pokemon-container";
@ -223,7 +222,7 @@ export default class EggSummaryUiHandler extends MessageUiHandler {
if (button === Button.CANCEL) { if (button === Button.CANCEL) {
if (!this.blockExit) { if (!this.blockExit) {
const phase = globalScene.getCurrentPhase(); const phase = globalScene.getCurrentPhase();
if (phase instanceof EggSummaryPhase) { if (phase?.isXPhase("EggSummaryPhase")) {
phase.end(); phase.end();
} }
success = true; success = true;

View File

@ -15,7 +15,6 @@ import { Button } from "#enums/buttons";
import { GameDataType } from "#enums/game-data-type"; import { GameDataType } from "#enums/game-data-type";
import BgmBar from "#app/ui/bgm-bar"; import BgmBar from "#app/ui/bgm-bar";
import type AwaitableUiHandler from "./awaitable-ui-handler"; import type AwaitableUiHandler from "./awaitable-ui-handler";
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
import { AdminMode, getAdminModeName } from "./admin-ui-handler"; import { AdminMode, getAdminModeName } from "./admin-ui-handler";
import { pokerogueApi } from "#app/plugins/api/pokerogue-api"; import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
@ -126,7 +125,7 @@ export default class MenuUiHandler extends MessageUiHandler {
const ui = this.getUi(); const ui = this.getUi();
this.excludedMenus = () => [ this.excludedMenus = () => [
{ {
condition: globalScene.getCurrentPhase() instanceof SelectModifierPhase, condition: !!globalScene.getCurrentPhase()?.isXPhase("SelectModifierPhase"),
options: [MenuOptions.EGG_GACHA], options: [MenuOptions.EGG_GACHA],
}, },
{ condition: bypassLogin, options: [MenuOptions.LOG_OUT] }, { condition: bypassLogin, options: [MenuOptions.LOG_OUT] },

View File

@ -29,7 +29,6 @@ import { MoveId } from "#enums/move-id";
import { SpeciesId } from "#enums/species-id"; import { SpeciesId } from "#enums/species-id";
import { getPokemonNameWithAffix } from "#app/messages"; import { getPokemonNameWithAffix } from "#app/messages";
import type { CommandPhase } from "#app/phases/command-phase"; import type { CommandPhase } from "#app/phases/command-phase";
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
import { globalScene } from "#app/global-scene"; import { globalScene } from "#app/global-scene";
const defaultMessage = i18next.t("partyUiHandler:choosePokemon"); const defaultMessage = i18next.t("partyUiHandler:choosePokemon");
@ -751,7 +750,7 @@ export default class PartyUiHandler extends MessageUiHandler {
// TODO: This risks hitting the other options (.MOVE_i and ALL) so does it? Do we need an extra check? // TODO: This risks hitting the other options (.MOVE_i and ALL) so does it? Do we need an extra check?
if ( if (
option >= PartyOption.FORM_CHANGE_ITEM && option >= PartyOption.FORM_CHANGE_ITEM &&
globalScene.getCurrentPhase() instanceof SelectModifierPhase && globalScene.getCurrentPhase()?.isXPhase("SelectModifierPhase") &&
this.partyUiMode === PartyUiMode.CHECK this.partyUiMode === PartyUiMode.CHECK
) { ) {
const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon);
@ -1338,7 +1337,7 @@ export default class PartyUiHandler extends MessageUiHandler {
this.addCommonOptions(pokemon); this.addCommonOptions(pokemon);
break; break;
case PartyUiMode.CHECK: case PartyUiMode.CHECK:
if (globalScene.getCurrentPhase() instanceof SelectModifierPhase) { if (globalScene.getCurrentPhase()?.isXPhase("SelectModifierPhase")) {
const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon);
for (let i = 0; i < formChangeItemModifiers.length; i++) { for (let i = 0; i < formChangeItemModifiers.length; i++) {
this.options.push(PartyOption.FORM_CHANGE_ITEM + i); this.options.push(PartyOption.FORM_CHANGE_ITEM + i);