Skip to content

Commit

Permalink
Fixes cantBeSurpressed ability check for breakable abilities (#5043)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pawkkie authored Jul 26, 2024
2 parents b0b63f6 + 5dd10a4 commit 3c1fbbb
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 15 deletions.
2 changes: 1 addition & 1 deletion include/battle_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility)
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg);
bool32 TryPrimalReversion(u32 battler);
bool32 IsNeutralizingGasOnField(void);
bool32 IsMoldBreakerTypeAbility(u32 ability);
bool32 IsMoldBreakerTypeAbility(u32 battler, u32 ability);
u32 GetBattlerAbility(u32 battler);
u32 IsAbilityOnSide(u32 battler, u32 ability);
u32 IsAbilityOnOpposingSide(u32 battler, u32 ability);
Expand Down
6 changes: 3 additions & 3 deletions src/battle_ai_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,7 @@ bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move)
if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE)
return FALSE; // AI handicap flag: doesn't understand ability suppression concept

if (IsMoldBreakerTypeAbility(atkAbility) || gMovesInfo[move].ignoresTargetAbility)
if (IsMoldBreakerTypeAbility(sBattler_AI, atkAbility) || gMovesInfo[move].ignoresTargetAbility)
return TRUE;

return FALSE;
Expand Down Expand Up @@ -2766,7 +2766,7 @@ bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u32 defAbility)

u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move)
{
if (((!IsMoldBreakerTypeAbility(AI_DATA->abilities[battlerAtk]) && (defAbility == ABILITY_SHIELD_DUST || defAbility == ABILITY_INNER_FOCUS))
if (((!IsMoldBreakerTypeAbility(battlerAtk, AI_DATA->abilities[battlerAtk]) && (defAbility == ABILITY_SHIELD_DUST || defAbility == ABILITY_INNER_FOCUS))
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_COVERT_CLOAK
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER)) // Opponent goes first
Expand Down Expand Up @@ -2809,7 +2809,7 @@ bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u32 move)
|| AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_CHOICE_BAND
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_COVERT_CLOAK
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| (!IsMoldBreakerTypeAbility(AI_DATA->abilities[battlerAtk])
|| (!IsMoldBreakerTypeAbility(battlerAtk, AI_DATA->abilities[battlerAtk])
&& (AI_DATA->abilities[battlerDef] == ABILITY_SHIELD_DUST || AI_DATA->abilities[battlerDef] == ABILITY_INNER_FOCUS)))
return FALSE;

Expand Down
32 changes: 21 additions & 11 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -6207,23 +6207,41 @@ bool32 IsNeutralizingGasOnField(void)
return FALSE;
}

bool32 IsMoldBreakerTypeAbility(u32 ability)
bool32 IsMoldBreakerTypeAbility(u32 battler, u32 ability)
{
if (gStatuses3[battler] & STATUS3_GASTRO_ACID)
return FALSE;

return (ability == ABILITY_MOLD_BREAKER || ability == ABILITY_TERAVOLT || ability == ABILITY_TURBOBLAZE
|| (ability == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gCurrentMove)));
}

static inline bool32 CanBreakThroughAbility(u32 battlerAtk, u32 battlerDef, u32 ability)
{
return ((IsMoldBreakerTypeAbility(battlerAtk, ability) || gMovesInfo[gCurrentMove].ignoresTargetAbility)
&& battlerDef != battlerAtk
&& gAbilitiesInfo[gBattleMons[battlerDef].ability].breakable
&& gBattlerByTurnOrder[gCurrentTurnActionNumber] == battlerAtk
&& gActionsByTurnOrder[gCurrentTurnActionNumber] == B_ACTION_USE_MOVE
&& gCurrentTurnActionNumber < gBattlersCount);
}

u32 GetBattlerAbility(u32 battler)
{
bool32 noAbilityShield = GetBattlerHoldEffectIgnoreAbility(battler, TRUE) != HOLD_EFFECT_ABILITY_SHIELD;
bool32 abilityCantBeSuppressed = gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed;

if (gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed)
if (abilityCantBeSuppressed)
{
// Edge case: pokemon under the effect of gastro acid transforms into a pokemon with Comatose (Todo: verify how other unsuppressable abilities behave)
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED
&& gStatuses3[battler] & STATUS3_GASTRO_ACID
&& gBattleMons[battler].ability == ABILITY_COMATOSE)
return ABILITY_NONE;

if (noAbilityShield && CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability))
return ABILITY_NONE;

return gBattleMons[battler].ability;
}

Expand All @@ -6235,15 +6253,7 @@ u32 GetBattlerAbility(u32 battler)
&& noAbilityShield)
return ABILITY_NONE;

if (((IsMoldBreakerTypeAbility(gBattleMons[gBattlerAttacker].ability)
&& !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID))
|| gMovesInfo[gCurrentMove].ignoresTargetAbility)
&& battler != gBattlerAttacker
&& gAbilitiesInfo[gBattleMons[battler].ability].breakable
&& noAbilityShield
&& gBattlerByTurnOrder[gCurrentTurnActionNumber] == gBattlerAttacker
&& gActionsByTurnOrder[gCurrentTurnActionNumber] == B_ACTION_USE_MOVE
&& gCurrentTurnActionNumber < gBattlersCount)
if (noAbilityShield && CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability))
return ABILITY_NONE;

return gBattleMons[battler].ability;
Expand Down
13 changes: 13 additions & 0 deletions test/battle/ability/disguise.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,16 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu takes damage from Rough Skin without break
EXPECT_EQ(player->species, SPECIES_MIMIKYU_DISGUISED);
}
}

SINGLE_BATTLE_TEST("Disguised Mimikyu is ignored by Mold Breaker")
{
GIVEN {
PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); }
OPPONENT(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
} WHEN {
TURN { MOVE(opponent, MOVE_AERIAL_ACE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, opponent);
NOT ABILITY_POPUP(player, ABILITY_DISGUISE);
}
}

0 comments on commit 3c1fbbb

Please sign in to comment.