From 4e7b1f2a973384cf84b187b41232b63d81d27d9c Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Tue, 6 May 2025 12:07:01 +0200 Subject: [PATCH] Fixes Stomping Tantrum not boosting damage when missed due to Accuracy (#6762) --- include/battle.h | 4 ++-- src/battle_main.c | 5 ++++- src/battle_script_commands.c | 12 +++++++++--- src/battle_util.c | 6 +++--- test/battle/move_effect/stomping_tantrum.c | 12 ++++++------ 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/include/battle.h b/include/battle.h index 8874857efb..a1134d4fb1 100644 --- a/include/battle.h +++ b/include/battle.h @@ -622,7 +622,6 @@ struct BattlerState u32 multipleSwitchInBattlers:1; u32 alreadyStatusedMoveAttempt:1; // For example when using Thunder Wave on an already paralyzed Pokémon. u32 activeAbilityPopUps:1; - u32 lastMoveFailed:1; // For Stomping Tantrum u32 forcedSwitch:1; u32 storedHealingWish:1; u32 storedLunarDance:1; @@ -630,7 +629,8 @@ struct BattlerState u32 sleepClauseEffectExempt:1; // Stores whether effect should be exempt from triggering Sleep Clause (Effect Spore) u32 usedMicleBerry:1; u32 pursuitTarget:1; - u32 padding:17; + u32 stompingTantrumTimer:2; + u32 padding:16; // End of Word }; diff --git a/src/battle_main.c b/src/battle_main.c index c220b37c4b..671a31737b 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3183,7 +3183,7 @@ void SwitchInClearSetData(u32 battler) gBattleStruct->lastTakenMoveFrom[battler][1] = 0; gBattleStruct->lastTakenMoveFrom[battler][2] = 0; gBattleStruct->lastTakenMoveFrom[battler][3] = 0; - gBattleStruct->battlerState[battler].lastMoveFailed = FALSE; + gBattleStruct->battlerState[battler].stompingTantrumTimer = 0; gBattleStruct->palaceFlags &= ~(1u << battler); gBattleStruct->canPickupItem &= ~(1u << battler); @@ -3985,6 +3985,9 @@ void BattleTurnPassed(void) gBattleStruct->battlerState[i].absentBattlerFlags = (gAbsentBattlerFlags & (1u << i) ? TRUE : FALSE); gBattleStruct->monToSwitchIntoId[i] = PARTY_SIZE; gStatuses4[i] &= ~STATUS4_ELECTRIFIED; + + if (gBattleStruct->battlerState[i].stompingTantrumTimer > 0) + gBattleStruct->battlerState[i].stompingTantrumTimer--; } for (i = 0; i < NUM_BATTLE_SIDES; i++) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 03680aa5fc..60c105bdab 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1643,6 +1643,8 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u } else { + u32 numTargets = 0; + u32 numMisses = 0; u32 moveType = GetBattleMoveType(move); u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move); bool32 calcSpreadMove = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(move); @@ -1657,6 +1659,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u || (gBattleStruct->noResultString[battlerDef] && gBattleStruct->noResultString[battlerDef] != DO_ACCURACY_CHECK)) continue; + numTargets++; if (JumpIfMoveAffectedByProtect(move, battlerDef, FALSE) || AccuracyCalcHelper(move, battlerDef)) continue; @@ -1672,6 +1675,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u { gBattleStruct->moveResultFlags[battlerDef] = MOVE_RESULT_MISSED; gBattleStruct->missStringId[battlerDef] = gBattleCommunication[MISS_TYPE] = B_MSG_MISSED; + numMisses++; if (holdEffectAtk == HOLD_EFFECT_BLUNDER_POLICY) gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks @@ -1683,6 +1687,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u && !TargetFullyImmuneToCurrMove(gBattlerAttacker, BATTLE_PARTNER(battlerDef))) { // Smart target to partner if miss + numMisses = 0; // Other dart might hit gBattlerTarget = BATTLE_PARTNER(battlerDef); AccuracyCheck(TRUE, nextInstr, failInstr, move); return; @@ -1693,6 +1698,9 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u } } + if (numTargets == numMisses) + gBattleStruct->battlerState[gBattlerAttacker].stompingTantrumTimer = 2; + if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_MISSED) gBattleStruct->moveResultFlags[gBattlerTarget] = MOVE_RESULT_MISSED; @@ -6821,9 +6829,7 @@ static void Cmd_moveend(void) if ((gBattleStruct->moveResultFlags[gBattlerTarget] & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)) || (gBattleMons[gBattlerAttacker].status2 & (STATUS2_FLINCHED)) || gProtectStructs[gBattlerAttacker].nonVolatileStatusImmobility) - gBattleStruct->battlerState[gBattlerAttacker].lastMoveFailed = TRUE; - else - gBattleStruct->battlerState[gBattlerAttacker].lastMoveFailed = FALSE; + gBattleStruct->battlerState[gBattlerAttacker].stompingTantrumTimer = 2; // Set ShellTrap to activate after the attacker's turn if target was hit by a physical move. if (GetMoveEffect(gChosenMoveByBattler[gBattlerTarget]) == EFFECT_SHELL_TRAP diff --git a/src/battle_util.c b/src/battle_util.c index 9bf82b0670..b03718f4b9 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -9353,7 +9353,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData * modifier = uq4_12_multiply(modifier, UQ_4_12(0.5)); break; case EFFECT_STOMPING_TANTRUM: - if (gBattleStruct->battlerState[battlerAtk].lastMoveFailed) + if (gBattleStruct->battlerState[battlerAtk].stompingTantrumTimer == 1) modifier = uq4_12_multiply(modifier, UQ_4_12(2.0)); break; case EFFECT_MAGNITUDE: @@ -12202,8 +12202,8 @@ void ClearDamageCalcResults(void) bool32 DoesDestinyBondFail(u32 battler) { if (B_DESTINY_BOND_FAIL >= GEN_7 - && GetMoveEffect(gLastResultingMoves[battler]) == EFFECT_DESTINY_BOND - && !gBattleStruct->battlerState[battler].lastMoveFailed) + && GetMoveEffect(gLastLandedMoves[battler]) == EFFECT_DESTINY_BOND + && GetMoveEffect(gLastResultingMoves[battler]) == EFFECT_DESTINY_BOND) return TRUE; return FALSE; } diff --git a/test/battle/move_effect/stomping_tantrum.c b/test/battle/move_effect/stomping_tantrum.c index 18d8ffb7e9..95d93e07e6 100644 --- a/test/battle/move_effect/stomping_tantrum.c +++ b/test/battle/move_effect/stomping_tantrum.c @@ -6,7 +6,7 @@ ASSUMPTIONS ASSUME(GetMoveEffect(MOVE_STOMPING_TANTRUM) == EFFECT_STOMPING_TANTRUM); } -SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user flinched on the previous turn") +SINGLE_BATTLE_TEST("Stomping Tantrum will deal double damage if user flinched on the previous turn") { s16 damage[3]; GIVEN { @@ -36,7 +36,7 @@ SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user flinched on } } -SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user failed to attack due to paralysis") +SINGLE_BATTLE_TEST("Stomping Tantrum will deal double damage if user failed to attack due to paralysis") { s16 damage[3]; PASSES_RANDOMLY(25, 100, RNG_PARALYSIS); @@ -66,7 +66,7 @@ SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user failed to at } } -SINGLE_BATTLE_TEST("Stomping Tatrum will not deal double damage if target protects") +SINGLE_BATTLE_TEST("Stomping Tantrum will not deal double damage if target protects") { s16 damage[2]; GIVEN { @@ -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 if it missed") +SINGLE_BATTLE_TEST("Stomping Tantrum will not deal double if it missed") { s16 damage[2]; GIVEN { @@ -107,11 +107,11 @@ SINGLE_BATTLE_TEST("Stomping Tatrum will not deal double if it missed") ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); HP_BAR(opponent, captureDamage: &damage[1]); } THEN { - EXPECT_EQ(damage[0], damage[1]); + EXPECT_MUL_EQ(damage[0], Q_4_12(2.0), damage[1]); } } -SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user was immune to previous move") +SINGLE_BATTLE_TEST("Stomping Tantrum will deal double damage if user was immune to previous move") { s16 damage[2]; GIVEN {