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
// IDs for how NPCs that copy player movement should respond.
// Most go unused.
#define COPY_MOVE_NONE 0
#define COPY_MOVE_FACE 1
#define COPY_MOVE_WALK 2
#define COPY_MOVE_WALK_FAST 3
#define COPY_MOVE_WALK_FASTER 4
#define COPY_MOVE_SLIDE 5
#define COPY_MOVE_JUMP_IN_PLACE 6
#define COPY_MOVE_JUMP 7
#define COPY_MOVE_JUMP2 8
#define COPY_MOVE_EMPTY_1 9
#define COPY_MOVE_EMPTY_2 10
enum CopyMovement
{
COPY_MOVE_NONE,
COPY_MOVE_FACE,
COPY_MOVE_WALK,
COPY_MOVE_WALK_FAST,
COPY_MOVE_WALK_FASTER,
COPY_MOVE_SLIDE,
COPY_MOVE_JUMP_IN_PLACE,
COPY_MOVE_JUMP,
COPY_MOVE_JUMP2,
COPY_MOVE_WALK_COLLIDE,
COPY_MOVE_WALK_COLLIDE_SLOW,
};
#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);
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_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_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));

View File

@ -11,7 +11,7 @@ u8 GetPlayerAvatarSpriteId(void);
void PlayerGetDestCoords(s16 *x, s16 *y);
enum Direction GetPlayerFacingDirection(void);
enum Direction GetPlayerMovementDirection(void);
u8 PlayerGetCopyableMovement(void);
enum CopyMovement PlayerGetCopyableMovement(void);
void PlayerWalkNormal(enum Direction direction);
void PlayerWalkFast(enum Direction direction);
void PlayerRideWaterCurrent(enum Direction direction);
@ -27,7 +27,7 @@ void PlayerStandingHoppingWheelie(enum Direction direction);
void PlayerMovingHoppingWheelie(enum Direction direction);
void PlayerLedgeHoppingWheelie(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);
void PlayerOnBikeCollideWithFarawayIslandMew(enum Direction direction);
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)) = {
[COPY_MOVE_NONE] = CopyablePlayerMovement_None,
[COPY_MOVE_FACE] = CopyablePlayerMovement_FaceDirection,
[COPY_MOVE_WALK] = CopyablePlayerMovement_WalkNormal,
[COPY_MOVE_WALK_FAST] = CopyablePlayerMovement_WalkFast,
[COPY_MOVE_WALK_FASTER] = CopyablePlayerMovement_WalkFaster,
[COPY_MOVE_SLIDE] = CopyablePlayerMovement_Slide,
[COPY_MOVE_JUMP_IN_PLACE] = CopyablePlayerMovement_JumpInPlace,
[COPY_MOVE_JUMP] = CopyablePlayerMovement_Jump,
[COPY_MOVE_JUMP2] = CopyablePlayerMovement_Jump2,
[COPY_MOVE_EMPTY_1] = CopyablePlayerMovement_None,
[COPY_MOVE_EMPTY_2] = CopyablePlayerMovement_None,
[COPY_MOVE_NONE] = CopyablePlayerMovement_None,
[COPY_MOVE_FACE] = CopyablePlayerMovement_FaceDirection,
[COPY_MOVE_WALK] = CopyablePlayerMovement_WalkNormal,
[COPY_MOVE_WALK_FAST] = CopyablePlayerMovement_WalkFast,
[COPY_MOVE_WALK_FASTER] = CopyablePlayerMovement_WalkFaster,
[COPY_MOVE_SLIDE] = CopyablePlayerMovement_Slide,
[COPY_MOVE_JUMP_IN_PLACE] = CopyablePlayerMovement_JumpInPlace,
[COPY_MOVE_JUMP] = CopyablePlayerMovement_Jump,
[COPY_MOVE_JUMP2] = CopyablePlayerMovement_Jump2,
[COPY_MOVE_WALK_COLLIDE] = CopyablePlayerMovement_WalkNormal,
[COPY_MOVE_WALK_COLLIDE_SLOW] = CopyablePlayerMovement_WalkSlow,
};
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] = FollowablePlayerMovement_GoSpeed4,
[COPY_MOVE_JUMP2] = FollowablePlayerMovement_Step,
[COPY_MOVE_EMPTY_1] = FollowablePlayerMovement_Idle,
[COPY_MOVE_EMPTY_2] = FollowablePlayerMovement_Idle,
[COPY_MOVE_WALK_COLLIDE] = FollowablePlayerMovement_Idle,
[COPY_MOVE_WALK_COLLIDE_SLOW] = FollowablePlayerMovement_Idle,
};
u8 (*const gMovementTypeFuncs_CopyPlayerInGrass[])(struct ObjectEvent *, struct Sprite *) = {

View File

@ -5493,6 +5493,26 @@ bool8 CopyablePlayerMovement_FaceDirection(struct ObjectEvent *objectEvent, stru
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))
{
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)
{
InitMoveInPlace(objectEvent, sprite, DIR_SOUTH, GetMoveDirectionAnimNum(DIR_SOUTH), 32);
InitMoveInPlace(objectEvent, sprite, DIR_SOUTH, GetMoveDirectionAnimNum(DIR_SOUTH), 31);
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)
{
InitMoveInPlace(objectEvent, sprite, DIR_NORTH, GetMoveDirectionAnimNum(DIR_NORTH), 32);
InitMoveInPlace(objectEvent, sprite, DIR_NORTH, GetMoveDirectionAnimNum(DIR_NORTH), 31);
return MovementAction_WalkInPlaceSlow_Step1(objectEvent, 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);
}
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);
}

View File

@ -1240,12 +1240,12 @@ static bool8 PlayerCheckIfAnimFinishedOrInactive(void)
return ObjectEventCheckHeldMovementStatus(&gObjectEvents[gPlayerAvatar.objectEventId]);
}
static void PlayerSetCopyableMovement(u8 movement)
static void PlayerSetCopyableMovement(enum CopyMovement movement)
{
gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement = movement;
}
u8 PlayerGetCopyableMovement(void)
enum CopyMovement PlayerGetCopyableMovement(void)
{
return gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement;
}
@ -1255,7 +1255,7 @@ static void PlayerForceSetHeldMovement(u8 movementActionId)
ObjectEventForceSetHeldMovement(&gObjectEvents[gPlayerAvatar.objectEventId], movementActionId);
}
void PlayerSetAnimId(u8 movementActionId, u8 copyableMovement)
void PlayerSetAnimId(u8 movementActionId, enum CopyMovement copyableMovement)
{
if (!PlayerIsAnimActive())
{
@ -1310,7 +1310,7 @@ static void PlayerRun(enum Direction direction)
void PlayerOnBikeCollide(enum Direction 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,
// move the follower into the player and hide them.
if (PlayerHasFollowerNPC())
@ -1331,18 +1331,18 @@ void PlayerOnBikeCollide(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)
{
PlayCollisionSoundIfNotFacingWarp(direction);
PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_FACE);
PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_WALK_COLLIDE_SLOW);
}
static void PlayerNotOnBikeCollideWithFarawayIslandMew(enum Direction direction)
{
PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_FACE);
PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_WALK_COLLIDE);
}
void PlayerFaceDirection(enum Direction direction)