Create Wander in Grass Movement Type - Pawkkie/Team-Aquas-Asset-Repo GitHub Wiki
Tutorial was written using pokeemerald-expansion v1.9.X
.
This creates a movement type that will only allow object events to 'wander' on grass tiles within a given range, perfect for overworld encounters.
Note: This feature only prevents an object event wandering onto non-grass metatiles. Placing an object with this movement type will cause behaviour similar to
MOVEMENT_TYPE_LOOK_AROUND
if there is not a grass metatile for it to wander onto next to it. Examples are provided at the end of this tutorial.
Defining a new movement
In include/constants/event_object_movement.h
, add a new movement type, remembering to change the total movement count.
#define MOVEMENT_TYPE_FOLLOW_PLAYER 0x51
- #define NUM_MOVEMENT_TYPES 0x52
+ #define MOVEMENT_TYPE_WANDER_IN_GRASS 0x52
+ #define NUM_MOVEMENT_TYPES 0x53
Then, head to somewhere in include/event_object_movement.h
and add in these two declarations. Feel free to add them in individually with the movement type and movement step declarations respectively.
+ void MovementType_WanderInGrass(struct Sprite *);
+ u8 MovementType_WanderInGrass_Step4(struct ObjectEvent *, struct Sprite *);
Adding the movement
In src/event_object_movement.c
, add these three lines to the end of their respective arrays.
static void (*const sMovementTypeCallbacks[])(struct Sprite *) =
{
… … …
+ [MOVEMENT_TYPE_WANDER_IN_GRASS] = MovementType_WanderInGrass,
};
static const bool8 sMovementTypeHasRange[NUM_MOVEMENT_TYPES] = {
… … …
+ [MOVEMENT_TYPE_WANDER_IN_GRASS] = TRUE,
};
const u8 gInitialMovementTypeFacingDirections[] = {
… … …
+ [MOVEMENT_TYPE_WANDER_IN_GRASS] = DIR_SOUTH,
};
Then, still in src/event_object_movement.c
, add the movement function itself.
+ movement_type_def(MovementType_WanderInGrass, gMovementTypeFuncs_WanderInGrass)
+
+ bool8 MovementType_WanderInGrass_Step4(struct ObjectEvent *objectEvent, struct Sprite *sprite)
+ {
+ u8 directions[4];
+ u8 chosenDirection;
+
+ memcpy(directions, gStandardDirections, sizeof directions);
+ chosenDirection = directions[Random() & 3];
+ SetObjectEventDirection(objectEvent, chosenDirection);
+ sprite->sTypeFuncId = 5;
+ if (!MetatileBehavior_IsPokeGrass(MapGridGetMetatileBehaviorAt(objectEvent->currentCoords.x + gDirectionToVectors[chosenDirection].x, objectEvent->currentCoords.y + gDirectionToVectors[chosenDirection].y))
+ || GetCollisionInDirection(objectEvent, chosenDirection))
+ sprite->sTypeFuncId = 1;
+
+ return TRUE;
+ }
And then finally in src/data/object_events/movement_type_func_tables.h
create the movement table by adding in the following.
+ u8 (*const gMovementTypeFuncs_WanderInGrass[])(struct ObjectEvent *, struct Sprite *) = {
+ MovementType_WanderAround_Step0,
+ MovementType_WanderAround_Step1,
+ MovementType_WanderAround_Step2,
+ MovementType_Wander_Step3,
+ MovementType_WanderInGrass_Step4,
+ MovementType_WanderAround_Step5,
+ MovementType_WanderAround_Step6,
+ };
Note: Multiple movement steps were condensed into
MovementType_Wander_Step3
inpokeemerald-expansion v1.9.2
. If you do not yet have these changes, replace it withMovementType_WanderAround_Step3
.
Results
And it's as easy as that. Simply set an objects movement type to MOVEMENT_TYPE_WANDER_IN_GRASS
, set it's maximum movement range, and enjoy restricting object events to only wandering into grass!