Fix Iron Ball type effectiveness check (#6794)

This commit is contained in:
spindrift64 2025-05-09 22:23:44 +02:00 committed by GitHub
parent 5e190d0782
commit 3b91a964c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 52 additions and 6 deletions

View File

@ -186,6 +186,7 @@
#define B_SAFARI_BALL_MODIFIER GEN_LATEST // In Gen8+, Safari Ball's catch multiplier was reduced from x1.5 to x1.
#define B_FRIEND_BALL_MODIFIER GEN_LATEST // In Gen8+, Friend Ball's friendship boost was reduced from 200 to 150.
#define B_SERENE_GRACE_BOOST GEN_LATEST // In Gen5+, Serene Grace boosts the added flinch chance of King's Rock and Razor Fang.
#define B_IRON_BALL GEN_LATEST // In Gen5+, Flying-type Pokemon holding Iron Ball take x1 damage from Ground-type moves regardless of their other types, except during Inverse Battles or if the Pokemon is grounded by any other effect.
// Flag settings
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.

View File

@ -8816,12 +8816,24 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move)
return isProtected;
}
// Only called directly when calculating damage type effectiveness
static bool32 IsBattlerGroundedInverseCheck(u32 battler, bool32 considerInverse)
enum InverseBattleCheck
{
INVERSE_BATTLE,
NOT_INVERSE_BATTLE
};
enum IronBallCheck
{
CHECK_IRON_BALL,
IGNORE_IRON_BALL
};
// Only called directly when calculating damage type effectiveness, and Iron Ball's type effectiveness mechanics
static bool32 IsBattlerGroundedInverseCheck(u32 battler, enum InverseBattleCheck checkInverse, enum IronBallCheck checkIronBall)
{
u32 holdEffect = GetBattlerHoldEffect(battler, TRUE);
if (holdEffect == HOLD_EFFECT_IRON_BALL)
if (!(checkIronBall == IGNORE_IRON_BALL) && holdEffect == HOLD_EFFECT_IRON_BALL)
return TRUE;
if (gFieldStatuses & STATUS_FIELD_GRAVITY)
return TRUE;
@ -8837,14 +8849,14 @@ static bool32 IsBattlerGroundedInverseCheck(u32 battler, bool32 considerInverse)
return FALSE;
if ((AI_DATA->aiCalcInProgress ? AI_DATA->abilities[battler] : GetBattlerAbility(battler)) == ABILITY_LEVITATE)
return FALSE;
if (IS_BATTLER_OF_TYPE(battler, TYPE_FLYING) && (!considerInverse || !FlagGet(B_FLAG_INVERSE_BATTLE)))
if (IS_BATTLER_OF_TYPE(battler, TYPE_FLYING) && (!(checkInverse == INVERSE_BATTLE) || !FlagGet(B_FLAG_INVERSE_BATTLE)))
return FALSE;
return TRUE;
}
bool32 IsBattlerGrounded(u32 battler)
{
return IsBattlerGroundedInverseCheck(battler, FALSE);
return IsBattlerGroundedInverseCheck(battler, NOT_INVERSE_BATTLE, CHECK_IRON_BALL);
}
u32 GetMoveSlot(u16 *moves, u32 move)
@ -10685,7 +10697,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 mov
if (B_GLARE_GHOST < GEN_4 && move == MOVE_GLARE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST))
modifier = UQ_4_12(0.0);
}
else if (moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(battlerDef, TRUE) && !(MoveIgnoresTypeIfFlyingAndUngrounded(move)))
else if (moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(battlerDef, INVERSE_BATTLE, CHECK_IRON_BALL) && !(MoveIgnoresTypeIfFlyingAndUngrounded(move)))
{
modifier = UQ_4_12(0.0);
if (recordAbilities && defAbility == ABILITY_LEVITATE)
@ -10710,6 +10722,17 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 mov
modifier = UQ_4_12(1.0);
}
// Iron Ball ignores type modifiers for flying-type mons if it is the only source of grounding
if (B_IRON_BALL >= GEN_5
&& moveType == TYPE_GROUND
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING)
&& GetBattlerHoldEffect(battlerDef, TRUE) == HOLD_EFFECT_IRON_BALL
&& !IsBattlerGroundedInverseCheck(battlerDef, NOT_INVERSE_BATTLE, IGNORE_IRON_BALL)
&& !FlagGet(B_FLAG_INVERSE_BATTLE))
{
modifier = UQ_4_12(1.0);
}
if (((defAbility == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0))
|| (defAbility == ABILITY_TELEPATHY && battlerDef == BATTLE_PARTNER(battlerAtk)))
&& GetMovePower(move) != 0)

View File

@ -0,0 +1,22 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS{
ASSUME(gItemsInfo[ITEM_IRON_BALL].holdEffect == HOLD_EFFECT_IRON_BALL);
}
SINGLE_BATTLE_TEST("Ground-type moves do neutral damage to non-grounded Flying types holding Iron Ball regardless of other typings") //gen5+ only
{
ASSUME(B_IRON_BALL >= GEN_5);
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_SKARMORY) { Item(ITEM_IRON_BALL); };
} WHEN {
TURN { MOVE(player, MOVE_EARTHQUAKE); };
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, player);
NONE_OF {
MESSAGE("It's super effective!");
}
}
}