diff --git a/src/data/move.ts b/src/data/move.ts index e89f3b20761..668246bd1e0 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -3665,7 +3665,6 @@ export class NeutralDamageAgainstFlyingTypeMultiplierAttr extends VariableMoveTy if (target.isOfType(Type.FLYING)) { multiplier.value = 1; } - target.addTag(BattlerTagType.IGNORE_FLYING, 20, move.id, user.id); //TODO: Grounded effect should not have turn limit return true; } @@ -7332,6 +7331,7 @@ export function initMoves() { .triageMove(), new AttackMove(Moves.THOUSAND_ARROWS, Type.GROUND, MoveCategory.PHYSICAL, 90, 100, 10, -1, 0, 6) .attr(NeutralDamageAgainstFlyingTypeMultiplierAttr) + .attr(AddBattlerTagAttr, BattlerTagType.IGNORE_FLYING, false, false, 20) // TODO: remove this turn count .attr(HitsTagAttr, BattlerTagType.FLYING, false) .attr(AddBattlerTagAttr, BattlerTagType.INTERRUPTED) .attr(RemoveBattlerTagAttr, [BattlerTagType.FLYING, BattlerTagType.MAGNET_RISEN]) diff --git a/src/test/moves/thousand_arrows.test.ts b/src/test/moves/thousand_arrows.test.ts new file mode 100644 index 00000000000..ff71a275743 --- /dev/null +++ b/src/test/moves/thousand_arrows.test.ts @@ -0,0 +1,65 @@ +import {afterEach, beforeAll, beforeEach, describe, expect, test, vi} from "vitest"; +import Phaser from "phaser"; +import GameManager from "#app/test/utils/gameManager"; +import * as overrides from "#app/overrides"; +import { + MoveEffectPhase, + TurnEndPhase +} from "#app/phases"; +import {getMovePosition} from "#app/test/utils/gameManagerUtils"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import { BattlerTagType } from "#app/enums/battler-tag-type.js"; + +const TIMEOUT = 20 * 1000; + +describe("Moves - Thousand Arrows", () => { + let phaserGame: Phaser.Game; + let game: GameManager; + + beforeAll(() => { + phaserGame = new Phaser.Game({ + type: Phaser.HEADLESS, + }); + }); + + afterEach(() => { + game.phaseInterceptor.restoreOg(); + }); + + beforeEach(() => { + game = new GameManager(phaserGame); + vi.spyOn(overrides, "SINGLE_BATTLE_OVERRIDE", "get").mockReturnValue(true); + vi.spyOn(overrides, "OPP_SPECIES_OVERRIDE", "get").mockReturnValue(Species.TOGETIC); + vi.spyOn(overrides, "STARTING_LEVEL_OVERRIDE", "get").mockReturnValue(100); + vi.spyOn(overrides, "OPP_LEVEL_OVERRIDE", "get").mockReturnValue(100); + vi.spyOn(overrides, "MOVESET_OVERRIDE", "get").mockReturnValue([ Moves.THOUSAND_ARROWS ]); + vi.spyOn(overrides, "OPP_MOVESET_OVERRIDE", "get").mockReturnValue([Moves.SPLASH,Moves.SPLASH,Moves.SPLASH,Moves.SPLASH]); + }); + + test( + "move should hit and ground Flying-type targets", + async () => { + await game.startBattle([ Species.ILLUMISE ]); + + const leadPokemon = game.scene.getPlayerPokemon(); + expect(leadPokemon).toBeDefined(); + + const enemyPokemon = game.scene.getEnemyPokemon(); + expect(enemyPokemon).toBeDefined(); + + const enemyStartingHp = enemyPokemon.hp; + + game.doAttack(getMovePosition(game.scene, 0, Moves.THOUSAND_ARROWS)); + + await game.phaseInterceptor.to(MoveEffectPhase, false); + // Enemy should not be grounded before move effect is applied + expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeUndefined(); + + await game.phaseInterceptor.to(TurnEndPhase, false); + + expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined(); + expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); + }, TIMEOUT + ); +});