diff --git a/asm/macros/movement.inc b/asm/macros/movement.inc index 7fb51ce225..e36f81fa55 100644 --- a/asm/macros/movement.inc +++ b/asm/macros/movement.inc @@ -164,6 +164,10 @@ create_movement_action fly_down, MOVEMENT_ACTION_FLY_DOWN create_movement_action emote_double_exclamation_mark, MOVEMENT_ACTION_EMOTE_DOUBLE_EXCL_MARK create_movement_action emote_x, MOVEMENT_ACTION_EMOTE_X + create_movement_action walk_slow_stairs_down, MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN + create_movement_action walk_slow_stairs_up, MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP + create_movement_action walk_slow_stairs_left, MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT + create_movement_action walk_slow_stairs_right, MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT create_movement_action exit_pokeball, MOVEMENT_ACTION_EXIT_POKEBALL create_movement_action enter_pokeball, MOVEMENT_ACTION_ENTER_POKEBALL diff --git a/include/constants/event_object_movement.h b/include/constants/event_object_movement.h index 650a6a2357..bc2081a54b 100755 --- a/include/constants/event_object_movement.h +++ b/include/constants/event_object_movement.h @@ -251,6 +251,10 @@ #define MOVEMENT_ACTION_RUN_UP_SLOW 0xA3 #define MOVEMENT_ACTION_RUN_LEFT_SLOW 0xA4 #define MOVEMENT_ACTION_RUN_RIGHT_SLOW 0xA5 +#define MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN 0xA6 +#define MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP 0xA7 +#define MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT 0xA8 +#define MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT 0xA9 #define MOVEMENT_ACTION_STEP_END 0xFE #define MOVEMENT_ACTION_NONE 0xFF diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 0170baf910..679ad80ea4 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -222,6 +222,7 @@ void ObjectEventMoveDestCoords(struct ObjectEvent *objEvent, u32 direction, s16 u8 AddCameraObject(u8 linkedSpriteId); void UpdateObjectEventsForCameraUpdate(s16 x, s16 y); u8 GetWalkSlowMovementAction(u32); +u8 GetWalkSlowStairsMovementAction(u32); u8 GetJumpMovementAction(u32); u8 ElevationToPriority(u8 elevation); void ObjectEventUpdateElevation(struct ObjectEvent *objEvent, struct Sprite *); diff --git a/src/data/object_events/movement_action_func_tables.h b/src/data/object_events/movement_action_func_tables.h index dda5ff3991..4f5fd57a82 100755 --- a/src/data/object_events/movement_action_func_tables.h +++ b/src/data/object_events/movement_action_func_tables.h @@ -271,6 +271,14 @@ u8 MovementActionFunc_RunSlowUp_Step0(struct ObjectEvent *objectEvent, struct Sp u8 MovementActionFunc_RunSlowLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); u8 MovementActionFunc_RunSlowRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); u8 MovementActionFunc_RunSlow_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsUp_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsDown_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsDown_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsLeft_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementAction_WalkSlowStairsRight_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite); u8 (*const gMovementActionFuncs_FaceDown[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_FaceUp[])(struct ObjectEvent *, struct Sprite *); @@ -438,6 +446,10 @@ u8 (*const gMovementActionFuncs_RunDownSlow[])(struct ObjectEvent *, struct Spri u8 (*const gMovementActionFuncs_RunUpSlow[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_RunLeftSlow[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_RunRightSlow[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkSlowStairsDown[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkSlowStairsUp[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkSlowStairsLeft[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkSlowStairsRight[])(struct ObjectEvent *, struct Sprite *); u8 (*const *const gMovementActionFuncs[])(struct ObjectEvent *, struct Sprite *) = { [MOVEMENT_ACTION_FACE_DOWN] = gMovementActionFuncs_FaceDown, @@ -606,6 +618,10 @@ u8 (*const *const gMovementActionFuncs[])(struct ObjectEvent *, struct Sprite *) [MOVEMENT_ACTION_RUN_UP_SLOW] = gMovementActionFuncs_RunUpSlow, [MOVEMENT_ACTION_RUN_LEFT_SLOW] = gMovementActionFuncs_RunLeftSlow, [MOVEMENT_ACTION_RUN_RIGHT_SLOW] = gMovementActionFuncs_RunRightSlow, + [MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN] = gMovementActionFuncs_WalkSlowStairsDown, + [MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP] = gMovementActionFuncs_WalkSlowStairsUp, + [MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT] = gMovementActionFuncs_WalkSlowStairsLeft, + [MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT] = gMovementActionFuncs_WalkSlowStairsRight, }; u8 (*const gMovementActionFuncs_FaceDown[])(struct ObjectEvent *, struct Sprite *) = { @@ -1591,3 +1607,27 @@ u8 (*const gMovementActionFuncs_RunRightSlow[])(struct ObjectEvent *, struct Spr MovementActionFunc_RunSlow_Step1, MovementAction_PauseSpriteAnim, }; + +bool8 (*const gMovementActionFuncs_WalkSlowStairsUp[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkSlowStairsUp_Step0, + MovementAction_WalkSlowStairsUp_Step1, + MovementAction_PauseSpriteAnim, +}; + +bool8 (*const gMovementActionFuncs_WalkSlowStairsDown[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkSlowStairsDown_Step0, + MovementAction_WalkSlowStairsDown_Step1, + MovementAction_PauseSpriteAnim, +}; + +bool8 (*const gMovementActionFuncs_WalkSlowStairsLeft[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkSlowStairsLeft_Step0, + MovementAction_WalkSlowStairsLeft_Step1, + MovementAction_PauseSpriteAnim, +}; + +bool8 (*const gMovementActionFuncs_WalkSlowStairsRight[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkSlowStairsRight_Step0, + MovementAction_WalkSlowStairsRight_Step1, + MovementAction_PauseSpriteAnim, +}; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index bb546e1fa9..65b25c3faa 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -193,6 +193,7 @@ static void DoShadowFieldEffect(struct ObjectEvent *); static void SetJumpSpriteData(struct Sprite *, u8, u8, u8); static void SetWalkSlowSpriteData(struct Sprite *, u8); static bool8 UpdateWalkSlowAnim(struct Sprite *); +static bool8 UpdateWalkSlowStairs(struct ObjectEvent *objectEvent, struct Sprite *sprite); static u8 DoJumpSpriteMovement(struct Sprite *); static u8 DoJumpSpecialSpriteMovement(struct Sprite *); static void CreateLevitateMovementTask(struct ObjectEvent *); @@ -962,6 +963,13 @@ const u8 gFaceDirectionMovementActions[] = { [DIR_NORTHWEST] = MOVEMENT_ACTION_FACE_LEFT, [DIR_NORTHEAST] = MOVEMENT_ACTION_FACE_RIGHT }; +static const u8 gWalkSlowStairsMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT, +}; const u8 gWalkSlowMovementActions[] = { [DIR_NONE] = MOVEMENT_ACTION_WALK_SLOW_DOWN, [DIR_SOUTH] = MOVEMENT_ACTION_WALK_SLOW_DOWN, @@ -5528,13 +5536,13 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri direction = GetDirectionToFace(x, y, targetX, targetY); // During a script, if player sidesteps or backsteps, // mirror player's direction instead - if (ArePlayerFieldControlsLocked() - && gObjectEvents[gPlayerAvatar.objectEventId].facingDirection != gObjectEvents[gPlayerAvatar.objectEventId].movementDirection) + if (ArePlayerFieldControlsLocked() && + gObjectEvents[gPlayerAvatar.objectEventId].facingDirection != gObjectEvents[gPlayerAvatar.objectEventId].movementDirection) { direction = gObjectEvents[gPlayerAvatar.objectEventId].movementDirection; objectEvent->facingDirectionLocked = TRUE; } - + MoveCoords(direction, &x, &y); GetCollisionAtCoords(objectEvent, x, y, direction); // Sets directionOverwrite for stairs if (GetLedgeJumpDirection(x, y, direction) != DIR_NONE) @@ -5542,12 +5550,12 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri // InitJumpRegular will set the proper speed ObjectEventSetSingleMovement(objectEvent, sprite, GetJump2MovementAction(direction)); } - else if (playerAction >= MOVEMENT_ACTION_WALK_SLOW_DOWN && playerAction <= MOVEMENT_ACTION_WALK_SLOW_RIGHT) + else if (playerAction >= MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN && playerAction <= MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT) { if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH)) // on sideways stairs objectEvent->movementActionId = GetWalkNormalMovementAction(direction); else - ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowMovementAction(direction)); + ObjectEventSetSingleMovement(objectEvent, sprite, GetWalkSlowStairsMovementAction(direction)); } else if (PlayerGetCopyableMovement() == COPY_MOVE_JUMP2) { @@ -6399,13 +6407,13 @@ static u8 TryUpdateMovementActionOnStairs(struct ObjectEvent *objectEvent, u8 mo switch (movementActionId) { case MOVEMENT_ACTION_WALK_NORMAL_DOWN: - return MOVEMENT_ACTION_WALK_SLOW_DOWN; + return MOVEMENT_ACTION_WALK_SLOW_STAIRS_DOWN; case MOVEMENT_ACTION_WALK_NORMAL_UP: - return MOVEMENT_ACTION_WALK_SLOW_UP; + return MOVEMENT_ACTION_WALK_SLOW_STAIRS_UP; case MOVEMENT_ACTION_WALK_NORMAL_LEFT: - return MOVEMENT_ACTION_WALK_SLOW_LEFT; + return MOVEMENT_ACTION_WALK_SLOW_STAIRS_LEFT; case MOVEMENT_ACTION_WALK_NORMAL_RIGHT: - return MOVEMENT_ACTION_WALK_SLOW_RIGHT; + return MOVEMENT_ACTION_WALK_SLOW_STAIRS_RIGHT; default: return movementActionId; } @@ -6534,6 +6542,7 @@ u8 name(u32 idx)\ } dirn_to_anim(GetFaceDirectionMovementAction, gFaceDirectionMovementActions); +dirn_to_anim(GetWalkSlowStairsMovementAction, gWalkSlowStairsMovementActions); dirn_to_anim(GetWalkSlowMovementAction, gWalkSlowMovementActions); dirn_to_anim(GetPlayerRunSlowMovementAction, gRunSlowMovementActions); dirn_to_anim(GetWalkNormalMovementAction, gWalkNormalMovementActions); @@ -10318,6 +10327,22 @@ static bool8 UpdateWalkSlowAnim(struct Sprite *sprite) return FALSE; } +bool8 UpdateWalkSlowStairsAnim(struct Sprite *sprite) +{ + if (++sprite->sTimer < 3) + { + Step1(sprite, sprite->sDirection); + sprite->sNumSteps++; + } + else + sprite->sTimer = 0; + + if (sprite->sNumSteps > 15) + return TRUE; + else + return FALSE; +} + #undef sTimer #undef sNumSteps @@ -11075,6 +11100,88 @@ bool8 MovementActionFunc_RunSlow_Step1(struct ObjectEvent *objectEvent, struct S return FALSE; } +static bool8 UpdateWalkSlowStairs(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairsAnim(sprite)) + { + ShiftStillObjectEventCoords(objectEvent); + objectEvent->triggerGroundEffectsOnStop = TRUE; + sprite->animPaused = TRUE; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_WalkSlowStairsUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + InitWalkSlow(objectEvent, sprite, DIR_NORTH); + return MovementAction_WalkSlowStairsUp_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkSlowStairsUp_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairs(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_WalkSlowStairsDown_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + InitWalkSlow(objectEvent, sprite, DIR_SOUTH); + return MovementAction_WalkSlowStairsDown_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkSlowStairsDown_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairs(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_WalkSlowStairsLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (objectEvent->directionOverwrite) + InitWalkSlow(objectEvent, sprite, objectEvent->directionOverwrite); + else + InitWalkSlow(objectEvent, sprite, DIR_WEST); + return MovementAction_WalkSlowStairsLeft_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkSlowStairsLeft_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairs(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_WalkSlowStairsRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (objectEvent->directionOverwrite) + InitWalkSlow(objectEvent, sprite, objectEvent->directionOverwrite); + else + InitWalkSlow(objectEvent, sprite, DIR_EAST); + return MovementAction_WalkSlowStairsRight_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkSlowStairsRight_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (UpdateWalkSlowStairs(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + static u16 GetGraphicsIdForMon(u32 species, bool32 shiny, bool32 female) { u16 graphicsId = species + OBJ_EVENT_MON; diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index e9cd3149f7..674fb7eddb 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -93,7 +93,8 @@ static bool8 PlayerAnimIsMultiFrameStationaryAndStateNotTurning(void); static bool8 PlayerIsAnimActive(void); static bool8 PlayerCheckIfAnimFinishedOrInactive(void); -static void PlayerWalkSlow(u8 direction); +static void PlayerWalkSlowStairs(u8 direction); +static void UNUSED PlayerWalkSlow(u8 direction); static void PlayerRunSlow(u8 direction); static void PlayerRun(u8); static void PlayerNotOnBikeCollide(u8); @@ -701,7 +702,7 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) else { if (ObjectMovingOnRockStairs(&gObjectEvents[gPlayerAvatar.objectEventId], direction)) - PlayerWalkSlow(direction); + PlayerWalkSlowStairs(direction); else PlayerWalkNormal(direction); } @@ -1016,8 +1017,14 @@ void PlayerSetAnimId(u8 movementActionId, u8 copyableMovement) } } +// slow stairs (from FRLG--faster than slow) +static void PlayerWalkSlowStairs(u8 direction) +{ + PlayerSetAnimId(GetWalkSlowStairsMovementAction(direction), 2); +} + // slow -static void PlayerWalkSlow(u8 direction) +static void UNUSED PlayerWalkSlow(u8 direction) { PlayerSetAnimId(GetWalkSlowMovementAction(direction), 2); }