From d637ee3b133220876be0c49aa8d55a86bd2c1773 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Feb 2023 21:59:36 +0100 Subject: [PATCH] Fix After You for gen8 (#2646) Fix After You --- include/battle.h | 1 + src/battle_script_commands.c | 3 ++- src/battle_util.c | 50 +++++++++++++++++++----------------- test/move_effect_after_you.c | 1 - 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/battle.h b/include/battle.h index 764c292bf..8be922384 100644 --- a/include/battle.h +++ b/include/battle.h @@ -191,6 +191,7 @@ struct SpecialStatus u8 weatherAbilityDone:1; u8 terrainAbilityDone:1; u8 emergencyExited:1; + u8 afterYou:1; }; struct SideTimer diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index b7adc22ae..57311e671 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9394,7 +9394,7 @@ static void Cmd_various(void) break; case VARIOUS_AFTER_YOU: if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget) - || GetBattlerTurnOrderNum(gBattlerAttacker) == GetBattlerTurnOrderNum(gBattlerTarget) + 1) + || GetBattlerTurnOrderNum(gBattlerAttacker) + 1 == GetBattlerTurnOrderNum(gBattlerTarget)) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); } @@ -9419,6 +9419,7 @@ static void Cmd_various(void) gBattlerByTurnOrder[2] = gBattlerTarget; gBattlerByTurnOrder[3] = data[2]; } + gSpecialStatuses[gBattlerTarget].afterYou = 1; gBattlescriptCurrInstr += 7; } return; diff --git a/src/battle_util.c b/src/battle_util.c index 4503c9208..8d350553d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -323,7 +323,7 @@ void HandleAction_UseMove(void) { gCurrentMove = gBattleStruct->zmove.toBeUsed[gBattlerAttacker]; } - + moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); if (gBattleMons[gBattlerAttacker].hp != 0) @@ -909,9 +909,8 @@ void HandleAction_NothingIsFainted(void) void HandleAction_ActionFinished(void) { #if B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 - u8 i, j; - u8 battler1 = 0; - u8 battler2 = 0; + u32 i, j; + bool32 afterYouActive = gSpecialStatuses[gBattlerByTurnOrder[gCurrentTurnActionNumber + 1]].afterYou; #endif *(gBattleStruct->monToSwitchIntoId + gBattlerByTurnOrder[gCurrentTurnActionNumber]) = PARTY_SIZE; gCurrentTurnActionNumber++; @@ -938,29 +937,32 @@ void HandleAction_ActionFinished(void) gBattleResources->battleScriptsStack->size = 0; #if B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 - // i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already - // taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action - for (i = gCurrentTurnActionNumber; i < gBattlersCount - 1; i++) + if (!afterYouActive) { - for (j = i + 1; j < gBattlersCount; j++) + // i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already + // taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action + for (i = gCurrentTurnActionNumber; i < gBattlersCount - 1; i++) { - u8 battler1 = gBattlerByTurnOrder[i]; - u8 battler2 = gBattlerByTurnOrder[j]; - - if (gProtectStructs[battler1].quash || gProtectStructs[battler2].quash) - continue; - - // We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should - // have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder - if((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)) + for (j = i + 1; j < gBattlersCount; j++) { - if (GetWhoStrikesFirst(battler1, battler2, FALSE)) - SwapTurnOrder(i, j); - } - else if ((gActionsByTurnOrder[i] == B_ACTION_SWITCH && gActionsByTurnOrder[j] == B_ACTION_SWITCH)) - { - if (GetWhoStrikesFirst(battler1, battler2, TRUE)) // If the actions chosen are switching, we recalc order but ignoring the moves - SwapTurnOrder(i, j); + u8 battler1 = gBattlerByTurnOrder[i]; + u8 battler2 = gBattlerByTurnOrder[j]; + + if (gProtectStructs[battler1].quash || gProtectStructs[battler2].quash) + continue; + + // We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should + // have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder + if((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)) + { + if (GetWhoStrikesFirst(battler1, battler2, FALSE)) + SwapTurnOrder(i, j); + } + else if ((gActionsByTurnOrder[i] == B_ACTION_SWITCH && gActionsByTurnOrder[j] == B_ACTION_SWITCH)) + { + if (GetWhoStrikesFirst(battler1, battler2, TRUE)) // If the actions chosen are switching, we recalc order but ignoring the moves + SwapTurnOrder(i, j); + } } } } diff --git a/test/move_effect_after_you.c b/test/move_effect_after_you.c index 400fc053f..a488d7a8c 100644 --- a/test/move_effect_after_you.c +++ b/test/move_effect_after_you.c @@ -8,7 +8,6 @@ ASSUMPTIONS DOUBLE_BATTLE_TEST("After You makes the target move after user") { - if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8) KNOWN_FAILING; // #2615. GIVEN { PLAYER(SPECIES_WOBBUFFET) { Speed(4); } PLAYER(SPECIES_WYNAUT) { Speed(1); }