1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-12-01 23:36:00 +00:00

Player Docs: Document Some Start Mode Actions (#2305)

* document blue warp arrive

* document warp song, door, and time travel

* document grotto and farores wind

* move animsfx

* review

* unname appear
This commit is contained in:
fig02 2024-11-27 21:19:53 -05:00 committed by GitHub
parent 53962a2cd8
commit cddca30442
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 96 additions and 65 deletions

View file

@ -673,8 +673,8 @@ typedef struct PlayerAgeProperties {
/* 0x92 */ u16 unk_92; /* 0x92 */ u16 unk_92;
/* 0x94 */ u16 unk_94; /* 0x94 */ u16 unk_94;
/* 0x98 */ LinkAnimationHeader* unk_98; /* 0x98 */ LinkAnimationHeader* unk_98;
/* 0x9C */ LinkAnimationHeader* unk_9C; /* 0x9C */ LinkAnimationHeader* timeTravelStartAnim;
/* 0xA0 */ LinkAnimationHeader* unk_A0; /* 0xA0 */ LinkAnimationHeader* timeTravelEndAnim;
/* 0xA4 */ LinkAnimationHeader* unk_A4; /* 0xA4 */ LinkAnimationHeader* unk_A4;
/* 0xA8 */ LinkAnimationHeader* unk_A8; /* 0xA8 */ LinkAnimationHeader* unk_A8;
/* 0xAC */ LinkAnimationHeader* unk_AC[4]; /* 0xAC */ LinkAnimationHeader* unk_AC[4];
@ -899,16 +899,22 @@ typedef struct Player {
/* 0x084F */ union { /* 0x084F */ union {
s8 actionVar1; s8 actionVar1;
s8 facingUpSlope; // Player_Action_SlideOnSlope: facing uphill when sliding on a slope s8 startedAnim; // Player_Action_EndTimeTravel: Started playing the animation that was previously frozen
s8 facingUpSlope; // Player_Action_SlideOnSlope: Facing uphill when sliding on a slope
s8 isLakeHyliaCs; // Player_Action_BlueWarpArrive: In Lake Hylia CS after Water Temple. Floating down is delayed until a specific point in the cutscene.
s8 bottleCatchType; // Player_Action_SwingBottle: entry type for `sBottleCatchInfo`, corresponds to actor caught in a bottle s8 bottleCatchType; // Player_Action_SwingBottle: entry type for `sBottleCatchInfo`, corresponds to actor caught in a bottle
} av1; // "Action Variable 1": context dependent variable that has different meanings depending on what action is currently running } av1; // "Action Variable 1": context dependent variable that has different meanings depending on what action is currently running
/* 0x0850 */ union { /* 0x0850 */ union {
s16 actionVar2; s16 actionVar2;
s16 fallDamageStunTimer; // Player_Action_Idle: Prevents any movement and shakes model up and down quickly to indicate fall damage stun s16 fallDamageStunTimer; // Player_Action_Idle: Prevents any movement and shakes model up and down quickly to indicate fall damage stun
s16 bonked; // Player_Action_Roll: set to true after bonking into a wall or an actor s16 bonked; // Player_Action_Roll: Set to true after bonking into a wall or an actor
s16 animDelayTimer; // Player_Action_EndTimeTravel: Delays playing animation until finished counting down
s16 startedTextbox; // Player_Action_SwingBottle: set to true when the textbox is started s16 startedTextbox; // Player_Action_SwingBottle: set to true when the textbox is started
s16 inWater; // Player_Action_SwingBottle: true if a bottle is swung in water. Used to determine which bottle swing animation to use. s16 inWater; // Player_Action_SwingBottle: True if a bottle is swung in water. Used to determine which bottle swing animation to use.
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)
} av2; // "Action Variable 2": context dependent variable that has different meanings depending on what action is currently running } av2; // "Action Variable 2": context dependent variable that has different meanings depending on what action is currently running
/* 0x0854 */ f32 unk_854; /* 0x0854 */ f32 unk_854;

View file

@ -303,26 +303,26 @@ void Player_Action_8084E368(Player* this, PlayState* play);
void Player_Action_8084E3C4(Player* this, PlayState* play); void Player_Action_8084E3C4(Player* this, PlayState* play);
void Player_Action_8084E604(Player* this, PlayState* play); void Player_Action_8084E604(Player* this, PlayState* play);
void Player_Action_8084E6D4(Player* this, PlayState* play); void Player_Action_8084E6D4(Player* this, PlayState* play);
void Player_Action_8084E9AC(Player* this, PlayState* play); void Player_Action_TimeTravelEnd(Player* this, PlayState* play);
void Player_Action_8084EAC0(Player* this, PlayState* play); void Player_Action_8084EAC0(Player* this, PlayState* play);
void Player_Action_SwingBottle(Player* this, PlayState* play); void Player_Action_SwingBottle(Player* this, PlayState* play);
void Player_Action_8084EED8(Player* this, PlayState* play); void Player_Action_8084EED8(Player* this, PlayState* play);
void Player_Action_8084EFC0(Player* this, PlayState* play); void Player_Action_8084EFC0(Player* this, PlayState* play);
void Player_Action_ExchangeItem(Player* this, PlayState* play); void Player_Action_ExchangeItem(Player* this, PlayState* play);
void Player_Action_SlideOnSlope(Player* this, PlayState* play); void Player_Action_SlideOnSlope(Player* this, PlayState* play);
void Player_Action_8084F608(Player* this, PlayState* play); void Player_Action_WaitForCutscene(Player* this, PlayState* play);
void Player_Action_8084F698(Player* this, PlayState* play); void Player_Action_StartWarpSongArrive(Player* this, PlayState* play);
void Player_Action_8084F710(Player* this, PlayState* play); void Player_Action_BlueWarpArrive(Player* this, PlayState* play);
void Player_Action_8084F88C(Player* this, PlayState* play); void Player_Action_8084F88C(Player* this, PlayState* play);
void Player_Action_8084F9A0(Player* this, PlayState* play); void Player_Action_TryOpeningDoor(Player* this, PlayState* play);
void Player_Action_8084F9C0(Player* this, PlayState* play); void Player_Action_ExitGrotto(Player* this, PlayState* play);
void Player_Action_8084FA54(Player* this, PlayState* play); void Player_Action_8084FA54(Player* this, PlayState* play);
void Player_Action_8084FB10(Player* this, PlayState* play); void Player_Action_8084FB10(Player* this, PlayState* play);
void Player_Action_8084FBF4(Player* this, PlayState* play); void Player_Action_8084FBF4(Player* this, PlayState* play);
void Player_Action_808502D0(Player* this, PlayState* play); void Player_Action_808502D0(Player* this, PlayState* play);
void Player_Action_808505DC(Player* this, PlayState* play); void Player_Action_808505DC(Player* this, PlayState* play);
void Player_Action_8085063C(Player* this, PlayState* play); void Player_Action_8085063C(Player* this, PlayState* play);
void Player_Action_8085076C(Player* this, PlayState* play); void Player_Action_FaroresWindArrive(Player* this, PlayState* play);
void Player_Action_808507F4(Player* this, PlayState* play); void Player_Action_808507F4(Player* this, PlayState* play);
void Player_Action_HookshotFly(Player* this, PlayState* play); void Player_Action_HookshotFly(Player* this, PlayState* play);
void Player_Action_80850C68(Player* this, PlayState* play); void Player_Action_80850C68(Player* this, PlayState* play);
@ -418,8 +418,8 @@ static PlayerAgeProperties sAgeProperties[] = {
0, // unk_92 0, // unk_92
0x80, // unk_94 0x80, // unk_94
&gPlayerAnim_link_demo_Tbox_open, // unk_98 &gPlayerAnim_link_demo_Tbox_open, // unk_98
&gPlayerAnim_link_demo_back_to_past, // unk_9C &gPlayerAnim_link_demo_back_to_past, // timeTravelStartAnim
&gPlayerAnim_link_demo_return_to_past, // unk_A0 &gPlayerAnim_link_demo_return_to_past, // timeTravelEndAnim
&gPlayerAnim_link_normal_climb_startA, // unk_A4 &gPlayerAnim_link_normal_climb_startA, // unk_A4
&gPlayerAnim_link_normal_climb_startB, // unk_A8 &gPlayerAnim_link_normal_climb_startB, // unk_A8
{ &gPlayerAnim_link_normal_climb_upL, &gPlayerAnim_link_normal_climb_upR, &gPlayerAnim_link_normal_Fclimb_upL, { &gPlayerAnim_link_normal_climb_upL, &gPlayerAnim_link_normal_climb_upR, &gPlayerAnim_link_normal_Fclimb_upL,
@ -470,8 +470,8 @@ static PlayerAgeProperties sAgeProperties[] = {
0x20, // unk_92 0x20, // unk_92
0, // unk_94 0, // unk_94
&gPlayerAnim_clink_demo_Tbox_open, // unk_98 &gPlayerAnim_clink_demo_Tbox_open, // unk_98
&gPlayerAnim_clink_demo_goto_future, // unk_9C &gPlayerAnim_clink_demo_goto_future, // timeTravelStartAnim
&gPlayerAnim_clink_demo_return_to_future, // unk_A0 &gPlayerAnim_clink_demo_return_to_future, // timeTravelEndAnim
&gPlayerAnim_clink_normal_climb_startA, // unk_A4 &gPlayerAnim_clink_normal_climb_startA, // unk_A4
&gPlayerAnim_clink_normal_climb_startB, // unk_A8 &gPlayerAnim_clink_normal_climb_startB, // unk_A8
{ &gPlayerAnim_clink_normal_climb_upL, &gPlayerAnim_clink_normal_climb_upR, &gPlayerAnim_link_normal_Fclimb_upL, { &gPlayerAnim_clink_normal_climb_upL, &gPlayerAnim_clink_normal_climb_upR, &gPlayerAnim_link_normal_Fclimb_upL,
@ -5347,7 +5347,7 @@ s32 Player_ActionHandler_1(Player* this, PlayState* play) {
if ((this->doorType != PLAYER_DOORTYPE_NONE) && if ((this->doorType != PLAYER_DOORTYPE_NONE) &&
(!(this->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) || (!(this->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) ||
((this->heldActor != NULL) && (this->heldActor->id == ACTOR_EN_RU1)))) { ((this->heldActor != NULL) && (this->heldActor->id == ACTOR_EN_RU1)))) {
if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A) || (Player_Action_8084F9A0 == this->actionFunc)) { if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A) || (Player_Action_TryOpeningDoor == this->actionFunc)) {
doorActor = this->doorActor; doorActor = this->doorActor;
if (this->doorType <= PLAYER_DOORTYPE_AJAR) { if (this->doorType <= PLAYER_DOORTYPE_AJAR) {
@ -5584,7 +5584,7 @@ void func_8083A0F4(PlayState* play, Player* this) {
if (interactActorId == ACTOR_BG_TOKI_SWD) { if (interactActorId == ACTOR_BG_TOKI_SWD) {
this->interactRangeActor->parent = &this->actor; this->interactRangeActor->parent = &this->actor;
Player_SetupAction(play, this, Player_Action_8084F608, 0); Player_SetupAction(play, this, Player_Action_WaitForCutscene, 0);
this->stateFlags1 |= PLAYER_STATE1_29; this->stateFlags1 |= PLAYER_STATE1_29;
} else { } else {
LinkAnimationHeader* anim; LinkAnimationHeader* anim;
@ -10501,15 +10501,17 @@ void Player_StartMode_Nothing(PlayState* play, Player* this) {
} }
void Player_StartMode_BlueWarp(PlayState* play, Player* this) { void Player_StartMode_BlueWarp(PlayState* play, Player* this) {
Player_SetupAction(play, this, Player_Action_8084F710, 0); Player_SetupAction(play, this, Player_Action_BlueWarpArrive, 0);
if ((play->sceneId == SCENE_LAKE_HYLIA) && IS_CUTSCENE_LAYER) { if ((play->sceneId == SCENE_LAKE_HYLIA) && IS_CUTSCENE_LAYER) {
this->av1.actionVar1 = 1; this->av1.isLakeHyliaCs = true;
} }
this->stateFlags1 |= PLAYER_STATE1_29; this->stateFlags1 |= PLAYER_STATE1_29;
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_okarina_warp_goal, 2.0f / 3.0f, 0.0f, 24.0f, LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_okarina_warp_goal, 2.0f / 3.0f, 0.0f, 24.0f,
ANIMMODE_ONCE, 0.0f); ANIMMODE_ONCE, 0.0f);
// Start high up in the air
this->actor.world.pos.y += 800.0f; this->actor.world.pos.y += 800.0f;
} }
@ -10543,14 +10545,16 @@ void Player_PutSwordInHand(PlayState* play, Player* this, s32 playSfx) {
void Player_StartMode_TimeTravel(PlayState* play, Player* this) { void Player_StartMode_TimeTravel(PlayState* play, Player* this) {
static Vec3f sPedestalPos = { -1.0f, 69.0f, 20.0f }; static Vec3f sPedestalPos = { -1.0f, 69.0f, 20.0f };
Player_SetupAction(play, this, Player_Action_8084E9AC, 0); Player_SetupAction(play, this, Player_Action_TimeTravelEnd, 0);
this->stateFlags1 |= PLAYER_STATE1_29; this->stateFlags1 |= PLAYER_STATE1_29;
Math_Vec3f_Copy(&this->actor.world.pos, &sPedestalPos); Math_Vec3f_Copy(&this->actor.world.pos, &sPedestalPos);
this->yaw = this->actor.shape.rot.y = -0x8000; this->yaw = this->actor.shape.rot.y = -0x8000;
LinkAnimation_Change(play, &this->skelAnime, this->ageProperties->unk_A0, 2.0f / 3.0f, 0.0f, 0.0f, ANIMMODE_ONCE, // The start frame and end frame are both set to 0 so that that the animation is frozen.
0.0f); // `Player_Action_TimeTravelEnd` will play the animation after `animDelayTimer` completes.
LinkAnimation_Change(play, &this->skelAnime, this->ageProperties->timeTravelEndAnim, 2.0f / 3.0f, 0.0f, 0.0f,
ANIMMODE_ONCE, 0.0f);
Player_StartAnimMovement(play, this, Player_StartAnimMovement(play, this,
PLAYER_ANIM_MOVEMENT_RESET_BY_AGE | ANIM_FLAG_UPDATE_XZ | ANIM_FLAG_UPDATE_Y | PLAYER_ANIM_MOVEMENT_RESET_BY_AGE | ANIM_FLAG_UPDATE_XZ | ANIM_FLAG_UPDATE_Y |
ANIM_FLAG_DISABLE_CHILD_ROOT_ADJUSTMENT | ANIM_FLAG_ENABLE_MOVEMENT | ANIM_FLAG_DISABLE_CHILD_ROOT_ADJUSTMENT | ANIM_FLAG_ENABLE_MOVEMENT |
@ -10560,11 +10564,11 @@ void Player_StartMode_TimeTravel(PlayState* play, Player* this) {
Player_PutSwordInHand(play, this, false); Player_PutSwordInHand(play, this, false);
} }
this->av2.actionVar2 = 20; this->av2.animDelayTimer = 20;
} }
void Player_StartMode_Door(PlayState* play, Player* this) { void Player_StartMode_Door(PlayState* play, Player* this) {
Player_SetupAction(play, this, Player_Action_8084F9A0, 0); Player_SetupAction(play, this, Player_Action_TryOpeningDoor, 0);
Player_StartAnimMovement(play, this, Player_StartAnimMovement(play, this,
ANIM_FLAG_UPDATE_XZ | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_ENABLE_MOVEMENT | ANIM_FLAG_UPDATE_XZ | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_ENABLE_MOVEMENT |
ANIM_FLAG_ADJUST_STARTING_POS | ANIM_FLAG_OVERRIDE_MOVEMENT); ANIM_FLAG_ADJUST_STARTING_POS | ANIM_FLAG_OVERRIDE_MOVEMENT);
@ -10572,7 +10576,7 @@ void Player_StartMode_Door(PlayState* play, Player* this) {
void Player_StartMode_Grotto(PlayState* play, Player* this) { void Player_StartMode_Grotto(PlayState* play, Player* this) {
func_808389E8(this, &gPlayerAnim_link_normal_jump, 12.0f, play); func_808389E8(this, &gPlayerAnim_link_normal_jump, 12.0f, play);
Player_SetupAction(play, this, Player_Action_8084F9C0, 0); Player_SetupAction(play, this, Player_Action_ExitGrotto, 0);
this->stateFlags1 |= PLAYER_STATE1_29; this->stateFlags1 |= PLAYER_STATE1_29;
this->fallStartHeight = this->actor.world.pos.y; this->fallStartHeight = this->actor.world.pos.y;
OnePointCutscene_Init(play, 5110, 40, &this->actor, CAM_ID_MAIN); OnePointCutscene_Init(play, 5110, 40, &this->actor, CAM_ID_MAIN);
@ -10583,8 +10587,8 @@ void Player_StartMode_KnockedOver(PlayState* play, Player* this) {
} }
void Player_StartMode_WarpSong(PlayState* play, Player* this) { void Player_StartMode_WarpSong(PlayState* play, Player* this) {
Player_SetupAction(play, this, Player_Action_8084F698, 0); Player_SetupAction(play, this, Player_Action_StartWarpSongArrive, 0);
this->actor.draw = NULL; this->actor.draw = NULL; // Start invisible
this->stateFlags1 |= PLAYER_STATE1_29; this->stateFlags1 |= PLAYER_STATE1_29;
} }
@ -10596,8 +10600,8 @@ Actor* Player_SpawnMagicSpell(PlayState* play, Player* this, s32 spell) {
} }
void Player_StartMode_FaroresWind(PlayState* play, Player* this) { void Player_StartMode_FaroresWind(PlayState* play, Player* this) {
this->actor.draw = NULL; this->actor.draw = NULL; // Start invisible
Player_SetupAction(play, this, Player_Action_8085076C, 0); Player_SetupAction(play, this, Player_Action_FaroresWindArrive, 0);
this->stateFlags1 |= PLAYER_STATE1_29; this->stateFlags1 |= PLAYER_STATE1_29;
} }
@ -13895,26 +13899,22 @@ void Player_Action_8084E6D4(Player* this, PlayState* play) {
} }
} }
static AnimSfxEntry D_808549F0[] = {
{ NA_SE_IT_MASTER_SWORD_SWING, -ANIMSFX_DATA(ANIMSFX_TYPE_GENERAL, 60) },
};
void func_8084E988(Player* this) { void func_8084E988(Player* this) {
static AnimSfxEntry D_808549F0[] = {
{ NA_SE_IT_MASTER_SWORD_SWING, -ANIMSFX_DATA(ANIMSFX_TYPE_GENERAL, 60) },
};
Player_ProcessAnimSfxList(this, D_808549F0); Player_ProcessAnimSfxList(this, D_808549F0);
} }
#if OOT_VERSION >= PAL_1_0 void Player_Action_TimeTravelEnd(Player* this, PlayState* play) {
static AnimSfxEntry D_808549F4[] = {
{ NA_SE_VO_LI_AUTO_JUMP, ANIMSFX_DATA(ANIMSFX_TYPE_VOICE, 5) },
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_LANDING, 15) },
};
#endif
void Player_Action_8084E9AC(Player* this, PlayState* play) {
if (LinkAnimation_Update(play, &this->skelAnime)) { if (LinkAnimation_Update(play, &this->skelAnime)) {
if (this->av1.actionVar1 == 0) { if (!this->av1.startedAnim) {
if (DECR(this->av2.actionVar2) == 0) { if (DECR(this->av2.animDelayTimer) == 0) {
this->av1.actionVar1 = 1; this->av1.startedAnim = true;
// endFrame was previously set to 0 to freeze the animation.
// Set it properly to allow the animation to play.
this->skelAnime.endFrame = this->skelAnime.animLength - 1.0f; this->skelAnime.endFrame = this->skelAnime.animLength - 1.0f;
} }
} else { } else {
@ -13928,13 +13928,20 @@ void Player_Action_8084E9AC(Player* this, PlayState* play) {
#if OOT_VERSION < PAL_1_0 #if OOT_VERSION < PAL_1_0
if (!LINK_IS_ADULT && LinkAnimation_OnFrame(&this->skelAnime, 5.0f)) { if (!LINK_IS_ADULT && LinkAnimation_OnFrame(&this->skelAnime, 5.0f)) {
// There is a jump sound when leaving the pedestal, but no landing sound when hitting the floor.
// This is fixed in PAL 1.0 and above.
Player_PlayVoiceSfx(this, NA_SE_VO_LI_AUTO_JUMP); Player_PlayVoiceSfx(this, NA_SE_VO_LI_AUTO_JUMP);
} else if (LINK_IS_ADULT) { } else if (LINK_IS_ADULT) {
func_8084E988(this); func_8084E988(this);
} }
#else #else
if (!LINK_IS_ADULT) { if (!LINK_IS_ADULT) {
Player_ProcessAnimSfxList(this, D_808549F4); static AnimSfxEntry sJumpOffPedestalAnimSfxList[] = {
{ NA_SE_VO_LI_AUTO_JUMP, ANIMSFX_DATA(ANIMSFX_TYPE_VOICE, 5) },
{ 0, -ANIMSFX_DATA(ANIMSFX_TYPE_LANDING, 15) },
};
Player_ProcessAnimSfxList(this, sJumpOffPedestalAnimSfxList);
} else { } else {
func_8084E988(this); func_8084E988(this);
} }
@ -14271,29 +14278,40 @@ void Player_Action_SlideOnSlope(Player* this, PlayState* play) {
} }
} }
void Player_Action_8084F608(Player* this, PlayState* play) { /**
if ((DECR(this->av2.actionVar2) == 0) && Player_StartCsAction(play, this)) { * Waits to start processing a Cutscene Action.
* First, the timer `csDelayTimer` much reach 0.
* Then, there must be a CS action available to start processing.
*
* When starting the cutscene action, `draw` will be set to make
* Player appear, if he was invisible.
*/
void Player_Action_WaitForCutscene(Player* this, PlayState* play) {
if ((DECR(this->av2.csDelayTimer) == 0) && Player_StartCsAction(play, this)) {
func_80852280(play, this, NULL); func_80852280(play, this, NULL);
Player_SetupAction(play, this, Player_Action_CsAction, 0); Player_SetupAction(play, this, Player_Action_CsAction, 0);
Player_Action_CsAction(this, play); Player_Action_CsAction(this, play);
} }
} }
void Player_Action_8084F698(Player* this, PlayState* play) { void Player_Action_StartWarpSongArrive(Player* this, PlayState* play) {
Player_SetupAction(play, this, Player_Action_8084F608, 0); Player_SetupAction(play, this, Player_Action_WaitForCutscene, 0);
this->av2.actionVar2 = 40; this->av2.csDelayTimer = 40;
// Note: The warp song sparkles actor is responsible for starting the warp-in cutscene script
Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_KANKYO, 0.0f, 0.0f, 0.0f, 0, 0, 0, DEMOKANKYO_WARP_IN); Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_KANKYO, 0.0f, 0.0f, 0.0f, 0, 0, 0, DEMOKANKYO_WARP_IN);
} }
void Player_Action_8084F710(Player* this, PlayState* play) { void Player_Action_BlueWarpArrive(Player* this, PlayState* play) {
s32 pad; s32 pad;
if ((this->av1.actionVar1 != 0) && (play->csCtx.curFrame < 305)) { if ((this->av1.isLakeHyliaCs) && (play->csCtx.curFrame < 305)) {
// Delay falling down until frame 306 of the Lake Hylia cutscene after completing Water Temple
this->actor.gravity = 0.0f; this->actor.gravity = 0.0f;
this->actor.velocity.y = 0.0f; this->actor.velocity.y = 0.0f;
} else if (sYDistToFloor < 150.0f) { } else if (sYDistToFloor < 150.0f) {
if (LinkAnimation_Update(play, &this->skelAnime)) { if (LinkAnimation_Update(play, &this->skelAnime)) {
if (this->av2.actionVar2 == 0) { if (!this->av2.playedLandingSfx) {
if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) { if (this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) {
this->skelAnime.endFrame = this->skelAnime.animLength - 1.0f; this->skelAnime.endFrame = this->skelAnime.animLength - 1.0f;
Player_PlayLandingSfx(this); Player_PlayLandingSfx(this);
@ -14303,9 +14321,11 @@ void Player_Action_8084F710(Player* this, PlayState* play) {
if ((play->sceneId == SCENE_KOKIRI_FOREST) && Player_StartCsAction(play, this)) { if ((play->sceneId == SCENE_KOKIRI_FOREST) && Player_StartCsAction(play, this)) {
return; return;
} }
func_80853080(this, play); func_80853080(this, play);
} }
} }
Math_SmoothStepToF(&this->actor.velocity.y, 2.0f, 0.3f, 8.0f, 0.5f); Math_SmoothStepToF(&this->actor.velocity.y, 2.0f, 0.3f, 8.0f, 0.5f);
} }
@ -14314,9 +14334,10 @@ void Player_Action_8084F710(Player* this, PlayState* play) {
} }
if ((play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.playerCue != NULL)) { if ((play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.playerCue != NULL)) {
f32 sp28 = this->actor.world.pos.y; f32 savedYPos = this->actor.world.pos.y;
func_808529D0(play, this, play->csCtx.playerCue); func_808529D0(play, this, play->csCtx.playerCue);
this->actor.world.pos.y = sp28; this->actor.world.pos.y = savedYPos;
} }
} }
@ -14348,11 +14369,15 @@ void Player_Action_8084F88C(Player* this, PlayState* play) {
} }
} }
void Player_Action_8084F9A0(Player* this, PlayState* play) { /**
* Automatically open a door (no need for the A button).
* Note: If no door is in useable range, a softlock will occur.
*/
void Player_Action_TryOpeningDoor(Player* this, PlayState* play) {
Player_ActionHandler_1(this, play); Player_ActionHandler_1(this, play);
} }
void Player_Action_8084F9C0(Player* this, PlayState* play) { void Player_Action_ExitGrotto(Player* this, PlayState* play) {
this->actor.gravity = -1.0f; this->actor.gravity = -1.0f;
LinkAnimation_Update(play, &this->skelAnime); LinkAnimation_Update(play, &this->skelAnime);
@ -14708,17 +14733,17 @@ void Player_Action_8085063C(Player* this, PlayState* play) {
} }
} }
void Player_Action_8085076C(Player* this, PlayState* play) { void Player_Action_FaroresWindArrive(Player* this, PlayState* play) {
s32 respawnData = gSaveContext.respawn[RESPAWN_MODE_TOP].data; s32 respawnData = gSaveContext.respawn[RESPAWN_MODE_TOP].data;
if (this->av2.actionVar2 > 20) { if (this->av2.appearTimer > 20) {
this->actor.draw = Player_Draw; this->actor.draw = Player_Draw;
this->actor.world.pos.y += 60.0f; this->actor.world.pos.y += 60.0f;
func_80837B9C(this, play); func_80837B9C(this, play);
return; return;
} }
if (this->av2.actionVar2++ == 20) { if (this->av2.appearTimer++ == 20) {
gSaveContext.respawn[RESPAWN_MODE_TOP].data = respawnData + 1; gSaveContext.respawn[RESPAWN_MODE_TOP].data = respawnData + 1;
Sfx_PlaySfxAtPos(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, NA_SE_PL_MAGIC_WIND_WARP); Sfx_PlaySfxAtPos(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, NA_SE_PL_MAGIC_WIND_WARP);
} }
@ -15449,12 +15474,12 @@ static LinkAnimationHeader* D_80855190[] = {
&gPlayerAnim_clink_demo_goto_future, &gPlayerAnim_clink_demo_goto_future,
}; };
static Vec3f D_80855198 = { -1.0f, 70.0f, 20.0f };
void func_808519EC(PlayState* play, Player* this, CsCmdActorCue* cue) { void func_808519EC(PlayState* play, Player* this, CsCmdActorCue* cue) {
Math_Vec3f_Copy(&this->actor.world.pos, &D_80855198); static Vec3f sPedestalPos = { -1.0f, 70.0f, 20.0f };
Math_Vec3f_Copy(&this->actor.world.pos, &sPedestalPos);
this->actor.shape.rot.y = -0x8000; this->actor.shape.rot.y = -0x8000;
Player_AnimPlayOnceAdjusted(play, this, this->ageProperties->unk_9C); Player_AnimPlayOnceAdjusted(play, this, this->ageProperties->timeTravelStartAnim);
Player_StartAnimMovement(play, this, Player_StartAnimMovement(play, this,
PLAYER_ANIM_MOVEMENT_RESET_BY_AGE | ANIM_FLAG_UPDATE_XZ | ANIM_FLAG_UPDATE_Y | PLAYER_ANIM_MOVEMENT_RESET_BY_AGE | ANIM_FLAG_UPDATE_XZ | ANIM_FLAG_UPDATE_Y |
ANIM_FLAG_DISABLE_CHILD_ROOT_ADJUSTMENT | ANIM_FLAG_ENABLE_MOVEMENT | ANIM_FLAG_DISABLE_CHILD_ROOT_ADJUSTMENT | ANIM_FLAG_ENABLE_MOVEMENT |