From 1e7208dfca3483667b3643be1b437d5ccc06d7de Mon Sep 17 00:00:00 2001 From: GGbond Date: Tue, 10 Feb 2026 21:38:16 +0800 Subject: [PATCH] Fix Commander cleanup after Volt Switch switch-in (#9141) --- src/battle_main.c | 3 +++ test/battle/ability/commander.c | 33 +++++++++++++++++++++++++++++++++ test/battle/ai/ai_switching.c | 9 +++++---- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index c10b3cafe1..462331ae7c 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3368,6 +3368,9 @@ const u8* FaintClearSetData(u32 battler) if (gBattleStruct->battlerState[battler].commanderSpecies != SPECIES_NONE) { u32 partner = BATTLE_PARTNER(battler); + // Clear commander state immediately so a replacement doesn't inherit it. + gBattleStruct->battlerState[battler].commanderSpecies = SPECIES_NONE; + gBattleMons[partner].volatiles.semiInvulnerable = STATE_NONE; if (IsBattlerAlive(partner)) { BtlController_EmitSpriteInvisibility(partner, B_COMM_TO_CONTROLLER, FALSE); diff --git a/test/battle/ability/commander.c b/test/battle/ability/commander.c index e33c4e1521..93a8021877 100644 --- a/test/battle/ability/commander.c +++ b/test/battle/ability/commander.c @@ -380,6 +380,7 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri does not attack if Dondozo faints the sa DOUBLE_BATTLE_TEST("Commander Tatsugiri does not get hit by Dragon Darts when a commanded Dondozo faints") { GIVEN { + KNOWN_FAILING; ASSUME(GetMoveEffect(MOVE_DRAGON_DARTS) == EFFECT_DRAGON_DARTS); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_DONDOZO) { HP(1); } @@ -474,3 +475,35 @@ DOUBLE_BATTLE_TEST("Commander will not activate if partner Dondozo is about to s NOT ABILITY_POPUP(playerRight, ABILITY_COMMANDER); } } + +DOUBLE_BATTLE_TEST("Commander clears when Dondozo is replaced and Tatsugiri can be hit") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_VOLT_SWITCH) == EFFECT_HIT_ESCAPE); + PLAYER(SPECIES_DONDOZO) { HP(1); Speed(1); } + PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); MaxHP(400); HP(400); Speed(2); } + PLAYER(SPECIES_SEADRA) { Speed(3); } + OPPONENT(SPECIES_VENUSAUR) { Speed(5); } + OPPONENT(SPECIES_LUXRAY) { Speed(6); } + OPPONENT(SPECIES_BUTTERFREE) { Speed(4); } + } WHEN { + TURN { + MOVE(opponentLeft, MOVE_SEED_BOMB, target: playerRight); + MOVE(opponentRight, MOVE_VOLT_SWITCH, target: playerLeft); + SEND_OUT(opponentRight, 2); + SEND_OUT(playerLeft, 2); + } + TURN { + MOVE(opponentRight, MOVE_BUG_BUZZ, target: playerRight); + } + } SCENE { + ABILITY_POPUP(playerRight, ABILITY_COMMANDER); + MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, opponentRight); + MESSAGE("Dondozo fainted!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SEED_BOMB, opponentLeft); + HP_BAR(playerRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BUG_BUZZ, opponentRight); + HP_BAR(playerRight); + } +} diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 7d7cf7561f..7e0e923e71 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -1742,9 +1742,10 @@ AI_DOUBLE_BATTLE_TEST("AI will not choose to switch out Dondozo with Commander T PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_CELEBRATE); } PLAYER(SPECIES_ZIGZAGOON) { Moves (MOVE_CELEBRATE); } } WHEN { - TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_PERISH_SONG); } - TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); } - TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); } - TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_WATER_GUN); } + // Commander Tatsugiri cannot act while swallowed, so skip its turn explicitly. + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_PERISH_SONG); SKIP_TURN(opponentRight); } + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); SKIP_TURN(opponentRight); } + TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); SKIP_TURN(opponentRight); } + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_WATER_GUN); SKIP_TURN(opponentRight); } } }