mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-12 04:07:43 -04:00
Vanilla bugfix, ladder cutscene softlock (#6804)
This commit is contained in:
@@ -845,7 +845,7 @@ typedef struct Player {
|
||||
/* 0x06A4 */ f32 closestSecretDistSq;
|
||||
/* 0x06A8 */ Actor* unk_6A8;
|
||||
/* 0x06AC */ s8 idleType;
|
||||
/* 0x06AD */ u8 unk_6AD;
|
||||
/* 0x06AD */ u8 unk_6AD; // Camera related. 0 = normal, 1 = first person without weapon, 2 = first person with weapon, 3 = cutscene action, 4 = cutscene items
|
||||
/* 0x06AE */ u16 unk_6AE_rotFlags; // See `UNK6AE_ROT_` macros. If its flag isn't set, a rot steps to 0.
|
||||
/* 0x06B0 */ s16 upperLimbYawSecondary;
|
||||
/* 0x06B2 */ char unk_6B4[0x004];
|
||||
|
||||
@@ -73,6 +73,15 @@ void RegisterAlwaysOnFixes() {
|
||||
}
|
||||
});
|
||||
|
||||
// Dismounting a ladder in a cutscene or using cutscene item (using restricted items glitch) i.e.
|
||||
// `player->unk_6AD` == 3 or 4 softlocks as animation update stops. Let animation continue in that case.
|
||||
COND_VB_SHOULD(VB_INTERRUPT_LADDER_DISMOUNT, true, {
|
||||
u8* unk_6AD = va_arg(args, u8*);
|
||||
if (*unk_6AD >= 3) {
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_PREVENT_HBA_FANFARE_SOFTLOCK_TIMER, true, {
|
||||
EnHorse* enHorse = va_arg(args, EnHorse*);
|
||||
if (enHorse->hbaFlags & 1) {
|
||||
|
||||
@@ -3270,6 +3270,14 @@ typedef enum {
|
||||
// - `*EnItem00`
|
||||
VB_ITEM00_KILL,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// interruptResult == PLAYER_INTERRUPT_NEW_ACTION
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*u8 (&player->unk_6AD)`
|
||||
VB_INTERRUPT_LADDER_DISMOUNT,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
||||
@@ -300,7 +300,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);
|
||||
@@ -7597,8 +7597,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));
|
||||
}
|
||||
|
||||
@@ -13233,7 +13233,7 @@ void Player_Action_8084BF1C(Player* this, PlayState* play) {
|
||||
func_8083A9B8(this, &gPlayerAnim_link_normal_jump_climb_up_free, play);
|
||||
this->stateFlags1 |= PLAYER_STATE1_CLIMBING_LEDGE;
|
||||
} 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];
|
||||
@@ -13247,7 +13247,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 {
|
||||
@@ -13296,50 +13296,56 @@ 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_LADDER, ANIMSFX_DATA(ANIMSFX_TYPE_GENERAL, 10) },
|
||||
{ NA_SE_PL_WALK_LADDER, ANIMSFX_DATA(ANIMSFX_TYPE_GENERAL, 20) },
|
||||
{ NA_SE_PL_WALK_LADDER, -ANIMSFX_DATA(ANIMSFX_TYPE_GENERAL, 30) },
|
||||
};
|
||||
|
||||
void Player_Action_8084C5F8(Player* this, PlayState* play) {
|
||||
s32 temp;
|
||||
f32* sp38;
|
||||
CollisionPoly* sp34;
|
||||
s32 sp30;
|
||||
Vec3f sp24;
|
||||
/**
|
||||
* Dismounting ladders, both upwards and downwards.
|
||||
* `actionVar2` true if dismounting down
|
||||
*/
|
||||
void Player_Action_DismountLadder(Player* this, PlayState* play) {
|
||||
s32 interruptResult;
|
||||
f32* frame;
|
||||
CollisionPoly* groundPoly;
|
||||
s32 bgId;
|
||||
Vec3f raycastPos;
|
||||
|
||||
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
|
||||
|
||||
temp = Player_TryActionInterrupt(play, this, &this->skelAnime, 4.0f);
|
||||
interruptResult = Player_TryActionInterrupt(play, this, &this->skelAnime, 4.0f);
|
||||
|
||||
if (temp == 0) {
|
||||
// SoH: Prevent ladder cutscene softlock
|
||||
if (GameInteractor_Should(VB_INTERRUPT_LADDER_DISMOUNT, interruptResult == PLAYER_INTERRUPT_NEW_ACTION,
|
||||
&this->unk_6AD)) {
|
||||
this->stateFlags1 &= ~PLAYER_STATE1_CLIMBING_LADDER;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((temp > 0) || LinkAnimation_Update(play, &this->skelAnime)) {
|
||||
if ((interruptResult > PLAYER_INTERRUPT_NEW_ACTION) || LinkAnimation_Update(play, &this->skelAnime)) {
|
||||
func_8083C0E8(this, play);
|
||||
this->stateFlags1 &= ~PLAYER_STATE1_CLIMBING_LADDER;
|
||||
return;
|
||||
}
|
||||
|
||||
sp38 = D_80854898;
|
||||
frame = sUpDismountLadderFrames;
|
||||
|
||||
if (this->av2.actionVar2 != 0) {
|
||||
Player_ProcessAnimSfxList(this, D_808548A8);
|
||||
sp38 = D_808548A0;
|
||||
if (this->av2.actionVar2 != 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_EntityRaycastFloor3(&play->colCtx, &sp34, &sp30, &sp24) != 0.0f) {
|
||||
this->floorSfxOffset = func_80041F10(&play->colCtx, sp34, sp30);
|
||||
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_EntityRaycastFloor3(&play->colCtx, &groundPoly, &bgId, &raycastPos) != 0.0f) {
|
||||
this->floorSfxOffset = func_80041F10(&play->colCtx, groundPoly, bgId);
|
||||
Player_PlayLandingSfx(this);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user