Fixes Stomping Tantrum not doubling power if asleep or frozen (#6719)

This commit is contained in:
Alex 2025-04-29 23:25:56 +02:00 committed by GitHub
parent c8e978c3d5
commit afcba8d9cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 23 additions and 46 deletions

View File

@ -148,27 +148,19 @@ struct ProtectStruct
u32 helpingHand:1;
u32 bounceMove:1;
u32 stealMove:1;
u32 prlzImmobility:1;
u32 nonVolatileStatusImmobility:1;
u32 confusionSelfDmg:1;
u32 targetAffected:1;
u32 chargingTurn:1;
u32 fleeType:2; // 0: Normal, 1: FLEE_ITEM, 2: FLEE_ABILITY
u32 usedImprisonedMove:1;
u32 loveImmobility:1;
u32 usedDisabledMove:1;
u32 usedTauntedMove:1;
u32 flag2Unknown:1; // Only set to 0 once. Checked in 'WasUnableToUseMove' function.
u32 flinchImmobility:1;
u32 unableToUseMove:1; // Not to be confused with HITMARKER_UNABLE_TO_USE_MOVE (It is questionable though if there is a difference. Needs further research)
u32 notFirstStrike:1;
u32 palaceUnableToUseMove:1;
u32 usedHealBlockedMove:1;
u32 usedGravityPreventedMove:1;
u32 powderSelfDmg:1;
u32 usedThroatChopPreventedMove:1;
u32 statRaised:1;
u32 usedCustapBerry:1; // also quick claw
u32 touchedProtectLike:1;
u32 unused:1;
u32 unused:9;
// End of 32-bit bitfield
u16 disableEjectPack:1;
u16 statFell:1;

View File

@ -3283,21 +3283,13 @@ const u8* FaintClearSetData(u32 battler)
gProtectStructs[battler].helpingHand = FALSE;
gProtectStructs[battler].bounceMove = FALSE;
gProtectStructs[battler].stealMove = FALSE;
gProtectStructs[battler].prlzImmobility = FALSE;
gProtectStructs[battler].nonVolatileStatusImmobility = FALSE;
gProtectStructs[battler].unableToUseMove = FALSE;
gProtectStructs[battler].confusionSelfDmg = FALSE;
gProtectStructs[battler].targetAffected = FALSE;
gProtectStructs[battler].chargingTurn = FALSE;
gProtectStructs[battler].fleeType = 0;
gProtectStructs[battler].usedImprisonedMove = FALSE;
gProtectStructs[battler].loveImmobility = FALSE;
gProtectStructs[battler].usedDisabledMove = FALSE;
gProtectStructs[battler].usedTauntedMove = FALSE;
gProtectStructs[battler].flag2Unknown = FALSE;
gProtectStructs[battler].flinchImmobility = FALSE;
gProtectStructs[battler].notFirstStrike = FALSE;
gProtectStructs[battler].usedHealBlockedMove = FALSE;
gProtectStructs[battler].usedGravityPreventedMove = FALSE;
gProtectStructs[battler].usedThroatChopPreventedMove = FALSE;
gProtectStructs[battler].statRaised = FALSE;
gProtectStructs[battler].statFell = FALSE;
gProtectStructs[battler].pranksterElevated = FALSE;

View File

@ -6820,7 +6820,7 @@ static void Cmd_moveend(void)
case MOVEEND_UPDATE_LAST_MOVES:
if ((gBattleStruct->moveResultFlags[gBattlerTarget] & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE))
|| (gBattleMons[gBattlerAttacker].status2 & (STATUS2_FLINCHED))
|| gProtectStructs[gBattlerAttacker].prlzImmobility)
|| gProtectStructs[gBattlerAttacker].nonVolatileStatusImmobility)
gBattleStruct->battlerState[gBattlerAttacker].lastMoveFailed = TRUE;
else
gBattleStruct->battlerState[gBattlerAttacker].lastMoveFailed = FALSE;

View File

@ -1081,21 +1081,12 @@ const u8* CancelMultiTurnMoves(u32 battler)
bool32 WasUnableToUseMove(u32 battler)
{
if (gProtectStructs[battler].prlzImmobility
|| gProtectStructs[battler].usedImprisonedMove
|| gProtectStructs[battler].loveImmobility
|| gProtectStructs[battler].usedDisabledMove
|| gProtectStructs[battler].usedTauntedMove
|| gProtectStructs[battler].usedGravityPreventedMove
|| gProtectStructs[battler].usedHealBlockedMove
|| gProtectStructs[battler].flag2Unknown
|| gProtectStructs[battler].flinchImmobility
|| gProtectStructs[battler].confusionSelfDmg
|| gProtectStructs[battler].powderSelfDmg
|| gProtectStructs[battler].usedThroatChopPreventedMove)
if (gProtectStructs[battler].nonVolatileStatusImmobility
|| gProtectStructs[battler].unableToUseMove
|| gProtectStructs[battler].powderSelfDmg
|| gProtectStructs[battler].confusionSelfDmg)
return TRUE;
else
return FALSE;
return FALSE;
}
void PrepareStringBattle(u16 stringId, u32 battler)
@ -3223,6 +3214,7 @@ static void CancellerAsleep(u32 *effect)
u32 moveEffect = GetMoveEffect(gChosenMove);
if (moveEffect != EFFECT_SNORE && moveEffect != EFFECT_SLEEP_TALK)
{
gProtectStructs[gBattlerAttacker].nonVolatileStatusImmobility = TRUE;
gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
*effect = 2;
@ -3247,6 +3239,7 @@ static void CancellerFrozen(u32 *effect)
{
if (!RandomPercentage(RNG_FROZEN, 20))
{
gProtectStructs[gBattlerAttacker].nonVolatileStatusImmobility = TRUE;
gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen;
gHitMarker |= (HITMARKER_NO_ATTACKSTRING | HITMARKER_UNABLE_TO_USE_MOVE);
}
@ -3335,7 +3328,7 @@ static void CancellerFlinch(u32 *effect)
{
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FLINCHED)
{
gProtectStructs[gBattlerAttacker].flinchImmobility = TRUE;
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
@ -3356,7 +3349,7 @@ static void CancellerInLove(u32 *effect)
{
BattleScriptPush(BattleScript_MoveUsedIsInLoveCantAttack);
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
gProtectStructs[gBattlerAttacker].loveImmobility = TRUE;
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
CancelMultiTurnMoves(gBattlerAttacker);
}
gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove;
@ -3368,7 +3361,7 @@ static void CancellerDisabled(u32 *effect)
{
if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].disabledMove == gCurrentMove && gDisableStructs[gBattlerAttacker].disabledMove != MOVE_NONE)
{
gProtectStructs[gBattlerAttacker].usedDisabledMove = TRUE;
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
gBattleScripting.battler = gBattlerAttacker;
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled;
@ -3381,7 +3374,7 @@ static void CancellerHealBlocked(u32 *effect)
{
if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(gBattlerAttacker, gCurrentMove))
{
gProtectStructs[gBattlerAttacker].usedHealBlockedMove = TRUE;
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
gBattleScripting.battler = gBattlerAttacker;
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveUsedHealBlockPrevents;
@ -3394,7 +3387,7 @@ static void CancellerGravity(u32 *effect)
{
if (gFieldStatuses & STATUS_FIELD_GRAVITY && IsGravityPreventingMove(gCurrentMove))
{
gProtectStructs[gBattlerAttacker].usedGravityPreventedMove = TRUE;
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
gBattleScripting.battler = gBattlerAttacker;
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveUsedGravityPrevents;
@ -3407,7 +3400,7 @@ static void CancellerThroatChop(u32 *effect)
{
if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer && IsSoundMove(gCurrentMove))
{
gProtectStructs[gBattlerAttacker].usedThroatChopPreventedMove = TRUE;
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
@ -3419,7 +3412,7 @@ static void CancellerTaunted(u32 *effect)
{
if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].tauntTimer && IsBattleMoveStatus(gCurrentMove))
{
gProtectStructs[gBattlerAttacker].usedTauntedMove = TRUE;
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
@ -3431,7 +3424,7 @@ static void CancellerImprisoned(u32 *effect)
{
if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && GetImprisonedMovesCount(gBattlerAttacker, gCurrentMove))
{
gProtectStructs[gBattlerAttacker].usedImprisonedMove = TRUE;
gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE;
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
@ -3489,7 +3482,7 @@ static void CancellerParalysed(u32 *effect)
&& !(B_MAGIC_GUARD == GEN_4 && GetBattlerAbility(gBattlerAttacker) == ABILITY_MAGIC_GUARD)
&& !RandomPercentage(RNG_PARALYSIS, 75))
{
gProtectStructs[gBattlerAttacker].prlzImmobility = TRUE;
gProtectStructs[gBattlerAttacker].nonVolatileStatusImmobility = TRUE;
// This is removed in FRLG and Emerald for some reason
//CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed;

View File

@ -90,7 +90,7 @@ SINGLE_BATTLE_TEST("Stomping Tatrum will not deal double damage if target protec
}
}
SINGLE_BATTLE_TEST("Stomping Tatrum will not deal double damage if it failed on the previous turn cause of Protect")
SINGLE_BATTLE_TEST("Stomping Tatrum will not deal double if it missed")
{
s16 damage[2];
GIVEN {