From b55c87f73f61fceab205419d4b1c8b227928eba1 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Mon, 11 Nov 2024 20:58:09 +0100 Subject: [PATCH] Fixes Take heart (#5658) Co-authored-by: KyleLaporte Co-authored-by: Pawkkie <61265402+Pawkkie@users.noreply.github.com> --- asm/macros/battle_script.inc | 2 +- data/battle_scripts_1.s | 4 +- include/constants/battle.h | 2 + src/battle_script_commands.c | 15 ++++-- test/battle/move_effect/refresh.c | 68 ++++++++++++++++++++++++++++ test/battle/move_effect/take_heart.c | 24 ++++++++++ 6 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 test/battle/move_effect/refresh.c diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index ea55903631..6dbcabe43e 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1104,7 +1104,7 @@ .byte 0xcc .endm - .macro cureifburnedparalysedorpoisoned failInstr:req + .macro curestatuswithmove failInstr:req .byte 0xcd .4byte \failInstr .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 8267e0c195..825ed3703e 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -443,7 +443,7 @@ BattleScript_EffectTakeHeart:: attackcanceler attackstring ppreduce - cureifburnedparalysedorpoisoned BattleScript_CalmMindTryToRaiseStats + curestatuswithmove BattleScript_CalmMindTryToRaiseStats attackanimation waitanimation updatestatusicon BS_ATTACKER @@ -5226,7 +5226,7 @@ BattleScript_EffectRefresh:: attackcanceler attackstring ppreduce - cureifburnedparalysedorpoisoned BattleScript_ButItFailed + curestatuswithmove BattleScript_ButItFailed attackanimation waitanimation printstring STRINGID_PKMNSTATUSNORMAL diff --git a/include/constants/battle.h b/include/constants/battle.h index 1f11adbd5f..d531ea80e6 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -122,6 +122,8 @@ #define STATUS1_PSN_ANY (STATUS1_POISON | STATUS1_TOXIC_POISON) #define STATUS1_ANY (STATUS1_SLEEP | STATUS1_POISON | STATUS1_BURN | STATUS1_FREEZE | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE) +#define STATUS1_REFRESH (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE) + // Volatile status ailments // These are removed after exiting the battle or switching out #define STATUS2_CONFUSION (1 << 0 | 1 << 1 | 1 << 2) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 26e89cd4f2..7212560ebd 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -545,7 +545,7 @@ static void Cmd_trymemento(void); static void Cmd_setforcedtarget(void); static void Cmd_setcharge(void); static void Cmd_callterrainattack(void); -static void Cmd_cureifburnedparalysedorpoisoned(void); +static void Cmd_curestatuswithmove(void); static void Cmd_settorment(void); static void Cmd_jumpifnodamage(void); static void Cmd_settaunt(void); @@ -804,7 +804,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = Cmd_setforcedtarget, //0xCA Cmd_setcharge, //0xCB Cmd_callterrainattack, //0xCC - Cmd_cureifburnedparalysedorpoisoned, //0xCD + Cmd_curestatuswithmove, //0xCD Cmd_settorment, //0xCE Cmd_jumpifnodamage, //0xCF Cmd_settaunt, //0xD0 @@ -14135,12 +14135,17 @@ u32 GetNaturePowerMove(u32 battler) return move; } -// Refresh -static void Cmd_cureifburnedparalysedorpoisoned(void) +static void Cmd_curestatuswithmove(void) { CMD_ARGS(const u8 *failInstr); + u32 shouldHeal; - if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE)) + if (gMovesInfo[gCurrentMove].effect == EFFECT_REFRESH) + shouldHeal = gBattleMons[gBattlerAttacker].status1 & STATUS1_REFRESH; + else // Take Heart + shouldHeal = gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY; + + if (shouldHeal) { gBattleMons[gBattlerAttacker].status1 = 0; gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/test/battle/move_effect/refresh.c b/test/battle/move_effect/refresh.c new file mode 100644 index 0000000000..7d49c7e8d0 --- /dev/null +++ b/test/battle/move_effect/refresh.c @@ -0,0 +1,68 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_REFRESH].effect == EFFECT_REFRESH); +} + +SINGLE_BATTLE_TEST("Refresh cures the user of burn, frostbite, poison, and paralysis") +{ + u32 status1; + PARAMETRIZE { status1 = STATUS1_POISON; } + PARAMETRIZE { status1 = STATUS1_BURN; } + PARAMETRIZE { status1 = STATUS1_PARALYSIS; } + PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; } + PARAMETRIZE { status1 = STATUS1_FROSTBITE; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(status1); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_REFRESH); } + } SCENE { + MESSAGE("Wobbuffet's status returned to normal!"); + STATUS_ICON(player, none: TRUE); + } +} + +SINGLE_BATTLE_TEST("Refresh does not cure the user of Freeze") +{ + PASSES_RANDOMLY(20, 100, RNG_FROZEN); + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_REFRESH); } + } SCENE { + MESSAGE("Wobbuffet used Refresh!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_REFRESH, player); + STATUS_ICON(player, none: TRUE); } + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Refresh does not cure sleep when used by Sleep Talk") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_REFRESH); } + } WHEN { + TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); } + TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_REFRESH); } + } SCENE { + MESSAGE("Wobbuffet used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("Foe Wobbuffet fell asleep!"); + MESSAGE("Foe Wobbuffet used Sleep Talk!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent); + MESSAGE("Foe Wobbuffet used Refresh!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_REFRESH, player); + STATUS_ICON(player, none: TRUE); } + MESSAGE("But it failed!"); + } +} diff --git a/test/battle/move_effect/take_heart.c b/test/battle/move_effect/take_heart.c index 081815cfb8..8c45a16f72 100644 --- a/test/battle/move_effect/take_heart.c +++ b/test/battle/move_effect/take_heart.c @@ -40,8 +40,32 @@ SINGLE_BATTLE_TEST("Take Heart cures the user of all status conditions") STATUS_ICON(player, none: TRUE); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } else { + STATUS_ICON(player, none: TRUE); MESSAGE("Wobbuffet's status returned to normal!"); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } } } + +SINGLE_BATTLE_TEST("Take Heart cures sleep when used by Sleep Talk") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP); + ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_TAKE_HEART); } + } WHEN { + TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); } + } SCENE { + MESSAGE("Wobbuffet used Spore!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + MESSAGE("Foe Wobbuffet fell asleep!"); + MESSAGE("Foe Wobbuffet used Sleep Talk!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent); + MESSAGE("Foe Wobbuffet used Take Heart!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAKE_HEART, opponent); + STATUS_ICON(opponent, none: TRUE); + MESSAGE("Foe Wobbuffet's status returned to normal!"); + } +}