Fix Inner Focus, Scrappy, etc granting immunity to all stat drops if the attacker has Intimidate (#4606)

* Fix Inner Focus, Scrappy, etc granting immunity to all stat drops if the attacker has Intimidate

* Formatting

* Test

* Update own_tempo.c
This commit is contained in:
kittenchilly 2024-05-22 15:20:44 -05:00 committed by GitHub
parent 973146c725
commit edab81b658
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 24 deletions

View file

@ -7726,6 +7726,12 @@ BattleScript_IntimidateLoop:
jumpiftargetally BattleScript_IntimidateLoopIncrement jumpiftargetally BattleScript_IntimidateLoopIncrement
jumpifabsent BS_TARGET, BattleScript_IntimidateLoopIncrement jumpifabsent BS_TARGET, BattleScript_IntimidateLoopIncrement
jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_IntimidateLoopIncrement jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_IntimidateLoopIncrement
.if B_UPDATED_INTIMIDATE >= GEN_8 @These abilties specifically prevent just intimidate, without blocking stat decreases
jumpifability BS_TARGET, ABILITY_INNER_FOCUS, BattleScript_IntimidatePrevented
jumpifability BS_TARGET, ABILITY_SCRAPPY, BattleScript_IntimidatePrevented
jumpifability BS_TARGET, ABILITY_OWN_TEMPO, BattleScript_IntimidatePrevented
jumpifability BS_TARGET, ABILITY_OBLIVIOUS, BattleScript_IntimidatePrevented
.endif
jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_IntimidateInReverse jumpifability BS_TARGET, ABILITY_GUARD_DOG, BattleScript_IntimidateInReverse
BattleScript_IntimidateEffect: BattleScript_IntimidateEffect:
copybyte sBATTLER, gBattlerAttacker copybyte sBATTLER, gBattlerAttacker
@ -7750,6 +7756,12 @@ BattleScript_IntimidateEnd:
pause B_WAIT_TIME_MED pause B_WAIT_TIME_MED
end3 end3
BattleScript_IntimidatePrevented:
copybyte sBATTLER, gBattlerTarget
call BattleScript_AbilityPopUp
printstring STRINGID_PKMNPREVENTSSTATLOSSWITH
goto BattleScript_IntimidateEffect_WaitString
BattleScript_IntimidateWontDecrease: BattleScript_IntimidateWontDecrease:
printstring STRINGID_STATSWONTDECREASE printstring STRINGID_STATSWONTDECREASE
goto BattleScript_IntimidateEffect_WaitString goto BattleScript_IntimidateEffect_WaitString

View file

@ -362,7 +362,7 @@ static void TryUpdateRoundTurnOrder(void);
static bool32 ChangeOrderTargetAfterAttacker(void); static bool32 ChangeOrderTargetAfterAttacker(void);
void ApplyExperienceMultipliers(s32 *expAmount, u8 expGetterMonId, u8 faintedBattler); void ApplyExperienceMultipliers(s32 *expAmount, u8 expGetterMonId, u8 faintedBattler);
static void RemoveAllTerrains(void); static void RemoveAllTerrains(void);
static bool8 CanAbilityPreventStatLoss(u16 abilityDef, bool8 isIntimidate); static bool8 CanAbilityPreventStatLoss(u16 abilityDef);
static bool8 CanBurnHitThaw(u16 move); static bool8 CanBurnHitThaw(u16 move);
static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent); static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent);
static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount, u16 usedMove); static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount, u16 usedMove);
@ -11568,8 +11568,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattlescriptCurrInstr = BattleScript_ButItFailed; gBattlescriptCurrInstr = BattleScript_ButItFailed;
return STAT_CHANGE_DIDNT_WORK; return STAT_CHANGE_DIDNT_WORK;
} }
else if ((battlerHoldEffect == HOLD_EFFECT_CLEAR_AMULET else if ((battlerHoldEffect == HOLD_EFFECT_CLEAR_AMULET || CanAbilityPreventStatLoss(battlerAbility))
|| CanAbilityPreventStatLoss(battlerAbility, GetBattlerAbility(gBattlerAttacker) == ABILITY_INTIMIDATE))
&& (!affectsUser || mirrorArmored) && !certain && gCurrentMove != MOVE_CURSE) && (!affectsUser || mirrorArmored) && !certain && gCurrentMove != MOVE_CURSE)
{ {
if (flags == STAT_CHANGE_ALLOW_PTR) if (flags == STAT_CHANGE_ALLOW_PTR)
@ -15817,7 +15816,7 @@ static bool8 IsFinalStrikeEffect(u16 move)
return FALSE; return FALSE;
} }
static bool8 CanAbilityPreventStatLoss(u16 abilityDef, bool8 byIntimidate) static bool8 CanAbilityPreventStatLoss(u16 abilityDef)
{ {
switch (abilityDef) switch (abilityDef)
{ {
@ -15825,13 +15824,6 @@ static bool8 CanAbilityPreventStatLoss(u16 abilityDef, bool8 byIntimidate)
case ABILITY_FULL_METAL_BODY: case ABILITY_FULL_METAL_BODY:
case ABILITY_WHITE_SMOKE: case ABILITY_WHITE_SMOKE:
return TRUE; return TRUE;
case ABILITY_INNER_FOCUS:
case ABILITY_SCRAPPY:
case ABILITY_OWN_TEMPO:
case ABILITY_OBLIVIOUS:
if (byIntimidate && (B_UPDATED_INTIMIDATE >= GEN_8))
return TRUE;
break;
} }
return FALSE; return FALSE;
} }

View file

@ -1,29 +1,24 @@
#include "global.h" #include "global.h"
#include "test/battle.h" #include "test/battle.h"
SINGLE_BATTLE_TEST("Own Tempo prevents intimidate") SINGLE_BATTLE_TEST("Own Tempo prevents Intimidate but no other stat down changes")
{ {
s16 turnOneHit;
s16 turnTwoHit;
GIVEN { GIVEN {
ASSUME(B_UPDATED_INTIMIDATE >= GEN_8); ASSUME(B_UPDATED_INTIMIDATE >= GEN_8);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }; ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); };
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }; OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); };
} WHEN { } WHEN {
TURN { MOVE(opponent, MOVE_TACKLE); } TURN { MOVE(player, MOVE_SCARY_FACE); }
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_TACKLE); }
} SCENE { } SCENE {
HP_BAR(player, captureDamage: &turnOneHit);
ABILITY_POPUP(player, ABILITY_INTIMIDATE); ABILITY_POPUP(player, ABILITY_INTIMIDATE);
NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); }
ABILITY_POPUP(opponent, ABILITY_OWN_TEMPO); ABILITY_POPUP(opponent, ABILITY_OWN_TEMPO);
MESSAGE("Foe Slowpoke's Own Tempo prevents stat loss!"); MESSAGE("Foe Slowpoke's Own Tempo prevents stat loss!");
HP_BAR(player, captureDamage: &turnTwoHit); ANIMATION(ANIM_TYPE_MOVE, MOVE_SCARY_FACE, player);
} THEN { NONE_OF {
EXPECT_EQ(turnOneHit, turnTwoHit); ABILITY_POPUP(opponent, ABILITY_OWN_TEMPO);
MESSAGE("Foe Slowpoke's Own Tempo prevents stat loss!");
}
} }
} }