mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 07:22:19 +02:00
Update PhaseManager
This commit is contained in:
parent
69d88b7cd9
commit
9fcd35e2b7
@ -2,6 +2,7 @@ import type { Phase } from "#app/phase";
|
||||
import type { default as Pokemon } from "#app/field/pokemon";
|
||||
import type { PhaseMap, PhaseString } from "./@types/phase-types";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { ActivatePriorityQueuePhase } from "#app/phases/activate-priority-queue-phase";
|
||||
import { AddEnemyBuffModifierPhase } from "#app/phases/add-enemy-buff-modifier-phase";
|
||||
import { AttemptCapturePhase } from "#app/phases/attempt-capture-phase";
|
||||
import { AttemptRunPhase } from "#app/phases/attempt-run-phase";
|
||||
@ -11,7 +12,9 @@ import { CheckStatusEffectPhase } from "#app/phases/check-status-effect-phase";
|
||||
import { CheckSwitchPhase } from "#app/phases/check-switch-phase";
|
||||
import { CommandPhase } from "#app/phases/command-phase";
|
||||
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
|
||||
import type { Constructor } from "#app/utils/common";
|
||||
import { DamageAnimPhase } from "#app/phases/damage-anim-phase";
|
||||
import type { DynamicPhaseType } from "#enums/dynamic-phase-type";
|
||||
import { EggHatchPhase } from "#app/phases/egg-hatch-phase";
|
||||
import { EggLapsePhase } from "#app/phases/egg-lapse-phase";
|
||||
import { EggSummaryPhase } from "#app/phases/egg-summary-phase";
|
||||
@ -55,6 +58,7 @@ import { NextEncounterPhase } from "#app/phases/next-encounter-phase";
|
||||
import { ObtainStatusEffectPhase } from "#app/phases/obtain-status-effect-phase";
|
||||
import { PartyExpPhase } from "#app/phases/party-exp-phase";
|
||||
import { PartyHealPhase } from "#app/phases/party-heal-phase";
|
||||
import { type PhasePriorityQueue, PostSummonPhasePriorityQueue } from "#app/data/phase-priority-queue";
|
||||
import { PokemonAnimPhase } from "#app/phases/pokemon-anim-phase";
|
||||
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
||||
import { PokemonTransformPhase } from "#app/phases/pokemon-transform-phase";
|
||||
@ -222,9 +226,19 @@ export class PhaseManager {
|
||||
private phaseQueuePrependSpliceIndex = -1;
|
||||
private nextCommandPhaseQueue: Phase[] = [];
|
||||
|
||||
/** Storage for {@linkcode PhasePriorityQueue}s which hold phases whose order dynamically changes */
|
||||
private dynamicPhaseQueues: PhasePriorityQueue[];
|
||||
/** Parallel array to {@linkcode dynamicPhaseQueues} - matches phase types to their queues */
|
||||
private dynamicPhaseTypes: Constructor<Phase>[];
|
||||
|
||||
private currentPhase: Phase | null = null;
|
||||
private standbyPhase: Phase | null = null;
|
||||
|
||||
constructor() {
|
||||
this.dynamicPhaseQueues = [new PostSummonPhasePriorityQueue()];
|
||||
this.dynamicPhaseTypes = [PostSummonPhase];
|
||||
}
|
||||
|
||||
/* Phase Functions */
|
||||
getCurrentPhase(): Phase | null {
|
||||
return this.currentPhase;
|
||||
@ -254,7 +268,11 @@ export class PhaseManager {
|
||||
* @param defer boolean on which queue to add to, defaults to false, and adds to phaseQueue
|
||||
*/
|
||||
pushPhase(phase: Phase, defer = false): void {
|
||||
(!defer ? this.phaseQueue : this.nextCommandPhaseQueue).push(phase);
|
||||
if (this.getDynamicPhaseType(phase) !== undefined) {
|
||||
this.pushDynamicPhase(phase);
|
||||
} else {
|
||||
(!defer ? this.phaseQueue : this.nextCommandPhaseQueue).push(phase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -283,6 +301,7 @@ export class PhaseManager {
|
||||
for (const queue of [this.phaseQueue, this.phaseQueuePrepend, this.conditionalQueue, this.nextCommandPhaseQueue]) {
|
||||
queue.splice(0, queue.length);
|
||||
}
|
||||
this.dynamicPhaseQueues.forEach(queue => queue.clear());
|
||||
this.currentPhase = null;
|
||||
this.standbyPhase = null;
|
||||
this.clearPhaseQueueSplice();
|
||||
@ -333,8 +352,9 @@ export class PhaseManager {
|
||||
|
||||
this.currentPhase = this.phaseQueue.shift() ?? null;
|
||||
|
||||
const unactivatedConditionalPhases: [() => boolean, Phase][] = [];
|
||||
// Check if there are any conditional phases queued
|
||||
if (this.conditionalQueue?.length) {
|
||||
while (this.conditionalQueue?.length) {
|
||||
// Retrieve the first conditional phase from the queue
|
||||
const conditionalPhase = this.conditionalQueue.shift();
|
||||
// Evaluate the condition associated with the phase
|
||||
@ -343,11 +363,12 @@ export class PhaseManager {
|
||||
this.pushPhase(conditionalPhase[1]);
|
||||
} else if (conditionalPhase) {
|
||||
// If the condition is not met, re-add the phase back to the front of the conditional queue
|
||||
this.conditionalQueue.unshift(conditionalPhase);
|
||||
unactivatedConditionalPhases.push(conditionalPhase);
|
||||
} else {
|
||||
console.warn("condition phase is undefined/null!", conditionalPhase);
|
||||
}
|
||||
}
|
||||
this.conditionalQueue.push(...unactivatedConditionalPhases);
|
||||
|
||||
if (this.currentPhase) {
|
||||
console.log(`%cStart Phase ${this.currentPhase.constructor.name}`, "color:green;");
|
||||
@ -431,17 +452,18 @@ export class PhaseManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to add the input phase(s) to index after target phase in the {@linkcode phaseQueue}, else simply calls {@linkcode unshiftPhase()}
|
||||
* @param phase - The phase(s) to be added
|
||||
* @param targetPhase - The phase to search for in phaseQueue
|
||||
* Tries to add the input phase(s) to index after target phase in the {@linkcode phaseQueue}, else simply calls {@linkcode unshiftPhase()}
|
||||
* @param phase {@linkcode Phase} the phase(s) to be added
|
||||
* @param targetPhase {@linkcode Phase} the type of phase to search for in {@linkcode phaseQueue}
|
||||
* @param condition Condition the target phase must meet to be appended to
|
||||
* @returns `true` if a `targetPhase` was found to append to
|
||||
*/
|
||||
appendToPhase(phase: Phase | Phase[], targetPhase: PhaseString): boolean {
|
||||
appendToPhase(phase: Phase | Phase[], targetPhase: PhaseString, condition?: (p: Phase) => boolean): boolean {
|
||||
if (!Array.isArray(phase)) {
|
||||
phase = [phase];
|
||||
}
|
||||
const target = PHASES[targetPhase];
|
||||
const targetIndex = this.phaseQueue.findIndex(ph => ph instanceof target);
|
||||
const targetIndex = this.phaseQueue.findIndex(ph => ph instanceof target && (!condition || condition(ph)));
|
||||
|
||||
if (targetIndex !== -1 && this.phaseQueue.length > targetIndex) {
|
||||
this.phaseQueue.splice(targetIndex + 1, 0, ...phase);
|
||||
@ -451,6 +473,68 @@ export class PhaseManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a phase and returns the matching {@linkcode DynamicPhaseType}, or undefined if it does not match one
|
||||
* @param phase The phase to check
|
||||
* @returns The corresponding {@linkcode DynamicPhaseType} or `undefined`
|
||||
*/
|
||||
public getDynamicPhaseType(phase: Phase | null): DynamicPhaseType | undefined {
|
||||
let phaseType: DynamicPhaseType | undefined;
|
||||
this.dynamicPhaseTypes.forEach((cls, index) => {
|
||||
if (phase instanceof cls) {
|
||||
phaseType = index;
|
||||
}
|
||||
});
|
||||
|
||||
return phaseType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes a phase onto its corresponding dynamic queue and marks the activation point in {@linkcode phaseQueue}
|
||||
*
|
||||
* The {@linkcode ActivatePriorityQueuePhase} will run the top phase in the dynamic queue (not necessarily {@linkcode phase})
|
||||
* @param phase The phase to push
|
||||
*/
|
||||
public pushDynamicPhase(phase: Phase): void {
|
||||
const type = this.getDynamicPhaseType(phase);
|
||||
if (type === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.pushPhase(new ActivatePriorityQueuePhase(type));
|
||||
this.dynamicPhaseQueues[type].push(phase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unshifts the top phase from the corresponding dynamic queue onto {@linkcode phaseQueue}
|
||||
* @param type {@linkcode DynamicPhaseType} The type of dynamic phase to start
|
||||
*/
|
||||
public startDynamicPhaseType(type: DynamicPhaseType): void {
|
||||
const phase = this.dynamicPhaseQueues[type].pop();
|
||||
if (phase) {
|
||||
this.unshiftPhase(phase);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unshifts an {@linkcode ActivatePriorityQueuePhase} for {@linkcode phase}, then pushes {@linkcode phase} to its dynamic queue
|
||||
*
|
||||
* This is the same as {@linkcode pushDynamicPhase}, except the activation phase is unshifted
|
||||
*
|
||||
* {@linkcode phase} is not guaranteed to be the next phase from the queue to run (if the queue is not empty)
|
||||
* @param phase The phase to add
|
||||
* @returns
|
||||
*/
|
||||
public startDynamicPhase(phase: Phase): void {
|
||||
const type = this.getDynamicPhaseType(phase);
|
||||
if (type === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.unshiftPhase(new ActivatePriorityQueuePhase(type));
|
||||
this.dynamicPhaseQueues[type].push(phase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a MessagePhase, either to PhaseQueuePrepend or nextCommandPhaseQueue
|
||||
* @param message - string for MessagePhase
|
||||
|
Loading…
Reference in New Issue
Block a user