Removes Resource Flags and moves fields to DisableStruct (#5945)
This commit is contained in:
parent
bfa9d905e1
commit
8f34c76395
@ -68,20 +68,6 @@
|
||||
|
||||
#define BATTLE_BUFFER_LINK_SIZE 0x1000
|
||||
|
||||
struct ResourceFlags
|
||||
{
|
||||
u32 flags[MAX_BATTLERS_COUNT];
|
||||
};
|
||||
|
||||
#define RESOURCE_FLAG_FLASH_FIRE 0x1
|
||||
#define RESOURCE_FLAG_ROOST 0x2
|
||||
#define RESOURCE_FLAG_UNBURDEN 0x4
|
||||
#define RESOURCE_FLAG_UNUSED 0x8
|
||||
#define RESOURCE_FLAG_UNUSED_2 0x10
|
||||
#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20
|
||||
#define RESOURCE_FLAG_NEUTRALIZING_GAS 0x40
|
||||
#define RESOURCE_FLAG_ICE_FACE 0x80
|
||||
|
||||
struct DisableStruct
|
||||
{
|
||||
u32 transformedMonPersonality;
|
||||
@ -118,6 +104,7 @@ struct DisableStruct
|
||||
u8 laserFocusTimer;
|
||||
u8 throatChopTimer;
|
||||
u8 wrapTurns;
|
||||
u8 syrupBombTimer;
|
||||
u8 tormentTimer:4; // used for G-Max Meltdown
|
||||
u8 usedMoves:4;
|
||||
u8 truantCounter:1;
|
||||
@ -130,16 +117,23 @@ struct DisableStruct
|
||||
u8 toxicSpikesDone:1;
|
||||
u8 stickyWebDone:1;
|
||||
u8 stealthRockDone:1;
|
||||
u8 syrupBombTimer;
|
||||
u8 syrupBombIsShiny:1;
|
||||
u8 steelSurgeDone:1;
|
||||
u8 weatherAbilityDone:1;
|
||||
u8 terrainAbilityDone:1;
|
||||
u8 syrupBombIsShiny:1;
|
||||
u8 steelSurgeDone:1;
|
||||
u8 usedProteanLibero:1;
|
||||
u8 flashFireBoosted:1;
|
||||
u16 overwrittenAbility; // abilities overwritten during battle (keep separate from battle history in case of switching)
|
||||
u8 boosterEnergyActivates:1;
|
||||
u8 roostActive:1;
|
||||
u8 unbrudenActive:1;
|
||||
u8 startEmergencyExit:1;
|
||||
u8 neutralizingGas:1;
|
||||
u8 iceFaceActivationPrevention:1; // fixes hit escape move edge case
|
||||
u8 padding:2;
|
||||
};
|
||||
|
||||
// Fully Cleared each turn after end turn effects are done. A few things are cleared before end turn effects
|
||||
struct ProtectStruct
|
||||
{
|
||||
u32 protected:1;
|
||||
@ -193,9 +187,9 @@ struct ProtectStruct
|
||||
u32 specialDmg;
|
||||
u8 physicalBattlerId;
|
||||
u8 specialBattlerId;
|
||||
|
||||
};
|
||||
|
||||
// Cleared at the start of HandleAction_ActionFinished
|
||||
struct SpecialStatus
|
||||
{
|
||||
s32 physicalDmg;
|
||||
@ -416,7 +410,6 @@ struct StatsArray
|
||||
struct BattleResources
|
||||
{
|
||||
struct SecretBase* secretBase;
|
||||
struct ResourceFlags *flags;
|
||||
struct BattleScriptsStack* battleScriptsStack;
|
||||
struct BattleCallbacksStack* battleCallbackStack;
|
||||
struct StatsArray* beforeLvlUp;
|
||||
|
||||
@ -2826,7 +2826,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case ABILITY_FLASH_FIRE:
|
||||
if (moveType == TYPE_FIRE
|
||||
&& HasMoveWithType(battlerAtkPartner, TYPE_FIRE)
|
||||
&& !(gBattleResources->flags->flags[battlerAtkPartner] & RESOURCE_FLAG_FLASH_FIRE))
|
||||
&& !gDisableStructs[battlerAtkPartner].flashFireBoosted)
|
||||
{
|
||||
RETURN_SCORE_PLUS(WEAK_EFFECT);
|
||||
}
|
||||
|
||||
@ -3049,7 +3049,6 @@ static void BattleStartClearSetData(void)
|
||||
gLastHitBy[i] = 0xFF;
|
||||
gLockedMoves[i] = MOVE_NONE;
|
||||
gLastPrintedMoves[i] = MOVE_NONE;
|
||||
gBattleResources->flags->flags[i] = 0;
|
||||
gPalaceSelectionBattleScripts[i] = 0;
|
||||
gBattleStruct->lastTakenMove[i] = MOVE_NONE;
|
||||
gBattleStruct->choicedMove[i] = MOVE_NONE;
|
||||
@ -3263,7 +3262,6 @@ void SwitchInClearSetData(u32 battler)
|
||||
}
|
||||
|
||||
gBattleStruct->choicedMove[battler] = MOVE_NONE;
|
||||
gBattleResources->flags->flags[battler] = 0;
|
||||
gCurrentMove = MOVE_NONE;
|
||||
gBattleStruct->arenaTurnCounter = 0xFF;
|
||||
|
||||
@ -3404,8 +3402,6 @@ const u8* FaintClearSetData(u32 battler)
|
||||
gBattleStruct->lastTakenMoveFrom[i][battler] = 0;
|
||||
}
|
||||
|
||||
gBattleResources->flags->flags[battler] = 0;
|
||||
|
||||
gBattleMons[battler].types[0] = gSpeciesInfo[gBattleMons[battler].species].types[0];
|
||||
gBattleMons[battler].types[1] = gSpeciesInfo[gBattleMons[battler].species].types[1];
|
||||
gBattleMons[battler].types[2] = TYPE_MYSTERY;
|
||||
@ -4818,7 +4814,7 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect)
|
||||
// various effects
|
||||
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_TAILWIND)
|
||||
speed *= 2;
|
||||
if (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_UNBURDEN)
|
||||
if (gDisableStructs[battler].unbrudenActive)
|
||||
speed *= 2;
|
||||
|
||||
// paralysis drop
|
||||
@ -5972,11 +5968,11 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost)
|
||||
u32 teraType;
|
||||
if (GetActiveGimmick(battler) == GIMMICK_TERA && ((teraType = GetMonData(mon, MON_DATA_TERA_TYPE)) != TYPE_STELLAR))
|
||||
return teraType;
|
||||
else if (type1 != TYPE_MYSTERY && !(gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST && type1 == TYPE_FLYING))
|
||||
else if (type1 != TYPE_MYSTERY && !(gDisableStructs[battler].roostActive && type1 == TYPE_FLYING))
|
||||
return type1;
|
||||
else if (type2 != TYPE_MYSTERY && !(gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST && type2 == TYPE_FLYING))
|
||||
else if (type2 != TYPE_MYSTERY && !(gDisableStructs[battler].roostActive && type2 == TYPE_FLYING))
|
||||
return type2;
|
||||
else if (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST)
|
||||
else if (gDisableStructs[battler].roostActive)
|
||||
return (B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY);
|
||||
else if (type3 != TYPE_MYSTERY)
|
||||
return type3;
|
||||
|
||||
@ -2137,7 +2137,7 @@ static void Cmd_adjustdamage(void)
|
||||
gBattleStruct->moveResultFlags[battlerDef] &= ~(MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE);
|
||||
gBattleStruct->moveDamage[battlerDef] = 0;
|
||||
RecordAbilityBattle(gBattlerTarget, ABILITY_ICE_FACE);
|
||||
gBattleResources->flags->flags[battlerDef] |= RESOURCE_FLAG_ICE_FACE;
|
||||
gDisableStructs[battlerDef].iceFaceActivationPrevention = TRUE;
|
||||
// Form change will be done after attack animation in Cmd_resultmessage.
|
||||
continue;
|
||||
}
|
||||
@ -2807,9 +2807,9 @@ static void Cmd_resultmessage(void)
|
||||
|
||||
// TODO: Convert this to a proper FORM_CHANGE type.
|
||||
// Do Ice Face form change which was set up in Cmd_adjustdamage.
|
||||
if (gBattleResources->flags->flags[gBattlerTarget] & RESOURCE_FLAG_ICE_FACE)
|
||||
if (gDisableStructs[gBattlerTarget].iceFaceActivationPrevention)
|
||||
{
|
||||
gBattleResources->flags->flags[gBattlerTarget] &= ~(RESOURCE_FLAG_ICE_FACE);
|
||||
gDisableStructs[gBattlerTarget].iceFaceActivationPrevention = FALSE;
|
||||
gBattleMons[gBattlerTarget].species = SPECIES_EISCUE_NOICE;
|
||||
gBattleScripting.battler = gBattlerTarget; // For STRINGID_PKMNTRANSFORMED
|
||||
BattleScriptPushCursor();
|
||||
@ -3062,7 +3062,7 @@ static void CheckSetUnburden(u8 battler)
|
||||
{
|
||||
if (GetBattlerAbility(battler) == ABILITY_UNBURDEN)
|
||||
{
|
||||
gBattleResources->flags->flags[battler] |= RESOURCE_FLAG_UNBURDEN;
|
||||
gDisableStructs[battler].unbrudenActive = TRUE;
|
||||
RecordAbilityBattle(battler, ABILITY_UNBURDEN);
|
||||
}
|
||||
}
|
||||
@ -3084,7 +3084,8 @@ void StealTargetItem(u8 battlerStealer, u8 battlerItem)
|
||||
{
|
||||
RecordItemEffectBattle(battlerStealer, ItemId_GetHoldEffect(gLastUsedItem));
|
||||
gBattleMons[battlerStealer].item = gLastUsedItem;
|
||||
gBattleResources->flags->flags[battlerStealer] &= ~RESOURCE_FLAG_UNBURDEN;
|
||||
|
||||
gDisableStructs[battlerStealer].unbrudenActive = FALSE;
|
||||
BtlController_EmitSetMonData(battlerStealer, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gLastUsedItem), &gLastUsedItem); // set attacker item
|
||||
MarkBattlerForControllerExec(battlerStealer);
|
||||
}
|
||||
@ -5586,7 +5587,7 @@ static void Cmd_setroost(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
|
||||
gBattleResources->flags->flags[gBattlerAttacker] |= RESOURCE_FLAG_ROOST;
|
||||
gDisableStructs[gBattlerAttacker].roostActive = TRUE;
|
||||
gBattleStruct->roostTypes[gBattlerAttacker][0] = gBattleMons[gBattlerAttacker].types[0];
|
||||
gBattleStruct->roostTypes[gBattlerAttacker][1] = gBattleMons[gBattlerAttacker].types[1];
|
||||
|
||||
@ -6714,7 +6715,7 @@ static void Cmd_moveend(void)
|
||||
}
|
||||
else // Eject Pack
|
||||
{
|
||||
if (!(gBattleResources->flags->flags[gBattlerTarget] & RESOURCE_FLAG_EMERGENCY_EXIT)
|
||||
if (!gDisableStructs[gBattlerTarget].startEmergencyExit
|
||||
&& !(gMovesInfo[gCurrentMove].effect == EFFECT_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker)))
|
||||
{
|
||||
effect = TRUE;
|
||||
@ -6892,12 +6893,12 @@ static void Cmd_moveend(void)
|
||||
{
|
||||
if (gBattleStruct->redCardActivates)
|
||||
{
|
||||
gBattleResources->flags->flags[i] &= ~RESOURCE_FLAG_EMERGENCY_EXIT;
|
||||
gDisableStructs[i].startEmergencyExit = FALSE;
|
||||
continue;
|
||||
}
|
||||
if (gBattleResources->flags->flags[i] & RESOURCE_FLAG_EMERGENCY_EXIT)
|
||||
if (gDisableStructs[i].startEmergencyExit)
|
||||
{
|
||||
gBattleResources->flags->flags[i] &= ~RESOURCE_FLAG_EMERGENCY_EXIT;
|
||||
gDisableStructs[i].startEmergencyExit = FALSE;
|
||||
gSpecialStatuses[i].emergencyExited = TRUE;
|
||||
gBattlerTarget = gBattlerAbility = i;
|
||||
BattleScriptPushCursor();
|
||||
@ -8610,7 +8611,7 @@ static void BestowItem(u32 battlerAtk, u32 battlerDef)
|
||||
gBattleMons[battlerDef].item = gLastUsedItem;
|
||||
BtlController_EmitSetMonData(battlerDef, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[battlerDef].item), &gBattleMons[battlerDef].item);
|
||||
MarkBattlerForControllerExec(battlerDef);
|
||||
gBattleResources->flags->flags[battlerDef] &= ~RESOURCE_FLAG_UNBURDEN;
|
||||
gDisableStructs[battlerDef].unbrudenActive = FALSE;
|
||||
}
|
||||
|
||||
// Called by Cmd_removeitem. itemId represents the item that was removed, not being given.
|
||||
@ -14665,8 +14666,8 @@ static void Cmd_tryswapitems(void)
|
||||
}
|
||||
else if (oldItemAtk == ITEM_NONE && *newItemAtk != ITEM_NONE)
|
||||
{
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNBURDEN && gBattleResources->flags->flags[gBattlerAttacker] & RESOURCE_FLAG_UNBURDEN)
|
||||
gBattleResources->flags->flags[gBattlerAttacker] &= ~RESOURCE_FLAG_UNBURDEN;
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNBURDEN && gDisableStructs[gBattlerAttacker].unbrudenActive)
|
||||
gDisableStructs[gBattlerAttacker].unbrudenActive = FALSE;
|
||||
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ITEM_SWAP_TAKEN; // nothing -> <- target's item
|
||||
}
|
||||
|
||||
@ -2782,8 +2782,8 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_ROOST: // Return flying type.
|
||||
if (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST)
|
||||
gBattleResources->flags->flags[battler] &= ~RESOURCE_FLAG_ROOST;
|
||||
if (gDisableStructs[battler].roostActive)
|
||||
gDisableStructs[battler].roostActive = FALSE;
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_ELECTRIFY:
|
||||
@ -5590,14 +5590,14 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
break;
|
||||
case MOVE_ABSORBED_BY_BOOST_FLASH_FIRE:
|
||||
gBattleStruct->pledgeMove = FALSE;
|
||||
if (!(gBattleResources->flags->flags[battler] & RESOURCE_FLAG_FLASH_FIRE))
|
||||
if (!gDisableStructs[battler].flashFireBoosted)
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FLASH_FIRE_BOOST;
|
||||
if (gProtectStructs[gBattlerAttacker].notFirstStrike)
|
||||
gBattlescriptCurrInstr = BattleScript_FlashFireBoost;
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss;
|
||||
gBattleResources->flags->flags[battler] |= RESOURCE_FLAG_FLASH_FIRE;
|
||||
gDisableStructs[battler].flashFireBoosted = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5704,7 +5704,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
// Not currently held by Sky Drop
|
||||
&& !(gStatuses3[battler] & STATUS3_SKY_DROPPED))
|
||||
{
|
||||
gBattleResources->flags->flags[battler] |= RESOURCE_FLAG_EMERGENCY_EXIT;
|
||||
gDisableStructs[battler].startEmergencyExit = TRUE;
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
@ -6489,9 +6489,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
// Prints message only. separate from ABILITYEFFECT_ON_SWITCHIN bc activates before entry hazards
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gBattleResources->flags->flags[i] & RESOURCE_FLAG_NEUTRALIZING_GAS))
|
||||
if (gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !gDisableStructs[i].neutralizingGas)
|
||||
{
|
||||
gBattleResources->flags->flags[i] |= RESOURCE_FLAG_NEUTRALIZING_GAS;
|
||||
gDisableStructs[i].neutralizingGas = TRUE;
|
||||
gBattlerAbility = i;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg);
|
||||
@ -7223,9 +7223,8 @@ static u32 ItemHealHp(u32 battler, u32 itemId, enum ItemEffect caseID, bool32 pe
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_ItemHealHP_RemoveItemRet;
|
||||
}
|
||||
if (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_EMERGENCY_EXIT
|
||||
&& GetNonDynamaxHP(battler) >= GetNonDynamaxMaxHP(battler) / 2)
|
||||
gBattleResources->flags->flags[battler] &= ~RESOURCE_FLAG_EMERGENCY_EXIT;
|
||||
if (gDisableStructs[battler].startEmergencyExit && GetNonDynamaxHP(battler) >= GetNonDynamaxMaxHP(battler) / 2)
|
||||
gDisableStructs[battler].startEmergencyExit = FALSE;
|
||||
|
||||
return ITEM_HP_CHANGE;
|
||||
}
|
||||
@ -9768,7 +9767,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(0.5));
|
||||
break;
|
||||
case ABILITY_FLASH_FIRE:
|
||||
if (moveType == TYPE_FIRE && gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_FLASH_FIRE)
|
||||
if (moveType == TYPE_FIRE && gDisableStructs[battlerAtk].flashFireBoosted)
|
||||
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
|
||||
break;
|
||||
case ABILITY_SWARM:
|
||||
@ -12065,7 +12064,7 @@ void GetBattlerTypes(u32 battler, bool32 ignoreTera, u32 types[static 3])
|
||||
types[2] = gBattleMons[battler].types[2];
|
||||
|
||||
// Roost.
|
||||
if (!isTera && (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST))
|
||||
if (!isTera && gDisableStructs[battler].roostActive)
|
||||
{
|
||||
if (types[0] == TYPE_FLYING && types[1] == TYPE_FLYING)
|
||||
types[0] = types[1] = B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY;
|
||||
|
||||
@ -25,7 +25,6 @@ void AllocateBattleResources(void)
|
||||
|
||||
gBattleResources = AllocZeroed(sizeof(*gBattleResources));
|
||||
gBattleResources->secretBase = AllocZeroed(sizeof(*gBattleResources->secretBase));
|
||||
gBattleResources->flags = AllocZeroed(sizeof(*gBattleResources->flags));
|
||||
gBattleResources->battleScriptsStack = AllocZeroed(sizeof(*gBattleResources->battleScriptsStack));
|
||||
gBattleResources->battleCallbackStack = AllocZeroed(sizeof(*gBattleResources->battleCallbackStack));
|
||||
gBattleResources->beforeLvlUp = AllocZeroed(sizeof(*gBattleResources->beforeLvlUp));
|
||||
@ -58,7 +57,6 @@ void FreeBattleResources(void)
|
||||
FREE_AND_SET_NULL(gBattleStruct);
|
||||
|
||||
FREE_AND_SET_NULL(gBattleResources->secretBase);
|
||||
FREE_AND_SET_NULL(gBattleResources->flags);
|
||||
FREE_AND_SET_NULL(gBattleResources->battleScriptsStack);
|
||||
FREE_AND_SET_NULL(gBattleResources->battleCallbackStack);
|
||||
FREE_AND_SET_NULL(gBattleResources->beforeLvlUp);
|
||||
|
||||
28
test/battle/ability/flash_fire.c
Normal file
28
test/battle/ability/flash_fire.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Flash Fire boosts fire type moves by 50% but no subsequent increase is applied")
|
||||
{
|
||||
s16 damage[3];
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_HEATRAN) { Ability(ABILITY_FLASH_FIRE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_EMBER); MOVE(opponent, MOVE_EMBER); }
|
||||
TURN { MOVE(player, MOVE_EMBER); MOVE(opponent, MOVE_EMBER); }
|
||||
TURN { MOVE(player, MOVE_EMBER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
ABILITY_POPUP(player, ABILITY_FLASH_FIRE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
ABILITY_POPUP(player, ABILITY_FLASH_FIRE);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[2]);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(damage[0], UQ_4_12(1.5), damage[1]);
|
||||
EXPECT_EQ(damage[1], damage[2]);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user