From c4e2022e18b6f38a7cea7f0c5359d3cc92ac1415 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Sun, 21 Sep 2025 15:21:50 -0400 Subject: [PATCH] Changed `setTurnOrder` to forbid `BattlerIndex.ATTACKER` --- src/utils/speed-order.ts | 4 ++-- test/moves/delayed-attack.test.ts | 11 +++++++---- test/moves/destiny-bond.test.ts | 4 ++-- test/moves/encore.test.ts | 10 ++++------ test/moves/wish.test.ts | 8 +++++--- test/test-utils/helpers/field-helper.ts | 2 +- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/utils/speed-order.ts b/src/utils/speed-order.ts index 5d29c7dfe89..4ed472cdea5 100644 --- a/src/utils/speed-order.ts +++ b/src/utils/speed-order.ts @@ -10,7 +10,7 @@ interface hasPokemon { } /** - * Sort an array of {@linkcode Pokemon} in _ascending_ speed order, taking Trick Room into account. + * Sort an array of {@linkcode Pokemon} in speed order, taking Trick Room into account. * @param pokemonList - An array of `Pokemon` or objects containing `Pokemon` to sort; * will be mutated and sorted in place. * @param shuffleFirst - Whether to shuffle the list before sorting (to handle speed ties); default `true`. @@ -41,7 +41,7 @@ function shufflePokemonList(pokemonList: T[]): T return pokemonList; } -/** Sort an array of {@linkcode Pokemon} in descending speed order (without shuffling) */ +/** Sort an array of {@linkcode Pokemon} in speed order (without shuffling) */ function sortBySpeed(pokemonList: T[]): void { pokemonList.sort((a, b) => { const aSpeed = (a instanceof Pokemon ? a : a.getPokemon()).getEffectiveStat(Stat.SPD); diff --git a/test/moves/delayed-attack.test.ts b/test/moves/delayed-attack.test.ts index e31c7f28e48..e9192b4c206 100644 --- a/test/moves/delayed-attack.test.ts +++ b/test/moves/delayed-attack.test.ts @@ -167,16 +167,16 @@ describe("Moves - Delayed Attacks", () => { game.override.battleStyle("double"); await game.classicMode.startBattle([SpeciesId.MAGIKARP, SpeciesId.FEEBAS]); - const [alomomola, blissey] = game.scene.getField(); + const [alomomola, blissey] = game.scene.getPlayerField(); - const oldOrder = game.field.getSpeedOrder(); + const oldOrder = game.field.getSpeedOrder(true); game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER, BattlerIndex.ENEMY); game.move.use(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2); await game.move.forceEnemyMove(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER); await game.move.forceEnemyMove(MoveId.FUTURE_SIGHT, BattlerIndex.PLAYER_2); // Ensure that the moves are used deterministically in speed order (for speed ties) - await game.setTurnOrder(oldOrder.map(p => p.getBattlerIndex())); + await game.setTurnOrder(oldOrder); await game.toNextTurn(); expectFutureSightActive(4); @@ -195,7 +195,10 @@ describe("Moves - Delayed Attacks", () => { const MEPs = game.scene.phaseManager["phaseQueue"].findAll("MoveEffectPhase"); expect(MEPs).toHaveLength(4); - expect(MEPs.map(mep => mep.getPokemon())).toEqual(oldOrder); + expect( + MEPs.map(mep => mep.getPokemon().getBattlerIndex()), + "Delayed Attacks were not queued in correct order!", + ).toEqual(oldOrder); }); it("should vanish silently if it would otherwise hit the user", async () => { diff --git a/test/moves/destiny-bond.test.ts b/test/moves/destiny-bond.test.ts index a5020b83944..c96c4e18f36 100644 --- a/test/moves/destiny-bond.test.ts +++ b/test/moves/destiny-bond.test.ts @@ -17,8 +17,8 @@ describe("Moves - Destiny Bond", () => { let game: GameManager; const defaultParty = [SpeciesId.BULBASAUR, SpeciesId.SQUIRTLE]; - const enemyFirst = [BattlerIndex.ENEMY, BattlerIndex.PLAYER]; - const playerFirst = [BattlerIndex.PLAYER, BattlerIndex.ENEMY]; + const enemyFirst = [BattlerIndex.ENEMY, BattlerIndex.PLAYER] as const; + const playerFirst = [BattlerIndex.PLAYER, BattlerIndex.ENEMY] as const; beforeAll(() => { phaserGame = new Phaser.Game({ diff --git a/test/moves/encore.test.ts b/test/moves/encore.test.ts index 0840346c3b1..8e8853abf4c 100644 --- a/test/moves/encore.test.ts +++ b/test/moves/encore.test.ts @@ -78,8 +78,9 @@ describe("Moves - Encore", () => { game.move.select(MoveId.ENCORE); - const turnOrder = delay ? [BattlerIndex.PLAYER, BattlerIndex.ENEMY] : [BattlerIndex.ENEMY, BattlerIndex.PLAYER]; - await game.setTurnOrder(turnOrder); + await game.setTurnOrder( + delay ? [BattlerIndex.PLAYER, BattlerIndex.ENEMY] : [BattlerIndex.ENEMY, BattlerIndex.PLAYER], + ); await game.phaseInterceptor.to("BerryPhase", false); expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); @@ -88,25 +89,22 @@ describe("Moves - Encore", () => { }); it("Pokemon under both Encore and Torment should alternate between Struggle and restricted move", async () => { - const turnOrder = [BattlerIndex.ENEMY, BattlerIndex.PLAYER]; game.override.moveset([MoveId.ENCORE, MoveId.TORMENT, MoveId.SPLASH]); await game.classicMode.startBattle([SpeciesId.FEEBAS]); const enemyPokemon = game.field.getEnemyPokemon(); game.move.select(MoveId.ENCORE); - await game.setTurnOrder(turnOrder); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.phaseInterceptor.to("BerryPhase"); expect(enemyPokemon.getTag(BattlerTagType.ENCORE)).toBeDefined(); await game.toNextTurn(); game.move.select(MoveId.TORMENT); - await game.setTurnOrder(turnOrder); await game.phaseInterceptor.to("BerryPhase"); expect(enemyPokemon.getTag(BattlerTagType.TORMENT)).toBeDefined(); await game.toNextTurn(); game.move.select(MoveId.SPLASH); - await game.setTurnOrder(turnOrder); await game.phaseInterceptor.to("BerryPhase"); const lastMove = enemyPokemon.getLastXMoves()[0]; expect(lastMove?.move).toBe(MoveId.STRUGGLE); diff --git a/test/moves/wish.test.ts b/test/moves/wish.test.ts index b64a15ac654..ef46c85eb73 100644 --- a/test/moves/wish.test.ts +++ b/test/moves/wish.test.ts @@ -109,14 +109,14 @@ describe("Move - Wish", () => { vi.spyOn(karp1, "getNameToRender").mockReturnValue("Karp 1"); vi.spyOn(karp2, "getNameToRender").mockReturnValue("Karp 2"); - const oldOrder = game.field.getSpeedOrder(); + const oldOrder = game.field.getSpeedOrder(true); game.move.use(MoveId.WISH, BattlerIndex.PLAYER); game.move.use(MoveId.WISH, BattlerIndex.PLAYER_2); await game.move.forceEnemyMove(MoveId.WISH); await game.move.forceEnemyMove(MoveId.WISH); // Ensure that the wishes are used deterministically in speed order (for speed ties) - await game.setTurnOrder(oldOrder.map(p => p.getBattlerIndex())); + await game.setTurnOrder(oldOrder); await game.toNextTurn(); expect(game).toHavePositionalTag(PositionalTagType.WISH, 4); @@ -137,7 +137,9 @@ describe("Move - Wish", () => { const healPhases = game.scene.phaseManager["phaseQueue"].findAll("PokemonHealPhase"); expect(healPhases).toHaveLength(4); - expect.soft(healPhases.map(php => php.getPokemon())).toEqual(oldOrder); + expect + .soft(healPhases.map(php => php.getPokemon().getBattlerIndex(), "Wishes were not queued in correct order!")) + .toEqual(oldOrder); await game.toEndOfTurn(); diff --git a/test/test-utils/helpers/field-helper.ts b/test/test-utils/helpers/field-helper.ts index 29eb70ae20c..db48e411d5e 100644 --- a/test/test-utils/helpers/field-helper.ts +++ b/test/test-utils/helpers/field-helper.ts @@ -68,7 +68,7 @@ export class FieldHelper extends GameManagerHelper { * This does not account for Trick Room as it does not modify the _speed_ of Pokemon on the field, * only their turn order. */ - public getSpeedOrder(indices: true): BattlerIndex[]; + public getSpeedOrder(indices: true): Exclude[]; public getSpeedOrder(indices = false): BattlerIndex[] | Pokemon[] { const ret = this.game.scene .getField(true)