diff --git a/include/battle.h b/include/battle.h index 5e435a9a5b..573283972a 100644 --- a/include/battle.h +++ b/include/battle.h @@ -238,49 +238,49 @@ struct SpecialStatus struct SideTimer { - u8 reflectTimer; + u16 reflectTimer; u8 reflectBattlerId; - u8 lightscreenTimer; + u16 lightscreenTimer; u8 lightscreenBattlerId; - u8 mistTimer; + u16 mistTimer; u8 mistBattlerId; - u8 safeguardTimer; + u16 safeguardTimer; u8 safeguardBattlerId; - u8 spikesAmount; - u8 toxicSpikesAmount; - u8 stealthRockAmount; - u8 stickyWebAmount; + u16 spikesAmount; // debug menu complains. might be better to solve there instead if possible + u16 toxicSpikesAmount; + u16 stealthRockAmount; + u16 stickyWebAmount; u8 stickyWebBattlerId; u8 stickyWebBattlerSide; // Used for Court Change - u8 auroraVeilTimer; + u16 auroraVeilTimer; u8 auroraVeilBattlerId; - u8 tailwindTimer; + u16 tailwindTimer; u8 tailwindBattlerId; - u8 luckyChantTimer; + u16 luckyChantTimer; u8 luckyChantBattlerId; - u8 steelsurgeAmount; + u16 steelsurgeAmount; // Timers below this point are not swapped by Court Change - u8 followmeTimer; + u16 followmeTimer; u8 followmeTarget:3; u8 followmePowder:1; // Rage powder, does not affect grass type pokemon. - u8 retaliateTimer; - u8 damageNonTypesTimer; + u16 retaliateTimer; + u16 damageNonTypesTimer; u8 damageNonTypesType; - u8 rainbowTimer; - u8 seaOfFireTimer; - u8 swampTimer; + u16 rainbowTimer; + u16 seaOfFireTimer; + u16 swampTimer; }; struct FieldTimer { - u8 mudSportTimer; - u8 waterSportTimer; - u8 wonderRoomTimer; - u8 magicRoomTimer; - u8 trickRoomTimer; - u8 terrainTimer; - u8 gravityTimer; - u8 fairyLockTimer; + u16 mudSportTimer; + u16 waterSportTimer; + u16 wonderRoomTimer; + u16 magicRoomTimer; + u16 trickRoomTimer; + u16 terrainTimer; + u16 gravityTimer; + u16 fairyLockTimer; }; struct WishFutureKnock @@ -289,7 +289,7 @@ struct WishFutureKnock u8 futureSightBattlerIndex[MAX_BATTLERS_COUNT]; u8 futureSightPartyIndex[MAX_BATTLERS_COUNT]; u16 futureSightMove[MAX_BATTLERS_COUNT]; - u8 wishCounter[MAX_BATTLERS_COUNT]; + u16 wishCounter[MAX_BATTLERS_COUNT]; u8 wishPartyId[MAX_BATTLERS_COUNT]; u8 weatherDuration; u8 knockedOffMons[NUM_BATTLE_SIDES]; // Each battler is represented by a bit. @@ -1169,6 +1169,7 @@ extern u16 gBattleMovePower; extern u16 gMoveToLearn; extern u32 gFieldStatuses; extern struct FieldTimer gFieldTimers; +extern u16 gBattleTurnCounter; extern u8 gBattlerAbility; extern struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT]; diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 66774d1afe..7393617058 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2102,8 +2102,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_DEFOG: if (gSideStatuses[GetBattlerSide(battlerDef)] - & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL | SIDE_STATUS_SAFEGUARD | SIDE_STATUS_MIST) - || gSideTimers[GetBattlerSide(battlerDef)].auroraVeilTimer != 0 + & (SIDE_STATUS_SCREEN_ANY | SIDE_STATUS_SAFEGUARD | SIDE_STATUS_MIST) || gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY) { if (PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove)) @@ -2201,7 +2200,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-4); break; case EFFECT_WISH: - if (gWishFutureKnock.wishCounter[battlerAtk] != 0) + if (gWishFutureKnock.wishCounter[battlerAtk] > gBattleTurnCounter) ADJUST_SCORE(-10); break; case EFFECT_ASSIST: @@ -2614,13 +2613,13 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } break; case EFFECT_TAILWIND: - if (gSideTimers[GetBattlerSide(battlerAtk)].tailwindTimer != 0 - || PartnerMoveEffectIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, EFFECT_TAILWIND) - || (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer > 1)) // Trick Room active and not ending this turn + if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_TAILWIND + || PartnerMoveEffectIs(BATTLE_PARTNER(battlerAtk), aiData->partnerMove, EFFECT_TAILWIND) + || gFieldStatuses & STATUS_FIELD_TRICK_ROOM) ADJUST_SCORE(-10); break; case EFFECT_LUCKY_CHANT: - if (gSideTimers[GetBattlerSide(battlerAtk)].luckyChantTimer != 0 + if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_LUCKY_CHANT || PartnerMoveIsSameNoTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove)) ADJUST_SCORE(-10); break; @@ -5320,7 +5319,7 @@ static s32 AI_PowerfulStatus(u32 battlerAtk, u32 battlerDef, u32 move, s32 score switch (moveEffect) { case EFFECT_TAILWIND: - if (!gSideTimers[GetBattlerSide(battlerAtk)].tailwindTimer && !(gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer > 1)) + if (!gSideTimers[GetBattlerSide(battlerAtk)].tailwindTimer && !(gFieldStatuses & STATUS_FIELD_TRICK_ROOM)) ADJUST_SCORE(POWERFUL_STATUS_MOVE); break; case EFFECT_TRICK_ROOM: diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 24fafaf8bd..ad81949a5d 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -2174,7 +2174,7 @@ static bool32 ShouldUseItem(u32 battler) break; case EFFECT_ITEM_SET_MIST: battlerSide = GetBattlerSide(battler); - if (gDisableStructs[battler].isFirstTurn && gSideTimers[battlerSide].mistTimer == 0) + if (gDisableStructs[battler].isFirstTurn && !(gSideStatuses[battlerSide] & SIDE_STATUS_MIST)) shouldUse = TRUE; break; case EFFECT_ITEM_REVIVE: diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index a3104122d1..98bcada84b 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -6693,16 +6693,21 @@ static void TrySwapWishBattlerIds(u32 battlerAtk, u32 battlerPartner) u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk)); // if used future sight on opposing side, properly track who used it - if (gSideStatuses[oppSide] & SIDE_STATUS_FUTUREATTACK) { - for (i = 0; i < gBattlersCount; i++) { + if (gSideStatuses[oppSide] & SIDE_STATUS_FUTUREATTACK) + { + for (i = 0; i < gBattlersCount; i++) + { if (IsAlly(i,battlerAtk)) continue; // only on opposing side - if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerAtk) { + if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerAtk) + { // if target was attacked with future sight from us, now they'll be the partner slot gWishFutureKnock.futureSightBattlerIndex[i] = battlerPartner; gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerPartner]; break; - } else if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerPartner) { + } + else if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerPartner) + { gWishFutureKnock.futureSightBattlerIndex[i] = battlerAtk; gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerAtk]; break; @@ -6711,10 +6716,9 @@ static void TrySwapWishBattlerIds(u32 battlerAtk, u32 battlerPartner) } // swap wish party indices - if (gWishFutureKnock.wishCounter[battlerAtk] > 0 - || gWishFutureKnock.wishCounter[battlerPartner] > 0) { + if (gWishFutureKnock.wishCounter[battlerAtk] > gBattleTurnCounter + || gWishFutureKnock.wishCounter[battlerPartner] > gBattleTurnCounter) SWAP(gWishFutureKnock.wishPartyId[battlerAtk], gWishFutureKnock.wishPartyId[battlerPartner], temp); - } } static void AnimTask_AllySwitchDataSwap(u8 taskId) diff --git a/src/battle_debug.c b/src/battle_debug.c index b140d3791e..44a92b5f93 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -818,7 +818,7 @@ static void PrintDigitChars(struct BattleDebugMenu *data); static void SetUpModifyArrows(struct BattleDebugMenu *data); static void UpdateBattlerValue(struct BattleDebugMenu *data); static void UpdateMonData(struct BattleDebugMenu *data); -static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue); +static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue); static bool32 TryMoveDigit(struct BattleDebugModifyArrows *modArrows, bool32 moveUp); static void SwitchToDebugView(u8 taskId); static void SwitchToDebugViewFromAiParty(u8 taskId); @@ -1852,7 +1852,7 @@ static void ValueToCharDigits(u8 *charDigits, u32 newValue, u8 maxDigits) charDigits[i] = valueDigits[i] + CHAR_0; } -static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue) +static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, bool32 statusTrue) { struct SideTimer *sideTimer = &gSideTimers[GetBattlerSide(data->battlerId)]; diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index 38664c5d09..cae562bf4e 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -646,9 +646,9 @@ void BS_SetMaxMoveEffect(void) gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; gFieldStatuses |= statusFlag; if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER) - gFieldTimers.terrainTimer = 8; + gFieldTimers.terrainTimer = gBattleTurnCounter + 8; else - gFieldTimers.terrainTimer = 5; + gFieldTimers.terrainTimer = gBattleTurnCounter + 5; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_EffectSetTerrain; effect++; @@ -665,7 +665,7 @@ void BS_SetMaxMoveEffect(void) { u32 moveType = GetMoveType(gCurrentMove); gSideStatuses[side] |= SIDE_STATUS_DAMAGE_NON_TYPES; - gSideTimers[side].damageNonTypesTimer = 5; // damage is dealt for 4 turns, ends on 5th + gSideTimers[side].damageNonTypesTimer = gBattleTurnCounter + 5; // damage is dealt for 4 turns, ends on 5th gSideTimers[side].damageNonTypesType = moveType; BattleScriptPush(gBattlescriptCurrInstr + 1); ChooseDamageNonTypesString(moveType); @@ -708,9 +708,9 @@ void BS_SetMaxMoveEffect(void) { gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_AURORA_VEIL; if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY) - gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = 8; + gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = gBattleTurnCounter + 8; else - gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = 5; + gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = gBattleTurnCounter + 5; gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilBattlerId = gBattlerAttacker; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SAFEGUARD; BattleScriptPush(gBattlescriptCurrInstr + 1); @@ -722,7 +722,7 @@ void BS_SetMaxMoveEffect(void) if (!(gFieldStatuses & STATUS_FIELD_GRAVITY)) { gFieldStatuses |= STATUS_FIELD_GRAVITY; - gFieldTimers.gravityTimer = 5; + gFieldTimers.gravityTimer = gBattleTurnCounter + 5; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_EffectGravitySuccess; effect++; diff --git a/src/battle_main.c b/src/battle_main.c index 31c8ac83b3..22d2cc32cf 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -225,6 +225,7 @@ EWRAM_DATA u16 gBattleMovePower = 0; EWRAM_DATA u16 gMoveToLearn = 0; EWRAM_DATA u32 gFieldStatuses = 0; EWRAM_DATA struct FieldTimer gFieldTimers = {0}; +EWRAM_DATA u16 gBattleTurnCounter = 0; EWRAM_DATA u8 gBattlerAbility = 0; EWRAM_DATA struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA bool8 gHasFetchedBall = FALSE; @@ -3900,6 +3901,7 @@ static void TryDoEventsBeforeFirstTurn(void) gBattleScripting.moveendState = 0; gBattleStruct->faintedActionsState = 0; gBattleStruct->turnCountersTracker = 0; + gBattleTurnCounter = 0; memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts)); SetShellSideArmCategory(); @@ -3954,9 +3956,10 @@ void BattleTurnPassed(void) return; if (DoBattlerEndTurnEffects()) return; + if (HandleWishPerishSongOnTurnEnd()) + return; } - if (HandleWishPerishSongOnTurnEnd()) - return; + if (HandleFaintedMonActions()) return; gBattleStruct->faintedActionsState = 0; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index daf0cc5b35..420e5d3302 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4225,9 +4225,9 @@ void SetMoveEffect(bool32 primary, bool32 certain) { gSideStatuses[side] |= SIDE_STATUS_REFLECT; if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY) - gSideTimers[side].reflectTimer = 8; + gSideTimers[side].reflectTimer = gBattleTurnCounter + 8; else - gSideTimers[side].reflectTimer = 5; + gSideTimers[side].reflectTimer = gBattleTurnCounter + 5; gSideTimers[side].reflectBattlerId = gBattlerAttacker; if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) @@ -4245,9 +4245,9 @@ void SetMoveEffect(bool32 primary, bool32 certain) { gSideStatuses[side] |= SIDE_STATUS_LIGHTSCREEN; if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY) - gSideTimers[side].lightscreenTimer = 8; + gSideTimers[side].lightscreenTimer = gBattleTurnCounter + 8; else - gSideTimers[side].lightscreenTimer = 5; + gSideTimers[side].lightscreenTimer = gBattleTurnCounter + 5; gSideTimers[side].lightscreenBattlerId = gBattlerAttacker; if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) @@ -8568,7 +8568,7 @@ static void Cmd_setgravity(void) else { gFieldStatuses |= STATUS_FIELD_GRAVITY; - gFieldTimers.gravityTimer = 5; + gFieldTimers.gravityTimer = gBattleTurnCounter + 5; gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -9145,7 +9145,6 @@ static void RemoveAllWeather(void) static void RemoveAllTerrains(void) { - gFieldTimers.terrainTimer = 0; switch (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) { case STATUS_FIELD_MISTY_TERRAIN: @@ -9637,7 +9636,7 @@ static void Cmd_various(void) else { gFieldStatuses |= STATUS_FIELD_FAIRY_LOCK; - gFieldTimers.fairyLockTimer = 2; + gFieldTimers.fairyLockTimer = gBattleTurnCounter + 2; gBattlescriptCurrInstr = cmd->nextInstr; } return; @@ -10270,7 +10269,7 @@ static void Cmd_various(void) { gSideStatuses[GetBattlerSide(battler)] |= SIDE_STATUS_LUCKY_CHANT; gSideTimers[GetBattlerSide(battler)].luckyChantBattlerId = battler; - gSideTimers[GetBattlerSide(battler)].luckyChantTimer = 5; + gSideTimers[GetBattlerSide(battler)].luckyChantTimer = gBattleTurnCounter + 5; gBattlescriptCurrInstr = cmd->nextInstr; } else @@ -10729,9 +10728,9 @@ static void Cmd_various(void) { gSideStatuses[GetBattlerSide(battler)] |= SIDE_STATUS_AURORA_VEIL; if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_LIGHT_CLAY) - gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = 8; + gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = gBattleTurnCounter + 8; else - gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = 5; + gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = gBattleTurnCounter + 5; gSideTimers[GetBattlerSide(battler)].auroraVeilBattlerId = battler; if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) @@ -11600,9 +11599,9 @@ static void Cmd_setreflect(void) { gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_REFLECT; if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY) - gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = 8; + gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = gBattleTurnCounter + 8; else - gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = 5; + gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = gBattleTurnCounter + 5; gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectBattlerId = gBattlerAttacker; if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) @@ -12647,9 +12646,9 @@ static void Cmd_setlightscreen(void) { gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_LIGHTSCREEN; if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY) - gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = 8; + gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = gBattleTurnCounter + 8; else - gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = 5; + gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = gBattleTurnCounter + 5; gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenBattlerId = gBattlerAttacker; if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) @@ -12861,7 +12860,7 @@ static void Cmd_setmist(void) } else { - gSideTimers[GetBattlerSide(gBattlerAttacker)].mistTimer = 5; + gSideTimers[GetBattlerSide(gBattlerAttacker)].mistTimer = gBattleTurnCounter + 5; gSideTimers[GetBattlerSide(gBattlerAttacker)].mistBattlerId = gBattlerAttacker; gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_MIST; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_MIST; @@ -13515,7 +13514,7 @@ static void Cmd_settailwind(void) { gSideStatuses[side] |= SIDE_STATUS_TAILWIND; gSideTimers[side].tailwindBattlerId = gBattlerAttacker; - gSideTimers[side].tailwindTimer = B_TAILWIND_TURNS >= GEN_5 ? 4 : 3; + gSideTimers[side].tailwindTimer = gBattleTurnCounter + (B_TAILWIND_TURNS >= GEN_5 ? 4 : 3); gBattlescriptCurrInstr = cmd->nextInstr; } else @@ -13929,7 +13928,7 @@ static void Cmd_setsafeguard(void) else { gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_SAFEGUARD; - gSideTimers[GetBattlerSide(gBattlerAttacker)].safeguardTimer = 5; + gSideTimers[GetBattlerSide(gBattlerAttacker)].safeguardTimer = gBattleTurnCounter + 5; gSideTimers[GetBattlerSide(gBattlerAttacker)].safeguardBattlerId = gBattlerAttacker; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SAFEGUARD; } @@ -14225,7 +14224,7 @@ static void Cmd_trysetfutureattack(void) { CMD_ARGS(const u8 *failInstr); - if (gWishFutureKnock.futureSightCounter[gBattlerTarget] != 0) + if (gWishFutureKnock.futureSightCounter[gBattlerTarget] > gBattleTurnCounter) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -14235,7 +14234,7 @@ static void Cmd_trysetfutureattack(void) gWishFutureKnock.futureSightMove[gBattlerTarget] = gCurrentMove; gWishFutureKnock.futureSightBattlerIndex[gBattlerTarget] = gBattlerAttacker; gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] = gBattlerPartyIndexes[gBattlerAttacker]; - gWishFutureKnock.futureSightCounter[gBattlerTarget] = 3; + gWishFutureKnock.futureSightCounter[gBattlerTarget] = gBattleTurnCounter + 3; if (gCurrentMove == MOVE_DOOM_DESIRE) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DOOM_DESIRE; @@ -14705,9 +14704,9 @@ static void Cmd_trywish(void) switch (cmd->turnNumber) { case 0: // use wish - if (gWishFutureKnock.wishCounter[gBattlerAttacker] == 0) + if (gWishFutureKnock.wishCounter[gBattlerAttacker] <= gBattleTurnCounter) { - gWishFutureKnock.wishCounter[gBattlerAttacker] = 2; + gWishFutureKnock.wishCounter[gBattlerAttacker] = gBattleTurnCounter + 2; gWishFutureKnock.wishPartyId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker]; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -14818,18 +14817,17 @@ static void Cmd_setdamagetohealthdifference(void) } } -static void HandleRoomMove(u32 statusFlag, u8 *timer, u8 stringId) +static void HandleRoomMove(u32 statusFlag, u16 *timer, u8 stringId) { if (gFieldStatuses & statusFlag) { gFieldStatuses &= ~statusFlag; - *timer = 0; gBattleCommunication[MULTISTRING_CHOOSER] = stringId + 1; } else { gFieldStatuses |= statusFlag; - *timer = 5; + *timer = gBattleTurnCounter + 5; gBattleCommunication[MULTISTRING_CHOOSER] = stringId; } } @@ -15227,7 +15225,7 @@ static void Cmd_settypebasedhalvers(void) if (!(gFieldStatuses & STATUS_FIELD_MUDSPORT)) { gFieldStatuses |= STATUS_FIELD_MUDSPORT; - gFieldTimers.mudSportTimer = 5; + gFieldTimers.mudSportTimer = gBattleTurnCounter + 5; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; worked = TRUE; } @@ -15249,7 +15247,7 @@ static void Cmd_settypebasedhalvers(void) if (!(gFieldStatuses & STATUS_FIELD_WATERSPORT)) { gFieldStatuses |= STATUS_FIELD_WATERSPORT; - gFieldTimers.waterSportTimer = 5; + gFieldTimers.waterSportTimer = gBattleTurnCounter + 5; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; worked = TRUE; } @@ -15434,17 +15432,9 @@ static void Cmd_removelightscreenreflect(void) else failed = FALSE; - if (!failed - && (gSideTimers[side].reflectTimer - || gSideTimers[side].lightscreenTimer - || gSideTimers[side].auroraVeilTimer)) + if (!failed && gSideStatuses[side] & SIDE_STATUS_SCREEN_ANY) { - gSideStatuses[side] &= ~SIDE_STATUS_REFLECT; - gSideStatuses[side] &= ~SIDE_STATUS_LIGHTSCREEN; - gSideStatuses[side] &= ~SIDE_STATUS_AURORA_VEIL; - gSideTimers[side].reflectTimer = 0; - gSideTimers[side].lightscreenTimer = 0; - gSideTimers[side].auroraVeilTimer = 0; + gSideStatuses[side] &= ~SIDE_STATUS_SCREEN_ANY; gBattleScripting.animTurn = 1; gBattleScripting.animTargetsHit = 1; } @@ -17178,13 +17168,13 @@ void BS_SetPledgeStatus(void) switch (cmd->sideStatus) { case SIDE_STATUS_RAINBOW: - gSideTimers[side].rainbowTimer = 4; + gSideTimers[side].rainbowTimer = gBattleTurnCounter + 4; break; case SIDE_STATUS_SEA_OF_FIRE: - gSideTimers[side].seaOfFireTimer = 4; + gSideTimers[side].seaOfFireTimer = gBattleTurnCounter + 4; break; case SIDE_STATUS_SWAMP: - gSideTimers[side].swampTimer = 4; + gSideTimers[side].swampTimer = gBattleTurnCounter + 4; } gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/src/battle_util.c b/src/battle_util.c index 97a2e0aa30..21a0928bd2 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1655,7 +1655,7 @@ static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId) { if (terrainFlag & STATUS_FIELD_GRASSY_TERRAIN) BattleScriptExecute(BattleScript_GrassyTerrainHeals); - if (gFieldTimers.terrainTimer > 0 && --gFieldTimers.terrainTimer == 0) + if (gFieldTimers.terrainTimer == gBattleTurnCounter) { gFieldStatuses &= ~terrainFlag; TryToRevertMimicryAndFlags(); @@ -1737,7 +1737,7 @@ u8 DoFieldEndTurnEffects(void) SwapTurnOrder(i, j); } } - + gBattleTurnCounter++; gBattleStruct->turnCountersTracker++; gBattleStruct->turnSideTracker = 0; // fall through @@ -1748,7 +1748,7 @@ u8 DoFieldEndTurnEffects(void) gBattlerAttacker = gSideTimers[side].reflectBattlerId; if (gSideStatuses[side] & SIDE_STATUS_REFLECT) { - if (--gSideTimers[side].reflectTimer == 0) + if (gSideTimers[side].reflectTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_REFLECT; BattleScriptExecute(BattleScript_SideStatusWoreOff); @@ -1773,7 +1773,7 @@ u8 DoFieldEndTurnEffects(void) gBattlerAttacker = gSideTimers[side].lightscreenBattlerId; if (gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN) { - if (--gSideTimers[side].lightscreenTimer == 0) + if (gSideTimers[side].lightscreenTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_LIGHTSCREEN; BattleScriptExecute(BattleScript_SideStatusWoreOff); @@ -1799,7 +1799,7 @@ u8 DoFieldEndTurnEffects(void) gBattlerAttacker = gSideTimers[side].auroraVeilBattlerId; if (gSideStatuses[side] & SIDE_STATUS_AURORA_VEIL) { - if (--gSideTimers[side].auroraVeilTimer == 0) + if (gSideTimers[side].auroraVeilTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_AURORA_VEIL; BattleScriptExecute(BattleScript_SideStatusWoreOff); @@ -1823,7 +1823,7 @@ u8 DoFieldEndTurnEffects(void) { side = gBattleStruct->turnSideTracker; gBattlerAttacker = gSideTimers[side].mistBattlerId; - if (gSideTimers[side].mistTimer != 0 && --gSideTimers[side].mistTimer == 0) + if (gSideTimers[side].mistTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_MIST; BattleScriptExecute(BattleScript_SideStatusWoreOff); @@ -1848,7 +1848,7 @@ u8 DoFieldEndTurnEffects(void) gBattlerAttacker = gSideTimers[side].safeguardBattlerId; if (gSideStatuses[side] & SIDE_STATUS_SAFEGUARD) { - if (--gSideTimers[side].safeguardTimer == 0) + if (gSideTimers[side].safeguardTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_SAFEGUARD; BattleScriptExecute(BattleScript_SafeguardEnds); @@ -1872,7 +1872,7 @@ u8 DoFieldEndTurnEffects(void) gBattlerAttacker = gSideTimers[side].luckyChantBattlerId; if (gSideStatuses[side] & SIDE_STATUS_LUCKY_CHANT) { - if (--gSideTimers[side].luckyChantTimer == 0) + if (gSideTimers[side].luckyChantTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_LUCKY_CHANT; BattleScriptExecute(BattleScript_LuckyChantEnds); @@ -1896,7 +1896,7 @@ u8 DoFieldEndTurnEffects(void) gBattlerAttacker = gSideTimers[side].tailwindBattlerId; if (gSideStatuses[side] & SIDE_STATUS_TAILWIND) { - if (gSideTimers[side].tailwindTimer > 0 && --gSideTimers[side].tailwindTimer == 0) + if (gSideTimers[side].tailwindTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_TAILWIND; BattleScriptExecute(BattleScript_TailwindEnds); @@ -1917,9 +1917,7 @@ u8 DoFieldEndTurnEffects(void) while (gBattleStruct->turnSideTracker < gBattlersCount) { u32 battler = gBattlerByTurnOrder[gBattleStruct->turnSideTracker]; - if (gWishFutureKnock.wishCounter[battler] != 0 - && --gWishFutureKnock.wishCounter[battler] == 0 - && IsBattlerAlive(battler)) + if (gWishFutureKnock.wishCounter[battler] == gBattleTurnCounter && IsBattlerAlive(battler)) { gBattlerTarget = battler; BattleScriptExecute(BattleScript_WishComesTrue); @@ -1943,7 +1941,7 @@ u8 DoFieldEndTurnEffects(void) while (gBattleStruct->turnSideTracker < 2) { side = gBattleStruct->turnSideTracker; - if (gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES && --gSideTimers[side].damageNonTypesTimer == 0) + if (gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES && gSideTimers[side].damageNonTypesTimer == gBattleTurnCounter) { // There is no in-game message when this side status ends. gSideStatuses[side] &= ~SIDE_STATUS_DAMAGE_NON_TYPES; @@ -1960,7 +1958,7 @@ u8 DoFieldEndTurnEffects(void) } break; case ENDTURN_TRICK_ROOM: - if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer > 0 && --gFieldTimers.trickRoomTimer == 0) + if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer == gBattleTurnCounter) { gFieldStatuses &= ~STATUS_FIELD_TRICK_ROOM; BattleScriptExecute(BattleScript_TrickRoomEnds); @@ -1969,7 +1967,7 @@ u8 DoFieldEndTurnEffects(void) gBattleStruct->turnCountersTracker++; break; case ENDTURN_WONDER_ROOM: - if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM && gFieldTimers.wonderRoomTimer > 0 && --gFieldTimers.wonderRoomTimer == 0) + if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM && gFieldTimers.wonderRoomTimer == gBattleTurnCounter) { gFieldStatuses &= ~STATUS_FIELD_WONDER_ROOM; BattleScriptExecute(BattleScript_WonderRoomEnds); @@ -1978,7 +1976,7 @@ u8 DoFieldEndTurnEffects(void) gBattleStruct->turnCountersTracker++; break; case ENDTURN_MAGIC_ROOM: - if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM && gFieldTimers.magicRoomTimer > 0 && --gFieldTimers.magicRoomTimer == 0) + if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM && gFieldTimers.magicRoomTimer == gBattleTurnCounter) { gFieldStatuses &= ~STATUS_FIELD_MAGIC_ROOM; BattleScriptExecute(BattleScript_MagicRoomEnds); @@ -2003,7 +2001,7 @@ u8 DoFieldEndTurnEffects(void) gBattleStruct->turnCountersTracker++; break; case ENDTURN_WATER_SPORT: - if (gFieldStatuses & STATUS_FIELD_WATERSPORT && --gFieldTimers.waterSportTimer == 0) + if (gFieldStatuses & STATUS_FIELD_WATERSPORT && gFieldTimers.waterSportTimer == gBattleTurnCounter) { gFieldStatuses &= ~STATUS_FIELD_WATERSPORT; BattleScriptExecute(BattleScript_WaterSportEnds); @@ -2012,7 +2010,7 @@ u8 DoFieldEndTurnEffects(void) gBattleStruct->turnCountersTracker++; break; case ENDTURN_MUD_SPORT: - if (gFieldStatuses & STATUS_FIELD_MUDSPORT && --gFieldTimers.mudSportTimer == 0) + if (gFieldStatuses & STATUS_FIELD_MUDSPORT && gFieldTimers.mudSportTimer == gBattleTurnCounter) { gFieldStatuses &= ~STATUS_FIELD_MUDSPORT; BattleScriptExecute(BattleScript_MudSportEnds); @@ -2021,7 +2019,7 @@ u8 DoFieldEndTurnEffects(void) gBattleStruct->turnCountersTracker++; break; case ENDTURN_GRAVITY: - if (gFieldStatuses & STATUS_FIELD_GRAVITY && --gFieldTimers.gravityTimer == 0) + if (gFieldStatuses & STATUS_FIELD_GRAVITY && gFieldTimers.gravityTimer == gBattleTurnCounter) { gFieldStatuses &= ~STATUS_FIELD_GRAVITY; BattleScriptExecute(BattleScript_GravityEnds); @@ -2034,7 +2032,7 @@ u8 DoFieldEndTurnEffects(void) gBattleStruct->turnCountersTracker++; break; case ENDTURN_FAIRY_LOCK: - if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK && --gFieldTimers.fairyLockTimer == 0) + if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK && gFieldTimers.fairyLockTimer == gBattleTurnCounter) { gFieldStatuses &= ~STATUS_FIELD_FAIRY_LOCK; } @@ -2067,7 +2065,7 @@ u8 DoFieldEndTurnEffects(void) break; } - if (gSideTimers[side].rainbowTimer > 0 && --gSideTimers[side].rainbowTimer == 0) + if (gSideTimers[side].rainbowTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_RAINBOW; BattleScriptExecute(BattleScript_TheRainbowDisappeared); @@ -2097,7 +2095,7 @@ u8 DoFieldEndTurnEffects(void) break; } - if (gSideTimers[side].seaOfFireTimer > 0 && --gSideTimers[side].seaOfFireTimer == 0) + if (gSideTimers[side].seaOfFireTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_SEA_OF_FIRE; BattleScriptExecute(BattleScript_TheSeaOfFireDisappeared); @@ -2127,7 +2125,7 @@ u8 DoFieldEndTurnEffects(void) break; } - if (gSideTimers[side].swampTimer > 0 && --gSideTimers[side].swampTimer == 0) + if (gSideTimers[side].swampTimer == gBattleTurnCounter) { gSideStatuses[side] &= ~SIDE_STATUS_SWAMP; BattleScriptExecute(BattleScript_TheSwampDisappeared); @@ -2873,7 +2871,7 @@ u8 DoBattlerEndTurnEffects(void) case ENDTURN_GMAX_MOVE_RESIDUAL_DAMAGE: { u32 side = GetBattlerSide(gBattlerAttacker); - if (gSideTimers[side].damageNonTypesTimer + if (gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES && !IS_BATTLER_OF_TYPE(gBattlerAttacker, gSideTimers[side].damageNonTypesType) && IsBattlerAlive(gBattlerAttacker) && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) @@ -2926,14 +2924,12 @@ bool32 HandleWishPerishSongOnTurnEnd(void) gBattleStruct->wishPerishSongBattlerId++; - if (gWishFutureKnock.futureSightCounter[battler] != 0 - && --gWishFutureKnock.futureSightCounter[battler] == 0 - && !(gAbsentBattlerFlags & (1u << battler))) + if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter && !(gAbsentBattlerFlags & (1u << battler))) { struct Pokemon *party; - if (gWishFutureKnock.futureSightCounter[battler] == 0 - && gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] == 0) + if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter + && gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] <= gBattleTurnCounter) { gSideStatuses[GetBattlerSide(battler)] &= ~SIDE_STATUS_FUTUREATTACK; } @@ -4053,7 +4049,7 @@ bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbilit return FALSE; } -static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer) +static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u16 *timer) { if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle))) { @@ -4339,7 +4335,7 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov return effect; } -static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *timer) +static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u16 *timer) { if (!(gFieldStatuses & flag)) { @@ -4347,7 +4343,7 @@ static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *ti gFieldStatuses |= flag; gBattleScripting.animArg1 = anim; if (gBattleStruct->startingStatusTimer) - *timer = gBattleStruct->startingStatusTimer; + *timer = gBattleTurnCounter + gBattleStruct->startingStatusTimer; else *timer = 0; // Infinite @@ -4357,7 +4353,7 @@ static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *ti return 0; } -static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u8 *timer) +static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u16 *timer) { if (!(gSideStatuses[side] & flag)) { @@ -4366,7 +4362,7 @@ static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 ani gSideStatuses[side] |= flag; gBattleScripting.animArg1 = anim; if (gBattleStruct->startingStatusTimer) - *timer = gBattleStruct->startingStatusTimer; + *timer = gBattleTurnCounter + gBattleStruct->startingStatusTimer; else *timer = 0; // Infinite @@ -11380,22 +11376,16 @@ static bool32 TryRemoveScreens(u32 battler) u8 enemySide = GetBattlerSide(BATTLE_OPPOSITE(battler)); // try to remove from battler's side - if (gSideStatuses[battlerSide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)) + if (gSideStatuses[battlerSide] & SIDE_STATUS_SCREEN_ANY) { - gSideStatuses[battlerSide] &= ~(SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL); - gSideTimers[battlerSide].reflectTimer = 0; - gSideTimers[battlerSide].lightscreenTimer = 0; - gSideTimers[battlerSide].auroraVeilTimer = 0; + gSideStatuses[battlerSide] &= ~SIDE_STATUS_SCREEN_ANY; removed = TRUE; } // try to remove from battler opponent's side - if (gSideStatuses[enemySide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)) + if (gSideStatuses[enemySide] & SIDE_STATUS_SCREEN_ANY) { - gSideStatuses[enemySide] &= ~(SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL); - gSideTimers[enemySide].reflectTimer = 0; - gSideTimers[enemySide].lightscreenTimer = 0; - gSideTimers[enemySide].auroraVeilTimer = 0; + gSideStatuses[enemySide] &= ~SIDE_STATUS_SCREEN_ANY; removed = TRUE; }