Add a new field move effect - pret/pokecrystal GitHub Wiki
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
- Define a menu item constant
- Associate the menu item with a move
- Implement the party menu item
- Implement the field effect
1. Define a menu item constant
Edit constants/menu_constants.asm:
; 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:
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 (or engine/menus/start_menu.asm in older versions of pokecrystal):
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:
+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 GetPartyNickname
+ 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:
Real effects, like Rock Climb or Dive, will be more complicated. Study how the existing effects work and try to imitate their structure.