diff --git a/src/data/ability.ts b/src/data/ability.ts index 491a14ba621..9e77013ff13 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -941,14 +941,19 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr { export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr { private weatherType: WeatherType; + protected condition: PokemonDefendCondition | null; - constructor(weatherType: WeatherType) { + constructor(weatherType: WeatherType, condition?: PokemonDefendCondition) { super(); this.weatherType = weatherType; + this.condition = condition ?? null; } applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { + if (this.condition !== null && !this.condition(pokemon, attacker, move)) { + return false; + } if (!pokemon.scene.arena.weather?.isImmutable()) { return pokemon.scene.arena.trySetWeather(this.weatherType, true); } @@ -5092,7 +5097,7 @@ export function initAbilities() { .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.SOUND_BASED), 0.5) .ignorable(), new Ability(Abilities.SAND_SPIT, 8) - .attr(PostDefendWeatherChangeAbAttr, WeatherType.SANDSTORM), + .attr(PostDefendWeatherChangeAbAttr, WeatherType.SANDSTORM, (target, user, move) => move.category !== MoveCategory.STATUS), new Ability(Abilities.ICE_SCALES, 8) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.category === MoveCategory.SPECIAL, 0.5) .ignorable(), diff --git a/src/test/abilities/sand_spit.test.ts b/src/test/abilities/sand_spit.test.ts new file mode 100644 index 00000000000..de75ba833dd --- /dev/null +++ b/src/test/abilities/sand_spit.test.ts @@ -0,0 +1,57 @@ +import GameManager from "#app/test/utils/gameManager"; +import { Abilities } from "#enums/abilities"; +import { Moves } from "#enums/moves"; +import { Species } from "#enums/species"; +import Phaser from "phaser"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { getMovePosition } from "../utils/gameManagerUtils"; +import { WeatherType } from "#app/enums/weather-type.js"; + + +describe("Ability Timing", () => { + 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.battleType("single"); + game.override.disableCrits(); + + game.override.enemySpecies(Species.MAGIKARP); + game.override.enemyAbility(Abilities.BALL_FETCH); + + game.override.starterSpecies(Species.SILICOBRA); + game.override.ability(Abilities.SAND_SPIT); + game.override.moveset([Moves.SPLASH, Moves.COIL]); + }); + + it("should trigger when hit with damaging move", async() => { + game.override.enemyMoveset(Array(4).fill(Moves.TACKLE)); + await game.startBattle(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + await game.toNextTurn(); + + expect(game.scene.arena.weather.weatherType).toBe(WeatherType.SANDSTORM); + }, 20000); + + it("should not trigger when targetted with status moves", async() => { + game.override.enemyMoveset(Array(4).fill(Moves.GROWL)); + await game.startBattle(); + + game.doAttack(getMovePosition(game.scene, 0, Moves.COIL)); + await game.toNextTurn(); + + expect(game.scene.arena.weather?.weatherType).not.toBe(WeatherType.SANDSTORM); + }, 20000); +});