diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index c2372ea830..8267e0c195 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -9628,6 +9628,13 @@ BattleScript_EjectPackActivates:: jumpifcantswitch BS_SCRIPTING, BattleScript_EjectButtonEnd goto BattleScript_EjectPackActivate_Ret +BattleScript_EjectPackMissesTiming:: + playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT + printstring STRINGID_EJECTBUTTONACTIVATE + waitmessage B_WAIT_TIME_LONG + removeitem BS_SCRIPTING + return + BattleScript_DarkTypePreventsPrankster:: attackstring ppreduce diff --git a/include/battle.h b/include/battle.h index f2e5297189..fda1639fa5 100644 --- a/include/battle.h +++ b/include/battle.h @@ -803,6 +803,7 @@ struct BattleStruct u32 stellarBoostFlags[NUM_BATTLE_SIDES]; // stored as a bitfield of flags for all types for each side u8 fickleBeamBoosted:1; u8 obedienceResult:3; + u8 redCardActivates:1; u8 usedMicleBerry; }; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 71daf5f66f..4e34a81da8 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -418,6 +418,7 @@ extern const u8 BattleScript_EjectButtonActivates[]; extern const u8 BattleScript_EjectPackActivate_Ret[]; extern const u8 BattleScript_EjectPackActivate_End2[]; extern const u8 BattleScript_EjectPackActivates[]; +extern const u8 BattleScript_EjectPackMissesTiming[]; extern const u8 BattleScript_MentalHerbCureRet[]; extern const u8 BattleScript_MentalHerbCureEnd2[]; extern const u8 BattleScript_TerrainPreventsEnd2[]; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 4f4ed0d3cb..26e89cd4f2 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6178,10 +6178,18 @@ static void Cmd_moveend(void) } else // Eject Pack { - gBattlescriptCurrInstr = BattleScript_EjectPackActivates; - // Are these 2 lines below needed? - gProtectStructs[battler].statFell = FALSE; - gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; + if (gBattleResources->flags->flags[gBattlerTarget] & RESOURCE_FLAG_EMERGENCY_EXIT) + { + gBattlescriptCurrInstr = BattleScript_EjectPackMissesTiming; + gProtectStructs[battler].statFell = FALSE; + } + else + { + gBattlescriptCurrInstr = BattleScript_EjectPackActivates; + // Are these 2 lines below needed? + gProtectStructs[battler].statFell = FALSE; + gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; + } } break; // Only the fastest Eject item activates } @@ -6238,6 +6246,7 @@ static void Cmd_moveend(void) SaveBattlerTarget(battler); // save battler with red card gBattleScripting.battler = battler; gEffectBattler = gBattlerAttacker; + gBattleStruct->redCardActivates = TRUE; if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE) gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection BattleScriptPushCursor(); @@ -6337,6 +6346,11 @@ static void Cmd_moveend(void) case MOVEEND_EMERGENCY_EXIT: // Special case, because moves hitting multiple opponents stop after switching out for (i = 0; i < gBattlersCount; i++) { + if (gBattleStruct->redCardActivates) + { + gBattleResources->flags->flags[i] &= ~RESOURCE_FLAG_EMERGENCY_EXIT; + continue; + } if (gBattleResources->flags->flags[i] & RESOURCE_FLAG_EMERGENCY_EXIT) { gBattleResources->flags->flags[i] &= ~RESOURCE_FLAG_EMERGENCY_EXIT; @@ -6444,6 +6458,7 @@ static void Cmd_moveend(void) gBattleStruct->poisonPuppeteerConfusion = FALSE; gBattleStruct->fickleBeamBoosted = FALSE; gBattleStruct->distortedTypeMatchups = 0; + gBattleStruct->redCardActivates = FALSE; gBattleStruct->usedMicleBerry &= ~(1u << gBattlerAttacker); if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) gBattleStruct->pledgeMove = FALSE; diff --git a/test/battle/hold_effect/eject_pack.c b/test/battle/hold_effect/eject_pack.c index 8d85a77062..9272a23a7c 100644 --- a/test/battle/hold_effect/eject_pack.c +++ b/test/battle/hold_effect/eject_pack.c @@ -63,3 +63,25 @@ SINGLE_BATTLE_TEST("Eject Pack is triggered by self-inflicting stat decreases") ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); } } + +SINGLE_BATTLE_TEST("Eject Pack will miss timing to switch out user if Emergency Exit was activated on target") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); } + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(133); }; + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(player, MOVE_OVERHEAT); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_OVERHEAT, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet is switched out with the Eject Pack!"); + ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT); + } THEN { + EXPECT(player->species == SPECIES_WOBBUFFET); + EXPECT(player->item == ITEM_NONE); + EXPECT(opponent->species == SPECIES_WYNAUT); + } +} diff --git a/test/battle/hold_effect/red_card.c b/test/battle/hold_effect/red_card.c index 138e3a3692..3209549de1 100644 --- a/test/battle/hold_effect/red_card.c +++ b/test/battle/hold_effect/red_card.c @@ -380,24 +380,6 @@ SINGLE_BATTLE_TEST("Red Card does not activate if attacker's Sheer Force applied } } -SINGLE_BATTLE_TEST("Red Card activates before Emergency Exit") -{ - GIVEN { - PLAYER(SPECIES_GOLISOPOD) { MaxHP(100); HP(51); Item(ITEM_RED_CARD); } - PLAYER(SPECIES_WIMPOD); - OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WYNAUT); - } WHEN { - TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); - MESSAGE("Golisopod held up its Red Card against Foe Wobbuffet!"); - ABILITY_POPUP(player, ABILITY_EMERGENCY_EXIT); - SEND_IN_MESSAGE("Wimpod"); - } -} - SINGLE_BATTLE_TEST("Red Card is consumed after dragged out replacement has its Speed lowered by Sticky Web") { GIVEN { @@ -468,4 +450,21 @@ SINGLE_BATTLE_TEST("Red Card does not activate if holder is switched in mid-turn } } +SINGLE_BATTLE_TEST("Red Card prevents Emergency Exit activation when triggered") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_GOLISOPOD) { Item(ITEM_RED_CARD); Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(262); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SUPER_FANG); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + NOT ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT); + } +} + // SINGLE_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed")