diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index bc87c47e2..6304c79ce 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -70,6 +70,7 @@ const std::vector enhancementsCvars = { "gForgeTime", "gClimbSpeed", "gFasterBlockPush", + "gCrawlSpeed", "gFasterHeavyBlockLift", "gNoForcedNavi", "gSkulltulaFreeze", diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 3c77438e8..7265087a0 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -542,6 +542,7 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementSliderInt("King Zora Speed: %dx", "##MWEEPSPEED", "gMweepSpeed", 1, 5, "", 1, true, false, true); UIWidgets::PaddedEnhancementSliderInt("Vine/Ladder Climb speed +%d", "##CLIMBSPEED", "gClimbSpeed", 0, 12, "", 0, true, false, true); UIWidgets::PaddedEnhancementSliderInt("Block pushing speed +%d", "##BLOCKSPEED", "gFasterBlockPush", 0, 5, "", 0, true, false, true); + UIWidgets::PaddedEnhancementSliderInt("Crawl speed %dx", "##CRAWLSPEED", "gCrawlSpeed", 1, 5, "", 1, true, false, true); UIWidgets::PaddedEnhancementCheckbox("Faster Heavy Block Lift", "gFasterHeavyBlockLift", false, false); UIWidgets::Tooltip("Speeds up lifting silver rocks and obelisks"); UIWidgets::PaddedEnhancementCheckbox("Skip Pickup Messages", "gFastDrops", true, false); diff --git a/soh/src/code/z_onepointdemo.c b/soh/src/code/z_onepointdemo.c index ab62692cc..9489eefcd 100644 --- a/soh/src/code/z_onepointdemo.c +++ b/soh/src/code/z_onepointdemo.c @@ -69,7 +69,13 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor PosRot sp8C; f32 tempRand; Unique9OnePointCs* csInfo = ONEPOINT_CS_INFO(csCam); - + + // #region SOH [Enhancement] + //the default is 90, lower values necessary to prevent camera swing as animation speeds up + s16 camCrawlTemp = CVarGetInteger("gCrawlSpeed", 1); + s16 camCrawlTimer = D_8012042C / camCrawlTemp; + // #endregion + switch (csId) { case 1020: if (timer < 20) { @@ -330,13 +336,26 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor case 9601: Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3); Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting); - OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120398); + if (CVarGetInteger("gCrawlSpeed", 1) > 1) { + OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, camCrawlTimer, D_80120308, D_80120398); + } else { + OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120398); + } break; case 9602: - Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3); - Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting); - OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120434); - break; + // #region SOH [Enhancement] + if (CVarGetInteger("gCrawlSpeed", 1) > 1) { + Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3); + Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting); + OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, camCrawlTimer, D_80120308, D_80120434); + break; + // #endregion + } else { + Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3); + Play_CameraChangeSetting(play, MAIN_CAM, mainCam->prevSetting); + OnePointCutscene_SetCsCamPoints(csCam, D_80120430 | 0x1000, D_8012042C, D_80120308, D_80120434); + break; + } case 4175: csInfo->keyFrames = D_8012147C; csInfo->keyFrameCnt = 4; diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 80f4828ed..0577add9e 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6982,9 +6982,19 @@ s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWall this->actor.world.pos.z = zVertex1 + (distToInteractWall * wallPolyNormZ); func_80832224(this); this->actor.prevPos = this->actor.world.pos; - Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_start); - Player_AnimReplaceApplyFlags(play, this, 0x9D); - + // #region SOH [Enhancement] + if (CVarGetInteger("gCrawlSpeed", 1) > 1) { + // increase animation speed when entering a tunnel + LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, + ((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f), 0.0f, + Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), ANIMMODE_ONCE, + 0.0f); + Player_AnimReplaceApplyFlags(play, this, 0x9D); + // #endregion + } else { + Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_start); + Player_AnimReplaceApplyFlags(play, this, 0x9D); + } return true; } } @@ -7065,16 +7075,39 @@ s32 Player_TryLeavingCrawlspace(Player* this, PlayState* play) { if (this->linearVelocity > 0.0f) { this->actor.shape.rot.y = this->actor.wallYaw + 0x8000; - Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_end); - Player_AnimReplaceApplyFlags(play, this, 0x9D); - OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM); + // #region SOH [Enhancement] + if (CVarGetInteger("gCrawlSpeed", 1) > 1) { + // animation when exiting a tunnel forward + LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_end, + ((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f), 0.0f, + Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_end), ANIMMODE_ONCE, + 0.0f); + Player_AnimReplaceApplyFlags(play, this, 0x9D); + OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM); + // #endregion + } else { + Player_AnimPlayOnce(play, this, &gPlayerAnim_link_child_tunnel_end); + Player_AnimReplaceApplyFlags(play, this, 0x9D); + OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM); + } } else { this->actor.shape.rot.y = this->actor.wallYaw; - LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, -1.0f, - Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE, - 0.0f); - Player_AnimReplaceApplyFlags(play, this, 0x9D); - OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM); + // #region SOH [Enhancement] + // animation when exiting a tunnel backward + if (CVarGetInteger("gCrawlSpeed",1) > 1) { + LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, + -1.0f * ((CVarGetInteger("gCrawlSpeed", 1) + 1.0f) / 2.0f), + Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE, 0.0f); + Player_AnimReplaceApplyFlags(play, this, 0x9D); + OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM); + // #endregion + } + else { + LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, -1.0f, + Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE, 0.0f); + Player_AnimReplaceApplyFlags(play, this, 0x9D); + OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM); + } } this->currentYaw = this->actor.shape.rot.y; @@ -12625,8 +12658,15 @@ void func_8084C760(Player* this, PlayState* play) { return; } + // player speed in a tunnel if (!Player_TryLeavingCrawlspace(this, play)) { - this->linearVelocity = sControlInput->rel.stick_y * 0.03f; + // #region SOH [Enhancement] + if (CVarGetInteger("gCrawlSpeed", 1) > 1) { + this->linearVelocity = sControlInput->rel.stick_y * 0.03f * CVarGetInteger("gCrawlSpeed", 1); + // #endregion + } else { + this->linearVelocity = sControlInput->rel.stick_y * 0.03f; + } } } return;