From a23f716209b7e765030d2f58bb9adc72eeb4d522 Mon Sep 17 00:00:00 2001 From: Evan Date: Tue, 14 Jul 2020 14:28:02 -0600 Subject: [PATCH] add slow stair movement back --- include/constants/global.h | 2 + include/field_player_avatar.h | 2 +- include/metatile_behavior.h | 1 + src/bike.c | 12 ++++-- src/event_object_movement.c | 73 +++++++++++++++++------------------ src/field_player_avatar.c | 41 +++++++++++++++++++- src/metatile_behavior.c | 9 +++++ 7 files changed, 95 insertions(+), 45 deletions(-) diff --git a/include/constants/global.h b/include/constants/global.h index 213ccca5b5..acc1f353d5 100644 --- a/include/constants/global.h +++ b/include/constants/global.h @@ -118,4 +118,6 @@ #define DIR_NORTHWEST 7 #define DIR_NORTHEAST 8 +#define SLOW_MOVEMENT_ON_STAIRS TRUE + #endif // GUARD_CONSTANTS_GLOBAL_H diff --git a/include/field_player_avatar.h b/include/field_player_avatar.h index 0f53e0b28d..658dc09d0a 100644 --- a/include/field_player_avatar.h +++ b/include/field_player_avatar.h @@ -64,7 +64,7 @@ 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); +bool8 ObjectMovingOnRockStairs(struct ObjectEvent *objectEvent, u8 direction); //sideways stairs u8 GetRightSideStairsDirection(u8 direction); u8 GetLeftSideStairsDirection(u8 direction); diff --git a/include/metatile_behavior.h b/include/metatile_behavior.h index 128978cae6..58d6e82d76 100644 --- a/include/metatile_behavior.h +++ b/include/metatile_behavior.h @@ -145,6 +145,7 @@ bool8 MetatileBehavior_IsQuestionnaire(u8); bool8 MetatileBehavior_IsLongGrass_Duplicate(u8); bool8 MetatileBehavior_IsLongGrassSouthEdge(u8); bool8 MetatileBehavior_IsTrainerHillTimer(u8); +bool8 MetatileBehavior_IsRockStairs(u8); //sideways stairs bool8 MetatileBehavior_IsSidewaysStairsRightSide(u8); bool8 MetatileBehavior_IsSidewaysStairsLeftSide(u8); diff --git a/src/bike.c b/src/bike.c index 1fe5b58b43..7c9eb0cf5c 100644 --- a/src/bike.c +++ b/src/bike.c @@ -246,6 +246,9 @@ static void MachBikeTransition_TrySpeedUp(u8 direction) } else { + if (ObjectMovingOnRockStairs(playerObjEvent, direction) && gPlayerAvatar.bikeFrameCounter > 1) + 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 @@ -380,7 +383,6 @@ static u8 AcroBikeHandleInputWheelieStanding(u8 *newDirection, u16 newKeys, u16 struct ObjectEvent *playerObjEvent; direction = GetPlayerMovementDirection(); - //gSidewaysStairsDirection = direction; playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId]; gPlayerAvatar.runningState = NOT_MOVING; @@ -577,7 +579,10 @@ static void AcroBikeTransition_Moving(u8 direction) } else { - PlayerRideWaterCurrent(direction); + if (ObjectMovingOnRockStairs(playerObjEvent, direction)) + PlayerGoSpeed2(direction); + else + PlayerRideWaterCurrent(direction); } } @@ -645,7 +650,7 @@ static void AcroBikeTransition_WheelieHoppingMoving(u8 direction) } else { - derp: + derp: PlayerMovingHoppingWheelie(direction); } } @@ -1033,7 +1038,6 @@ void Bike_UpdateBikeCounterSpeed(u8 counter) static void Bike_SetBikeStill(void) { - //gSidewaysStairsDirection = gObjectEvents[gPlayerAvatar.objectEventId].facingDirection; gPlayerAvatar.bikeFrameCounter = 0; gPlayerAvatar.bikeSpeed = SPEED_STANDING; } diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 1695388029..fc13c96643 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -135,7 +135,6 @@ static bool8 AnimateSpriteInFigure8(struct Sprite *sprite); static void UpdateObjectEventSprite(struct Sprite *); static void StartSlowRunningAnim(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 direction); -static bool8 npc_obj_ministep_stop_on_arrival_slow(struct ObjectEvent *objectEvent, struct Sprite *sprite); const u8 gReflectionEffectPaletteMap[] = {1, 1, 6, 7, 8, 9, 6, 7, 8, 9, 11, 11, 0, 0, 0, 0}; @@ -1142,6 +1141,10 @@ const u8 gRunSlowMovementActions[] = { [DIR_NORTH] = MOVEMENT_ACTION_RUN_UP_SLOW, [DIR_WEST] = MOVEMENT_ACTION_RUN_LEFT_SLOW, [DIR_EAST] = MOVEMENT_ACTION_RUN_RIGHT_SLOW, + [DIR_SOUTHWEST] = MOVEMENT_ACTION_RUN_LEFT_SLOW, + [DIR_SOUTHEAST] = MOVEMENT_ACTION_RUN_RIGHT_SLOW, + [DIR_NORTHWEST] = MOVEMENT_ACTION_RUN_LEFT_SLOW, + [DIR_NORTHEAST] = MOVEMENT_ACTION_RUN_RIGHT_SLOW, }; const u8 gOppositeDirections[] = { @@ -5170,10 +5173,35 @@ bool8 ObjectEventIsHeldMovementActive(struct ObjectEvent *objectEvent) return FALSE; } +static u8 TryUpdateMovementActionOnStairs(struct ObjectEvent *objectEvent, u8 movementActionId) +{ + if (objectEvent->isPlayer) + return movementActionId; //handled separately + + if (!ObjectMovingOnRockStairs(objectEvent, objectEvent->movementDirection)) + return movementActionId; + + switch (movementActionId) + { + case MOVEMENT_ACTION_WALK_NORMAL_DOWN: + return MOVEMENT_ACTION_WALK_SLOW_DOWN; + case MOVEMENT_ACTION_WALK_NORMAL_UP: + return MOVEMENT_ACTION_WALK_SLOW_UP; + case MOVEMENT_ACTION_WALK_NORMAL_LEFT: + return MOVEMENT_ACTION_WALK_SLOW_LEFT; + case MOVEMENT_ACTION_WALK_NORMAL_RIGHT: + return MOVEMENT_ACTION_WALK_SLOW_RIGHT; + default: + return movementActionId; + } +} + bool8 ObjectEventSetHeldMovement(struct ObjectEvent *objectEvent, u8 movementActionId) { if (ObjectEventIsMovementOverridden(objectEvent)) return TRUE; + + movementActionId = TryUpdateMovementActionOnStairs(objectEvent, movementActionId); UnfreezeObjectEvent(objectEvent); objectEvent->movementActionId = movementActionId; @@ -5185,6 +5213,7 @@ bool8 ObjectEventSetHeldMovement(struct ObjectEvent *objectEvent, u8 movementAct void ObjectEventForceSetHeldMovement(struct ObjectEvent *objectEvent, u8 movementActionId) { + movementActionId = TryUpdateMovementActionOnStairs(objectEvent, movementActionId); ObjectEventClearHeldMovementIfActive(objectEvent); ObjectEventSetHeldMovement(objectEvent, movementActionId); } @@ -5224,7 +5253,7 @@ u8 ObjectEventClearHeldMovementIfFinished(struct ObjectEvent *objectEvent) u8 ObjectEventGetHeldMovementActionId(struct ObjectEvent *objectEvent) { if (objectEvent->heldMovementActive) - return objectEvent->movementActionId; + return TryUpdateMovementActionOnStairs(objectEvent, objectEvent->movementActionId); return 0xFF; } @@ -5329,6 +5358,7 @@ static u32 state_to_direction(u8 a0, u32 a1, u32 a2) static void ObjectEventExecHeldMovementAction(struct ObjectEvent *objectEvent, struct Sprite *sprite) { + objectEvent->movementActionId = TryUpdateMovementActionOnStairs(objectEvent, objectEvent->movementActionId); if (gMovementActionFuncs[objectEvent->movementActionId][sprite->data[2]](objectEvent, sprite)) { objectEvent->heldMovementFinished = TRUE; @@ -5337,6 +5367,7 @@ static void ObjectEventExecHeldMovementAction(struct ObjectEvent *objectEvent, s static bool8 ObjectEventExecSingleMovementAction(struct ObjectEvent *objectEvent, struct Sprite *sprite) { + objectEvent->movementActionId = TryUpdateMovementActionOnStairs(objectEvent, objectEvent->movementActionId); if (gMovementActionFuncs[objectEvent->movementActionId][sprite->data[2]](objectEvent, sprite)) { objectEvent->movementActionId = 0xFF; @@ -5348,7 +5379,7 @@ static bool8 ObjectEventExecSingleMovementAction(struct ObjectEvent *objectEvent static void ObjectEventSetSingleMovement(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 animId) { - objectEvent->movementActionId = animId; + objectEvent->movementActionId = TryUpdateMovementActionOnStairs(objectEvent, animId); sprite->data[2] = 0; } @@ -9359,40 +9390,6 @@ static void StartSlowRunningAnim(struct ObjectEvent *objectEvent, struct Sprite 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); @@ -9425,7 +9422,7 @@ bool8 MovementActionFunc_RunSlowRight_Step0(struct ObjectEvent *objectEvent, str bool8 MovementActionFunc_RunSlow_Step1(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - if (npc_obj_ministep_stop_on_arrival_slow(objectEvent, sprite)) + if (npc_obj_ministep_stop_on_arrival(objectEvent, sprite)) { sprite->data[2] = 2; return TRUE; diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 2d70fd2b10..19e3fb4869 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -643,13 +643,20 @@ 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 (ObjectMovingOnRockStairs(&gObjectEvents[gPlayerAvatar.objectEventId], direction)) + PlayerRunSlow(direction); + else + PlayerRun(direction); + gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_DASH; return; } else { - PlayerGoSpeed1(direction); + if (ObjectMovingOnRockStairs(&gObjectEvents[gPlayerAvatar.objectEventId], direction)) + PlayerGoSlow(direction); + else + PlayerGoSpeed1(direction); } } @@ -2283,3 +2290,33 @@ u8 GetLeftSideStairsDirection(u8 direction) } } +bool8 ObjectMovingOnRockStairs(struct ObjectEvent *objectEvent, u8 direction) +{ + #if SLOW_MOVEMENT_ON_STAIRS + 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: + case DIR_EAST: + case DIR_NORTHEAST: + case DIR_NORTHWEST: + case DIR_SOUTHWEST: + case DIR_SOUTHEAST: + // directionOverwrite is only used for sideways stairs motion + if (objectEvent->directionOverwrite) + return TRUE; + default: + return FALSE; + } + #else + return FALSE; + #endif +} + diff --git a/src/metatile_behavior.c b/src/metatile_behavior.c index ab5d6f288d..ea397ab91d 100644 --- a/src/metatile_behavior.c +++ b/src/metatile_behavior.c @@ -1564,3 +1564,12 @@ bool8 MetatileBehavior_IsSidewaysStairsLeftSideAny(u8 metatileBehavior) return FALSE; } +bool8 MetatileBehavior_IsRockStairs(u8 metatileBehavior) +{ + if (metatileBehavior == MB_ROCK_STAIRS) + return TRUE; + else + return FALSE; +} + +