From 9b3e1b1c352c6964ae609bc68fe692edd22093fa Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Fri, 7 Feb 2025 08:58:54 -0300 Subject: [PATCH 1/5] Given Sparkly Swirl MOVE_EFFECT_AROMATHERAPY --- data/battle_scripts_1.s | 9 --------- include/battle_scripts.h | 1 - include/constants/battle_move_effects.h | 1 - src/data/battle_move_effects.h | 6 ------ src/data/moves_info.h | 12 ++++++------ test/battle/sleep_clause.c | 2 +- 6 files changed, 7 insertions(+), 24 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 7f796eb0be45..58ff87812ca0 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -956,15 +956,6 @@ BattleScript_MoveEffectIonDeluge:: waitmessage B_WAIT_TIME_LONG return -BattleScript_EffectSparklySwirl:: - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - healpartystatus - waitstate - updatestatusicon BS_ATTACKER_WITH_PARTNER - waitstate - goto BattleScript_MoveEnd - BattleScript_MoveEffectHaze:: printstring STRINGID_STATCHANGESGONE waitmessage B_WAIT_TIME_LONG diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 64e6018bcbf9..a2cab790c31b 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -822,7 +822,6 @@ extern const u8 BattleScript_MoveEffectLightScreen[]; extern const u8 BattleScript_MoveEffectReflect[]; extern const u8 BattleScript_MoveEffectLeechSeed[]; extern const u8 BattleScript_MoveEffectHaze[]; -extern const u8 BattleScript_EffectSparklySwirl[]; extern const u8 BattleScript_MoveEffectIonDeluge[]; extern const u8 BattleScript_EffectHyperspaceFury[]; extern const u8 BattleScript_EffectAuraWheel[]; diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 4d2ccef9ac7e..5b5b872da53d 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -295,7 +295,6 @@ enum { EFFECT_RECOIL_HP_25, EFFECT_STUFF_CHEEKS, EFFECT_GRAV_APPLE, - EFFECT_SPARKLY_SWIRL, EFFECT_HYPERSPACE_FURY, EFFECT_AURA_WHEEL, EFFECT_PHOTON_GEYSER, diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index ea6b26902cd7..4626e8e4fe33 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -1895,12 +1895,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = .battleTvScore = 0, // TODO: Assign points }, - [EFFECT_SPARKLY_SWIRL] = - { - .battleScript = BattleScript_EffectSparklySwirl, - .battleTvScore = 0, // TODO: Assign points - }, - [EFFECT_HYPERSPACE_FURY] = { .battleScript = BattleScript_EffectHyperspaceFury, diff --git a/src/data/moves_info.h b/src/data/moves_info.h index 0a71a24ab797..85295b741fc6 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -17068,7 +17068,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Wrap foe with whirlwind of\n" "scent. Heals party's status."), - .effect = EFFECT_SPARKLY_SWIRL, // Temprorary + .effect = EFFECT_HIT, .power = B_UPDATED_MOVE_DATA >= GEN_8 ? 120 : 90, .type = TYPE_FAIRY, .accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 85 : 100, @@ -17078,11 +17078,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .category = DAMAGE_CATEGORY_SPECIAL, .mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8, .metronomeBanned = TRUE, - // .additionalEffects = ADDITIONAL_EFFECTS({ - // .moveEffect = 0, // MOVE_EFFECT_AROMATHERAPY, Added 0 for Sheer Force boost - // .chance = 100, - // .sheerForceBoost = SHEER_FORCE_NO_BOOST, - // }), + .additionalEffects = ADDITIONAL_EFFECTS({ + .moveEffect = MOVE_EFFECT_AROMATHERAPY, + .chance = 100, + .sheerForceBoost = SHEER_FORCE_NO_BOOST, + }), .battleAnimScript = gBattleAnimMove_SparklySwirl, }, diff --git a/test/battle/sleep_clause.c b/test/battle/sleep_clause.c index ae20a0acadbb..63fa6ce01efc 100644 --- a/test/battle/sleep_clause.c +++ b/test/battle/sleep_clause.c @@ -567,7 +567,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP); ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL); ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL); - ASSUME(GetMoveEffect(MOVE_SPARKLY_SWIRL) == EFFECT_SPARKLY_SWIRL); + ASSUME(MoveHasAdditionalEffect(MOVE_SPARKLY_SWIRL, MOVE_EFFECT_AROMATHERAPY)); ASSUME(B_SLEEP_TURNS >= GEN_5); PLAYER(SPECIES_ZIGZAGOON); PLAYER(SPECIES_ZIGZAGOON); From 2e4da783128abc6e3df832e7739a89dae801e312 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Fri, 7 Feb 2025 11:48:14 -0300 Subject: [PATCH 2/5] Fixed MOVE_EFFECT_AROMATHERAPY only healing in-battle teammates --- data/battle_scripts_1.s | 28 ++------------- include/battle_scripts.h | 2 +- src/battle_script_commands.c | 2 +- test/battle/gimmick/dynamax.c | 12 +++++-- .../move_effect_secondary/aromatherapy.c | 34 +++++++++++++++++++ test/battle/sleep_clause.c | 2 +- 6 files changed, 50 insertions(+), 30 deletions(-) create mode 100644 test/battle/move_effect_secondary/aromatherapy.c diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 58ff87812ca0..b6831e512edd 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -4066,10 +4066,11 @@ BattleScript_EffectHealBell:: attackcanceler attackstring ppreduce - healpartystatus - waitstate attackanimation waitanimation +BattleScript_EffectHealBell_FromHeal:: + healpartystatus + waitstate printfromtable gPartyStatusHealStringIds waitmessage B_WAIT_TIME_LONG jumpifnotmove MOVE_HEAL_BELL, BattleScript_PartyHealEnd @@ -9953,29 +9954,6 @@ BattleScript_HealOneSixthAlliesEnd: restoretarget goto BattleScript_MoveEnd -BattleScript_EffectCureStatusAllies:: - jumpifteamhealthy BS_ATTACKER, BattleScript_MoveEnd - savetarget - copybyte gBattlerTarget, gBattlerAttacker -BattleScript_CureStatusAlliesLoop: - jumpifabsent BS_TARGET, BattleScript_CureStatusAlliesIncrement - jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_CureStatusActivate -BattleScript_CureStatusAlliesIncrement: - jumpifbytenotequal gBattlerTarget, gBattlerAttacker, BattleScript_CureStatusAlliesEnd - setallytonexttarget BattleScript_CureStatusAlliesLoop -BattleScript_CureStatusAlliesEnd: - restoretarget - goto BattleScript_MoveEnd - -BattleScript_CureStatusActivate: - curestatus BS_TARGET - updatestatusicon BS_TARGET - swapattackerwithtarget - printstring STRINGID_PKMNSTATUSNORMAL - waitmessage B_WAIT_TIME_LONG - swapattackerwithtarget - goto BattleScript_CureStatusAlliesIncrement - BattleScript_EffectRecycleBerriesAllies:: savetarget copybyte gBattlerTarget, gBattlerAttacker diff --git a/include/battle_scripts.h b/include/battle_scripts.h index a2cab790c31b..901d5d8c784e 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -554,7 +554,6 @@ extern const u8 BattleScript_EffectMeanLookSide[]; extern const u8 BattleScript_TormentEnds[]; extern const u8 BattleScript_EffectRaiseCritAlliesAnim[]; extern const u8 BattleScript_EffectHealOneSixthAllies[]; -extern const u8 BattleScript_EffectCureStatusAllies[]; extern const u8 BattleScript_EffectRecycleBerriesAllies[]; extern const u8 BattleScript_RemoveGenericType[]; @@ -644,6 +643,7 @@ extern const u8 BattleScript_EffectSleepTalk[]; extern const u8 BattleScript_EffectDestinyBond[]; extern const u8 BattleScript_EffectSpite[]; extern const u8 BattleScript_EffectHealBell[]; +extern const u8 BattleScript_EffectHealBell_FromHeal[]; extern const u8 BattleScript_EffectMeanLook[]; extern const u8 BattleScript_EffectNightmare[]; extern const u8 BattleScript_EffectMinimize[]; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index b0fe3281bf9b..460cccfb00f5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4623,7 +4623,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) break; case MOVE_EFFECT_AROMATHERAPY: BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_EffectCureStatusAllies; + gBattlescriptCurrInstr = BattleScript_EffectHealBell_FromHeal; break; case MOVE_EFFECT_RECYCLE_BERRIES: { diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index b2f659faa07f..40cbd28ae8a1 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -1376,10 +1376,15 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Finale heals allies by 1/6 of their health") DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions") { + u32 j; GIVEN { ASSUME(MoveHasAdditionalEffect(MOVE_G_MAX_SWEETNESS, MOVE_EFFECT_AROMATHERAPY)); PLAYER(SPECIES_APPLETUN) { Status1(STATUS1_POISON); GigantamaxFactor(TRUE); } PLAYER(SPECIES_APPLIN) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_APPLIN) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_APPLIN) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_APPLIN) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_APPLIN) { Status1(STATUS1_POISON); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -1387,9 +1392,12 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions") } SCENE { MESSAGE("Appletun used G-Max Sweetness!"); STATUS_ICON(playerLeft, none: TRUE); - MESSAGE("Appletun's status returned to normal!"); + //MESSAGE("Appletun's status returned to normal!"); STATUS_ICON(playerRight, none: TRUE); - MESSAGE("Applin's status returned to normal!"); + //MESSAGE("Applin's status returned to normal!"); + } THEN { + for (j = 0; j < PARTY_SIZE; j++) + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_STATUS), STATUS1_NONE); } } diff --git a/test/battle/move_effect_secondary/aromatherapy.c b/test/battle/move_effect_secondary/aromatherapy.c new file mode 100644 index 000000000000..6b7d7094c776 --- /dev/null +++ b/test/battle/move_effect_secondary/aromatherapy.c @@ -0,0 +1,34 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(MoveHasAdditionalEffect(MOVE_SPARKLY_SWIRL, MOVE_EFFECT_AROMATHERAPY)); +} + +DOUBLE_BATTLE_TEST("Sparkly Swirl cures the entire party") +{ + u32 j; + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } + OPPONENT(SPECIES_WYNAUT); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(playerLeft, MOVE_SPARKLY_SWIRL, target: playerLeft); } + TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); } + } SCENE { + MESSAGE("Wobbuffet used Sparkly Swirl!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPARKLY_SWIRL, playerLeft); + STATUS_ICON(playerLeft, sleep: FALSE); + STATUS_ICON(playerRight, sleep: FALSE); + NOT MESSAGE("Wobbuffet was hurt by its poisoning!"); + } THEN { + for (j = 0; j < PARTY_SIZE; j++) + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_STATUS), STATUS1_NONE); + } +} diff --git a/test/battle/sleep_clause.c b/test/battle/sleep_clause.c index 63fa6ce01efc..3416e43ce054 100644 --- a/test/battle/sleep_clause.c +++ b/test/battle/sleep_clause.c @@ -1147,7 +1147,7 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); MESSAGE("Wobbuffet fell asleep!"); MESSAGE("Appletun used G-Max Sweetness!"); - MESSAGE("Wobbuffet's status returned to normal!"); + //MESSAGE("Wobbuffet's status returned to normal!"); MESSAGE("The opposing Wobbuffet used Spore!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); From 4f4acc12b6c4233bc4cc8e4bf173f36e7136a56a Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Fri, 7 Feb 2025 13:25:14 -0300 Subject: [PATCH 3/5] Consolidate healpartystatus's conditions + improved tests --- src/battle_script_commands.c | 134 ++++++++---------- test/battle/gimmick/dynamax.c | 2 - test/battle/move_effect/heal_bell.c | 55 ++++--- .../move_effect_secondary/aromatherapy.c | 39 +++-- test/battle/sleep_clause.c | 1 - 5 files changed, 123 insertions(+), 108 deletions(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 460cccfb00f5..9612f5789029 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -13936,106 +13936,84 @@ static void Cmd_healpartystatus(void) { CMD_ARGS(); - u32 zero = 0; + u32 i, zero = 0; u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); u8 toHeal = 0; struct Pokemon *party = GetBattlerParty(gBattlerAttacker); - s32 i; + bool32 isSoundMove = IsSoundMove(gCurrentMove); - if (gCurrentMove == MOVE_HEAL_BELL) + if (B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8 + || !(isSoundMove && GetBattlerAbility(gBattlerAttacker) == ABILITY_SOUNDPROOF)) + { + if (isSoundMove) + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BELL; + else + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SOOTHING_AROMA; + gBattleMons[gBattlerAttacker].status1 = 0; + gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; + } + else { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BELL; + RecordAbilityBattle(gBattlerAttacker, gBattleMons[gBattlerAttacker].ability); + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BELL_SOUNDPROOF_ATTACKER; + } + + gBattleScripting.battler = partner; - if (GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF - || B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8) + if (IsBattlerAlive(partner)) + { + if (B_HEAL_BELL_SOUNDPROOF == GEN_5 || !(isSoundMove && GetBattlerAbility(partner) == ABILITY_SOUNDPROOF)) { - gBattleMons[gBattlerAttacker].status1 = 0; - gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; + gBattleMons[partner].status1 = 0; + gBattleMons[partner].status2 &= ~STATUS2_NIGHTMARE; } else { - RecordAbilityBattle(gBattlerAttacker, gBattleMons[gBattlerAttacker].ability); - gBattleCommunication[MULTISTRING_CHOOSER] |= B_MSG_BELL_SOUNDPROOF_ATTACKER; + RecordAbilityBattle(partner, gBattleMons[partner].ability); + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BELL_SOUNDPROOF_PARTNER; } + } - gBattleScripting.battler = partner; - - if (IsBattlerAlive(partner)) - { - if (GetBattlerAbility(partner) != ABILITY_SOUNDPROOF || B_HEAL_BELL_SOUNDPROOF == GEN_5) - { - gBattleMons[partner].status1 = 0; - gBattleMons[partner].status2 &= ~STATUS2_NIGHTMARE; - } - else - { - RecordAbilityBattle(partner, gBattleMons[partner].ability); - gBattleCommunication[MULTISTRING_CHOOSER] |= B_MSG_BELL_SOUNDPROOF_PARTNER; - } - } + // Because the above MULTISTRING_CHOOSER are ORd, if both are set then it will be B_MSG_BELL_BOTH_SOUNDPROOF - // Because the above MULTISTRING_CHOOSER are ORd, if both are set then it will be B_MSG_BELL_BOTH_SOUNDPROOF + for (i = 0; i < PARTY_SIZE; i++) + { + u16 species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG); + u8 abilityNum = GetMonData(&party[i], MON_DATA_ABILITY_NUM); - for (i = 0; i < PARTY_SIZE; i++) + if (species != SPECIES_NONE && species != SPECIES_EGG) { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG); - u8 abilityNum = GetMonData(&party[i], MON_DATA_ABILITY_NUM); + u16 ability; + bool32 isAttacker = gBattlerPartyIndexes[gBattlerAttacker] == i; + bool32 isDoublesPartner = gBattlerPartyIndexes[partner] == i && IsBattlerAlive(partner); - if (species != SPECIES_NONE && species != SPECIES_EGG) + if (B_HEAL_BELL_SOUNDPROOF == GEN_5 || (isAttacker && B_HEAL_BELL_SOUNDPROOF >= GEN_8)) + ability = ABILITY_NONE; + else if (B_HEAL_BELL_SOUNDPROOF > GEN_5 && !isAttacker && !isDoublesPartner) + ability = ABILITY_NONE; + else if (isAttacker) + ability = GetBattlerAbility(gBattlerAttacker); + else if (isDoublesPartner) + ability = GetBattlerAbility(partner); + else { - u16 ability; - bool32 isAttacker = gBattlerPartyIndexes[gBattlerAttacker] == i; - bool32 isDoublesPartner = gBattlerPartyIndexes[partner] == i && IsBattlerAlive(partner); - - if (B_HEAL_BELL_SOUNDPROOF == GEN_5 || (isAttacker && B_HEAL_BELL_SOUNDPROOF >= GEN_8)) - ability = ABILITY_NONE; - else if (B_HEAL_BELL_SOUNDPROOF > GEN_5 && !isAttacker && !isDoublesPartner) - ability = ABILITY_NONE; - else if (isAttacker) - ability = GetBattlerAbility(gBattlerAttacker); - else if (isDoublesPartner) - ability = GetBattlerAbility(partner); - else + ability = GetAbilityBySpecies(species, abilityNum); + #if TESTING + if (gTestRunnerEnabled) { - ability = GetAbilityBySpecies(species, abilityNum); - #if TESTING - if (gTestRunnerEnabled) - { - u32 side = GetBattlerSide(gBattlerAttacker); - if (TestRunner_Battle_GetForcedAbility(side, i)) - ability = TestRunner_Battle_GetForcedAbility(side, i); - } - #endif - } - - if (ability != ABILITY_SOUNDPROOF) - { - toHeal |= (1 << i); - TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), i); + u32 side = GetBattlerSide(gBattlerAttacker); + if (TestRunner_Battle_GetForcedAbility(side, i)) + ability = TestRunner_Battle_GetForcedAbility(side, i); } + #endif } - } - } - else // Aromatherapy - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SOOTHING_AROMA; - toHeal = (1 << PARTY_SIZE) - 1; - for (i = 0; i < PARTY_SIZE; i++) - { - TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), i); - } - - gBattleMons[gBattlerAttacker].status1 = 0; - gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; - - if (IsDoubleBattle() - && !(gAbsentBattlerFlags & (1u <= GEN_5); GIVEN { + ASSUME(IsSoundMove(MOVE_HEAL_BELL)); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } PLAYER(SPECIES_EXPLOUD) { Ability(ability); Status1(STATUS1_POISON); } OPPONENT(SPECIES_WYNAUT); @@ -89,6 +111,7 @@ SINGLE_BATTLE_TEST("Heal Bell cures inactive soundproof Pokemon") SINGLE_BATTLE_TEST("Heal Bell cures a soundproof user") { GIVEN { + ASSUME(IsSoundMove(MOVE_HEAL_BELL)); ASSUME(B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8); PLAYER(SPECIES_EXPLOUD) { Ability(ABILITY_SOUNDPROOF); Status1(STATUS1_POISON); } OPPONENT(SPECIES_WYNAUT); diff --git a/test/battle/move_effect_secondary/aromatherapy.c b/test/battle/move_effect_secondary/aromatherapy.c index 6b7d7094c776..9f1e82ba2d85 100644 --- a/test/battle/move_effect_secondary/aromatherapy.c +++ b/test/battle/move_effect_secondary/aromatherapy.c @@ -6,27 +6,44 @@ ASSUMPTIONS ASSUME(MoveHasAdditionalEffect(MOVE_SPARKLY_SWIRL, MOVE_EFFECT_AROMATHERAPY)); } -DOUBLE_BATTLE_TEST("Sparkly Swirl cures the entire party") +DOUBLE_BATTLE_TEST("Sparkly Swirl cures the entire party of the user from primary status effects") { u32 j; + u32 status; + PARAMETRIZE { status = STATUS1_SLEEP; } + PARAMETRIZE { status = STATUS1_POISON; } + PARAMETRIZE { status = STATUS1_BURN; } + PARAMETRIZE { status = STATUS1_FREEZE; } + PARAMETRIZE { status = STATUS1_PARALYSIS; } + PARAMETRIZE { status = STATUS1_TOXIC_POISON; } + PARAMETRIZE { status = STATUS1_FROSTBITE; } GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } - PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } - PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } - PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } - PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } - PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } + PLAYER(SPECIES_WOBBUFFET) { + if (status != STATUS1_SLEEP && status != STATUS1_FREEZE) + Status1(status); + } + PLAYER(SPECIES_WOBBUFFET) { Status1(status); } + PLAYER(SPECIES_WOBBUFFET) { Status1(status); } + PLAYER(SPECIES_WOBBUFFET) { Status1(status); } + PLAYER(SPECIES_WOBBUFFET) { Status1(status); } + PLAYER(SPECIES_WOBBUFFET) { Status1(status); } OPPONENT(SPECIES_WYNAUT); OPPONENT(SPECIES_WYNAUT); } WHEN { - TURN { MOVE(playerLeft, MOVE_SPARKLY_SWIRL, target: playerLeft); } + TURN { MOVE(playerLeft, MOVE_SPARKLY_SWIRL, target: opponentLeft); } TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); } } SCENE { MESSAGE("Wobbuffet used Sparkly Swirl!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_SPARKLY_SWIRL, playerLeft); - STATUS_ICON(playerLeft, sleep: FALSE); - STATUS_ICON(playerRight, sleep: FALSE); - NOT MESSAGE("Wobbuffet was hurt by its poisoning!"); + switch(status) + { + case STATUS1_SLEEP: STATUS_ICON(playerLeft, sleep: FALSE); STATUS_ICON(playerRight, sleep: FALSE); break; + case STATUS1_POISON: STATUS_ICON(playerLeft, poison: FALSE); STATUS_ICON(playerRight, poison: FALSE); break; + case STATUS1_BURN: STATUS_ICON(playerLeft, burn: FALSE); STATUS_ICON(playerRight, burn: FALSE); break; + case STATUS1_PARALYSIS: STATUS_ICON(playerLeft, paralysis: FALSE); STATUS_ICON(playerRight, paralysis: FALSE); break; + case STATUS1_TOXIC_POISON: STATUS_ICON(playerLeft, badPoison: FALSE); STATUS_ICON(playerRight, badPoison: FALSE); break; + case STATUS1_FROSTBITE: STATUS_ICON(playerLeft, frostbite: FALSE); STATUS_ICON(playerRight, frostbite: FALSE); break; + } } THEN { for (j = 0; j < PARTY_SIZE; j++) EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_STATUS), STATUS1_NONE); diff --git a/test/battle/sleep_clause.c b/test/battle/sleep_clause.c index 3416e43ce054..7537fb437abd 100644 --- a/test/battle/sleep_clause.c +++ b/test/battle/sleep_clause.c @@ -1147,7 +1147,6 @@ DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mo ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); MESSAGE("Wobbuffet fell asleep!"); MESSAGE("Appletun used G-Max Sweetness!"); - //MESSAGE("Wobbuffet's status returned to normal!"); MESSAGE("The opposing Wobbuffet used Spore!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight); From d20ac3ad6302c1243d21649299f4f2cc7a366e4b Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Fri, 7 Feb 2025 14:34:19 -0300 Subject: [PATCH 4/5] Generational checks in Heal Bell tests --- include/battle.h | 1 + include/constants/generational_changes.h | 1 + include/generational_changes.h | 3 +- src/battle_ai_util.c | 11 ++++-- src/battle_main.c | 1 - src/battle_script_commands.c | 11 ++++-- test/battle/ai/ai_check_viability.c | 13 ++++--- test/battle/move_effect/heal_bell.c | 48 +++++++++++++++--------- 8 files changed, 57 insertions(+), 32 deletions(-) diff --git a/include/battle.h b/include/battle.h index e417d176b8ed..be55936b12fe 100644 --- a/include/battle.h +++ b/include/battle.h @@ -17,6 +17,7 @@ #include "battle_dynamax.h" #include "battle_terastal.h" #include "battle_gimmick.h" +#include "generational_changes.h" #include "move.h" #include "random.h" // for rng_value_t #include "trainer_slide.h" diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h index 557b34b6537e..370853b73d9a 100644 --- a/include/constants/generational_changes.h +++ b/include/constants/generational_changes.h @@ -4,6 +4,7 @@ enum GenConfigTag { GEN_CONFIG_GALE_WINGS, + GEN_CONFIG_HEAL_BELL_SOUNDPROOF, GEN_CONFIG_COUNT }; diff --git a/include/generational_changes.h b/include/generational_changes.h index 5a726007c36e..c517357c158d 100644 --- a/include/generational_changes.h +++ b/include/generational_changes.h @@ -6,7 +6,8 @@ static const u8 sGenerationalChanges[GEN_CONFIG_COUNT] = { - [GEN_CONFIG_GALE_WINGS] = B_GALE_WINGS, + [GEN_CONFIG_GALE_WINGS] = B_GALE_WINGS, + [GEN_CONFIG_HEAL_BELL_SOUNDPROOF] = B_HEAL_BELL_SOUNDPROOF, }; #if TESTING diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index a516093a040d..335035bdfb0b 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -3160,7 +3160,9 @@ bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof) battlerOnField1 = gBattlerPartyIndexes[battlerId]; battlerOnField2 = gBattlerPartyIndexes[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battlerId)))]; // Check partner's status - if ((B_HEAL_BELL_SOUNDPROOF == GEN_5 || AI_DATA->abilities[BATTLE_PARTNER(battlerId)] != ABILITY_SOUNDPROOF || !checkSoundproof) + if ((GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5 + || AI_DATA->abilities[BATTLE_PARTNER(battlerId)] != ABILITY_SOUNDPROOF + || !checkSoundproof) && GetMonData(&party[battlerOnField2], MON_DATA_STATUS) != STATUS1_NONE) return TRUE; } @@ -3171,7 +3173,8 @@ bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof) } // Check attacker's status - if ((B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8 + if ((GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5 + || GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) >= GEN_8 || AI_DATA->abilities[battlerId] != ABILITY_SOUNDPROOF || !checkSoundproof) && GetMonData(&party[battlerOnField1], MON_DATA_STATUS) != STATUS1_NONE) return TRUE; @@ -3181,7 +3184,9 @@ bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof) { if (i == battlerOnField1 || i == battlerOnField2) continue; - if (B_HEAL_BELL_SOUNDPROOF < GEN_5 && checkSoundproof && GetMonAbility(&party[i]) == ABILITY_SOUNDPROOF) + if (GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) < GEN_5 + && checkSoundproof + && GetMonAbility(&party[i]) == ABILITY_SOUNDPROOF) continue; if (GetMonData(&party[i], MON_DATA_STATUS) != STATUS1_NONE) return TRUE; diff --git a/src/battle_main.c b/src/battle_main.c index 6e51a4d69f04..5d16f5c3bced 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -25,7 +25,6 @@ #include "event_data.h" #include "evolution_scene.h" #include "field_weather.h" -#include "generational_changes.h" #include "graphics.h" #include "gpu_regs.h" #include "international_string_util.h" diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 9612f5789029..2408df57ad71 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -13942,7 +13942,8 @@ static void Cmd_healpartystatus(void) struct Pokemon *party = GetBattlerParty(gBattlerAttacker); bool32 isSoundMove = IsSoundMove(gCurrentMove); - if (B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8 + if (GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5 + || GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) >= GEN_8 || !(isSoundMove && GetBattlerAbility(gBattlerAttacker) == ABILITY_SOUNDPROOF)) { if (isSoundMove) @@ -13962,7 +13963,8 @@ static void Cmd_healpartystatus(void) if (IsBattlerAlive(partner)) { - if (B_HEAL_BELL_SOUNDPROOF == GEN_5 || !(isSoundMove && GetBattlerAbility(partner) == ABILITY_SOUNDPROOF)) + if (GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5 + || !(isSoundMove && GetBattlerAbility(partner) == ABILITY_SOUNDPROOF)) { gBattleMons[partner].status1 = 0; gBattleMons[partner].status2 &= ~STATUS2_NIGHTMARE; @@ -13987,9 +13989,10 @@ static void Cmd_healpartystatus(void) bool32 isAttacker = gBattlerPartyIndexes[gBattlerAttacker] == i; bool32 isDoublesPartner = gBattlerPartyIndexes[partner] == i && IsBattlerAlive(partner); - if (B_HEAL_BELL_SOUNDPROOF == GEN_5 || (isAttacker && B_HEAL_BELL_SOUNDPROOF >= GEN_8)) + if (GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) == GEN_5 + || (GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) >= GEN_8 && isAttacker)) ability = ABILITY_NONE; - else if (B_HEAL_BELL_SOUNDPROOF > GEN_5 && !isAttacker && !isDoublesPartner) + else if (GetGenConfig(GEN_CONFIG_HEAL_BELL_SOUNDPROOF) > GEN_5 && !isAttacker && !isDoublesPartner) ability = ABILITY_NONE; else if (isAttacker) ability = GetBattlerAbility(gBattlerAttacker); diff --git a/test/battle/ai/ai_check_viability.c b/test/battle/ai/ai_check_viability.c index 35f74d43c098..0e9377fdeac8 100644 --- a/test/battle/ai/ai_check_viability.c +++ b/test/battle/ai/ai_check_viability.c @@ -203,7 +203,7 @@ AI_DOUBLE_BATTLE_TEST("AI chooses moves that cure self or partner") GIVEN { ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL); - ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_8); + WITH_CONFIG(GEN_CONFIG_HEAL_BELL_SOUNDPROOF, GEN_8); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -219,21 +219,22 @@ AI_DOUBLE_BATTLE_TEST("AI chooses moves that cure self or partner") AI_SINGLE_BATTLE_TEST("AI chooses moves that cure inactive party members") { - u32 status, ability; + u32 status, ability, config; PARAMETRIZE { status = STATUS1_TOXIC_POISON; ability = ABILITY_SCRAPPY; } - PARAMETRIZE { status = STATUS1_NONE; ability = ABILITY_SCRAPPY; } - PARAMETRIZE { status = STATUS1_TOXIC_POISON; ability = ABILITY_SOUNDPROOF; } + PARAMETRIZE { status = STATUS1_NONE; ability = ABILITY_SCRAPPY; } + PARAMETRIZE { status = STATUS1_TOXIC_POISON; ability = ABILITY_SOUNDPROOF; config = GEN_4; } + PARAMETRIZE { status = STATUS1_TOXIC_POISON; ability = ABILITY_SOUNDPROOF; config = GEN_5; } GIVEN { ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL); - ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_5); + WITH_CONFIG(GEN_CONFIG_HEAL_BELL_SOUNDPROOF, config); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_REGIROCK) { Moves(MOVE_BODY_PRESS, MOVE_HEAL_BELL); } OPPONENT(SPECIES_EXPLOUD) { Status1(status); Ability(ability); } } WHEN { - if (status == STATUS1_NONE) + if (status == STATUS1_NONE || (ability == ABILITY_SOUNDPROOF && config <= GEN_4)) TURN { EXPECT_MOVE(opponent, MOVE_BODY_PRESS); } else TURN { EXPECT_MOVE(opponent, MOVE_HEAL_BELL); } diff --git a/test/battle/move_effect/heal_bell.c b/test/battle/move_effect/heal_bell.c index eefe0d88d739..7730879d4542 100644 --- a/test/battle/move_effect/heal_bell.c +++ b/test/battle/move_effect/heal_bell.c @@ -56,17 +56,18 @@ DOUBLE_BATTLE_TEST("Heal Bell/Aromatherapy cures the entire party of the user fr } } -DOUBLE_BATTLE_TEST("Heal Bell does not cure soundproof partners") +DOUBLE_BATTLE_TEST("Heal Bell does not cure Soundproof partners (Gen 4, Gen 6+)") { - u32 ability; + u32 ability, config; - PARAMETRIZE { ability = ABILITY_SCRAPPY; } - PARAMETRIZE { ability = ABILITY_SOUNDPROOF; } - - ASSUME(B_HEAL_BELL_SOUNDPROOF != GEN_5); + PARAMETRIZE { ability = ABILITY_SCRAPPY; config = GEN_4; } + PARAMETRIZE { ability = ABILITY_SOUNDPROOF; config = GEN_4; } + PARAMETRIZE { ability = ABILITY_SOUNDPROOF; config = GEN_5; } + PARAMETRIZE { ability = ABILITY_SOUNDPROOF; config = GEN_6; } GIVEN { ASSUME(IsSoundMove(MOVE_HEAL_BELL)); + WITH_CONFIG(GEN_CONFIG_HEAL_BELL_SOUNDPROOF, config); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_EXPLOUD) { Ability(ability); Status1(STATUS1_POISON); } OPPONENT(SPECIES_WYNAUT); @@ -75,7 +76,7 @@ DOUBLE_BATTLE_TEST("Heal Bell does not cure soundproof partners") TURN { MOVE(playerLeft, MOVE_HEAL_BELL, target: playerLeft); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BELL, playerLeft); - if (ability == ABILITY_SOUNDPROOF) { + if (ability == ABILITY_SOUNDPROOF && config != GEN_5) { MESSAGE("Exploud was hurt by its poisoning!"); } else { NOT MESSAGE("Exploud was hurt by its poisoning!"); @@ -83,17 +84,17 @@ DOUBLE_BATTLE_TEST("Heal Bell does not cure soundproof partners") } } -SINGLE_BATTLE_TEST("Heal Bell cures inactive soundproof Pokemon") +SINGLE_BATTLE_TEST("Heal Bell cures inactive Soundproof Pokemon (Gen5+)") { - u32 ability; - - PARAMETRIZE { ability = ABILITY_SCRAPPY; } - PARAMETRIZE { ability = ABILITY_SOUNDPROOF; } + u32 config, ability; - ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_5); + PARAMETRIZE { config = GEN_4, ability = ABILITY_SCRAPPY; } + PARAMETRIZE { config = GEN_4, ability = ABILITY_SOUNDPROOF; } + PARAMETRIZE { config = GEN_5, ability = ABILITY_SOUNDPROOF; } GIVEN { ASSUME(IsSoundMove(MOVE_HEAL_BELL)); + WITH_CONFIG(GEN_CONFIG_HEAL_BELL_SOUNDPROOF, config); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_POISON); } PLAYER(SPECIES_EXPLOUD) { Ability(ability); Status1(STATUS1_POISON); } OPPONENT(SPECIES_WYNAUT); @@ -103,22 +104,35 @@ SINGLE_BATTLE_TEST("Heal Bell cures inactive soundproof Pokemon") } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BELL, player); SEND_IN_MESSAGE("Exploud"); - NOT MESSAGE("Exploud was hurt by its poisoning!"); + if (ability == ABILITY_SCRAPPY || config >= GEN_5) { + NOT MESSAGE("Exploud was hurt by its poisoning!"); + } else { + MESSAGE("Exploud was hurt by its poisoning!"); + } } } -SINGLE_BATTLE_TEST("Heal Bell cures a soundproof user") +SINGLE_BATTLE_TEST("Heal Bell cures a Soundproof user (Gen5, Gen8+)") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } + PARAMETRIZE { config = GEN_6; } + PARAMETRIZE { config = GEN_8; } GIVEN { ASSUME(IsSoundMove(MOVE_HEAL_BELL)); - ASSUME(B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8); + WITH_CONFIG(GEN_CONFIG_HEAL_BELL_SOUNDPROOF, config); PLAYER(SPECIES_EXPLOUD) { Ability(ABILITY_SOUNDPROOF); Status1(STATUS1_POISON); } OPPONENT(SPECIES_WYNAUT); } WHEN { TURN { MOVE(player, MOVE_HEAL_BELL, target: player); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BELL, player); - NOT MESSAGE("Exploud was hurt by its poisoning!"); + if (config == GEN_5 || config >= GEN_8) { + NOT MESSAGE("Exploud was hurt by its poisoning!"); + } else { + MESSAGE("Exploud was hurt by its poisoning!"); + } } } From 129df4b38db2585eb681002f27b10017047fe93f Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Fri, 7 Feb 2025 14:49:56 -0300 Subject: [PATCH 5/5] Removed last harcoded Heal Bell --- data/battle_scripts_1.s | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index b6831e512edd..3827982058c0 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -4073,7 +4073,9 @@ BattleScript_EffectHealBell_FromHeal:: waitstate printfromtable gPartyStatusHealStringIds waitmessage B_WAIT_TIME_LONG - jumpifnotmove MOVE_HEAL_BELL, BattleScript_PartyHealEnd + jumpifblockedbysoundproof BS_ATTACKER_PARTNER, BattleScript_HealBellSoundproof + goto BattleScript_PartyHealEnd +BattleScript_HealBellSoundproof:: jumpifbyte CMP_NO_COMMON_BITS, cMULTISTRING_CHOOSER, B_MSG_BELL_SOUNDPROOF_ATTACKER, BattleScript_CheckHealBellMon2Unaffected printstring STRINGID_PKMNSXBLOCKSY waitmessage B_WAIT_TIME_LONG