diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index c82506b64d5..fc578f130c6 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -2004,8 +2004,6 @@ export class HealOnAllyAttr extends HealAttr { } } -} - /** * Cures the user's party of non-volatile status conditions, ie. Heal Bell, Aromatherapy * @extends MoveEffectAttr diff --git a/test/moves/spit_up.test.ts b/test/moves/spit_up.test.ts deleted file mode 100644 index 83549c28f40..00000000000 --- a/test/moves/spit_up.test.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { Stat } from "#enums/stat"; -import { StockpilingTag } from "#app/data/battler-tags"; -import { allMoves } from "#app/data/data-lists"; -import { BattlerTagType } from "#app/enums/battler-tag-type"; -import type { TurnMove } from "#app/field/pokemon"; -import { MoveResult } from "#enums/move-result"; -import GameManager from "#test/testUtils/gameManager"; -import { AbilityId } from "#enums/ability-id"; -import { MoveId } from "#enums/move-id"; -import type Move from "#app/data/moves/move"; -import { SpeciesId } from "#enums/species-id"; -import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { MovePhase } from "#app/phases/move-phase"; -import { TurnInitPhase } from "#app/phases/turn-init-phase"; - -describe("Moves - Spit Up", () => { - let phaserGame: Phaser.Game; - let game: GameManager; - - let spitUp: Move; - - beforeAll(() => { - phaserGame = new Phaser.Game({ type: Phaser.HEADLESS }); - }); - - afterEach(() => { - game.phaseInterceptor.restoreOg(); - }); - - beforeEach(() => { - spitUp = allMoves[MoveId.SPIT_UP]; - game = new GameManager(phaserGame); - - game.override.battleStyle("single"); - - game.override.enemySpecies(SpeciesId.RATTATA); - game.override.enemyMoveset(MoveId.SPLASH); - game.override.enemyAbility(AbilityId.NONE); - game.override.enemyLevel(2000); - - game.override.moveset(new Array(4).fill(spitUp.id)); - game.override.ability(AbilityId.NONE); - - vi.spyOn(spitUp, "calculateBattlePower"); - }); - - describe("consumes all stockpile stacks to deal damage (scaling with stacks)", () => { - it("1 stack -> 100 power", async () => { - const stacksToSetup = 1; - const expectedPower = 100; - - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - expect(stockpilingTag.stockpiledCount).toBe(stacksToSetup); - - game.move.select(MoveId.SPIT_UP); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(spitUp.calculateBattlePower).toHaveBeenCalledOnce(); - expect(spitUp.calculateBattlePower).toHaveReturnedWith(expectedPower); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - - it("2 stacks -> 200 power", async () => { - const stacksToSetup = 2; - const expectedPower = 200; - - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - pokemon.addTag(BattlerTagType.STOCKPILING); - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - expect(stockpilingTag.stockpiledCount).toBe(stacksToSetup); - - game.move.select(MoveId.SPIT_UP); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(spitUp.calculateBattlePower).toHaveBeenCalledOnce(); - expect(spitUp.calculateBattlePower).toHaveReturnedWith(expectedPower); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - - it("3 stacks -> 300 power", async () => { - const stacksToSetup = 3; - const expectedPower = 300; - - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - pokemon.addTag(BattlerTagType.STOCKPILING); - pokemon.addTag(BattlerTagType.STOCKPILING); - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - expect(stockpilingTag.stockpiledCount).toBe(stacksToSetup); - - game.move.select(MoveId.SPIT_UP); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(spitUp.calculateBattlePower).toHaveBeenCalledOnce(); - expect(spitUp.calculateBattlePower).toHaveReturnedWith(expectedPower); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - }); - - it("fails without stacks", async () => { - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeUndefined(); - - game.move.select(MoveId.SPIT_UP); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.getMoveHistory().at(-1)).toMatchObject({ - move: MoveId.SPIT_UP, - result: MoveResult.FAIL, - targets: [game.scene.getEnemyPokemon()!.getBattlerIndex()], - }); - - expect(spitUp.calculateBattlePower).not.toHaveBeenCalled(); - }); - - describe("restores stat boosts granted by stacks", () => { - it("decreases stats based on stored values (both boosts equal)", async () => { - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - - game.move.select(MoveId.SPIT_UP); - await game.phaseInterceptor.to(MovePhase); - - expect(pokemon.getStatStage(Stat.DEF)).toBe(1); - expect(pokemon.getStatStage(Stat.SPDEF)).toBe(1); - - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.getMoveHistory().at(-1)).toMatchObject({ - move: MoveId.SPIT_UP, - result: MoveResult.SUCCESS, - targets: [game.scene.getEnemyPokemon()!.getBattlerIndex()], - }); - - expect(spitUp.calculateBattlePower).toHaveBeenCalledOnce(); - - expect(pokemon.getStatStage(Stat.DEF)).toBe(0); - expect(pokemon.getStatStage(Stat.SPDEF)).toBe(0); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - - it("decreases stats based on stored values (different boosts)", async () => { - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - - // for the sake of simplicity (and because other tests cover the setup), set boost amounts directly - stockpilingTag.statChangeCounts = { - [Stat.DEF]: -1, - [Stat.SPDEF]: 2, - }; - - game.move.select(MoveId.SPIT_UP); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.getMoveHistory().at(-1)).toMatchObject({ - move: MoveId.SPIT_UP, - result: MoveResult.SUCCESS, - targets: [game.scene.getEnemyPokemon()!.getBattlerIndex()], - }); - - expect(spitUp.calculateBattlePower).toHaveBeenCalledOnce(); - - expect(pokemon.getStatStage(Stat.DEF)).toBe(1); - expect(pokemon.getStatStage(Stat.SPDEF)).toBe(-2); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - }); -}); diff --git a/test/moves/swallow-spit-up.test.ts b/test/moves/swallow-spit-up.test.ts new file mode 100644 index 00000000000..96fd4ebdb07 --- /dev/null +++ b/test/moves/swallow-spit-up.test.ts @@ -0,0 +1,265 @@ +import { Stat } from "#enums/stat"; +import { StockpilingTag } from "#app/data/battler-tags"; +import { BattlerTagType } from "#app/enums/battler-tag-type"; +import { MoveResult } from "#enums/move-result"; +import { AbilityId } from "#enums/ability-id"; +import { MoveId } from "#enums/move-id"; +import { SpeciesId } from "#enums/species-id"; +import GameManager from "#test/testUtils/gameManager"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it, vi, type MockInstance } from "vitest"; +import { BattlerIndex } from "#enums/battler-index"; +import { allMoves } from "#app/data/data-lists"; +import { getPokemonNameWithAffix } from "#app/messages"; +import i18next from "i18next"; + +describe("Swallow & Spit Up", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ type: Phaser.HEADLESS }); + }); + + describe("Moves - Swallow", () => { + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + game.override + .battleStyle("single") + .enemySpecies(SpeciesId.RATTATA) + .enemyMoveset(MoveId.SPLASH) + .enemyAbility(AbilityId.BALL_FETCH) + .enemyLevel(100) + .startingLevel(100) + .ability(AbilityId.BALL_FETCH); + }); + + it.each<{ stackCount: number; healPercent: number }>([ + { stackCount: 1, healPercent: 25 }, + { stackCount: 2, healPercent: 50 }, + { stackCount: 3, healPercent: 100 }, + ])( + "should heal the user by $healPercent% max HP when consuming $stackCount stockpile stacks", + async ({ stackCount, healPercent }) => { + await game.classicMode.startBattle([SpeciesId.SWALOT]); + + const swalot = game.field.getPlayerPokemon(); + swalot.hp = 1; + + for (let i = 0; i < stackCount; i++) { + swalot.addTag(BattlerTagType.STOCKPILING); + } + + const stockpilingTag = swalot.getTag(StockpilingTag)!; + expect(stockpilingTag).toBeDefined(); + expect(stockpilingTag.stockpiledCount).toBe(stackCount); + + game.move.use(MoveId.SWALLOW); + await game.toEndOfTurn(); + + expect(swalot.getHpRatio()).toBeCloseTo(healPercent / 100, 1); + expect(swalot.getTag(StockpilingTag)).toBeUndefined(); + }, + ); + + it("should fail without Stockpile stacks", async () => { + await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); + + const player = game.field.getPlayerPokemon(); + player.hp = 1; + + const stockpilingTag = player.getTag(StockpilingTag)!; + expect(stockpilingTag).toBeUndefined(); + + game.move.use(MoveId.SWALLOW); + await game.toEndOfTurn(); + + expect(player.getLastXMoves()[0]).toMatchObject({ + move: MoveId.SWALLOW, + result: MoveResult.FAIL, + }); + }); + + it("should fail and display message at full HP without consuming stacks", async () => { + await game.classicMode.startBattle([SpeciesId.SWALOT]); + + const swalot = game.field.getPlayerPokemon(); + swalot.addTag(BattlerTagType.STOCKPILING); + const stockpilingTag = swalot.getTag(StockpilingTag)!; + expect(stockpilingTag).toBeDefined(); + + game.move.use(MoveId.SWALLOW); + await game.toEndOfTurn(); + + expect(swalot.getLastXMoves()[0]).toMatchObject({ + move: MoveId.SWALLOW, + result: MoveResult.FAIL, + }); + expect(game.textInterceptor.logs).toContain( + i18next.t("battle:hpIsFull", { + pokemonName: getPokemonNameWithAffix(swalot), + }), + ); + expect(stockpilingTag).toBeDefined(); + }); + }); + + describe("Moves - Spit Up", () => { + let spitUpSpy: MockInstance; + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override + .battleStyle("single") + .enemySpecies(SpeciesId.RATTATA) + .enemyAbility(AbilityId.BALL_FETCH) + .enemyLevel(2000) + .enemyMoveset(MoveId.SPLASH) + .ability(AbilityId.BALL_FETCH); + + spitUpSpy = vi.spyOn(allMoves[MoveId.SPIT_UP], "calculateBattlePower"); + }); + + it.each<{ stackCount: number; power: number }>([ + { stackCount: 1, power: 100 }, + { stackCount: 2, power: 200 }, + { stackCount: 3, power: 300 }, + ])("should have $power base power when consuming $stackCount stockpile stacks", async ({ stackCount, power }) => { + await game.classicMode.startBattle([SpeciesId.SWALOT]); + + const swalot = game.field.getPlayerPokemon(); + + for (let i = 0; i < stackCount; i++) { + swalot.addTag(BattlerTagType.STOCKPILING); + } + + const stockpilingTag = swalot.getTag(StockpilingTag)!; + expect(stockpilingTag).toBeDefined(); + expect(stockpilingTag.stockpiledCount).toBe(stackCount); + + game.move.use(MoveId.SPIT_UP); + await game.toEndOfTurn(); + + expect(spitUpSpy).toHaveReturnedWith(power); + expect(swalot.getTag(StockpilingTag)).toBeUndefined(); + }); + + it("should fail without Stockpile stacks", async () => { + await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); + + const player = game.field.getPlayerPokemon(); + + const stockpilingTag = player.getTag(StockpilingTag)!; + expect(stockpilingTag).toBeUndefined(); + + game.move.use(MoveId.SPIT_UP); + await game.toEndOfTurn(); + + expect(player.getLastXMoves()[0]).toMatchObject({ + move: MoveId.SPIT_UP, + result: MoveResult.FAIL, + }); + }); + }); + + describe("Stockpile stack removal", () => { + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + + game.override + .battleStyle("single") + .enemySpecies(SpeciesId.RATTATA) + .enemyMoveset(MoveId.SPLASH) + .enemyAbility(AbilityId.BALL_FETCH) + .enemyLevel(100) + .startingLevel(100) + .ability(AbilityId.BALL_FETCH); + }); + + it("should undo stat boosts when losing stacks", async () => { + await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); + + const player = game.field.getPlayerPokemon(); + player.hp = 1; + + player.addTag(BattlerTagType.STOCKPILING); + const stockpilingTag = player.getTag(StockpilingTag)!; + expect(stockpilingTag).toBeDefined(); + expect(player.getStatStage(Stat.DEF)).toBe(1); + expect(player.getStatStage(Stat.SPDEF)).toBe(1); + + // remove the prior stat boosts from the log + game.phaseInterceptor.clearLogs(); + game.move.use(MoveId.SWALLOW); + await game.move.forceEnemyMove(MoveId.ACID_SPRAY); + await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); + await game.toEndOfTurn(); + + expect(player.getStatStage(Stat.DEF)).toBe(0); + expect(player.getStatStage(Stat.SPDEF)).toBe(-2); // +1 --> -1 --> -2 + expect(game.phaseInterceptor.log.filter(l => l === "StatStageChangePhase")).toHaveLength(3); + }); + + it("should double stat drops when gaining Simple", async () => { + await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); + + const player = game.field.getPlayerPokemon(); + + game.move.use(MoveId.STOCKPILE); + await game.move.forceEnemyMove(MoveId.SIMPLE_BEAM); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toNextTurn(); + + expect(player.getStatStage(Stat.DEF)).toBe(1); + expect(player.getStatStage(Stat.SPDEF)).toBe(1); + expect(player.hasAbility(AbilityId.SIMPLE)).toBe(true); + + game.move.use(MoveId.SPIT_UP); + await game.move.forceEnemyMove(MoveId.SPLASH); + await game.toEndOfTurn(); + + // should have fallen by 2 stages from Simple + expect(player.getStatStage(Stat.DEF)).toBe(-1); + expect(player.getStatStage(Stat.SPDEF)).toBe(-1); + expect(player.waveData.abilityRevealed).toBe(true); + }); + + it("should invert stat drops when gaining Contrary", async () => { + game.override.enemyAbility(AbilityId.CONTRARY); + await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); + + const player = game.field.getPlayerPokemon(); + + game.move.use(MoveId.STOCKPILE); + await game.move.forceEnemyMove(MoveId.ENTRAINMENT); + await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.ENEMY]); + await game.toEndOfTurn(); + + expect(player.getStatStage(Stat.DEF)).toBe(1); + expect(player.getStatStage(Stat.SPDEF)).toBe(1); + expect(player.hasAbility(AbilityId.CONTRARY)).toBe(true); + + game.move.use(MoveId.SPIT_UP); + await game.move.forceEnemyMove(MoveId.SPLASH); + await game.toEndOfTurn(); + + // should have risen 1 stage from Contrary + expect(player.getStatStage(Stat.DEF)).toBe(2); + expect(player.getStatStage(Stat.SPDEF)).toBe(2); + expect(player.waveData.abilityRevealed).toBe(true); + }); + }); +}); diff --git a/test/moves/swallow.test.ts b/test/moves/swallow.test.ts deleted file mode 100644 index bb95c2c593d..00000000000 --- a/test/moves/swallow.test.ts +++ /dev/null @@ -1,205 +0,0 @@ -import { Stat } from "#enums/stat"; -import { StockpilingTag } from "#app/data/battler-tags"; -import { BattlerTagType } from "#app/enums/battler-tag-type"; -import type { TurnMove } from "#app/field/pokemon"; -import { MoveResult } from "#enums/move-result"; -import { MovePhase } from "#app/phases/move-phase"; -import { TurnInitPhase } from "#app/phases/turn-init-phase"; -import { AbilityId } from "#enums/ability-id"; -import { MoveId } from "#enums/move-id"; -import { SpeciesId } from "#enums/species-id"; -import GameManager from "#test/testUtils/gameManager"; -import Phaser from "phaser"; -import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; - -describe("Moves - Swallow", () => { - 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 - .battleStyle("single") - .enemySpecies(SpeciesId.RATTATA) - .enemyMoveset(MoveId.SPLASH) - .enemyAbility(AbilityId.NONE) - .enemyLevel(2000) - .moveset(MoveId.SWALLOW) - .ability(AbilityId.NONE); - }); - - describe("consumes all stockpile stacks to heal (scaling with stacks)", () => { - it("1 stack -> 25% heal", async () => { - const stacksToSetup = 1; - const expectedHeal = 25; - - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - vi.spyOn(pokemon, "getMaxHp").mockReturnValue(100); - pokemon["hp"] = 1; - - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - expect(stockpilingTag.stockpiledCount).toBe(stacksToSetup); - - vi.spyOn(pokemon, "heal"); - - game.move.select(MoveId.SWALLOW); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.heal).toHaveBeenCalledOnce(); - expect(pokemon.heal).toHaveReturnedWith(expectedHeal); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - - it("2 stacks -> 50% heal", async () => { - const stacksToSetup = 2; - const expectedHeal = 50; - - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - vi.spyOn(pokemon, "getMaxHp").mockReturnValue(100); - pokemon["hp"] = 1; - - pokemon.addTag(BattlerTagType.STOCKPILING); - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - expect(stockpilingTag.stockpiledCount).toBe(stacksToSetup); - - vi.spyOn(pokemon, "heal"); - - game.move.select(MoveId.SWALLOW); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.heal).toHaveBeenCalledOnce(); - expect(pokemon.heal).toHaveReturnedWith(expectedHeal); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - - it("3 stacks -> 100% heal", async () => { - const stacksToSetup = 3; - const expectedHeal = 100; - - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - vi.spyOn(pokemon, "getMaxHp").mockReturnValue(100); - pokemon["hp"] = 0.0001; - - pokemon.addTag(BattlerTagType.STOCKPILING); - pokemon.addTag(BattlerTagType.STOCKPILING); - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - expect(stockpilingTag.stockpiledCount).toBe(stacksToSetup); - - vi.spyOn(pokemon, "heal"); - - game.move.select(MoveId.SWALLOW); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.heal).toHaveBeenCalledOnce(); - expect(pokemon.heal).toHaveReturnedWith(expect.closeTo(expectedHeal)); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - }); - - it("fails without stacks", async () => { - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeUndefined(); - - game.move.select(MoveId.SWALLOW); - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.getMoveHistory().at(-1)).toMatchObject({ - move: MoveId.SWALLOW, - result: MoveResult.FAIL, - targets: [pokemon.getBattlerIndex()], - }); - }); - - describe("restores stat stage boosts granted by stacks", () => { - it("decreases stats based on stored values (both boosts equal)", async () => { - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - - game.move.select(MoveId.SWALLOW); - await game.phaseInterceptor.to(MovePhase); - - expect(pokemon.getStatStage(Stat.DEF)).toBe(1); - expect(pokemon.getStatStage(Stat.SPDEF)).toBe(1); - - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.getMoveHistory().at(-1)).toMatchObject({ - move: MoveId.SWALLOW, - result: MoveResult.SUCCESS, - targets: [pokemon.getBattlerIndex()], - }); - - expect(pokemon.getStatStage(Stat.DEF)).toBe(0); - expect(pokemon.getStatStage(Stat.SPDEF)).toBe(0); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - - it("lower stat stages based on stored values (different boosts)", async () => { - await game.classicMode.startBattle([SpeciesId.ABOMASNOW]); - - const pokemon = game.scene.getPlayerPokemon()!; - pokemon.addTag(BattlerTagType.STOCKPILING); - - const stockpilingTag = pokemon.getTag(StockpilingTag)!; - expect(stockpilingTag).toBeDefined(); - - // for the sake of simplicity (and because other tests cover the setup), set boost amounts directly - stockpilingTag.statChangeCounts = { - [Stat.DEF]: -1, - [Stat.SPDEF]: 2, - }; - - game.move.select(MoveId.SWALLOW); - - await game.phaseInterceptor.to(TurnInitPhase); - - expect(pokemon.getMoveHistory().at(-1)).toMatchObject({ - move: MoveId.SWALLOW, - result: MoveResult.SUCCESS, - targets: [pokemon.getBattlerIndex()], - }); - - expect(pokemon.getStatStage(Stat.DEF)).toBe(1); - expect(pokemon.getStatStage(Stat.SPDEF)).toBe(-2); - - expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); - }); - }); -});