fix red card overwriting gBattlerAttacker causing subsequent MOVEEND cases checking attacker not to trigger properly

This commit is contained in:
ghoulslash 2025-03-03 14:56:08 -05:00
parent ec8344c2ad
commit d44eff4e0c
5 changed files with 82 additions and 9 deletions

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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;
}

View File

@ -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);
}
}