From 1428d8b870e44a48373d79e53b32fb58d648b54e Mon Sep 17 00:00:00 2001 From: Madmadness65 <59298170+Madmadness65@users.noreply.github.com> Date: Sun, 20 Jul 2025 13:59:01 -0500 Subject: [PATCH] [Balance] Add faint trigger to various form changes (#6122) * [Balance] Add faint trigger to Battle Bond Greninja's form change The form change functionality will now be slightly closer to Generation 7/8, as the Greninja will now revert from Ash form to Battle Bond form upon fainting. * Change how the form change on faint is triggered It is no longer directly handled by the faint phase, and is instead part of the abilities now, as more than Battle Bond Greninja revert via this method (Disguise Mimikyu, Power Construct Zygarde). * Adjust Disguise test --- src/data/abilities/ability.ts | 23 +++++++++++++++++++++++ test/abilities/disguise.test.ts | 6 +----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/data/abilities/ability.ts b/src/data/abilities/ability.ts index ff459f24193..f2c1cc81801 100644 --- a/src/data/abilities/ability.ts +++ b/src/data/abilities/ability.ts @@ -5305,6 +5305,26 @@ export class PostFaintUnsuppressedWeatherFormChangeAbAttr extends PostFaintAbAtt } } +export class PostFaintFormChangeAbAttr extends PostFaintAbAttr { + private formFunc: (p: Pokemon) => number; + + constructor(formFunc: (p: Pokemon) => number) { + super(true); + + this.formFunc = formFunc; + } + + override canApply({ pokemon }: AbAttrBaseParams): boolean { + return this.formFunc(pokemon) !== pokemon.formIndex; + } + + override apply({ pokemon, simulated }: AbAttrBaseParams): void { + if (!simulated) { + globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false); + } + } +} + export class PostFaintContactDamageAbAttr extends PostFaintAbAttr { private damageRatio: number; @@ -7296,6 +7316,7 @@ export function initAbilities() { (pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }), (pokemon) => toDmgValue(pokemon.getMaxHp() / 8)) .attr(PostBattleInitFormChangeAbAttr, () => 0) + .attr(PostFaintFormChangeAbAttr, () => 0) .uncopiable() .unreplaceable() .unsuppressable() @@ -7304,6 +7325,7 @@ export function initAbilities() { new Ability(AbilityId.BATTLE_BOND, 7) .attr(PostVictoryFormChangeAbAttr, () => 2) .attr(PostBattleInitFormChangeAbAttr, () => 1) + .attr(PostFaintFormChangeAbAttr, () => 1) .attr(NoFusionAbilityAbAttr) .uncopiable() .unreplaceable() @@ -7315,6 +7337,7 @@ export function initAbilities() { .conditionalAttr(p => p.formIndex === 4 || p.formIndex === 5, PostBattleInitFormChangeAbAttr, p => p.formIndex - 2) .conditionalAttr(p => p.getHpRatio() <= 0.5 && (p.formIndex === 2 || p.formIndex === 3), PostSummonFormChangeAbAttr, p => p.formIndex + 2) .conditionalAttr(p => p.getHpRatio() <= 0.5 && (p.formIndex === 2 || p.formIndex === 3), PostTurnFormChangeAbAttr, p => p.formIndex + 2) + .conditionalAttr(p => p.formIndex === 4 || p.formIndex === 5, PostFaintFormChangeAbAttr, p => p.formIndex - 2) .attr(NoFusionAbilityAbAttr) .uncopiable() .unreplaceable() diff --git a/test/abilities/disguise.test.ts b/test/abilities/disguise.test.ts index 94d9dbf1d47..9bd36def8d7 100644 --- a/test/abilities/disguise.test.ts +++ b/test/abilities/disguise.test.ts @@ -165,7 +165,7 @@ describe("Abilities - Disguise", () => { expect(mimikyu.formIndex).toBe(disguisedForm); }); - it("reverts to Disguised form on biome change when fainted", async () => { + it("reverts to Disguised form when fainted", async () => { game.override .startingWave(10) .starterSpecies(0) @@ -181,10 +181,6 @@ describe("Abilities - Disguise", () => { game.move.select(MoveId.SPLASH); await game.killPokemon(mimikyu1); - game.doSelectPartyPokemon(1); - await game.toNextTurn(); - game.move.select(MoveId.SPLASH); - await game.doKillOpponents(); await game.phaseInterceptor.to("QuietFormChangePhase"); expect(mimikyu1.formIndex).toBe(disguisedForm);