mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-03 23:12:20 +02:00
Add dynamic queue manager
This commit is contained in:
parent
5f098545f5
commit
0121589d6f
@ -193,6 +193,7 @@ import { AiType } from "#enums/ai-type";
|
||||
import type { MoveResult } from "#enums/move-result";
|
||||
import { PokemonMove } from "#app/data/moves/pokemon-move";
|
||||
import type { AbAttrMap, AbAttrString } from "#app/@types/ability-types";
|
||||
import type { TurnCommand } from "#app/battle";
|
||||
|
||||
/** Base typeclass for damage parameter methods, used for DRY */
|
||||
type damageParams = {
|
||||
@ -6868,6 +6869,7 @@ export class PokemonWaveData {
|
||||
* Resets at the start of a new turn, as well as on switch.
|
||||
*/
|
||||
export class PokemonTurnData {
|
||||
public turnCommand?: TurnCommand;
|
||||
public flinched = false;
|
||||
public acted = false;
|
||||
/** How many times the current move should hit the target(s) */
|
||||
|
@ -12,9 +12,8 @@ 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 { coerceArray, type Constructor } from "#app/utils/common";
|
||||
import { coerceArray } 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";
|
||||
@ -58,7 +57,6 @@ 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";
|
||||
@ -99,6 +97,7 @@ import { UnavailablePhase } from "#app/phases/unavailable-phase";
|
||||
import { UnlockPhase } from "#app/phases/unlock-phase";
|
||||
import { VictoryPhase } from "#app/phases/victory-phase";
|
||||
import { WeatherEffectPhase } from "#app/phases/weather-effect-phase";
|
||||
import { DynamicQueueManager } from "#app/queues/dynamic-queue-manager";
|
||||
|
||||
/**
|
||||
* Manager for phases used by battle scene.
|
||||
@ -227,19 +226,11 @@ 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 dynamicQueueManager = new DynamicQueueManager();
|
||||
|
||||
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;
|
||||
@ -269,7 +260,7 @@ 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 {
|
||||
if (this.getDynamicPhaseType(phase) !== undefined) {
|
||||
if (this.dynamicQueueManager.isDynamicPhase(phase.phaseName)) {
|
||||
this.pushDynamicPhase(phase);
|
||||
} else {
|
||||
(!defer ? this.phaseQueue : this.nextCommandPhaseQueue).push(phase);
|
||||
@ -302,7 +293,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.dynamicQueueManager.clearQueues();
|
||||
this.currentPhase = null;
|
||||
this.standbyPhase = null;
|
||||
this.clearPhaseQueueSplice();
|
||||
@ -470,22 +461,6 @@ 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}
|
||||
*
|
||||
@ -493,21 +468,16 @@ export class PhaseManager {
|
||||
* @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);
|
||||
this.pushNew("ActivatePriorityQueuePhase", phase.phaseName);
|
||||
this.dynamicQueueManager.queueDynamicPhase(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();
|
||||
public startNextDynamicPhaseOfType(type: PhaseString): void {
|
||||
const phase = this.dynamicQueueManager.popNextPhaseOfType(type);
|
||||
if (phase) {
|
||||
this.unshiftPhase(phase);
|
||||
}
|
||||
@ -523,13 +493,8 @@ export class PhaseManager {
|
||||
* @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);
|
||||
this.unshiftNew("ActivatePriorityQueuePhase", phase.phaseName);
|
||||
this.dynamicQueueManager.queueDynamicPhase(phase);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,23 +1,23 @@
|
||||
import type { DynamicPhaseType } from "#enums/dynamic-phase-type";
|
||||
import type { PhaseString } from "#app/@types/phase-types";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { Phase } from "#app/phase";
|
||||
|
||||
export class ActivatePriorityQueuePhase extends Phase {
|
||||
public readonly phaseName = "ActivatePriorityQueuePhase";
|
||||
private type: DynamicPhaseType;
|
||||
private readonly type: PhaseString;
|
||||
|
||||
constructor(type: DynamicPhaseType) {
|
||||
constructor(type: PhaseString) {
|
||||
super();
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
override start() {
|
||||
super.start();
|
||||
globalScene.phaseManager.startDynamicPhaseType(this.type);
|
||||
globalScene.phaseManager.startNextDynamicPhaseOfType(this.type);
|
||||
this.end();
|
||||
}
|
||||
|
||||
public getType(): DynamicPhaseType {
|
||||
public getType(): PhaseString {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import type Pokemon from "#app/field/pokemon";
|
||||
import { MoveResult } from "#enums/move-result";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import Overrides from "#app/overrides";
|
||||
import { BattlePhase } from "#app/phases/battle-phase";
|
||||
import { NumberHolder } from "#app/utils/common";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||
@ -28,8 +27,9 @@ import { MoveId } from "#enums/move-id";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import i18next from "i18next";
|
||||
import { frenzyMissFunc } from "#app/data/moves/move-utils";
|
||||
import { PokemonPhase } from "#app/phases/pokemon-phase";
|
||||
|
||||
export class MovePhase extends BattlePhase {
|
||||
export class MovePhase extends PokemonPhase {
|
||||
public readonly phaseName = "MovePhase";
|
||||
protected _pokemon: Pokemon;
|
||||
protected _move: PokemonMove;
|
||||
@ -81,7 +81,7 @@ export class MovePhase extends BattlePhase {
|
||||
reflected = false,
|
||||
forcedLast = false,
|
||||
) {
|
||||
super();
|
||||
super(pokemon.getBattlerIndex());
|
||||
|
||||
this.pokemon = pokemon;
|
||||
this.targets = targets;
|
||||
|
@ -69,7 +69,7 @@ export class TurnStartPhase extends FieldPhase {
|
||||
applyAbAttrs("BypassSpeedChanceAbAttr", p, null, false, bypassSpeed);
|
||||
applyAbAttrs("PreventBypassSpeedChanceAbAttr", p, null, false, bypassSpeed, canCheckHeldItems);
|
||||
if (canCheckHeldItems.value) {
|
||||
globalScene.applyModifiers(BypassSpeedChanceModifier, p.isPlayer(), p, bypassSpeed);
|
||||
globalScene.applyModifiers(BypassSpeedChanceModifier, p.isPlayer(), p);
|
||||
}
|
||||
battlerBypassSpeed[p.getBattlerIndex()] = bypassSpeed;
|
||||
});
|
||||
|
35
src/queues/dynamic-queue-manager.ts
Normal file
35
src/queues/dynamic-queue-manager.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import type { PhaseString } from "#app/@types/phase-types";
|
||||
import type { Phase } from "#app/phase";
|
||||
import type { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
|
||||
import { MovePhasePriorityQueue } from "#app/queues/move-phase-priority-queue";
|
||||
import type { PhasePriorityQueue } from "#app/queues/phase-priority-queue";
|
||||
import { PokemonPhasePriorityQueue } from "#app/queues/pokemon-phase-priority-queue";
|
||||
import { PostSummonPhasePriorityQueue } from "#app/queues/post-summon-phase-priority-queue";
|
||||
export class DynamicQueueManager {
|
||||
private dynamicPhaseMap: Map<PhaseString, PhasePriorityQueue<Phase>>;
|
||||
|
||||
constructor() {
|
||||
this.dynamicPhaseMap = new Map();
|
||||
this.dynamicPhaseMap.set("SwitchSummonPhase", new PokemonPhasePriorityQueue<SwitchSummonPhase>());
|
||||
this.dynamicPhaseMap.set("PostSummonPhase", new PostSummonPhasePriorityQueue());
|
||||
this.dynamicPhaseMap.set("MovePhase", new MovePhasePriorityQueue());
|
||||
}
|
||||
|
||||
public clearQueues(): void {
|
||||
for (const queue of this.dynamicPhaseMap.values()) {
|
||||
queue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public queueDynamicPhase(phase: Phase): void {
|
||||
this.dynamicPhaseMap.get(phase.phaseName)?.push(phase);
|
||||
}
|
||||
|
||||
public popNextPhaseOfType(type: PhaseString): Phase | undefined {
|
||||
return this.dynamicPhaseMap.get(type)?.pop();
|
||||
}
|
||||
|
||||
public isDynamicPhase(type: PhaseString): boolean {
|
||||
return this.dynamicPhaseMap.has(type);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user