This commit is contained in:
Bertie690 2025-08-05 21:41:35 -04:00
parent 5653ec83be
commit ce8491f4a5
2 changed files with 35 additions and 11 deletions

View File

@ -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.

View File

@ -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],