From 35e76e9868b955ae55760a2a860bce37f69e9dbe Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Sun, 24 Sep 2023 00:01:18 -0300 Subject: [PATCH] Fixed Ice Spinner, refactored battle terrain text string tables and ditched EFFECT_REMOVE_TERRAIN (#3247) Co-authored-by: Alex --- asm/macros/battle_script.inc | 29 +- data/battle_scripts_1.s | 61 +++-- include/constants/battle_move_effects.h | 103 ++++---- include/constants/battle_script_commands.h | 247 +++++++++--------- include/constants/battle_string_ids.h | 99 +++---- src/battle_message.c | 19 +- src/battle_script_commands.c | 178 +++++++------ src/battle_tv.c | 1 - src/battle_util.c | 8 +- src/data/battle_moves.h | 9 +- .../move_effect/hit_set_remove_terrain.c | 84 ++++++ 11 files changed, 469 insertions(+), 369 deletions(-) create mode 100644 test/battle/move_effect/hit_set_remove_terrain.c diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 4b6cc0961..1fd843e4b 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1382,6 +1382,24 @@ .4byte \ptr .endm + .macro jumpifargument argument:req, jumpInstr:req + callnative BS_JumpIfArgument + .byte \argument + .4byte \jumpInstr + .endm + + .macro setremoveterrain failInstr:req + callnative BS_SetRemoveTerrain + .4byte \failInstr + .endm + + .macro jumpifterrainaffected battler:req, terrainFlags:req, jumpInstr:req + callnative BS_JumpIfTerrainAffected + .byte \battler + .4byte \terrainFlags + .4byte \jumpInstr + .endm + @ various command changed to more readable macros .macro cancelmultiturnmoves battler:req various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES @@ -1597,11 +1615,6 @@ various \battler, VARIOUS_INVERT_STAT_STAGES .endm - .macro setterrain failInstr:req - various BS_ATTACKER, VARIOUS_SET_TERRAIN - .4byte \failInstr - .endm - .macro trymefirst failInstr:req various BS_ATTACKER, VARIOUS_TRY_ME_FIRST .4byte \failInstr @@ -1894,12 +1907,6 @@ .4byte \failInstr .endm - .macro jumpifterrainaffected battler:req, terrainFlags:req, jumpInstr:req - various \battler, VARIOUS_JUMP_IF_TERRAIN_AFFECTED - .4byte \terrainFlags - .4byte \jumpInstr - .endm - .macro jumpifpranksterblocked battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_PRANKSTER_BLOCKED .4byte \jumpInstr diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 2b3803ab9..76b873aaf 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -377,7 +377,6 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectCoaching @ EFFECT_COACHING .4byte BattleScript_EffectHit @ EFFECT_LASH_OUT .4byte BattleScript_EffectHit @ EFFECT_GRASSY_GLIDE - .4byte BattleScript_EffectRemoveTerrain @ EFFECT_REMOVE_TERRAIN .4byte BattleScript_EffectHit @ EFFECT_DYNAMAX_DOUBLE_DMG .4byte BattleScript_EffectDecorate @ EFFECT_DECORATE .4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT @@ -1245,33 +1244,6 @@ BattleScript_DecorateBoostSpAtk: waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd -BattleScript_EffectRemoveTerrain: - attackcanceler - attackstring - ppreduce - jumpifword CMP_NO_COMMON_BITS, gFieldStatuses, STATUS_FIELD_TERRAIN_ANY, BattleScript_ButItFailed - critcalc - damagecalc - adjustdamage - attackanimation - waitanimation - effectivenesssound - hitanimation BS_TARGET - waitstate - healthbarupdate BS_TARGET - datahpupdate BS_TARGET - critmessage - waitmessage B_WAIT_TIME_LONG - resultmessage - waitmessage B_WAIT_TIME_LONG - removeterrain - jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_TERRAINENDS_COUNT, BattleScript_MoveEnd - printfromtable gTerrainEndingStringIds - waitmessage B_WAIT_TIME_LONG - playanimation BS_ATTACKER, B_ANIM_RESTORE_BG - tryfaintmon BS_TARGET - goto BattleScript_MoveEnd - BattleScript_EffectCoaching: attackcanceler attackstring @@ -2582,7 +2554,7 @@ BattleScript_EffectPsychicTerrain: attackcanceler attackstring ppreduce - setterrain BattleScript_ButItFailed + setremoveterrain BattleScript_ButItFailed attackanimation waitanimation printfromtable gTerrainStringIds @@ -6874,7 +6846,7 @@ BattleScript_MagicRoomEnds:: end2 BattleScript_TerrainEnds_Ret:: - printfromtable gTerrainEndingStringIds + printfromtable gTerrainStringIds waitmessage B_WAIT_TIME_LONG playanimation BS_ATTACKER, B_ANIM_RESTORE_BG return @@ -10157,6 +10129,7 @@ BattleScript_EffectHitSetRemoveTerrain: accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce + jumpifargument ARG_TRY_REMOVE_TERRAIN_FAIL, BattleScript_RemoveTerrain critcalc damagecalc adjustdamage @@ -10171,13 +10144,39 @@ BattleScript_EffectHitSetRemoveTerrain: waitmessage B_WAIT_TIME_LONG resultmessage waitmessage B_WAIT_TIME_LONG - setterrain BattleScript_TryFaint + setremoveterrain BattleScript_TryFaint playanimation BS_ATTACKER, B_ANIM_RESTORE_BG printfromtable gTerrainStringIds + waitmessage B_WAIT_TIME_LONG BattleScript_TryFaint: tryfaintmon BS_TARGET goto BattleScript_MoveEnd +BattleScript_RemoveTerrain: + jumpifterrainaffected BS_TARGET, STATUS_FIELD_TERRAIN_ANY, BattleScript_RemoveTerrain_Cont + goto BattleScript_ButItFailed +BattleScript_RemoveTerrain_Cont: + critcalc + damagecalc + adjustdamage + attackanimation + waitanimation + effectivenesssound + hitanimation BS_TARGET + waitstate + healthbarupdate BS_TARGET + datahpupdate BS_TARGET + critmessage + waitmessage B_WAIT_TIME_LONG + resultmessage + waitmessage B_WAIT_TIME_LONG + removeterrain + playanimation BS_ATTACKER, B_ANIM_RESTORE_BG + printfromtable gTerrainStringIds + waitmessage B_WAIT_TIME_LONG + tryfaintmon BS_TARGET + goto BattleScript_MoveEnd + BattleScript_Pickpocket:: call BattleScript_AbilityPopUp jumpifability BS_ATTACKER, ABILITY_STICKY_HOLD, BattleScript_PickpocketPrevented diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 300bb9d2e..6b18efb17 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -355,58 +355,57 @@ #define EFFECT_COACHING 348 #define EFFECT_LASH_OUT 349 #define EFFECT_GRASSY_GLIDE 350 -#define EFFECT_REMOVE_TERRAIN 351 -#define EFFECT_DYNAMAX_DOUBLE_DMG 352 -#define EFFECT_DECORATE 353 -#define EFFECT_SNIPE_SHOT 354 -#define EFFECT_RECOIL_HP_25 355 -#define EFFECT_STUFF_CHEEKS 356 -#define EFFECT_GRAV_APPLE 357 -#define EFFECT_EVASION_UP_HIT 358 -#define EFFECT_GLITZY_GLOW 359 -#define EFFECT_BADDY_BAD 360 -#define EFFECT_SAPPY_SEED 361 -#define EFFECT_FREEZY_FROST 362 -#define EFFECT_SPARKLY_SWIRL 363 -#define EFFECT_PLASMA_FISTS 364 -#define EFFECT_HYPERSPACE_FURY 365 -#define EFFECT_AURA_WHEEL 366 -#define EFFECT_PHOTON_GEYSER 367 -#define EFFECT_SHELL_SIDE_ARM 368 -#define EFFECT_TERRAIN_PULSE 369 -#define EFFECT_JAW_LOCK 370 -#define EFFECT_NO_RETREAT 371 -#define EFFECT_TAR_SHOT 372 -#define EFFECT_POLTERGEIST 373 -#define EFFECT_OCTOLOCK 374 -#define EFFECT_CLANGOROUS_SOUL 375 -#define EFFECT_BOLT_BEAK 376 -#define EFFECT_SKY_DROP 377 -#define EFFECT_EXPANDING_FORCE 378 -#define EFFECT_METEOR_BEAM 379 -#define EFFECT_RISING_VOLTAGE 380 -#define EFFECT_BEAK_BLAST 381 -#define EFFECT_COURT_CHANGE 382 -#define EFFECT_STEEL_BEAM 383 -#define EFFECT_EXTREME_EVOBOOST 384 -#define EFFECT_HIT_SET_REMOVE_TERRAIN 385 // genesis supernova -#define EFFECT_DARK_VOID 386 -#define EFFECT_SLEEP_HIT 387 -#define EFFECT_DOUBLE_SHOCK 388 -#define EFFECT_SPECIAL_ATTACK_UP_HIT 389 -#define EFFECT_VICTORY_DANCE 390 -#define EFFECT_TEATIME 391 -#define EFFECT_ATTACK_UP_USER_ALLY 392 // Howl 8th Gen -#define EFFECT_SHELL_TRAP 393 -#define EFFECT_PSYBLADE 394 -#define EFFECT_HYDRO_STEAM 395 -#define EFFECT_HIT_SET_ENTRY_HAZARD 396 -#define EFFECT_DIRE_CLAW 397 -#define EFFECT_BARB_BARRAGE 398 -#define EFFECT_REVIVAL_BLESSING 399 -#define EFFECT_FROSTBITE_HIT 400 -#define EFFECT_SNOWSCAPE 401 +#define EFFECT_DYNAMAX_DOUBLE_DMG 351 +#define EFFECT_DECORATE 352 +#define EFFECT_SNIPE_SHOT 353 +#define EFFECT_RECOIL_HP_25 354 +#define EFFECT_STUFF_CHEEKS 355 +#define EFFECT_GRAV_APPLE 356 +#define EFFECT_EVASION_UP_HIT 357 +#define EFFECT_GLITZY_GLOW 358 +#define EFFECT_BADDY_BAD 359 +#define EFFECT_SAPPY_SEED 360 +#define EFFECT_FREEZY_FROST 361 +#define EFFECT_SPARKLY_SWIRL 362 +#define EFFECT_PLASMA_FISTS 363 +#define EFFECT_HYPERSPACE_FURY 364 +#define EFFECT_AURA_WHEEL 365 +#define EFFECT_PHOTON_GEYSER 366 +#define EFFECT_SHELL_SIDE_ARM 367 +#define EFFECT_TERRAIN_PULSE 368 +#define EFFECT_JAW_LOCK 369 +#define EFFECT_NO_RETREAT 370 +#define EFFECT_TAR_SHOT 371 +#define EFFECT_POLTERGEIST 372 +#define EFFECT_OCTOLOCK 373 +#define EFFECT_CLANGOROUS_SOUL 374 +#define EFFECT_BOLT_BEAK 375 +#define EFFECT_SKY_DROP 376 +#define EFFECT_EXPANDING_FORCE 377 +#define EFFECT_METEOR_BEAM 378 +#define EFFECT_RISING_VOLTAGE 379 +#define EFFECT_BEAK_BLAST 380 +#define EFFECT_COURT_CHANGE 381 +#define EFFECT_STEEL_BEAM 382 +#define EFFECT_EXTREME_EVOBOOST 383 +#define EFFECT_HIT_SET_REMOVE_TERRAIN 384 // genesis supernova +#define EFFECT_DARK_VOID 385 +#define EFFECT_SLEEP_HIT 386 +#define EFFECT_DOUBLE_SHOCK 387 +#define EFFECT_SPECIAL_ATTACK_UP_HIT 388 +#define EFFECT_VICTORY_DANCE 389 +#define EFFECT_TEATIME 390 +#define EFFECT_ATTACK_UP_USER_ALLY 391 // Howl 8th Gen +#define EFFECT_SHELL_TRAP 392 +#define EFFECT_PSYBLADE 393 +#define EFFECT_HYDRO_STEAM 394 +#define EFFECT_HIT_SET_ENTRY_HAZARD 395 +#define EFFECT_DIRE_CLAW 396 +#define EFFECT_BARB_BARRAGE 397 +#define EFFECT_REVIVAL_BLESSING 398 +#define EFFECT_FROSTBITE_HIT 399 +#define EFFECT_SNOWSCAPE 400 -#define NUM_BATTLE_MOVE_EFFECTS 402 +#define NUM_BATTLE_MOVE_EFFECTS 401 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index e71e445fe..1b0bfba3c 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -134,128 +134,126 @@ #define VARIOUS_TRY_HEAL_PULSE 42 #define VARIOUS_TRY_QUASH 43 #define VARIOUS_INVERT_STAT_STAGES 44 -#define VARIOUS_SET_TERRAIN 45 -#define VARIOUS_TRY_ME_FIRST 46 -#define VARIOUS_JUMP_IF_BATTLE_END 47 -#define VARIOUS_TRY_ELECTRIFY 48 -#define VARIOUS_TRY_REFLECT_TYPE 49 -#define VARIOUS_TRY_SOAK 50 -#define VARIOUS_HANDLE_MEGA_EVO 51 -#define VARIOUS_TRY_LAST_RESORT 52 -#define VARIOUS_ARGUMENT_STATUS_EFFECT 53 -#define VARIOUS_TRY_HIT_SWITCH_TARGET 54 -#define VARIOUS_TRY_AUTOTOMIZE 55 -#define VARIOUS_TRY_COPYCAT 56 -#define VARIOUS_ABILITY_POPUP 57 -#define VARIOUS_DEFOG 58 -#define VARIOUS_JUMP_IF_TARGET_ALLY 59 -#define VARIOUS_TRY_SYNCHRONOISE 60 -#define VARIOUS_PSYCHO_SHIFT 61 -#define VARIOUS_CURE_STATUS 62 -#define VARIOUS_POWER_TRICK 63 -#define VARIOUS_AFTER_YOU 64 -#define VARIOUS_BESTOW 65 -#define VARIOUS_ARGUMENT_TO_MOVE_EFFECT 66 -#define VARIOUS_JUMP_IF_NOT_GROUNDED 67 -#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 68 -#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 69 -#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 70 -#define VARIOUS_SET_AURORA_VEIL 71 -#define VARIOUS_TRY_THIRD_TYPE 72 -#define VARIOUS_ACUPRESSURE 73 -#define VARIOUS_SET_POWDER 74 -#define VARIOUS_SPECTRAL_THIEF 75 -#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 76 -#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 77 -#define VARIOUS_JUMP_IF_ROAR_FAILS 78 -#define VARIOUS_TRY_INSTRUCT 79 -#define VARIOUS_JUMP_IF_NOT_BERRY 80 -#define VARIOUS_TRACE_ABILITY 81 -#define VARIOUS_UPDATE_NICK 82 -#define VARIOUS_TRY_ILLUSION_OFF 83 -#define VARIOUS_SET_SPRITEIGNORE0HP 84 -#define VARIOUS_HANDLE_FORM_CHANGE 85 -#define VARIOUS_GET_STAT_VALUE 86 -#define VARIOUS_JUMP_IF_FULL_HP 87 -#define VARIOUS_LOSE_TYPE 88 -#define VARIOUS_TRY_ACTIVATE_SOULHEART 89 -#define VARIOUS_TRY_ACTIVATE_RECEIVER 90 -#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 91 -#define VARIOUS_TRY_FRISK 92 -#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 93 -#define VARIOUS_TRY_FAIRY_LOCK 94 -#define VARIOUS_JUMP_IF_NO_ALLY 95 -#define VARIOUS_POISON_TYPE_IMMUNITY 96 -#define VARIOUS_JUMP_IF_NO_HOLD_EFFECT 97 -#define VARIOUS_INFATUATE_WITH_BATTLER 98 -#define VARIOUS_SET_LAST_USED_ITEM 99 -#define VARIOUS_PARALYZE_TYPE_IMMUNITY 100 -#define VARIOUS_JUMP_IF_ABSENT 101 -#define VARIOUS_DESTROY_ABILITY_POPUP 102 -#define VARIOUS_TOTEM_BOOST 103 -#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 104 -#define VARIOUS_MOVEEND_ITEM_EFFECTS 105 -#define VARIOUS_TERRAIN_SEED 106 -#define VARIOUS_MAKE_INVISIBLE 107 -#define VARIOUS_ROOM_SERVICE 108 -#define VARIOUS_JUMP_IF_TERRAIN_AFFECTED 109 -#define VARIOUS_EERIE_SPELL_PP_REDUCE 110 -#define VARIOUS_JUMP_IF_TEAM_HEALTHY 111 -#define VARIOUS_TRY_HEAL_QUARTER_HP 112 -#define VARIOUS_REMOVE_TERRAIN 113 -#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114 -#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115 -#define VARIOUS_GET_ROTOTILLER_TARGETS 116 -#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 117 -#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 118 -#define VARIOUS_CONSUME_BERRY 119 -#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 120 -#define VARIOUS_HANDLE_PRIMAL_REVERSION 121 -#define VARIOUS_APPLY_PLASMA_FISTS 122 -#define VARIOUS_JUMP_IF_SPECIES 123 -#define VARIOUS_UPDATE_ABILITY_POPUP 124 -#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 125 -#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 126 -#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 127 -#define VARIOUS_PHOTON_GEYSER_CHECK 128 -#define VARIOUS_SHELL_SIDE_ARM_CHECK 129 -#define VARIOUS_TRY_NO_RETREAT 130 -#define VARIOUS_TRY_TAR_SHOT 131 -#define VARIOUS_CAN_TAR_SHOT_WORK 132 -#define VARIOUS_CHECK_POLTERGEIST 133 -#define VARIOUS_SET_OCTOLOCK 134 -#define VARIOUS_CUT_1_3_HP_RAISE_STATS 135 -#define VARIOUS_TRY_END_NEUTRALIZING_GAS 136 -#define VARIOUS_JUMP_IF_UNDER_200 137 -#define VARIOUS_SET_SKY_DROP 138 -#define VARIOUS_CLEAR_SKY_DROP 139 -#define VARIOUS_SKY_DROP_YAWN 140 -#define VARIOUS_JUMP_IF_HOLD_EFFECT 142 -#define VARIOUS_CURE_CERTAIN_STATUSES 143 -#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 144 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 145 -#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 146 -#define VARIOUS_SAVE_BATTLER_ITEM 147 -#define VARIOUS_RESTORE_BATTLER_ITEM 148 -#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 149 -#define VARIOUS_SET_BEAK_BLAST 150 -#define VARIOUS_SWAP_SIDE_STATUSES 151 -#define VARIOUS_SWAP_STATS 152 -#define VARIOUS_JUMP_IF_ROD 153 -#define VARIOUS_JUMP_IF_ABSORB 154 -#define VARIOUS_JUMP_IF_MOTOR 155 -#define VARIOUS_TEATIME_INVUL 156 -#define VARIOUS_TEATIME_TARGETS 157 -#define VARIOUS_TRY_WIND_RIDER_POWER 158 -#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 159 -#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 160 -#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 161 -#define VARIOUS_STORE_HEALING_WISH 162 -#define VARIOUS_HIT_SWITCH_TARGET_FAILED 163 -#define VARIOUS_JUMP_IF_SHELL_TRAP 164 -#define VARIOUS_TRY_REVIVAL_BLESSING 165 -#define VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE 166 -#define VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION 167 +#define VARIOUS_TRY_ME_FIRST 45 +#define VARIOUS_JUMP_IF_BATTLE_END 46 +#define VARIOUS_TRY_ELECTRIFY 47 +#define VARIOUS_TRY_REFLECT_TYPE 48 +#define VARIOUS_TRY_SOAK 49 +#define VARIOUS_HANDLE_MEGA_EVO 50 +#define VARIOUS_TRY_LAST_RESORT 51 +#define VARIOUS_ARGUMENT_STATUS_EFFECT 52 +#define VARIOUS_TRY_HIT_SWITCH_TARGET 53 +#define VARIOUS_TRY_AUTOTOMIZE 54 +#define VARIOUS_TRY_COPYCAT 55 +#define VARIOUS_ABILITY_POPUP 56 +#define VARIOUS_DEFOG 57 +#define VARIOUS_JUMP_IF_TARGET_ALLY 58 +#define VARIOUS_TRY_SYNCHRONOISE 59 +#define VARIOUS_PSYCHO_SHIFT 60 +#define VARIOUS_CURE_STATUS 61 +#define VARIOUS_POWER_TRICK 62 +#define VARIOUS_AFTER_YOU 63 +#define VARIOUS_BESTOW 64 +#define VARIOUS_ARGUMENT_TO_MOVE_EFFECT 65 +#define VARIOUS_JUMP_IF_NOT_GROUNDED 66 +#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 67 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 68 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 69 +#define VARIOUS_SET_AURORA_VEIL 70 +#define VARIOUS_TRY_THIRD_TYPE 71 +#define VARIOUS_ACUPRESSURE 72 +#define VARIOUS_SET_POWDER 73 +#define VARIOUS_SPECTRAL_THIEF 74 +#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 75 +#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 76 +#define VARIOUS_JUMP_IF_ROAR_FAILS 77 +#define VARIOUS_TRY_INSTRUCT 78 +#define VARIOUS_JUMP_IF_NOT_BERRY 79 +#define VARIOUS_TRACE_ABILITY 80 +#define VARIOUS_UPDATE_NICK 81 +#define VARIOUS_TRY_ILLUSION_OFF 82 +#define VARIOUS_SET_SPRITEIGNORE0HP 83 +#define VARIOUS_HANDLE_FORM_CHANGE 84 +#define VARIOUS_GET_STAT_VALUE 85 +#define VARIOUS_JUMP_IF_FULL_HP 86 +#define VARIOUS_LOSE_TYPE 87 +#define VARIOUS_TRY_ACTIVATE_SOULHEART 88 +#define VARIOUS_TRY_ACTIVATE_RECEIVER 89 +#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 90 +#define VARIOUS_TRY_FRISK 91 +#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 92 +#define VARIOUS_TRY_FAIRY_LOCK 93 +#define VARIOUS_JUMP_IF_NO_ALLY 94 +#define VARIOUS_POISON_TYPE_IMMUNITY 95 +#define VARIOUS_JUMP_IF_NO_HOLD_EFFECT 96 +#define VARIOUS_INFATUATE_WITH_BATTLER 97 +#define VARIOUS_SET_LAST_USED_ITEM 98 +#define VARIOUS_PARALYZE_TYPE_IMMUNITY 99 +#define VARIOUS_JUMP_IF_ABSENT 100 +#define VARIOUS_DESTROY_ABILITY_POPUP 101 +#define VARIOUS_TOTEM_BOOST 102 +#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 103 +#define VARIOUS_MOVEEND_ITEM_EFFECTS 104 +#define VARIOUS_TERRAIN_SEED 105 +#define VARIOUS_MAKE_INVISIBLE 106 +#define VARIOUS_ROOM_SERVICE 107 +#define VARIOUS_EERIE_SPELL_PP_REDUCE 108 +#define VARIOUS_JUMP_IF_TEAM_HEALTHY 109 +#define VARIOUS_TRY_HEAL_QUARTER_HP 110 +#define VARIOUS_REMOVE_TERRAIN 111 +#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 112 +#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 113 +#define VARIOUS_GET_ROTOTILLER_TARGETS 114 +#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 115 +#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 116 +#define VARIOUS_CONSUME_BERRY 117 +#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 118 +#define VARIOUS_HANDLE_PRIMAL_REVERSION 119 +#define VARIOUS_APPLY_PLASMA_FISTS 120 +#define VARIOUS_JUMP_IF_SPECIES 121 +#define VARIOUS_UPDATE_ABILITY_POPUP 122 +#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 123 +#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 124 +#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 125 +#define VARIOUS_PHOTON_GEYSER_CHECK 126 +#define VARIOUS_SHELL_SIDE_ARM_CHECK 127 +#define VARIOUS_TRY_NO_RETREAT 128 +#define VARIOUS_TRY_TAR_SHOT 129 +#define VARIOUS_CAN_TAR_SHOT_WORK 130 +#define VARIOUS_CHECK_POLTERGEIST 131 +#define VARIOUS_SET_OCTOLOCK 132 +#define VARIOUS_CUT_1_3_HP_RAISE_STATS 133 +#define VARIOUS_TRY_END_NEUTRALIZING_GAS 134 +#define VARIOUS_JUMP_IF_UNDER_200 135 +#define VARIOUS_SET_SKY_DROP 136 +#define VARIOUS_CLEAR_SKY_DROP 137 +#define VARIOUS_SKY_DROP_YAWN 138 +#define VARIOUS_JUMP_IF_HOLD_EFFECT 139 +#define VARIOUS_CURE_CERTAIN_STATUSES 140 +#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 141 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 142 +#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 143 +#define VARIOUS_SAVE_BATTLER_ITEM 144 +#define VARIOUS_RESTORE_BATTLER_ITEM 145 +#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 146 +#define VARIOUS_SET_BEAK_BLAST 147 +#define VARIOUS_SWAP_SIDE_STATUSES 148 +#define VARIOUS_SWAP_STATS 149 +#define VARIOUS_JUMP_IF_ROD 150 +#define VARIOUS_JUMP_IF_ABSORB 151 +#define VARIOUS_JUMP_IF_MOTOR 152 +#define VARIOUS_TEATIME_INVUL 153 +#define VARIOUS_TEATIME_TARGETS 154 +#define VARIOUS_TRY_WIND_RIDER_POWER 155 +#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 156 +#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 157 +#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 158 +#define VARIOUS_STORE_HEALING_WISH 159 +#define VARIOUS_HIT_SWITCH_TARGET_FAILED 160 +#define VARIOUS_JUMP_IF_SHELL_TRAP 161 +#define VARIOUS_TRY_REVIVAL_BLESSING 162 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE 163 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION 164 // Cmd_manipulatedamage #define DMG_CHANGE_SIGN 0 @@ -338,4 +336,9 @@ #define B_SWITCH_HIT 1 // dragon tail, circle throw #define B_SWITCH_RED_CARD 2 +// Argument labels for EFFECT_HIT_SET_REMOVE_TERRAIN +#define ARG_SET_PSYCHIC_TERRAIN 0 +#define ARG_TRY_REMOVE_TERRAIN_HIT 1 +#define ARG_TRY_REMOVE_TERRAIN_FAIL 2 + #endif // GUARD_CONSTANTS_BATTLE_SCRIPT_COMMANDS_H diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 0597612d1..a122e617a 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -623,49 +623,48 @@ #define STRINGID_ZMOVERESTOREHP 621 #define STRINGID_ZMOVESTATUP 622 #define STRINGID_ZMOVEHPTRAP 623 -#define STRINGID_TERRAINREMOVED 624 -#define STRINGID_ATTACKEREXPELLEDTHEPOISON 625 -#define STRINGID_ATTACKERSHOOKITSELFAWAKE 626 -#define STRINGID_ATTACKERBROKETHROUGHPARALYSIS 627 -#define STRINGID_ATTACKERHEALEDITSBURN 628 -#define STRINGID_ATTACKERMELTEDTHEICE 629 -#define STRINGID_TARGETTOUGHEDITOUT 630 -#define STRINGID_ATTACKERLOSTELECTRICTYPE 631 -#define STRINGID_ATTACKERSWITCHEDSTATWITHTARGET 632 -#define STRINGID_BEINGHITCHARGEDPKMNWITHPOWER 633 -#define STRINGID_SUNLIGHTACTIVATEDABILITY 634 -#define STRINGID_STATWASHEIGHTENED 635 -#define STRINGID_ELECTRICTERRAINACTIVATEDABILITY 636 -#define STRINGID_ABILITYWEAKENEDFSURROUNDINGMONSSTAT 637 -#define STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN 638 -#define STRINGID_PKMNSABILITYPREVENTSABILITY 639 -#define STRINGID_PREPARESHELLTRAP 640 -#define STRINGID_SHELLTRAPDIDNTWORK 641 -#define STRINGID_SPIKESDISAPPEAREDFROMTEAM 642 -#define STRINGID_TOXICSPIKESDISAPPEAREDFROMTEAM 643 -#define STRINGID_STICKYWEBDISAPPEAREDFROMTEAM 644 -#define STRINGID_STEALTHROCKDISAPPEAREDFROMTEAM 645 -#define STRINGID_COULDNTFULLYPROTECT 646 -#define STRINGID_STOCKPILEDEFFECTWOREOFF 647 -#define STRINGID_PKMNREVIVEDREADYTOFIGHT 648 -#define STRINGID_ITEMRESTOREDSPECIESHEALTH 649 -#define STRINGID_ITEMCUREDSPECIESSTATUS 650 -#define STRINGID_ITEMRESTOREDSPECIESPP 651 -#define STRINGID_THUNDERCAGETRAPPED 652 -#define STRINGID_PKMNHURTBYFROSTBITE 653 -#define STRINGID_PKMNGOTFROSTBITE 654 -#define STRINGID_PKMNSITEMHEALEDFROSTBITE 655 -#define STRINGID_ATTACKERHEALEDITSFROSTBITE 656 -#define STRINGID_PKMNFROSTBITEHEALED 657 -#define STRINGID_PKMNFROSTBITEHEALED2 658 -#define STRINGID_PKMNFROSTBITEHEALEDBY 659 -#define STRINGID_MIRRORHERBCOPIED 660 -#define STRINGID_STARTEDSNOW 661 -#define STRINGID_SNOWCONTINUES 662 -#define STRINGID_SNOWSTOPPED 663 -#define STRINGID_SNOWWARNINGSNOW 664 +#define STRINGID_ATTACKEREXPELLEDTHEPOISON 624 +#define STRINGID_ATTACKERSHOOKITSELFAWAKE 625 +#define STRINGID_ATTACKERBROKETHROUGHPARALYSIS 626 +#define STRINGID_ATTACKERHEALEDITSBURN 627 +#define STRINGID_ATTACKERMELTEDTHEICE 628 +#define STRINGID_TARGETTOUGHEDITOUT 629 +#define STRINGID_ATTACKERLOSTELECTRICTYPE 630 +#define STRINGID_ATTACKERSWITCHEDSTATWITHTARGET 631 +#define STRINGID_BEINGHITCHARGEDPKMNWITHPOWER 632 +#define STRINGID_SUNLIGHTACTIVATEDABILITY 633 +#define STRINGID_STATWASHEIGHTENED 634 +#define STRINGID_ELECTRICTERRAINACTIVATEDABILITY 635 +#define STRINGID_ABILITYWEAKENEDFSURROUNDINGMONSSTAT 636 +#define STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN 637 +#define STRINGID_PKMNSABILITYPREVENTSABILITY 638 +#define STRINGID_PREPARESHELLTRAP 639 +#define STRINGID_SHELLTRAPDIDNTWORK 640 +#define STRINGID_SPIKESDISAPPEAREDFROMTEAM 641 +#define STRINGID_TOXICSPIKESDISAPPEAREDFROMTEAM 642 +#define STRINGID_STICKYWEBDISAPPEAREDFROMTEAM 643 +#define STRINGID_STEALTHROCKDISAPPEAREDFROMTEAM 644 +#define STRINGID_COULDNTFULLYPROTECT 645 +#define STRINGID_STOCKPILEDEFFECTWOREOFF 646 +#define STRINGID_PKMNREVIVEDREADYTOFIGHT 647 +#define STRINGID_ITEMRESTOREDSPECIESHEALTH 648 +#define STRINGID_ITEMCUREDSPECIESSTATUS 649 +#define STRINGID_ITEMRESTOREDSPECIESPP 650 +#define STRINGID_THUNDERCAGETRAPPED 651 +#define STRINGID_PKMNHURTBYFROSTBITE 652 +#define STRINGID_PKMNGOTFROSTBITE 653 +#define STRINGID_PKMNSITEMHEALEDFROSTBITE 654 +#define STRINGID_ATTACKERHEALEDITSFROSTBITE 655 +#define STRINGID_PKMNFROSTBITEHEALED 656 +#define STRINGID_PKMNFROSTBITEHEALED2 657 +#define STRINGID_PKMNFROSTBITEHEALEDBY 658 +#define STRINGID_MIRRORHERBCOPIED 659 +#define STRINGID_STARTEDSNOW 660 +#define STRINGID_SNOWCONTINUES 661 +#define STRINGID_SNOWSTOPPED 662 +#define STRINGID_SNOWWARNINGSNOW 663 -#define BATTLESTRINGS_COUNT 665 +#define BATTLESTRINGS_COUNT 664 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, @@ -932,12 +931,16 @@ #define B_MSG_TERRAINPREVENTS_ELECTRIC 1 #define B_MSG_TERRAINPREVENTS_PSYCHIC 2 -// gTerrainEndingStringIds -#define B_MSG_TERRAINENDS_MISTY 0 -#define B_MSG_TERRAINENDS_ELECTRIC 1 -#define B_MSG_TERRAINENDS_PSYCHIC 2 -#define B_MSG_TERRAINENDS_GRASS 3 -#define B_MSG_TERRAINENDS_COUNT 4 +// gTerrainStringIds +#define B_MSG_TERRAIN_SET_MISTY 0 +#define B_MSG_TERRAIN_SET_ELECTRIC 1 +#define B_MSG_TERRAIN_SET_PSYCHIC 2 +#define B_MSG_TERRAIN_SET_GRASSY 3 +#define B_MSG_TERRAIN_END_MISTY 4 +#define B_MSG_TERRAIN_END_ELECTRIC 5 +#define B_MSG_TERRAIN_END_PSYCHIC 6 +#define B_MSG_TERRAIN_END_GRASSY 7 +#define B_MSG_TERRAIN_COUNT 8 // gWrappedStringIds #define B_MSG_WRAPPED_BIND 0 diff --git a/src/battle_message.c b/src/battle_message.c index cc8c99521..2a51761b3 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -1483,17 +1483,16 @@ const u16 gMentalHerbCureStringIds[] = [B_MSG_MENTALHERBCURE_DISABLE] = STRINGID_PKMNMOVEDISABLEDNOMORE, }; -const u16 gTerrainStringIds[] = +const u16 gTerrainStringIds[B_MSG_TERRAIN_COUNT] = { - STRINGID_TERRAINBECOMESMISTY, STRINGID_TERRAINBECOMESGRASSY, STRINGID_TERRAINBECOMESELECTRIC, STRINGID_TERRAINBECOMESPSYCHIC, STRINGID_TERRAINREMOVED, -}; - -const u16 gTerrainEndingStringIds[B_MSG_TERRAINENDS_COUNT] = -{ - [B_MSG_TERRAINENDS_MISTY] = STRINGID_MISTYTERRAINENDS, - [B_MSG_TERRAINENDS_ELECTRIC] = STRINGID_ELECTRICTERRAINENDS, - [B_MSG_TERRAINENDS_PSYCHIC] = STRINGID_PSYCHICTERRAINENDS, - [B_MSG_TERRAINENDS_GRASS] = STRINGID_GRASSYTERRAINENDS, + [B_MSG_TERRAIN_SET_MISTY] = STRINGID_TERRAINBECOMESMISTY, + [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_TERRAINBECOMESELECTRIC, + [B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_TERRAINBECOMESPSYCHIC, + [B_MSG_TERRAIN_SET_GRASSY] = STRINGID_TERRAINBECOMESGRASSY, + [B_MSG_TERRAIN_END_MISTY] = STRINGID_MISTYTERRAINENDS, + [B_MSG_TERRAIN_END_ELECTRIC] = STRINGID_ELECTRICTERRAINENDS, + [B_MSG_TERRAIN_END_PSYCHIC] = STRINGID_PSYCHICTERRAINENDS, + [B_MSG_TERRAIN_END_GRASSY] = STRINGID_GRASSYTERRAINENDS, }; const u16 gTerrainPreventsStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 1049acde8..8615a23d0 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -354,6 +354,7 @@ static void BestowItem(u32 battlerAtk, u32 battlerDef); static bool8 IsFinalStrikeEffect(u16 move); static void TryUpdateRoundTurnOrder(void); static bool32 ChangeOrderTargetAfterAttacker(void); +static void RemoveAllTerrains(void); static void Cmd_attackcanceler(void); static void Cmd_accuracycheck(void); @@ -8460,71 +8461,6 @@ static bool32 HasAttackerFaintedTarget(void) return FALSE; } -static void HandleTerrainMove(u16 move) -{ - u32 statusFlag = 0; - - switch (gBattleMoves[move].effect) - { - case EFFECT_MISTY_TERRAIN: - statusFlag = STATUS_FIELD_MISTY_TERRAIN; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - break; - case EFFECT_GRASSY_TERRAIN: - statusFlag = STATUS_FIELD_GRASSY_TERRAIN; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - break; - case EFFECT_ELECTRIC_TERRAIN: - statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - break; - case EFFECT_PSYCHIC_TERRAIN: - statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN; - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - break; - case EFFECT_HIT_SET_REMOVE_TERRAIN: - switch (gBattleMoves[move].argument) - { - case 0: //genesis supernova - statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN; - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - break; - case 1: //splintered stormshards - if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)) - { - //no terrain to remove -> jump to battle script pointer - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - } - else - { - // remove all terrain - gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - gBattlescriptCurrInstr += 7; - } - return; - default: - break; - } - break; - } - - if (gFieldStatuses & statusFlag || statusFlag == 0) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - } - else - { - gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; - gFieldStatuses |= statusFlag; - if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER) - gFieldTimers.terrainTimer = 8; - else - gFieldTimers.terrainTimer = 5; - gBattlescriptCurrInstr += 7; - } -} - bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget) { return ((GetBattlerAbility(battlerAttacker) == ABILITY_CORROSION && gBattleMoves[gCurrentMove].split == SPLIT_STATUS) @@ -8558,19 +8494,19 @@ static void RemoveAllTerrains(void) switch (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) { case STATUS_FIELD_MISTY_TERRAIN: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINENDS_MISTY; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_END_MISTY; break; case STATUS_FIELD_GRASSY_TERRAIN: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINENDS_GRASS; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_END_GRASSY; break; case STATUS_FIELD_ELECTRIC_TERRAIN: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINENDS_ELECTRIC; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_END_ELECTRIC; break; case STATUS_FIELD_PSYCHIC_TERRAIN: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINENDS_PSYCHIC; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_END_PSYCHIC; break; default: - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINENDS_COUNT; // failsafe + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_COUNT; // failsafe break; } gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain @@ -9782,12 +9718,6 @@ static void Cmd_various(void) } break; } - case VARIOUS_SET_TERRAIN: - { - VARIOUS_ARGS(const u8 *failInstr); - HandleTerrainMove(gCurrentMove); - return; - } case VARIOUS_TRY_ME_FIRST: { VARIOUS_ARGS(const u8 *failInstr); @@ -10415,16 +10345,6 @@ static void Cmd_various(void) MarkBattlerForControllerExec(gActiveBattler); break; } - case VARIOUS_JUMP_IF_TERRAIN_AFFECTED: - { - VARIOUS_ARGS(u32 flags, const u8 *jumpInstr); - u32 flags = cmd->flags; - if (IsBattlerTerrainAffected(gActiveBattler, flags)) - gBattlescriptCurrInstr = cmd->jumpInstr; - else - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } case VARIOUS_EERIE_SPELL_PP_REDUCE: { VARIOUS_ARGS(const u8 *failInstr); @@ -16611,3 +16531,89 @@ void BS_SetSnow(void) } gBattlescriptCurrInstr = cmd->nextInstr; } + +void BS_JumpIfArgument(void) +{ + NATIVE_ARGS(u8 argument, const u8 *jumpInstr); + + if (gBattleMoves[gCurrentMove].argument == cmd->argument) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} + +void BS_SetRemoveTerrain(void) +{ + NATIVE_ARGS(const u8 *jumpInstr); + u32 statusFlag = 0; + + switch (gBattleMoves[gCurrentMove].effect) + { + case EFFECT_MISTY_TERRAIN: + statusFlag = STATUS_FIELD_MISTY_TERRAIN; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY; + break; + case EFFECT_GRASSY_TERRAIN: + statusFlag = STATUS_FIELD_GRASSY_TERRAIN; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_GRASSY; + break; + case EFFECT_ELECTRIC_TERRAIN: + statusFlag = STATUS_FIELD_ELECTRIC_TERRAIN; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC; + break; + case EFFECT_PSYCHIC_TERRAIN: + statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC; + break; + case EFFECT_HIT_SET_REMOVE_TERRAIN: + switch (gBattleMoves[gCurrentMove].argument) + { + case ARG_SET_PSYCHIC_TERRAIN: // Genesis Supernova + statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC; + break; + case ARG_TRY_REMOVE_TERRAIN_HIT: // Splintered Stormshards + case ARG_TRY_REMOVE_TERRAIN_FAIL: // Steel Roller + if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)) + { + // No terrain to remove, jump to battle script pointer. + gBattlescriptCurrInstr = cmd->jumpInstr; + } + else + { + // Remove all terrains. + RemoveAllTerrains(); + gBattlescriptCurrInstr = cmd->nextInstr; + } + return; + default: + break; + } + break; + } + + if (gFieldStatuses & statusFlag || statusFlag == 0) + { + gBattlescriptCurrInstr = cmd->jumpInstr; + } + else + { + u16 atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE); + + gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; + gFieldStatuses |= statusFlag; + gFieldTimers.terrainTimer = (atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5; + gBattlescriptCurrInstr = cmd->nextInstr; + } +} + +void BS_JumpIfTerrainAffected(void) +{ + NATIVE_ARGS(u8 battler, u32 flags, const u8 *jumpInstr); + u32 battler = GetBattlerForBattleScript(cmd->battler); + + if (IsBattlerTerrainAffected(battler, cmd->flags)) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} diff --git a/src/battle_tv.c b/src/battle_tv.c index ba33e0f08..40f13f42e 100644 --- a/src/battle_tv.c +++ b/src/battle_tv.c @@ -441,7 +441,6 @@ static const u16 sPoints_MoveEffect[NUM_BATTLE_MOVE_EFFECTS] = [EFFECT_COACHING] = 0, // TODO: Assign points [EFFECT_LASH_OUT] = 0, // TODO: Assign points [EFFECT_GRASSY_GLIDE] = 0, // TODO: Assign points - [EFFECT_REMOVE_TERRAIN] = 0, // TODO: Assign points [EFFECT_DYNAMAX_DOUBLE_DMG] = 0, // TODO: Assign points [EFFECT_DECORATE] = 0, // TODO: Assign points [EFFECT_SNIPE_SHOT] = 0, // TODO: Assign points diff --git a/src/battle_util.c b/src/battle_util.c index a6c7810ba..e32c78bb1 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2441,19 +2441,19 @@ u8 DoFieldEndTurnEffects(void) gBattleStruct->turnCountersTracker++; break; case ENDTURN_ELECTRIC_TERRAIN: - effect = EndTurnTerrain(STATUS_FIELD_ELECTRIC_TERRAIN, B_MSG_TERRAINENDS_ELECTRIC); + effect = EndTurnTerrain(STATUS_FIELD_ELECTRIC_TERRAIN, B_MSG_TERRAIN_END_ELECTRIC); gBattleStruct->turnCountersTracker++; break; case ENDTURN_MISTY_TERRAIN: - effect = EndTurnTerrain(STATUS_FIELD_MISTY_TERRAIN, B_MSG_TERRAINENDS_MISTY); + effect = EndTurnTerrain(STATUS_FIELD_MISTY_TERRAIN, B_MSG_TERRAIN_END_MISTY); gBattleStruct->turnCountersTracker++; break; case ENDTURN_GRASSY_TERRAIN: - effect = EndTurnTerrain(STATUS_FIELD_GRASSY_TERRAIN, B_MSG_TERRAINENDS_GRASS); + effect = EndTurnTerrain(STATUS_FIELD_GRASSY_TERRAIN, B_MSG_TERRAIN_END_GRASSY); gBattleStruct->turnCountersTracker++; break; case ENDTURN_PSYCHIC_TERRAIN: - effect = EndTurnTerrain(STATUS_FIELD_PSYCHIC_TERRAIN, B_MSG_TERRAINENDS_PSYCHIC); + effect = EndTurnTerrain(STATUS_FIELD_PSYCHIC_TERRAIN, B_MSG_TERRAIN_END_PSYCHIC); gBattleStruct->turnCountersTracker++; break; case ENDTURN_WATER_SPORT: diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index e2791b78d..35490c8e4 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -12023,7 +12023,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = [MOVE_STEEL_ROLLER] = { - .effect = EFFECT_REMOVE_TERRAIN, + .effect = EFFECT_HIT_SET_REMOVE_TERRAIN, .power = 130, .type = TYPE_STEEL, .accuracy = 100, @@ -12034,6 +12034,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, .split = SPLIT_PHYSICAL, .zMoveEffect = Z_EFFECT_NONE, + .argument = ARG_TRY_REMOVE_TERRAIN_FAIL, // Remove a field terrain if there is one and hit, otherwise fail. }, [MOVE_SCALE_SHOT] = @@ -13056,7 +13057,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, .split = SPLIT_PHYSICAL, .zMoveEffect = Z_EFFECT_NONE, - .argument = 1, // Remove the active field terrain if there is one. + .argument = ARG_TRY_REMOVE_TERRAIN_HIT, // Remove the active field terrain if there is one. }, [MOVE_GLAIVE_RUSH] = @@ -13992,7 +13993,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .priority = 0, .flags = 0, .split = SPLIT_SPECIAL, - .argument = 0, // Set Psychic Terrain. If there's a different field terrain active, overwrite it. + .argument = ARG_SET_PSYCHIC_TERRAIN, // Set Psychic Terrain. If there's a different field terrain active, overwrite it. .zMoveEffect = 0 }, [MOVE_SINISTER_ARROW_RAID] = @@ -14049,7 +14050,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .priority = 0, .flags = 0, .split = SPLIT_PHYSICAL, - .argument = 1, // Remove the active field terrain if there is one. + .argument = ARG_TRY_REMOVE_TERRAIN_HIT, // Remove the active field terrain if there is one. .zMoveEffect = 0 }, [MOVE_LETS_SNUGGLE_FOREVER] = diff --git a/test/battle/move_effect/hit_set_remove_terrain.c b/test/battle/move_effect/hit_set_remove_terrain.c new file mode 100644 index 000000000..140a112f7 --- /dev/null +++ b/test/battle/move_effect/hit_set_remove_terrain.c @@ -0,0 +1,84 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_ELECTRIC_TERRAIN].effect == MOVE_ELECTRIC_TERRAIN); + ASSUME(gBattleMoves[MOVE_PSYCHIC_TERRAIN].effect == EFFECT_PSYCHIC_TERRAIN); + ASSUME(gBattleMoves[MOVE_GRASSY_TERRAIN].effect == EFFECT_GRASSY_TERRAIN); + ASSUME(gBattleMoves[MOVE_MISTY_TERRAIN].effect == EFFECT_MISTY_TERRAIN); + ASSUME(gBattleMoves[MOVE_STEEL_ROLLER].effect == EFFECT_HIT_SET_REMOVE_TERRAIN); + ASSUME(gBattleMoves[MOVE_ICE_SPINNER].effect == EFFECT_HIT_SET_REMOVE_TERRAIN); +} + +SINGLE_BATTLE_TEST("Steel Roller and Ice Spinner can remove a terrain from the field") +{ + u32 j; + static const u16 terrainMoves[] = + { + MOVE_ELECTRIC_TERRAIN, + MOVE_PSYCHIC_TERRAIN, + MOVE_GRASSY_TERRAIN, + MOVE_MISTY_TERRAIN, + }; + + u16 terrainMove; + u16 removeTerrainMove; + + for (j = 0; j < ARRAY_COUNT(terrainMoves); j++) + { + PARAMETRIZE { removeTerrainMove = MOVE_STEEL_ROLLER; terrainMove = terrainMoves[j]; } + PARAMETRIZE { removeTerrainMove = MOVE_ICE_SPINNER; terrainMove = terrainMoves[j]; } + } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, terrainMove); MOVE(player, removeTerrainMove); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, terrainMove, opponent); + ANIMATION(ANIM_TYPE_MOVE, removeTerrainMove, player); + switch (terrainMove) + { + case MOVE_ELECTRIC_TERRAIN: + MESSAGE("The electricity disappeared from the battlefield."); + break; + case MOVE_PSYCHIC_TERRAIN: + MESSAGE("The weirdness disappeared from the battlefield."); + break; + case MOVE_GRASSY_TERRAIN: + MESSAGE("The grass disappeared from the battlefield."); + break; + case MOVE_MISTY_TERRAIN: + MESSAGE("The mist disappeared from the battlefield."); + break; + } + } +} + +SINGLE_BATTLE_TEST("Steel Roller fails if there is no terrain on the field") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STEEL_ROLLER); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_STEEL_ROLLER, player); + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Ice Spinner doesn't fail if there is no terrain on the field") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ICE_SPINNER); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ICE_SPINNER, player); + NOT MESSAGE("But it failed!"); + } +}