mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 07:22:19 +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 type { MoveResult } from "#enums/move-result";
|
||||||
import { PokemonMove } from "#app/data/moves/pokemon-move";
|
import { PokemonMove } from "#app/data/moves/pokemon-move";
|
||||||
import type { AbAttrMap, AbAttrString } from "#app/@types/ability-types";
|
import type { AbAttrMap, AbAttrString } from "#app/@types/ability-types";
|
||||||
|
import type { TurnCommand } from "#app/battle";
|
||||||
|
|
||||||
/** Base typeclass for damage parameter methods, used for DRY */
|
/** Base typeclass for damage parameter methods, used for DRY */
|
||||||
type damageParams = {
|
type damageParams = {
|
||||||
@ -6868,6 +6869,7 @@ export class PokemonWaveData {
|
|||||||
* Resets at the start of a new turn, as well as on switch.
|
* Resets at the start of a new turn, as well as on switch.
|
||||||
*/
|
*/
|
||||||
export class PokemonTurnData {
|
export class PokemonTurnData {
|
||||||
|
public turnCommand?: TurnCommand;
|
||||||
public flinched = false;
|
public flinched = false;
|
||||||
public acted = false;
|
public acted = false;
|
||||||
/** How many times the current move should hit the target(s) */
|
/** 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 { CheckSwitchPhase } from "#app/phases/check-switch-phase";
|
||||||
import { CommandPhase } from "#app/phases/command-phase";
|
import { CommandPhase } from "#app/phases/command-phase";
|
||||||
import { CommonAnimPhase } from "#app/phases/common-anim-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 { DamageAnimPhase } from "#app/phases/damage-anim-phase";
|
||||||
import type { DynamicPhaseType } from "#enums/dynamic-phase-type";
|
|
||||||
import { EggHatchPhase } from "#app/phases/egg-hatch-phase";
|
import { EggHatchPhase } from "#app/phases/egg-hatch-phase";
|
||||||
import { EggLapsePhase } from "#app/phases/egg-lapse-phase";
|
import { EggLapsePhase } from "#app/phases/egg-lapse-phase";
|
||||||
import { EggSummaryPhase } from "#app/phases/egg-summary-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 { ObtainStatusEffectPhase } from "#app/phases/obtain-status-effect-phase";
|
||||||
import { PartyExpPhase } from "#app/phases/party-exp-phase";
|
import { PartyExpPhase } from "#app/phases/party-exp-phase";
|
||||||
import { PartyHealPhase } from "#app/phases/party-heal-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 { PokemonAnimPhase } from "#app/phases/pokemon-anim-phase";
|
||||||
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
|
||||||
import { PokemonTransformPhase } from "#app/phases/pokemon-transform-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 { UnlockPhase } from "#app/phases/unlock-phase";
|
||||||
import { VictoryPhase } from "#app/phases/victory-phase";
|
import { VictoryPhase } from "#app/phases/victory-phase";
|
||||||
import { WeatherEffectPhase } from "#app/phases/weather-effect-phase";
|
import { WeatherEffectPhase } from "#app/phases/weather-effect-phase";
|
||||||
|
import { DynamicQueueManager } from "#app/queues/dynamic-queue-manager";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for phases used by battle scene.
|
* Manager for phases used by battle scene.
|
||||||
@ -227,19 +226,11 @@ export class PhaseManager {
|
|||||||
private phaseQueuePrependSpliceIndex = -1;
|
private phaseQueuePrependSpliceIndex = -1;
|
||||||
private nextCommandPhaseQueue: Phase[] = [];
|
private nextCommandPhaseQueue: Phase[] = [];
|
||||||
|
|
||||||
/** Storage for {@linkcode PhasePriorityQueue}s which hold phases whose order dynamically changes */
|
private dynamicQueueManager = new DynamicQueueManager();
|
||||||
private dynamicPhaseQueues: PhasePriorityQueue[];
|
|
||||||
/** Parallel array to {@linkcode dynamicPhaseQueues} - matches phase types to their queues */
|
|
||||||
private dynamicPhaseTypes: Constructor<Phase>[];
|
|
||||||
|
|
||||||
private currentPhase: Phase | null = null;
|
private currentPhase: Phase | null = null;
|
||||||
private standbyPhase: Phase | null = null;
|
private standbyPhase: Phase | null = null;
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.dynamicPhaseQueues = [new PostSummonPhasePriorityQueue()];
|
|
||||||
this.dynamicPhaseTypes = [PostSummonPhase];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Phase Functions */
|
/* Phase Functions */
|
||||||
getCurrentPhase(): Phase | null {
|
getCurrentPhase(): Phase | null {
|
||||||
return this.currentPhase;
|
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
|
* @param defer boolean on which queue to add to, defaults to false, and adds to phaseQueue
|
||||||
*/
|
*/
|
||||||
pushPhase(phase: Phase, defer = false): void {
|
pushPhase(phase: Phase, defer = false): void {
|
||||||
if (this.getDynamicPhaseType(phase) !== undefined) {
|
if (this.dynamicQueueManager.isDynamicPhase(phase.phaseName)) {
|
||||||
this.pushDynamicPhase(phase);
|
this.pushDynamicPhase(phase);
|
||||||
} else {
|
} else {
|
||||||
(!defer ? this.phaseQueue : this.nextCommandPhaseQueue).push(phase);
|
(!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]) {
|
for (const queue of [this.phaseQueue, this.phaseQueuePrepend, this.conditionalQueue, this.nextCommandPhaseQueue]) {
|
||||||
queue.splice(0, queue.length);
|
queue.splice(0, queue.length);
|
||||||
}
|
}
|
||||||
this.dynamicPhaseQueues.forEach(queue => queue.clear());
|
this.dynamicQueueManager.clearQueues();
|
||||||
this.currentPhase = null;
|
this.currentPhase = null;
|
||||||
this.standbyPhase = null;
|
this.standbyPhase = null;
|
||||||
this.clearPhaseQueueSplice();
|
this.clearPhaseQueueSplice();
|
||||||
@ -470,22 +461,6 @@ export class PhaseManager {
|
|||||||
return false;
|
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}
|
* 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
|
* @param phase The phase to push
|
||||||
*/
|
*/
|
||||||
public pushDynamicPhase(phase: Phase): void {
|
public pushDynamicPhase(phase: Phase): void {
|
||||||
const type = this.getDynamicPhaseType(phase);
|
this.pushNew("ActivatePriorityQueuePhase", phase.phaseName);
|
||||||
if (type === undefined) {
|
this.dynamicQueueManager.queueDynamicPhase(phase);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.pushPhase(new ActivatePriorityQueuePhase(type));
|
|
||||||
this.dynamicPhaseQueues[type].push(phase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unshifts the top phase from the corresponding dynamic queue onto {@linkcode phaseQueue}
|
* Unshifts the top phase from the corresponding dynamic queue onto {@linkcode phaseQueue}
|
||||||
* @param type {@linkcode DynamicPhaseType} The type of dynamic phase to start
|
* @param type {@linkcode DynamicPhaseType} The type of dynamic phase to start
|
||||||
*/
|
*/
|
||||||
public startDynamicPhaseType(type: DynamicPhaseType): void {
|
public startNextDynamicPhaseOfType(type: PhaseString): void {
|
||||||
const phase = this.dynamicPhaseQueues[type].pop();
|
const phase = this.dynamicQueueManager.popNextPhaseOfType(type);
|
||||||
if (phase) {
|
if (phase) {
|
||||||
this.unshiftPhase(phase);
|
this.unshiftPhase(phase);
|
||||||
}
|
}
|
||||||
@ -523,13 +493,8 @@ export class PhaseManager {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public startDynamicPhase(phase: Phase): void {
|
public startDynamicPhase(phase: Phase): void {
|
||||||
const type = this.getDynamicPhaseType(phase);
|
this.unshiftNew("ActivatePriorityQueuePhase", phase.phaseName);
|
||||||
if (type === undefined) {
|
this.dynamicQueueManager.queueDynamicPhase(phase);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.unshiftPhase(new ActivatePriorityQueuePhase(type));
|
|
||||||
this.dynamicPhaseQueues[type].push(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 { globalScene } from "#app/global-scene";
|
||||||
import { Phase } from "#app/phase";
|
import { Phase } from "#app/phase";
|
||||||
|
|
||||||
export class ActivatePriorityQueuePhase extends Phase {
|
export class ActivatePriorityQueuePhase extends Phase {
|
||||||
public readonly phaseName = "ActivatePriorityQueuePhase";
|
public readonly phaseName = "ActivatePriorityQueuePhase";
|
||||||
private type: DynamicPhaseType;
|
private readonly type: PhaseString;
|
||||||
|
|
||||||
constructor(type: DynamicPhaseType) {
|
constructor(type: PhaseString) {
|
||||||
super();
|
super();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
override start() {
|
override start() {
|
||||||
super.start();
|
super.start();
|
||||||
globalScene.phaseManager.startDynamicPhaseType(this.type);
|
globalScene.phaseManager.startNextDynamicPhaseOfType(this.type);
|
||||||
this.end();
|
this.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getType(): DynamicPhaseType {
|
public getType(): PhaseString {
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import type Pokemon from "#app/field/pokemon";
|
|||||||
import { MoveResult } from "#enums/move-result";
|
import { MoveResult } from "#enums/move-result";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { BattlePhase } from "#app/phases/battle-phase";
|
|
||||||
import { NumberHolder } from "#app/utils/common";
|
import { NumberHolder } from "#app/utils/common";
|
||||||
import { AbilityId } from "#enums/ability-id";
|
import { AbilityId } from "#enums/ability-id";
|
||||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||||
@ -28,8 +27,9 @@ import { MoveId } from "#enums/move-id";
|
|||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { frenzyMissFunc } from "#app/data/moves/move-utils";
|
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";
|
public readonly phaseName = "MovePhase";
|
||||||
protected _pokemon: Pokemon;
|
protected _pokemon: Pokemon;
|
||||||
protected _move: PokemonMove;
|
protected _move: PokemonMove;
|
||||||
@ -81,7 +81,7 @@ export class MovePhase extends BattlePhase {
|
|||||||
reflected = false,
|
reflected = false,
|
||||||
forcedLast = false,
|
forcedLast = false,
|
||||||
) {
|
) {
|
||||||
super();
|
super(pokemon.getBattlerIndex());
|
||||||
|
|
||||||
this.pokemon = pokemon;
|
this.pokemon = pokemon;
|
||||||
this.targets = targets;
|
this.targets = targets;
|
||||||
|
@ -69,7 +69,7 @@ export class TurnStartPhase extends FieldPhase {
|
|||||||
applyAbAttrs("BypassSpeedChanceAbAttr", p, null, false, bypassSpeed);
|
applyAbAttrs("BypassSpeedChanceAbAttr", p, null, false, bypassSpeed);
|
||||||
applyAbAttrs("PreventBypassSpeedChanceAbAttr", p, null, false, bypassSpeed, canCheckHeldItems);
|
applyAbAttrs("PreventBypassSpeedChanceAbAttr", p, null, false, bypassSpeed, canCheckHeldItems);
|
||||||
if (canCheckHeldItems.value) {
|
if (canCheckHeldItems.value) {
|
||||||
globalScene.applyModifiers(BypassSpeedChanceModifier, p.isPlayer(), p, bypassSpeed);
|
globalScene.applyModifiers(BypassSpeedChanceModifier, p.isPlayer(), p);
|
||||||
}
|
}
|
||||||
battlerBypassSpeed[p.getBattlerIndex()] = bypassSpeed;
|
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