Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ typedef struct Player {
s16 csDelayTimer; // Player_Action_WaitForCutscene: Number of frames to wait before responding to a cutscene
s16 playedLandingSfx; // Player_Action_BlueWarpArrive: Played sfx when landing on the ground
s16 appearTimer; // Player_Action_FaroresWindArrive: Counts up, appear at 20 frames (1 second)
s16 dismountDown; // Player_Action_DismountLadder: True if player is dismounting the ladder downwards
} av2; // "Action Variable 2": context dependent variable that has different meanings depending on what action is currently running

/* 0x0854 */ f32 unk_854;
Expand Down
50 changes: 30 additions & 20 deletions src/overlays/actors/ovl_player_actor/z_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ void Player_Action_8084B9E4(Player* this, PlayState* play);
void Player_Action_8084BBE4(Player* this, PlayState* play);
void Player_Action_8084BDFC(Player* this, PlayState* play);
void Player_Action_8084BF1C(Player* this, PlayState* play);
void Player_Action_8084C5F8(Player* this, PlayState* play);
void Player_Action_DismountLadder(Player* this, PlayState* play);
void Player_Action_8084C760(Player* this, PlayState* play);
void Player_Action_8084C81C(Player* this, PlayState* play);
void Player_Action_8084CC98(Player* this, PlayState* play);
Expand Down Expand Up @@ -7595,8 +7595,8 @@ s32 func_8083EC18(Player* this, PlayState* play, u32 wallFlags) {
return false;
}

void func_8083F070(Player* this, LinkAnimationHeader* anim, PlayState* play) {
Player_SetupActionPreserveAnimMovement(play, this, Player_Action_8084C5F8, 0);
void Player_SetupDismountLadder(Player* this, LinkAnimationHeader* anim, PlayState* play) {
Player_SetupActionPreserveAnimMovement(play, this, Player_Action_DismountLadder, 0);
LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, anim, (4.0f / 3.0f));
}

Expand Down Expand Up @@ -12905,7 +12905,7 @@ void Player_Action_8084BF1C(Player* this, PlayState* play) {
func_8083A9B8(this, &gPlayerAnim_link_normal_jump_climb_up_free, play);
this->stateFlags1 |= PLAYER_STATE1_14;
} else {
func_8083F070(this, this->ageProperties->unk_CC[this->av2.actionVar2], play);
Player_SetupDismountLadder(this, this->ageProperties->unk_CC[this->av2.actionVar2], play);
}
} else {
this->skelAnime.prevTransl = this->ageProperties->unk_4A[sp68];
Expand All @@ -12919,7 +12919,7 @@ void Player_Action_8084BF1C(Player* this, PlayState* play) {
if (this->av2.actionVar2 != 0) {
this->skelAnime.prevTransl = this->ageProperties->unk_44;
}
func_8083F070(this, this->ageProperties->unk_C4[this->av2.actionVar2], play);
Player_SetupDismountLadder(this, this->ageProperties->unk_C4[this->av2.actionVar2], play);
this->av2.actionVar2 = 1;
}
} else {
Expand Down Expand Up @@ -12968,26 +12968,36 @@ void Player_Action_8084BF1C(Player* this, PlayState* play) {
}
}

static f32 D_80854898[] = { 10.0f, 20.0f };
static f32 D_808548A0[] = { 40.0f, 50.0f };
static f32 sUpDismountLadderFrames[] = { 10.0f, 20.0f };
static f32 sDownDismountLadderFrames[] = { 40.0f, 50.0f };

static AnimSfxEntry D_808548A8[] = {
static AnimSfxEntry sDownDismountLadderAnimSfx[] = {
{ NA_SE_PL_WALK_GROUND + SURFACE_SFX_OFFSET_WOOD, ANIMSFX_DATA(ANIMSFX_TYPE_GENERAL, 10) },
{ NA_SE_PL_WALK_GROUND + SURFACE_SFX_OFFSET_WOOD, ANIMSFX_DATA(ANIMSFX_TYPE_GENERAL, 20) },
{ NA_SE_PL_WALK_GROUND + SURFACE_SFX_OFFSET_WOOD, -ANIMSFX_DATA(ANIMSFX_TYPE_GENERAL, 30) },
};

void Player_Action_8084C5F8(Player* this, PlayState* play) {
/**
* Dismounting ladders, both upwards and downwards.
* actionVar2 (dismountDown) true if dismounting down
*/
void Player_Action_DismountLadder(Player* this, PlayState* play) {
s32 interruptResult;
f32* sp38;
f32* frame;
CollisionPoly* groundPoly;
s32 bgId;
Vec3f sp24;
Vec3f raycastPos;

this->stateFlags2 |= PLAYER_STATE2_6;

interruptResult = Player_TryActionInterrupt(play, this, &this->skelAnime, 4.0f);

//! @bug Ladder dismount cutscene softlock. Player_TryActionInterrupt will always return true in cutscene
//! as AH 0 calls AH 13 (due to unk_6AD > 0) and then returns true. This both removes PLAYER_STATE1_CLIMBING
//! below, which causes Player_UpdateCommon to continuously set unk_6AD to 3, and causes the final
//! LinkAnimation_Update (that normally exits the action and sets idle action) to never run.
//! This also causes ladder restricted items softlock with cutscene items (unk_6AD is 4).
//! Adding `&& this->unk_6AD < 3` prevents this softlock, as the animation update can play.
if (interruptResult == PLAYER_INTERRUPT_NEW_ACTION) {
this->stateFlags1 &= ~PLAYER_STATE1_21;
return;
Expand All @@ -12999,18 +13009,18 @@ void Player_Action_8084C5F8(Player* this, PlayState* play) {
return;
}

sp38 = D_80854898;
frame = sUpDismountLadderFrames;

if (this->av2.actionVar2 != 0) {
Player_ProcessAnimSfxList(this, D_808548A8);
sp38 = D_808548A0;
if (this->av2.dismountDown != false) {
Player_ProcessAnimSfxList(this, sDownDismountLadderAnimSfx);
frame = sDownDismountLadderFrames;
}

if (LinkAnimation_OnFrame(&this->skelAnime, sp38[0]) || LinkAnimation_OnFrame(&this->skelAnime, sp38[1])) {
sp24.x = this->actor.world.pos.x;
sp24.y = this->actor.world.pos.y + 20.0f;
sp24.z = this->actor.world.pos.z;
if (BgCheck_EntityRaycastDown3(&play->colCtx, &groundPoly, &bgId, &sp24) != 0.0f) {
if (LinkAnimation_OnFrame(&this->skelAnime, frame[0]) || LinkAnimation_OnFrame(&this->skelAnime, frame[1])) {
raycastPos.x = this->actor.world.pos.x;
raycastPos.y = this->actor.world.pos.y + 20.0f;
raycastPos.z = this->actor.world.pos.z;
if (BgCheck_EntityRaycastDown3(&play->colCtx, &groundPoly, &bgId, &raycastPos) != 0.0f) {
//! @bug should use `SurfaceType_GetSfxOffset` instead of `SurfaceType_GetMaterial`.
// Most material and sfxOffsets share identical enum values,
// so this will mostly result in the correct sfx played, but not in all cases, such as carpet and ice.
Expand Down