From 85b5dac4d070772ac502e90835dd598de8e242cb Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Thu, 8 Jan 2026 20:09:44 -0300 Subject: [PATCH] Support end-of-battle party data check in tests (#8831) --- src/battle_main.c | 16 +- test/battle/ability/ice_face.c | 10 + test/battle/ability/stance_change.c | 1 - test/battle/ability/zen_mode.c | 2 +- test/battle/form_change/begin_battle.c | 4 +- test/battle/form_change/end_battle.c | 288 ++++++++++++++++++ .../form_change/end_battle_environment.c | 33 ++ test/battle/form_change/faint.c | 24 +- test/battle/form_change/gigantamax.c | 45 +++ test/battle/form_change/mega_evolution.c | 30 +- test/battle/form_change/primal_reversion.c | 15 + test/battle/form_change/status.c | 1 - test/battle/form_change/ultra_burst.c | 18 +- test/battle/gimmick/dynamax.c | 31 -- 14 files changed, 462 insertions(+), 56 deletions(-) create mode 100644 test/battle/form_change/end_battle.c create mode 100644 test/battle/form_change/end_battle_environment.c create mode 100644 test/battle/form_change/gigantamax.c diff --git a/src/battle_main.c b/src/battle_main.c index b10e506499..c54323c826 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -1799,7 +1799,8 @@ void CB2_QuitRecordedBattle(void) if (taskId != TASK_NONE) DestroyTask(taskId); - TestRunner_Battle_AfterLastTurn(); + gCurrentActionFuncId = B_ACTION_FINISHED; + sEndTurnFuncsTable[gBattleOutcome & 0x7F](); // Contains TestRunner_Battle_AfterLastTurn } FreeRestoreBattleData(); FreeAllWindowBuffers(); @@ -5624,21 +5625,11 @@ static void HandleEndTurn_FinishBattle(void) TryPutBreakingNewsOnAir(); } - RecordedBattle_SetPlaybackFinished(); - if (gTestRunnerEnabled) - TestRunner_Battle_AfterLastTurn(); BeginFastPaletteFade(3); FadeOutMapMusic(5); if (B_TRAINERS_KNOCK_OFF_ITEMS == TRUE || B_RESTORE_HELD_BATTLE_ITEMS >= GEN_9) TryRestoreHeldItems(); - // Undo Dynamax HP multiplier before recalculating stats. - for (battler = 0; battler < gBattlersCount; ++battler) - { - if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX) - UndoDynamax(battler); - } - for (i = 0; i < PARTY_SIZE; i++) { bool32 changedForm = TryRevertPartyMonFormChange(i); @@ -5647,6 +5638,9 @@ static void HandleEndTurn_FinishBattle(void) if (!changedForm && B_RECALCULATE_STATS >= GEN_5) CalculateMonStats(&gPlayerParty[i]); } + RecordedBattle_SetPlaybackFinished(); + if (gTestRunnerEnabled) + TestRunner_Battle_AfterLastTurn(); // Clear battle mon species to avoid a bug on the next battle that causes // healthboxes loading incorrectly due to it trying to create a Mega Indicator // if the previous battler would've had it. diff --git a/test/battle/ability/ice_face.c b/test/battle/ability/ice_face.c index c3df84baeb..4abb9a9baf 100644 --- a/test/battle/ability/ice_face.c +++ b/test/battle/ability/ice_face.c @@ -11,7 +11,10 @@ SINGLE_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noi TURN { MOVE(opponent, MOVE_SCRATCH); } } SCENE { ABILITY_POPUP(player, ABILITY_ICE_FACE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); MESSAGE("Eiscue transformed!"); + } THEN { + EXPECT_EQ(player->species, SPECIES_EISCUE_NOICE); } } @@ -26,6 +29,8 @@ SINGLE_BATTLE_TEST("Ice Face does not block special moves, Eiscue stays in Ice F TURN { MOVE(opponent, MOVE_EMBER); } } SCENE { NOT ABILITY_POPUP(player, ABILITY_ICE_FACE); + } THEN { + EXPECT_EQ(player->species, SPECIES_EISCUE_ICE); } } @@ -46,11 +51,16 @@ SINGLE_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face TURN { MOVE(opponent, MOVE_SCRATCH); } } SCENE { ABILITY_POPUP(player, ABILITY_ICE_FACE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); MESSAGE("Eiscue transformed!"); ABILITY_POPUP(player, ABILITY_ICE_FACE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); MESSAGE("Eiscue transformed!"); ABILITY_POPUP(player, ABILITY_ICE_FACE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); MESSAGE("Eiscue transformed!"); + } THEN { + EXPECT_EQ(player->species, SPECIES_EISCUE_NOICE); } } diff --git a/test/battle/ability/stance_change.c b/test/battle/ability/stance_change.c index 0c82c93177..ebddb8a884 100644 --- a/test/battle/ability/stance_change.c +++ b/test/battle/ability/stance_change.c @@ -1,7 +1,6 @@ #include "global.h" #include "test/battle.h" - SINGLE_BATTLE_TEST("Stance Change changes Aegislash from Shield to Blade when using a damaging move") { u16 move; diff --git a/test/battle/ability/zen_mode.c b/test/battle/ability/zen_mode.c index 1e73961cda..96f47a3180 100644 --- a/test/battle/ability/zen_mode.c +++ b/test/battle/ability/zen_mode.c @@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Zen Mode switches Darmanitan's form when HP is half or less ABILITY_POPUP(player, ABILITY_ZEN_MODE); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); } THEN { - ASSUME(player->hp <= player->maxHP / 2); + EXPECT_LT(player->hp, player->maxHP / 2); EXPECT_EQ(player->species, zenSpecies); } } diff --git a/test/battle/form_change/begin_battle.c b/test/battle/form_change/begin_battle.c index bee9c4fe6b..a133d321a3 100644 --- a/test/battle/form_change/begin_battle.c +++ b/test/battle/form_change/begin_battle.c @@ -39,7 +39,7 @@ SINGLE_BATTLE_TEST("Zacian's Iron Head becomes Behemoth Blade upon form change") } WHEN { TURN { MOVE(player, MOVE_CELEBRATE); } } THEN { - ASSUME(player->species == SPECIES_ZACIAN_CROWNED); // Assumes form change worked. + EXPECT_EQ(player->species, SPECIES_ZACIAN_CROWNED); EXPECT_EQ(player->moves[0], MOVE_BEHEMOTH_BLADE); } } @@ -70,7 +70,7 @@ SINGLE_BATTLE_TEST("Zamazenta's Iron Head becomes Behemoth Bash upon form change } WHEN { TURN { MOVE(player, MOVE_CELEBRATE); } } THEN { - ASSUME(player->species == SPECIES_ZAMAZENTA_CROWNED); // Assumes form change worked. + EXPECT_EQ(player->species, SPECIES_ZAMAZENTA_CROWNED); EXPECT_EQ(player->moves[0], MOVE_BEHEMOTH_BASH); } } diff --git a/test/battle/form_change/end_battle.c b/test/battle/form_change/end_battle.c new file mode 100644 index 0000000000..9de52a83f2 --- /dev/null +++ b/test/battle/form_change/end_battle.c @@ -0,0 +1,288 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Xerneas returns its Neutral Form upon battle end") +{ + GIVEN { + PLAYER(SPECIES_XERNEAS_NEUTRAL); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_XERNEAS_NEUTRAL); + } +} + +SINGLE_BATTLE_TEST("Zacian returns its Hero Form upon battle end") +{ + GIVEN { + PLAYER(SPECIES_ZACIAN_HERO) { Item(ITEM_RUSTED_SWORD); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_ZACIAN_HERO); + } +} + +SINGLE_BATTLE_TEST("Zacian returns its Hero Form upon battle end") +{ + GIVEN { + ASSUME(GetMovePP(MOVE_BEHEMOTH_BLADE) == 5); + PLAYER(SPECIES_ZACIAN_HERO) { Item(ITEM_RUSTED_SWORD); Moves(MOVE_IRON_HEAD, MOVE_CELEBRATE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_ZACIAN_HERO); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE1), MOVE_IRON_HEAD); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_PP1), 5); // Behemoth Blade's PP + } +} + +SINGLE_BATTLE_TEST("Zamazenta returns its Hero Form upon battle end") +{ + GIVEN { + PLAYER(SPECIES_ZAMAZENTA_HERO) { Item(ITEM_RUSTED_SHIELD); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_ZAMAZENTA_HERO); + } +} + +SINGLE_BATTLE_TEST("Zamazenta returns its Hero Form upon battle end") +{ + GIVEN { + ASSUME(GetMovePP(MOVE_BEHEMOTH_BASH) == 5); + PLAYER(SPECIES_ZAMAZENTA_HERO) { Item(ITEM_RUSTED_SHIELD); Moves(MOVE_IRON_HEAD, MOVE_CELEBRATE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_ZAMAZENTA_HERO); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MOVE1), MOVE_IRON_HEAD); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_PP1), 5); // Behemoth Bash's PP + } +} + +SINGLE_BATTLE_TEST("Palafin returns to Zero form upon battle end") +{ + GIVEN { + PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { SWITCH(player, 1); } + TURN { SWITCH(player, 0); } + } SCENE { + SWITCH_OUT_MESSAGE("Palafin"); + SEND_IN_MESSAGE("Wobbuffet"); + SWITCH_OUT_MESSAGE("Wobbuffet"); + SEND_IN_MESSAGE("Palafin"); + ABILITY_POPUP(player, ABILITY_ZERO_TO_HERO); + MESSAGE("Palafin underwent a heroic transformation!"); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_PALAFIN_ZERO); + } +} + +SINGLE_BATTLE_TEST("Shaymin retains Land form if it was frozen or frostbitten in battle") +{ + KNOWN_FAILING; // changedSpecies is forcing the return to Sky Form + GIVEN { + ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE)); + PLAYER(SPECIES_SHAYMIN_SKY); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_POWDER_SNOW); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_POWDER_SNOW, opponent); + FREEZE_OR_FROSTBURN_STATUS(player, TRUE); + NOT HP_BAR(player); // Regression caused by Mimikyu form change + MESSAGE("Shaymin transformed!"); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_SHAYMIN_LAND); + } +} + +SINGLE_BATTLE_TEST("Meloetta returns to Aria form upon battle end after using Relic Song") +{ + GIVEN { + PLAYER(SPECIES_MELOETTA_ARIA); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_RELIC_SONG); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); + HP_BAR(opponent); + MESSAGE("Meloetta transformed!"); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_MELOETTA_ARIA); + } +} + +SINGLE_BATTLE_TEST("Battle Bond Greninja returns to base form upon battle end after knocking out an opponent") +{ + GIVEN { + WITH_CONFIG(CONFIG_BATTLE_BOND, GEN_8); + PLAYER(SPECIES_GRENINJA_BATTLE_BOND); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_WATER_GUN); SEND_OUT(opponent, 1); } + } SCENE { + HP_BAR(opponent); + MESSAGE("The opposing Wobbuffet fainted!"); + ABILITY_POPUP(player, ABILITY_BATTLE_BOND); + MESSAGE("Greninja became fully charged due to its bond with its trainer!"); + MESSAGE("Greninja became Ash-Greninja!"); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_GRENINJA_BATTLE_BOND); + } +} + +SINGLE_BATTLE_TEST("Aegislash reverts to Shield Form upon battle end after using an attack") +{ + GIVEN { + PLAYER(SPECIES_AEGISLASH_SHIELD); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_AEGISLASH_SHIELD); + } +} + +SINGLE_BATTLE_TEST("Wishiwashi reverts to Solo form upon battle end after changing form at the beginning of the battle") +{ + GIVEN { + PLAYER(SPECIES_WISHIWASHI_SOLO) { Level(100); Ability(ABILITY_SCHOOLING); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(player, ABILITY_SCHOOLING); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_WISHIWASHI_SOLO); + } +} + +SINGLE_BATTLE_TEST("Minior Meteor reverts to Core form upon battle end after changing form at the beginning of the battle") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { HP(1); } + PLAYER(SPECIES_MINIOR_CORE) { Ability(ABILITY_SHIELDS_DOWN); HP(51); MaxHP(101); } + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(opponent, MOVE_SCRATCH); SEND_OUT(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SHIELDS_DOWN); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_SPECIES), SPECIES_MINIOR_CORE); + } +} + +SINGLE_BATTLE_TEST("Mimikyu Busted reverts to Disguised form upon battle end after busting its Disguise in battle") +{ + u32 species; + PARAMETRIZE { species = SPECIES_MIMIKYU_DISGUISED; } + PARAMETRIZE { species = SPECIES_MIMIKYU_TOTEM_DISGUISED; } + GIVEN { + WITH_CONFIG(CONFIG_DISGUISE_HP_LOSS, GEN_7); + PLAYER(species) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_AERIAL_ACE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, opponent); + ABILITY_POPUP(player, ABILITY_DISGUISE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), species); + } +} + +SINGLE_BATTLE_TEST("Cramorant reverts to base Form upon battle end after using Surf in battle") +{ + GIVEN { + PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SURF); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_CRAMORANT); + } +} + +SINGLE_BATTLE_TEST("Eiscue Noice reverts to Ice Form upon battle end after being hit by a physical move in battle") +{ + GIVEN { + ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_EISCUE_ICE); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SCRATCH); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); + MESSAGE("Eiscue transformed!"); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_EISCUE_ICE); + } +} + +SINGLE_BATTLE_TEST("Morpeko Hangry reverts to Full Belly Form upon battle end after changing forms at the end of the turn") +{ + GIVEN { + PLAYER(SPECIES_MORPEKO_FULL_BELLY) { Speed(2); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(1); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("Morpeko used Celebrate!"); + MESSAGE("The opposing Wobbuffet used Celebrate!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_MORPEKO_FULL_BELLY); + } +} + +SINGLE_BATTLE_TEST("Ogerpon reverts to the correct form upon battle end after terastallizing") +{ + u32 species; + PARAMETRIZE { species = SPECIES_OGERPON_TEAL; } + PARAMETRIZE { species = SPECIES_OGERPON_WELLSPRING; } + PARAMETRIZE { species = SPECIES_OGERPON_HEARTHFLAME; } + PARAMETRIZE { species = SPECIES_OGERPON_CORNERSTONE; } + GIVEN { + PLAYER(species); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE, gimmick: GIMMICK_TERA); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), species); + } +} + +SINGLE_BATTLE_TEST("Terapagos reverts to the correct form upon battle end after terastallizing") +{ + GIVEN { + PLAYER(SPECIES_TERAPAGOS_NORMAL); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE, gimmick: GIMMICK_TERA); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_TERAPAGOS_NORMAL); + } +} diff --git a/test/battle/form_change/end_battle_environment.c b/test/battle/form_change/end_battle_environment.c new file mode 100644 index 0000000000..d4dfee3f5e --- /dev/null +++ b/test/battle/form_change/end_battle_environment.c @@ -0,0 +1,33 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Burmy changes form based on the environment it appeared in-battle") +{ + u32 currentForm = 0, newForm = 0, environment = 0; + + static u32 sBurmyForms[] = { + SPECIES_BURMY_PLANT, + SPECIES_BURMY_SANDY, + SPECIES_BURMY_TRASH, + }; + + for (u32 j = 0; j < ARRAY_COUNT(sBurmyForms); j++) { + PARAMETRIZE { currentForm = sBurmyForms[j]; newForm = SPECIES_BURMY_PLANT; environment = BATTLE_ENVIRONMENT_GRASS; } + PARAMETRIZE { currentForm = sBurmyForms[j]; newForm = SPECIES_BURMY_PLANT; environment = BATTLE_ENVIRONMENT_LONG_GRASS; } + PARAMETRIZE { currentForm = sBurmyForms[j]; newForm = SPECIES_BURMY_PLANT; environment = BATTLE_ENVIRONMENT_POND; } + PARAMETRIZE { currentForm = sBurmyForms[j]; newForm = SPECIES_BURMY_PLANT; environment = BATTLE_ENVIRONMENT_MOUNTAIN; } + PARAMETRIZE { currentForm = sBurmyForms[j]; newForm = SPECIES_BURMY_PLANT; environment = BATTLE_ENVIRONMENT_PLAIN; } + PARAMETRIZE { currentForm = sBurmyForms[j]; newForm = SPECIES_BURMY_SANDY; environment = BATTLE_ENVIRONMENT_CAVE; } + PARAMETRIZE { currentForm = sBurmyForms[j]; newForm = SPECIES_BURMY_SANDY; environment = BATTLE_ENVIRONMENT_SAND; } + PARAMETRIZE { currentForm = sBurmyForms[j]; newForm = SPECIES_BURMY_TRASH; environment = BATTLE_ENVIRONMENT_BUILDING; } + } + GIVEN { + PLAYER(currentForm); + OPPONENT(SPECIES_WOBBUFFET); + Environment(environment); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), newForm); + } +} diff --git a/test/battle/form_change/faint.c b/test/battle/form_change/faint.c index 316ecca0bf..4f66dc84c1 100644 --- a/test/battle/form_change/faint.c +++ b/test/battle/form_change/faint.c @@ -8,12 +8,19 @@ SINGLE_BATTLE_TEST("Aegislash reverts to Shield Form upon fainting (start as Shi PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(player, MOVE_SCRATCH); MOVE(opponent, MOVE_GUST); SEND_OUT(player, 1); } + TURN { MOVE(opponent, MOVE_GUST); SEND_OUT(player, 1); } + TURN { USE_ITEM(player, ITEM_REVIVE, 0); } + TURN { SWITCH(player, 0); } } SCENE { - MESSAGE("The opposing Wobbuffet used Gust!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_GUST, opponent); + HP_BAR(player); MESSAGE("Aegislash fainted!"); + SEND_IN_MESSAGE("Wobbuffet"); + SWITCH_OUT_MESSAGE("Wobbuffet") + SEND_IN_MESSAGE("Aegislash"); } THEN { - EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_AEGISLASH_SHIELD); + // We do not check gPlayerParty data to avoid triggering FORM_CHANGE_END_BATTLE. + EXPECT_EQ(player->species, SPECIES_AEGISLASH_SHIELD); } } @@ -25,11 +32,18 @@ SINGLE_BATTLE_TEST("Aegislash reverts to Shield Form upon fainting (start as Bla OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(opponent, MOVE_GUST); SEND_OUT(player, 1); } + TURN { USE_ITEM(player, ITEM_REVIVE, 0); } + TURN { SWITCH(player, 0); } } SCENE { - MESSAGE("The opposing Wobbuffet used Gust!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_GUST, opponent); + HP_BAR(player); MESSAGE("Aegislash fainted!"); + SEND_IN_MESSAGE("Wobbuffet"); + SWITCH_OUT_MESSAGE("Wobbuffet") + SEND_IN_MESSAGE("Aegislash"); } THEN { - EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_AEGISLASH_SHIELD); + // We do not check gPlayerParty data to avoid triggering FORM_CHANGE_END_BATTLE. + EXPECT_EQ(player->species, SPECIES_AEGISLASH_SHIELD); } } diff --git a/test/battle/form_change/gigantamax.c b/test/battle/form_change/gigantamax.c new file mode 100644 index 0000000000..92e2b49224 --- /dev/null +++ b/test/battle/form_change/gigantamax.c @@ -0,0 +1,45 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Dynamax: Pokemon with Gigantamax forms change upon Dynamaxing") +{ + u32 species; + bool32 gigantamaxFactor; + PARAMETRIZE { gigantamaxFactor = FALSE; species = SPECIES_VENUSAUR; } + PARAMETRIZE { gigantamaxFactor = TRUE; species = SPECIES_VENUSAUR_GMAX; } + GIVEN { + PLAYER(SPECIES_VENUSAUR) { GigantamaxFactor(gigantamaxFactor); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH, gimmick: GIMMICK_DYNAMAX); } + } THEN { + EXPECT_EQ(player->species, species); + } +} + +SINGLE_BATTLE_TEST("Dynamax: Pokemon with Gigantamax forms revert upon switching") +{ + GIVEN { + PLAYER(SPECIES_VENUSAUR); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH, gimmick: GIMMICK_DYNAMAX); } + TURN { SWITCH(player, 1); } + TURN { SWITCH(player, 0); } + } THEN { + EXPECT_EQ(player->species, SPECIES_VENUSAUR); + } +} + +SINGLE_BATTLE_TEST("Dynamax: Venusaur returns its base Form upon battle end after Gigantamaxing") +{ + GIVEN { + PLAYER(SPECIES_VENUSAUR) { GigantamaxFactor(TRUE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH, gimmick: GIMMICK_DYNAMAX); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_VENUSAUR); + } +} diff --git a/test/battle/form_change/mega_evolution.c b/test/battle/form_change/mega_evolution.c index 7cb3d2b783..f246cf1cc6 100644 --- a/test/battle/form_change/mega_evolution.c +++ b/test/battle/form_change/mega_evolution.c @@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Mega Evolution doesn't affect turn order (Gen6)") MESSAGE("The opposing Wobbuffet used Celebrate!"); MESSAGE("Gardevoir used Celebrate!"); } THEN { - ASSUME(player->speed == 205); + EXPECT_EQ(player->speed, 205); } } @@ -99,7 +99,7 @@ SINGLE_BATTLE_TEST("Mega Evolution affects turn order (Gen7+)") MESSAGE("Gardevoir used Celebrate!"); MESSAGE("The opposing Wobbuffet used Celebrate!"); } THEN { - ASSUME(player->speed == 205); + EXPECT_EQ(player->speed, 205); } } @@ -117,7 +117,7 @@ SINGLE_BATTLE_TEST("Abilities replaced by Mega Evolution do not affect turn orde MESSAGE("Sableye used Celebrate!"); MESSAGE("The opposing Wobbuffet used Celebrate!"); } THEN { - ASSUME(player->speed == 105); + EXPECT_EQ(player->speed, 105); } } @@ -192,3 +192,27 @@ SINGLE_BATTLE_TEST("Mega Evolved Pokemon do not change abilities after fainting" } } } + +SINGLE_BATTLE_TEST("Venusaur returns its base Form upon battle end after Mega Evolving") +{ + GIVEN { + PLAYER(SPECIES_VENUSAUR) { Item(ITEM_VENUSAURITE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE, gimmick: GIMMICK_MEGA); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_VENUSAUR); + } +} + +SINGLE_BATTLE_TEST("Rayquaza returns its base Form upon battle end after Mega Evolving") +{ + GIVEN { + PLAYER(SPECIES_RAYQUAZA) { Moves(MOVE_DRAGON_ASCENT, MOVE_CELEBRATE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE, gimmick: GIMMICK_MEGA); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_RAYQUAZA); + } +} diff --git a/test/battle/form_change/primal_reversion.c b/test/battle/form_change/primal_reversion.c index 3addb2afdb..c6bab2f77a 100644 --- a/test/battle/form_change/primal_reversion.c +++ b/test/battle/form_change/primal_reversion.c @@ -332,3 +332,18 @@ DOUBLE_BATTLE_TEST("Primal reversion and other switch-in effects trigger for all EXPECT_EQ(opponentRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE - 1); } } + +SINGLE_BATTLE_TEST("Primal reversion is reverted upon battle end") +{ + u32 species, item; + PARAMETRIZE { species = SPECIES_GROUDON; item = ITEM_RED_ORB; } + PARAMETRIZE { species = SPECIES_KYOGRE; item = ITEM_BLUE_ORB; } + GIVEN { + PLAYER(species) { Item(item); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); } + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), species); + } +} diff --git a/test/battle/form_change/status.c b/test/battle/form_change/status.c index 612c125497..02e346ed6e 100644 --- a/test/battle/form_change/status.c +++ b/test/battle/form_change/status.c @@ -35,6 +35,5 @@ SINGLE_BATTLE_TEST("Shaymin-Sky reverts to Shaymin-Land when frozen or frostbitt EXPECT_EQ(player->species, SPECIES_SHAYMIN_LAND); else EXPECT_EQ(player->species, SPECIES_SHAYMIN_SKY); - } } diff --git a/test/battle/form_change/ultra_burst.c b/test/battle/form_change/ultra_burst.c index edaf391d43..fcb0efded5 100644 --- a/test/battle/form_change/ultra_burst.c +++ b/test/battle/form_change/ultra_burst.c @@ -67,7 +67,7 @@ SINGLE_BATTLE_TEST("Ultra Burst affects turn order") MESSAGE("Necrozma used Celebrate!"); MESSAGE("The opposing Wobbuffet used Celebrate!"); } THEN { - ASSUME(player->speed == 263); + EXPECT_EQ(player->speed, 263); } } @@ -119,3 +119,19 @@ SINGLE_BATTLE_TEST("Ultra Burst and Mega Evolution can happen on the same turn") EXPECT_EQ(opponent->species, SPECIES_GARDEVOIR_MEGA); } } + +SINGLE_BATTLE_TEST("Necrozma returns its proper Form upon battle end after Ultra Bursting") +{ + u32 species; + PARAMETRIZE { species = SPECIES_NECROZMA_DUSK_MANE; } + PARAMETRIZE { species = SPECIES_NECROZMA_DAWN_WINGS; } + GIVEN { + PLAYER(species) { Item(ITEM_ULTRANECROZIUM_Z); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE, gimmick: GIMMICK_ULTRA_BURST); } + } THEN { + EXPECT_EQ(player->species, SPECIES_NECROZMA_ULTRA); + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), species); + } +} diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index f1683df156..e47cd2ca86 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -532,37 +532,6 @@ DOUBLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are immune to Instruct") } } -SINGLE_BATTLE_TEST("Dynamax: Pokemon with Gigantamax forms change upon Dynamaxing") -{ - u32 species; - bool32 gigantamaxFactor; - PARAMETRIZE { gigantamaxFactor = FALSE; species = SPECIES_VENUSAUR; } - PARAMETRIZE { gigantamaxFactor = TRUE; species = SPECIES_VENUSAUR_GMAX; } - GIVEN { - PLAYER(SPECIES_VENUSAUR) { GigantamaxFactor(gigantamaxFactor); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_SCRATCH, gimmick: GIMMICK_DYNAMAX); } - } THEN { - EXPECT_EQ(player->species, species); - } -} - -SINGLE_BATTLE_TEST("Dynamax: Pokemon with Gigantamax forms revert upon switching") -{ - GIVEN { - PLAYER(SPECIES_VENUSAUR); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_SCRATCH, gimmick: GIMMICK_DYNAMAX); } - TURN { SWITCH(player, 1); } - TURN { SWITCH(player, 0); } - } THEN { - EXPECT_EQ(player->species, SPECIES_VENUSAUR); - } -} - SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are not affected by Choice items", s16 damage) { u16 item;