diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 91b9ae523c..df4e00fb19 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1447,10 +1447,6 @@ callnative BS_SetGlaiveRush .endm - .macro tryrelicsong - callnative BS_TryRelicSong - .endm - .macro setpledge jumpInstr:req callnative BS_SetPledge .4byte \jumpInstr diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 2d1999464b..51ba648943 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1094,13 +1094,6 @@ BattleScript_JungleHealingTryRestoreAlly: setallytonexttarget JungleHealing_RestoreTargetHealth goto BattleScript_MoveEnd -BattleScript_EffectRelicSong:: - call BattleScript_EffectHit_Ret - tryfaintmon BS_TARGET - moveendall - tryrelicsong - end - BattleScript_EffectAllySwitch:: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 315c2939e1..d4cb6dfb8a 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -819,7 +819,6 @@ extern const u8 BattleScript_EffectShoreUp[]; extern const u8 BattleScript_EffectGeomancy[]; extern const u8 BattleScript_EffectFairyLock[]; extern const u8 BattleScript_EffectAllySwitch[]; -extern const u8 BattleScript_EffectRelicSong[]; extern const u8 BattleScript_MoveEffectEerieSpell[]; extern const u8 BattleScript_EffectJungleHealing[]; extern const u8 BattleScript_EffectCoaching[]; diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index fdd256740e..f9063c5717 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -281,7 +281,6 @@ enum BattleMoveEffects EFFECT_GEOMANCY, EFFECT_FAIRY_LOCK, EFFECT_ALLY_SWITCH, - EFFECT_RELIC_SONG, EFFECT_BODY_PRESS, EFFECT_JUNGLE_HEALING, EFFECT_COACHING, diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 2fcc0d4d58..e08a6dc239 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -277,6 +277,7 @@ enum MoveEndEffects MOVEEND_RED_CARD, // Red Card triggers before Eject Pack MOVEEND_EJECT_BUTTON, MOVEEND_LIFEORB_SHELLBELL, // Includes shell bell, throat spray, etc + MOVEEND_FORM_CHANGE, MOVEEND_EMERGENCY_EXIT, MOVEEND_EJECT_PACK, MOVEEND_HIT_ESCAPE, diff --git a/include/constants/form_change_types.h b/include/constants/form_change_types.h index 85aa27c75b..aef60b593d 100644 --- a/include/constants/form_change_types.h +++ b/include/constants/form_change_types.h @@ -126,6 +126,9 @@ enum FormChanges // param1: move to check // param2: ability to check, optional FORM_CHANGE_BATTLE_BEFORE_MOVE, + // Form change that activates after using a move. + // param1: move to check + FORM_CHANGE_BATTLE_AFTER_MOVE, // Form change that activates before using a specific move category. // param1: move category to check // param2: ability to check, optional diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a1a0814253..a6b76ac213 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7247,6 +7247,14 @@ static void Cmd_moveend(void) } gBattleScripting.moveendState++; break; + case MOVEEND_FORM_CHANGE: + if (TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_AFTER_MOVE)) + { + effect = TRUE; + BattleScriptCall(BattleScript_AttackerFormChangeMoveEffect); + } + gBattleScripting.moveendState++; + break; case MOVEEND_EMERGENCY_EXIT: // Special case, because moves hitting multiple opponents stop after switching out { // Because sorting the battlers by speed takes lots of cycles, @@ -17358,28 +17366,6 @@ void BS_SetGlaiveRush(void) gBattlescriptCurrInstr = cmd->nextInstr; } -// TODO: Convert this to a proper FORM_CHANGE type. -void BS_TryRelicSong(void) -{ - NATIVE_ARGS(); - - if (GetBattlerAbility(gBattlerAttacker) != ABILITY_SHEER_FORCE && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED) - && (gBattleMons[gBattlerAttacker].species == SPECIES_MELOETTA_ARIA || gBattleMons[gBattlerAttacker].species == SPECIES_MELOETTA_PIROUETTE)) - { - if (gBattleMons[gBattlerAttacker].species == SPECIES_MELOETTA_ARIA) - gBattleMons[gBattlerAttacker].species = SPECIES_MELOETTA_PIROUETTE; - else if (gBattleMons[gBattlerAttacker].species == SPECIES_MELOETTA_PIROUETTE) - gBattleMons[gBattlerAttacker].species = SPECIES_MELOETTA_ARIA; - - BattleScriptPush(cmd->nextInstr); - gBattlescriptCurrInstr = BattleScript_AttackerFormChangeMoveEffect; - } - else - { - gBattlescriptCurrInstr = cmd->nextInstr; - } -} - void BS_SetPledge(void) { NATIVE_ARGS(const u8 *jumpInstr); diff --git a/src/battle_util.c b/src/battle_util.c index a3367e27b5..09c021cebb 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -10052,6 +10052,7 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, enum FormChanges method) targetSpecies = formChanges[i].targetSpecies; break; case FORM_CHANGE_BATTLE_BEFORE_MOVE: + case FORM_CHANGE_BATTLE_AFTER_MOVE: if (formChanges[i].param1 == gCurrentMove && (formChanges[i].param2 == ABILITY_NONE || formChanges[i].param2 == GetBattlerAbility(battler))) targetSpecies = formChanges[i].targetSpecies; diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index bd757914e5..578444a380 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -1798,12 +1798,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = .battleTvScore = 0, // TODO: Assign points }, - [EFFECT_RELIC_SONG] = - { - .battleScript = BattleScript_EffectRelicSong, - .battleTvScore = 0, // TODO: Assign points - }, - [EFFECT_BODY_PRESS] = { .battleScript = BattleScript_EffectHit, diff --git a/src/data/moves_info.h b/src/data/moves_info.h index 0a34c5672f..836b9e5466 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -13993,7 +13993,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .description = COMPOUND_STRING( "Attacks with an ancient\n" "song. May induce sleep."), - .effect = EFFECT_RELIC_SONG, + .effect = EFFECT_HIT, .power = 75, .type = TYPE_NORMAL, .accuracy = 100, diff --git a/src/data/pokemon/form_change_tables.h b/src/data/pokemon/form_change_tables.h index a17a432834..ed80ae2178 100644 --- a/src/data/pokemon/form_change_tables.h +++ b/src/data/pokemon/form_change_tables.h @@ -771,15 +771,17 @@ static const struct FormChange sKeldeoFormChangeTable[] = { #if P_FAMILY_MELOETTA static const struct FormChange sMeloettaFormChangeTable[] = { - {FORM_CHANGE_FAINT, SPECIES_MELOETTA_ARIA}, - {FORM_CHANGE_END_BATTLE, SPECIES_MELOETTA_ARIA}, + {FORM_CHANGE_BATTLE_AFTER_MOVE, SPECIES_MELOETTA_PIROUETTE, MOVE_RELIC_SONG}, + {FORM_CHANGE_BATTLE_AFTER_MOVE, SPECIES_MELOETTA_ARIA, MOVE_RELIC_SONG}, + {FORM_CHANGE_FAINT, SPECIES_MELOETTA_ARIA}, + {FORM_CHANGE_END_BATTLE, SPECIES_MELOETTA_ARIA}, {FORM_CHANGE_TERMINATOR}, }; #endif //P_FAMILY_MELOETTA #if P_FAMILY_GENESECT static const struct FormChange sGenesectFormChangeTable[] = { - {FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT, ITEM_NONE}, + {FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT, ITEM_NONE}, {FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT_DOUSE, ITEM_DOUSE_DRIVE}, {FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT_SHOCK, ITEM_SHOCK_DRIVE}, {FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT_BURN, ITEM_BURN_DRIVE}, diff --git a/test/battle/move_effect/relic_song.c b/test/battle/form_change/battle_after_move.c similarity index 66% rename from test/battle/move_effect/relic_song.c rename to test/battle/form_change/battle_after_move.c index f1e7fae92f..2dc9d95a15 100644 --- a/test/battle/move_effect/relic_song.c +++ b/test/battle/form_change/battle_after_move.c @@ -1,74 +1,6 @@ #include "global.h" #include "test/battle.h" -ASSUMPTIONS -{ - ASSUME(GetMoveEffect(MOVE_RELIC_SONG) == EFFECT_RELIC_SONG); - ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP) == TRUE); -} - -SINGLE_BATTLE_TEST("Relic Song has a 10% chance to put the target to sleep") -{ - PASSES_RANDOMLY(10, 100, RNG_SECONDARY_EFFECT); - GIVEN { - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_RELIC_SONG); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); - HP_BAR(opponent); - ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); - STATUS_ICON(opponent, sleep: TRUE); - } -} - -SINGLE_BATTLE_TEST("Relic Song is prevented by Soundproof") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_VOLTORB) { Ability(ABILITY_SOUNDPROOF); } - } WHEN { - TURN { MOVE(player, MOVE_RELIC_SONG); } - } SCENE { - ABILITY_POPUP(opponent, ABILITY_SOUNDPROOF); - MESSAGE("The opposing Voltorb's Soundproof blocks Relic Song!"); - NONE_OF { - ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); - HP_BAR(opponent); - } - } -} - -SINGLE_BATTLE_TEST("Relic Song will become a Water-type move when used by a Pokémon with the Ability Liquid Voice") -{ - GIVEN { - PLAYER(SPECIES_VULPIX); - OPPONENT(SPECIES_POPPLIO) { Ability(ABILITY_LIQUID_VOICE); } - } WHEN { - TURN { MOVE(opponent, MOVE_RELIC_SONG); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, opponent); - HP_BAR(player); - MESSAGE("It's super effective!"); - } -} - -SINGLE_BATTLE_TEST("Relic Song is blocked by Throat Chop") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(opponent, MOVE_THROAT_CHOP); MOVE(player, MOVE_RELIC_SONG); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_THROAT_CHOP, opponent); - HP_BAR(player); - MESSAGE("The effects of Throat Chop prevent Wobbuffet from using certain moves!"); - NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); - } -} - SINGLE_BATTLE_TEST("Relic Song transforms Meloetta if used successfully") { GIVEN { diff --git a/test/battle/move_effects_combined/relic_song.c b/test/battle/move_effects_combined/relic_song.c new file mode 100644 index 0000000000..dec92f069e --- /dev/null +++ b/test/battle/move_effects_combined/relic_song.c @@ -0,0 +1,69 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP) == TRUE); +} + +SINGLE_BATTLE_TEST("Relic Song has a 10% chance to put the target to sleep") +{ + PASSES_RANDOMLY(10, 100, RNG_SECONDARY_EFFECT); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_RELIC_SONG); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + STATUS_ICON(opponent, sleep: TRUE); + } +} + +SINGLE_BATTLE_TEST("Relic Song is prevented by Soundproof") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_VOLTORB) { Ability(ABILITY_SOUNDPROOF); } + } WHEN { + TURN { MOVE(player, MOVE_RELIC_SONG); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_SOUNDPROOF); + MESSAGE("The opposing Voltorb's Soundproof blocks Relic Song!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); + HP_BAR(opponent); + } + } +} + +SINGLE_BATTLE_TEST("Relic Song will become a Water-type move when used by a Pokémon with the Ability Liquid Voice") +{ + GIVEN { + PLAYER(SPECIES_VULPIX); + OPPONENT(SPECIES_POPPLIO) { Ability(ABILITY_LIQUID_VOICE); } + } WHEN { + TURN { MOVE(opponent, MOVE_RELIC_SONG); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, opponent); + HP_BAR(player); + MESSAGE("It's super effective!"); + } +} + +SINGLE_BATTLE_TEST("Relic Song is blocked by Throat Chop") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_THROAT_CHOP); MOVE(player, MOVE_RELIC_SONG); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_THROAT_CHOP, opponent); + HP_BAR(player); + MESSAGE("The effects of Throat Chop prevent Wobbuffet from using certain moves!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player); + } +}