Add a new map object movement behavior - pret/pokecrystal GitHub Wiki
This tutorial is for how to add a new map object movement behavior.
Map objects are defined by object_event
s in map event scripts, and their assigned SPRITEMOVEDATA_*
constants define their movement behavior. This controls how the objects' sprite appears, how it moves, and how it interacts with the player. For example, objects with SPRITEMOVEDATA_WALK_UP_DOWN
appear as a 16x16 pixel sprite that walks up and down within a certain radius; while objects with SPRITEMOVEDATA_BIGDOLL
appear as a 32x32 pixel sprite that does not move.
(Map objects are not the same as sprites. A sprite is an 8x8 pixel entity, of which you can have 40 on-screen at a time. Map objects are composed of sprites—a 16x16 pixel object consists of four sprites, for instance—but sprites are used throughout the game, not just in the overworld map engine.)
Contents
1. Define sprite movement constant and data
At a minimum, you need to define a new SPRITEMOVEDATA_*
constant and its corresponding data. As an example, we'll define SPRITEMOVEDATA_SWIM_UP_DOWN
.
Edit constants/map_object_constants.asm:
; SpriteMovementData indexes (see data/sprites/map_objects.asm)
const_def
const SPRITEMOVEDATA_00 ; 00
...
const SPRITEMOVEDATA_SWIM_WANDER ; 24
+ const SPRITEMOVEDATA_SWIM_UP_DOWN
NUM_SPRITEMOVEDATA EQU const_value
And edit data/sprites/map_objects.asm:
SpriteMovementData::
; entries correspond to SPRITEMOVEDATA_* constants
; SPRITEMOVEDATA_00
db SPRITEMOVEFN_00 ; movement function
db DOWN ; facing
db OBJECT_ACTION_STAND ; action
db WONT_DELETE ; flags1
db 0 ; flags2
db 0 ; palette flags
...
; SPRITEMOVEDATA_SWIM_WANDER
db SPRITEMOVEFN_RANDOM_WALK_XY ; movement function
db DOWN ; facing
db OBJECT_ACTION_STAND ; action
db 0 ; flags1
db 0 ; flags2
db SWIMMING ; palette flags
-; 25
- db SPRITEMOVEFN_00 ; movement function
- db DOWN ; facing
- db OBJECT_ACTION_STAND ; action
- db 0 ; flags1
- db 0 ; flags2
- db 0 ; palette flags
+; SPRITEMOVEDATA_SWIM_UP_DOWN
+ db SPRITEMOVEFN_RANDOM_WALK_Y ; movement function
+ db DOWN ; facing
+ db OBJECT_ACTION_STAND ; action
+ db 0 ; flags1
+ db 0 ; flags2
+ db SWIMMING ; palette flags
Note that we had to delete some unused data at the bottom which didn't correspond to any SPRITEMOVEDATA_*
constant.
Here's what the individual db
values mean:
- movement function: A
SPRITEMOVEFN_*
constant, as defined in constants/map_object_constants.asm. - facing:
UP
,DOWN
,LEFT
, orRIGHT
. - action: An
OBJECT_ACTION_*
constant, as defined in constants/map_object_constants.asm. - flags1: A combination of any of these values, or 0 for none of them:
WONT_DELETE
: The object won't be deleted if it moves off-screen. Example:SPRITEMOVEDATA_STRENGTH_BOULDER
, which needs to stay where it's been pushed.FIXED_FACING
: The object doesn't change its facing direction if it moves. Example:SPRITEMOVEDATA_SHADOW
, which moves along with the player over a ledge but always looks the same.SLIDING
: The object doesn't animate its steps if it moves. Example:SPRITEMOVEDATA_GRASS
, which moves along with the player through tall grass but doesn't have a "stepping" animation.MOVE_ANYWHERE
: The object isn't limited to moving within a particular radius. Example:SPRITEMOVEDATA_STRENGTH_BOULDER
, which can be pushed anywhere.EMOTE_OBJECT
: The object is meant to be transient and gets deleted differently. Example:SPRITEMOVEDATA_EMOTE
, which pops up briefly above an NPC.
- flags2: A combination of any of these values, or 0 for none of them:
LOW_PRIORITY
: The object will appear below other objects, which have normal priority by default. Example:SPRITEMOVEDATA_BOULDERDUST
, which appears below Strength boulders when they're pushed.HIGH_PRIORITY
: The object will appear above other objects. Do not combine withLOW_PRIORITY
. Example:SPRITEMOVEDATA_GRASS
, which appears above the player when walking through tall grass.USE_OBP1
: The object will use SGB palette #1 instead of #0. This was relevant for Gold and Silver since they could be played on the Super Game Boy, but not Crystal.
- palette flags: A combination of any of these values, or 0 for none of them:
SWIMMING
: The object can move over water but is blocked by land, instead of vice-versa. Example:SPRITEMOVEDATA_SWIM_WANDER
, which is used for the Lapras in Union Cave.STRENGTH_BOULDER
: The object blocks the player if they haven't used Strength. Example:SPRITEMOVEDATA_STRENGTH_BOULDER
of course, but also theSPRITEMOVEDATA_BIGDOLL*
data for some reason.BIG_OBJECT
: The object blocks the spaces below it, to its right, and to its bottom-right, not just the space its coordinates are at. Example:SPRITEMOVEDATA_BIGDOLLSYM
, which is used for the Snorlax in Vermilion City.
In the example, we based SPRITEMOVEDATA_SWIM_UP_DOWN
off of SPRITEMOVEDATA_SWIM_WANDER
but gave it the same movement function as SPRITEMOVEDATA_WALK_UP_DOWN
. In particular, it needed the SWIMMING
palette flag.
One more thing: there happens to be a bug that affects objects which swim and move randomly; they're not actually limited by their movement radius. So be sure to fix that.
Anyway, that's all! Now you can use SPRITEMOVEDATA_SWIM_UP_DOWN
for object_event
s just like the rest.
TODO: define new SPRITEMOVEFN_*
, OBJECT_ACTION_*
, and FACING_*
data.
TODO: define new STEP_TYPE_*
and STEP_*
data.