diff --git a/include/battle.h b/include/battle.h index ee91a75c56..70e65b2d56 100644 --- a/include/battle.h +++ b/include/battle.h @@ -217,13 +217,9 @@ struct SpecialStatus struct SideTimer { u16 reflectTimer; - u8 reflectBattlerId; u16 lightscreenTimer; - u8 lightscreenBattlerId; u16 mistTimer; - u8 mistBattlerId; u16 safeguardTimer; - u8 safeguardBattlerId; u16 spikesAmount; // debug menu complains. might be better to solve there instead if possible u16 toxicSpikesAmount; u16 stealthRockAmount; @@ -231,11 +227,8 @@ struct SideTimer u8 stickyWebBattlerId; u8 stickyWebBattlerSide; // Used for Court Change u16 auroraVeilTimer; - u8 auroraVeilBattlerId; u16 tailwindTimer; - u8 tailwindBattlerId; u16 luckyChantTimer; - u8 luckyChantBattlerId; u16 steelsurgeAmount; // Timers below this point are not swapped by Court Change u16 followmeTimer; @@ -619,6 +612,7 @@ struct BattlerState u32 sleepClauseEffectExempt:1; // Stores whether effect should be exempt from triggering Sleep Clause (Effect Spore) u32 usedMicleBerry:1; u32 pursuitTarget:1; + u32 canPickupItem:1; u32 padding:17; // End of Word }; @@ -691,7 +685,6 @@ struct BattleStruct u16 chosenItem[MAX_BATTLERS_COUNT]; u16 choicedMove[MAX_BATTLERS_COUNT]; u16 changedItems[MAX_BATTLERS_COUNT]; - u8 canPickupItem; u8 switchInBattlerCounter; u8 arenaTurnCounter; u8 turnSideTracker; @@ -805,7 +798,6 @@ struct BattleStruct u8 numSpreadTargets:2; u8 bypassMoldBreakerChecks:1; // for ABILITYEFFECT_IMMUNITY u8 noTargetPresent:1; - u8 usedMicleBerry; struct MessageStatus slideMessageStatus; u8 trainerSlideSpriteIds[MAX_BATTLERS_COUNT]; u8 storeBattlerSpriteId; diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index 96e0aad14a..5ab23ccdc9 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -6828,18 +6828,8 @@ static void TrySwapSkyDropTargets(u32 battlerAtk, u32 battlerPartner) static void TrySwapStickyWebBattlerId(u32 battlerAtk, u32 battlerPartner) { - u32 atkSide = GetBattlerSide(battlerAtk); u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk)); - // not all of these are needed to be swapped, but are done so to be robust to anything in the future that might care about them - TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, reflectBattlerId); - TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, lightscreenBattlerId); - TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, mistBattlerId); - TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, safeguardBattlerId); - TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, auroraVeilBattlerId); - TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, tailwindBattlerId); - TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, luckyChantBattlerId); - // if we've set sticky web on the opposing side, need to swap stickyWebBattlerId for mirror armor TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, oppSide, stickyWebBattlerId); } diff --git a/src/battle_debug.c b/src/battle_debug.c index 8eba2ac936..0a0a8894ad 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -1898,7 +1898,6 @@ static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_REFLECT; else *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_REFLECT; - sideTimer->reflectBattlerId = data->battlerId; } return &sideTimer->reflectTimer; case LIST_SIDE_LIGHTSCREEN: @@ -1908,7 +1907,6 @@ static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_LIGHTSCREEN; else *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_LIGHTSCREEN; - sideTimer->lightscreenBattlerId = data->battlerId; } return &sideTimer->lightscreenTimer; case LIST_SIDE_STICKY_WEB: @@ -1938,7 +1936,6 @@ static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_SAFEGUARD; else *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_SAFEGUARD; - sideTimer->safeguardBattlerId = data->battlerId; } return &sideTimer->safeguardTimer; case LIST_SIDE_MIST: @@ -1948,7 +1945,6 @@ static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_MIST; else *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_MIST; - sideTimer->mistBattlerId = data->battlerId; } return &sideTimer->mistTimer; case LIST_SIDE_TAILWIND: @@ -1958,7 +1954,6 @@ static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_TAILWIND; else *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_TAILWIND; - sideTimer->tailwindBattlerId = data->battlerId; } return &sideTimer->tailwindTimer; case LIST_SIDE_AURORA_VEIL: @@ -1968,7 +1963,6 @@ static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_AURORA_VEIL; else *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_AURORA_VEIL; - sideTimer->auroraVeilBattlerId = data->battlerId; } return &sideTimer->auroraVeilTimer; case LIST_SIDE_LUCKY_CHANT: @@ -1978,7 +1972,6 @@ static u16 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_LUCKY_CHANT; else *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_LUCKY_CHANT; - sideTimer->luckyChantBattlerId = data->battlerId; } return &sideTimer->luckyChantTimer; case LIST_SIDE_TOXIC_SPIKES: diff --git a/src/battle_end_turn.c b/src/battle_end_turn.c index d6905e9065..397bbe134f 100644 --- a/src/battle_end_turn.c +++ b/src/battle_end_turn.c @@ -116,6 +116,19 @@ static inline bool32 IsBattlerProtectedByMagicGuard(u32 battler, u32 ability) return TRUE; } +static u32 GetBattlerSideForMessage(u32 side) +{ + u32 battler = 0; + + for (battler = 0; battler < gBattlersCount; battler++) + { + if (GetBattlerSide(battler) == side) + break; + } + + return battler; +} + static bool32 HandleEndTurnOrder(u32 battler) { bool32 effect = FALSE; @@ -1074,7 +1087,7 @@ static bool32 HandleEndTurnSecondEventBlock(u32 battler) case SECOND_EVENT_BLOCK_REFLECT: if (gSideStatuses[side] & SIDE_STATUS_REFLECT && gSideTimers[side].reflectTimer == gBattleTurnCounter) { - gBattlerAttacker = gSideTimers[side].reflectBattlerId; + gBattlerAttacker = GetBattlerSideForMessage(side); gSideStatuses[side] &= ~SIDE_STATUS_REFLECT; BattleScriptExecute(BattleScript_SideStatusWoreOff); gBattleCommunication[MULTISTRING_CHOOSER] = side; @@ -1086,7 +1099,7 @@ static bool32 HandleEndTurnSecondEventBlock(u32 battler) case SECOND_EVENT_BLOCK_LIGHT_SCREEN: if (gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN && gSideTimers[side].lightscreenTimer == gBattleTurnCounter) { - gBattlerAttacker = gSideTimers[side].lightscreenBattlerId; + gBattlerAttacker = GetBattlerSideForMessage(side); gSideStatuses[side] &= ~SIDE_STATUS_LIGHTSCREEN; BattleScriptExecute(BattleScript_SideStatusWoreOff); gBattleCommunication[MULTISTRING_CHOOSER] = side; @@ -1098,7 +1111,7 @@ static bool32 HandleEndTurnSecondEventBlock(u32 battler) case SECOND_EVENT_BLOCK_SAFEGUARD: if (gSideStatuses[side] & SIDE_STATUS_SAFEGUARD && gSideTimers[side].safeguardTimer == gBattleTurnCounter) { - gBattlerAttacker = gSideTimers[side].safeguardBattlerId; + gBattlerAttacker = GetBattlerSideForMessage(side); gSideStatuses[side] &= ~SIDE_STATUS_SAFEGUARD; BattleScriptExecute(BattleScript_SafeguardEnds); effect = TRUE; @@ -1108,7 +1121,7 @@ static bool32 HandleEndTurnSecondEventBlock(u32 battler) case SECOND_EVENT_BLOCK_MIST: if (gSideTimers[side].mistTimer != 0 && gSideTimers[side].mistTimer == gBattleTurnCounter) { - gBattlerAttacker = gSideTimers[side].mistBattlerId; + gBattlerAttacker = GetBattlerSideForMessage(side); gSideStatuses[side] &= ~SIDE_STATUS_MIST; BattleScriptExecute(BattleScript_SideStatusWoreOff); gBattleCommunication[MULTISTRING_CHOOSER] = side; @@ -1120,7 +1133,7 @@ static bool32 HandleEndTurnSecondEventBlock(u32 battler) case SECOND_EVENT_BLOCK_TAILWIND: if (gSideStatuses[side] & SIDE_STATUS_TAILWIND && gSideTimers[side].tailwindTimer == gBattleTurnCounter) { - gBattlerAttacker = gSideTimers[side].tailwindBattlerId; + gBattlerAttacker = GetBattlerSideForMessage(side); gSideStatuses[side] &= ~SIDE_STATUS_TAILWIND; BattleScriptExecute(BattleScript_TailwindEnds); effect = TRUE; @@ -1130,7 +1143,7 @@ static bool32 HandleEndTurnSecondEventBlock(u32 battler) case SECOND_EVENT_BLOCK_LUCKY_CHANT: if (gSideStatuses[side] & SIDE_STATUS_LUCKY_CHANT && gSideTimers[side].luckyChantTimer == gBattleTurnCounter) { - gBattlerAttacker = gSideTimers[side].luckyChantBattlerId; + gBattlerAttacker = GetBattlerSideForMessage(side); gSideStatuses[side] &= ~SIDE_STATUS_LUCKY_CHANT; BattleScriptExecute(BattleScript_LuckyChantEnds); effect = TRUE; @@ -1138,63 +1151,38 @@ static bool32 HandleEndTurnSecondEventBlock(u32 battler) gBattleStruct->eventBlockCounter++; break; case SECOND_EVENT_BLOCK_RAINBOW: - if (gSideStatuses[side] & SIDE_STATUS_RAINBOW) + gBattlerAttacker = GetBattlerSideForMessage(side); + if (gSideStatuses[side] & SIDE_STATUS_RAINBOW && gSideTimers[side].rainbowTimer == gBattleTurnCounter) { - for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) - { - if (GetBattlerSide(gBattlerAttacker) == side) - break; - } - - if (gSideTimers[side].rainbowTimer == gBattleTurnCounter) - { - gSideStatuses[side] &= ~SIDE_STATUS_RAINBOW; - BattleScriptExecute(BattleScript_TheRainbowDisappeared); - effect = TRUE; - } + gSideStatuses[side] &= ~SIDE_STATUS_RAINBOW; + BattleScriptExecute(BattleScript_TheRainbowDisappeared); + effect = TRUE; } gBattleStruct->eventBlockCounter++; break; case SECOND_EVENT_BLOCK_SEA_OF_FIRE: - if (gSideStatuses[side] & SIDE_STATUS_SEA_OF_FIRE) + if (gSideStatuses[side] & SIDE_STATUS_SEA_OF_FIRE && gSideTimers[side].seaOfFireTimer == gBattleTurnCounter) { - for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) - { - if (GetBattlerSide(gBattlerAttacker) == side) - break; - } - - if (gSideTimers[side].seaOfFireTimer == gBattleTurnCounter) - { - gSideStatuses[side] &= ~SIDE_STATUS_SEA_OF_FIRE; - BattleScriptExecute(BattleScript_TheSeaOfFireDisappeared); - effect = TRUE; - } + gSideStatuses[side] &= ~SIDE_STATUS_SEA_OF_FIRE; + BattleScriptExecute(BattleScript_TheSeaOfFireDisappeared); + effect = TRUE; } gBattleStruct->eventBlockCounter++; break; case SECOND_EVENT_BLOCK_SWAMP: - if (gSideStatuses[side] & SIDE_STATUS_SWAMP) + gBattlerAttacker = GetBattlerSideForMessage(side); + if (gSideStatuses[side] & SIDE_STATUS_SWAMP && gSideTimers[side].swampTimer == gBattleTurnCounter) { - for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) - { - if (GetBattlerSide(gBattlerAttacker) == side) - break; - } - - if (gSideTimers[side].swampTimer == gBattleTurnCounter) - { - gSideStatuses[side] &= ~SIDE_STATUS_SWAMP; - BattleScriptExecute(BattleScript_TheSwampDisappeared); - effect = TRUE; - } + gSideStatuses[side] &= ~SIDE_STATUS_SWAMP; + BattleScriptExecute(BattleScript_TheSwampDisappeared); + effect = TRUE; } gBattleStruct->eventBlockCounter++; break; case SECOND_EVENT_BLOCK_AURORA_VEIL: if (gSideStatuses[side] & SIDE_STATUS_AURORA_VEIL && gSideTimers[side].auroraVeilTimer == gBattleTurnCounter) { - gBattlerAttacker = gSideTimers[side].auroraVeilBattlerId; + gBattlerAttacker = GetBattlerSideForMessage(side); gSideStatuses[side] &= ~SIDE_STATUS_AURORA_VEIL; BattleScriptExecute(BattleScript_SideStatusWoreOff); gBattleCommunication[MULTISTRING_CHOOSER] = side; diff --git a/src/battle_main.c b/src/battle_main.c index 7737592d32..c29b0c6dc9 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3198,7 +3198,7 @@ void SwitchInClearSetData(u32 battler) gBattleStruct->lastTakenMoveFrom[battler][3] = 0; gBattleStruct->battlerState[battler].lastMoveFailed = FALSE; gBattleStruct->palaceFlags &= ~(1u << battler); - gBattleStruct->canPickupItem &= ~(1u << battler); + gBattleStruct->battlerState[battler].canPickupItem = FALSE; ClearPursuitValuesIfSet(battler); @@ -5079,7 +5079,7 @@ static void TurnValuesCleanUp(bool8 var0) if (gDisableStructs[i].rechargeTimer == 0) gBattleMons[i].status2 &= ~STATUS2_RECHARGE; } - gBattleStruct->canPickupItem &= ~(1u << i); + gBattleStruct->battlerState[i].canPickupItem = FALSE; } if (gDisableStructs[i].substituteHP == 0) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index fe00417616..85fe7a3d11 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3157,7 +3157,6 @@ static inline bool32 TrySetReflect(u32 battler) gSideTimers[side].reflectTimer = gBattleTurnCounter + 8; else gSideTimers[side].reflectTimer = gBattleTurnCounter + 5; - gSideTimers[side].reflectBattlerId = battler; if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, battler) == 2) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_DOUBLE; @@ -3179,7 +3178,6 @@ static inline bool32 TrySetLightScreen(u32 battler) gSideTimers[side].lightscreenTimer = gBattleTurnCounter + 8; else gSideTimers[side].lightscreenTimer = gBattleTurnCounter + 5; - gSideTimers[side].lightscreenBattlerId = battler; if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, battler) == 2) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_DOUBLE; @@ -4320,7 +4318,6 @@ void SetMoveEffect(bool32 primary, bool32 certain) gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = gBattleTurnCounter + 8; else gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilTimer = gBattleTurnCounter + 5; - gSideTimers[GetBattlerSide(gBattlerAttacker)].auroraVeilBattlerId = gBattlerAttacker; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SAFEGUARD; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_EffectAuroraVeilSuccess; @@ -9168,7 +9165,7 @@ static void Cmd_removeitem(void) gBattleStruct->usedHeldItems[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)] = itemId; // Remember if switched out gBattleMons[battler].item = ITEM_NONE; - gBattleStruct->canPickupItem |= (1u << battler); + gBattleStruct->battlerState[battler].canPickupItem = TRUE; CheckSetUnburden(battler); BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[battler].item), &gBattleMons[battler].item); @@ -9917,14 +9914,6 @@ void BS_CourtChangeSwapSideStatuses(void) COURTCHANGE_SWAP(SIDE_STATUS_SWAMP, swampTimer, temp); // Change battler IDs of swapped effects. Needed for the correct string when they expire - // E.g. "Foe's Reflect wore off!" - UPDATE_COURTCHANGED_BATTLER(reflectBattlerId); - UPDATE_COURTCHANGED_BATTLER(lightscreenBattlerId); - UPDATE_COURTCHANGED_BATTLER(mistBattlerId); - UPDATE_COURTCHANGED_BATTLER(safeguardBattlerId); - UPDATE_COURTCHANGED_BATTLER(auroraVeilBattlerId); - UPDATE_COURTCHANGED_BATTLER(tailwindBattlerId); - UPDATE_COURTCHANGED_BATTLER(luckyChantBattlerId); UPDATE_COURTCHANGED_BATTLER(stickyWebBattlerId); // Track which side originally set the Sticky Web @@ -10657,7 +10646,6 @@ static void Cmd_various(void) if (!(gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_LUCKY_CHANT)) { gSideStatuses[GetBattlerSide(battler)] |= SIDE_STATUS_LUCKY_CHANT; - gSideTimers[GetBattlerSide(battler)].luckyChantBattlerId = battler; gSideTimers[GetBattlerSide(battler)].luckyChantTimer = gBattleTurnCounter + 5; gBattlescriptCurrInstr = cmd->nextInstr; } @@ -11111,7 +11099,6 @@ static void Cmd_various(void) gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = gBattleTurnCounter + 8; else gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = gBattleTurnCounter + 5; - gSideTimers[GetBattlerSide(battler)].auroraVeilBattlerId = battler; if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) gBattleCommunication[MULTISTRING_CHOOSER] = 5; @@ -13143,7 +13130,6 @@ static void Cmd_setmist(void) else { gSideTimers[GetBattlerSide(gBattlerAttacker)].mistTimer = gBattleTurnCounter + 5; - gSideTimers[GetBattlerSide(gBattlerAttacker)].mistBattlerId = gBattlerAttacker; gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_MIST; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_MIST; } @@ -13808,7 +13794,6 @@ static void Cmd_settailwind(void) if (!(gSideStatuses[side] & SIDE_STATUS_TAILWIND)) { gSideStatuses[side] |= SIDE_STATUS_TAILWIND; - gSideTimers[side].tailwindBattlerId = gBattlerAttacker; gSideTimers[side].tailwindTimer = gBattleTurnCounter + (B_TAILWIND_TURNS >= GEN_5 ? 4 : 3); gBattlescriptCurrInstr = cmd->nextInstr; } @@ -14206,7 +14191,6 @@ static void Cmd_setsafeguard(void) { gSideStatuses[GetBattlerSide(gBattlerAttacker)] |= SIDE_STATUS_SAFEGUARD; gSideTimers[GetBattlerSide(gBattlerAttacker)].safeguardTimer = gBattleTurnCounter + 5; - gSideTimers[GetBattlerSide(gBattlerAttacker)].safeguardBattlerId = gBattlerAttacker; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SAFEGUARD; } diff --git a/src/battle_util.c b/src/battle_util.c index 6e1ea967f2..8408868e3c 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -10834,7 +10834,7 @@ bool32 CantPickupItem(u32 battler) // Used by RandomUniformExcept() for RNG_PICKUP if (battler == gBattlerAttacker && (B_PICKUP_WILD < GEN_9 || gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK))) return TRUE; - return !(IsBattlerAlive(battler) && GetUsedHeldItem(battler) && gBattleStruct->canPickupItem & (1u << battler)); + return !(IsBattlerAlive(battler) && GetUsedHeldItem(battler) && gBattleStruct->battlerState[battler].canPickupItem); } bool32 PickupHasValidTarget(u32 battler)