summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event_object_movement.c4
-rw-r--r--src/field_control_avatar.c10
-rw-r--r--src/field_player_avatar.c405
-rw-r--r--src/metatile_behavior.c8
4 files changed, 416 insertions, 11 deletions
diff --git a/src/event_object_movement.c b/src/event_object_movement.c
index a399ddf5e..dbde0cb93 100644
--- a/src/event_object_movement.c
+++ b/src/event_object_movement.c
@@ -4623,8 +4623,8 @@ dirn_to_anim(sub_8063FDC, gUnknown_83A650F);
dirn_to_anim(sub_8064008, gUnknown_83A6514);
dirn_to_anim(GetWalkFastestMovementAction, gUnknown_83A6519);
dirn_to_anim(GetSlideMovementAction, gUnknown_83A651E);
-dirn_to_anim(sub_806408C, gUnknown_83A6523);
-dirn_to_anim(sub_80640B8, gUnknown_83A6528);
+dirn_to_anim(GetPlayerRunMovementAction, gUnknown_83A6523);
+dirn_to_anim(GetPlayerRunSlowMovementAction, gUnknown_83A6528);
dirn_to_anim(sub_80640E4, gUnknown_83A652D);
dirn_to_anim(GetJump2MovementAction, gUnknown_83A6532);
dirn_to_anim(GetJumpInPlaceMovementAction, gUnknown_83A6537);
diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c
index 89b90ca92..da3fb4a03 100644
--- a/src/field_control_avatar.c
+++ b/src/field_control_avatar.c
@@ -105,11 +105,11 @@ void FieldGetPlayerInput(struct FieldInput *input, u16 newKeys, u16 heldKeys)
{
if (GetPlayerSpeed() != 4)
{
- if ((newKeys & START_BUTTON) && !(gPlayerAvatar.flags & 0x40))
+ if ((newKeys & START_BUTTON) && !(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MVMT_IS_FORCED))
input->pressedStartButton = TRUE;
if (gQuestLogState != QL_STATE_2 && gQuestLogState != QL_STATE_3)
{
- if (!(gPlayerAvatar.flags & 0x40))
+ if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MVMT_IS_FORCED))
{
if (newKeys & SELECT_BUTTON)
input->pressedSelectButton = TRUE;
@@ -625,7 +625,7 @@ static bool8 TryStartStepBasedScript(struct MapPosition *position, u16 metatileB
return TRUE;
if (TryStartStepCountScript(metatileBehavior) == TRUE)
return TRUE;
- if (!(gPlayerAvatar.flags & 0x40) && !MetatileBehavior_IsForcedMovementTile(metatileBehavior) && UpdateRepelCounter() == TRUE)
+ if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MVMT_IS_FORCED) && !MetatileBehavior_IsForcedMovementTile(metatileBehavior) && UpdateRepelCounter() == TRUE)
return TRUE;
return FALSE;
}
@@ -655,7 +655,7 @@ static bool8 TryStartStepCountScript(u16 metatileBehavior)
UpdateHappinessStepCounter();
- if (!(gPlayerAvatar.flags & 0x40) && !MetatileBehavior_IsForcedMovementTile(metatileBehavior))
+ if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MVMT_IS_FORCED) && !MetatileBehavior_IsForcedMovementTile(metatileBehavior))
{
if (sub_810C4EC() == TRUE)
{
@@ -839,7 +839,7 @@ static bool8 TryArrowWarp(struct MapPosition *position, u16 metatileBehavior, u8
else if (sub_806DB84(metatileBehavior, direction) == TRUE)
{
delay = 0;
- if (gPlayerAvatar.flags & 6)
+ if (gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
{
SetPlayerAvatarTransitionFlags(1);
delay = 12;
diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c
new file mode 100644
index 000000000..33c68a253
--- /dev/null
+++ b/src/field_player_avatar.c
@@ -0,0 +1,405 @@
+#include "global.h"
+#include "gflib.h"
+#include "bike.h"
+#include "event_object_movement.h"
+#include "field_player_avatar.h"
+#include "metatile_behavior.h"
+#include "constants/event_object_movement.h"
+#include "constants/songs.h"
+
+EWRAM_DATA struct ObjectEvent * gUnknown_2036E30 = NULL;
+EWRAM_DATA bool8 gUnknown_2036E34 = FALSE;
+EWRAM_DATA struct ObjectEvent gObjectEvents[OBJECT_EVENTS_COUNT] = {};
+EWRAM_DATA struct PlayerAvatar gPlayerAvatar = {};
+
+u8 ObjectEventCB2_NoMovement2(struct ObjectEvent * object, struct Sprite * sprite);
+bool8 sub_805B528(void);
+bool8 TryInterruptObjectEventSpecialAnim(struct ObjectEvent * playerObjEvent, u8 direction);
+void npc_clear_strange_bits(struct ObjectEvent * playerObjEvent);
+void DoPlayerAvatarTransition(void);
+bool8 TryDoMetatileBehaviorForcedMovement(void);
+void MovePlayerAvatarUsingKeypadInput(u8 direction, u16 newKeys, u16 heldKeys);
+void PlayerAllowForcedMovementIfMovingSameDirection(void);
+bool8 ForcedMovement_None(void);
+void PlayerJumpLedge(u8 direction);
+u8 CheckForPlayerAvatarCollision(u8 direction);
+bool8 ForcedMovement_Slip(void);
+bool8 ForcedMovement_WalkSouth(void);
+bool8 ForcedMovement_WalkNorth(void);
+bool8 ForcedMovement_WalkWest(void);
+bool8 ForcedMovement_WalkEast(void);
+bool8 ForcedMovement_SpinRight(void);
+bool8 ForcedMovement_SpinLeft(void);
+bool8 ForcedMovement_SpinUp(void);
+bool8 ForcedMovement_SpinDown(void);
+void PlaySpinSound(void);
+bool8 ForcedMovement_PushedSouthByCurrent(void);
+bool8 ForcedMovement_PushedNorthByCurrent(void);
+bool8 ForcedMovement_PushedWestByCurrent(void);
+bool8 ForcedMovement_PushedEastByCurrent(void);
+bool8 ForcedMovement_SlideSouth(void);
+bool8 ForcedMovement_SlideNorth(void);
+bool8 ForcedMovement_SlideWest(void);
+bool8 ForcedMovement_SlideEast(void);
+bool8 ForcedMovement_0xBB(void);
+bool8 ForcedMovement_0xBC(void);
+u8 CheckMovementInputNotOnBike(u8 direction);
+void PlayerNotOnBikeNotMoving(u8 direction, u16 heldKeys);
+void PlayerNotOnBikeTurningInPlace(u8 direction, u16 heldKeys);
+void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys);
+void PlayerGoSpeed2(u8 direction);
+void PlayerGoSpeed1(u8 direction);
+void PlayerGoSpin(u8 direction);
+void PlayerRideWaterCurrent(u8 direction);
+void sub_805C2CC(u8 metatileBehavior);
+void sub_805CC40(struct ObjectEvent * playerObjEvent);
+void DoPlayerMatJump(void);
+void DoPlayerMatSpin(void);
+
+void MovementType_Player(struct Sprite *sprite)
+{
+ UpdateObjectEventCurrentMovement(&gObjectEvents[sprite->data[0]], sprite, ObjectEventCB2_NoMovement2);
+}
+
+u8 ObjectEventCB2_NoMovement2(struct ObjectEvent * object, struct Sprite * sprite)
+{
+ return 0;
+}
+
+void player_step(u8 direction, u16 newKeys, u16 heldKeys)
+{
+ struct ObjectEvent *playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
+
+ sub_805CC40(playerObjEvent);
+ if (!gPlayerAvatar.preventStep && !sub_805B528())
+ {
+ if (!TryInterruptObjectEventSpecialAnim(playerObjEvent, direction))
+ {
+ npc_clear_strange_bits(playerObjEvent);
+ DoPlayerAvatarTransition();
+ if (!TryDoMetatileBehaviorForcedMovement())
+ {
+ MovePlayerAvatarUsingKeypadInput(direction, newKeys, heldKeys);
+ PlayerAllowForcedMovementIfMovingSameDirection();
+ }
+ }
+ }
+}
+
+bool8 TryInterruptObjectEventSpecialAnim(struct ObjectEvent *playerObjEvent, u8 direction)
+{
+
+ if (ObjectEventIsMovementOverridden(playerObjEvent)
+ && !ObjectEventClearHeldMovementIfFinished(playerObjEvent))
+ {
+ u8 heldMovementActionId = ObjectEventGetHeldMovementActionId(playerObjEvent);
+ if (heldMovementActionId > MOVEMENT_ACTION_WALK_FAST_RIGHT && heldMovementActionId < MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_DOWN)
+ {
+ if (direction != DIR_NONE && playerObjEvent->movementDirection != direction)
+ {
+ ObjectEventClearHeldMovement(playerObjEvent);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void npc_clear_strange_bits(struct ObjectEvent *objEvent)
+{
+ objEvent->inanimate = 0;
+ objEvent->disableAnim = 0;
+ objEvent->facingDirectionLocked = 0;
+ gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_DASH;
+}
+
+void MovePlayerAvatarUsingKeypadInput(u8 direction, u16 newKeys, u16 heldKeys)
+{
+ if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE)
+ || (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ MovePlayerOnBike(direction, newKeys, heldKeys);
+ else
+ MovePlayerNotOnBike(direction, heldKeys);
+}
+
+void PlayerAllowForcedMovementIfMovingSameDirection(void)
+{
+ if (gPlayerAvatar.runningState == MOVING)
+ gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_FORCED_MVMT_DISABLED;
+}
+
+bool8 sub_805B528(void)
+{
+ if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MVMT_IS_FORCED) && MetatileBehavior_IsSpinTile(gPlayerAvatar.unk1C))
+ {
+ gUnknown_2036E30 = &gObjectEvents[gPlayerAvatar.objectEventId];
+ if (gUnknown_2036E30->heldMovementFinished)
+ {
+ if (MetatileBehavior_IsStopSpinning(gUnknown_2036E30->currentMetatileBehavior))
+ {
+ return FALSE;
+ }
+ if (MetatileBehavior_IsSpinTile(gUnknown_2036E30->currentMetatileBehavior))
+ {
+ gPlayerAvatar.unk1C = gUnknown_2036E30->currentMetatileBehavior;
+ }
+ ObjectEventClearHeldMovement(gUnknown_2036E30);
+ sub_805C2CC(gPlayerAvatar.unk1C);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+const struct {
+ bool8 (*unk0)(u8 metatileBehavior);
+ bool8 (*unk4)(void);
+} sForcedMovementFuncs[] = {
+ {MetatileBehavior_IsUnknownMovement48, ForcedMovement_Slip},
+ {MetatileBehavior_IsIce_2, ForcedMovement_Slip},
+ {MetatileBehavior_IsWalkSouth, ForcedMovement_WalkSouth},
+ {MetatileBehavior_IsWalkNorth, ForcedMovement_WalkNorth},
+ {MetatileBehavior_IsWalkWest, ForcedMovement_WalkWest},
+ {MetatileBehavior_IsWalkEast, ForcedMovement_WalkEast},
+ {MetatileBehavior_IsSouthwardCurrent, ForcedMovement_PushedSouthByCurrent},
+ {MetatileBehavior_IsNorthwardCurrent, ForcedMovement_PushedNorthByCurrent},
+ {MetatileBehavior_IsWestwardCurrent, ForcedMovement_PushedWestByCurrent},
+ {MetatileBehavior_IsEastwardCurrent, ForcedMovement_PushedEastByCurrent},
+ {MetatileBehavior_IsSpinRight, ForcedMovement_SpinRight},
+ {MetatileBehavior_IsSpinLeft, ForcedMovement_SpinLeft},
+ {MetatileBehavior_IsSpinUp, ForcedMovement_SpinUp},
+ {MetatileBehavior_IsSpinDown, ForcedMovement_SpinDown},
+ {MetatileBehavior_IsSlideSouth, ForcedMovement_SlideSouth},
+ {MetatileBehavior_IsSlideNorth, ForcedMovement_SlideNorth},
+ {MetatileBehavior_IsSlideWest, ForcedMovement_SlideWest},
+ {MetatileBehavior_IsSlideEast, ForcedMovement_SlideEast},
+ {MetatileBehavior_IsWaterfall, ForcedMovement_PushedSouthByCurrent},
+ {MetatileBehavior_UnusedReturnFalse_7, ForcedMovement_0xBB},
+ {MetatileBehavior_UnusedReturnFalse_8, ForcedMovement_0xBC},
+ {NULL, ForcedMovement_None},
+};
+
+bool8 TryDoMetatileBehaviorForcedMovement(void)
+{
+ int i;
+ u8 behavior;
+ if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_FORCED_MVMT_DISABLED))
+ {
+ behavior = gObjectEvents[gPlayerAvatar.objectEventId].currentMetatileBehavior;
+ for (i = 0; sForcedMovementFuncs[i].unk0 != NULL; i++)
+ {
+ if (sForcedMovementFuncs[i].unk0(behavior))
+ {
+ gPlayerAvatar.unk1C = behavior;
+ return sForcedMovementFuncs[i].unk4();
+ }
+ }
+ return sForcedMovementFuncs[i].unk4();
+ }
+ else
+ {
+ for (i = 0; sForcedMovementFuncs[i].unk0 != NULL; i++)
+ ;
+ return sForcedMovementFuncs[i].unk4();
+ }
+}
+
+bool8 ForcedMovement_None(void)
+{
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MVMT_IS_FORCED)
+ {
+ struct ObjectEvent *playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
+
+ playerObjEvent->facingDirectionLocked = FALSE;
+ playerObjEvent->enableAnim = TRUE;
+ SetObjectEventDirection(playerObjEvent, playerObjEvent->facingDirection);
+ gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_MVMT_IS_FORCED;
+ }
+ return FALSE;
+}
+
+u8 DoForcedMovement(u8 direction, MovementAction movementAction)
+{
+ struct PlayerAvatar *playerAvatar = &gPlayerAvatar;
+ u8 collision = CheckForPlayerAvatarCollision(direction);
+
+ playerAvatar->flags |= PLAYER_AVATAR_FLAG_MVMT_IS_FORCED;
+ if (collision)
+ {
+ ForcedMovement_None();
+ if (collision < COLLISION_STOP_SURFING)
+ {
+ return 0;
+ }
+ else
+ {
+ if (collision == COLLISION_LEDGE_JUMP)
+ PlayerJumpLedge(direction);
+ playerAvatar->flags |= PLAYER_AVATAR_FLAG_MVMT_IS_FORCED;
+ playerAvatar->runningState = MOVING;
+ return 1;
+ }
+ }
+ else
+ {
+ playerAvatar->runningState = MOVING;
+ movementAction(direction);
+ return 1;
+ }
+}
+
+u8 DoForcedMovementInCurrentDirection(MovementAction movementAction)
+{
+ struct ObjectEvent *playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
+
+ playerObjEvent->disableAnim = TRUE;
+ return DoForcedMovement(playerObjEvent->movementDirection, movementAction);
+}
+
+bool8 ForcedMovement_Slip(void)
+{
+ return DoForcedMovementInCurrentDirection(PlayerGoSpeed2);
+}
+
+bool8 ForcedMovement_WalkSouth(void)
+{
+ return DoForcedMovement(DIR_SOUTH, PlayerGoSpeed1);
+}
+
+bool8 ForcedMovement_WalkNorth(void)
+{
+ return DoForcedMovement(DIR_NORTH, PlayerGoSpeed1);
+}
+
+bool8 ForcedMovement_WalkWest(void)
+{
+ return DoForcedMovement(DIR_WEST, PlayerGoSpeed1);
+}
+
+bool8 ForcedMovement_WalkEast(void)
+{
+ return DoForcedMovement(DIR_EAST, PlayerGoSpeed1);
+}
+
+bool8 ForcedMovement_SpinRight(void)
+{
+ PlaySpinSound();
+ return DoForcedMovement(DIR_EAST, PlayerGoSpin);
+}
+
+bool8 ForcedMovement_SpinLeft(void)
+{
+ PlaySpinSound();
+ return DoForcedMovement(DIR_WEST, PlayerGoSpin);
+}
+
+bool8 ForcedMovement_SpinUp(void)
+{
+ PlaySpinSound();
+ return DoForcedMovement(DIR_NORTH, PlayerGoSpin);
+}
+
+bool8 ForcedMovement_SpinDown(void)
+{
+ PlaySpinSound();
+ return DoForcedMovement(DIR_SOUTH, PlayerGoSpin);
+}
+
+void PlaySpinSound(void)
+{
+ PlaySE(SE_W013B);
+}
+
+bool8 ForcedMovement_PushedSouthByCurrent(void)
+{
+ return DoForcedMovement(DIR_SOUTH, PlayerRideWaterCurrent);
+}
+
+bool8 ForcedMovement_PushedNorthByCurrent(void)
+{
+ return DoForcedMovement(DIR_NORTH, PlayerRideWaterCurrent);
+}
+
+bool8 ForcedMovement_PushedWestByCurrent(void)
+{
+ return DoForcedMovement(DIR_WEST, PlayerRideWaterCurrent);
+}
+
+bool8 ForcedMovement_PushedEastByCurrent(void)
+{
+ return DoForcedMovement(DIR_EAST, PlayerRideWaterCurrent);
+}
+
+u8 ForcedMovement_Slide(u8 direction, MovementAction movementAction)
+{
+ struct ObjectEvent *playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
+
+ playerObjEvent->disableAnim = TRUE;
+ playerObjEvent->facingDirectionLocked = TRUE;
+ return DoForcedMovement(direction, movementAction);
+}
+
+bool8 ForcedMovement_SlideSouth(void)
+{
+ return ForcedMovement_Slide(DIR_SOUTH, PlayerGoSpeed2);
+}
+
+bool8 ForcedMovement_SlideNorth(void)
+{
+ return ForcedMovement_Slide(DIR_NORTH, PlayerGoSpeed2);
+}
+
+bool8 ForcedMovement_SlideWest(void)
+{
+ return ForcedMovement_Slide(DIR_WEST, PlayerGoSpeed2);
+}
+
+bool8 ForcedMovement_SlideEast(void)
+{
+ return ForcedMovement_Slide(DIR_EAST, PlayerGoSpeed2);
+}
+
+bool8 ForcedMovement_0xBB(void)
+{
+ DoPlayerMatJump();
+ return TRUE;
+}
+
+bool8 ForcedMovement_0xBC(void)
+{
+ DoPlayerMatSpin();
+ return TRUE;
+}
+
+void (*const gUnknown_835B814[])(u8, u16) = {
+ PlayerNotOnBikeNotMoving,
+ PlayerNotOnBikeTurningInPlace,
+ PlayerNotOnBikeMoving
+};
+
+void MovePlayerNotOnBike(u8 direction, u16 heldKeys)
+{
+ gUnknown_835B814[CheckMovementInputNotOnBike(direction)](direction, heldKeys);
+}
+
+u8 CheckMovementInputNotOnBike(u8 direction)
+{
+ if (direction == DIR_NONE)
+ {
+ gPlayerAvatar.runningState = NOT_MOVING;
+ return 0;
+ }
+ else if (direction != GetPlayerMovementDirection() && gPlayerAvatar.runningState != MOVING)
+ {
+ gPlayerAvatar.runningState = TURN_DIRECTION;
+ return 1;
+ }
+ else
+ {
+ gPlayerAvatar.runningState = MOVING;
+ return 2;
+ }
+}
diff --git a/src/metatile_behavior.c b/src/metatile_behavior.c
index d6a983744..988c9fad0 100644
--- a/src/metatile_behavior.c
+++ b/src/metatile_behavior.c
@@ -750,7 +750,7 @@ bool8 TestMetatileAttributeBit(u8 arg1, u8 arg2)
return FALSE;
}
-bool8 MetatileBehavior_UnusedIsSpinRight(u8 metatileBehavior)
+bool8 MetatileBehavior_IsSpinRight(u8 metatileBehavior)
{
if(metatileBehavior == MB_SPIN_RIGHT)
return TRUE;
@@ -758,7 +758,7 @@ bool8 MetatileBehavior_UnusedIsSpinRight(u8 metatileBehavior)
return FALSE;
}
-bool8 MetatileBehavior_UnusedIsSpinLeft(u8 metatileBehavior)
+bool8 MetatileBehavior_IsSpinLeft(u8 metatileBehavior)
{
if(metatileBehavior == MB_SPIN_LEFT)
return TRUE;
@@ -766,7 +766,7 @@ bool8 MetatileBehavior_UnusedIsSpinLeft(u8 metatileBehavior)
return FALSE;
}
-bool8 MetatileBehavior_UnusedIsSpinUp(u8 metatileBehavior)
+bool8 MetatileBehavior_IsSpinUp(u8 metatileBehavior)
{
if(metatileBehavior == MB_SPIN_UP)
return TRUE;
@@ -774,7 +774,7 @@ bool8 MetatileBehavior_UnusedIsSpinUp(u8 metatileBehavior)
return FALSE;
}
-bool8 MetatileBehavior_UnusedIsSpinDown(u8 metatileBehavior)
+bool8 MetatileBehavior_IsSpinDown(u8 metatileBehavior)
{
if(metatileBehavior == MB_SPIN_DOWN)
return TRUE;