From 2b0b9fcb708273bb1684334990a7455f13669cb1 Mon Sep 17 00:00:00 2001 From: NightKev <34855794+DayKev@users.noreply.github.com> Date: Tue, 13 Aug 2024 14:14:49 -0700 Subject: [PATCH] [Bug] Palafin should not swap to Hero form when switching due to faint (#3532) * Palafin should not swap to Hero form when switching due to faint Also add more tests for Zero to Hero * Use `.isFainted()` instead of checking HP --- src/data/ability.ts | 2 +- src/test/abilities/zero_to_hero.test.ts | 107 +++++++++++++++++------- 2 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/data/ability.ts b/src/data/ability.ts index 1840254d618..abc45273131 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -5296,7 +5296,7 @@ export function initAbilities() { .attr(NoTransformAbilityAbAttr) .attr(NoFusionAbilityAbAttr) .attr(PostBattleInitFormChangeAbAttr, () => 0) - .attr(PreSwitchOutFormChangeAbAttr, () => 1) + .attr(PreSwitchOutFormChangeAbAttr, (pokemon) => !pokemon.isFainted() ? 1 : pokemon.formIndex) .bypassFaint(), new Ability(Abilities.COMMANDER, 9) .attr(UncopiableAbilityAbAttr) diff --git a/src/test/abilities/zero_to_hero.test.ts b/src/test/abilities/zero_to_hero.test.ts index c58761ce621..7924b30eb76 100644 --- a/src/test/abilities/zero_to_hero.test.ts +++ b/src/test/abilities/zero_to_hero.test.ts @@ -6,13 +6,16 @@ import { Moves } from "#enums/moves"; import { Species } from "#enums/species"; import GameManager from "#test/utils/gameManager"; import { getMovePosition } from "#test/utils/gameManagerUtils"; -import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; +import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; +import { SPLASH_ONLY } from "../utils/testUtils"; const TIMEOUT = 20 * 1000; describe("Abilities - ZERO TO HERO", () => { let phaserGame: Phaser.Game; let game: GameManager; + const baseForm = 0; + const heroForm = 1; beforeAll(() => { phaserGame = new Phaser.Game({ @@ -26,41 +29,83 @@ describe("Abilities - ZERO TO HERO", () => { beforeEach(() => { game = new GameManager(phaserGame); - const moveToUse = Moves.SPLASH; - game.override.battleType("single"); - game.override.ability(Abilities.ZERO_TO_HERO); - game.override.moveset([moveToUse]); - game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]); + game.override + .battleType("single") + .moveset(SPLASH_ONLY) + .enemyMoveset(SPLASH_ONLY) + .enemyAbility(Abilities.BALL_FETCH); }); - test( - "check if fainted pokemon switches to base form on arena reset", - async () => { - const baseForm = 0, - heroForm = 1; - game.override.startingWave(4); - game.override.starterForms({ - [Species.PALAFIN]: heroForm, - }); + it("should swap to base form on arena reset", async () => { + game.override.startingWave(4); + game.override.starterForms({ + [Species.PALAFIN]: heroForm, + }); - await game.startBattle([Species.MAGIKARP, Species.PALAFIN]); + await game.startBattle([Species.FEEBAS, Species.PALAFIN, Species.PALAFIN]); - const palafin = game.scene.getParty().find((p) => p.species.speciesId === Species.PALAFIN)!; - expect(palafin).not.toBe(undefined); - expect(palafin.formIndex).toBe(heroForm); + const palafin1 = game.scene.getParty()[1]; + const palafin2 = game.scene.getParty()[2]; + expect(palafin1.formIndex).toBe(heroForm); + expect(palafin2.formIndex).toBe(heroForm); + palafin2.hp = 0; + palafin2.status = new Status(StatusEffect.FAINT); + expect(palafin2.isFainted()).toBe(true); - palafin.hp = 0; - palafin.status = new Status(StatusEffect.FAINT); - expect(palafin.isFainted()).toBe(true); + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + await game.doKillOpponents(); + await game.phaseInterceptor.to(TurnEndPhase); + game.doSelectModifier(); + await game.phaseInterceptor.to(QuietFormChangePhase); + await game.phaseInterceptor.to(QuietFormChangePhase); - game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); - await game.doKillOpponents(); - await game.phaseInterceptor.to(TurnEndPhase); - game.doSelectModifier(); - await game.phaseInterceptor.to(QuietFormChangePhase); + expect(palafin1.formIndex).toBe(baseForm); + expect(palafin2.formIndex).toBe(baseForm); + }, TIMEOUT); - expect(palafin.formIndex).toBe(baseForm); - }, - TIMEOUT - ); + it("should swap to Hero form when switching out during a battle", async () => { + await game.startBattle([Species.PALAFIN, Species.FEEBAS]); + + const palafin = game.scene.getPlayerPokemon()!; + expect(palafin.formIndex).toBe(baseForm); + + game.doSwitchPokemon(1); + await game.phaseInterceptor.to(QuietFormChangePhase); + expect(palafin.formIndex).toBe(heroForm); + }, TIMEOUT); + + it("should not swap to Hero form if switching due to faint", async () => { + await game.startBattle([Species.PALAFIN, Species.FEEBAS]); + + const palafin = game.scene.getPlayerPokemon()!; + expect(palafin.formIndex).toBe(baseForm); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + await game.killPokemon(palafin); + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + expect(palafin.formIndex).toBe(baseForm); + }, TIMEOUT); + + it("should stay hero form if fainted and then revived", async () => { + game.override.starterForms({ + [Species.PALAFIN]: heroForm, + }); + + await game.startBattle([Species.PALAFIN, Species.FEEBAS]); + + const palafin = game.scene.getPlayerPokemon()!; + expect(palafin.formIndex).toBe(heroForm); + + game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH)); + await game.killPokemon(palafin); + game.doSelectPartyPokemon(1); + await game.toNextTurn(); + + game.doRevivePokemon(1); + game.doSwitchPokemon(1); + await game.toNextTurn(); + + expect(palafin.formIndex).toBe(heroForm); + }, TIMEOUT); });