Clean up for item hold effect refactor (#8014)

This commit is contained in:
Alex 2025-10-30 21:07:37 +01:00 committed by GitHub
parent fd84adc421
commit ff557e3d0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 80 deletions

View File

@ -384,7 +384,7 @@ BattleScript_SaltCureExtraDamage::
printstring STRINGID_TARGETISHURTBYSALTCURE
waitmessage B_WAIT_TIME_LONG
tryfaintmon BS_ATTACKER
tryactivateitem BS_ATTACKER, ON_ITEM_HP_THRESHOLD
tryactivateitem BS_ATTACKER, ACTIVATION_ON_HP_THRESHOLD
end2
BattleScript_EffectCorrosiveGas::
@ -1407,7 +1407,7 @@ BattleScript_EffectBestow::
waitanimation
printstring STRINGID_BESTOWITEMGIVING
waitmessage B_WAIT_TIME_LONG
tryactivateitem BS_TARGET, ON_ITEM_USABLE_AGAIN
tryactivateitem BS_TARGET, ACTIVATION_ON_USABLE_AGAIN
trysymbiosis BS_ATTACKER
goto BattleScript_MoveEnd
@ -4896,7 +4896,7 @@ BattleScript_MagicRoomEnds::
setbyte gBattlerTarget, 0
BattleScript_MagicRoomHealingItemsLoop:
copyarraywithindex gBattlerAttacker, gBattlerByTurnOrder, gBattlerTarget, 1
tryactivateitem BS_ATTACKER, ON_ITEM_USABLE_AGAIN
tryactivateitem BS_ATTACKER, ACTIVATION_ON_USABLE_AGAIN
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_MagicRoomHealingItemsLoop
end2
@ -6068,7 +6068,7 @@ BattleScript_DoTurnDmg:
datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE
tryfaintmon BS_ATTACKER
checkteamslost BattleScript_DoTurnDmgEnd
tryactivateitem BS_ATTACKER, ON_ITEM_HP_THRESHOLD
tryactivateitem BS_ATTACKER, ACTIVATION_ON_HP_THRESHOLD
BattleScript_DoTurnDmgEnd:
end2
@ -6308,7 +6308,7 @@ BattleScript_YawnEnd:
BattleScript_EmbargoEndTurn::
printstring STRINGID_EMBARGOENDS
waitmessage B_WAIT_TIME_LONG
tryactivateitem BS_ATTACKER, ON_ITEM_USABLE_AGAIN
tryactivateitem BS_ATTACKER, ACTIVATION_ON_USABLE_AGAIN
end2
BattleScript_TelekinesisEndTurn::
@ -6596,7 +6596,7 @@ BattleScript_PickupActivates::
call BattleScript_AbilityPopUp
printstring STRINGID_XFOUNDONEY
waitmessage B_WAIT_TIME_LONG
tryactivateitem BS_ATTACKER, ON_ITEM_PICK_UP
tryactivateitem BS_ATTACKER, ACTIVATION_ON_PICK_UP
BattleScript_PickupActivatesEnd:
end2
@ -6606,7 +6606,7 @@ BattleScript_HarvestActivates::
call BattleScript_AbilityPopUp
printstring STRINGID_HARVESTBERRY
waitmessage B_WAIT_TIME_LONG
tryactivateitem BS_ATTACKER, ON_BERRY_HARVEST
tryactivateitem BS_ATTACKER, ACTIVATION_ON_HARVEST
BattleScript_HarvestActivatesEnd:
end2

View File

@ -28,8 +28,6 @@ extern const struct HoldEffectInfo gHoldEffectsInfo[];
typedef bool32 (*ActivationTiming)(enum HoldEffect holdEffect);
enum ItemEffect ItemBattleEffects(u32 primaryBattler, u32 secondaryBattler, enum HoldEffect holdEffect, ActivationTiming timing);
enum ItemEffect TryBoosterEnergy(u32 battler, enum Ability ability, ActivationTiming timing);
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, enum Stat statId, u32 itemId, ActivationTiming timing);
bool32 IsOnSwitchInActivation(enum HoldEffect holdEffect);
bool32 IsOnSwitchInFirstTurnActivation(enum HoldEffect holdEffect);
@ -47,8 +45,8 @@ bool32 IsLifeOrbShellBellActivation(enum HoldEffect holdEffect);
bool32 IsLeftoversActivation(enum HoldEffect holdEffect);
bool32 IsOrbsActivation(enum HoldEffect holdEffect);
bool32 IsOnEffectActivation(enum HoldEffect holdEffect);
bool32 IsActivationForceTriggerItem(enum HoldEffect holdEffect);
bool32 IsActivationOnBerry(enum HoldEffect holdEffect);
bool32 IsForceTriggerItemActivation(enum HoldEffect holdEffect);
bool32 IsOnBerryActivation(enum HoldEffect holdEffect);
bool32 IsOnFlingActivation(enum HoldEffect holdEffect);
#endif // GUARD_BATTLE_HOLD_EFFECTS

View File

@ -151,12 +151,12 @@ enum __attribute__((packed)) HoldEffect
#define HOLD_EFFECT_PARAM_MISTY_TERRAIN 2
#define HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN 3
enum ActivationState
enum ItemActivationState
{
ON_ITEM_USABLE_AGAIN,
ON_ITEM_PICK_UP,
ON_BERRY_HARVEST,
ON_ITEM_HP_THRESHOLD,
ACTIVATION_ON_USABLE_AGAIN,
ACTIVATION_ON_PICK_UP,
ACTIVATION_ON_HARVEST,
ACTIVATION_ON_HP_THRESHOLD,
};
#endif // GUARD_HOLD_EFFECTS_H

View File

@ -27,10 +27,10 @@ bool32 IsLifeOrbShellBellActivation(enum HoldEffect holdEffect) { return gHol
bool32 IsLeftoversActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].leftovers; }
bool32 IsOrbsActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].orbs; }
bool32 IsOnEffectActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].onEffect; }
bool32 IsActivationOnBerry(enum HoldEffect holdEffect) { return GetItemPocket(gLastUsedItem) == POCKET_BERRIES; }
bool32 IsOnBerryActivation(enum HoldEffect holdEffect) { return GetItemPocket(gLastUsedItem) == POCKET_BERRIES; }
bool32 IsOnFlingActivation(enum HoldEffect holdEffect) { return gHoldEffectsInfo[holdEffect].onFling; }
bool32 IsActivationForceTriggerItem(enum HoldEffect holdEffect)
bool32 IsForceTriggerItemActivation(enum HoldEffect holdEffect)
{
return gHoldEffectsInfo[holdEffect].onSwitchIn
|| gHoldEffectsInfo[holdEffect].whiteHerb
@ -64,7 +64,6 @@ enum ItemEffect TryBoosterEnergy(u32 battler, enum Ability ability, ActivationTi
PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler));
gBattlerAbility = gBattleScripting.battler = battler;
gDisableStructs[battler].boosterEnergyActivated = TRUE;
gLastUsedItem = ITEM_BOOSTER_ENERGY;
RecordAbilityBattle(battler, ability);
if (timing == IsOnSwitchInFirstTurnActivation)
BattleScriptExecute(BattleScript_BoosterEnergyEnd2);
@ -84,7 +83,6 @@ static enum ItemEffect TryRoomService(u32 battler, ActivationTiming timing)
SET_STATCHANGER(STAT_SPEED, 1, TRUE);
gBattleScripting.animArg1 = STAT_ANIM_PLUS1 + STAT_SPEED;
gBattleScripting.animArg2 = 0;
gLastUsedItem = gBattleMons[battler].item;
if (timing == IsOnSwitchInFirstTurnActivation)
BattleScriptExecute(BattleScript_ConsumableStatRaiseEnd2);
@ -97,11 +95,10 @@ static enum ItemEffect TryRoomService(u32 battler, ActivationTiming timing)
return ITEM_NO_EFFECT;
}
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, enum Stat statId, u32 itemId, ActivationTiming timing)
enum ItemEffect TryHandleSeed(u32 battler, u32 terrainFlag, enum Stat statId, ActivationTiming timing)
{
if (gFieldStatuses & terrainFlag && CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
{
gLastUsedItem = itemId; // For surge abilities
gEffectBattler = gBattleScripting.battler = battler;
SET_STATCHANGER(statId, 1, FALSE);
gBattleScripting.animArg1 = STAT_ANIM_PLUS1 + statId;
@ -122,16 +119,16 @@ static enum ItemEffect TryTerrainSeeds(u32 battler, u32 item, ActivationTiming t
switch (GetItemHoldEffectParam(item))
{
case HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN:
effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, item, timing);
effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, timing);
break;
case HOLD_EFFECT_PARAM_GRASSY_TERRAIN:
effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, item, timing);
effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, timing);
break;
case HOLD_EFFECT_PARAM_MISTY_TERRAIN:
effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, item, timing);
effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, timing);
break;
case HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN:
effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, item, timing);
effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, timing);
break;
}
@ -257,7 +254,7 @@ static enum ItemEffect TryAirBalloon(u32 battler, ActivationTiming timing)
return effect;
}
static enum ItemEffect TryRockyHelmet(u32 battlerDef, u32 battlerAtk)
static enum ItemEffect TryRockyHelmet(u32 battlerDef, u32 battlerAtk, u32 item)
{
enum ItemEffect effect = ITEM_NO_EFFECT;
enum Ability ability = GetBattlerAbility(battlerAtk);
@ -268,7 +265,7 @@ static enum ItemEffect TryRockyHelmet(u32 battlerDef, u32 battlerAtk)
&& !IsAbilityAndRecord(battlerAtk, ability, ABILITY_MAGIC_GUARD))
{
SetPassiveDamageAmount(battlerAtk, GetNonDynamaxMaxHP(battlerAtk) / 6);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battlerDef].item);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, item);
BattleScriptCall(BattleScript_RockyHelmetActivates);
effect = ITEM_HP_CHANGE;
}
@ -355,7 +352,7 @@ static enum ItemEffect TryAbsorbBulb(u32 battlerDef)
return effect;
}
static enum ItemEffect TryJabocaBerry(u32 battlerDef, u32 battlerAtk)
static enum ItemEffect TryJabocaBerry(u32 battlerDef, u32 battlerAtk, u32 item)
{
enum ItemEffect effect = ITEM_NO_EFFECT;
@ -370,14 +367,14 @@ static enum ItemEffect TryJabocaBerry(u32 battlerDef, u32 battlerAtk)
jabocaDamage *= 2;
SetPassiveDamageAmount(battlerAtk, jabocaDamage);
BattleScriptCall(BattleScript_JabocaRowapBerryActivates);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battlerDef].item);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, item);
effect = ITEM_HP_CHANGE;
}
return effect;
}
static enum ItemEffect TryRowapBerry(u32 battlerDef, u32 battlerAtk)
static enum ItemEffect TryRowapBerry(u32 battlerDef, u32 battlerAtk, u32 item)
{
enum ItemEffect effect = ITEM_NO_EFFECT;
@ -392,7 +389,7 @@ static enum ItemEffect TryRowapBerry(u32 battlerDef, u32 battlerAtk)
rowapDamage *= 2;
SetPassiveDamageAmount(battlerAtk, rowapDamage);
BattleScriptCall(BattleScript_JabocaRowapBerryActivates);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battlerDef].item);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, item);
effect = ITEM_HP_CHANGE;
}
@ -582,7 +579,7 @@ static enum ItemEffect TryLifeOrb(u32 battlerAtk)
return effect;
}
static enum ItemEffect TryStickyBarbOnTargetHit(u32 battlerDef, u32 battlerAtk)
static enum ItemEffect TryStickyBarbOnTargetHit(u32 battlerDef, u32 battlerAtk, u32 item)
{
enum ItemEffect effect = ITEM_NO_EFFECT;
@ -590,8 +587,8 @@ static enum ItemEffect TryStickyBarbOnTargetHit(u32 battlerDef, u32 battlerAtk)
&& !CanBattlerAvoidContactEffects(battlerAtk, battlerDef, GetBattlerAbility(battlerAtk), GetBattlerHoldEffect(battlerAtk), gCurrentMove)
&& !DoesSubstituteBlockMove(battlerAtk, battlerDef, gCurrentMove)
&& IsBattlerAlive(battlerAtk)
&& CanStealItem(battlerAtk, battlerDef, gBattleMons[battlerDef].item)
&& gBattleMons[battlerAtk].item == ITEM_NONE)
&& CanStealItem(battlerAtk, battlerDef, item)
&& item == ITEM_NONE)
{
// No sticky hold checks.
gEffectBattler = battlerDef;
@ -603,14 +600,14 @@ static enum ItemEffect TryStickyBarbOnTargetHit(u32 battlerDef, u32 battlerAtk)
return effect;
}
static enum ItemEffect TryStickyBarbOnEndTurn(u32 battler)
static enum ItemEffect TryStickyBarbOnEndTurn(u32 battler, u32 item)
{
enum ItemEffect effect = ITEM_NO_EFFECT;
if (!IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD))
{
SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / 8);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[battler].item);
PREPARE_ITEM_BUFFER(gBattleTextBuff1, item);
BattleScriptExecute(BattleScript_ItemHurtEnd2);
effect = ITEM_HP_CHANGE;
}
@ -1070,7 +1067,7 @@ static enum ItemEffect TrySetMicleBerry(u32 battler, u32 itemId, ActivationTimin
enum ItemEffect ItemBattleEffects(u32 itemBattler, u32 battler, enum HoldEffect holdEffect, ActivationTiming timing)
{
enum ItemEffect effect = ITEM_NO_EFFECT;
u32 item = (timing == IsActivationOnBerry) ? gLastUsedItem : gBattleMons[itemBattler].item;
u32 item = (timing == IsOnBerryActivation) ? gLastUsedItem : gBattleMons[itemBattler].item;
if (holdEffect == HOLD_EFFECT_NONE
|| !timing(holdEffect)
@ -1113,7 +1110,7 @@ enum ItemEffect ItemBattleEffects(u32 itemBattler, u32 battler, enum HoldEffect
effect = TryAirBalloon(itemBattler, timing);
break;
case HOLD_EFFECT_ROCKY_HELMET:
effect = TryRockyHelmet(itemBattler, battler);
effect = TryRockyHelmet(itemBattler, battler, item);
break;
case HOLD_EFFECT_WEAKNESS_POLICY:
effect = TryWeaknessPolicy(itemBattler);
@ -1131,10 +1128,10 @@ enum ItemEffect ItemBattleEffects(u32 itemBattler, u32 battler, enum HoldEffect
effect = TryAbsorbBulb(itemBattler);
break;
case HOLD_EFFECT_JABOCA_BERRY:
effect = TryJabocaBerry(itemBattler, battler);
effect = TryJabocaBerry(itemBattler, battler, item);
break;
case HOLD_EFFECT_ROWAP_BERRY:
effect = TryRowapBerry(itemBattler, battler);
effect = TryRowapBerry(itemBattler, battler, item);
break;
case HOLD_EFFECT_ENIGMA_BERRY: // consume and heal if hit by super effective move
effect = TrySetEnigmaBerry(itemBattler, battler);
@ -1162,9 +1159,9 @@ enum ItemEffect ItemBattleEffects(u32 itemBattler, u32 battler, enum HoldEffect
break;
case HOLD_EFFECT_STICKY_BARB:
if (timing == IsOnTargetHitActivation)
effect = TryStickyBarbOnTargetHit(itemBattler, battler);
effect = TryStickyBarbOnTargetHit(itemBattler, battler, item);
else
effect = TryStickyBarbOnEndTurn(itemBattler);
effect = TryStickyBarbOnEndTurn(itemBattler, item);
break;
case HOLD_EFFECT_TOXIC_ORB:
effect = TryToxicOrb(itemBattler);
@ -1202,7 +1199,7 @@ enum ItemEffect ItemBattleEffects(u32 itemBattler, u32 battler, enum HoldEffect
case HOLD_EFFECT_CURE_STATUS: // Lum Berry
effect = TryCureAnyStatus(itemBattler, timing);
break;
case HOLD_EFFECT_RESTORE_HP: // Oran Berry / Berry Juice
case HOLD_EFFECT_RESTORE_HP: // Oran / Sitrus Berry / Berry Juice
effect = ItemHealHp(itemBattler, item, FIXED_HEAL_AMOUNT, timing);
break;
case HOLD_EFFECT_RESTORE_PCT_HP: // Sitrus Berry

View File

@ -12124,18 +12124,19 @@ static void Cmd_tryactivateitem(void)
CMD_ARGS(u8 battler, u8 flag);
u32 battler = GetBattlerForBattleScript(cmd->battler);
switch (cmd->flag)
switch ((enum ItemActivationState)cmd->flag)
{
case ON_ITEM_USABLE_AGAIN:
case ON_ITEM_PICK_UP:
if (ItemBattleEffects(battler, 0, GetBattlerHoldEffect(battler), IsActivationForceTriggerItem))
case ACTIVATION_ON_USABLE_AGAIN:
case ACTIVATION_ON_PICK_UP:
if (ItemBattleEffects(battler, 0, GetBattlerHoldEffect(battler), IsForceTriggerItemActivation))
return;
break;
case ON_BERRY_HARVEST:
if (ItemBattleEffects(battler, 0, GetBattlerHoldEffect(battler), IsActivationOnBerry))
case ACTIVATION_ON_HARVEST:
gLastUsedItem = gBattleMons[battler].item;
if (ItemBattleEffects(battler, 0, GetBattlerHoldEffect(battler), IsOnBerryActivation))
return;
break;
case ON_ITEM_HP_THRESHOLD:
case ACTIVATION_ON_HP_THRESHOLD:
if (ItemBattleEffects(battler, 0, GetBattlerHoldEffect(battler), IsOnHpThresholdActivation))
return;
break;
@ -16432,16 +16433,17 @@ void BS_TryBoosterEnergy(void)
for (u32 orderNum = 0; orderNum < gBattlersCount; orderNum++)
{
u32 battlerByTurnOrder = gBattlerByTurnOrder[orderNum];
if (GetBattlerHoldEffect(battlerByTurnOrder) != HOLD_EFFECT_BOOSTER_ENERGY)
u32 battler = gBattlerByTurnOrder[orderNum];
enum HoldEffect holdEffect = GetBattlerHoldEffect(battler);
if (holdEffect != HOLD_EFFECT_BOOSTER_ENERGY)
continue;
enum Ability ability = GetBattlerAbility(battlerByTurnOrder);
enum Ability ability = GetBattlerAbility(battler);
if (!(ability == ABILITY_PROTOSYNTHESIS && cmd->onFieldStatus != ON_TERRAIN)
&& !(ability == ABILITY_QUARK_DRIVE && cmd->onFieldStatus != ON_WEATHER))
continue;
if (TryBoosterEnergy(battlerByTurnOrder, ability, IsOnEffectActivation))
if (ItemBattleEffects(battler, 0, holdEffect, IsOnEffectActivation))
return;
}
@ -17600,7 +17602,7 @@ void BS_ActivateItemEffects(void)
if (!IsBattlerAlive(battler))
continue;
if (ItemBattleEffects(battler, 0, GetBattlerHoldEffect(battler), IsActivationForceTriggerItem))
if (ItemBattleEffects(battler, 0, GetBattlerHoldEffect(battler), IsForceTriggerItemActivation))
return;
}
gBattlescriptCurrInstr = cmd->nextInstr;
@ -17620,29 +17622,9 @@ void BS_TryTerrainSeed(void)
{
NATIVE_ARGS(u8 battler, const u8 *failInstr);
u32 battler = GetBattlerForBattleScript(cmd->battler);
if (GetBattlerHoldEffect(battler) == HOLD_EFFECT_TERRAIN_SEED)
{
enum ItemEffect effect = ITEM_NO_EFFECT;
u16 item = gBattleMons[battler].item;
switch (GetBattlerHoldEffectParam(battler))
{
case HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN:
effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, item, IsOnEffectActivation);
break;
case HOLD_EFFECT_PARAM_GRASSY_TERRAIN:
effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, item, IsOnEffectActivation);
break;
case HOLD_EFFECT_PARAM_MISTY_TERRAIN:
effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, item, IsOnEffectActivation);
break;
case HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN:
effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, item, IsOnEffectActivation);
break;
}
if (effect != ITEM_NO_EFFECT)
return;
}
enum HoldEffect holdEffect = GetBattlerHoldEffect(battler);
if (holdEffect == HOLD_EFFECT_TERRAIN_SEED && ItemBattleEffects(battler, 0, holdEffect, IsOnEffectActivation))
return;
gBattlescriptCurrInstr = cmd->failInstr;
}
@ -17890,7 +17872,7 @@ void BS_ConsumeBerry(void)
gBattleScripting.overrideBerryRequirements = 1;
GetBattlerPartyState(battler)->ateBerry = TRUE;
if (ItemBattleEffects(battler, 0, GetItemHoldEffect(gLastUsedItem), IsActivationOnBerry))
if (ItemBattleEffects(battler, 0, GetItemHoldEffect(gLastUsedItem), IsOnBerryActivation))
{
gBattleScripting.overrideBerryRequirements = 2;
return;