From 3ab2fe83a52278b8a236e46acd818ed1a09edff4 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Wed, 18 Jun 2025 18:25:05 -0400 Subject: [PATCH] Cleaned up a few phase files to call `super.start` --- src/phase-manager.ts | 73 ++++++++++++------- src/phase.ts | 2 + src/phases/check-status-effect-phase.ts | 4 +- src/phases/common-anim-phase.ts | 1 + src/phases/money-reward-phase.ts | 1 + src/phases/obtain-status-effect-phase.ts | 2 + src/phases/pokemon-heal-phase.ts | 5 +- .../post-summon-activate-ability-phase.ts | 2 + src/phases/post-turn-status-effect-phase.ts | 2 + src/phases/stat-stage-change-phase.ts | 1 + src/phases/trainer-victory-phase.ts | 2 + src/phases/weather-effect-phase.ts | 1 + 12 files changed, 66 insertions(+), 30 deletions(-) diff --git a/src/phase-manager.ts b/src/phase-manager.ts index 9390e6dd75d..c59bd42eea6 100644 --- a/src/phase-manager.ts +++ b/src/phase-manager.ts @@ -217,13 +217,28 @@ export type PhaseConstructorMap = typeof PHASES; * PhaseManager is responsible for managing the phases in the battle scene */ export class PhaseManager { - /** PhaseQueue: dequeue/remove the first element to get the next phase */ + /** + * A queue of yet-unexecuted {@linkcode Phase}s to be run. \ + * Each time the current phase ends, all phases from {@linkcode phaseQueuePrepend} are added + * to the front of this queue and the next phase is started. + */ public phaseQueue: Phase[] = []; - public conditionalQueue: Array<[() => boolean, Phase]> = []; - /** PhaseQueuePrepend: is a temp storage of what will be added to PhaseQueue */ + /** + * A queue of yet-unexecuted {@linkcode Phase}s with conditions for their execution. \ + * Each entry is evaluated whenever a new phase starts, being added to the {@linkcode phaseQueue} if the condition is satisfied. + * + */ + public conditionalQueue: Array<[condition: () => boolean, phase: Phase]> = []; + /** A temporary storage of {@linkcode Phase}s */ private phaseQueuePrepend: Phase[] = []; - /** overrides default of inserting phases to end of phaseQueuePrepend array. Useful for inserting Phases "out of order" */ + /** + * If set, will cause subsequent calls to {@linkcode unshiftPhase} to insert at this index in **LIFO** order. + * Useful for inserting Phases "out of order". + * + * Is cleared whenever a phase ends, or when {@linkcode clearPhaseQueueSplice} is called. + * @defaultValue `-1` + */ private phaseQueuePrependSpliceIndex = -1; private nextCommandPhaseQueue: Phase[] = []; @@ -238,9 +253,14 @@ export class PhaseManager { constructor() { this.dynamicPhaseQueues = [new PostSummonPhasePriorityQueue()]; this.dynamicPhaseTypes = [PostSummonPhase]; - } + } /* Phase Functions */ - /* Phase Functions */ + /** + * Getter function to return the currently-in-progess {@linkcode Phase}. + * @returns The current Phase, or `null` if no phase is currently active. + * @remarks + * Type narrowing can be done by the caller using {@linkcode Phase.is}. + */ getCurrentPhase(): Phase | null { return this.currentPhase; } @@ -255,18 +275,17 @@ export class PhaseManager { * This method allows deferring the execution of a phase until certain conditions are met, which is useful for handling * situations like abilities and entry hazards that depend on specific game states. * - * @param phase - The phase to be added to the conditional queue. + * @param phase - The {@linkcode Phase} to add to the conditional queue. * @param condition - A function that returns a boolean indicating whether the phase should be executed. - * */ pushConditionalPhase(phase: Phase, condition: () => boolean): void { this.conditionalQueue.push([condition, phase]); } /** - * Adds a phase to nextCommandPhaseQueue, as long as boolean passed in is false - * @param phase {@linkcode Phase} the phase to add - * @param defer boolean on which queue to add to, defaults to false, and adds to phaseQueue + * Add a phase to the end of the {@linkcode phaseQueue}. + * @param phase - The {@linkcode Phase} to be queued. + * @param defer If `true`, will add the phase to {@linkcode nextCommandPhaseQueue} instead of the normal {@linkcode phaseQueue}; default `false`. */ pushPhase(phase: Phase, defer = false): void { if (this.getDynamicPhaseType(phase) !== undefined) { @@ -277,8 +296,13 @@ export class PhaseManager { } /** - * Adds Phase(s) to the end of phaseQueuePrepend, or at phaseQueuePrependSpliceIndex - * @param phases {@linkcode Phase} the phase(s) to add + * Adds one or more phase(s) to the **END** of {@linkcode phaseQueuePrepend}. + * If called multiple times, phases will be ran in **FIFO** order. + * @param phases - One or more {@linkcode Phase}s to add. + * @todo Find a better name for this given that "unshift" implies adding to the front. + * @remarks + * If {@linkcode phaseQueuePrependSpliceIndex} is set, the phases will be inserted at that index + * in **LIFO** order. */ unshiftPhase(...phases: Phase[]): void { if (this.phaseQueuePrependSpliceIndex === -1) { @@ -337,14 +361,8 @@ export class PhaseManager { if (this.phaseQueuePrependSpliceIndex > -1) { this.clearPhaseQueueSplice(); } - if (this.phaseQueuePrepend.length) { - while (this.phaseQueuePrepend.length) { - const poppedPhase = this.phaseQueuePrepend.pop(); - if (poppedPhase) { - this.phaseQueue.unshift(poppedPhase); - } - } - } + this.phaseQueue.unshift(...this.phaseQueuePrepend); + if (!this.phaseQueue.length) { this.populatePhaseQueue(); // Clear the conditionalQueue if there are no phases left in the phaseQueue @@ -370,11 +388,15 @@ export class PhaseManager { } } this.conditionalQueue.push(...unactivatedConditionalPhases); + this.startCurrentPhase(); + } - if (this.currentPhase) { - console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;"); - this.currentPhase.start(); + private startCurrentPhase(): void { + if (!this.currentPhase) { + return; } + console.log(`%cStart Phase ${this.currentPhase.phaseName}`, "color:green;"); + this.currentPhase.start(); } overridePhase(phase: Phase): boolean { @@ -384,8 +406,7 @@ export class PhaseManager { this.standbyPhase = this.currentPhase; this.currentPhase = phase; - console.log(`%cStart Phase ${phase.constructor.name}`, "color:green;"); - phase.start(); + this.startCurrentPhase(); return true; } diff --git a/src/phase.ts b/src/phase.ts index 5e81679d29e..54c439b6644 100644 --- a/src/phase.ts +++ b/src/phase.ts @@ -2,8 +2,10 @@ import { globalScene } from "#app/global-scene"; import type { PhaseMap, PhaseString } from "./@types/phase-types"; export abstract class Phase { + /** Start the current phase. */ start() {} + /** End the current phase and start a new one. */ end() { globalScene.phaseManager.shiftPhase(); } diff --git a/src/phases/check-status-effect-phase.ts b/src/phases/check-status-effect-phase.ts index 43495e038e9..45b600ff09e 100644 --- a/src/phases/check-status-effect-phase.ts +++ b/src/phases/check-status-effect-phase.ts @@ -11,12 +11,14 @@ export class CheckStatusEffectPhase extends Phase { } start() { + super.start(); + const field = globalScene.getField(); for (const o of this.order) { if (field[o].status?.isPostTurn()) { globalScene.phaseManager.unshiftNew("PostTurnStatusEffectPhase", o); } } - this.end(); + super.end(); } } diff --git a/src/phases/common-anim-phase.ts b/src/phases/common-anim-phase.ts index abfe8ed99f0..f4a9afc3587 100644 --- a/src/phases/common-anim-phase.ts +++ b/src/phases/common-anim-phase.ts @@ -30,6 +30,7 @@ export class CommonAnimPhase extends PokemonPhase { } start() { + super.start(); const target = this.targetIndex !== undefined ? (this.player ? globalScene.getEnemyField() : globalScene.getPlayerField())[this.targetIndex] diff --git a/src/phases/money-reward-phase.ts b/src/phases/money-reward-phase.ts index 52cb9ecb3ff..c3ebc5a864d 100644 --- a/src/phases/money-reward-phase.ts +++ b/src/phases/money-reward-phase.ts @@ -16,6 +16,7 @@ export class MoneyRewardPhase extends BattlePhase { } start() { + super.start(); const moneyAmount = new NumberHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier)); globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); diff --git a/src/phases/obtain-status-effect-phase.ts b/src/phases/obtain-status-effect-phase.ts index dc26d070029..d26bad2ed10 100644 --- a/src/phases/obtain-status-effect-phase.ts +++ b/src/phases/obtain-status-effect-phase.ts @@ -34,6 +34,8 @@ export class ObtainStatusEffectPhase extends PokemonPhase { } start() { + super.start(); + const pokemon = this.getPokemon(); if (pokemon && !pokemon.status) { if (pokemon.trySetStatus(this.statusEffect, false, this.sourcePokemon)) { diff --git a/src/phases/pokemon-heal-phase.ts b/src/phases/pokemon-heal-phase.ts index cf6cf40a923..5f263ed2a7b 100644 --- a/src/phases/pokemon-heal-phase.ts +++ b/src/phases/pokemon-heal-phase.ts @@ -48,9 +48,8 @@ export class PokemonHealPhase extends CommonAnimPhase { } start() { - if (!this.skipAnim && (this.revive || this.getPokemon().hp) && !this.getPokemon().isFullHp()) { - super.start(); - } else { + super.start(); + if (!(this.skipAnim && (this.revive || this.getPokemon().hp) && !this.getPokemon().isFullHp())) { this.end(); } } diff --git a/src/phases/post-summon-activate-ability-phase.ts b/src/phases/post-summon-activate-ability-phase.ts index ba6c80d4ee0..e647695cef5 100644 --- a/src/phases/post-summon-activate-ability-phase.ts +++ b/src/phases/post-summon-activate-ability-phase.ts @@ -16,6 +16,8 @@ export class PostSummonActivateAbilityPhase extends PostSummonPhase { } start() { + super.start(); + applyPostSummonAbAttrs("PostSummonAbAttr", this.getPokemon(), this.passive, false); this.end(); diff --git a/src/phases/post-turn-status-effect-phase.ts b/src/phases/post-turn-status-effect-phase.ts index e0a3bb5c00b..fa5f3f8b204 100644 --- a/src/phases/post-turn-status-effect-phase.ts +++ b/src/phases/post-turn-status-effect-phase.ts @@ -18,6 +18,8 @@ export class PostTurnStatusEffectPhase extends PokemonPhase { } start() { + super.start(); + const pokemon = this.getPokemon(); if (pokemon?.isActive(true) && pokemon.status && pokemon.status.isPostTurn() && !pokemon.switchOutStatus) { pokemon.status.incrementTurn(); diff --git a/src/phases/stat-stage-change-phase.ts b/src/phases/stat-stage-change-phase.ts index e73f72f7a63..2398834b388 100644 --- a/src/phases/stat-stage-change-phase.ts +++ b/src/phases/stat-stage-change-phase.ts @@ -83,6 +83,7 @@ export class StatStageChangePhase extends PokemonPhase { return this.end(); } + super.start(); const pokemon = this.getPokemon(); let opponentPokemon: Pokemon | undefined; diff --git a/src/phases/trainer-victory-phase.ts b/src/phases/trainer-victory-phase.ts index 554b8109f02..5830fbde673 100644 --- a/src/phases/trainer-victory-phase.ts +++ b/src/phases/trainer-victory-phase.ts @@ -14,6 +14,8 @@ import { timedEventManager } from "#app/global-event-manager"; export class TrainerVictoryPhase extends BattlePhase { public readonly phaseName = "TrainerVictoryPhase"; start() { + super.start(); + globalScene.disableMenu = true; globalScene.playBgm(globalScene.currentBattle.trainer?.config.victoryBgm); diff --git a/src/phases/weather-effect-phase.ts b/src/phases/weather-effect-phase.ts index d9239220376..d609b1feccb 100644 --- a/src/phases/weather-effect-phase.ts +++ b/src/phases/weather-effect-phase.ts @@ -28,6 +28,7 @@ export class WeatherEffectPhase extends CommonAnimPhase { } start() { + super.start(); // Update weather state with any changes that occurred during the turn this.weather = globalScene?.arena?.weather;