From d44eff4e0c9857e1e8158414ca14addd9d04ccd0 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 3 Mar 2025 14:56:08 -0500 Subject: [PATCH 1/2] fix red card overwriting gBattlerAttacker causing subsequent MOVEEND cases checking attacker not to trigger properly --- asm/macros/battle_script.inc | 4 +++ data/battle_scripts_1.s | 17 +++++----- include/battle.h | 1 + src/battle_script_commands.c | 15 +++++++++ test/battle/hold_effect/red_card.c | 54 ++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 9 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index a169b3580b..e50cbcbe43 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -2376,6 +2376,10 @@ callnative BS_SwapStats .byte \stat .endm + + .macro restoresavedmove + callnative BS_RestoreSavedMove + .endm @ helpful macros .macro setstatchanger stat:req, stages:req, down:req diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 748fa2c5be..aaa03f0ac6 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6045,6 +6045,8 @@ BattleScript_RoarSuccessSwitch:: BattleScript_RoarSuccessSwitch_Ret: swapattackerwithtarget @ continuation of RedCardActivates restoretarget + restoreattacker + restoresavedmove setbyte sSWITCH_CASE, B_SWITCH_NORMAL return @@ -9519,6 +9521,8 @@ BattleScript_RedCardActivationNoSwitch:: waitmessage B_WAIT_TIME_LONG removeitem BS_SCRIPTING restoretarget + restoreattacker + restoresavedmove return BattleScript_RedCardActivates:: @@ -9537,22 +9541,17 @@ BattleScript_RedCardEnd: return BattleScript_RedCardIngrain: printstring STRINGID_PKMNANCHOREDITSELF +BattleScript_RedCardIngrainContinue: waitmessage B_WAIT_TIME_LONG removeitem BS_SCRIPTING restoretarget return BattleScript_RedCardSuctionCups: - printstring STRINGID_PKMNANCHORSITSELFWITH - waitmessage B_WAIT_TIME_LONG - removeitem BS_SCRIPTING - restoretarget - return + printstring STRINGID_PKMNANCHORSITSELFWITH + goto BattleScript_RedCardIngrainContinue BattleScript_RedCardDynamaxed: printstring STRINGID_MOVEBLOCKEDBYDYNAMAX - waitmessage B_WAIT_TIME_LONG - removeitem BS_SCRIPTING - restoretarget - return + goto BattleScript_RedCardIngrainContinue BattleScript_EjectButtonActivates:: makevisible BS_ATTACKER diff --git a/include/battle.h b/include/battle.h index 27227544d9..c9517b9b71 100644 --- a/include/battle.h +++ b/include/battle.h @@ -836,6 +836,7 @@ struct BattleStruct struct MessageStatus slideMessageStatus; u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT]; u8 embodyAspectBoost[NUM_BATTLE_SIDES]; + u16 savedMove; // backup current move for mid-turn switching, e.g. Red Card }; // The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index be57f4ae18..331ff44ff2 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7075,6 +7075,8 @@ static void Cmd_moveend(void) { gLastUsedItem = gBattleMons[battler].item; SaveBattlerTarget(battler); // save battler with red card + SaveBattlerAttacker(gBattlerAttacker); + gBattleStruct->savedMove = gCurrentMove; gBattleScripting.battler = battler; gEffectBattler = gBattlerAttacker; gBattleStruct->redCardActivates = TRUE; @@ -18637,3 +18639,16 @@ void BS_SetSteelsurge(void) gBattlescriptCurrInstr = cmd->nextInstr; } } + +void BS_RestoreSavedMove(void) +{ + NATIVE_ARGS(); + + if (gBattleStruct->savedMove == MOVE_NONE) + DebugPrintfLevel(MGBA_LOG_WARN, "restoresavedmove was called with no move saved!"); + + gCurrentMove = gBattleStruct->savedMove; + gBattleStruct->savedMove = MOVE_NONE; + gBattlescriptCurrInstr = cmd->nextInstr; +} + diff --git a/test/battle/hold_effect/red_card.c b/test/battle/hold_effect/red_card.c index 88b208cf50..80595b5b65 100644 --- a/test/battle/hold_effect/red_card.c +++ b/test/battle/hold_effect/red_card.c @@ -520,3 +520,57 @@ SINGLE_BATTLE_TEST("Red Card activates before Eject Pack") ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); } } + +DOUBLE_BATTLE_TEST("Dancer still activates after Red Card") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) ; + PLAYER(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); } + PLAYER(SPECIES_CHANSEY); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } + OPPONENT(SPECIES_BULBASAUR); + OPPONENT(SPECIES_SHUCKLE); + } WHEN { + TURN { MOVE(playerLeft, MOVE_FIERY_DANCE, target: opponentLeft); } + } SCENE { + MESSAGE("Wobbuffet used Fiery Dance!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerLeft); + HP_BAR(opponentLeft); + // Red card trigger + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft); + MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!"); + MESSAGE("Chansey was dragged out!"); + // Dancer + ABILITY_POPUP(playerRight, ABILITY_DANCER); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerRight); + HP_BAR(opponentLeft); + } +} + +DOUBLE_BATTLE_TEST("Red Card: Dancer still activate after Red Card even if blocked by Suction Cups") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SUCTION_CUPS); } + PLAYER(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); } + PLAYER(SPECIES_CHANSEY); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } + OPPONENT(SPECIES_BULBASAUR); + OPPONENT(SPECIES_SHUCKLE); + } WHEN { + TURN { MOVE(playerLeft, MOVE_FIERY_DANCE, target: opponentLeft); } + } SCENE { + MESSAGE("Wobbuffet used Fiery Dance!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerLeft); + HP_BAR(opponentLeft); + // red card trigger + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft); + MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!"); + MESSAGE("Wobbuffet anchors itself with Suction Cups!"); + NOT MESSAGE("Chansey was dragged out!"); + // Dancer + ABILITY_POPUP(playerRight, ABILITY_DANCER); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerRight); + HP_BAR(opponentLeft); + } +} + From 26c73dca32a4b1cab0c7a4b56554588d648a1289 Mon Sep 17 00:00:00 2001 From: ghoulslash Date: Mon, 3 Mar 2025 17:01:15 -0500 Subject: [PATCH 2/2] move red card dancer tests to dancer.c --- test/battle/ability/dancer.c | 54 ++++++++++++++++++++++++++++++ test/battle/hold_effect/red_card.c | 53 ----------------------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/test/battle/ability/dancer.c b/test/battle/ability/dancer.c index 657a126470..1e4c61dba0 100644 --- a/test/battle/ability/dancer.c +++ b/test/battle/ability/dancer.c @@ -246,3 +246,57 @@ DOUBLE_BATTLE_TEST("Dancer doesn't call a move that didn't execute due to Powder } } } + + +DOUBLE_BATTLE_TEST("Dancer still activates after Red Card") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) ; + PLAYER(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); } + PLAYER(SPECIES_CHANSEY); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } + OPPONENT(SPECIES_BULBASAUR); + OPPONENT(SPECIES_SHUCKLE); + } WHEN { + TURN { MOVE(playerLeft, MOVE_FIERY_DANCE, target: opponentLeft); } + } SCENE { + MESSAGE("Wobbuffet used Fiery Dance!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerLeft); + HP_BAR(opponentLeft); + // Red card trigger + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft); + MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!"); + MESSAGE("Chansey was dragged out!"); + // Dancer + ABILITY_POPUP(playerRight, ABILITY_DANCER); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerRight); + HP_BAR(opponentLeft); + } +} + +DOUBLE_BATTLE_TEST("Dancer still activate after Red Card even if blocked by Suction Cups") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SUCTION_CUPS); } + PLAYER(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); } + PLAYER(SPECIES_CHANSEY); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } + OPPONENT(SPECIES_BULBASAUR); + OPPONENT(SPECIES_SHUCKLE); + } WHEN { + TURN { MOVE(playerLeft, MOVE_FIERY_DANCE, target: opponentLeft); } + } SCENE { + MESSAGE("Wobbuffet used Fiery Dance!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerLeft); + HP_BAR(opponentLeft); + // red card trigger + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft); + MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!"); + MESSAGE("Wobbuffet anchors itself with Suction Cups!"); + NOT MESSAGE("Chansey was dragged out!"); + // Dancer + ABILITY_POPUP(playerRight, ABILITY_DANCER); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerRight); + HP_BAR(opponentLeft); + } +} diff --git a/test/battle/hold_effect/red_card.c b/test/battle/hold_effect/red_card.c index 80595b5b65..8513e795b9 100644 --- a/test/battle/hold_effect/red_card.c +++ b/test/battle/hold_effect/red_card.c @@ -521,56 +521,3 @@ SINGLE_BATTLE_TEST("Red Card activates before Eject Pack") } } -DOUBLE_BATTLE_TEST("Dancer still activates after Red Card") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) ; - PLAYER(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); } - PLAYER(SPECIES_CHANSEY); - OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } - OPPONENT(SPECIES_BULBASAUR); - OPPONENT(SPECIES_SHUCKLE); - } WHEN { - TURN { MOVE(playerLeft, MOVE_FIERY_DANCE, target: opponentLeft); } - } SCENE { - MESSAGE("Wobbuffet used Fiery Dance!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerLeft); - HP_BAR(opponentLeft); - // Red card trigger - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft); - MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!"); - MESSAGE("Chansey was dragged out!"); - // Dancer - ABILITY_POPUP(playerRight, ABILITY_DANCER); - ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerRight); - HP_BAR(opponentLeft); - } -} - -DOUBLE_BATTLE_TEST("Red Card: Dancer still activate after Red Card even if blocked by Suction Cups") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SUCTION_CUPS); } - PLAYER(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); } - PLAYER(SPECIES_CHANSEY); - OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); } - OPPONENT(SPECIES_BULBASAUR); - OPPONENT(SPECIES_SHUCKLE); - } WHEN { - TURN { MOVE(playerLeft, MOVE_FIERY_DANCE, target: opponentLeft); } - } SCENE { - MESSAGE("Wobbuffet used Fiery Dance!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerLeft); - HP_BAR(opponentLeft); - // red card trigger - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft); - MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!"); - MESSAGE("Wobbuffet anchors itself with Suction Cups!"); - NOT MESSAGE("Chansey was dragged out!"); - // Dancer - ABILITY_POPUP(playerRight, ABILITY_DANCER); - ANIMATION(ANIM_TYPE_MOVE, MOVE_FIERY_DANCE, playerRight); - HP_BAR(opponentLeft); - } -} -