From ce8491f4a5d18ce55a54cc5f2f47c28e2d7f6a01 Mon Sep 17 00:00:00 2001 From: Bertie690 Date: Tue, 5 Aug 2025 21:41:35 -0400 Subject: [PATCH] rrr --- src/data/battler-tags.ts | 12 +++++++----- test/moves/encore.test.ts | 34 ++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index a188b99cad8..cad8f4055e0 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -29,7 +29,6 @@ import { applyMoveAttrs } from "#moves/apply-attrs"; import { invalidEncoreMoves } from "#moves/invalid-moves"; import type { Move } from "#moves/move"; import { getMoveTargets } from "#moves/move-utils"; -import { PokemonMove } from "#moves/pokemon-move"; import type { MoveEffectPhase } from "#phases/move-effect-phase"; import type { MovePhase } from "#phases/move-phase"; import type { StatStageChangeCallback } from "#phases/stat-stage-change-phase"; @@ -1262,6 +1261,10 @@ export class EncoreTag extends MoveRestrictionBattlerTag { return false; } + if (!pokemon.getMoveset().some(m => m.moveId === this.moveId && m.ppUsed > 0)) { + return false; + } + this.moveId = lastMove.move; return true; @@ -1283,10 +1286,9 @@ export class EncoreTag extends MoveRestrictionBattlerTag { return; } - // Use the prior move in the moveset. If it isn't there (presumably due to move forgetting), - // just make a new one for time being as the tag will be removed on turn end. - // TODO: Investigate this... - const movesetMove = pokemon.getMoveset().find(m => m.moveId === this.moveId) ?? new PokemonMove(this.moveId); + // Use the prior move in the moveset. + // Bang is justified as `canAdd` returns false if not possible + const movesetMove = pokemon.getMoveset().find(m => m.moveId === this.moveId)!; const moveTargets = getMoveTargets(pokemon, this.moveId); // Spread moves and ones with only 1 valid target will use their normal targeting. diff --git a/test/moves/encore.test.ts b/test/moves/encore.test.ts index 510b36e8581..1add9a52d9d 100644 --- a/test/moves/encore.test.ts +++ b/test/moves/encore.test.ts @@ -52,28 +52,50 @@ describe("Moves - Encore", () => { expect(enemyPokemon.isMoveRestricted(MoveId.SPLASH)).toBe(false); }); - it("should override any pending move phases with the Encored move, while still consuming PP", async () => { + it("should override any upcoming moves with the Encored move, while still consuming PP", async () => { await game.classicMode.startBattle([SpeciesId.SNORLAX]); // Fake enemy having used tackle the turn prior const enemy = game.field.getEnemyPokemon(); + game.move.changeMoveset(enemy, [MoveId.SPLASH, MoveId.TACKLE]); enemy.pushMoveHistory({ move: MoveId.TACKLE, targets: [BattlerIndex.PLAYER], useMode: MoveUseMode.NORMAL }); game.move.use(MoveId.ENCORE); - await game.move.forceEnemyMove(MoveId.SPLASH); + await game.move.selectEnemyMove(MoveId.SPLASH); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.toNextTurn(); expect(enemy).toHaveUsedMove({ move: MoveId.TACKLE, targets: [BattlerIndex.PLAYER], useMode: MoveUseMode.NORMAL }); - expect(enemy.isMoveRestricted(MoveId.TACKLE)).toBe(true); - expect(enemy.isMoveRestricted(MoveId.SPLASH)).toBe(false); + expect(enemy).toHaveUsedPP(MoveId.TACKLE, 1); }); // TODO: Make test using `changeMoveset` it.todo("should end at turn end if the user forgets the Encored move"); - // TODO: Make test (presumably involving Spite) - it.todo("should end immediately if the move runs out of PP"); + it("should end immediately if the move runs out of PP", async () => { + await game.classicMode.startBattle([SpeciesId.SNORLAX]); + + // Fake enemy having used tackle the turn prior + const enemy = game.field.getEnemyPokemon(); + game.move.changeMoveset(enemy, [MoveId.SPLASH, MoveId.TACKLE]); + enemy.pushMoveHistory({ move: MoveId.TACKLE, targets: [BattlerIndex.PLAYER], useMode: MoveUseMode.NORMAL }); + enemy.moveset[1].ppUsed = 2; + + game.move.use(MoveId.ENCORE); + await game.move.selectEnemyMove(MoveId.SPLASH); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toNextTurn(); + + expect(enemy).toHaveUsedMove({ move: MoveId.TACKLE, targets: [BattlerIndex.PLAYER], useMode: MoveUseMode.NORMAL }); + expect(enemy).toHaveUsedPP(MoveId.TACKLE, 39); + expect(enemy).toHaveBattlerTag(BattlerTagType.ENCORE); + + game.move.use(MoveId.SPLASH); + await game.toEndOfTurn(); + + expect(enemy).toHaveUsedPP(MoveId.TACKLE, "all"); + expect(enemy).not.toHaveBattlerTag(BattlerTagType.ENCORE); + }); const invalidMoves = [...invalidEncoreMoves].map(m => ({ name: MoveId[m],