Cleaned up a few phase files to call super.start

This commit is contained in:
Bertie690 2025-06-18 18:25:05 -04:00
parent b458d512f1
commit 3ab2fe83a5
12 changed files with 66 additions and 30 deletions

View File

@ -217,13 +217,28 @@ export type PhaseConstructorMap = typeof PHASES;
* PhaseManager is responsible for managing the phases in the battle scene * PhaseManager is responsible for managing the phases in the battle scene
*/ */
export class PhaseManager { 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 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[] = []; 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 phaseQueuePrependSpliceIndex = -1;
private nextCommandPhaseQueue: Phase[] = []; private nextCommandPhaseQueue: Phase[] = [];
@ -238,9 +253,14 @@ export class PhaseManager {
constructor() { constructor() {
this.dynamicPhaseQueues = [new PostSummonPhasePriorityQueue()]; this.dynamicPhaseQueues = [new PostSummonPhasePriorityQueue()];
this.dynamicPhaseTypes = [PostSummonPhase]; 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 { getCurrentPhase(): Phase | null {
return this.currentPhase; 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 * 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. * 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. * @param condition - A function that returns a boolean indicating whether the phase should be executed.
*
*/ */
pushConditionalPhase(phase: Phase, condition: () => boolean): void { pushConditionalPhase(phase: Phase, condition: () => boolean): void {
this.conditionalQueue.push([condition, phase]); this.conditionalQueue.push([condition, phase]);
} }
/** /**
* Adds a phase to nextCommandPhaseQueue, as long as boolean passed in is false * Add a phase to the end of the {@linkcode phaseQueue}.
* @param phase {@linkcode Phase} the phase to add * @param phase - The {@linkcode Phase} to be queued.
* @param defer boolean on which queue to add to, defaults to false, and adds to phaseQueue * @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 { pushPhase(phase: Phase, defer = false): void {
if (this.getDynamicPhaseType(phase) !== undefined) { if (this.getDynamicPhaseType(phase) !== undefined) {
@ -277,8 +296,13 @@ export class PhaseManager {
} }
/** /**
* Adds Phase(s) to the end of phaseQueuePrepend, or at phaseQueuePrependSpliceIndex * Adds one or more phase(s) to the **END** of {@linkcode phaseQueuePrepend}.
* @param phases {@linkcode Phase} the phase(s) to add * 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 { unshiftPhase(...phases: Phase[]): void {
if (this.phaseQueuePrependSpliceIndex === -1) { if (this.phaseQueuePrependSpliceIndex === -1) {
@ -337,14 +361,8 @@ export class PhaseManager {
if (this.phaseQueuePrependSpliceIndex > -1) { if (this.phaseQueuePrependSpliceIndex > -1) {
this.clearPhaseQueueSplice(); this.clearPhaseQueueSplice();
} }
if (this.phaseQueuePrepend.length) { this.phaseQueue.unshift(...this.phaseQueuePrepend);
while (this.phaseQueuePrepend.length) {
const poppedPhase = this.phaseQueuePrepend.pop();
if (poppedPhase) {
this.phaseQueue.unshift(poppedPhase);
}
}
}
if (!this.phaseQueue.length) { if (!this.phaseQueue.length) {
this.populatePhaseQueue(); this.populatePhaseQueue();
// Clear the conditionalQueue if there are no phases left in the phaseQueue // Clear the conditionalQueue if there are no phases left in the phaseQueue
@ -370,11 +388,15 @@ export class PhaseManager {
} }
} }
this.conditionalQueue.push(...unactivatedConditionalPhases); this.conditionalQueue.push(...unactivatedConditionalPhases);
this.startCurrentPhase();
}
if (this.currentPhase) { private startCurrentPhase(): void {
console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;"); if (!this.currentPhase) {
this.currentPhase.start(); return;
} }
console.log(`%cStart Phase ${this.currentPhase.phaseName}`, "color:green;");
this.currentPhase.start();
} }
overridePhase(phase: Phase): boolean { overridePhase(phase: Phase): boolean {
@ -384,8 +406,7 @@ export class PhaseManager {
this.standbyPhase = this.currentPhase; this.standbyPhase = this.currentPhase;
this.currentPhase = phase; this.currentPhase = phase;
console.log(`%cStart Phase ${phase.constructor.name}`, "color:green;"); this.startCurrentPhase();
phase.start();
return true; return true;
} }

View File

@ -2,8 +2,10 @@ import { globalScene } from "#app/global-scene";
import type { PhaseMap, PhaseString } from "./@types/phase-types"; import type { PhaseMap, PhaseString } from "./@types/phase-types";
export abstract class Phase { export abstract class Phase {
/** Start the current phase. */
start() {} start() {}
/** End the current phase and start a new one. */
end() { end() {
globalScene.phaseManager.shiftPhase(); globalScene.phaseManager.shiftPhase();
} }

View File

@ -11,12 +11,14 @@ export class CheckStatusEffectPhase extends Phase {
} }
start() { start() {
super.start();
const field = globalScene.getField(); const field = globalScene.getField();
for (const o of this.order) { for (const o of this.order) {
if (field[o].status?.isPostTurn()) { if (field[o].status?.isPostTurn()) {
globalScene.phaseManager.unshiftNew("PostTurnStatusEffectPhase", o); globalScene.phaseManager.unshiftNew("PostTurnStatusEffectPhase", o);
} }
} }
this.end(); super.end();
} }
} }

View File

@ -30,6 +30,7 @@ export class CommonAnimPhase extends PokemonPhase {
} }
start() { start() {
super.start();
const target = const target =
this.targetIndex !== undefined this.targetIndex !== undefined
? (this.player ? globalScene.getEnemyField() : globalScene.getPlayerField())[this.targetIndex] ? (this.player ? globalScene.getEnemyField() : globalScene.getPlayerField())[this.targetIndex]

View File

@ -16,6 +16,7 @@ export class MoneyRewardPhase extends BattlePhase {
} }
start() { start() {
super.start();
const moneyAmount = new NumberHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier)); const moneyAmount = new NumberHolder(globalScene.getWaveMoneyAmount(this.moneyMultiplier));
globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount); globalScene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);

View File

@ -34,6 +34,8 @@ export class ObtainStatusEffectPhase extends PokemonPhase {
} }
start() { start() {
super.start();
const pokemon = this.getPokemon(); const pokemon = this.getPokemon();
if (pokemon && !pokemon.status) { if (pokemon && !pokemon.status) {
if (pokemon.trySetStatus(this.statusEffect, false, this.sourcePokemon)) { if (pokemon.trySetStatus(this.statusEffect, false, this.sourcePokemon)) {

View File

@ -48,9 +48,8 @@ export class PokemonHealPhase extends CommonAnimPhase {
} }
start() { start() {
if (!this.skipAnim && (this.revive || this.getPokemon().hp) && !this.getPokemon().isFullHp()) { super.start();
super.start(); if (!(this.skipAnim && (this.revive || this.getPokemon().hp) && !this.getPokemon().isFullHp())) {
} else {
this.end(); this.end();
} }
} }

View File

@ -16,6 +16,8 @@ export class PostSummonActivateAbilityPhase extends PostSummonPhase {
} }
start() { start() {
super.start();
applyPostSummonAbAttrs("PostSummonAbAttr", this.getPokemon(), this.passive, false); applyPostSummonAbAttrs("PostSummonAbAttr", this.getPokemon(), this.passive, false);
this.end(); this.end();

View File

@ -18,6 +18,8 @@ export class PostTurnStatusEffectPhase extends PokemonPhase {
} }
start() { start() {
super.start();
const pokemon = this.getPokemon(); const pokemon = this.getPokemon();
if (pokemon?.isActive(true) && pokemon.status && pokemon.status.isPostTurn() && !pokemon.switchOutStatus) { if (pokemon?.isActive(true) && pokemon.status && pokemon.status.isPostTurn() && !pokemon.switchOutStatus) {
pokemon.status.incrementTurn(); pokemon.status.incrementTurn();

View File

@ -83,6 +83,7 @@ export class StatStageChangePhase extends PokemonPhase {
return this.end(); return this.end();
} }
super.start();
const pokemon = this.getPokemon(); const pokemon = this.getPokemon();
let opponentPokemon: Pokemon | undefined; let opponentPokemon: Pokemon | undefined;

View File

@ -14,6 +14,8 @@ import { timedEventManager } from "#app/global-event-manager";
export class TrainerVictoryPhase extends BattlePhase { export class TrainerVictoryPhase extends BattlePhase {
public readonly phaseName = "TrainerVictoryPhase"; public readonly phaseName = "TrainerVictoryPhase";
start() { start() {
super.start();
globalScene.disableMenu = true; globalScene.disableMenu = true;
globalScene.playBgm(globalScene.currentBattle.trainer?.config.victoryBgm); globalScene.playBgm(globalScene.currentBattle.trainer?.config.victoryBgm);

View File

@ -28,6 +28,7 @@ export class WeatherEffectPhase extends CommonAnimPhase {
} }
start() { start() {
super.start();
// Update weather state with any changes that occurred during the turn // Update weather state with any changes that occurred during the turn
this.weather = globalScene?.arena?.weather; this.weather = globalScene?.arena?.weather;