Adds partyState to BattleStruct (#6783)

This commit is contained in:
Alex 2025-05-09 12:29:54 +02:00 committed by GitHub
parent f3113eb865
commit 9060d401c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 22 deletions

View File

@ -593,10 +593,22 @@ struct BattlerState
// End of Word // 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. // Cleared at the beginning of the battle. Fields need to be cleared when needed manually otherwise.
struct BattleStruct struct BattleStruct
{ {
struct BattlerState battlerState[MAX_BATTLERS_COUNT]; struct BattlerState battlerState[MAX_BATTLERS_COUNT];
struct PartyState partyState[NUM_BATTLE_SIDES][PARTY_SIZE];
u8 eventBlockCounter; u8 eventBlockCounter;
u8 turnEffectsBattlerId; u8 turnEffectsBattlerId;
u8 endTurnEventsCounter; u8 endTurnEventsCounter;
@ -703,7 +715,6 @@ struct BattleStruct
struct BattleGimmickData gimmick; struct BattleGimmickData gimmick;
const u8 *trainerSlideMsg; const u8 *trainerSlideMsg;
enum BattleIntroStates introState:8; 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 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 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]; u16 tracedAbility[MAX_BATTLERS_COUNT];
@ -734,7 +745,6 @@ struct BattleStruct
u8 pledgeMove:1; u8 pledgeMove:1;
u8 effectsBeforeUsingMoveDone:1; // Mega Evo and Focus Punch/Shell Trap effects. u8 effectsBeforeUsingMoveDone:1; // Mega Evo and Focus Punch/Shell Trap effects.
u8 spriteIgnore0Hp:1; 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 bonusCritStages[MAX_BATTLERS_COUNT]; // G-Max Chi Strike boosts crit stages of allies.
u8 itemPartyIndex[MAX_BATTLERS_COUNT]; u8 itemPartyIndex[MAX_BATTLERS_COUNT];
u8 itemMoveIndex[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 aiDelayFrames; // Number of frames it took to choose an action.
s32 aiDelayCycles; // Number of cycles 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 timesGotHit[NUM_BATTLE_SIDES][PARTY_SIZE];
u8 transformZeroToHero[NUM_BATTLE_SIDES];
u8 stickySyrupdBy[MAX_BATTLERS_COUNT]; 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 supremeOverlordCounter[MAX_BATTLERS_COUNT];
u8 shellSideArmCategory[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT]; u8 shellSideArmCategory[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT];
u8 speedTieBreaks; // MAX_BATTLERS_COUNT! values. u8 speedTieBreaks; // MAX_BATTLERS_COUNT! values.

View File

@ -2401,7 +2401,7 @@ static inline bool32 TryActivateWeakenessBerry(u32 battlerDef)
gSpecialStatuses[battlerDef].berryReduced = FALSE; gSpecialStatuses[battlerDef].berryReduced = FALSE;
gBattleScripting.battler = battlerDef; gBattleScripting.battler = battlerDef;
gLastUsedItem = gBattleMons[battlerDef].item; gLastUsedItem = gBattleMons[battlerDef].item;
gBattleStruct->ateBerry[battlerDef & BIT_SIDE] |= 1u << gBattlerPartyIndexes[battlerDef]; gBattleStruct->partyState[GetBattlerSide(battlerDef)][gBattlerPartyIndexes[battlerDef]].ateBerry = TRUE;
BattleScriptPushCursor(); BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryReduceDmg; gBattlescriptCurrInstr = BattleScript_BerryReduceDmg;
return TRUE; return TRUE;
@ -6206,14 +6206,14 @@ static bool32 HandleMoveEndAbilityBlock(u32 battlerAtk, u32 battlerDef, u32 move
u32 side = GetBattlerSide(battlerAtk); u32 side = GetBattlerSide(battlerAtk);
if (gBattleStruct->battleBondBoost[side] & (1u << gBattlerPartyIndexes[battlerAtk])) if (gBattleStruct->partyState[side][gBattlerPartyIndexes[battlerAtk]].battleBondBoost)
break; break;
if (GetGenConfig(GEN_CONFIG_BATTLE_BOND) < GEN_9 && gBattleMons[battlerAtk].species == SPECIES_GRENINJA_BATTLE_BOND) if (GetGenConfig(GEN_CONFIG_BATTLE_BOND) < GEN_9 && gBattleMons[battlerAtk].species == SPECIES_GRENINJA_BATTLE_BOND)
{ {
// TODO: Convert this to a proper FORM_CHANGE type. // TODO: Convert this to a proper FORM_CHANGE type.
gLastUsedAbility = abilityAtk; gLastUsedAbility = abilityAtk;
gBattleStruct->battleBondBoost[side] |= 1u << gBattlerPartyIndexes[battlerAtk]; gBattleStruct->partyState[side][gBattlerPartyIndexes[battlerAtk]].battleBondBoost = TRUE;
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[battlerAtk].species); PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[battlerAtk].species);
gBattleStruct->changedSpecies[side][gBattlerPartyIndexes[battlerAtk]] = gBattleMons[battlerAtk].species; gBattleStruct->changedSpecies[side][gBattlerPartyIndexes[battlerAtk]] = gBattleMons[battlerAtk].species;
gBattleMons[battlerAtk].species = SPECIES_GRENINJA_ASH; gBattleMons[battlerAtk].species = SPECIES_GRENINJA_ASH;
@ -6247,7 +6247,7 @@ static bool32 HandleMoveEndAbilityBlock(u32 battlerAtk, u32 battlerDef, u32 move
gLastUsedAbility = abilityAtk; gLastUsedAbility = abilityAtk;
gBattlerAbility = battlerAtk; gBattlerAbility = battlerAtk;
gBattleStruct->battleBondBoost[side] |= 1u << gBattlerPartyIndexes[battlerAtk]; gBattleStruct->partyState[side][gBattlerPartyIndexes[battlerAtk]].battleBondBoost = TRUE;
BattleScriptPushCursor(); BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_EffectBattleBondStatIncrease; gBattlescriptCurrInstr = BattleScript_EffectBattleBondStatIncrease;
effect = TRUE; effect = TRUE;
@ -9075,7 +9075,7 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId)
if (ItemId_GetPocket(itemId) == POCKET_BERRIES if (ItemId_GetPocket(itemId) == POCKET_BERRIES
&& GetBattlerAbility(battler) == ABILITY_CHEEK_POUCH && GetBattlerAbility(battler) == ABILITY_CHEEK_POUCH
&& !(gStatuses3[battler] & STATUS3_HEAL_BLOCK) && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)
&& gBattleStruct->ateBerry[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]) && gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].ateBerry
&& !IsBattlerAtMaxHp(battler)) && !IsBattlerAtMaxHp(battler))
{ {
gBattleStruct->cheekPouchActivated = TRUE; gBattleStruct->cheekPouchActivated = TRUE;
@ -11411,7 +11411,7 @@ static void Cmd_various(void)
if (cmd->fromBattler) if (cmd->fromBattler)
gLastUsedItem = gBattleMons[battler].item; 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 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)) if (ItemBattleEffects(ITEMEFFECT_USE_LAST_ITEM, battler, FALSE))
return; return;

View File

@ -1281,7 +1281,7 @@ bool32 IsBelchPreventingMove(u32 battler, u32 move)
if (GetMoveEffect(move) != EFFECT_BELCH) if (GetMoveEffect(move) != EFFECT_BELCH)
return FALSE; 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. // 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; break;
case ABILITY_SUPERSWEET_SYRUP: case ABILITY_SUPERSWEET_SYRUP:
if (!gSpecialStatuses[battler].switchInAbilityDone if (!gSpecialStatuses[battler].switchInAbilityDone
&& !(gBattleStruct->supersweetSyrup[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]))) && !gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].supersweetSyrup)
{ {
gBattlerAttacker = battler; gBattlerAttacker = battler;
gSpecialStatuses[battler].switchInAbilityDone = TRUE; gSpecialStatuses[battler].switchInAbilityDone = TRUE;
gBattleStruct->supersweetSyrup[GetBattlerSide(battler)] |= (1u << gBattlerPartyIndexes[battler]); gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]].supersweetSyrup = TRUE;
BattleScriptPushCursorAndCallback(BattleScript_SupersweetSyrupActivates); BattleScriptPushCursorAndCallback(BattleScript_SupersweetSyrupActivates);
effect++; effect++;
} }
@ -3897,12 +3897,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break; break;
case ABILITY_INTREPID_SWORD: case ABILITY_INTREPID_SWORD:
if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) 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; gBattleScripting.savedBattler = gBattlerAttacker;
gBattlerAttacker = battler; gBattlerAttacker = battler;
if (B_INTREPID_SWORD == GEN_9) 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; gSpecialStatuses[battler].switchInAbilityDone = TRUE;
SET_STATCHANGER(STAT_ATK, 1, FALSE); SET_STATCHANGER(STAT_ATK, 1, FALSE);
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn); BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
@ -3911,12 +3911,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break; break;
case ABILITY_DAUNTLESS_SHIELD: case ABILITY_DAUNTLESS_SHIELD:
if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN) 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; gBattleScripting.savedBattler = gBattlerAttacker;
gBattlerAttacker = battler; gBattlerAttacker = battler;
if (B_DAUNTLESS_SHIELD == GEN_9) 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; gSpecialStatuses[battler].switchInAbilityDone = TRUE;
SET_STATCHANGER(STAT_DEF, 1, FALSE); SET_STATCHANGER(STAT_DEF, 1, FALSE);
BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn); BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn);
@ -4033,10 +4033,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (!gSpecialStatuses[battler].switchInAbilityDone if (!gSpecialStatuses[battler].switchInAbilityDone
&& GetMonData(mon, MON_DATA_SPECIES) == SPECIES_PALAFIN_HERO && GetMonData(mon, MON_DATA_SPECIES) == SPECIES_PALAFIN_HERO
&& !(gBattleStruct->transformZeroToHero[side] & (1u << gBattlerPartyIndexes[battler]))) && !gBattleStruct->partyState[side][gBattlerPartyIndexes[battler]].transformZeroToHero)
{ {
gSpecialStatuses[battler].switchInAbilityDone = TRUE; gSpecialStatuses[battler].switchInAbilityDone = TRUE;
gBattleStruct->transformZeroToHero[side] |= 1u << gBattlerPartyIndexes[battler]; gBattleStruct->partyState[side][gBattlerPartyIndexes[battler]].transformZeroToHero = TRUE;
BattleScriptPushCursorAndCallback(BattleScript_ZeroToHeroActivates); BattleScriptPushCursorAndCallback(BattleScript_ZeroToHeroActivates);
effect++; effect++;
} }
@ -7431,7 +7431,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn)
// Berry was successfully used on a Pokemon. // Berry was successfully used on a Pokemon.
if (effect && (gLastUsedItem >= FIRST_BERRY_INDEX && gLastUsedItem <= LAST_BERRY_INDEX)) 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; return effect;
} }