In the vanilla games, ledges allow the player to jump over them unconditionally. Game Freak intentionally avoided putting object events and impassible metatiles in front of ledges for this reason. However, in our hacks, we may want to have objects moving around near ledges or ledges that cannot be jumped over because there is an impassible metatile in front of them.
This quick edit makes it so the game checks the landing metatile's collision before jumping. If the metatile is impassible in some way, the player will not jump over the ledge. If an object event is in the way, the player will be able to jump once it moves off the target landing tile.
There is only one function that needs to be edited to do this. Open up src/event_object_movement.c and CTRL+F to the GetLedgeJumpDirection() function.
Use the diff as a guide to modify the function:
u8 GetLedgeJumpDirection(s16 x, s16 y, u8 direction)
{
static bool8 (*const ledgeBehaviorFuncs[])(u8) = {
[DIR_SOUTH - 1] = MetatileBehavior_IsJumpSouth,
[DIR_NORTH - 1] = MetatileBehavior_IsJumpNorth,
[DIR_WEST - 1] = MetatileBehavior_IsJumpWest,
[DIR_EAST - 1] = MetatileBehavior_IsJumpEast,
};
u8 behavior;
u8 index = direction;
+ s16 x2 = x;
+ s16 y2 = y;
+ u8 collision;
if (index == DIR_NONE)
return DIR_NONE;
else if (index > DIR_EAST)
index -= DIR_EAST;
index--;
behavior = MapGridGetMetatileBehaviorAt(x, y);
+ switch(direction)
+ {
+ case DIR_SOUTH:
+ y2 += 1;
+ break;
+ case DIR_NORTH:
+ y2 -= 1;
+ break;
+ case DIR_WEST:
+ x2 -= 1;
+ break;
+ case DIR_EAST:
+ x2 += 1;
+ break;
+ }
+ collision = GetCollisionAtCoords(&gObjectEvents[gPlayerAvatar.objectEventId], x2, y2, direction);
- if (ledgeBehaviorFuncs[index](behavior) == TRUE)
+ if (ledgeBehaviorFuncs[index](behavior) == TRUE && collision == COLLISION_NONE)
return index + 1;
return DIR_NONE;
}
And that's it! The function now checks the collision of the target landing metatile and disallows the jump if it's impassible.