Powder Move blocking cleanup (#8194)

This commit is contained in:
PhallenTree 2025-11-10 20:01:35 +00:00 committed by GitHub
parent d31e59d96e
commit 649798449e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 30 additions and 44 deletions

View File

@ -6834,10 +6834,11 @@ BattleScript_PowderMoveNoEffect::
pause B_WAIT_TIME_SHORT
jumpiftype BS_TARGET, TYPE_GRASS, BattleScript_PowderMoveNoEffectPrint
jumpifability BS_TARGET, ABILITY_OVERCOAT, BattleScript_PowderMoveNoEffectOvercoat
setlastuseditem BS_TARGET
printstring STRINGID_SAFETYGOGGLESPROTECTED
goto BattleScript_PowderMoveNoEffectWaitMsg
BattleScript_PowderMoveNoEffectOvercoat:
call BattleScript_AbilityPopUp
call BattleScript_AbilityPopUpTarget
BattleScript_PowderMoveNoEffectPrint:
printstring STRINGID_ITDOESNTAFFECT
BattleScript_PowderMoveNoEffectWaitMsg:

View File

@ -151,7 +151,6 @@ u32 CountPositiveStatStages(u32 battlerId);
u32 CountNegativeStatStages(u32 battlerId);
// move checks
bool32 IsAffectedByPowder(u32 battler, u32 ability, enum ItemHoldEffect holdEffect);
bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, enum DamageCategory category);
enum MoveComparisonResult AI_WhichMoveBetter(u32 move1, u32 move2, u32 battlerAtk, u32 battlerDef, s32 noOfHitsToKo);
struct SimulatedDamage AI_CalcDamageSaveBattlers(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef);

View File

@ -416,5 +416,6 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
bool32 IsSemiInvulnerable(u32 battler, enum SemiInvulnerableExclusion excludeCommander);
bool32 BreaksThroughSemiInvulnerablity(u32 battler, u32 move);
bool32 HasPartnerTrainer(u32 battler);
bool32 IsAffectedByPowderMove(u32 battler, u32 ability, enum ItemHoldEffect holdEffect);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -166,6 +166,7 @@
#define B_BATTLE_BOND GEN_LATEST // In Gen9+, Battle Bond increases Atk, SpAtk and Speed by one stage, once per battle
#define B_ATE_MULTIPLIER GEN_LATEST // In Gen7+, -ate abilities (Aerilate, Galvanize, Normalize, Pixilate, Refrigerate) multiply damage by 1.2. Otherwise, it's 1.3, except Normalize which has no multiplier.
#define B_DEFIANT_STICKY_WEB GEN_LATEST // In Gen9+, Defiant activates on Sticky Web regardless of who set it up. In Gen8, Defiant does not activate on Sticky Web set up by an ally after Court Change swaps its side.
#define B_POWDER_OVERCOAT GEN_LATEST // In Gen6+, Overcoat blocks powder and spore moves from affecting the user.
// Item settings
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore HP activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.

View File

@ -42,6 +42,7 @@ enum GenConfigTag
GEN_CONFIG_DESTINY_BOND_FAIL,
GEN_CONFIG_POWDER_RAIN,
GEN_CONFIG_POWDER_GRASS,
GEN_CONFIG_POWDER_OVERCOAT,
GEN_CONFIG_OBLIVIOUS_TAUNT,
GEN_CONFIG_TOXIC_NEVER_MISS,
GEN_CONFIG_PARALYZE_ELECTRIC,

View File

@ -45,6 +45,7 @@ static const u8 sGenerationalChanges[GEN_CONFIG_COUNT] =
[GEN_CONFIG_DESTINY_BOND_FAIL] = B_DESTINY_BOND_FAIL,
[GEN_CONFIG_POWDER_RAIN] = B_POWDER_RAIN,
[GEN_CONFIG_POWDER_GRASS] = B_POWDER_GRASS,
[GEN_CONFIG_POWDER_OVERCOAT] = B_POWDER_OVERCOAT,
[GEN_CONFIG_OBLIVIOUS_TAUNT] = B_OBLIVIOUS_TAUNT,
[GEN_CONFIG_TOXIC_NEVER_MISS] = B_TOXIC_NEVER_MISS,
[GEN_CONFIG_PARALYZE_ELECTRIC] = B_PARALYZE_ELECTRIC,

View File

@ -1089,7 +1089,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
SetTypeBeforeUsingMove(move, battlerAtk);
moveType = GetBattleMoveType(move);
if (IsPowderMove(move) && !IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef]))
if (IsPowderMove(move) && !IsAffectedByPowderMove(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef]))
RETURN_SCORE_MINUS(10);
if (!BreaksThroughSemiInvulnerablity(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY))
@ -4768,7 +4768,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
if (hasPartner
&& GetMoveTarget(move) == MOVE_TARGET_USER
&& !IsBattlerIncapacitated(battlerDef, aiData->abilities[battlerDef])
&& (!IsPowderMove(move) || IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef])))
&& (!IsPowderMove(move) || IsAffectedByPowderMove(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef])))
// Rage Powder doesn't affect powder immunities
{
u32 predictedMoveOnPartner = gLastMoves[BATTLE_PARTNER(battlerAtk)];

View File

@ -530,16 +530,6 @@ bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler)
return FALSE;
}
// move checks
bool32 IsAffectedByPowder(u32 battler, u32 ability, enum ItemHoldEffect holdEffect)
{
if (ability == ABILITY_OVERCOAT
|| (GetGenConfig(GEN_CONFIG_POWDER_GRASS) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GRASS))
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES)
return FALSE;
return TRUE;
}
// This function checks if all physical/special moves are either unusable or unreasonable to use.
// Consider a pokemon boosting their attack against a ghost pokemon having only normal-type physical attacks.
bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, enum DamageCategory category)

View File

@ -1040,31 +1040,15 @@ u32 NumFaintedBattlersByAttacker(u32 battlerAtk)
return numMonsFainted;
}
bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move)
bool32 IsPowderMoveBlocked(u32 battlerAtk, u32 battlerDef, u32 move)
{
bool32 effect = FALSE;
if (!IsPowderMove(move)
|| battlerAtk == battlerDef
|| IsAffectedByPowderMove(battlerDef, GetBattlerAbility(battlerDef), GetBattlerHoldEffect(battlerDef, TRUE)))
return FALSE;
if (IsPowderMove(move) && (battlerAtk != battlerDef))
{
if (GetGenConfig(GEN_CONFIG_POWDER_GRASS) >= GEN_6
&& (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) || GetBattlerAbility(battlerDef) == ABILITY_OVERCOAT))
{
gBattlerAbility = battlerDef;
RecordAbilityBattle(gBattlerTarget, ABILITY_OVERCOAT);
effect = TRUE;
}
else if (GetBattlerHoldEffect(battlerDef, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES)
{
RecordItemEffectBattle(battlerDef, HOLD_EFFECT_SAFETY_GOGGLES);
gLastUsedItem = gBattleMons[battlerDef].item;
effect = TRUE;
}
if (effect)
gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect;
}
return effect;
gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect;
return TRUE;
}
bool32 EmergencyExitCanBeTriggered(u32 battler)
@ -1151,7 +1135,7 @@ static void Cmd_attackcanceler(void)
return;
}
if (IsMovePowderBlocked(gBattlerAttacker, gBattlerTarget, gCurrentMove))
if (IsPowderMoveBlocked(gBattlerAttacker, gBattlerTarget, gCurrentMove))
return;
if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE

View File

@ -310,7 +310,7 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
if (effect == EFFECT_PURSUIT && IsPursuitTargetSet())
return FALSE;
if (gSideTimers[defSide].followmePowder && !IsAffectedByPowder(battlerAtk, ability, GetBattlerHoldEffect(battlerAtk, TRUE)))
if (gSideTimers[defSide].followmePowder && !IsAffectedByPowderMove(battlerAtk, ability, GetBattlerHoldEffect(battlerAtk, TRUE)))
return FALSE;
return TRUE;
@ -4689,9 +4689,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_EFFECT_SPORE:
{
u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
if ((GetGenConfig(GEN_CONFIG_POWDER_GRASS) < GEN_6 || !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GRASS))
&& abilityAtk != ABILITY_OVERCOAT
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES)
enum ItemHoldEffect holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
if (IsAffectedByPowderMove(gBattlerAttacker, abilityAtk, holdEffectAtk))
{
u32 poison, paralysis, sleep;
@ -4718,7 +4717,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& IsBattlerTurnDamaged(gBattlerTarget)
&& CanBeSlept(gBattlerTarget, gBattlerAttacker, abilityAtk, NOT_BLOCKED_BY_SLEEP_CLAUSE)
&& !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker, TRUE), move))
&& !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, abilityAtk, holdEffectAtk, move))
{
if (IsSleepClauseEnabled())
gBattleStruct->battlerState[gBattlerAttacker].sleepClauseEffectExempt = TRUE;
@ -11965,3 +11964,12 @@ static bool32 IsOpposingSideEmpty(u32 battler)
return FALSE;
return TRUE;
}
bool32 IsAffectedByPowderMove(u32 battler, u32 ability, enum ItemHoldEffect holdEffect)
{
if ((GetGenConfig(GEN_CONFIG_POWDER_OVERCOAT) >= GEN_6 && ability == ABILITY_OVERCOAT)
|| (GetGenConfig(GEN_CONFIG_POWDER_GRASS) >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GRASS))
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES)
return FALSE;
return TRUE;
}

View File

@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Overcoat blocks powder and spore moves (Gen6+)")
PARAMETRIZE { gen = GEN_5; }
PARAMETRIZE { gen = GEN_6; }
GIVEN {
WITH_CONFIG(GEN_CONFIG_POWDER_GRASS, gen);
WITH_CONFIG(GEN_CONFIG_POWDER_OVERCOAT, gen);
ASSUME(IsPowderMove(MOVE_STUN_SPORE));
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_PINECO) { Ability(ABILITY_OVERCOAT); }