diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 588360d226..a9584dcef6 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1766,10 +1766,6 @@ callnative BS_WaitFanfare .endm - .macro setbeakblast - callnative BS_SetBeakBlast - .endm - .macro cantarshotwork failInstr:req callnative BS_CanTarShotWork .4byte \failInstr diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 5f0b650f72..777481ac5e 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -671,7 +671,6 @@ BattleScript_EffectCourtChange:: goto BattleScript_MoveEnd BattleScript_BeakBlastSetUp:: - setbeakblast flushtextbox playanimation BS_ATTACKER, B_ANIM_BEAK_BLAST_SETUP, NULL printstring STRINGID_HEATUPBEAK diff --git a/include/battle.h b/include/battle.h index 1c7b824fd1..559b4eb88b 100755 --- a/include/battle.h +++ b/include/battle.h @@ -158,19 +158,18 @@ struct ProtectStruct u32 disableEjectPack:1; u32 pranksterElevated:1; u32 quickDraw:1; - u32 beakBlastCharge:1; u32 quash:1; u32 shellTrap:1; u32 eatMirrorHerb:1; u32 activateOpportunist:2; // 2 - to copy stats. 1 - stats copied (do not repeat). 0 - no stats to copy u16 usedAllySwitch:1; + u16 lashOutAffected:1; // End of 32-bit bitfield u32 helpingHand:3; - u16 lashOutAffected:1; u16 assuranceDoubled:1; u16 myceliumMight:1; u16 laggingTail:1; - u16 padding:9; + u16 padding:10; // End of 16-bit bitfield u16 physicalDmg; u16 specialDmg; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e246c48fbb..bc66490054 100755 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1069,6 +1069,15 @@ bool32 EmergencyExitCanBeTriggered(u32 battler) return FALSE; } +static inline bool32 IsBattlerUsingBeakBlast(u32 battler) +{ + if (gChosenActionByBattler[battler] != B_ACTION_USE_MOVE) + return FALSE; + if (GetMoveEffect(gChosenMoveByBattler[battler]) != EFFECT_BEAK_BLAST) + return FALSE; + return !HasBattlerActedThisTurn(battler); +} + static void Cmd_attackcanceler(void) { CMD_ARGS(); @@ -1295,7 +1304,8 @@ static void Cmd_attackcanceler(void) gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED; gBattlescriptCurrInstr = cmd->nextInstr; } - else if (gProtectStructs[gBattlerTarget].beakBlastCharge && !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker, TRUE), gCurrentMove)) + else if (IsBattlerUsingBeakBlast(gBattlerTarget) + && !CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker, TRUE), gCurrentMove)) { gProtectStructs[gBattlerAttacker].touchedProtectLike = TRUE; gBattlescriptCurrInstr = cmd->nextInstr; @@ -6116,7 +6126,7 @@ static void Cmd_moveend(void) } // Not strictly a protect effect, but works the same way - if (gProtectStructs[gBattlerTarget].beakBlastCharge + if (IsBattlerUsingBeakBlast(gBattlerTarget) && CanBeBurned(gBattlerAttacker, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker)) && !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)) { @@ -16299,13 +16309,6 @@ void BS_WaitFanfare(void) gBattlescriptCurrInstr = cmd->nextInstr; } -void BS_SetBeakBlast(void) -{ - NATIVE_ARGS(); - gProtectStructs[gBattlerAttacker].beakBlastCharge = TRUE; - gBattlescriptCurrInstr = cmd->nextInstr; -} - void BS_RemoveTerrain(void) { NATIVE_ARGS(); diff --git a/test/battle/move_effect/beak_blast.c b/test/battle/move_effect/beak_blast.c index b879a198c8..6e94a908e5 100644 --- a/test/battle/move_effect/beak_blast.c +++ b/test/battle/move_effect/beak_blast.c @@ -86,7 +86,7 @@ SINGLE_BATTLE_TEST("Beak Blast burns only when contact moves are used") PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(player, MOVE_BEAK_BLAST); MOVE(opponent, move); } + TURN { MOVE(opponent, move); MOVE(player, MOVE_BEAK_BLAST); } TURN {} } SCENE { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_BEAK_BLAST_SETUP, player); @@ -115,11 +115,11 @@ SINGLE_BATTLE_TEST("Beak Blast burns only when contact moves are used") SINGLE_BATTLE_TEST("Beak Blast doesn't burn fire types") { GIVEN { - ASSUME(gSpeciesInfo[SPECIES_ARCANINE].types[0] == TYPE_FIRE || gSpeciesInfo[SPECIES_ARCANINE].types[1]); + ASSUME(gSpeciesInfo[SPECIES_ARCANINE].types[0] == TYPE_FIRE || gSpeciesInfo[SPECIES_ARCANINE].types[1] == TYPE_FIRE); PLAYER(SPECIES_ARCANINE); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(opponent, MOVE_BEAK_BLAST); MOVE(player, MOVE_SCRATCH); } + TURN { MOVE(player, MOVE_SCRATCH); MOVE(opponent, MOVE_BEAK_BLAST); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); NOT STATUS_ICON(player, burn: TRUE); @@ -127,6 +127,20 @@ SINGLE_BATTLE_TEST("Beak Blast doesn't burn fire types") } } +SINGLE_BATTLE_TEST("Beak Blast doesn't burn after being used") +{ + GIVEN { + ASSUME(GetMovePriority(MOVE_COUNTER) < GetMovePriority(MOVE_BEAK_BLAST)); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_BEAK_BLAST); MOVE(player, MOVE_COUNTER); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BEAK_BLAST, opponent); + NOT STATUS_ICON(player, burn: TRUE); + } +} + TO_DO_BATTLE_TEST("Beak Blast's charging message is shown regardless if it would've missed"); TO_DO_BATTLE_TEST("Beak Blast fails if it's forced by Encore after choosing a different move"); TO_DO_BATTLE_TEST("Bulletproof is immune to Beak Blast but not to the burn it causes");