diff --git a/src/battle_util.c b/src/battle_util.c index 91299c64df..9adfcc5016 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -10161,7 +10161,7 @@ bool32 TryBattleFormChange(u32 battler, enum FormChanges method) targetSpecies = GetBattleFormChangeTargetSpecies(battler, method); if (targetSpecies == currentSpecies) targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0); - if (targetSpecies != currentSpecies) + if (targetSpecies != currentSpecies && targetSpecies != SPECIES_NONE) { // Saves the original species on the first form change. @@ -10178,17 +10178,22 @@ bool32 TryBattleFormChange(u32 battler, enum FormChanges method) { bool32 restoreSpecies = FALSE; - // Mega Evolved and Ultra Bursted Pokémon should always revert to normal upon fainting or ending the battle, so no need to add it to the form change tables. - if ((IsBattlerMegaEvolved(battler) || IsBattlerUltraBursted(battler) || IsBattlerInTeraForm(battler)) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_END_BATTLE)) - restoreSpecies = TRUE; - - // Unlike Megas, Primal Reversion isn't canceled on fainting. - else if (IsBattlerPrimalReverted(battler) && (method == FORM_CHANGE_END_BATTLE)) - restoreSpecies = TRUE; - - // Gigantamax Pokemon have their forms reverted after fainting, switching, or ending the battle. - else if (IsGigantamaxed(battler) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE)) + switch (method) + { + case FORM_CHANGE_END_BATTLE: restoreSpecies = TRUE; + break; + case FORM_CHANGE_FAINT: + if (IsBattlerMegaEvolved(battler) || IsBattlerUltraBursted(battler) || IsBattlerInTeraForm(battler) || IsGigantamaxed(battler)) + restoreSpecies = TRUE; + break; + case FORM_CHANGE_BATTLE_SWITCH: + if (IsGigantamaxed(battler)) + restoreSpecies = TRUE; + break; + default: + break; + } if (restoreSpecies) { diff --git a/test/battle/ability/power_construct.c b/test/battle/ability/power_construct.c index 6a8ca9db5f..07d52c1767 100644 --- a/test/battle/ability/power_construct.c +++ b/test/battle/ability/power_construct.c @@ -2,3 +2,56 @@ #include "test/battle.h" TO_DO_BATTLE_TEST("TODO: Write Power Construct (Ability) test titles") + +SINGLE_BATTLE_TEST("Power Construct switches Zygarde's form when HP is below half") +{ + u16 baseSpecies; + PARAMETRIZE { baseSpecies = SPECIES_ZYGARDE_10_POWER_CONSTRUCT; } + PARAMETRIZE { baseSpecies = SPECIES_ZYGARDE_50_POWER_CONSTRUCT; } + + GIVEN { + PLAYER(baseSpecies) + { + Ability(ABILITY_POWER_CONSTRUCT); + HP((GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP) / 2) + 1); + } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SCRATCH); MOVE(player, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("You sense the presence of many!"); + ABILITY_POPUP(player, ABILITY_POWER_CONSTRUCT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_POWER_CONSTRUCT, player); + } THEN { + EXPECT_EQ(player->species, SPECIES_ZYGARDE_COMPLETE); + } +} + +WILD_BATTLE_TEST("Power Construct Zygarde reverts to its original form upon catching") +{ + u16 baseSpecies; + PARAMETRIZE { baseSpecies = SPECIES_ZYGARDE_10_POWER_CONSTRUCT; } + PARAMETRIZE { baseSpecies = SPECIES_ZYGARDE_50_POWER_CONSTRUCT; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(baseSpecies) + { + Ability(ABILITY_POWER_CONSTRUCT); + HP((GetMonData(&OPPONENT_PARTY[0], MON_DATA_MAX_HP) / 2) + 1); + } + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); } + TURN { USE_ITEM(player, ITEM_MASTER_BALL); } + } SCENE { + // Turn 1 + MESSAGE("You sense the presence of many!"); + ABILITY_POPUP(opponent, ABILITY_POWER_CONSTRUCT); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_POWER_CONSTRUCT, opponent); + + // Turn 2 + ANIMATION(ANIM_TYPE_SPECIAL, B_ANIM_BALL_THROW, player); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_SPECIES), baseSpecies); + } +}