import { allMoves, MultiHitAttr } from "#app/data/moves/move"; import { MultiHitType } from "#enums/MultiHitType"; import { Status } from "#app/data/status-effect"; import { Abilities } from "#enums/abilities"; import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import { StatusEffect } from "#enums/status-effect"; import GameManager from "#test/testUtils/gameManager"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; describe("Abilities - BATTLE BOND", () => { let phaserGame: Phaser.Game; let game: GameManager; const baseForm = 1; const ashForm = 2; beforeAll(() => { phaserGame = new Phaser.Game({ type: Phaser.HEADLESS, }); }); afterEach(() => { game.phaseInterceptor.restoreOg(); }); beforeEach(() => { game = new GameManager(phaserGame); game.override .battleType("single") .startingWave(4) // Leads to arena reset on Wave 5 trainer battle .ability(Abilities.BATTLE_BOND) .starterForms({ [Species.GRENINJA]: ashForm }) .moveset([Moves.SPLASH, Moves.WATER_SHURIKEN]) .enemySpecies(Species.BULBASAUR) .enemyMoveset(Moves.SPLASH) .startingLevel(100) // Avoid levelling up .enemyLevel(1000); // Avoid opponent dying before `doKillOpponents()` }); it("check if fainted pokemon switches to base form on arena reset", async () => { await game.classicMode.startBattle([Species.MAGIKARP, Species.GRENINJA]); const greninja = game.scene.getPlayerParty()[1]; expect(greninja.formIndex).toBe(ashForm); greninja.hp = 0; greninja.status = new Status(StatusEffect.FAINT); expect(greninja.isFainted()).toBe(true); game.move.select(Moves.SPLASH); await game.doKillOpponents(); await game.phaseInterceptor.to("TurnEndPhase"); game.doSelectModifier(); await game.phaseInterceptor.to("QuietFormChangePhase"); expect(greninja.formIndex).toBe(baseForm); }); it("should not keep buffing Water Shuriken after Greninja switches to base form", async () => { await game.classicMode.startBattle([Species.GRENINJA]); const waterShuriken = allMoves[Moves.WATER_SHURIKEN]; vi.spyOn(waterShuriken, "calculateBattlePower"); let actualMultiHitType: MultiHitType | null = null; const multiHitAttr = waterShuriken.getAttrs(MultiHitAttr)[0]; vi.spyOn(multiHitAttr, "getHitCount").mockImplementation(() => { actualMultiHitType = multiHitAttr.getMultiHitType(); return 3; }); // Wave 4: Use Water Shuriken in Ash form let expectedBattlePower = 20; let expectedMultiHitType = MultiHitType._3; game.move.select(Moves.WATER_SHURIKEN); await game.phaseInterceptor.to("BerryPhase", false); expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower); expect(actualMultiHitType).toBe(expectedMultiHitType); await game.doKillOpponents(); await game.toNextWave(); // Wave 5: Use Water Shuriken in base form expectedBattlePower = 15; expectedMultiHitType = MultiHitType._2_TO_5; game.move.select(Moves.WATER_SHURIKEN); await game.phaseInterceptor.to("BerryPhase", false); expect(waterShuriken.calculateBattlePower).toHaveLastReturnedWith(expectedBattlePower); expect(actualMultiHitType).toBe(expectedMultiHitType); }); });