import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerIndex } from "#app/battle"; import { MoveResult } from "#app/field/pokemon"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/testUtils/gameManager"; import Phaser from "phaser"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; describe("Moves - Encore", () => { let phaserGame: Phaser.Game; let game: GameManager; beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, }); }); afterEach(() => { game.phaseInterceptor.restoreOg(); }); beforeEach(() => { game = new GameManager(phaserGame); game.override .moveset([Moves.SPLASH, Moves.ENCORE]) .ability(Abilities.BALL_FETCH) .battleType("single") .disableCrits() .enemySpecies(Species.MAGIKARP) .enemyAbility(Abilities.BALL_FETCH) .enemyMoveset([Moves.SPLASH, Moves.TACKLE]) .startingLevel(100) .enemyLevel(100); }); it("should prevent the target from using any move except the last used move", async () => { await game.classicMode.startBattle([Species.SNORLAX]); const enemyPokemon = game.scene.getEnemyPokemon()!; game.move.select(Moves.ENCORE); await game.forceEnemyMove(Moves.SPLASH); await game.toNextTurn(); expect(enemyPokemon.getTag(BattlerTagType.ENCORE)).toBeDefined(); game.move.select(Moves.SPLASH); // The enemy AI would normally be inclined to use Tackle, but should be // forced into using Splash. await game.phaseInterceptor.to("BerryPhase", false); expect(enemyPokemon.getLastXMoves().every(turnMove => turnMove.move === Moves.SPLASH)).toBeTruthy(); }); describe("should fail against the following moves:", () => { it.each([ { moveId: Moves.TRANSFORM, name: "Transform", delay: false }, { moveId: Moves.MIMIC, name: "Mimic", delay: true }, { moveId: Moves.SKETCH, name: "Sketch", delay: true }, { moveId: Moves.ENCORE, name: "Encore", delay: false }, { moveId: Moves.STRUGGLE, name: "Struggle", delay: false }, ])("$name", async ({ moveId, delay }) => { game.override.enemyMoveset(moveId); await game.classicMode.startBattle([Species.SNORLAX]); const playerPokemon = game.scene.getPlayerPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!; if (delay) { game.move.select(Moves.SPLASH); await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); await game.toNextTurn(); } game.move.select(Moves.ENCORE); const turnOrder = delay ? [BattlerIndex.PLAYER, BattlerIndex.ENEMY] : [BattlerIndex.ENEMY, BattlerIndex.PLAYER]; await game.setTurnOrder(turnOrder); await game.phaseInterceptor.to("BerryPhase", false); expect(playerPokemon.getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); expect(enemyPokemon.getTag(BattlerTagType.ENCORE)).toBeUndefined(); }); }); it("Pokemon under both Encore and Torment should alternate between Struggle and restricted move", async () => { const turnOrder = [BattlerIndex.ENEMY, BattlerIndex.PLAYER]; game.override.moveset([Moves.ENCORE, Moves.TORMENT, Moves.SPLASH]); await game.classicMode.startBattle([Species.FEEBAS]); const enemyPokemon = game.scene.getEnemyPokemon(); game.move.select(Moves.ENCORE); await game.setTurnOrder(turnOrder); await game.phaseInterceptor.to("BerryPhase"); expect(enemyPokemon?.getTag(BattlerTagType.ENCORE)).toBeDefined(); await game.toNextTurn(); game.move.select(Moves.TORMENT); await game.setTurnOrder(turnOrder); await game.phaseInterceptor.to("BerryPhase"); expect(enemyPokemon?.getTag(BattlerTagType.TORMENT)).toBeDefined(); await game.toNextTurn(); game.move.select(Moves.SPLASH); await game.setTurnOrder(turnOrder); await game.phaseInterceptor.to("BerryPhase"); const lastMove = enemyPokemon?.getLastXMoves()[0]; expect(lastMove?.move).toBe(Moves.STRUGGLE); }); });