[Bug][Test] Adding bypass faint to abilities that need it + fixing Perish Body (#5226)
* Added tests for snad spit, seed sower and perish body; for all three, the test checking if the ability triggers after the user faints is failing. * Adding .bypassFaint() to the three abilities, tests passing * Apply suggestions from code review Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> * Removed incorrect test for perish song * Added tests for perish body when one mon already has the perish song tag, both ways * Changed ability behavior to pass tests * Removing superfluous conditional --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
This commit is contained in:
parent
f087162eeb
commit
5743751e5c
|
@ -1003,7 +1003,7 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
|
|||
|
||||
override applyPostDefend(pokemon: Pokemon, _passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, _hitResult: HitResult, _args: any[]): boolean {
|
||||
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !move.hitsSubstitute(attacker, pokemon)) {
|
||||
if (pokemon.getTag(BattlerTagType.PERISH_SONG) || attacker.getTag(BattlerTagType.PERISH_SONG)) {
|
||||
if (attacker.getTag(BattlerTagType.PERISH_SONG)) {
|
||||
return false;
|
||||
} else {
|
||||
if (!simulated) {
|
||||
|
@ -6141,7 +6141,8 @@ 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, (target, user, move) => move.category !== MoveCategory.STATUS),
|
||||
.attr(PostDefendWeatherChangeAbAttr, WeatherType.SANDSTORM, (target, user, move) => move.category !== MoveCategory.STATUS)
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.ICE_SCALES, 8)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.category === MoveCategory.SPECIAL, 0.5)
|
||||
.ignorable(),
|
||||
|
@ -6174,7 +6175,8 @@ export function initAbilities() {
|
|||
new Ability(Abilities.STEELY_SPIRIT, 8)
|
||||
.attr(UserFieldMoveTypePowerBoostAbAttr, Type.STEEL),
|
||||
new Ability(Abilities.PERISH_BODY, 8)
|
||||
.attr(PostDefendPerishSongAbAttr, 4),
|
||||
.attr(PostDefendPerishSongAbAttr, 4)
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.WANDERING_SPIRIT, 8)
|
||||
.attr(PostDefendAbilitySwapAbAttr)
|
||||
.bypassFaint()
|
||||
|
@ -6232,7 +6234,8 @@ export function initAbilities() {
|
|||
.attr(PostDefendAbilityGiveAbAttr, Abilities.LINGERING_AROMA)
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.SEED_SOWER, 9)
|
||||
.attr(PostDefendTerrainChangeAbAttr, TerrainType.GRASSY),
|
||||
.attr(PostDefendTerrainChangeAbAttr, TerrainType.GRASSY)
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.THERMAL_EXCHANGE, 9)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE && move.category !== MoveCategory.STATUS, Stat.ATK, 1)
|
||||
.attr(StatusEffectImmunityAbAttr, StatusEffect.BURN)
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
|
||||
describe("Abilities - Perish Song", () => {
|
||||
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.CURSOLA);
|
||||
game.override.ability(Abilities.PERISH_BODY);
|
||||
game.override.moveset([ Moves.SPLASH ]);
|
||||
});
|
||||
|
||||
it("should trigger when hit with damaging move", async () => {
|
||||
game.override.enemyMoveset([ Moves.AQUA_JET ]);
|
||||
await game.classicMode.startBattle();
|
||||
const cursola = game.scene.getPlayerPokemon();
|
||||
const magikarp = game.scene.getEnemyPokemon();
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(cursola?.summonData.tags[0].turnCount).toBe(3);
|
||||
expect(magikarp?.summonData.tags[0].turnCount).toBe(3);
|
||||
});
|
||||
|
||||
it("should trigger even when fainting", async () => {
|
||||
game.override.enemyMoveset([ Moves.AQUA_JET ])
|
||||
.enemyLevel(100)
|
||||
.startingLevel(1);
|
||||
await game.classicMode.startBattle([ Species.CURSOLA, Species.FEEBAS ]);
|
||||
const magikarp = game.scene.getEnemyPokemon();
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(magikarp?.summonData.tags[0].turnCount).toBe(3);
|
||||
});
|
||||
|
||||
it("should not activate if attacker already has perish song", async () => {
|
||||
game.override.enemyMoveset([ Moves.PERISH_SONG, Moves.AQUA_JET, Moves.SPLASH ]);
|
||||
await game.classicMode.startBattle([ Species.FEEBAS, Species.CURSOLA ]);
|
||||
const feebas = game.scene.getPlayerPokemon();
|
||||
const magikarp = game.scene.getEnemyPokemon();
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.forceEnemyMove(Moves.PERISH_SONG);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(feebas?.summonData.tags[0].turnCount).toBe(3);
|
||||
expect(magikarp?.summonData.tags[0].turnCount).toBe(3);
|
||||
|
||||
game.doSwitchPokemon(1);
|
||||
await game.forceEnemyMove(Moves.SPLASH);
|
||||
await game.toNextTurn();
|
||||
|
||||
const cursola = game.scene.getPlayerPokemon();
|
||||
expect(cursola?.summonData.tags.length).toBe(0);
|
||||
expect(magikarp?.summonData.tags[0].turnCount).toBe(2);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.forceEnemyMove(Moves.AQUA_JET);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(cursola?.summonData.tags.length).toBe(0);
|
||||
expect(magikarp?.summonData.tags[0].turnCount).toBe(1);
|
||||
|
||||
});
|
||||
|
||||
it("should activate if cursola already has perish song, but not reset its counter", async () => {
|
||||
game.override.enemyMoveset([ Moves.PERISH_SONG, Moves.AQUA_JET, Moves.SPLASH ]);
|
||||
game.override.moveset([ Moves.WHIRLWIND, Moves.SPLASH ]);
|
||||
game.override.startingWave(5);
|
||||
await game.classicMode.startBattle([ Species.CURSOLA ]);
|
||||
const cursola = game.scene.getPlayerPokemon();
|
||||
|
||||
game.move.select(Moves.WHIRLWIND);
|
||||
await game.forceEnemyMove(Moves.PERISH_SONG);
|
||||
await game.toNextTurn();
|
||||
|
||||
const magikarp = game.scene.getEnemyPokemon();
|
||||
expect(cursola?.summonData.tags[0].turnCount).toBe(3);
|
||||
expect(magikarp?.summonData.tags.length).toBe(0);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.forceEnemyMove(Moves.AQUA_JET);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(cursola?.summonData.tags[0].turnCount).toBe(2);
|
||||
expect(magikarp?.summonData.tags.length).toBe(1);
|
||||
expect(magikarp?.summonData.tags[0].turnCount).toBe(3);
|
||||
});
|
||||
});
|
|
@ -36,7 +36,7 @@ describe("Abilities - Sand Spit", () => {
|
|||
|
||||
it("should trigger when hit with damaging move", async () => {
|
||||
game.override.enemyMoveset([ Moves.TACKLE ]);
|
||||
await game.startBattle();
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.toNextTurn();
|
||||
|
@ -44,9 +44,22 @@ describe("Abilities - Sand Spit", () => {
|
|||
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.SANDSTORM);
|
||||
}, 20000);
|
||||
|
||||
it("should trigger even when fainting", async () => {
|
||||
game.override.enemyMoveset([ Moves.TACKLE ])
|
||||
.enemyLevel(100)
|
||||
.startingLevel(1);
|
||||
await game.classicMode.startBattle([ Species.SILICOBRA, Species.MAGIKARP ]);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(game.scene.arena.weather?.weatherType).toBe(WeatherType.SANDSTORM);
|
||||
});
|
||||
|
||||
it("should not trigger when targetted with status moves", async () => {
|
||||
game.override.enemyMoveset([ Moves.GROWL ]);
|
||||
await game.startBattle();
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
game.move.select(Moves.COIL);
|
||||
await game.toNextTurn();
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { TerrainType } from "#app/data/terrain";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
|
||||
describe("Abilities - Seed Sower", () => {
|
||||
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.ARBOLIVA);
|
||||
game.override.ability(Abilities.SEED_SOWER);
|
||||
game.override.moveset([ Moves.SPLASH ]);
|
||||
});
|
||||
|
||||
it("should trigger when hit with damaging move", async () => {
|
||||
game.override.enemyMoveset([ Moves.TACKLE ]);
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(game.scene.arena.terrain?.terrainType).toBe(TerrainType.GRASSY);
|
||||
});
|
||||
|
||||
it("should trigger even when fainting", async () => {
|
||||
game.override.enemyMoveset([ Moves.TACKLE ])
|
||||
.enemyLevel(100)
|
||||
.startingLevel(1);
|
||||
await game.classicMode.startBattle([ Species.ARBOLIVA, Species.MAGIKARP ]);
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
game.doSelectPartyPokemon(1);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(game.scene.arena.terrain?.terrainType).toBe(TerrainType.GRASSY);
|
||||
});
|
||||
|
||||
it("should not trigger when targetted with status moves", async () => {
|
||||
game.override.enemyMoveset([ Moves.GROWL ]);
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
game.move.select(Moves.SPLASH);
|
||||
await game.toNextTurn();
|
||||
|
||||
expect(game.scene.arena.terrain?.terrainType).not.toBe(TerrainType.GRASSY);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue