From e2df932775b46453e83183ac45f5e965b531ed1c Mon Sep 17 00:00:00 2001 From: GGbond Date: Fri, 20 Feb 2026 23:10:18 +0800 Subject: [PATCH 1/9] Fix incorrect Adaptability interaction with non Tera type moves after Terastalization (#9272) --- src/battle_terastal.c | 10 +++++--- test/battle/ability/adaptability.c | 37 +++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/battle_terastal.c b/src/battle_terastal.c index f0e720c93e..320e236662 100644 --- a/src/battle_terastal.c +++ b/src/battle_terastal.c @@ -163,15 +163,19 @@ uq4_12_t GetTeraMultiplier(struct DamageContext *ctx) else return UQ_4_12(2.0); } - // Base or Tera type only. - else if ((ctx->moveType == teraType && !IS_BATTLER_OF_BASE_TYPE(ctx->battlerAtk, ctx->moveType)) - || (ctx->moveType != teraType && IS_BATTLER_OF_BASE_TYPE(ctx->battlerAtk, ctx->moveType))) + // Tera type only (Adaptability applies). + else if (ctx->moveType == teraType && !IS_BATTLER_OF_BASE_TYPE(ctx->battlerAtk, ctx->moveType)) { if (ctx->abilityAtk == ABILITY_ADAPTABILITY) return UQ_4_12(2.0); else return UQ_4_12(1.5); } + // Base type only (Adaptability does not apply while Terastallized). + else if (ctx->moveType != teraType && IS_BATTLER_OF_BASE_TYPE(ctx->battlerAtk, ctx->moveType)) + { + return UQ_4_12(1.5); + } // Neither base or Tera type. else { diff --git a/test/battle/ability/adaptability.c b/test/battle/ability/adaptability.c index 876dac212c..ba54590cd2 100644 --- a/test/battle/ability/adaptability.c +++ b/test/battle/ability/adaptability.c @@ -61,4 +61,39 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing into the same type with Adaptability g } } -TO_DO_BATTLE_TEST("Adaptability does not affect Stellar-type moves"); +SINGLE_BATTLE_TEST("(TERA) Adaptability does not increase non-Tera base STAB beyond 1.5x", s16 damage) +{ + u32 move; + PARAMETRIZE { move = MOVE_GUST; } + PARAMETRIZE { move = MOVE_WATER_GUN; } + GIVEN { + PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_NORMAL); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move, gimmick: GIMMICK_TERA); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + // With Adaptability, non-Tera base type should still be 1.5x STAB (not 2.0x). + EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("(TERA) Adaptability does not affect Stellar-type moves", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_HYPER_CUTTER; } + PARAMETRIZE { ability = ABILITY_ADAPTABILITY; } + GIVEN { + PLAYER(SPECIES_CRAWDAUNT) { Ability(ability); TeraType(TYPE_STELLAR); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TERA_BLAST, gimmick: GIMMICK_TERA); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_BLAST, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + } +} From d57a067f5e2716ead252896ea59635597b87794b Mon Sep 17 00:00:00 2001 From: GGbond Date: Sat, 21 Feb 2026 02:17:07 +0800 Subject: [PATCH 2/9] Fix Ability Shield exemption when Neutralizing Gas ends (#9273) Co-authored-by: PhallenTree <168426989+PhallenTree@users.noreply.github.com> --- src/battle_script_commands.c | 6 +++++ test/battle/hold_effect/ability_shield.c | 32 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 225c411095..a80ed670e0 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -16560,6 +16560,12 @@ void BS_JumpIfAbilityCantBeReactivated(void) u32 battler = GetBattlerForBattleScript(cmd->battler); u32 ability = gBattleMons[battler].ability; + if (GetBattlerHoldEffectIgnoreAbility(battler) == HOLD_EFFECT_ABILITY_SHIELD) + { + gBattlescriptCurrInstr = cmd->jumpInstr; + return; + } + switch (ability) { case ABILITY_IMPOSTER: diff --git a/test/battle/hold_effect/ability_shield.c b/test/battle/hold_effect/ability_shield.c index 6e5a9884b8..e0798c9cfd 100644 --- a/test/battle/hold_effect/ability_shield.c +++ b/test/battle/hold_effect/ability_shield.c @@ -35,6 +35,38 @@ SINGLE_BATTLE_TEST("Ability Shield protects against Neutralizing Gas") } } +DOUBLE_BATTLE_TEST("Ability Shield prevents Intimidate from reactivating after Neutralizing Gas ends") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Speed(5); } + PLAYER(SPECIES_WYNAUT) { Speed(4); } + OPPONENT(SPECIES_KOFFING) { Ability(ABILITY_NEUTRALIZING_GAS); HP(1); Speed(1); } + OPPONENT(SPECIES_GYARADOS) { Ability(ABILITY_INTIMIDATE); Item(ITEM_ABILITY_SHIELD); Speed(3); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_SCRATCH, target: opponentLeft); } + } SCENE { + ABILITY_POPUP(opponentLeft, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing gas filled the area!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight); + MESSAGE("The opposing Gyarados's Ability is protected by the effects of its Ability Shield!"); + ABILITY_POPUP(opponentRight, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, playerLeft); + HP_BAR(opponentLeft); + MESSAGE("The effects of the neutralizing gas wore off!"); + NONE_OF { + ABILITY_POPUP(opponentRight, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + } + MESSAGE("The opposing Koffing fainted!"); + } THEN { + EXPECT_EQ(playerLeft->statStages[STAT_ATK], DEFAULT_STAT_STAGE - 1); + EXPECT_EQ(playerRight->statStages[STAT_ATK], DEFAULT_STAT_STAGE - 1); + } +} + SINGLE_BATTLE_TEST("Ability Shield protects against Mold Breaker (no message)") { u32 item; From b7755887cc0b2fb16f37e17197823680f0004752 Mon Sep 17 00:00:00 2001 From: GGbond Date: Sat, 21 Feb 2026 17:23:49 +0800 Subject: [PATCH 3/9] Fix Tickle to be blocked by Substitute in Gen 4+ (#9288) --- data/battle_scripts_1.s | 1 + test/battle/move_effect/tickle.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 043a7fbd24..6ae21720cc 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -4319,6 +4319,7 @@ BattleScript_EffectWaterSport:: BattleScript_EffectTickle:: attackcanceler + jumpifsubstituteblocks BattleScript_ButItFailed jumpifstat BS_TARGET, CMP_GREATER_THAN, STAT_ATK, MIN_STAT_STAGE, BattleScript_TickleDoMoveAnim jumpifstat BS_TARGET, CMP_EQUAL, STAT_DEF, MIN_STAT_STAGE, BattleScript_CantLowerMultipleStats BattleScript_TickleDoMoveAnim:: diff --git a/test/battle/move_effect/tickle.c b/test/battle/move_effect/tickle.c index 3a878868fd..8513340f4b 100644 --- a/test/battle/move_effect/tickle.c +++ b/test/battle/move_effect/tickle.c @@ -21,3 +21,20 @@ SINGLE_BATTLE_TEST("Tickle reduces the target's Attack and Defense by 1 stage ea EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE - 1); } } + +SINGLE_BATTLE_TEST("Tickle is blocked by Substitute (Gen4+)") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TICKLE, MOVE_CELEBRATE); Speed(5); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SUBSTITUTE, MOVE_CELEBRATE); Speed(10); } + } WHEN { + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_TICKLE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TICKLE, player); + MESSAGE("But it failed!"); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE); + EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE); + } +} From ccf71d2d6aab90c7f7ad523a8f9d180fc4f1fd55 Mon Sep 17 00:00:00 2001 From: GGbond Date: Sat, 21 Feb 2026 17:24:43 +0800 Subject: [PATCH 4/9] Fix Venom Drench bypassing Substitute (#9289) --- data/battle_scripts_1.s | 1 + test/battle/move_effect/venom_drench.c | 40 +++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 6ae21720cc..8a24a0043b 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1652,6 +1652,7 @@ BattleScript_ToxicThreadTryPsn:: BattleScript_EffectVenomDrench:: attackcanceler + jumpifsubstituteblocks BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_PSN_ANY, BattleScript_EffectVenomDrenchCanBeUsed goto BattleScript_ButItFailed BattleScript_EffectVenomDrenchCanBeUsed: diff --git a/test/battle/move_effect/venom_drench.c b/test/battle/move_effect/venom_drench.c index 00dac65858..aa09061f22 100644 --- a/test/battle/move_effect/venom_drench.c +++ b/test/battle/move_effect/venom_drench.c @@ -1,4 +1,42 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Venom Drench (Move Effect) test titles") +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_VENOM_DRENCH) == EFFECT_VENOM_DRENCH); +} + +SINGLE_BATTLE_TEST("Venom Drench lowers stats of a poisoned target") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_VENOM_DRENCH); } + OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } + } WHEN { + TURN { MOVE(player, MOVE_VENOM_DRENCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_VENOM_DRENCH, player); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE - 1); + EXPECT_EQ(opponent->statStages[STAT_SPATK], DEFAULT_STAT_STAGE - 1); + EXPECT_EQ(opponent->statStages[STAT_SPEED], DEFAULT_STAT_STAGE - 1); + } +} + +SINGLE_BATTLE_TEST("Venom Drench is blocked by Substitute") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE); + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_VENOM_DRENCH, MOVE_CELEBRATE); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SUBSTITUTE, MOVE_CELEBRATE); Status1(STATUS1_POISON); } + } WHEN { + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_CELEBRATE); } + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_VENOM_DRENCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUBSTITUTE, opponent); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_VENOM_DRENCH, player); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE); + EXPECT_EQ(opponent->statStages[STAT_SPATK], DEFAULT_STAT_STAGE); + EXPECT_EQ(opponent->statStages[STAT_SPEED], DEFAULT_STAT_STAGE); + } +} From ae3369e87fabf5add6c2c16cac9923d6401ab506 Mon Sep 17 00:00:00 2001 From: GGbond Date: Sat, 21 Feb 2026 18:46:51 +0800 Subject: [PATCH 5/9] Fix Assist to account for temporarily changed moves in Gen 5+ (#9287) --- src/battle_util.c | 17 ++++++++++++++++- test/battle/move_effect/assist.c | 23 ++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index dd08a155ef..9787bbe282 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -11215,11 +11215,21 @@ static u32 GetAssistMove(void) u32 move = MOVE_NONE; s32 chooseableMovesNo = 0; struct Pokemon *party; + u8 battlerByPartyId[PARTY_SIZE]; u16 *validMoves = Alloc(sizeof(u16) * PARTY_SIZE * MAX_MON_MOVES); if (validMoves != NULL) { party = GetBattlerParty(gBattlerAttacker); + for (u32 i = 0; i < PARTY_SIZE; i++) + battlerByPartyId[i] = MAX_BATTLERS_COUNT; + for (u32 battler = 0; battler < gBattlersCount; battler++) + { + if (GetBattlerSide(battler) != GetBattlerSide(gBattlerAttacker)) + continue; + if (gBattlerPartyIndexes[battler] < PARTY_SIZE) + battlerByPartyId[gBattlerPartyIndexes[battler]] = battler; + } for (u32 monId = 0; monId < PARTY_SIZE; monId++) { @@ -11232,7 +11242,12 @@ static u32 GetAssistMove(void) for (u32 moveId = 0; moveId < MAX_MON_MOVES; moveId++) { - u16 move = GetMonData(&party[monId], MON_DATA_MOVE1 + moveId); + u16 move; + + if (battlerByPartyId[monId] != MAX_BATTLERS_COUNT) + move = gBattleMons[battlerByPartyId[monId]].moves[moveId]; + else + move = GetMonData(&party[monId], MON_DATA_MOVE1 + moveId); if (IsMoveAssistBanned(move)) continue; diff --git a/test/battle/move_effect/assist.c b/test/battle/move_effect/assist.c index 3a380ef125..6f236af983 100644 --- a/test/battle/move_effect/assist.c +++ b/test/battle/move_effect/assist.c @@ -12,7 +12,6 @@ TO_DO_BATTLE_TEST("Assist can call moves with no PP left"); TO_DO_BATTLE_TEST("Assist can call moves from a fainted party member"); TO_DO_BATTLE_TEST("Assist can call moves that are blocked to its partners"); // Eg. double battle parter blocked by Disable TO_DO_BATTLE_TEST("Assist can only call the original moves of a Transformed partner (Gen4 only)"); -TO_DO_BATTLE_TEST("Assist can only call the current moves of a Transformed partner (Gen5+)"); TO_DO_BATTLE_TEST("Assist cannot call a Mimicked move (Gen4 only)"); TO_DO_BATTLE_TEST("Assist can call a Mimicked move but not the original Mimic (Gen5+)"); TO_DO_BATTLE_TEST("Assist can call moves in unhatched Eggs (Gen5 only)"); @@ -57,3 +56,25 @@ SINGLE_BATTLE_TEST("Assisted move triggers correct weakness berry") ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player); } } + +DOUBLE_BATTLE_TEST("Assist can only call the current moves of a Transformed partner (Gen5+)") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_TRANSFORM) == EFFECT_TRANSFORM); + PLAYER(SPECIES_WOBBUFFET) { Speed(3); Moves(MOVE_ASSIST); } + PLAYER(SPECIES_DITTO) { Speed(4); Moves(MOVE_TRANSFORM); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(2); Moves(MOVE_SCRATCH); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(1); } + } WHEN { + TURN { + MOVE(playerRight, MOVE_TRANSFORM, target: opponentLeft); + MOVE(playerLeft, MOVE_ASSIST); + MOVE(opponentLeft, MOVE_SCRATCH, target: playerRight); + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRANSFORM, playerRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ASSIST, playerLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, playerLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponentLeft); + } +} From cb5db2491fae4e5761b658da6aed3a7a0900dae2 Mon Sep 17 00:00:00 2001 From: luuma <31407427+luuma@users.noreply.github.com> Date: Sat, 21 Feb 2026 16:45:32 +0000 Subject: [PATCH 6/9] Fixes Minior not appearing in Meteor form when encountered in the wild (#9282) --- include/constants/form_change_types.h | 2 ++ src/battle_main.c | 6 ++++- src/data/pokemon/form_change_tables.h | 8 +++++- src/pokemon.c | 1 + test/battle/ability/shields_down.c | 36 +++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/constants/form_change_types.h b/include/constants/form_change_types.h index f43f3bddc6..1f9a58cd94 100644 --- a/include/constants/form_change_types.h +++ b/include/constants/form_change_types.h @@ -137,6 +137,8 @@ enum FormChanges FORM_CHANGE_OVERWORLD_WEATHER, // Form change that activates when the Pokémon is deposited into the PC or Daycare. FORM_CHANGE_DEPOSIT, + // Form change for Minior, which appears unchanged when encountered in the wild + FORM_CHANGE_BEGIN_WILD_ENCOUNTER, }; #endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H diff --git a/src/battle_main.c b/src/battle_main.c index 708448f1b7..6f2eeb5df4 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -582,7 +582,11 @@ static void CB2_InitBattleInternal(void) TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_BEGIN_BATTLE); TryFormChange(i, B_SIDE_OPPONENT, FORM_CHANGE_BEGIN_BATTLE); } - + if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER)) + { + TryFormChange(0, B_SIDE_OPPONENT, FORM_CHANGE_BEGIN_WILD_ENCOUNTER); + TryFormChange(1, B_SIDE_OPPONENT, FORM_CHANGE_BEGIN_WILD_ENCOUNTER);// Only tries to change the first two opposing slots, assuming these are the only ones occupied in a wild battle. + } if (TESTING) { gPlayerPartyCount = CalculatePartyCount(gPlayerParty); diff --git a/src/data/pokemon/form_change_tables.h b/src/data/pokemon/form_change_tables.h index 6926e20ef9..9e1eaaa6f7 100644 --- a/src/data/pokemon/form_change_tables.h +++ b/src/data/pokemon/form_change_tables.h @@ -1316,10 +1316,10 @@ static const struct FormChange sSilvallyFormChangeTable[] = {FORM_CHANGE_TERMINATOR}, }; #endif //P_FAMILY_TYPE_NULL - #if P_FAMILY_MINIOR static const struct FormChange sMiniorRedFormChangeTable[] = { + {FORM_CHANGE_BEGIN_WILD_ENCOUNTER, SPECIES_MINIOR_METEOR_RED}, {FORM_CHANGE_BEGIN_BATTLE, SPECIES_MINIOR_CORE_RED}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_RED, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_RED, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50}, @@ -1330,6 +1330,7 @@ static const struct FormChange sMiniorRedFormChangeTable[] = }; static const struct FormChange sMiniorBlueFormChangeTable[] = { + {FORM_CHANGE_BEGIN_WILD_ENCOUNTER, SPECIES_MINIOR_METEOR_BLUE}, {FORM_CHANGE_BEGIN_BATTLE, SPECIES_MINIOR_CORE_BLUE}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_BLUE, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_BLUE, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50}, @@ -1340,6 +1341,7 @@ static const struct FormChange sMiniorBlueFormChangeTable[] = }; static const struct FormChange sMiniorGreenFormChangeTable[] = { + {FORM_CHANGE_BEGIN_WILD_ENCOUNTER, SPECIES_MINIOR_METEOR_GREEN}, {FORM_CHANGE_BEGIN_BATTLE, SPECIES_MINIOR_CORE_GREEN}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_GREEN, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_GREEN, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50}, @@ -1350,6 +1352,7 @@ static const struct FormChange sMiniorGreenFormChangeTable[] = }; static const struct FormChange sMiniorIndigoFormChangeTable[] = { + {FORM_CHANGE_BEGIN_WILD_ENCOUNTER, SPECIES_MINIOR_METEOR_INDIGO}, {FORM_CHANGE_BEGIN_BATTLE, SPECIES_MINIOR_CORE_INDIGO}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_INDIGO, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_INDIGO, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50}, @@ -1360,6 +1363,7 @@ static const struct FormChange sMiniorIndigoFormChangeTable[] = }; static const struct FormChange sMiniorOrangeFormChangeTable[] = { + {FORM_CHANGE_BEGIN_WILD_ENCOUNTER, SPECIES_MINIOR_METEOR_ORANGE}, {FORM_CHANGE_BEGIN_BATTLE, SPECIES_MINIOR_CORE_ORANGE}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_ORANGE, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_ORANGE, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50}, @@ -1370,6 +1374,7 @@ static const struct FormChange sMiniorOrangeFormChangeTable[] = }; static const struct FormChange sMiniorVioletFormChangeTable[] = { + {FORM_CHANGE_BEGIN_WILD_ENCOUNTER, SPECIES_MINIOR_METEOR_VIOLET}, {FORM_CHANGE_BEGIN_BATTLE, SPECIES_MINIOR_CORE_VIOLET}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_VIOLET, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_VIOLET, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50}, @@ -1379,6 +1384,7 @@ static const struct FormChange sMiniorVioletFormChangeTable[] = {FORM_CHANGE_TERMINATOR}, }; static const struct FormChange sMiniorYellowFormChangeTable[] = { + {FORM_CHANGE_BEGIN_WILD_ENCOUNTER, SPECIES_MINIOR_METEOR_YELLOW}, {FORM_CHANGE_BEGIN_BATTLE, SPECIES_MINIOR_CORE_YELLOW}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_YELLOW, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50}, {FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_YELLOW, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50}, diff --git a/src/pokemon.c b/src/pokemon.c index 96b661bf52..1df1510bbd 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -6970,6 +6970,7 @@ u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, enum FormChanges case FORM_CHANGE_DEPOSIT: case FORM_CHANGE_FAINT: case FORM_CHANGE_DAYS_PASSED: + case FORM_CHANGE_BEGIN_WILD_ENCOUNTER: targetSpecies = formChanges[i].targetSpecies; break; case FORM_CHANGE_STATUS: diff --git a/test/battle/ability/shields_down.c b/test/battle/ability/shields_down.c index d16aa240da..ca1ade2c37 100644 --- a/test/battle/ability/shields_down.c +++ b/test/battle/ability/shields_down.c @@ -75,3 +75,39 @@ SINGLE_BATTLE_TEST("Shields Down protects Minior Meteor from status conditions") EXPECT(opponent->status1 & STATUS1_BURN); } } + +WILD_BATTLE_TEST("Wild Minior appear in Meteor form without transforming")// To be replaced with WILD_DOUBLE_BATTLE_TEST when that is made possible. +{ + GIVEN { + PLAYER(SPECIES_MINIOR_CORE) { Ability(ABILITY_SHIELDS_DOWN); } + OPPONENT(SPECIES_MINIOR_CORE) { Ability(ABILITY_SHIELDS_DOWN); } + } WHEN { + TURN {} + } SCENE { + ABILITY_POPUP(player, ABILITY_SHIELDS_DOWN); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); + NONE_OF { + ABILITY_POPUP(opponent, ABILITY_SHIELDS_DOWN); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, opponent); + } + } THEN { + EXPECT_EQ(opponent->species, SPECIES_MINIOR_METEOR); + EXPECT_EQ(player->species, SPECIES_MINIOR_METEOR); + } +} + +SINGLE_BATTLE_TEST("Trainers' Minior appear in Core form") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) + OPPONENT(SPECIES_MINIOR_METEOR) { Ability(ABILITY_SHIELDS_DOWN); } + } WHEN { + TURN {} + } SCENE { + ABILITY_POPUP(opponent, ABILITY_SHIELDS_DOWN); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, opponent); + } THEN { + EXPECT_EQ(opponent->species, SPECIES_MINIOR_METEOR); + } +} + From b20b7fda5b02cc4e302260b4cbbea2aa9048b9fb Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 22:27:59 +0100 Subject: [PATCH 7/9] add KnightGallade as a contributor for bug (#9296) Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ CREDITS.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 627b52827a..3d356bbc97 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -651,6 +651,15 @@ "contributions": [ "bug" ] + }, + { + "login": "KnightGallade", + "name": "KnightGallade", + "avatar_url": "https://avatars.githubusercontent.com/u/189022270?v=4", + "profile": "https://github.com/KnightGallade", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/CREDITS.md b/CREDITS.md index c3d7df099a..133208fa95 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -93,6 +93,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d PacFire
PacFire

🎨 ChrispyChris27
ChrispyChris27

💻 LogicalLlama
LogicalLlama

🐛 + KnightGallade
KnightGallade

🐛 From 931663568713a75f7f7f1ffe5b68221b6d892073 Mon Sep 17 00:00:00 2001 From: Hedara Date: Sun, 22 Feb 2026 13:36:32 +0100 Subject: [PATCH 8/9] Fix setting the wall clock crashing with OW_USE_FAKE_RTC set to FALSE and LTO=1 --- src/fake_rtc.c | 6 ++++++ src/rtc.c | 3 ++- src/scrcmd.c | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/fake_rtc.c b/src/fake_rtc.c index 2024065b7d..c6b68d9105 100644 --- a/src/fake_rtc.c +++ b/src/fake_rtc.c @@ -50,6 +50,9 @@ void FakeRtc_TickTimeForward(void) void FakeRtc_AdvanceTimeBy(u32 days, u32 hours, u32 minutes, u32 seconds) { + if (!OW_USE_FAKE_RTC) + return; + struct DateTime dateTime; struct SiiRtcInfo *rtc = FakeRtc_GetCurrentTime(); @@ -63,6 +66,9 @@ void FakeRtc_AdvanceTimeBy(u32 days, u32 hours, u32 minutes, u32 seconds) void FakeRtc_ForwardTimeTo(u32 hour, u32 minute, u32 second) { + if (!OW_USE_FAKE_RTC) + return; + Script_PauseFakeRtc(); struct Time diff, target; struct SiiRtcInfo *fakeRtc = FakeRtc_GetCurrentTime(); diff --git a/src/rtc.c b/src/rtc.c index ace7bfb0c4..adab416446 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -349,7 +349,8 @@ void RtcCalcLocalTimeOffset(s32 days, s32 hours, s32 minutes, s32 seconds) gLocalTime.hours = hours; gLocalTime.minutes = minutes; gLocalTime.seconds = seconds; - FakeRtc_ManuallySetTime(gLocalTime.days, gLocalTime.hours, gLocalTime.minutes, seconds); + if (!OW_USE_FAKE_RTC) + FakeRtc_ManuallySetTime(gLocalTime.days, gLocalTime.hours, gLocalTime.minutes, seconds); RtcGetInfo(&sRtc); RtcCalcTimeDifference(&sRtc, &gSaveBlock2Ptr->localTimeOffset, &gLocalTime); } diff --git a/src/scrcmd.c b/src/scrcmd.c index e05190c18d..7983f54b43 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -3239,6 +3239,9 @@ bool8 ScrCmd_fwdtime(struct ScriptContext *ctx) bool8 ScrCmd_fwdweekday(struct ScriptContext *ctx) { + if (!OW_USE_FAKE_RTC) + return FALSE; + struct SiiRtcInfo *rtc = FakeRtc_GetCurrentTime(); u32 weekdayTarget = ScriptReadWord(ctx); From 484eef4143cbe7593a9a649cc7c972dcd5bc5855 Mon Sep 17 00:00:00 2001 From: KnightGallade Date: Sun, 22 Feb 2026 15:14:03 +0100 Subject: [PATCH 9/9] Allow Power Construct Animation (#9298) --- src/battle_script_commands.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a80ed670e0..4fd3c472e8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -5538,6 +5538,7 @@ static void PlayAnimation(u32 battler, u8 animId, const u16 *argPtr, const u8 *n || animId == B_ANIM_FORM_CHANGE || animId == B_ANIM_SUBSTITUTE_FADE || animId == B_ANIM_PRIMAL_REVERSION + || animId == B_ANIM_POWER_CONSTRUCT || animId == B_ANIM_ULTRA_BURST || animId == B_ANIM_TERA_CHARGE || animId == B_ANIM_TERA_ACTIVATE)