diff options
Diffstat (limited to 'src/field_player_avatar.c')
-rw-r--r-- | src/field_player_avatar.c | 211 |
1 files changed, 110 insertions, 101 deletions
diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index f57cc9979..9b1f4ceb6 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -31,7 +31,7 @@ #include "constants/songs.h" #include "constants/trainer_types.h" -static EWRAM_DATA u8 gUnknown_0203734C = 0; +static EWRAM_DATA u8 sSpinStartFacingDir = 0; EWRAM_DATA struct ObjectEvent gObjectEvents[OBJECT_EVENTS_COUNT] = {}; EWRAM_DATA struct PlayerAvatar gPlayerAvatar = {}; @@ -96,7 +96,7 @@ static void PlayerNotOnBikeCollideWithFarawayIslandMew(u8); static void PlayCollisionSoundIfNotFacingWarp(u8 a); -static void sub_808C280(struct ObjectEvent *); +static void HideShowWarpArrow(struct ObjectEvent *); static void StartStrengthAnim(u8, u8); static void Task_PushBoulder(u8 taskId); @@ -138,7 +138,7 @@ static u8 Fishing_PutRodAway(struct Task *task); static u8 Fishing_EndNoMon(struct Task *task); static void AlignFishingAnimationFrames(void); -static u8 sub_808D38C(struct ObjectEvent *object, s16 *a1); +static u8 TrySpinPlayerForWarp(struct ObjectEvent *object, s16 *a1); // .rodata @@ -323,7 +323,7 @@ void PlayerStep(u8 direction, u16 newKeys, u16 heldKeys) { struct ObjectEvent *playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId]; - sub_808C280(playerObjEvent); + HideShowWarpArrow(playerObjEvent); if (gPlayerAvatar.preventStep == FALSE) { Bike_TryAcroBikeHistoryUpdate(newKeys, heldKeys); @@ -382,8 +382,7 @@ static void npc_clear_strange_bits(struct ObjectEvent *objEvent) static void MovePlayerAvatarUsingKeypadInput(u8 direction, u16 newKeys, u16 heldKeys) { - if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE) - || (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)) + if (gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE)) MovePlayerOnBike(direction, newKeys, heldKeys); else MovePlayerNotOnBike(direction, heldKeys); @@ -723,9 +722,9 @@ static bool8 CanStopSurfing(s16 x, s16 y, u8 direction) } } -static bool8 ShouldJumpLedge(s16 x, s16 y, u8 z) +static bool8 ShouldJumpLedge(s16 x, s16 y, u8 direction) { - if (GetLedgeJumpDirection(x, y, z) != 0) + if (GetLedgeJumpDirection(x, y, direction) != DIR_NONE) return TRUE; else return FALSE; @@ -864,7 +863,7 @@ static void PlayerAvatarTransition_Surfing(struct ObjectEvent *objEvent) gFieldEffectArguments[2] = gPlayerAvatar.objectEventId; spriteId = FieldEffectStart(FLDEFF_SURF_BLOB); objEvent->fieldEffectSpriteId = spriteId; - SetSurfBobState(spriteId, 1); + SetSurfBlob_BobState(spriteId, BOB_PLAYER_AND_MON); } static void PlayerAvatarTransition_Underwater(struct ObjectEvent *objEvent) @@ -872,7 +871,7 @@ static void PlayerAvatarTransition_Underwater(struct ObjectEvent *objEvent) ObjectEventSetGraphicsId(objEvent, GetPlayerAvatarGraphicsIdByStateId(PLAYER_AVATAR_STATE_UNDERWATER)); ObjectEventTurn(objEvent, objEvent->movementDirection); SetPlayerAvatarStateMask(PLAYER_AVATAR_FLAG_UNDERWATER); - objEvent->fieldEffectSpriteId = sub_8155800(objEvent->spriteId); + objEvent->fieldEffectSpriteId = StartUnderwaterSurfBlobBobbing(objEvent->spriteId); } static void PlayerAvatarTransition_ReturnToField(struct ObjectEvent *objEvent) @@ -940,9 +939,9 @@ u8 PlayerGetCopyableMovement(void) return gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement; } -static void sub_808B6BC(u8 a) +static void PlayerForceSetHeldMovement(u8 movementActionId) { - ObjectEventForceSetHeldMovement(&gObjectEvents[gPlayerAvatar.objectEventId], a); + ObjectEventForceSetHeldMovement(&gObjectEvents[gPlayerAvatar.objectEventId], movementActionId); } void PlayerSetAnimId(u8 movementActionId, u8 copyableMovement) @@ -1020,12 +1019,13 @@ void PlayerJumpLedge(u8 direction) PlayerSetAnimId(GetJump2MovementAction(direction), 8); } -void sub_808B864(void) +// Stop player on current facing direction once they're done moving and if they're not currently Acro Biking on bumpy slope +void PlayerFreeze(void) { if (gPlayerAvatar.tileTransitionState == T_TILE_CENTER || gPlayerAvatar.tileTransitionState == T_NOT_MOVING) { - if (player_should_look_direction_be_enforced_upon_movement()) - sub_808B6BC(GetFaceDirectionMovementAction(gObjectEvents[gPlayerAvatar.objectEventId].facingDirection)); + if (IsPlayerNotUsingAcroBikeOnBumpySlope()) + PlayerForceSetHeldMovement(GetFaceDirectionMovementAction(gObjectEvents[gPlayerAvatar.objectEventId].facingDirection)); } } @@ -1192,7 +1192,7 @@ u8 GetPlayerAvatarFlags(void) return gPlayerAvatar.flags; } -u8 GetPlayerAvatarObjectId(void) +u8 GetPlayerAvatarSpriteId(void) { return gPlayerAvatar.spriteId; } @@ -1424,7 +1424,7 @@ void SetPlayerAvatarWatering(u8 direction) StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], GetFaceDirectionAnimNum(direction)); } -static void sub_808C280(struct ObjectEvent *objectEvent) +static void HideShowWarpArrow(struct ObjectEvent *objectEvent) { s16 x; s16 y; @@ -1435,6 +1435,7 @@ static void sub_808C280(struct ObjectEvent *objectEvent) { if (sArrowWarpMetatileBehaviorChecks2[x](metatileBehavior) && direction == objectEvent->movementDirection) { + // Show warp arrow if applicable x = objectEvent->currentCoords.x; y = objectEvent->currentCoords.y; MoveCoords(direction, &x, &y); @@ -1645,7 +1646,7 @@ static void Task_StopSurfingInit(u8 taskId) if (!ObjectEventClearHeldMovementIfFinished(playerObjEvent)) return; } - SetSurfBobState(playerObjEvent->fieldEffectSpriteId, 2); + SetSurfBlob_BobState(playerObjEvent->fieldEffectSpriteId, BOB_JUST_MON); ObjectEventSetHeldMovement(playerObjEvent, GetJumpSpecialMovementAction((u8)gTasks[taskId].data[0])); gTasks[taskId].func = Task_WaitStopSurfing; } @@ -1931,7 +1932,7 @@ static bool8 Fishing_StartEncounter(struct Task *task) ObjectEventSetGraphicsId(playerObjEvent, task->tPlayerGfxId); ObjectEventTurn(playerObjEvent, playerObjEvent->movementDirection); if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) - SetSurfBobWhileFishingState(gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId, 0, 0); + SetSurfBlob_PlayerOffset(gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId, FALSE, 0); gSprites[gPlayerAvatar.spriteId].pos2.x = 0; gSprites[gPlayerAvatar.spriteId].pos2.y = 0; ClearDialogWindowAndFrame(0, TRUE); @@ -1988,7 +1989,7 @@ static bool8 Fishing_PutRodAway(struct Task *task) ObjectEventSetGraphicsId(playerObjEvent, task->tPlayerGfxId); ObjectEventTurn(playerObjEvent, playerObjEvent->movementDirection); if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) - SetSurfBobWhileFishingState(gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId, 0, 0); + SetSurfBlob_PlayerOffset(gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId, FALSE, 0); gSprites[gPlayerAvatar.spriteId].pos2.x = 0; gSprites[gPlayerAvatar.spriteId].pos2.y = 0; task->tStep++; @@ -2047,57 +2048,67 @@ static void AlignFishingAnimationFrames(void) if (animType == 10 || animType == 11) playerSprite->pos2.y = 8; if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) - SetSurfBobWhileFishingState(gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId, 1, playerSprite->pos2.y); + SetSurfBlob_PlayerOffset(gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId, TRUE, playerSprite->pos2.y); } -void sub_808D074(u8 a0) +void SetSpinStartFacingDir(u8 direction) { - gUnknown_0203734C = a0; + sSpinStartFacingDir = direction; } -static u8 sub_808D080(void) +static u8 GetSpinStartFacingDir(void) { - if (gUnknown_0203734C == 0) - { - return 1; - } - return gUnknown_0203734C; + if (sSpinStartFacingDir == DIR_NONE) + return DIR_SOUTH; + + return sSpinStartFacingDir; } -static void sub_808D094(u8 taskId) +// Task data for Task_DoPlayerSpinEntrance and Task_DoPlayerSpinExit +#define tState data[0] +#define tSpinDelayTimer data[1] +#define tSpeed data[2] +#define tCurY data[3] +#define tDestY data[4] +#define tStartDir data[5] +#define tPriority data[6] +#define tSubpriority data[7] +#define tGroundTimer data[8] + +static void Task_DoPlayerSpinExit(u8 taskId) { struct ObjectEvent *object = &gObjectEvents[gPlayerAvatar.objectEventId]; struct Sprite *sprite = &gSprites[object->spriteId]; s16 *data = gTasks[taskId].data; - switch (data[0]) + switch (tState) { - case 0: + case 0: // Init if (!ObjectEventClearHeldMovementIfFinished(object)) - { return; - } - sub_808D074(object->facingDirection); - data[1] = 0; - data[2] = 1; - data[3] = (u16)(sprite->pos1.y + sprite->pos2.y) << 4; + SetSpinStartFacingDir(object->facingDirection); + tSpinDelayTimer = 0; + tSpeed = 1; + tCurY = (u16)(sprite->pos1.y + sprite->pos2.y) << 4; sprite->pos2.y = 0; CameraObjectReset2(); object->fixedPriority = TRUE; sprite->oam.priority = 0; sprite->subpriority = 0; sprite->subspriteMode = SUBSPRITES_OFF; - data[0]++; - case 1: - sub_808D38C(object, &data[1]); - data[3] -= data[2]; - data[2] += 3; - sprite->pos1.y = data[3] >> 4; + tState++; + case 1: // Spin while rising + TrySpinPlayerForWarp(object, &tSpinDelayTimer); + + // Rise and accelerate + tCurY -= tSpeed; + tSpeed += 3; + sprite->pos1.y = tCurY >> 4; + + // Check if offscreen if (sprite->pos1.y + (s16)gTotalCameraPixelOffsetY < -32) - { - data[0]++; - } + tState++; break; case 2: DestroyTask(taskId); @@ -2105,84 +2116,86 @@ static void sub_808D094(u8 taskId) } } -static void sub_808D1FC(u8 taskId); +static void Task_DoPlayerSpinEntrance(u8 taskId); -void sub_808D194(void) +void DoPlayerSpinEntrance(void) { - sub_808D1FC(CreateTask(sub_808D1FC, 0)); + Task_DoPlayerSpinEntrance(CreateTask(Task_DoPlayerSpinEntrance, 0)); } -bool32 sub_808D1B4(void) +bool32 IsPlayerSpinEntranceActive(void) { - return FuncIsActiveTask(sub_808D1FC); + return FuncIsActiveTask(Task_DoPlayerSpinEntrance); } -void sub_808D1C8(void) +void DoPlayerSpinExit(void) { - sub_808D094(CreateTask(sub_808D094, 0)); + Task_DoPlayerSpinExit(CreateTask(Task_DoPlayerSpinExit, 0)); } -bool32 sub_808D1E8(void) +bool32 IsPlayerSpinExitActive(void) { - return FuncIsActiveTask(sub_808D094); + return FuncIsActiveTask(Task_DoPlayerSpinExit); } -static const u8 gUnknown_084975BC[] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH}; +static const u8 sSpinDirections[] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH}; -static void sub_808D1FC(u8 taskId) +static void Task_DoPlayerSpinEntrance(u8 taskId) { struct ObjectEvent *object = &gObjectEvents[gPlayerAvatar.objectEventId]; struct Sprite *sprite = &gSprites[object->spriteId]; s16 *data = gTasks[taskId].data; - switch (data[0]) + switch (tState) { case 0: - data[5] = sub_808D080(); - ObjectEventForceSetHeldMovement(object, GetFaceDirectionMovementAction(gUnknown_084975BC[data[5]])); - data[1] = 0; - data[2] = 116; - data[4] = sprite->pos1.y; - data[6] = sprite->oam.priority; - data[7] = sprite->subpriority; - data[3] = -((u16)sprite->pos2.y + 32) * 16; + // Because the spin start facing direction is never set for this + // warp type, the player will always exit the warp facing South. + // This may have been intentional, unclear + tStartDir = GetSpinStartFacingDir(); + ObjectEventForceSetHeldMovement(object, GetFaceDirectionMovementAction(sSpinDirections[tStartDir])); + tSpinDelayTimer = 0; + tSpeed = 116; + tDestY = sprite->pos1.y; + tPriority = sprite->oam.priority; + tSubpriority = sprite->subpriority; + tCurY = -((u16)sprite->pos2.y + 32) * 16; sprite->pos2.y = 0; CameraObjectReset2(); object->fixedPriority = TRUE; sprite->oam.priority = 1; sprite->subpriority = 0; sprite->subspriteMode = SUBSPRITES_OFF; - data[0]++; - case 1: - sub_808D38C(object, &data[1]); - data[3] += data[2]; - data[2] -= 3; - if (data[2] < 4) + tState++; + case 1: // Spin while descending + TrySpinPlayerForWarp(object, &tSpinDelayTimer); + + // Fall and decelerate + tCurY += tSpeed; + tSpeed -= 3; + if (tSpeed < 4) + tSpeed = 4; + sprite->pos1.y = tCurY >> 4; + + // Check if reached dest + if (sprite->pos1.y >= tDestY) { - data[2] = 4; - } - sprite->pos1.y = data[3] >> 4; - if (sprite->pos1.y >= data[4]) - { - sprite->pos1.y = data[4]; - data[8] = 0; - data[0]++; + sprite->pos1.y = tDestY; + tGroundTimer = 0; + tState++; } break; - case 2: - sub_808D38C(object, &data[1]); - data[8]++; - if (data[8] > 8) - { - data[0]++; - } + case 2: // Spin on ground + TrySpinPlayerForWarp(object, &tSpinDelayTimer); + if (++tGroundTimer > 8) + tState++; break; - case 3: - if (data[5] == sub_808D38C(object, &data[1])) + case 3: // Spin until facing original direction + if (tStartDir == TrySpinPlayerForWarp(object, &tSpinDelayTimer)) { object->fixedPriority = 0; - sprite->oam.priority = data[6]; - sprite->subpriority = data[7]; + sprite->oam.priority = tPriority; + sprite->subpriority = tSubpriority; CameraObjectReset1(); DestroyTask(taskId); } @@ -2190,19 +2203,15 @@ static void sub_808D1FC(u8 taskId) } } -static u8 sub_808D38C(struct ObjectEvent *object, s16 *a1) +static u8 TrySpinPlayerForWarp(struct ObjectEvent *object, s16 *delayTimer) { - if (*a1 < 8 && ++(*a1) < 8) - { + if (*delayTimer < 8 && ++(*delayTimer) < 8) return object->facingDirection; - } if (!ObjectEventCheckHeldMovementStatus(object)) - { return object->facingDirection; - } - ObjectEventForceSetHeldMovement(object, GetFaceDirectionMovementAction(gUnknown_084975BC[object->facingDirection])); - *a1 = 0; - return gUnknown_084975BC[object->facingDirection]; + ObjectEventForceSetHeldMovement(object, GetFaceDirectionMovementAction(sSpinDirections[object->facingDirection])); + *delayTimer = 0; + return sSpinDirections[object->facingDirection]; } |