Fix Throat Spray activating multiply times (#7818)

This commit is contained in:
Alex 2025-09-29 19:32:11 +02:00 committed by GitHub
parent 210aeb1d11
commit 09aa452659
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 23 additions and 17 deletions

View File

@ -388,6 +388,7 @@ bool32 IsPursuitTargetSet(void);
void ClearPursuitValuesIfSet(u32 battler);
void ClearPursuitValues(void);
bool32 HasWeatherEffect(void);
bool32 IsAnyTargetAffected(u32 battlerAtk);
u32 RestoreWhiteHerbStats(u32 battler);
bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 HadMoreThanHalfHpNowDoesnt(u32 battler);

View File

@ -153,6 +153,7 @@ enum MoveEndEffects
MOVEEND_MULTIHIT_MOVE,
MOVEEND_MOVE_BLOCK,
MOVEEND_ITEM_EFFECTS_ATTACKER,
MOVEEND_ITEM_THROAT_SPRAY,
MOVEEND_ABILITY_BLOCK,
MOVEEND_SHEER_FORCE, // If move is Sheer Force affected, skip until Opportunist
MOVEEND_RED_CARD,

View File

@ -6494,10 +6494,30 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_ITEM_EFFECTS_ATTACKER:
// ITEMEFFECT_MOVE_END loops over all battlers, not just attacker.
// It will executre only the first mon with an applicable item.
// So presumably it is a bug
if (ItemBattleEffects(ITEMEFFECT_MOVE_END, gBattlerAttacker))
effect = TRUE;
gBattleScripting.moveendState++;
break;
case MOVEEND_ITEM_THROAT_SPRAY:
if (IsSoundMove(gCurrentMove)
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_THROAT_SPRAY
&& IsBattlerAlive(gBattlerAttacker)
&& IsAnyTargetAffected(gBattlerAttacker)
&& CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)
&& !NoAliveMonsForEitherParty()) // Don't activate if battle will end
{
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
gBattleScripting.battler = gBattlerAttacker;
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
effect = TRUE;
BattleScriptCall(BattleScript_AttackerItemStatRaise);
}
gBattleScripting.moveendState++;
break;
case MOVEEND_ABILITY_BLOCK:
effect = HandleMoveEndAbilityBlock(gBattlerAttacker, gBattlerTarget, gCurrentMove);
gBattleScripting.moveendState++;

View File

@ -65,7 +65,6 @@ static u32 GetFlingPowerFromItemId(u32 itemId);
static void SetRandomMultiHitCounter();
static u32 GetBattlerItemHoldEffectParam(u32 battler, u32 item);
static bool32 CanBeInfinitelyConfused(u32 battler);
static bool32 IsAnyTargetAffected(u32 battlerAtk);
static bool32 IsNonVolatileStatusBlocked(u32 battlerDef, u32 abilityDef, u32 abilityAffected, const u8 *battleScript, enum FunctionCallOption option);
static bool32 CanSleepDueToSleepClause(u32 battlerAtk, u32 battlerDef, enum FunctionCallOption option);
@ -6501,21 +6500,6 @@ static u8 ItemEffectMoveEnd(u32 battler, enum ItemHoldEffect holdEffect)
case HOLD_EFFECT_MIRROR_HERB:
effect = TryConsumeMirrorHerb(battler, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_THROAT_SPRAY:
if (IsSoundMove(gCurrentMove)
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& IsBattlerAlive(gBattlerAttacker)
&& IsAnyTargetAffected(gBattlerAttacker)
&& CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)
&& !NoAliveMonsForEitherParty()) // Don't activate if battle will end
{
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
gBattleScripting.battler = gBattlerAttacker;
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
effect = ITEM_STATS_CHANGE;
BattleScriptCall(BattleScript_AttackerItemStatRaise);
}
break;
default:
break;
}
@ -11412,7 +11396,7 @@ bool32 HasWeatherEffect(void)
return TRUE;
}
static bool32 IsAnyTargetAffected(u32 battlerAtk)
bool32 IsAnyTargetAffected(u32 battlerAtk)
{
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{