From 31e9f97d52d4b82b9e75b4a86c699ea57d463fdf Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 3 Jun 2020 14:23:28 -0600 Subject: [PATCH] cherry pick 4eb7fcc261934c0f9f10985761cd3e7b7abf0dab --- include/constants/event_object_movement.h | 24 + include/constants/metatile_behaviors.h | 19 +- include/event_object_movement.h | 12 + include/field_player_avatar.h | 10 + include/global.fieldmap.h | 5 + include/metatile_behavior.h | 4 + src/bike.c | 75 ++- .../movement_action_func_tables.h | 156 +++++++ src/event_object_movement.c | 441 ++++++++++++++++-- src/field_player_avatar.c | 198 +++++++- src/metatile_behavior.c | 30 +- 11 files changed, 909 insertions(+), 65 deletions(-) diff --git a/include/constants/event_object_movement.h b/include/constants/event_object_movement.h index 223650081..9bd3e87c6 100755 --- a/include/constants/event_object_movement.h +++ b/include/constants/event_object_movement.h @@ -1,6 +1,8 @@ #ifndef GUARD_CONSTANTS_EVENT_OBJECT_MOVEMENT_H #define GUARD_CONSTANTS_EVENT_OBJECT_MOVEMENT_H +#define SLOW_MOVEMENT_ON_STAIRS TRUE // change to false to keep emerald's normal movement speed on outdoor stairs + #define MOVEMENT_TYPE_NONE 0x0 #define MOVEMENT_TYPE_LOOK_AROUND 0x1 #define MOVEMENT_TYPE_WANDER_AROUND 0x2 @@ -241,6 +243,28 @@ #define MOVEMENT_ACTION_FIGURE_8 0x9B #define MOVEMENT_ACTION_FLY_UP 0x9C #define MOVEMENT_ACTION_FLY_DOWN 0x9D +// slow running (for stairs) +#define MOVEMENT_ACTION_RUN_DOWN_SLOW 0x9E +#define MOVEMENT_ACTION_RUN_UP_SLOW 0x9F +#define MOVEMENT_ACTION_RUN_LEFT_SLOW 0xA0 +#define MOVEMENT_ACTION_RUN_RIGHT_SLOW 0xA1 +// sideways stairs - walking +#define MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_LEFT 0xA2 +#define MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_RIGHT 0xA3 +#define MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_LEFT 0xA4 +#define MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_RIGHT 0xA5 +// sideways stairs - running +#define MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_LEFT_RUNNING 0xA6 +#define MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_RIGHT_RUNNING 0xA7 +#define MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_LEFT_RUNNING 0xA8 +#define MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_RIGHT_RUNNING 0xA9 +// sideways stairs - acro bike +#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_LEFT 0xAA +#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_RIGHT 0xAB +#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_LEFT 0xAC +#define MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_RIGHT 0xAD +//sideways stairs - mach bike + #define MOVEMENT_ACTION_STEP_END 0xFE diff --git a/include/constants/metatile_behaviors.h b/include/constants/metatile_behaviors.h index 7fe10a7d2..ef79f0b6d 100755 --- a/include/constants/metatile_behaviors.h +++ b/include/constants/metatile_behaviors.h @@ -74,9 +74,9 @@ #define MB_SLIDE_NORTH 0x46 #define MB_SLIDE_SOUTH 0x47 #define MB_TRICK_HOUSE_PUZZLE_8_FLOOR 0x48 -#define MB_UNUSED_49 0x49 -#define MB_UNUSED_4A 0x4A -#define MB_UNUSED_4B 0x4B +#define MB_SIDEWAYS_STAIRS_RIGHT 0x49 +#define MB_SIDEWAYS_STAIRS_LEFT 0x4A +#define MB_ROCK_STAIRS 0x4B #define MB_UNUSED_4C 0x4C #define MB_UNUSED_4D 0x4D #define MB_UNUSED_4E 0x4E @@ -236,14 +236,11 @@ #define MB_WIRELESS_BOX_RESULTS 0xE8 #define MB_TRAINER_HILL_TIMER 0xE9 #define MB_SKY_PILLAR_CLOSED_DOOR 0xEA - -//sideways stairs -#define MB_SIDEWAYS_STAIRS_0 0xEB -#define MB_SIDEWAYS_STAIRS_1 0xEC -#define MB_SIDEWAYS_STAIRS_2 0xED -#define MB_SIDEWAYS_STAIRS_3 0xEE -#define MB_SIDEWAYS_STAIRS_4 0xEF -#define MB_SIDEWAYS_STAIRS_5 0xF0 +#define MB_UNUSED_EB 0xEB +#define MB_UNUSED_EC 0xEC +#define MB_UNUSED_ED 0xED +#define MB_UNUSED_EE 0xEE +#define MB_UNUSED_EF 0xEF #endif // GUARD_METATILE_BEHAVIORS diff --git a/include/event_object_movement.h b/include/event_object_movement.h index 1e754dcd9..e8f8df1a4 100644 --- a/include/event_object_movement.h +++ b/include/event_object_movement.h @@ -428,4 +428,16 @@ void SetObjectEventSpriteGraphics(u8 objectEventId, u8 graphicsId); void SetObjectEventSpriteAnim(u8 objectEventId, u8 animNum); bool32 IsObjectEventSpriteAnimating(u8 objectEventId); +// run slow +u8 GetPlayerRunSlowMovementAction(u32); +//sideways stairs +u8 GetSidewaysStairsToRightDirection(s16, s16, u8); +u8 GetSidewaysStairsToLeftDirection(s16, s16, u8); +u8 GetDiagonalRightStairsMovement(u32); +u8 GetDiagonalLeftStairsMovement(u32); +u8 GetDiagonalRightStairsRunningMovement(u32); +u8 GetDiagonalLeftStairsRunningMovement(u32); +u8 GetDiagonalLeftAcroBikeMovement(u32); +u8 GetDiagonalRightAcroBikeMovement(u32); + #endif //GUARD_EVENT_OBJECT_MOVEMENT_H diff --git a/include/field_player_avatar.h b/include/field_player_avatar.h index c30ce0b6f..3177a887c 100644 --- a/include/field_player_avatar.h +++ b/include/field_player_avatar.h @@ -64,5 +64,15 @@ bool32 IsPlayerSpinExitActive(void); void SetPlayerInvisibility(bool8 invisible); u8 player_get_pos_including_state_based_drift(s16 *x, s16 *y); void StartFishing(u8 rod); +bool32 PlayerIsMovingOnRockStairs(u8 direction); +//sideways stairs +u8 GetRightStairsDirection(u8 direction); +u8 GetLeftStairsDirection(u8 direction); +void PlayerSidewaysStairsToRight(u8 direction); +void PlayerSidewaysStairsToLeft(u8 direction); +void PlayerSidewaysStairsToRightRunning(u8 direction); +void PlayerSidewaysStairsToLeftRunning(u8 direction); +void PlayerSidewaysStairsToAcroBikeLeft(u8 direction); +void PlayerSidewaysStairsToAcroBikeRight(u8 direction); #endif // GUARD_FIELD_PLAYER_AVATAR_H diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index c4d7be35d..baedb9bf3 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -278,6 +278,11 @@ enum COLLISION_ISOLATED_HORIZONTAL_RAIL, COLLISION_VERTICAL_RAIL, COLLISION_HORIZONTAL_RAIL, + //sideways_stairs + COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING, + COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING, + COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_RUNNING, + COLLISION_SIDEWAYS_STAIRS_TO_LEFT_RUNNING, }; // player running states diff --git a/include/metatile_behavior.h b/include/metatile_behavior.h index d4bd9e683..f5781a337 100644 --- a/include/metatile_behavior.h +++ b/include/metatile_behavior.h @@ -145,5 +145,9 @@ bool8 MetatileBehavior_IsQuestionnaire(u8); bool8 MetatileBehavior_IsLongGrass_Duplicate(u8); bool8 MetatileBehavior_IsLongGrassSouthEdge(u8); bool8 MetatileBehavior_IsTrainerHillTimer(u8); +bool8 MetatileBehavior_IsRockStairs(u8 metatileBehavior); +//sideways stairs +bool8 MetatileBehavior_IsSidewaysStairsRight(u8); +bool8 MetatileBehavior_IsSidewaysStairsLeft(u8); #endif // GUARD_METATILE_BEHAVIOR diff --git a/src/bike.c b/src/bike.c index bbcda989c..18dbda6ba 100644 --- a/src/bike.c +++ b/src/bike.c @@ -179,6 +179,9 @@ static u8 GetMachBikeTransition(u8 *dirTraveling) // the difference between face direction and turn direction is that one changes direction while the other does the animation of turning as well as changing direction. static void MachBikeTransition_FaceDirection(u8 direction) { + //if (direction > DIR_EAST) + // direction -= DIR_EAST; + PlayerFaceDirection(direction); Bike_SetBikeStill(); } @@ -187,6 +190,9 @@ static void MachBikeTransition_TurnDirection(u8 direction) { struct ObjectEvent *playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId]; + //if (direction > DIR_EAST) + // direction -= DIR_EAST; + if (CanBikeFaceDirOnMetatile(direction, playerObjEvent->currentMetatileBehavior)) { PlayerTurnInPlace(direction); @@ -194,6 +200,9 @@ static void MachBikeTransition_TurnDirection(u8 direction) } else { + //if (playerObjEvent->facingDirection > DIR_EAST) + // playerObjEvent->facingDirection -= DIR_EAST; + MachBikeTransition_FaceDirection(playerObjEvent->facingDirection); } } @@ -231,9 +240,28 @@ static void MachBikeTransition_TrySpeedUp(u8 direction) PlayerOnBikeCollide(direction); } } + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING) + { + gPlayerAvatar.bikeFrameCounter = 0; + gPlayerAvatar.bikeSpeed = SPEED_STANDING; + PlayerGoSpeed2(GetLeftStairsDirection(direction)); + //PlayerSidewaysStairsToAcroBikeLeft(direction); + return; + } + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING) + { + gPlayerAvatar.bikeFrameCounter = 0; + gPlayerAvatar.bikeSpeed = SPEED_STANDING; + //PlayerSidewaysStairsToAcroBikeRight(direction); + PlayerGoSpeed2(GetRightStairsDirection(direction)); + return; + } else { - // we did not hit anything that can slow us down, so perform the advancement callback depending on the bikeFrameCounter and try to increase the mach bike's speed. + // to do: this sometimes crashes based on the metatile behaviours (eg. holding up while traveling down sideways stairs to sw) + if (PlayerIsMovingOnRockStairs(direction)) + gPlayerAvatar.bikeFrameCounter--; + sMachBikeSpeedCallbacks[gPlayerAvatar.bikeFrameCounter](direction); gPlayerAvatar.bikeSpeed = gPlayerAvatar.bikeFrameCounter + (gPlayerAvatar.bikeFrameCounter >> 1); // same as dividing by 2, but compiler is insistent on >> 1 if (gPlayerAvatar.bikeFrameCounter < 2) // do not go faster than the last element in the mach bike array @@ -268,6 +296,18 @@ static void MachBikeTransition_TrySlowDown(u8 direction) } else { + /* + if (collision == COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING) + { + return PlayerGoSpeed2(GetLeftStairsDirection(direction)); + //return PlayerSidewaysStairsToLeftMachBike(direction); + } + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING) + { + return PlayerGoSpeed2(GetRightStairsDirection(direction)); + //return PlayerSidewaysStairsToRightMachBike(direction); + }*/ + sMachBikeSpeedCallbacks[gPlayerAvatar.bikeFrameCounter](direction); } } @@ -563,7 +603,27 @@ static void AcroBikeTransition_Moving(u8 direction) } else { - PlayerRideWaterCurrent(direction); + if (collision == COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING) + return PlayerGoSpeed2(GetRightStairsDirection(direction)); + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING) + return PlayerGoSpeed2(GetLeftStairsDirection(direction)); + + if (PlayerIsMovingOnRockStairs(direction)) + PlayerGoSpeed2(direction); + else + PlayerRideWaterCurrent(direction); + + /* works, but might be better to keep rock stairs to up/down for mach bike + if (collision == COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING) + direction = GetRightStairsDirection(direction); + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING) + direction = GetLeftStairsDirection(direction); + + if (PlayerIsMovingOnRockStairs(direction)) + PlayerGoSpeed2(direction); + else + PlayerRideWaterCurrent(direction); + */ } } @@ -632,6 +692,11 @@ static void AcroBikeTransition_WheelieHoppingMoving(u8 direction) else { derp: + /*if (collision == COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING) + direction = GetLeftStairsDirection(direction); + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING) + direction = GetRightStairsDirection(direction); + */ PlayerMovingHoppingWheelie(direction); } } @@ -699,6 +764,12 @@ static void AcroBikeTransition_WheelieMoving(u8 direction) } return; } + + /*if (collision == COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING) + direction = GetLeftStairsDirection(direction); + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING) + direction = GetRightStairsDirection(direction);*/ + PlayerWheelieMove(direction); gPlayerAvatar.runningState = MOVING; } diff --git a/src/data/object_events/movement_action_func_tables.h b/src/data/object_events/movement_action_func_tables.h index 8cf7d1699..cc1b52215 100755 --- a/src/data/object_events/movement_action_func_tables.h +++ b/src/data/object_events/movement_action_func_tables.h @@ -261,6 +261,26 @@ u8 MovementAction_FlyUp_Step1(struct ObjectEvent *, struct Sprite *); u8 MovementAction_Fly_Finish(struct ObjectEvent *, struct Sprite *); u8 MovementAction_FlyDown_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementAction_FlyDown_Step1(struct ObjectEvent *, struct Sprite *); +//slow running +u8 MovementActionFunc_RunSlowDown_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +u8 MovementActionFunc_RunSlowUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite); +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); +//sideways stairs +u8 MovementAction_WalkStairDiagonalUpLeft_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_WalkStairDiagonalUpRight_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_WalkStairDiagonalDownLeft_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_WalkStairDiagonalDownRight_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_RunStairDiagonalUpLeft_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_RunStairDiagonalUpRight_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_RunStairDiagonalDownLeft_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_RunStairDiagonalDownRight_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_RunStairDiagonal_Step1(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_AcroBikeDiagonalUpLeft_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_AcroBikeDiagonalDownLeft_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_AcroBikeDiagonalUpRight_Step0(struct ObjectEvent *, struct Sprite *); +u8 MovementAction_AcroBikeDiagonalDownRight_Step0(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_FaceDown[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_FaceUp[])(struct ObjectEvent *, struct Sprite *); @@ -420,6 +440,24 @@ u8 (*const gMovementActionFuncs_DestroyExtraTaskIfAtTop[])(struct ObjectEvent *, u8 (*const gMovementActionFuncs_Figure8[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_FlyUp[])(struct ObjectEvent *, struct Sprite *); u8 (*const gMovementActionFuncs_FlyDown[])(struct ObjectEvent *, struct Sprite *); +//run slow +u8 (*const gMovementActionFuncs_RunDownSlow[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_RunUpSlow[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_RunLeftSlow[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_RunRightSlow[])(struct ObjectEvent *, struct Sprite *); +//sideways stairs +u8 (*const gMovementActionFuncs_WalkStairDiagonalUpLeft[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkStairDiagonalUpRight[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkStairDiagonalDownLeft[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_WalkStairDiagonalDownRight[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_RunStairDiagonalUpLeft[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_RunStairDiagonalUpRight[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_RunStairDiagonalDownLeft[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_RunStairDiagonalDownRight[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_AcroBikeDiagonalUpLeft[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_AcroBikeDiagonalDownLeft[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_AcroBikeDiagonalUpRight[])(struct ObjectEvent *, struct Sprite *); +u8 (*const gMovementActionFuncs_AcroBikeDiagonalDownRight[])(struct ObjectEvent *, struct Sprite *); u8 (*const *const gMovementActionFuncs[])(struct ObjectEvent *, struct Sprite *) = { [MOVEMENT_ACTION_FACE_DOWN] = gMovementActionFuncs_FaceDown, @@ -580,6 +618,24 @@ u8 (*const *const gMovementActionFuncs[])(struct ObjectEvent *, struct Sprite *) [MOVEMENT_ACTION_FIGURE_8] = gMovementActionFuncs_Figure8, [MOVEMENT_ACTION_FLY_UP] = gMovementActionFuncs_FlyUp, [MOVEMENT_ACTION_FLY_DOWN] = gMovementActionFuncs_FlyDown, + //run slow + [MOVEMENT_ACTION_RUN_DOWN_SLOW] = gMovementActionFuncs_RunDownSlow, + [MOVEMENT_ACTION_RUN_UP_SLOW] = gMovementActionFuncs_RunUpSlow, + [MOVEMENT_ACTION_RUN_LEFT_SLOW] = gMovementActionFuncs_RunLeftSlow, + [MOVEMENT_ACTION_RUN_RIGHT_SLOW] = gMovementActionFuncs_RunRightSlow, + //sideways stairs + [MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_LEFT] = gMovementActionFuncs_WalkStairDiagonalUpLeft, + [MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_RIGHT] = gMovementActionFuncs_WalkStairDiagonalUpRight, + [MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_LEFT] = gMovementActionFuncs_WalkStairDiagonalDownLeft, + [MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_RIGHT] = gMovementActionFuncs_WalkStairDiagonalDownRight, + [MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_LEFT_RUNNING] = gMovementActionFuncs_RunStairDiagonalUpLeft, + [MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_RIGHT_RUNNING] = gMovementActionFuncs_RunStairDiagonalUpRight, + [MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_LEFT_RUNNING] = gMovementActionFuncs_RunStairDiagonalDownLeft, + [MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_RIGHT_RUNNING] = gMovementActionFuncs_RunStairDiagonalDownRight, + [MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_LEFT] = gMovementActionFuncs_AcroBikeDiagonalUpLeft, + [MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_RIGHT] = gMovementActionFuncs_AcroBikeDiagonalUpRight, + [MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_LEFT] = gMovementActionFuncs_AcroBikeDiagonalDownLeft, + [MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_RIGHT] = gMovementActionFuncs_AcroBikeDiagonalDownRight, }; u8 (*const gMovementActionFuncs_FaceDown[])(struct ObjectEvent *, struct Sprite *) = { @@ -1511,3 +1567,103 @@ u8 (*const gMovementActionFuncs_DestroyExtraTaskIfAtTop[])(struct ObjectEvent *, MovementAction_DestroyExtraTaskIfAtTop_Step0, MovementAction_Finish, }; + +//slow running +u8 (*const gMovementActionFuncs_RunDownSlow[])(struct ObjectEvent *, struct Sprite *) = { + MovementActionFunc_RunSlowDown_Step0, + MovementActionFunc_RunSlow_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_RunUpSlow[])(struct ObjectEvent *, struct Sprite *) = { + MovementActionFunc_RunSlowUp_Step0, + MovementActionFunc_RunSlow_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_RunLeftSlow[])(struct ObjectEvent *, struct Sprite *) = { + MovementActionFunc_RunSlowLeft_Step0, + MovementActionFunc_RunSlow_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_RunRightSlow[])(struct ObjectEvent *, struct Sprite *) = { + MovementActionFunc_RunSlowRight_Step0, + MovementActionFunc_RunSlow_Step1, + MovementAction_PauseSpriteAnim, +}; + +//sideways stairs +u8 (*const gMovementActionFuncs_WalkStairDiagonalUpLeft[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkStairDiagonalUpLeft_Step0, + MovementAction_WalkSlowDiagonalUpLeft_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_WalkStairDiagonalUpRight[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkStairDiagonalUpRight_Step0, + MovementAction_WalkSlowDiagonalUpRight_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_WalkStairDiagonalDownLeft[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkStairDiagonalDownLeft_Step0, + MovementAction_WalkSlowDiagonalDownLeft_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_WalkStairDiagonalDownRight[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_WalkStairDiagonalDownRight_Step0, + MovementAction_WalkSlowDiagonalDownRight_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_RunStairDiagonalUpLeft[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_RunStairDiagonalUpLeft_Step0, + MovementAction_RunStairDiagonal_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_RunStairDiagonalUpRight[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_RunStairDiagonalUpRight_Step0, + MovementAction_RunStairDiagonal_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_RunStairDiagonalDownLeft[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_RunStairDiagonalDownLeft_Step0, + MovementAction_RunStairDiagonal_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_RunStairDiagonalDownRight[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_RunStairDiagonalDownRight_Step0, + MovementAction_RunStairDiagonal_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_AcroBikeDiagonalUpLeft[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_AcroBikeDiagonalUpLeft_Step0, + MovementAction_RideWaterCurrentLeft_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_AcroBikeDiagonalDownLeft[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_AcroBikeDiagonalDownLeft_Step0, + MovementAction_RideWaterCurrentLeft_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_AcroBikeDiagonalUpRight[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_AcroBikeDiagonalUpRight_Step0, + MovementAction_RideWaterCurrentRight_Step1, + MovementAction_PauseSpriteAnim, +}; + +u8 (*const gMovementActionFuncs_AcroBikeDiagonalDownRight[])(struct ObjectEvent *, struct Sprite *) = { + MovementAction_AcroBikeDiagonalDownRight_Step0, + MovementAction_RideWaterCurrentRight_Step1, + MovementAction_PauseSpriteAnim, +}; + + diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 1a7d08db2..edbc20acb 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -841,6 +841,18 @@ const u8 gRunningDirectionAnimNums[] = { [DIR_NORTHEAST] = 21, }; +const u8 gStairsRunningDirectionAnimNums[] = { + [DIR_NONE] = 20, + [DIR_SOUTH] = 20, + [DIR_NORTH] = 21, + [DIR_WEST] = 22, + [DIR_EAST] = 23, + [DIR_SOUTHWEST] = 22, + [DIR_SOUTHEAST] = 23, + [DIR_NORTHWEST] = 22, + [DIR_NORTHEAST] = 23, +}; + const u8 gTrainerFacingDirectionMovementTypes[] = { [DIR_NONE] = MOVEMENT_TYPE_FACE_DOWN, [DIR_SOUTH] = MOVEMENT_TYPE_FACE_DOWN, @@ -876,50 +888,78 @@ static const struct Coords16 sDirectionToVectors[] = { {-1, 1}, { 1, 1}, {-1, -1}, - { 1, -1} + { 1, -1}, + {-2, 1}, + { 2, 1}, + {-2, -1}, + { 2, -1} }; const u8 gFaceDirectionMovementActions[] = { - MOVEMENT_ACTION_FACE_DOWN, - MOVEMENT_ACTION_FACE_DOWN, - MOVEMENT_ACTION_FACE_UP, - MOVEMENT_ACTION_FACE_LEFT, - MOVEMENT_ACTION_FACE_RIGHT, + [DIR_NONE] = MOVEMENT_ACTION_FACE_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_FACE_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_FACE_UP, + [DIR_WEST] = MOVEMENT_ACTION_FACE_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_FACE_RIGHT, + [DIR_SOUTHWEST] = MOVEMENT_ACTION_FACE_LEFT, + [DIR_SOUTHEAST] = MOVEMENT_ACTION_FACE_RIGHT, + [DIR_NORTHWEST] = MOVEMENT_ACTION_FACE_LEFT, + [DIR_NORTHEAST] = MOVEMENT_ACTION_FACE_RIGHT }; const u8 gWalkSlowMovementActions[] = { - MOVEMENT_ACTION_WALK_SLOW_DOWN, - MOVEMENT_ACTION_WALK_SLOW_DOWN, - MOVEMENT_ACTION_WALK_SLOW_UP, - MOVEMENT_ACTION_WALK_SLOW_LEFT, - MOVEMENT_ACTION_WALK_SLOW_RIGHT, + [DIR_NONE] = MOVEMENT_ACTION_WALK_SLOW_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_WALK_SLOW_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_WALK_SLOW_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_SLOW_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_WALK_SLOW_RIGHT, + [DIR_SOUTHWEST] = MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_DOWN_LEFT, + [DIR_SOUTHEAST] = MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_DOWN_RIGHT, + [DIR_NORTHWEST] = MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_UP_LEFT, + [DIR_NORTHEAST] = MOVEMENT_ACTION_WALK_SLOW_DIAGONAL_UP_RIGHT }; const u8 gWalkNormalMovementActions[] = { - MOVEMENT_ACTION_WALK_NORMAL_DOWN, - MOVEMENT_ACTION_WALK_NORMAL_DOWN, - MOVEMENT_ACTION_WALK_NORMAL_UP, - MOVEMENT_ACTION_WALK_NORMAL_LEFT, - MOVEMENT_ACTION_WALK_NORMAL_RIGHT, + [DIR_NONE] = MOVEMENT_ACTION_WALK_NORMAL_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_WALK_NORMAL_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_WALK_NORMAL_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_NORMAL_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_WALK_NORMAL_RIGHT, + [DIR_SOUTHWEST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_LEFT, + [DIR_SOUTHEAST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_RIGHT, + [DIR_NORTHWEST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_LEFT, + [DIR_NORTHEAST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_RIGHT }; const u8 gWalkFastMovementActions[] = { - MOVEMENT_ACTION_WALK_FAST_DOWN, - MOVEMENT_ACTION_WALK_FAST_DOWN, - MOVEMENT_ACTION_WALK_FAST_UP, - MOVEMENT_ACTION_WALK_FAST_LEFT, - MOVEMENT_ACTION_WALK_FAST_RIGHT, + [DIR_NONE] = MOVEMENT_ACTION_WALK_FAST_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_WALK_FAST_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_WALK_FAST_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_FAST_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_WALK_FAST_RIGHT, + [DIR_SOUTHWEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_LEFT, + [DIR_SOUTHEAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_RIGHT, + [DIR_NORTHWEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_LEFT, + [DIR_NORTHEAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_RIGHT, }; const u8 gRideWaterCurrentMovementActions[] = { - MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN, - MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN, - MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP, - MOVEMENT_ACTION_RIDE_WATER_CURRENT_LEFT, - MOVEMENT_ACTION_RIDE_WATER_CURRENT_RIGHT, + [DIR_NONE] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP, + [DIR_WEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_RIGHT, + [DIR_SOUTHWEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_LEFT, + [DIR_SOUTHEAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_RIGHT, + [DIR_NORTHWEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_LEFT, + [DIR_NORTHEAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_RIGHT }; const u8 gWalkFastestMovementActions[] = { - MOVEMENT_ACTION_WALK_FASTEST_DOWN, - MOVEMENT_ACTION_WALK_FASTEST_DOWN, - MOVEMENT_ACTION_WALK_FASTEST_UP, - MOVEMENT_ACTION_WALK_FASTEST_LEFT, - MOVEMENT_ACTION_WALK_FASTEST_RIGHT, + [DIR_NONE] = MOVEMENT_ACTION_WALK_FASTEST_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_WALK_FASTEST_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_WALK_FASTEST_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_FASTEST_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_WALK_FASTEST_RIGHT, + [DIR_SOUTHWEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_LEFT, + [DIR_SOUTHEAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_RIGHT, + [DIR_NORTHWEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_LEFT, + [DIR_NORTHEAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_RIGHT }; const u8 gSlideMovementActions[] = { MOVEMENT_ACTION_SLIDE_DOWN, @@ -999,11 +1039,11 @@ const u8 gWalkInPlaceFastestMovementActions[] = { MOVEMENT_ACTION_WALK_IN_PLACE_FASTEST_RIGHT, }; const u8 gAcroWheelieFaceDirectionMovementActions[] = { - MOVEMENT_ACTION_ACRO_WHEELIE_FACE_DOWN, - MOVEMENT_ACTION_ACRO_WHEELIE_FACE_DOWN, - MOVEMENT_ACTION_ACRO_WHEELIE_FACE_UP, - MOVEMENT_ACTION_ACRO_WHEELIE_FACE_LEFT, - MOVEMENT_ACTION_ACRO_WHEELIE_FACE_RIGHT, + [DIR_NONE] = MOVEMENT_ACTION_ACRO_WHEELIE_FACE_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_ACRO_WHEELIE_FACE_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_ACRO_WHEELIE_FACE_UP, + [DIR_WEST] = MOVEMENT_ACTION_ACRO_WHEELIE_FACE_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_ACRO_WHEELIE_FACE_RIGHT, }; const u8 gAcroPopWheelieFaceDirectionMovementActions[] = { MOVEMENT_ACTION_ACRO_POP_WHEELIE_DOWN, @@ -1027,11 +1067,15 @@ const u8 gAcroWheelieHopFaceDirectionMovementActions[] = { MOVEMENT_ACTION_ACRO_WHEELIE_HOP_FACE_RIGHT, }; const u8 gAcroWheelieHopDirectionMovementActions[] = { - MOVEMENT_ACTION_ACRO_WHEELIE_HOP_DOWN, - MOVEMENT_ACTION_ACRO_WHEELIE_HOP_DOWN, - MOVEMENT_ACTION_ACRO_WHEELIE_HOP_UP, - MOVEMENT_ACTION_ACRO_WHEELIE_HOP_LEFT, - MOVEMENT_ACTION_ACRO_WHEELIE_HOP_RIGHT, + [DIR_NONE] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_DOWN, + [DIR_SOUTH] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_UP, + [DIR_WEST] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_RIGHT, + /*[DIR_SOUTHWEST] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_LEFT, + [DIR_SOUTHEAST] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_RIGHT, + [DIR_NORTHWEST] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_LEFT, + [DIR_NORTHEAST] = MOVEMENT_ACTION_ACRO_WHEELIE_HOP_RIGHT*/ }; const u8 gAcroWheelieJumpDirectionMovementActions[] = { MOVEMENT_ACTION_ACRO_WHEELIE_JUMP_DOWN, @@ -1068,6 +1112,59 @@ const u8 gAcroEndWheelieMoveDirectionMovementActions[] = { MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_LEFT, MOVEMENT_ACTION_ACRO_END_WHEELIE_MOVE_RIGHT, }; +// run slow +const u8 gRunSlowMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_RUN_DOWN_SLOW, + [DIR_SOUTH] = MOVEMENT_ACTION_RUN_DOWN_SLOW, + [DIR_NORTH] = MOVEMENT_ACTION_RUN_UP_SLOW, + [DIR_WEST] = MOVEMENT_ACTION_RUN_LEFT_SLOW, + [DIR_EAST] = MOVEMENT_ACTION_RUN_RIGHT_SLOW, +}; + +// sideways stairs +const u8 gDiagonalStairRightMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_JUMP_2_RIGHT, + [DIR_SOUTH] = MOVEMENT_ACTION_JUMP_2_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_JUMP_2_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_RIGHT, +}; +const u8 gDiagonalStairLeftMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_JUMP_2_LEFT, + [DIR_SOUTH] = MOVEMENT_ACTION_JUMP_2_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_JUMP_2_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_RIGHT, +}; +const u8 gDiagonalStairRightRunningMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_JUMP_2_RIGHT, + [DIR_SOUTH] = MOVEMENT_ACTION_JUMP_2_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_JUMP_2_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_LEFT_RUNNING, + [DIR_EAST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_RIGHT_RUNNING, +}; +const u8 gDiagonalStairLeftRunningMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_JUMP_2_LEFT, + [DIR_SOUTH] = MOVEMENT_ACTION_JUMP_2_DOWN, + [DIR_NORTH] = MOVEMENT_ACTION_JUMP_2_UP, + [DIR_WEST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_UP_LEFT_RUNNING, + [DIR_EAST] = MOVEMENT_ACTION_WALK_STAIRS_DIAGONAL_DOWN_RIGHT_RUNNING, +}; +const u8 gDiagonalStairLeftAcroBikeMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_LEFT, + [DIR_SOUTH] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_LEFT, + [DIR_NORTH] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_LEFT, + [DIR_WEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_RIGHT, + +}; +const u8 gDiagonalStairRightAcroBikeMovementActions[] = { + [DIR_NONE] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_RIGHT, + [DIR_SOUTH] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_RIGHT, + [DIR_NORTH] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_RIGHT, + [DIR_WEST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_DOWN_LEFT, + [DIR_EAST] = MOVEMENT_ACTION_RIDE_WATER_CURRENT_UP_RIGHT, +}; const u8 gOppositeDirections[] = { DIR_NORTH, @@ -5058,12 +5155,21 @@ u8 name(u32 idx)\ u8 animIds[sizeof(table)];\ direction = idx;\ memcpy(animIds, (table), sizeof(table));\ - if (direction > DIR_EAST) direction = 0;\ + if (direction > sizeof(table)) direction = 0;\ return animIds[direction];\ } +//sideways stairs +dirn_to_anim(GetDiagonalRightStairsMovement, gDiagonalStairRightMovementActions); +dirn_to_anim(GetDiagonalLeftStairsMovement, gDiagonalStairLeftMovementActions); +dirn_to_anim(GetDiagonalRightStairsRunningMovement, gDiagonalStairRightRunningMovementActions); +dirn_to_anim(GetDiagonalLeftStairsRunningMovement, gDiagonalStairLeftRunningMovementActions); +dirn_to_anim(GetDiagonalLeftAcroBikeMovement, gDiagonalStairLeftAcroBikeMovementActions); +dirn_to_anim(GetDiagonalRightAcroBikeMovement, gDiagonalStairRightAcroBikeMovementActions); + dirn_to_anim(GetFaceDirectionMovementAction, gFaceDirectionMovementActions); dirn_to_anim(GetWalkSlowMovementAction, gWalkSlowMovementActions); +dirn_to_anim(GetPlayerRunSlowMovementAction, gRunSlowMovementActions); dirn_to_anim(GetWalkNormalMovementAction, gWalkNormalMovementActions); dirn_to_anim(GetWalkFastMovementAction, gWalkFastMovementActions); dirn_to_anim(GetRideWaterCurrentMovementAction, gRideWaterCurrentMovementActions); @@ -9044,3 +9150,254 @@ u8 MovementAction_Fly_Finish(struct ObjectEvent *objectEvent, struct Sprite *spr { return TRUE; } + +// running slow +static void StartSlowRunningAnim(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 direction) +{ + sub_8093AF0(objectEvent, sprite, direction); + npc_apply_anim_looping(objectEvent, sprite, GetRunningDirectionAnimNum(objectEvent->facingDirection)); +} + +#define tDirection data[3] +#define tDelay data[4] +#define tStepNo data[5] +static bool8 obj_npc_ministep_slow(struct Sprite *sprite) +{ + if ((++sprite->tDelay) & 1) + { + Step1(sprite, sprite->tDirection); + sprite->tStepNo++; + } + else + { + Step2(sprite, sprite->tDirection); + sprite->tStepNo += 2; + } + + if (sprite->tStepNo > 15) + return TRUE; + else + return FALSE; +} +static bool8 npc_obj_ministep_stop_on_arrival_slow(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (obj_npc_ministep_slow(sprite)) + { + ShiftStillObjectEventCoords(objectEvent); + objectEvent->triggerGroundEffectsOnStop = TRUE; + sprite->animPaused = TRUE; + return TRUE; + } + return FALSE; +} + + +bool8 MovementActionFunc_RunSlowDown_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + StartSlowRunningAnim(objectEvent, sprite, DIR_SOUTH); + return MovementActionFunc_RunSlow_Step1(objectEvent, sprite); +} + +bool8 MovementActionFunc_RunSlowUp_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + StartSlowRunningAnim(objectEvent, sprite, DIR_NORTH); + return MovementActionFunc_RunSlow_Step1(objectEvent, sprite); +} + +bool8 MovementActionFunc_RunSlowLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + StartSlowRunningAnim(objectEvent, sprite, DIR_WEST); + return MovementActionFunc_RunSlow_Step1(objectEvent, sprite); +} + +bool8 MovementActionFunc_RunSlowRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + StartSlowRunningAnim(objectEvent, sprite, DIR_EAST); + return MovementActionFunc_RunSlow_Step1(objectEvent, sprite); +} + +bool8 MovementActionFunc_RunSlow_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (npc_obj_ministep_stop_on_arrival_slow(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + +//sideways stairs +u8 GetSidewaysStairsToRightDirection(s16 x, s16 y, u8 z) +{ + static bool8 (*const direction[])(u8) = { + MetatileBehavior_IsWalkSouth, + MetatileBehavior_IsWalkNorth, + MetatileBehavior_IsSidewaysStairsRight, + MetatileBehavior_IsSidewaysStairsRight, + }; + + u8 b; + u8 index = z; + + if (index == 0) + return 0; + else if (index > 4) + index -= 4; + + index--; + b = MapGridGetMetatileBehaviorAt(x, y); + + if (direction[index](b) == 1) + return index + 1; + + return 0; +} + +u8 GetSidewaysStairsToLeftDirection(s16 x, s16 y, u8 z) +{ + static bool8 (*const direction[])(u8) = { + MetatileBehavior_IsWalkSouth, + MetatileBehavior_IsWalkNorth, + MetatileBehavior_IsSidewaysStairsLeft, + MetatileBehavior_IsSidewaysStairsLeft, + }; + + u8 b; + u8 index = z; + + if (index == 0) + return 0; + else if (index > 4) + index -= 4; + + index--; + b = MapGridGetMetatileBehaviorAt(x, y); + + if (direction[index](b) == 1) + return index + 1; + + return 0; +} + +bool8 MovementAction_WalkStairDiagonalUpLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_WEST; + objectEvent->facingDirectionLocked = TRUE; + sub_8093B60(objectEvent, sprite, DIR_NORTHWEST); + return MovementAction_WalkSlowDiagonalUpLeft_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkStairDiagonalUpRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_EAST; + objectEvent->facingDirectionLocked = TRUE; + sub_8093B60(objectEvent, sprite, DIR_NORTHEAST); + return MovementAction_WalkSlowDiagonalUpRight_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkStairDiagonalDownLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_WEST; + objectEvent->facingDirectionLocked = TRUE; + sub_8093B60(objectEvent, sprite, DIR_SOUTHWEST); + return MovementAction_WalkSlowDiagonalDownLeft_Step1(objectEvent, sprite); +} + +bool8 MovementAction_WalkStairDiagonalDownRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_EAST; + objectEvent->facingDirectionLocked = TRUE; + sub_8093B60(objectEvent, sprite, DIR_SOUTHEAST); + return MovementAction_WalkSlowDiagonalDownRight_Step1(objectEvent, sprite); +} + +bool8 MovementAction_RunStairDiagonalUpLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_WEST; + objectEvent->facingDirectionLocked = TRUE; + StartSlowRunningAnim(objectEvent, sprite, DIR_NORTHWEST); + return MovementAction_RunStairDiagonal_Step1(objectEvent, sprite); +} + +bool8 MovementAction_RunStairDiagonalUpRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_EAST; + objectEvent->facingDirectionLocked = TRUE; + StartSlowRunningAnim(objectEvent, sprite, DIR_NORTHEAST); + return MovementAction_RunStairDiagonal_Step1(objectEvent, sprite); +} + +bool8 MovementAction_RunStairDiagonalDownLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_WEST; + objectEvent->facingDirectionLocked = TRUE; + StartSlowRunningAnim(objectEvent, sprite, DIR_SOUTHWEST); + return MovementAction_RunStairDiagonal_Step1(objectEvent, sprite); +} + +bool8 MovementAction_RunStairDiagonalDownRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_EAST; + objectEvent->facingDirectionLocked = TRUE; + StartSlowRunningAnim(objectEvent, sprite, DIR_SOUTHEAST); + return MovementAction_RunStairDiagonal_Step1(objectEvent, sprite); +} + +bool8 MovementAction_RunStairDiagonal_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + if (npc_obj_ministep_stop_on_arrival(objectEvent, sprite)) + { + sprite->data[2] = 2; + return TRUE; + } + return FALSE; +} + +bool8 MovementAction_AcroBikeDiagonalUpLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_WEST; + objectEvent->facingDirectionLocked = TRUE; + #if SLOW_MOVEMENT_ON_STAIRS + do_go_anim(objectEvent, sprite, DIR_NORTHWEST, 0); + #else + do_go_anim(objectEvent, sprite, DIR_NORTHWEST, 2); + #endif + return MovementAction_RideWaterCurrentLeft_Step1(objectEvent, sprite); +} + +bool8 MovementAction_AcroBikeDiagonalDownLeft_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_WEST; + objectEvent->facingDirectionLocked = TRUE; + #if SLOW_MOVEMENT_ON_STAIRS + do_go_anim(objectEvent, sprite, DIR_SOUTHWEST, 0); + #else + do_go_anim(objectEvent, sprite, DIR_SOUTHWEST, 2); + #endif + return MovementAction_RideWaterCurrentLeft_Step1(objectEvent, sprite); +} + +bool8 MovementAction_AcroBikeDiagonalUpRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_EAST; + objectEvent->facingDirectionLocked = TRUE; + #if SLOW_MOVEMENT_ON_STAIRS + do_go_anim(objectEvent, sprite, DIR_NORTHEAST, 0); + #else + do_go_anim(objectEvent, sprite, DIR_NORTHEAST, 2); + #endif + return MovementAction_RideWaterCurrentRight_Step1(objectEvent, sprite); +} + +bool8 MovementAction_AcroBikeDiagonalDownRight_Step0(struct ObjectEvent *objectEvent, struct Sprite *sprite) +{ + objectEvent->facingDirection = DIR_EAST; + objectEvent->facingDirectionLocked = TRUE; + #if SLOW_MOVEMENT_ON_STAIRS + do_go_anim(objectEvent, sprite, DIR_SOUTHEAST, 0); + #else + do_go_anim(objectEvent, sprite, DIR_SOUTHEAST, 2); + #endif + return MovementAction_RideWaterCurrentRight_Step1(objectEvent, sprite); +} + diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 4f85ad628..0a98f3dc7 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -44,6 +44,8 @@ static void MovePlayerAvatarUsingKeypadInput(u8, u16, u16); static void PlayerAllowForcedMovementIfMovingSameDirection(); static bool8 TryDoMetatileBehaviorForcedMovement(); static u8 GetForcedMovementByMetatileBehavior(); +static bool8 IsSidewaysStairToRight(s16, s16, u8); +static bool8 IsSidewaysStairToLeft(s16, s16, u8); static bool8 ForcedMovement_None(void); static bool8 ForcedMovement_Slip(void); @@ -90,6 +92,8 @@ static bool8 sub_808B618(void); static bool8 PlayerIsAnimActive(void); static bool8 PlayerCheckIfAnimFinishedOrInactive(void); +static void PlayerGoSlow(u8 direction); +static void PlayerRunSlow(u8 direction); static void PlayerRun(u8); static void PlayerNotOnBikeCollide(u8); static void PlayerNotOnBikeCollideWithFarawayIslandMew(u8); @@ -407,7 +411,7 @@ static u8 GetForcedMovementByMetatileBehavior(void) { u8 metatileBehavior = gObjectEvents[gPlayerAvatar.objectEventId].currentMetatileBehavior; - for (i = 0; i < 18; i++) + for (i = 0; i < NELEMS(sForcedMovementTestFuncs); i++) { if (sForcedMovementTestFuncs[i](metatileBehavior)) return i + 1; @@ -607,7 +611,7 @@ static void PlayerNotOnBikeTurningInPlace(u8 direction, u16 heldKeys) static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) { u8 collision = CheckForPlayerAvatarCollision(direction); - + if (collision) { if (collision == COLLISION_LEDGE_JUMP) @@ -620,6 +624,26 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) PlayerNotOnBikeCollideWithFarawayIslandMew(direction); return; } + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING) + { + PlayerSidewaysStairsToRight(direction); + return; + } + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING) + { + PlayerSidewaysStairsToLeft(direction); + return; + } + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_RUNNING) + { + PlayerSidewaysStairsToRightRunning(direction); + return; + } + else if (collision == COLLISION_SIDEWAYS_STAIRS_TO_LEFT_RUNNING) + { + PlayerSidewaysStairsToLeftRunning(direction); + return; + } else { u8 adjustedCollision = collision - COLLISION_STOP_SURFING; @@ -628,10 +652,10 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) return; } } - + if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) { - // speed 2 is fast, same speed as running + // speed 2 is fast, same speed as running PlayerGoSpeed2(direction); return; } @@ -639,16 +663,65 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_UNDERWATER) && (heldKeys & B_BUTTON) && FlagGet(FLAG_SYS_B_DASH) && IsRunningDisallowed(gObjectEvents[gPlayerAvatar.objectEventId].currentMetatileBehavior) == 0) { - PlayerRun(direction); + if (PlayerIsMovingOnRockStairs(direction)) + PlayerRunSlow(direction); + else + PlayerRun(direction); + gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_DASH; return; } else { - PlayerGoSpeed1(direction); + if (PlayerIsMovingOnRockStairs(direction)) + PlayerGoSlow(direction); + else + PlayerGoSpeed1(direction); } } +bool32 PlayerIsMovingOnRockStairs(u8 direction) +{ + #if SLOW_MOVEMENT_ON_STAIRS + struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId]; + s16 x = objectEvent->currentCoords.x; + s16 y = objectEvent->currentCoords.y; + + switch (direction) + { + case DIR_NORTH: + return MetatileBehavior_IsRockStairs(MapGridGetMetatileBehaviorAt(x, y)); + case DIR_SOUTH: + MoveCoords(DIR_SOUTH, &x, &y); + return MetatileBehavior_IsRockStairs(MapGridGetMetatileBehaviorAt(x, y)); + /* + case DIR_WEST: + MoveCoords(DIR_WEST, &x, &y); + return MetatileBehavior_IsRockStairs(MapGridGetMetatileBehaviorAt(x, y)); + case DIR_EAST: + MoveCoords(DIR_EAST, &x, &y); + return MetatileBehavior_IsRockStairs(MapGridGetMetatileBehaviorAt(x, y)); + case DIR_SOUTHWEST: + MoveCoords(DIR_SOUTHWEST, &x, &y); + return MetatileBehavior_IsRockStairs(MapGridGetMetatileBehaviorAt(x, y)); + case DIR_SOUTHEAST: + MoveCoords(DIR_SOUTHEAST, &x, &y); + return MetatileBehavior_IsRockStairs(MapGridGetMetatileBehaviorAt(x, y)); + case DIR_NORTHWEST: + MoveCoords(DIR_NORTHWEST, &x, &y); + return MetatileBehavior_IsRockStairs(MapGridGetMetatileBehaviorAt(x, y)); + case DIR_NORTHEAST: + MoveCoords(DIR_NORTHEAST, &x, &y); + return MetatileBehavior_IsRockStairs(MapGridGetMetatileBehaviorAt(x, y)); + */ + default: + return FALSE; + } + #else + return FALSE + #endif +} + static u8 CheckForPlayerAvatarCollision(u8 direction) { s16 x, y; @@ -656,6 +729,7 @@ static u8 CheckForPlayerAvatarCollision(u8 direction) x = playerObjEvent->currentCoords.x; y = playerObjEvent->currentCoords.y; + MoveCoords(direction, &x, &y); return CheckForObjectEventCollision(playerObjEvent, x, y, direction, MapGridGetMetatileBehaviorAt(x, y)); } @@ -691,7 +765,26 @@ u8 CheckForObjectEventCollision(struct ObjectEvent *objectEvent, s16 x, s16 y, u return COLLISION_ROTATING_GATE; CheckAcroBikeCollision(x, y, metatileBehavior, &collision); } - return collision; + + if (collision != COLLISION_IMPASSABLE) + { + if (IsSidewaysStairToRight(x, y, direction)) + { + if (gMain.heldKeys & B_BUTTON) + return COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_RUNNING; + else + return COLLISION_SIDEWAYS_STAIRS_TO_RIGHT_WALKING; + } + else if (IsSidewaysStairToLeft(x, y, direction)) + { + if (gMain.heldKeys & B_BUTTON) + return COLLISION_SIDEWAYS_STAIRS_TO_LEFT_RUNNING; + else + return COLLISION_SIDEWAYS_STAIRS_TO_LEFT_WALKING; + } + } + + return collision; } static u8 sub_808B164(struct ObjectEvent *objectEvent, s16 x, s16 y, u8 direction, u8 metatileBehavior) @@ -953,6 +1046,16 @@ void PlayerSetAnimId(u8 movementActionId, u8 copyableMovement) } } +// slow +static void PlayerGoSlow(u8 direction) +{ + PlayerSetAnimId(GetWalkSlowMovementAction(direction), 2); +} +static void PlayerRunSlow(u8 direction) +{ + PlayerSetAnimId(GetPlayerRunSlowMovementAction(direction), 2); +} + // normal speed (1 speed) void PlayerGoSpeed1(u8 a) { @@ -965,6 +1068,7 @@ void PlayerGoSpeed2(u8 a) PlayerSetAnimId(GetWalkFastMovementAction(a), 2); } +// acro bike speed void PlayerRideWaterCurrent(u8 a) { PlayerSetAnimId(GetRideWaterCurrentMovementAction(a), 2); @@ -2215,3 +2319,83 @@ static u8 TrySpinPlayerForWarp(struct ObjectEvent *object, s16 *delayTimer) *delayTimer = 0; return sSpinDirections[object->facingDirection]; } + +//sideways stairs +static bool8 IsSidewaysStairToRight(s16 x, s16 y, u8 z) +{ + if (GetSidewaysStairsToRightDirection(x, y, z) != 0) + return TRUE; + else + return FALSE; +} + +static bool8 IsSidewaysStairToLeft(s16 x, s16 y, u8 z) +{ + if (GetSidewaysStairsToLeftDirection(x, y, z) != 0) + return TRUE; + else + return FALSE; +} + +u8 GetRightStairsDirection(u8 direction) +{ + switch (direction) + { + case DIR_WEST: + return DIR_SOUTHWEST; + case DIR_EAST: + return DIR_NORTHEAST; + default: + if (direction > DIR_EAST) + direction -= DIR_EAST; + + return direction; + } +} + +u8 GetLeftStairsDirection(u8 direction) +{ + switch (direction) + { + case DIR_WEST: + return DIR_NORTHWEST; + case DIR_EAST: + return DIR_SOUTHEAST; + default: + if (direction > DIR_EAST) + direction -= DIR_EAST; + + return direction; + } +} + +void PlayerSidewaysStairsToRight(u8 direction) +{ + PlayerSetAnimId(GetDiagonalRightStairsMovement(direction), 8); +} + +void PlayerSidewaysStairsToLeft(u8 direction) +{ + PlayerSetAnimId(GetDiagonalLeftStairsMovement(direction), 8); +} + +void PlayerSidewaysStairsToRightRunning(u8 direction) +{ + PlayerSetAnimId(GetDiagonalRightStairsRunningMovement(direction), 8); +} + +void PlayerSidewaysStairsToLeftRunning(u8 direction) +{ + PlayerSetAnimId(GetDiagonalLeftStairsRunningMovement(direction), 8); +} + +void PlayerSidewaysStairsToAcroBikeLeft(u8 direction) +{ + PlayerSetAnimId(GetDiagonalLeftAcroBikeMovement(direction), 8); +} + +void PlayerSidewaysStairsToAcroBikeRight(u8 direction) +{ + PlayerSetAnimId(GetDiagonalRightAcroBikeMovement(direction), 8); +} + diff --git a/src/metatile_behavior.c b/src/metatile_behavior.c index 2a9304a4d..fa773a3b7 100644 --- a/src/metatile_behavior.c +++ b/src/metatile_behavior.c @@ -83,9 +83,9 @@ static const u8 sTileBitAttributes[] = [MB_SLIDE_NORTH] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_SLIDE_SOUTH] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_TRICK_HOUSE_PUZZLE_8_FLOOR] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), - [MB_UNUSED_49] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), - [MB_UNUSED_4A] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), - [MB_UNUSED_4B] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), + [MB_SIDEWAYS_STAIRS_RIGHT] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), + [MB_SIDEWAYS_STAIRS_LEFT] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), + [MB_ROCK_STAIRS] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_UNUSED_4C] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_UNUSED_4D] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_UNUSED_4E] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), @@ -1495,3 +1495,27 @@ bool8 MetatileBehavior_IsTrainerHillTimer(u8 metatileBehavior) else return FALSE; } + +bool8 MetatileBehavior_IsSidewaysStairsRight(u8 metatileBehavior) +{ + if (metatileBehavior == MB_SIDEWAYS_STAIRS_RIGHT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsSidewaysStairsLeft(u8 metatileBehavior) +{ + if (metatileBehavior == MB_SIDEWAYS_STAIRS_LEFT) + return TRUE; + else + return FALSE; +} + +bool8 MetatileBehavior_IsRockStairs(u8 metatileBehavior) +{ + if (metatileBehavior == MB_ROCK_STAIRS) // || metatileBehavior == MB_SIDEWAYS_STAIRS_LEFT || metatileBehavior == MB_SIDEWAYS_STAIRS_RIGHT) + return TRUE; + else + return FALSE; +}