From 99372b9c1ea08d3b0f1c43237bc4a1589a6b364c Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Thu, 4 Dec 2025 15:31:52 +0000 Subject: [PATCH] Fixes Wind Power/Electromorphosis potentially boosting 2 electric attacks (#8431) --- src/battle_script_commands.c | 16 ++++--- test/battle/ability/wind_power.c | 71 +++++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 54162af52a..acb60f3c36 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1024,10 +1024,14 @@ static void TryClearChargeVolatile(u32 moveType) if (B_CHARGE < GEN_9) // Prior to gen9, charge is cleared during the end turn return; - if (gBattleMons[gBattlerAttacker].volatiles.chargeTimer == 2) // Has been set this turn by move - gBattleMons[gBattlerAttacker].volatiles.chargeTimer--; - else if (moveType == TYPE_ELECTRIC && gBattleMons[gBattlerAttacker].volatiles.chargeTimer == 1) + if (moveType == TYPE_ELECTRIC && gBattleMons[gBattlerAttacker].volatiles.chargeTimer == 1) gBattleMons[gBattlerAttacker].volatiles.chargeTimer = 0; + + for (u32 battler = 0; battler < gBattlersCount; battler++) + { + if (gBattleMons[battler].volatiles.chargeTimer == 2) // Has been set this turn by move + gBattleMons[battler].volatiles.chargeTimer--; + } } static bool32 IsAnyTargetAffected(void) @@ -4046,7 +4050,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, enum MoveEffect moveEffect, c gBattleMons[gBattlerAttacker].volatiles.bonusCritStages++; if (gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].volatiles.bonusCritStages < 3) gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].volatiles.bonusCritStages++; - BattleScriptPush(gBattlescriptCurrInstr + 1); + BattleScriptPush(battleScript); gBattlescriptCurrInstr = BattleScript_EffectRaiseCritAlliesAnim; break; case MOVE_EFFECT_HEAL_TEAM: @@ -12211,6 +12215,8 @@ static void Cmd_tryactivateitem(void) CMD_ARGS(u8 battler, u8 flag); u32 battler = GetBattlerForBattleScript(cmd->battler); + gBattlescriptCurrInstr = cmd->nextInstr; + switch ((enum ItemActivationState)cmd->flag) { case ACTIVATION_ON_USABLE_AGAIN: @@ -12228,8 +12234,6 @@ static void Cmd_tryactivateitem(void) return; break; } - - gBattlescriptCurrInstr = cmd->nextInstr; } // Belly Drum, Fillet Away diff --git a/test/battle/ability/wind_power.c b/test/battle/ability/wind_power.c index c38bbf3569..c78df34190 100644 --- a/test/battle/ability/wind_power.c +++ b/test/battle/ability/wind_power.c @@ -3,9 +3,10 @@ ASSUMPTIONS { - ASSUME(!IsBattleMoveStatus(MOVE_THUNDERBOLT)); - ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); + ASSUME(!IsBattleMoveStatus(MOVE_NUZZLE)); + ASSUME(GetMoveType(MOVE_NUZZLE) == TYPE_ELECTRIC); ASSUME(!IsBattleMoveStatus(MOVE_SCRATCH)); + ASSUME(!IsWindMove(MOVE_SCRATCH)); ASSUME(!IsBattleMoveStatus(MOVE_AIR_CUTTER)); ASSUME(GetMoveTarget(MOVE_AIR_CUTTER) == MOVE_TARGET_BOTH); ASSUME(IsWindMove(MOVE_AIR_CUTTER)); @@ -25,12 +26,12 @@ SINGLE_BATTLE_TEST("Wind Power sets up Charge for player when hit by a wind move GIVEN { PLAYER(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(10); } - OPPONENT(SPECIES_WOBBUFFET) {Ability(ABILITY_LIMBER); Speed(5) ;} // Limber, so it doesn't get paralyzed. + OPPONENT(SPECIES_PERSIAN) {Ability(ABILITY_LIMBER); Speed(5) ;} // Limber, so it doesn't get paralyzed. } WHEN { - TURN { MOVE(player, MOVE_THUNDERBOLT), MOVE(opponent, move); } - TURN { MOVE(player, MOVE_THUNDERBOLT), MOVE(opponent, move); } + TURN { MOVE(player, MOVE_NUZZLE), MOVE(opponent, move); } + TURN { MOVE(player, MOVE_NUZZLE), MOVE(opponent, move); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_NUZZLE, player); HP_BAR(opponent, captureDamage: &dmgBefore); ANIMATION(ANIM_TYPE_MOVE, move, opponent); @@ -40,7 +41,7 @@ SINGLE_BATTLE_TEST("Wind Power sets up Charge for player when hit by a wind move MESSAGE("Being hit by Air Cutter charged Wattrel with power!"); } - ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_NUZZLE, player); HP_BAR(opponent, captureDamage: &dmgAfter); ANIMATION(ANIM_TYPE_MOVE, move, opponent); @@ -69,13 +70,13 @@ SINGLE_BATTLE_TEST("Wind Power sets up Charge for opponent when hit by a wind mo PARAMETRIZE {move = MOVE_AIR_CUTTER; } GIVEN { - PLAYER(SPECIES_WOBBUFFET) {Ability(ABILITY_LIMBER); Speed(5) ;} // Limber, so it doesn't get paralyzed. + PLAYER(SPECIES_PERSIAN) {Ability(ABILITY_LIMBER); Speed(5) ;} // Limber, so it doesn't get paralyzed. OPPONENT(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(10); } } WHEN { - TURN { MOVE(opponent, MOVE_THUNDERBOLT), MOVE(player, move); } - TURN { MOVE(opponent, MOVE_THUNDERBOLT), MOVE(player, move); } + TURN { MOVE(opponent, MOVE_NUZZLE), MOVE(player, move); } + TURN { MOVE(opponent, MOVE_NUZZLE), MOVE(player, move); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_NUZZLE, opponent); HP_BAR(player, captureDamage: &dmgBefore); ANIMATION(ANIM_TYPE_MOVE, move, player); @@ -85,7 +86,7 @@ SINGLE_BATTLE_TEST("Wind Power sets up Charge for opponent when hit by a wind mo MESSAGE("Being hit by Air Cutter charged the opposing Wattrel with power!"); } - ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_NUZZLE, opponent); HP_BAR(player, captureDamage: &dmgAfter); ANIMATION(ANIM_TYPE_MOVE, move, player); @@ -105,6 +106,44 @@ SINGLE_BATTLE_TEST("Wind Power sets up Charge for opponent when hit by a wind mo } } +SINGLE_BATTLE_TEST("Wind Power sets up Charge for only one attack when hit by a wind move") +{ + s16 dmgCharged, dmgAfter; + u16 move; + + PARAMETRIZE {move = MOVE_SCRATCH; } + PARAMETRIZE {move = MOVE_AIR_CUTTER; } + + GIVEN { + PLAYER(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(5); } + OPPONENT(SPECIES_PERSIAN) {Ability(ABILITY_LIMBER); Speed(10) ;} // Limber, so it doesn't get paralyzed. + } WHEN { + TURN { MOVE(opponent, move); MOVE(player, MOVE_NUZZLE); } + TURN { MOVE(player, MOVE_NUZZLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, opponent); + HP_BAR(player); + if (move == MOVE_AIR_CUTTER) { + ABILITY_POPUP(player, ABILITY_WIND_POWER); + MESSAGE("Being hit by Air Cutter charged Wattrel with power!"); + } + + ANIMATION(ANIM_TYPE_MOVE, MOVE_NUZZLE, player); + HP_BAR(opponent, captureDamage: &dmgCharged); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_NUZZLE, player); + HP_BAR(opponent, captureDamage: &dmgAfter); + } + THEN { + if (move == MOVE_AIR_CUTTER) { + EXPECT_MUL_EQ(dmgAfter, Q_4_12(2.0), dmgCharged); + } + else { + EXPECT_EQ(dmgAfter, dmgCharged); + } + } +} + DOUBLE_BATTLE_TEST("Wind Power activates correctly for every battler with the ability when hit by a 2/3 target move") { enum Ability abilityLeft, abilityRight; @@ -116,8 +155,8 @@ DOUBLE_BATTLE_TEST("Wind Power activates correctly for every battler with the ab GIVEN { PLAYER(SPECIES_WATTREL) { Ability(abilityLeft); Speed(10); } PLAYER(SPECIES_WATTREL) { Ability(abilityRight); Speed(5); } - OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_LIMBER); Speed(20); } - OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_LIMBER); Speed(15); } + OPPONENT(SPECIES_PERSIAN) { Ability(ABILITY_LIMBER); Speed(20); } + OPPONENT(SPECIES_PERSIAN) { Ability(ABILITY_LIMBER); Speed(15); } } WHEN { TURN { MOVE(opponentLeft, MOVE_AIR_CUTTER); MOVE(opponentRight, MOVE_AIR_CUTTER);} } SCENE { @@ -157,8 +196,8 @@ DOUBLE_BATTLE_TEST("Wind Power activates correctly for every battler with the ab GIVEN { PLAYER(SPECIES_WATTREL) { Ability(abilityLeft); Speed(10); } PLAYER(SPECIES_WATTREL) { Ability(abilityRight); Speed(5); } - OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_LIMBER); Speed(20); } - OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_LIMBER); Speed(15); } + OPPONENT(SPECIES_PERSIAN) { Ability(ABILITY_LIMBER); Speed(20); } + OPPONENT(SPECIES_PERSIAN) { Ability(ABILITY_LIMBER); Speed(15); } } WHEN { TURN { MOVE(opponentLeft, MOVE_PETAL_BLIZZARD);} } SCENE {