This tutorial is for how to add a new field move effect: a function for a move outside of battle, like Rock Smash, Sweet Scent, all the HM moves, etc. As an example, we'll add a field effect for Earthquake. ## Contents 1. [Define a menu item constant](#1-define-a-menu-item-constant) 2. [Associate the menu item with a move](#2-associate-the-menu-item-with-a-move) 3. [Implement the party menu item](#3-implement-the-party-menu-item) 4. [Implement the field effect](#4-implement-the-field-effect) ## 1. Define a menu item constant Edit [constants/menu_constants.asm](../blob/master/constants/menu_constants.asm): ```diff ; MonMenuOptions indexes (see data/mon_menu.asm) ; used by PokemonActionSubmenu (see engine/pokemon/mon_menu.asm) const_def 1 ; moves const MONMENUITEM_CUT ; 1 ... const MONMENUITEM_SWEETSCENT ; 14 + const MONMENUITEM_EARTHQUAKE ; options const MONMENUITEM_STATS ; 15 ... ``` ## 2. Associate the menu item with a move Edit [data/mon_menu.asm](../blob/master/data/mon_menu.asm): ```diff MonMenuOptions: ; category, item, value; actions are in PokemonActionSubmenu (see engine/pokemon/mon_menu.asm) ; moves db MONMENU_FIELD_MOVE, MONMENUITEM_CUT, CUT ... db MONMENU_FIELD_MOVE, MONMENUITEM_SWEETSCENT, SWEET_SCENT + db MONMENU_FIELD_MOVE, MONMENUITEM_EARTHQUAKE, EARTHQUAKE ; options db MONMENU_MENUOPTION, MONMENUITEM_STATS, MONMENUVALUE_STATS ... ``` ## 3. Implement the party menu item Edit [engine/pokemon/mon_menu.asm](../blob/master/engine/pokemon/mon_menu.asm) (or [engine/menus/start_menu.asm](../blob/master/engine/menus/start_menu.asm) in older versions of pokecrystal): ```diff PokemonActionSubmenu: ... .Actions: dbw MONMENUITEM_CUT, MonMenu_Cut ... dbw MONMENUITEM_SWEETSCENT, MonMenu_SweetScent + dbw MONMENUITEM_EARTHQUAKE, MonMenu_Earthquake dbw MONMENUITEM_STATS, OpenPartyStats ... MonMenu_RockSmash: farcall RockSmashFunction ld a, [wFieldMoveSucceeded] cp $1 jr nz, .Fail ld b, $4 ld a, $2 ret .Fail: ld a, $3 ret MonMenu_SweetScent: farcall SweetScentFromMenu ld b, $4 ld a, $2 ret + +MonMenu_Earthquake: + farcall EarthquakeFunction + ld a, [wFieldMoveSucceeded] + and a + jr z, .Fail + ld b, $4 + ld a, $2 + ret + +.Fail: + ld a, $3 + ret ``` The returned value of `a` affects what happens after the menu item is chosen: - **$0:** Stays in the party menu. - **$1:** Unused, seems buggy. - **$2:** Exits the Start menu. - **$3:** Stays in the party menu. Like many other field move menu items, `MonMenu_Earthquake` returns `$2` or `$3` depending on whether its effect succeeded. Next and last, we'll define its effect as `EarthquakeFunction`. ## 4. Implement the field effect Edit [engine/events/overworld.asm](../blob/master/engine/events/overworld.asm): ```diff +EarthquakeFunction: + call FieldMoveJumptableReset +.loop + ld hl, .Jumptable + call FieldMoveJumptable + jr nc, .loop + and $7f + ld [wFieldMoveSucceeded], a + ret + +.Jumptable: + dw .TryEarthquake + dw .DoEarthquake + dw .FailEarthquake_Bike + dw .FailEarthquake_Surf + +.TryEarthquake: + ld a, [wPlayerState] + cp PLAYER_BIKE + jr z, .fail_bike + cp PLAYER_SURF + jr z, .fail_surf + cp PLAYER_SURF_PIKA + jr z, .fail_surf + ld a, $1 + ret +.fail_bike + ld a, $2 + ret +.fail_surf + ld a, $3 + ret + +.DoEarthquake: + ld hl, EarthquakeScript + call QueueScript + ld a, $81 + ret + +.FailEarthquake_Bike: + ld hl, CantEarthquakeOnBikeText + call MenuTextboxBackup + ld a, $80 + ret + +.FailEarthquake_Surf: + ld hl, CantEarthquakeOnWaterText + call MenuTextboxBackup + ld a, $80 + ret + +EarthquakeScript: + reloadmappart + special UpdateTimePals + callasm GetPartyNick + writetext UsedEarthquakeText + waitbutton + closetext + playsound SFX_STRENGTH + earthquake 50 + pause 30 + jumptext TheGroundShookText + +UsedEarthquakeText: + text_ram wStringBuffer3 + text " used" + line "EARTHQUAKE!" + done + +TheGroundShookText: + text "The ground shook!" + done + +CantEarthquakeOnBikeText: + text "It's unsafe to" + line "ride a bike in" + cont "an EARTHQUAKE!" + prompt + +CantEarthquakeOnWaterText: + text "There's no earth" + line "to quake here!" + prompt ``` This step calls for the most originality. You have to implement whatever your new field move is supposed to do, using assembly code and event scripts. Here I just made Earthquake play a short visual effect, but fail to do so if you're Surfing or on a Bicycle. That's everything: ![Screenshot](screenshots/field-move-earthquake.png) Real effects, like Rock Climb or Dive, will be more complicated. Study how the existing effects work and try to imitate their structure.