diff --git a/include/battle.h b/include/battle.h index ceb5e67557..91b96a6ccd 100644 --- a/include/battle.h +++ b/include/battle.h @@ -593,10 +593,22 @@ struct BattlerState // End of Word }; +struct PartyState +{ + u32 intrepidSwordBoost:1; + u32 dauntlessShieldBoost:1; + u32 ateBerry:1; + u32 battleBondBoost:1; + u32 transformZeroToHero:1; + u32 supersweetSyrup:1; + u32 padding:26; +}; + // Cleared at the beginning of the battle. Fields need to be cleared when needed manually otherwise. struct BattleStruct { struct BattlerState battlerState[MAX_BATTLERS_COUNT]; + struct PartyState partyState[NUM_BATTLE_SIDES][PARTY_SIZE]; u8 eventBlockCounter; u8 turnEffectsBattlerId; u8 endTurnEventsCounter; @@ -703,7 +715,6 @@ struct BattleStruct struct BattleGimmickData gimmick; const u8 *trainerSlideMsg; enum BattleIntroStates introState:8; - u8 ateBerry[NUM_BATTLE_SIDES]; // array id determined by side, each party pokemon as bit u8 stolenStats[NUM_BATTLE_STATS]; // hp byte is used for which stats to raise, other inform about by how many stages u8 lastMoveTarget[MAX_BATTLERS_COUNT]; // The last target on which each mon used a move, for the sake of Instruct u16 tracedAbility[MAX_BATTLERS_COUNT]; @@ -734,7 +745,6 @@ struct BattleStruct u8 pledgeMove:1; u8 effectsBeforeUsingMoveDone:1; // Mega Evo and Focus Punch/Shell Trap effects. u8 spriteIgnore0Hp:1; - u8 battleBondBoost[NUM_BATTLE_SIDES]; // Bitfield for each party. u8 bonusCritStages[MAX_BATTLERS_COUNT]; // G-Max Chi Strike boosts crit stages of allies. u8 itemPartyIndex[MAX_BATTLERS_COUNT]; u8 itemMoveIndex[MAX_BATTLERS_COUNT]; @@ -743,11 +753,7 @@ struct BattleStruct s32 aiDelayFrames; // Number of frames it took to choose an action. s32 aiDelayCycles; // Number of cycles it took to choose an action. u8 timesGotHit[NUM_BATTLE_SIDES][PARTY_SIZE]; - u8 transformZeroToHero[NUM_BATTLE_SIDES]; u8 stickySyrupdBy[MAX_BATTLERS_COUNT]; - u8 intrepidSwordBoost[NUM_BATTLE_SIDES]; - u8 dauntlessShieldBoost[NUM_BATTLE_SIDES]; - u8 supersweetSyrup[NUM_BATTLE_SIDES]; u8 supremeOverlordCounter[MAX_BATTLERS_COUNT]; u8 shellSideArmCategory[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT]; u8 speedTieBreaks; // MAX_BATTLERS_COUNT! values. diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 24f884b863..e60a79e059 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2401,7 +2401,7 @@ static inline bool32 TryActivateWeakenessBerry(u32 battlerDef) gSpecialStatuses[battlerDef].berryReduced = FALSE; gBattleScripting.battler = battlerDef; gLastUsedItem = gBattleMons[battlerDef].item; - gBattleStruct->ateBerry[battlerDef & BIT_SIDE] |= 1u << gBattlerPartyIndexes[battlerDef]; + gBattleStruct->partyState[GetBattlerSide(battlerDef)][gBattlerPartyIndexes[battlerDef]].ateBerry = TRUE; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryReduceDmg; return TRUE; @@ -6206,14 +6206,14 @@ static bool32 HandleMoveEndAbilityBlock(u32 battlerAtk, u32 battlerDef, u32 move u32 side = GetBattlerSide(battlerAtk); - if (gBattleStruct->battleBondBoost[side] & (1u << gBattlerPartyIndexes[battlerAtk])) + if (gBattleStruct->partyState[side][gBattlerPartyIndexes[battlerAtk]].battleBondBoost) break; if (GetGenConfig(GEN_CONFIG_BATTLE_BOND) < GEN_9 && gBattleMons[battlerAtk].species == SPECIES_GRENINJA_BATTLE_BOND) { // TODO: Convert this to a proper FORM_CHANGE type. gLastUsedAbility = abilityAtk; - gBattleStruct->battleBondBoost[side] |= 1u << gBattlerPartyIndexes[battlerAtk]; + gBattleStruct->partyState[side][gBattlerPartyIndexes[battlerAtk]].battleBondBoost = TRUE; PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[battlerAtk].species); gBattleStruct->changedSpecies[side][gBattlerPartyIndexes[battlerAtk]] = gBattleMons[battlerAtk].species; gBattleMons[battlerAtk].species = SPECIES_GRENINJA_ASH; @@ -6247,7 +6247,7 @@ static bool32 HandleMoveEndAbilityBlock(u32 battlerAtk, u32 battlerDef, u32 move gLastUsedAbility = abilityAtk; gBattlerAbility = battlerAtk; - gBattleStruct->battleBondBoost[side] |= 1u << gBattlerPartyIndexes[battlerAtk]; + gBattleStruct->partyState[side][gBattlerPartyIndexes[battlerAtk]].battleBondBoost = TRUE; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_EffectBattleBondStatIncrease; effect = TRUE; @@ -9075,7 +9075,7 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId) if (ItemId_GetPocket(itemId) == POCKET_BERRIES && GetBattlerAbility(battler) == ABILITY_CHEEK_POUCH && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK) - && gBattleStruct->ateBerry[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]) + && gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].ateBerry && !IsBattlerAtMaxHp(battler)) { gBattleStruct->cheekPouchActivated = TRUE; @@ -11411,7 +11411,7 @@ static void Cmd_various(void) if (cmd->fromBattler) gLastUsedItem = gBattleMons[battler].item; - gBattleStruct->ateBerry[battler & BIT_SIDE] |= 1u << gBattlerPartyIndexes[battler]; + gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].ateBerry = TRUE; gBattleScripting.battler = gEffectBattler = gBattlerTarget = battler; // Cover all berry effect battler cases. e.g. ChangeStatBuffs uses target ID if (ItemBattleEffects(ITEMEFFECT_USE_LAST_ITEM, battler, FALSE)) return; diff --git a/src/battle_util.c b/src/battle_util.c index 92fb7d5976..a8c26644fc 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1281,7 +1281,7 @@ bool32 IsBelchPreventingMove(u32 battler, u32 move) if (GetMoveEffect(move) != EFFECT_BELCH) return FALSE; - return !(gBattleStruct->ateBerry[battler & BIT_SIDE] & (1u << gBattlerPartyIndexes[battler])); + return !gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].ateBerry; } // Dynamax bypasses all selection prevention except Taunt and Assault Vest. @@ -3856,11 +3856,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_SUPERSWEET_SYRUP: if (!gSpecialStatuses[battler].switchInAbilityDone - && !(gBattleStruct->supersweetSyrup[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]))) + && !gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].supersweetSyrup) { gBattlerAttacker = battler; gSpecialStatuses[battler].switchInAbilityDone = TRUE; - gBattleStruct->supersweetSyrup[GetBattlerSide(battler)] |= (1u << gBattlerPartyIndexes[battler]); + gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].supersweetSyrup = TRUE; BattleScriptPushCursorAndCallback(BattleScript_SupersweetSyrupActivates); effect++; } @@ -3897,12 +3897,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_INTREPID_SWORD: if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) - && !(gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]))) + && !gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].intrepidSwordBoost) { gBattleScripting.savedBattler = gBattlerAttacker; gBattlerAttacker = battler; if (B_INTREPID_SWORD == GEN_9) - gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] |= 1u << gBattlerPartyIndexes[battler]; + gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].intrepidSwordBoost = TRUE; gSpecialStatuses[battler].switchInAbilityDone = TRUE; SET_STATCHANGER(STAT_ATK, 1, FALSE); BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn); @@ -3911,12 +3911,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_DAUNTLESS_SHIELD: if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN) - && !(gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]))) + && !gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].dauntlessShieldBoost) { gBattleScripting.savedBattler = gBattlerAttacker; gBattlerAttacker = battler; if (B_DAUNTLESS_SHIELD == GEN_9) - gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] |= 1u << gBattlerPartyIndexes[battler]; + gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].dauntlessShieldBoost = TRUE; gSpecialStatuses[battler].switchInAbilityDone = TRUE; SET_STATCHANGER(STAT_DEF, 1, FALSE); BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn); @@ -4033,10 +4033,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!gSpecialStatuses[battler].switchInAbilityDone && GetMonData(mon, MON_DATA_SPECIES) == SPECIES_PALAFIN_HERO - && !(gBattleStruct->transformZeroToHero[side] & (1u << gBattlerPartyIndexes[battler]))) + && !gBattleStruct->partyState[side][gBattlerPartyIndexes[battler]].transformZeroToHero) { gSpecialStatuses[battler].switchInAbilityDone = TRUE; - gBattleStruct->transformZeroToHero[side] |= 1u << gBattlerPartyIndexes[battler]; + gBattleStruct->partyState[side][gBattlerPartyIndexes[battler]].transformZeroToHero = TRUE; BattleScriptPushCursorAndCallback(BattleScript_ZeroToHeroActivates); effect++; } @@ -7431,7 +7431,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn) // Berry was successfully used on a Pokemon. if (effect && (gLastUsedItem >= FIRST_BERRY_INDEX && gLastUsedItem <= LAST_BERRY_INDEX)) - gBattleStruct->ateBerry[battler & BIT_SIDE] |= 1u << gBattlerPartyIndexes[battler]; + gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].ateBerry = TRUE; return effect; }