Fix turn order tracking

This commit is contained in:
Dean 2025-06-15 23:05:09 -07:00
parent 3aa1940a8d
commit c790f2e84f
5 changed files with 39 additions and 29 deletions

View File

@ -4429,28 +4429,7 @@ export class LastMoveDoublePowerAttr extends VariablePowerAttr {
*/ */
apply(user: Pokemon, _target: Pokemon, _move: Move, args: any[]): boolean { apply(user: Pokemon, _target: Pokemon, _move: Move, args: any[]): boolean {
const power = args[0] as NumberHolder; const power = args[0] as NumberHolder;
const enemy = user.getOpponent(0); for (const p of globalScene.phaseManager.dynamicQueueManager.getLastTurnOrder().slice(0, -1).reverse()) {
const pokemonActed: Pokemon[] = [];
if (enemy?.turnData.acted) {
pokemonActed.push(enemy);
}
if (globalScene.currentBattle.double) {
const userAlly = user.getAlly();
const enemyAlly = enemy?.getAlly();
if (userAlly?.turnData.acted) {
pokemonActed.push(userAlly);
}
if (enemyAlly?.turnData.acted) {
pokemonActed.push(enemyAlly);
}
}
pokemonActed.sort((a, b) => b.turnData.order - a.turnData.order);
for (const p of pokemonActed) {
const [ lastMove ] = p.getLastXMoves(1); const [ lastMove ] = p.getLastXMoves(1);
if (lastMove.result !== MoveResult.FAIL) { if (lastMove.result !== MoveResult.FAIL) {
if ((lastMove.result === MoveResult.SUCCESS) && (lastMove.move === this.move)) { if ((lastMove.result === MoveResult.SUCCESS) && (lastMove.move === this.move)) {

View File

@ -23,6 +23,7 @@ export class TurnEndPhase extends FieldPhase {
globalScene.currentBattle.incrementTurn(); globalScene.currentBattle.incrementTurn();
globalScene.eventTarget.dispatchEvent(new TurnEndEvent(globalScene.currentBattle.turn)); globalScene.eventTarget.dispatchEvent(new TurnEndEvent(globalScene.currentBattle.turn));
globalScene.phaseManager.dynamicQueueManager.clearLastTurnOrder();
globalScene.phaseManager.hideAbilityBar(); globalScene.phaseManager.hideAbilityBar();

View File

@ -1,6 +1,7 @@
import type { PhaseConditionFunc } from "#app/@types/phase-condition"; import type { PhaseConditionFunc } from "#app/@types/phase-condition";
import type { DynamicPhaseString, PhaseString } from "#app/@types/phase-types"; import type { DynamicPhaseString, PhaseString } from "#app/@types/phase-types";
import type { PokemonMove } from "#app/data/moves/pokemon-move"; import type { PokemonMove } from "#app/data/moves/pokemon-move";
import type Pokemon from "#app/field/pokemon";
import type { Phase } from "#app/phase"; import type { Phase } from "#app/phase";
import { MovePhasePriorityQueue } from "#app/queues/move-phase-priority-queue"; import { MovePhasePriorityQueue } from "#app/queues/move-phase-priority-queue";
import type { PhasePriorityQueue } from "#app/queues/phase-priority-queue"; import type { PhasePriorityQueue } from "#app/queues/phase-priority-queue";
@ -69,6 +70,14 @@ export class DynamicQueueManager {
this.getMovePhaseQueue().setMoveOrder(order); this.getMovePhaseQueue().setMoveOrder(order);
} }
public getLastTurnOrder(): Pokemon[] {
return this.getMovePhaseQueue().getTurnOrder();
}
public clearLastTurnOrder(): void {
this.getMovePhaseQueue().clearTurnOrder();
}
private getMovePhaseQueue(): MovePhasePriorityQueue { private getMovePhaseQueue(): MovePhasePriorityQueue {
return this.dynamicPhaseMap.get("MovePhase") as MovePhasePriorityQueue; return this.dynamicPhaseMap.get("MovePhase") as MovePhasePriorityQueue;
} }

View File

@ -1,5 +1,6 @@
import type { PhaseConditionFunc } from "#app/@types/phase-condition"; import type { PhaseConditionFunc } from "#app/@types/phase-condition";
import type { PokemonMove } from "#app/data/moves/pokemon-move"; import type { PokemonMove } from "#app/data/moves/pokemon-move";
import type Pokemon from "#app/field/pokemon";
import type { MovePhase } from "#app/phases/move-phase"; import type { MovePhase } from "#app/phases/move-phase";
import { PokemonPhasePriorityQueue } from "#app/queues/pokemon-phase-priority-queue"; import { PokemonPhasePriorityQueue } from "#app/queues/pokemon-phase-priority-queue";
import { isNullOrUndefined } from "#app/utils/common"; import { isNullOrUndefined } from "#app/utils/common";
@ -7,6 +8,8 @@ import type { BattlerIndex } from "#enums/battler-index";
import type { MovePhaseTimingModifier } from "#enums/move-phase-timing-modifier"; import type { MovePhaseTimingModifier } from "#enums/move-phase-timing-modifier";
export class MovePhasePriorityQueue extends PokemonPhasePriorityQueue<MovePhase> { export class MovePhasePriorityQueue extends PokemonPhasePriorityQueue<MovePhase> {
private lastTurnOrder: Pokemon[] = [];
public override reorder(): void { public override reorder(): void {
super.reorder(); super.reorder();
this.sortPostSpeed(); this.sortPostSpeed();
@ -31,8 +34,26 @@ export class MovePhasePriorityQueue extends PokemonPhasePriorityQueue<MovePhase>
this.setOrder = order; this.setOrder = order;
} }
public override pop(): MovePhase | undefined {
this.reorder();
const phase = this.queue.shift();
if (phase) {
this.lastTurnOrder.push(phase.pokemon);
}
return phase;
}
public getTurnOrder(): Pokemon[] {
return this.lastTurnOrder;
}
public clearTurnOrder(): void {
this.lastTurnOrder = [];
}
public override clear(): void { public override clear(): void {
this.setOrder = undefined; this.setOrder = undefined;
this.lastTurnOrder = [];
super.clear(); super.clear();
} }

View File

@ -64,7 +64,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to(DamageAnimPhase, false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200);
}, 20000); });
it("FUSION_BOLT should double power of subsequent FUSION_FLARE", async () => { it("FUSION_BOLT should double power of subsequent FUSION_FLARE", async () => {
await game.classicMode.startBattle([SpeciesId.ZEKROM, SpeciesId.ZEKROM]); await game.classicMode.startBattle([SpeciesId.ZEKROM, SpeciesId.ZEKROM]);
@ -84,7 +84,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to(DamageAnimPhase, false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
}, 20000); });
it("FUSION_FLARE should double power of subsequent FUSION_BOLT if a move failed in between", async () => { it("FUSION_FLARE should double power of subsequent FUSION_BOLT if a move failed in between", async () => {
await game.classicMode.startBattle([SpeciesId.ZEKROM, SpeciesId.ZEKROM]); await game.classicMode.startBattle([SpeciesId.ZEKROM, SpeciesId.ZEKROM]);
@ -109,7 +109,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to(DamageAnimPhase, false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(200);
}, 20000); });
it("FUSION_FLARE should not double power of subsequent FUSION_BOLT if a move succeeded in between", async () => { it("FUSION_FLARE should not double power of subsequent FUSION_BOLT if a move succeeded in between", async () => {
game.override.enemyMoveset(MoveId.SPLASH); game.override.enemyMoveset(MoveId.SPLASH);
@ -134,7 +134,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionBolt.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to(DamageAnimPhase, false);
expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100); expect(fusionBolt.calculateBattlePower).toHaveLastReturnedWith(100);
}, 20000); });
it("FUSION_FLARE should double power of subsequent FUSION_BOLT if moves are aimed at allies", async () => { it("FUSION_FLARE should double power of subsequent FUSION_BOLT if moves are aimed at allies", async () => {
await game.classicMode.startBattle([SpeciesId.ZEKROM, SpeciesId.RESHIRAM]); await game.classicMode.startBattle([SpeciesId.ZEKROM, SpeciesId.RESHIRAM]);
@ -154,7 +154,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to(DamageAnimPhase, false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
}, 20000); });
it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves", async () => { it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves", async () => {
game.override.enemyMoveset(fusionFlare.id); game.override.enemyMoveset(fusionFlare.id);
@ -208,7 +208,7 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to(DamageAnimPhase, false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
}, 20000); });
it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves if moves are aimed at allies", async () => { it("FUSION_FLARE and FUSION_BOLT alternating throughout turn should double power of subsequent moves if moves are aimed at allies", async () => {
game.override.enemyMoveset(fusionFlare.id); game.override.enemyMoveset(fusionFlare.id);
@ -262,5 +262,5 @@ describe("Moves - Fusion Flare and Fusion Bolt", () => {
expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id); expect((game.scene.phaseManager.getCurrentPhase() as MoveEffectPhase).move.id).toBe(fusionFlare.id);
await game.phaseInterceptor.to(DamageAnimPhase, false); await game.phaseInterceptor.to(DamageAnimPhase, false);
expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200); expect(fusionFlare.calculateBattlePower).toHaveLastReturnedWith(200);
}, 20000); });
}); });