diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index c9f92837d..7dad63850 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -149,6 +149,9 @@ const std::vector enhancementsCvars = { "gCrouchStabHammerFix", "gCrouchStabFix", "gGerudoWarriorClothingFix", + "gFixCameraDrift", + "gFixCameraSwing", + "gFixHangingLedgeSwingRate", "gRedGanonBlood", "gHoverFishing", "gN64WeirdFrames", diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index e37ce54a9..c0b14576a 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -753,6 +753,10 @@ namespace GameMenuBar { UIWidgets::Tooltip("Prevent the Gerudo Warrior's clothes changing color when changing Link's tunic or using bombs in front of her"); UIWidgets::PaddedEnhancementCheckbox("Fix Camera Drift", "gFixCameraDrift", true, false); UIWidgets::Tooltip("Fixes camera slightly drifting to the left when standing still due to a math error"); + UIWidgets::PaddedEnhancementCheckbox("Fix Camera Swing", "gFixCameraSwing", true, false); + UIWidgets::Tooltip("Fixes camera getting stuck on collision when standing still, also fixes slight shift back in camera when stop moving"); + UIWidgets::PaddedEnhancementCheckbox("Fix Hanging Ledge Swing Rate", "gFixHangingLedgeSwingRate", true, false); + UIWidgets::Tooltip("Fixes camera swing rate when player falls of a ledge and camera swings around"); ImGui::EndMenu(); } diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index af343d8fc..13c1f3dab 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -1316,6 +1316,7 @@ s16 Camera_CalcDefaultYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32 acc return cur + (s16)(angDelta * velocity * velFactor * yawUpdRate); } +//Follow player with collision void func_80046E20(Camera* camera, VecSph* eyeAdjustment, f32 minDist, f32 arg3, f32* arg4, SwingAnimation* anim) { static CamColChk atEyeColChk; static CamColChk eyeAtColChk; @@ -1699,6 +1700,7 @@ s32 Camera_Normal1(Camera* camera) { Camera_Vec3fVecSphGeoAdd(eyeNext, at, &eyeAdjustment); if ((camera->status == CAM_STAT_ACTIVE) && (!(norm1->interfaceFlags & 0x10))) { anim->swingYawTarget = BINANG_ROT180(camera->playerPosRot.rot.y); + if (!CVar_GetS32("gFixCameraSwing", 0)) { if (anim->startSwingTimer > 0) { func_80046E20(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing); } else { @@ -1712,7 +1714,13 @@ s32 Camera_Normal1(Camera* camera) { } anim->swing.unk_18 = 0; } - + } else { + if (anim->startSwingTimer <= 0) { + anim->swing.swingUpdateRate = camera->yawUpdateRateInv = norm1->unk_0C * 2.0f; + anim->swing.unk_18 = 0; + } + func_80046E20(camera, &eyeAdjustment, norm1->distMin, norm1->unk_0C, &sp98, &anim->swing); + } if (anim->swing.unk_18 != 0) { camera->inputDir.y = Camera_LERPCeilS(camera->inputDir.y + BINANG_SUB(BINANG_ROT180(anim->swing.unk_16), camera->inputDir.y), @@ -4710,7 +4718,7 @@ s32 Camera_Unique1(Camera* camera) { anim->timer--; } - sp8C.yaw = Camera_LERPFloorS(anim->yawTarget, eyeNextAtOffset.yaw, 0.5f, 0x2710); + sp8C.yaw = Camera_LERPFloorS(anim->yawTarget, eyeNextAtOffset.yaw, 0.5f, CVar_GetS32("gFixHangingLedgeSwingRate", 0) ? 0xA : 0x2710); Camera_Vec3fVecSphGeoAdd(eyeNext, at, &sp8C); *eye = *eyeNext; Camera_BGCheck(camera, at, eye);