Movement follow player (#9365)

This commit is contained in:
FosterProgramming 2026-02-28 15:45:57 +01:00 committed by GitHub
parent 310f746565
commit 1af1e6a4e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 61 additions and 38 deletions

View File

@ -364,17 +364,19 @@
#define ANIM_HOOKED_POKEMON_EAST 11 #define ANIM_HOOKED_POKEMON_EAST 11
// IDs for how NPCs that copy player movement should respond. // IDs for how NPCs that copy player movement should respond.
// Most go unused. enum CopyMovement
#define COPY_MOVE_NONE 0 {
#define COPY_MOVE_FACE 1 COPY_MOVE_NONE,
#define COPY_MOVE_WALK 2 COPY_MOVE_FACE,
#define COPY_MOVE_WALK_FAST 3 COPY_MOVE_WALK,
#define COPY_MOVE_WALK_FASTER 4 COPY_MOVE_WALK_FAST,
#define COPY_MOVE_SLIDE 5 COPY_MOVE_WALK_FASTER,
#define COPY_MOVE_JUMP_IN_PLACE 6 COPY_MOVE_SLIDE,
#define COPY_MOVE_JUMP 7 COPY_MOVE_JUMP_IN_PLACE,
#define COPY_MOVE_JUMP2 8 COPY_MOVE_JUMP,
#define COPY_MOVE_EMPTY_1 9 COPY_MOVE_JUMP2,
#define COPY_MOVE_EMPTY_2 10 COPY_MOVE_WALK_COLLIDE,
COPY_MOVE_WALK_COLLIDE_SLOW,
};
#endif // GUARD_CONSTANTS_EVENT_OBJECT_MOVEMENT_H #endif // GUARD_CONSTANTS_EVENT_OBJECT_MOVEMENT_H

View File

@ -467,6 +467,7 @@ u8 MovementType_CopyPlayer_Step1(struct ObjectEvent *objectEvent, struct Sprite
u8 MovementType_CopyPlayer_Step2(struct ObjectEvent *objectEvent, struct Sprite *sprite); u8 MovementType_CopyPlayer_Step2(struct ObjectEvent *objectEvent, struct Sprite *sprite);
bool8 CopyablePlayerMovement_None(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8)); bool8 CopyablePlayerMovement_None(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8));
bool8 CopyablePlayerMovement_FaceDirection(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8)); bool8 CopyablePlayerMovement_FaceDirection(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8));
bool8 CopyablePlayerMovement_WalkSlow(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8));
bool8 CopyablePlayerMovement_WalkNormal(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8)); bool8 CopyablePlayerMovement_WalkNormal(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8));
bool8 CopyablePlayerMovement_WalkFast(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8)); bool8 CopyablePlayerMovement_WalkFast(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8));
bool8 CopyablePlayerMovement_WalkFaster(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8)); bool8 CopyablePlayerMovement_WalkFaster(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8));

View File

@ -11,7 +11,7 @@ u8 GetPlayerAvatarSpriteId(void);
void PlayerGetDestCoords(s16 *x, s16 *y); void PlayerGetDestCoords(s16 *x, s16 *y);
enum Direction GetPlayerFacingDirection(void); enum Direction GetPlayerFacingDirection(void);
enum Direction GetPlayerMovementDirection(void); enum Direction GetPlayerMovementDirection(void);
u8 PlayerGetCopyableMovement(void); enum CopyMovement PlayerGetCopyableMovement(void);
void PlayerWalkNormal(enum Direction direction); void PlayerWalkNormal(enum Direction direction);
void PlayerWalkFast(enum Direction direction); void PlayerWalkFast(enum Direction direction);
void PlayerRideWaterCurrent(enum Direction direction); void PlayerRideWaterCurrent(enum Direction direction);
@ -27,7 +27,7 @@ void PlayerStandingHoppingWheelie(enum Direction direction);
void PlayerMovingHoppingWheelie(enum Direction direction); void PlayerMovingHoppingWheelie(enum Direction direction);
void PlayerLedgeHoppingWheelie(enum Direction direction); void PlayerLedgeHoppingWheelie(enum Direction direction);
void PlayerAcroTurnJump(enum Direction direction); void PlayerAcroTurnJump(enum Direction direction);
void PlayerSetAnimId(u8 movementActionId, u8 copyableMovement); void PlayerSetAnimId(u8 movementActionId, enum CopyMovement copyableMovement);
bool8 IsPlayerCollidingWithFarawayIslandMew(enum Direction direction); bool8 IsPlayerCollidingWithFarawayIslandMew(enum Direction direction);
void PlayerOnBikeCollideWithFarawayIslandMew(enum Direction direction); void PlayerOnBikeCollideWithFarawayIslandMew(enum Direction direction);
enum Collision CheckForObjectEventCollision(struct ObjectEvent *objectEvent, s16 x, s16 y, enum Direction direction, u8 metatileBehavior); enum Collision CheckForObjectEventCollision(struct ObjectEvent *objectEvent, s16 x, s16 y, enum Direction direction, u8 metatileBehavior);

View File

@ -398,17 +398,17 @@ u8 (*const gMovementTypeFuncs_CopyPlayer[])(struct ObjectEvent *, struct Sprite
}; };
bool8 (*const gCopyPlayerMovementFuncs[])(struct ObjectEvent *, struct Sprite *, enum Direction, bool8(u8)) = { bool8 (*const gCopyPlayerMovementFuncs[])(struct ObjectEvent *, struct Sprite *, enum Direction, bool8(u8)) = {
[COPY_MOVE_NONE] = CopyablePlayerMovement_None, [COPY_MOVE_NONE] = CopyablePlayerMovement_None,
[COPY_MOVE_FACE] = CopyablePlayerMovement_FaceDirection, [COPY_MOVE_FACE] = CopyablePlayerMovement_FaceDirection,
[COPY_MOVE_WALK] = CopyablePlayerMovement_WalkNormal, [COPY_MOVE_WALK] = CopyablePlayerMovement_WalkNormal,
[COPY_MOVE_WALK_FAST] = CopyablePlayerMovement_WalkFast, [COPY_MOVE_WALK_FAST] = CopyablePlayerMovement_WalkFast,
[COPY_MOVE_WALK_FASTER] = CopyablePlayerMovement_WalkFaster, [COPY_MOVE_WALK_FASTER] = CopyablePlayerMovement_WalkFaster,
[COPY_MOVE_SLIDE] = CopyablePlayerMovement_Slide, [COPY_MOVE_SLIDE] = CopyablePlayerMovement_Slide,
[COPY_MOVE_JUMP_IN_PLACE] = CopyablePlayerMovement_JumpInPlace, [COPY_MOVE_JUMP_IN_PLACE] = CopyablePlayerMovement_JumpInPlace,
[COPY_MOVE_JUMP] = CopyablePlayerMovement_Jump, [COPY_MOVE_JUMP] = CopyablePlayerMovement_Jump,
[COPY_MOVE_JUMP2] = CopyablePlayerMovement_Jump2, [COPY_MOVE_JUMP2] = CopyablePlayerMovement_Jump2,
[COPY_MOVE_EMPTY_1] = CopyablePlayerMovement_None, [COPY_MOVE_WALK_COLLIDE] = CopyablePlayerMovement_WalkNormal,
[COPY_MOVE_EMPTY_2] = CopyablePlayerMovement_None, [COPY_MOVE_WALK_COLLIDE_SLOW] = CopyablePlayerMovement_WalkSlow,
}; };
u8 (*const gMovementTypeFuncs_FollowPlayer[])(struct ObjectEvent *, struct Sprite *) = { u8 (*const gMovementTypeFuncs_FollowPlayer[])(struct ObjectEvent *, struct Sprite *) = {
@ -427,8 +427,8 @@ bool8 (*const gFollowPlayerMovementFuncs[])(struct ObjectEvent *, struct Sprite
[COPY_MOVE_JUMP_IN_PLACE] = FollowablePlayerMovement_JumpInPlace, [COPY_MOVE_JUMP_IN_PLACE] = FollowablePlayerMovement_JumpInPlace,
[COPY_MOVE_JUMP] = FollowablePlayerMovement_GoSpeed4, [COPY_MOVE_JUMP] = FollowablePlayerMovement_GoSpeed4,
[COPY_MOVE_JUMP2] = FollowablePlayerMovement_Step, [COPY_MOVE_JUMP2] = FollowablePlayerMovement_Step,
[COPY_MOVE_EMPTY_1] = FollowablePlayerMovement_Idle, [COPY_MOVE_WALK_COLLIDE] = FollowablePlayerMovement_Idle,
[COPY_MOVE_EMPTY_2] = FollowablePlayerMovement_Idle, [COPY_MOVE_WALK_COLLIDE_SLOW] = FollowablePlayerMovement_Idle,
}; };
u8 (*const gMovementTypeFuncs_CopyPlayerInGrass[])(struct ObjectEvent *, struct Sprite *) = { u8 (*const gMovementTypeFuncs_CopyPlayerInGrass[])(struct ObjectEvent *, struct Sprite *) = {

View File

@ -5493,6 +5493,26 @@ bool8 CopyablePlayerMovement_FaceDirection(struct ObjectEvent *objectEvent, stru
return TRUE; return TRUE;
} }
bool8 CopyablePlayerMovement_WalkSlow(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8))
{
enum Direction direction;
s16 x;
s16 y;
direction = playerDirection;
direction = GetCopyDirection(gInitialMovementTypeFacingDirections[objectEvent->movementType], objectEvent->directionSequenceIndex, direction);
ObjectEventMoveDestCoords(objectEvent, direction, &x, &y);
ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction));
objectEvent->playerCopyableMovement = TRUE;
if (GetCollisionAtCoords(objectEvent, x, y, direction) || (tileCallback != NULL && !tileCallback(MapGridGetMetatileBehaviorAt(x, y))))
ObjectEventSetSingleMovement(objectEvent, sprite, GetFaceDirectionMovementAction(direction));
objectEvent->singleMovementActive = TRUE;
sprite->sTypeFuncId = 2;
return TRUE;
}
bool8 CopyablePlayerMovement_WalkNormal(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8)) bool8 CopyablePlayerMovement_WalkNormal(struct ObjectEvent *objectEvent, struct Sprite *sprite, enum Direction playerDirection, bool8 tileCallback(u8))
{ {
enum Direction direction; enum Direction direction;
@ -7709,7 +7729,7 @@ bool8 MovementAction_WalkInPlaceSlow_Step1(struct ObjectEvent *objectEvent, stru
bool8 MovementAction_WalkInPlaceSlowDown_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) bool8 MovementAction_WalkInPlaceSlowDown_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite)
{ {
InitMoveInPlace(objectEvent, sprite, DIR_SOUTH, GetMoveDirectionAnimNum(DIR_SOUTH), 32); InitMoveInPlace(objectEvent, sprite, DIR_SOUTH, GetMoveDirectionAnimNum(DIR_SOUTH), 31);
return MovementAction_WalkInPlaceSlow_Step1(objectEvent, sprite); return MovementAction_WalkInPlaceSlow_Step1(objectEvent, sprite);
} }
@ -7920,19 +7940,19 @@ bool8 MovementAction_EnterPokeball_Step2(struct ObjectEvent *objectEvent, struct
bool8 MovementAction_WalkInPlaceSlowUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) bool8 MovementAction_WalkInPlaceSlowUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite)
{ {
InitMoveInPlace(objectEvent, sprite, DIR_NORTH, GetMoveDirectionAnimNum(DIR_NORTH), 32); InitMoveInPlace(objectEvent, sprite, DIR_NORTH, GetMoveDirectionAnimNum(DIR_NORTH), 31);
return MovementAction_WalkInPlaceSlow_Step1(objectEvent, sprite); return MovementAction_WalkInPlaceSlow_Step1(objectEvent, sprite);
} }
bool8 MovementAction_WalkInPlaceSlowLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) bool8 MovementAction_WalkInPlaceSlowLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite)
{ {
InitMoveInPlace(objectEvent, sprite, DIR_WEST, GetMoveDirectionAnimNum(DIR_WEST), 32); InitMoveInPlace(objectEvent, sprite, DIR_WEST, GetMoveDirectionAnimNum(DIR_WEST), 31);
return MovementAction_WalkInPlaceSlow_Step1(objectEvent, sprite); return MovementAction_WalkInPlaceSlow_Step1(objectEvent, sprite);
} }
bool8 MovementAction_WalkInPlaceSlowRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) bool8 MovementAction_WalkInPlaceSlowRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite)
{ {
InitMoveInPlace(objectEvent, sprite, DIR_EAST, GetMoveDirectionAnimNum(DIR_EAST), 32); InitMoveInPlace(objectEvent, sprite, DIR_EAST, GetMoveDirectionAnimNum(DIR_EAST), 31);
return MovementAction_WalkInPlaceSlow_Step1(objectEvent, sprite); return MovementAction_WalkInPlaceSlow_Step1(objectEvent, sprite);
} }

View File

@ -1240,12 +1240,12 @@ static bool8 PlayerCheckIfAnimFinishedOrInactive(void)
return ObjectEventCheckHeldMovementStatus(&gObjectEvents[gPlayerAvatar.objectEventId]); return ObjectEventCheckHeldMovementStatus(&gObjectEvents[gPlayerAvatar.objectEventId]);
} }
static void PlayerSetCopyableMovement(u8 movement) static void PlayerSetCopyableMovement(enum CopyMovement movement)
{ {
gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement = movement; gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement = movement;
} }
u8 PlayerGetCopyableMovement(void) enum CopyMovement PlayerGetCopyableMovement(void)
{ {
return gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement; return gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement;
} }
@ -1255,7 +1255,7 @@ static void PlayerForceSetHeldMovement(u8 movementActionId)
ObjectEventForceSetHeldMovement(&gObjectEvents[gPlayerAvatar.objectEventId], movementActionId); ObjectEventForceSetHeldMovement(&gObjectEvents[gPlayerAvatar.objectEventId], movementActionId);
} }
void PlayerSetAnimId(u8 movementActionId, u8 copyableMovement) void PlayerSetAnimId(u8 movementActionId, enum CopyMovement copyableMovement)
{ {
if (!PlayerIsAnimActive()) if (!PlayerIsAnimActive())
{ {
@ -1310,7 +1310,7 @@ static void PlayerRun(enum Direction direction)
void PlayerOnBikeCollide(enum Direction direction) void PlayerOnBikeCollide(enum Direction direction)
{ {
PlayCollisionSoundIfNotFacingWarp(direction); PlayCollisionSoundIfNotFacingWarp(direction);
PlayerSetAnimId(GetWalkInPlaceNormalMovementAction(direction), COPY_MOVE_FACE); PlayerSetAnimId(GetWalkInPlaceNormalMovementAction(direction), COPY_MOVE_WALK_COLLIDE);
// Edge case: If the player stops at the top of a mud slide, but the NPC follower is still on a mud slide tile, // Edge case: If the player stops at the top of a mud slide, but the NPC follower is still on a mud slide tile,
// move the follower into the player and hide them. // move the follower into the player and hide them.
if (PlayerHasFollowerNPC()) if (PlayerHasFollowerNPC())
@ -1331,18 +1331,18 @@ void PlayerOnBikeCollide(enum Direction direction)
void PlayerOnBikeCollideWithFarawayIslandMew(enum Direction direction) void PlayerOnBikeCollideWithFarawayIslandMew(enum Direction direction)
{ {
PlayerSetAnimId(GetWalkInPlaceNormalMovementAction(direction), COPY_MOVE_FACE); PlayerSetAnimId(GetWalkInPlaceNormalMovementAction(direction), COPY_MOVE_WALK_COLLIDE);
} }
static void PlayerNotOnBikeCollide(enum Direction direction) static void PlayerNotOnBikeCollide(enum Direction direction)
{ {
PlayCollisionSoundIfNotFacingWarp(direction); PlayCollisionSoundIfNotFacingWarp(direction);
PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_FACE); PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_WALK_COLLIDE_SLOW);
} }
static void PlayerNotOnBikeCollideWithFarawayIslandMew(enum Direction direction) static void PlayerNotOnBikeCollideWithFarawayIslandMew(enum Direction direction)
{ {
PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_FACE); PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_WALK_COLLIDE);
} }
void PlayerFaceDirection(enum Direction direction) void PlayerFaceDirection(enum Direction direction)