diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 8f56ac8719..74eb40f0ef 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -94,9 +94,6 @@ #define GEN_8 5 #endif -// Mega Evolution settings -#define B_MEGA_EVO_TURN_ORDER GEN_7 // In Gen7, a Pokémon's Speed after Mega Evolution is used to determine turn order, not its Speed before. - // Calculation settings #define B_CRIT_CHANCE GEN_7 // Chances of a critical hit landing. See CalcCritChanceStage. #define B_CRIT_MULTIPLIER GEN_7 // In Gen6+, critical hits multiply damage by 1.5 instead of 2. @@ -131,7 +128,7 @@ #define B_PRANKSTER_DARK_TYPES GEN_7 // In Gen7+, Prankster-elevated status moves do not affect Dark type Pokémon. #define B_SHEER_COLD_IMMUNITY GEN_7 // In Gen7+, Ice-types are immune to Sheer Cold -// Turn count settings +// Turn settings #define B_BINDING_TURNS GEN_7 // In Gen5+, binding moves last for 4-5 turns instead of 2-5 turns. (With Grip Claw, 7 and 5 turns respectively.) #define B_UPROAR_TURNS GEN_7 // In Gen5+, Uproar lasts for 3 turns instead of 2-5 turns. #define B_DISABLE_TURNS GEN_7 // Disable's turns. See Cmd_disablelastusedattack. @@ -139,6 +136,8 @@ #define B_SLEEP_TURNS GEN_7 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns. #define B_TAUNT_TURNS GEN_7 // In Gen5+, Taunt lasts 3 turns if the user acts before the target, or 4 turns if the target acted before the user. In Gen3, taunt lasts 2 turns and in Gen 4, 3-5 turns. #define B_SPORT_TURNS GEN_7 // In Gen6+, Water/Mud Sport last 5 turns, even if the user switches out. +#define B_MEGA_EVO_TURN_ORDER GEN_7 // In Gen7, a Pokémon's Speed after Mega Evolution is used to determine turn order, not its Speed before. +#define B_RECALC_TURN_AFTER_ACTIONS GEN_8 // In Gen8, switching/using a move affects the current turn's order of actions. // Move data settings #define B_UPDATED_MOVE_DATA GEN_8 // Updates move data in gBattleMoves, including Power, Accuracy, PP, stat changes, targets, chances of secondary effects, etc. diff --git a/src/battle_util.c b/src/battle_util.c index d65dbcfb27..0d4f83fc84 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -872,6 +872,11 @@ 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; + #endif *(gBattleStruct->monToSwitchIntoId + gBattlerByTurnOrder[gCurrentTurnActionNumber]) = PARTY_SIZE; gCurrentTurnActionNumber++; gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; @@ -895,6 +900,31 @@ void HandleAction_ActionFinished(void) gBattleCommunication[4] = 0; gBattleScripting.multihitMoveEffect = 0; 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++) + { + for (j = i + 1; j < gBattlersCount; j++) + { + u8 battler1 = gBattlerByTurnOrder[i]; + u8 battler2 = gBattlerByTurnOrder[j]; + // 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); + } + } + } + #endif } static const u8 sMovesNotAffectedByStench[] =