From 72c9f123768d1dd067ca7a042ef857391c16c5dd Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 01:20:05 -0600 Subject: [PATCH 01/10] overcomplicated shit --- MenuScalePatch/HarmonyPatches.cs | 108 +++++++++++++++ MenuScalePatch/MSP_Menus.cs | 25 ++++ MenuScalePatch/Main.cs | 104 +++----------- MenuScalePatch/MainMenuHelper.cs | 159 ++++++++++++++++++++++ MenuScalePatch/Properties/AssemblyInfo.cs | 4 +- MenuScalePatch/QuickMenuHelper.cs | 148 ++++++++++++++++++++ 6 files changed, 458 insertions(+), 90 deletions(-) create mode 100644 MenuScalePatch/HarmonyPatches.cs create mode 100644 MenuScalePatch/MSP_Menus.cs create mode 100644 MenuScalePatch/MainMenuHelper.cs create mode 100644 MenuScalePatch/QuickMenuHelper.cs diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs new file mode 100644 index 0000000..3d24450 --- /dev/null +++ b/MenuScalePatch/HarmonyPatches.cs @@ -0,0 +1,108 @@ +using ABI_RC.Core.InteractionSystem; +using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; +using ABI_RC.Core; +using cohtml; +using HarmonyLib; +using NAK.Melons.MenuScalePatch.Helpers; +using UnityEngine; + +namespace NAK.Melons.MenuScalePatch.HarmonyPatches; + +[HarmonyPatch] +internal class HarmonyPatches +{ + [HarmonyPrefix] + [HarmonyPatch(typeof(CVR_MenuManager), "SetScale")] + private static void SetQMScale(float avatarHeight, ref float ____scaleFactor, out bool __runOriginal) + { + ____scaleFactor = avatarHeight / 1.8f; + if (MetaPort.Instance.isUsingVr) + { + ____scaleFactor *= 0.5f; + } + MSP_MenuInfo.ScaleFactor = ____scaleFactor; + __runOriginal = false; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(ViewManager), "SetScale")] + private static void CheckMMScale(out bool __runOriginal) + { + /** + ViewManager.SetScale runs once a second when it should only run when aspect ratio changes- CVR bug + assuming its caused by cast from int to float getting the screen size, something floating point bleh + i dont need it so i will nuke it >:) + **/ + __runOriginal = false; + } + + //nuke UpdateMenuPosition methods + //there are 2 Jobs calling this each second, which is fucking my shit + [HarmonyPrefix] + [HarmonyPatch(typeof(CVR_MenuManager), "UpdateMenuPosition")] + private static void Prefix_CVR_MenuManager_UpdateMenuPosition(out bool __runOriginal) + { + __runOriginal = false; + } + [HarmonyPrefix] + [HarmonyPatch(typeof(ViewManager), "UpdateMenuPosition")] + private static void Prefix_ViewManager_UpdateMenuPosition(out bool __runOriginal) + { + __runOriginal = false; + } + + //Set QM stuff + [HarmonyPostfix] + [HarmonyPatch(typeof(CVR_MenuManager), "Start")] + private static void SetupQMHelper(ref CVR_MenuManager __instance, ref GameObject ____leftVrAnchor) + { + QuickMenuHelper helper = __instance.quickMenu.gameObject.AddComponent(); + helper.handAnchor = ____leftVrAnchor.transform; + } + + //Set MM stuff + [HarmonyPostfix] + [HarmonyPatch(typeof(ViewManager), "Start")] + private static void SetupMMHelper(ref ViewManager __instance) + { + __instance.gameObject.AddComponent(); + } + + //hook quickmenu open/close + [HarmonyPostfix] + [HarmonyPatch(typeof(CVR_MenuManager), "ToggleQuickMenu", new Type[] { typeof(bool) })] + private static void Postfix_CVR_MenuManager_ToggleQuickMenu(bool show) + { + if (QuickMenuHelper.Instance == null) return; + QuickMenuHelper.Instance.UpdateWorldAnchors(); + QuickMenuHelper.Instance.ToggleDesktopInputMethod(show); + QuickMenuHelper.Instance.enabled = show; + } + + //add independent head movement to important input + [HarmonyPostfix] + [HarmonyPatch(typeof(InputModuleMouseKeyboard), "UpdateImportantInput")] + private static void Postfix_InputModuleMouseKeyboard_UpdateImportantInput(ref CVRInputManager ____inputManager) + { + ____inputManager.independentHeadTurn |= Input.GetKey(KeyCode.LeftAlt); + } + + //hook menu open/close + [HarmonyPostfix] + [HarmonyPatch(typeof(ViewManager), "UiStateToggle", new Type[] { typeof(bool) })] + private static void Postfix_ViewManager_UiStateToggle(bool show) + { + if (MainMenuHelper.Instance == null) return; + MainMenuHelper.Instance.UpdateWorldAnchors(); + MainMenuHelper.Instance.enabled = show; + } + + //Support for changing VRMode during runtime. + [HarmonyPostfix] + [HarmonyPatch(typeof(PlayerSetup), "CalibrateAvatar")] + private static void CheckVRModeOnSwitch() + { + MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform; + } +} \ No newline at end of file diff --git a/MenuScalePatch/MSP_Menus.cs b/MenuScalePatch/MSP_Menus.cs new file mode 100644 index 0000000..341c3c3 --- /dev/null +++ b/MenuScalePatch/MSP_Menus.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using ABI_RC.Core.Savior; + +namespace NAK.Melons.MenuScalePatch.Helpers; + +public class MSP_MenuInfo +{ + //Shared Info + public static float ScaleFactor = 1f; + public static Transform CameraTransform; + + //Settings...? + public static bool WorldAnchorQM; + + //if other mods need to disable? + public static bool DisableQMHelper; + public static bool DisableQMHelper_VR; + public static bool DisableMMHelper; + public static bool DisableMMHelper_VR; +} \ No newline at end of file diff --git a/MenuScalePatch/Main.cs b/MenuScalePatch/Main.cs index e8da0bd..812989b 100644 --- a/MenuScalePatch/Main.cs +++ b/MenuScalePatch/Main.cs @@ -5,100 +5,28 @@ using cohtml; using HarmonyLib; using MelonLoader; using UnityEngine; +using NAK.Melons.MenuScalePatch.Helpers; -namespace MenuScalePatch; +namespace NAK.Melons.MenuScalePatch; public class MenuScalePatch : MelonMod { - [HarmonyPatch] - private class HarmonyPatches + private static MelonPreferences_Category m_categoryMenuScalePatch; + private static MelonPreferences_Entry m_entryWorldAnchorVRQM; + public override void OnInitializeMelon() { - internal static bool adjustedMenuPosition = false; - internal static void SetMenuPosition(Transform menuTransform, float scale) + m_categoryMenuScalePatch = MelonPreferences.CreateCategory(nameof(MenuScalePatch)); + m_entryWorldAnchorVRQM = m_categoryMenuScalePatch.CreateEntry("World Anchor VR QM", false, description: "Should place QM in World Space while VR."); + + foreach (var setting in m_categoryMenuScalePatch.Entries) { - Transform rotationPivot = PlayerSetup.Instance._movementSystem.rotationPivot; - if (!MetaPort.Instance.isUsingVr) - { - menuTransform.eulerAngles = rotationPivot.eulerAngles; - } - menuTransform.position = rotationPivot.position + rotationPivot.forward * 1f * scale; - adjustedMenuPosition = true; - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(CVR_MenuManager), "SetScale")] - private static void SetQMScale(ref CohtmlView ___quickMenu, ref bool ___needsQuickmenuPositionUpdate, ref float ____scaleFactor, ref GameObject ____leftVrAnchor) - { - if (MetaPort.Instance.isUsingVr) - { - ___quickMenu.transform.position = ____leftVrAnchor.transform.position; - ___quickMenu.transform.rotation = ____leftVrAnchor.transform.rotation; - ___needsQuickmenuPositionUpdate = false; - return; - } - PlayerSetup.Instance.HandleDesktopCameraPosition(true); - SetMenuPosition(___quickMenu.transform, ____scaleFactor); - ___needsQuickmenuPositionUpdate = false; - } - - /** - ViewManager.SetScale runs once a second when it should only run when aspect ratio changes- CVR bug - assuming its caused by cast from int to float getting the screen size, something floating point bleh - attempting to ignore that call if there wasnt actually a change - **/ - - [HarmonyPrefix] - [HarmonyPatch(typeof(ViewManager), "SetScale")] - private static void CheckMMScale(float avatarHeight, ref float ___cachedAvatarHeight, out bool __state) - { - if (___cachedAvatarHeight == avatarHeight) - { - __state = false; - return; - } - __state = true; - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(ViewManager), "SetScale")] - private static void SetMMScale(ref ViewManager __instance, ref bool ___needsMenuPositionUpdate, ref float ___scaleFactor, bool __state) - { - if (!__state) return; - - PlayerSetup.Instance.HandleDesktopCameraPosition(true); - SetMenuPosition(__instance.transform, ___scaleFactor); - ___needsMenuPositionUpdate = false; - } - - /** - Following code resets the menu position on LateUpdate so you can use the menu while moving/falling. - It is Desktop only. QM inputs still don't work because they do their input checks in LateUpdate??? - **/ - - [HarmonyPrefix] - [HarmonyPatch(typeof(CVR_MenuManager), "LateUpdate")] - private static void DesktopQMFix(ref CohtmlView ___quickMenu, ref bool ___needsQuickmenuPositionUpdate, ref float ____scaleFactor, ref bool ____quickMenuOpen) - { - if (MetaPort.Instance.isUsingVr) return; - if (____quickMenuOpen && !adjustedMenuPosition) - { - SetMenuPosition(___quickMenu.transform, ____scaleFactor); - ___needsQuickmenuPositionUpdate = false; - } - adjustedMenuPosition = false; - } - - [HarmonyPrefix] - [HarmonyPatch(typeof(ViewManager), "LateUpdate")] - private static void DesktopMMFix(ref ViewManager __instance, ref bool ___needsMenuPositionUpdate, ref float ___scaleFactor, bool __state, ref bool ____gameMenuOpen) - { - if (MetaPort.Instance.isUsingVr) return; - if (____gameMenuOpen && !adjustedMenuPosition) - { - SetMenuPosition(__instance.transform, ___scaleFactor); - ___needsMenuPositionUpdate = false; - } - adjustedMenuPosition = false; + setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); } } + + private void UpdateAllSettings() + { + MSP_MenuInfo.WorldAnchorQM = m_entryWorldAnchorVRQM.Value; + } + private void OnUpdateSettings(object arg1, object arg2) => UpdateAllSettings(); } \ No newline at end of file diff --git a/MenuScalePatch/MainMenuHelper.cs b/MenuScalePatch/MainMenuHelper.cs new file mode 100644 index 0000000..ba3f83d --- /dev/null +++ b/MenuScalePatch/MainMenuHelper.cs @@ -0,0 +1,159 @@ +using ABI_RC.Core.InteractionSystem; +using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; +using ABI_RC.Core; +using ABI_RC.Systems.MovementSystem; +using cohtml; +using HarmonyLib; +using MelonLoader; +using UnityEngine; +using System.Reflection; + +namespace NAK.Melons.MenuScalePatch.Helpers; + +//TODO: Implement desktop ratio scaling back to MM + +/** + + This helper is assigned to the MainMenu object. + The DefaultExecutionOrder attribute saves me from needing + to use OnPreRender() callback... yay. + +**/ + +[DefaultExecutionOrder(999999)] +public class MainMenuHelper : MonoBehaviour +{ + public static MainMenuHelper Instance; + public Transform worldAnchor; + + static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); + private bool independentHeadTurn = false; + private bool returnIndependentHeadTurn = false; + private bool prevIndependentHeadTurn = false; + + void Start() + { + Instance = this; + CreateWorldAnchors(); + } + + void LateUpdate() + { + UpdateMenuPosition(); + } + + void OnDisable() + { + independentHeadTurn = false; + returnIndependentHeadTurn = false; + prevIndependentHeadTurn = false; + } + + public void ToggleDesktopInputMethod(bool flag) + { + PlayerSetup.Instance._movementSystem.disableCameraControl = flag; + CVRInputManager.Instance.inputEnabled = !flag; + RootLogic.Instance.ToggleMouse(flag); + CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag; + Traverse.Create(CVR_MenuManager.Instance).Field("_desktopMouseMode").SetValue(flag); + } + + public void CreateWorldAnchors() + { + //VR specific anchor + GameObject vrAnchor = new GameObject("MSP_MMVR_Anchor"); + vrAnchor.transform.parent = PlayerSetup.Instance.vrCameraRig.transform; + vrAnchor.transform.localPosition = Vector3.zero; + this.worldAnchor = vrAnchor.transform; + } + + public void UpdateWorldAnchors() + { + if (this.worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; + + if (MetaPort.Instance.isUsingVr) + { + float zRotation = Mathf.Abs(MSP_MenuInfo.CameraTransform.localRotation.eulerAngles.z); + float minTilt = MetaPort.Instance.settings.GetSettingsFloat("GeneralMinimumMenuTilt", 0f); + if (zRotation <= minTilt || zRotation >= 360f - minTilt) + { + this.worldAnchor.rotation = Quaternion.LookRotation(MSP_MenuInfo.CameraTransform.forward, Vector3.up); + } + else + { + this.worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; + } + this.worldAnchor.position = MSP_MenuInfo.CameraTransform.position + MSP_MenuInfo.CameraTransform.forward * 2f * MSP_MenuInfo.ScaleFactor; + } + else + { + this.worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; + this.worldAnchor.position = MSP_MenuInfo.CameraTransform.position; + } + } + + public void UpdateMenuPosition() + { + if (MetaPort.Instance.isUsingVr) + { + HandleVRPosition(); + return; + } + + bool independentHeadTurnChanged = CVRInputManager.Instance.independentHeadTurn != prevIndependentHeadTurn; + if (independentHeadTurnChanged) + { + prevIndependentHeadTurn = CVRInputManager.Instance.independentHeadTurn; + //if pressing but not already enabled + if (prevIndependentHeadTurn) + { + if (!independentHeadTurn) + { + UpdateWorldAnchors(); + ToggleDesktopInputMethod(!prevIndependentHeadTurn); + independentHeadTurn = true; + } + returnIndependentHeadTurn = false; + } + else + { + returnIndependentHeadTurn = true; + } + } + + if (returnIndependentHeadTurn) + { + float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); + if (angle == 0f) + { + independentHeadTurn = false; + returnIndependentHeadTurn = false; + ToggleDesktopInputMethod(!prevIndependentHeadTurn); + } + } + + HandleDesktopPosition(); + } + + //Desktop Main Menu + public void HandleDesktopPosition() + { + if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableMMHelper) return; + + Transform activeAnchor = independentHeadTurn ? this.worldAnchor : MSP_MenuInfo.CameraTransform; + this.transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor, 0.9f * MSP_MenuInfo.ScaleFactor, 1f); + this.transform.eulerAngles = activeAnchor.eulerAngles; + this.transform.position = activeAnchor.position + activeAnchor.forward * 1f * MSP_MenuInfo.ScaleFactor; + } + + //VR Main Menu + public void HandleVRPosition() + { + if (this.worldAnchor == null || MSP_MenuInfo.DisableMMHelper_VR) return; + this.transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor * 1.8f, 0.9f * MSP_MenuInfo.ScaleFactor * 1.8f, 1f); + this.transform.position = this.worldAnchor.position; + this.transform.eulerAngles = this.worldAnchor.eulerAngles; + } +} + diff --git a/MenuScalePatch/Properties/AssemblyInfo.cs b/MenuScalePatch/Properties/AssemblyInfo.cs index a007473..34cef9b 100644 --- a/MenuScalePatch/Properties/AssemblyInfo.cs +++ b/MenuScalePatch/Properties/AssemblyInfo.cs @@ -11,7 +11,7 @@ using System.Reflection; [assembly: AssemblyProduct(nameof(MenuScalePatch))] [assembly: MelonInfo( - typeof(MenuScalePatch.MenuScalePatch), + typeof(NAK.Melons.MenuScalePatch.MenuScalePatch), nameof(MenuScalePatch), AssemblyInfoParams.Version, AssemblyInfoParams.Author, @@ -25,6 +25,6 @@ using System.Reflection; namespace MenuScalePatch.Properties; internal static class AssemblyInfoParams { - public const string Version = "3.0.0"; + public const string Version = "4.0.0"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/MenuScalePatch/QuickMenuHelper.cs b/MenuScalePatch/QuickMenuHelper.cs new file mode 100644 index 0000000..82e5791 --- /dev/null +++ b/MenuScalePatch/QuickMenuHelper.cs @@ -0,0 +1,148 @@ +using ABI_RC.Core.InteractionSystem; +using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; +using ABI_RC.Core; +using ABI_RC.Systems.MovementSystem; +using cohtml; +using HarmonyLib; +using MelonLoader; +using UnityEngine; +using System.Reflection; + +namespace NAK.Melons.MenuScalePatch.Helpers; + +/** + + This helper is assigned to the QuickMenu object. + The DefaultExecutionOrder attribute saves me from needing + to use OnPreRender() callback... yay. + +**/ + +[DefaultExecutionOrder(999999)] +public class QuickMenuHelper : MonoBehaviour +{ + public static QuickMenuHelper Instance; + public Transform worldAnchor; + public Transform handAnchor; + + static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); + private bool independentHeadTurn = false; + private bool returnIndependentHeadTurn = false; + private bool prevIndependentHeadTurn = false; + + void Start() + { + Instance = this; + CreateWorldAnchors(); + } + + void LateUpdate() + { + UpdateMenuPosition(); + } + + void OnDisable() + { + independentHeadTurn = false; + returnIndependentHeadTurn = false; + prevIndependentHeadTurn = false; + } + + public void ToggleDesktopInputMethod(bool flag) + { + PlayerSetup.Instance._movementSystem.disableCameraControl = flag; + CVRInputManager.Instance.inputEnabled = !flag; + RootLogic.Instance.ToggleMouse(flag); + CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag; + Traverse.Create(CVR_MenuManager.Instance).Field("_desktopMouseMode").SetValue(flag); + } + + public void CreateWorldAnchors() + { + //VR specific anchor + GameObject vrAnchor = new GameObject("MSP_QMVR_Anchor"); + vrAnchor.transform.parent = PlayerSetup.Instance.vrCameraRig.transform; + vrAnchor.transform.localPosition = Vector3.zero; + this.worldAnchor = vrAnchor.transform; + } + + public void UpdateWorldAnchors() + { + if (this.worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; + + this.worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; + this.worldAnchor.position = MSP_MenuInfo.CameraTransform.position; + } + + public void UpdateMenuPosition() + { + if (MetaPort.Instance.isUsingVr) + { + HandleVRPosition(); + return; + } + + bool independentHeadTurnChanged = CVRInputManager.Instance.independentHeadTurn != prevIndependentHeadTurn; + if (independentHeadTurnChanged) + { + prevIndependentHeadTurn = CVRInputManager.Instance.independentHeadTurn; + //if pressing but not already enabled + if (prevIndependentHeadTurn) + { + if (!independentHeadTurn) + { + UpdateWorldAnchors(); + ToggleDesktopInputMethod(!prevIndependentHeadTurn); + independentHeadTurn = true; + } + returnIndependentHeadTurn = false; + } + else + { + returnIndependentHeadTurn = true; + } + } + + if (returnIndependentHeadTurn) + { + float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); + if (angle == 0f) + { + independentHeadTurn = false; + returnIndependentHeadTurn = false; + ToggleDesktopInputMethod(!prevIndependentHeadTurn); + } + } + + HandleDesktopPosition(); + } + + //Desktop Quick Menu + public void HandleDesktopPosition() + { + if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableQMHelper) return; + + Transform activeAnchor = independentHeadTurn ? this.worldAnchor : MSP_MenuInfo.CameraTransform; + this.transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); + this.transform.eulerAngles = activeAnchor.eulerAngles; + this.transform.position = activeAnchor.position + activeAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor; + } + + //VR Quick Menu + public void HandleVRPosition() + { + if (this.handAnchor == null || MSP_MenuInfo.DisableQMHelper_VR) return; + + if (MSP_MenuInfo.WorldAnchorQM) + { + this.transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); + this.transform.eulerAngles = this.worldAnchor.eulerAngles; + this.transform.position = this.worldAnchor.position + this.worldAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor; + return; + } + this.transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); + this.transform.position = this.handAnchor.position; + this.transform.rotation = this.handAnchor.rotation; + } +} \ No newline at end of file From 61823892d17fc66191813411bc08a7d167ee806e Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 10:33:27 -0600 Subject: [PATCH 02/10] Update README.md --- README.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9b27b01..4a8dc6c 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,20 @@ # MenuScalePatch -just updates the menu position when the game detects a change in avatar scale +Originally forced menu position to update while scaling. Now changes ChilloutVR menu behavior to feel less clunky. -additional options to scale player collision & remove collider margin (skinWidth is pushing avatars off the floor by 0.08f) +## Features: +* Menu position properly updates at end of update cycle. + * This makes sure menu is always correctly positioned while moving and scaling. + * This also allows for menus to be used while moving. (this is iffy though) -To fully reach the floor, enable Scale Collision, No Skin Width, & Allow Small Player Collider in Experimental settings. - -**Be aware**, as Allow Small Player Collider will allow the collider to reach below 0.3f, which will cause *harmless..?* console errors. +* Adds independent head moving support while on Desktop. (makes selecting users easier) + * Hold ALT while on Desktop. Native feature that now works while in a menu. +* Implemented world anchors for menus. They can now be placed in the world, but still attached to you. + * This is used for independent head movement internally, as well as a toggle for VR QM. +* Main Menu in VR is now attached to player rig. + * Menu will now follow you while moving in world space, but not while moving in play space. https://user-images.githubusercontent.com/37721153/189479474-41e93dff-a695-42f2-9d20-6a895a723039.mp4 From 77c1e0fea97c63f65d8dfd9416bded5875faedc4 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 11:59:13 -0600 Subject: [PATCH 03/10] dont change mouse input while in VR bruh --- MenuScalePatch/HarmonyPatches.cs | 1 + .../{ => Helpers}/MainMenuHelper.cs | 37 ++++++++++--------- .../{ => Helpers}/QuickMenuHelper.cs | 34 +++++++++-------- MenuScalePatch/Properties/AssemblyInfo.cs | 2 +- 4 files changed, 39 insertions(+), 35 deletions(-) rename MenuScalePatch/{ => Helpers}/MainMenuHelper.cs (73%) rename MenuScalePatch/{ => Helpers}/QuickMenuHelper.cs (72%) diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs index 3d24450..d0c1abc 100644 --- a/MenuScalePatch/HarmonyPatches.cs +++ b/MenuScalePatch/HarmonyPatches.cs @@ -6,6 +6,7 @@ using cohtml; using HarmonyLib; using NAK.Melons.MenuScalePatch.Helpers; using UnityEngine; +using MenuScalePatch.Helpers; namespace NAK.Melons.MenuScalePatch.HarmonyPatches; diff --git a/MenuScalePatch/MainMenuHelper.cs b/MenuScalePatch/Helpers/MainMenuHelper.cs similarity index 73% rename from MenuScalePatch/MainMenuHelper.cs rename to MenuScalePatch/Helpers/MainMenuHelper.cs index ba3f83d..fd93a19 100644 --- a/MenuScalePatch/MainMenuHelper.cs +++ b/MenuScalePatch/Helpers/MainMenuHelper.cs @@ -8,8 +8,9 @@ using HarmonyLib; using MelonLoader; using UnityEngine; using System.Reflection; +using NAK.Melons.MenuScalePatch.Helpers; -namespace NAK.Melons.MenuScalePatch.Helpers; +namespace MenuScalePatch.Helpers; //TODO: Implement desktop ratio scaling back to MM @@ -52,6 +53,7 @@ public class MainMenuHelper : MonoBehaviour public void ToggleDesktopInputMethod(bool flag) { + if (MetaPort.Instance.isUsingVr) return; PlayerSetup.Instance._movementSystem.disableCameraControl = flag; CVRInputManager.Instance.inputEnabled = !flag; RootLogic.Instance.ToggleMouse(flag); @@ -65,12 +67,12 @@ public class MainMenuHelper : MonoBehaviour GameObject vrAnchor = new GameObject("MSP_MMVR_Anchor"); vrAnchor.transform.parent = PlayerSetup.Instance.vrCameraRig.transform; vrAnchor.transform.localPosition = Vector3.zero; - this.worldAnchor = vrAnchor.transform; + worldAnchor = vrAnchor.transform; } public void UpdateWorldAnchors() { - if (this.worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; + if (worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; if (MetaPort.Instance.isUsingVr) { @@ -78,18 +80,18 @@ public class MainMenuHelper : MonoBehaviour float minTilt = MetaPort.Instance.settings.GetSettingsFloat("GeneralMinimumMenuTilt", 0f); if (zRotation <= minTilt || zRotation >= 360f - minTilt) { - this.worldAnchor.rotation = Quaternion.LookRotation(MSP_MenuInfo.CameraTransform.forward, Vector3.up); + worldAnchor.rotation = Quaternion.LookRotation(MSP_MenuInfo.CameraTransform.forward, Vector3.up); } else { - this.worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; + worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; } - this.worldAnchor.position = MSP_MenuInfo.CameraTransform.position + MSP_MenuInfo.CameraTransform.forward * 2f * MSP_MenuInfo.ScaleFactor; + worldAnchor.position = MSP_MenuInfo.CameraTransform.position + MSP_MenuInfo.CameraTransform.forward * 2f * MSP_MenuInfo.ScaleFactor; } else { - this.worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; - this.worldAnchor.position = MSP_MenuInfo.CameraTransform.position; + worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; + worldAnchor.position = MSP_MenuInfo.CameraTransform.position; } } @@ -141,19 +143,18 @@ public class MainMenuHelper : MonoBehaviour { if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableMMHelper) return; - Transform activeAnchor = independentHeadTurn ? this.worldAnchor : MSP_MenuInfo.CameraTransform; - this.transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor, 0.9f * MSP_MenuInfo.ScaleFactor, 1f); - this.transform.eulerAngles = activeAnchor.eulerAngles; - this.transform.position = activeAnchor.position + activeAnchor.forward * 1f * MSP_MenuInfo.ScaleFactor; + Transform activeAnchor = independentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; + transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor, 0.9f * MSP_MenuInfo.ScaleFactor, 1f); + transform.eulerAngles = activeAnchor.eulerAngles; + transform.position = activeAnchor.position + activeAnchor.forward * 1f * MSP_MenuInfo.ScaleFactor; } //VR Main Menu public void HandleVRPosition() { - if (this.worldAnchor == null || MSP_MenuInfo.DisableMMHelper_VR) return; - this.transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor * 1.8f, 0.9f * MSP_MenuInfo.ScaleFactor * 1.8f, 1f); - this.transform.position = this.worldAnchor.position; - this.transform.eulerAngles = this.worldAnchor.eulerAngles; + if (worldAnchor == null || MSP_MenuInfo.DisableMMHelper_VR) return; + transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor * 1.8f, 0.9f * MSP_MenuInfo.ScaleFactor * 1.8f, 1f); + transform.position = worldAnchor.position; + transform.eulerAngles = worldAnchor.eulerAngles; } -} - +} \ No newline at end of file diff --git a/MenuScalePatch/QuickMenuHelper.cs b/MenuScalePatch/Helpers/QuickMenuHelper.cs similarity index 72% rename from MenuScalePatch/QuickMenuHelper.cs rename to MenuScalePatch/Helpers/QuickMenuHelper.cs index 82e5791..b99c5a5 100644 --- a/MenuScalePatch/QuickMenuHelper.cs +++ b/MenuScalePatch/Helpers/QuickMenuHelper.cs @@ -8,8 +8,9 @@ using HarmonyLib; using MelonLoader; using UnityEngine; using System.Reflection; +using NAK.Melons.MenuScalePatch.Helpers; -namespace NAK.Melons.MenuScalePatch.Helpers; +namespace MenuScalePatch.Helpers; /** @@ -51,6 +52,7 @@ public class QuickMenuHelper : MonoBehaviour public void ToggleDesktopInputMethod(bool flag) { + if (MetaPort.Instance.isUsingVr) return; PlayerSetup.Instance._movementSystem.disableCameraControl = flag; CVRInputManager.Instance.inputEnabled = !flag; RootLogic.Instance.ToggleMouse(flag); @@ -64,15 +66,15 @@ public class QuickMenuHelper : MonoBehaviour GameObject vrAnchor = new GameObject("MSP_QMVR_Anchor"); vrAnchor.transform.parent = PlayerSetup.Instance.vrCameraRig.transform; vrAnchor.transform.localPosition = Vector3.zero; - this.worldAnchor = vrAnchor.transform; + worldAnchor = vrAnchor.transform; } public void UpdateWorldAnchors() { - if (this.worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; + if (worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; - this.worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; - this.worldAnchor.position = MSP_MenuInfo.CameraTransform.position; + worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; + worldAnchor.position = MSP_MenuInfo.CameraTransform.position; } public void UpdateMenuPosition() @@ -123,26 +125,26 @@ public class QuickMenuHelper : MonoBehaviour { if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableQMHelper) return; - Transform activeAnchor = independentHeadTurn ? this.worldAnchor : MSP_MenuInfo.CameraTransform; - this.transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); - this.transform.eulerAngles = activeAnchor.eulerAngles; - this.transform.position = activeAnchor.position + activeAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor; + Transform activeAnchor = independentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; + transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); + transform.eulerAngles = activeAnchor.eulerAngles; + transform.position = activeAnchor.position + activeAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor; } //VR Quick Menu public void HandleVRPosition() { - if (this.handAnchor == null || MSP_MenuInfo.DisableQMHelper_VR) return; + if (handAnchor == null || MSP_MenuInfo.DisableQMHelper_VR) return; if (MSP_MenuInfo.WorldAnchorQM) { - this.transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); - this.transform.eulerAngles = this.worldAnchor.eulerAngles; - this.transform.position = this.worldAnchor.position + this.worldAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor; + transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); + transform.eulerAngles = worldAnchor.eulerAngles; + transform.position = worldAnchor.position + worldAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor; return; } - this.transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); - this.transform.position = this.handAnchor.position; - this.transform.rotation = this.handAnchor.rotation; + transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); + transform.position = handAnchor.position; + transform.rotation = handAnchor.rotation; } } \ No newline at end of file diff --git a/MenuScalePatch/Properties/AssemblyInfo.cs b/MenuScalePatch/Properties/AssemblyInfo.cs index 34cef9b..ab7045d 100644 --- a/MenuScalePatch/Properties/AssemblyInfo.cs +++ b/MenuScalePatch/Properties/AssemblyInfo.cs @@ -25,6 +25,6 @@ using System.Reflection; namespace MenuScalePatch.Properties; internal static class AssemblyInfoParams { - public const string Version = "4.0.0"; + public const string Version = "4.0.1"; public const string Author = "NotAKidoS"; } \ No newline at end of file From 8ef891434ae66772719c5e076a2e13cac89f374e Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 12:27:08 -0600 Subject: [PATCH 04/10] add aspect ratio calculation --- MenuScalePatch/HarmonyPatches.cs | 27 +++++++++++++++--------- MenuScalePatch/Helpers/MainMenuHelper.cs | 2 +- MenuScalePatch/MSP_Menus.cs | 1 + 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs index d0c1abc..3cfee9d 100644 --- a/MenuScalePatch/HarmonyPatches.cs +++ b/MenuScalePatch/HarmonyPatches.cs @@ -10,6 +10,16 @@ using MenuScalePatch.Helpers; namespace NAK.Melons.MenuScalePatch.HarmonyPatches; +/** + ViewManager.SetScale runs once a second when it should only run when aspect ratio changes- CVR bug + assuming its caused by cast from int to float getting the screen size, something floating point bleh + + ViewManager.UpdatePosition & CVR_MenuManager.UpdatePosition are called every second in a scheduled job. + (its why ViewManager.SetScale is called, because MM uses aspect ratio in scale calculation) + + I nuke those methods. Fuck them. I cannot disable the jobs though... +**/ + [HarmonyPatch] internal class HarmonyPatches { @@ -18,10 +28,7 @@ internal class HarmonyPatches private static void SetQMScale(float avatarHeight, ref float ____scaleFactor, out bool __runOriginal) { ____scaleFactor = avatarHeight / 1.8f; - if (MetaPort.Instance.isUsingVr) - { - ____scaleFactor *= 0.5f; - } + if (MetaPort.Instance.isUsingVr) ____scaleFactor *= 0.5f; MSP_MenuInfo.ScaleFactor = ____scaleFactor; __runOriginal = false; } @@ -30,11 +37,7 @@ internal class HarmonyPatches [HarmonyPatch(typeof(ViewManager), "SetScale")] private static void CheckMMScale(out bool __runOriginal) { - /** - ViewManager.SetScale runs once a second when it should only run when aspect ratio changes- CVR bug - assuming its caused by cast from int to float getting the screen size, something floating point bleh - i dont need it so i will nuke it >:) - **/ + //bitch __runOriginal = false; } @@ -48,8 +51,11 @@ internal class HarmonyPatches } [HarmonyPrefix] [HarmonyPatch(typeof(ViewManager), "UpdateMenuPosition")] - private static void Prefix_ViewManager_UpdateMenuPosition(out bool __runOriginal) + private static void Prefix_ViewManager_UpdateMenuPosition(ref float ___cachedScreenAspectRatio, out bool __runOriginal) { + //this is called once a second, so ill fix their dumb aspect ratio shit + float ratio = (float)Screen.width / (float)Screen.height; + MSP_MenuInfo.AspectRatio = 1.7777779f / ratio; __runOriginal = false; } @@ -96,6 +102,7 @@ internal class HarmonyPatches { if (MainMenuHelper.Instance == null) return; MainMenuHelper.Instance.UpdateWorldAnchors(); + MainMenuHelper.Instance.ToggleDesktopInputMethod(show); MainMenuHelper.Instance.enabled = show; } diff --git a/MenuScalePatch/Helpers/MainMenuHelper.cs b/MenuScalePatch/Helpers/MainMenuHelper.cs index fd93a19..c5411d1 100644 --- a/MenuScalePatch/Helpers/MainMenuHelper.cs +++ b/MenuScalePatch/Helpers/MainMenuHelper.cs @@ -146,7 +146,7 @@ public class MainMenuHelper : MonoBehaviour Transform activeAnchor = independentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor, 0.9f * MSP_MenuInfo.ScaleFactor, 1f); transform.eulerAngles = activeAnchor.eulerAngles; - transform.position = activeAnchor.position + activeAnchor.forward * 1f * MSP_MenuInfo.ScaleFactor; + transform.position = activeAnchor.position + activeAnchor.forward * 1f * MSP_MenuInfo.ScaleFactor * MSP_MenuInfo.AspectRatio; } //VR Main Menu diff --git a/MenuScalePatch/MSP_Menus.cs b/MenuScalePatch/MSP_Menus.cs index 341c3c3..d690295 100644 --- a/MenuScalePatch/MSP_Menus.cs +++ b/MenuScalePatch/MSP_Menus.cs @@ -12,6 +12,7 @@ public class MSP_MenuInfo { //Shared Info public static float ScaleFactor = 1f; + public static float AspectRatio = 1f; public static Transform CameraTransform; //Settings...? From 81affe9377284d337a25891f6e84e7e977c5b21b Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 12:44:56 -0600 Subject: [PATCH 05/10] add clamp to aspect ratio --- MenuScalePatch/HarmonyPatches.cs | 3 ++- MenuScalePatch/MenuScalePatch.csproj | 9 --------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs index 3cfee9d..189e34a 100644 --- a/MenuScalePatch/HarmonyPatches.cs +++ b/MenuScalePatch/HarmonyPatches.cs @@ -55,7 +55,8 @@ internal class HarmonyPatches { //this is called once a second, so ill fix their dumb aspect ratio shit float ratio = (float)Screen.width / (float)Screen.height; - MSP_MenuInfo.AspectRatio = 1.7777779f / ratio; + float clamp = Mathf.Clamp(ratio, 0f, 1.8f); + MSP_MenuInfo.AspectRatio = 1.7777779f / clamp; __runOriginal = false; } diff --git a/MenuScalePatch/MenuScalePatch.csproj b/MenuScalePatch/MenuScalePatch.csproj index bb32f6d..655b3bd 100644 --- a/MenuScalePatch/MenuScalePatch.csproj +++ b/MenuScalePatch/MenuScalePatch.csproj @@ -18,24 +18,15 @@ ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll - - ..\..\Giamoz\Giamoz\bin\Debug\net472\Giamoz.dll - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll - - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\SteamVR.dll - C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll - - ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll - From 845baee8498153243d63938b9d8a6e6d724933ef Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:45:32 -0600 Subject: [PATCH 06/10] well --- MenuScalePatch/HarmonyPatches.cs | 13 +++++++++++-- MenuScalePatch/Helpers/MainMenuHelper.cs | 21 +++++++++------------ MenuScalePatch/Helpers/QuickMenuHelper.cs | 21 +++++++++------------ MenuScalePatch/MSP_Menus.cs | 16 ++++++++++++++++ 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs index 189e34a..d6e1a3d 100644 --- a/MenuScalePatch/HarmonyPatches.cs +++ b/MenuScalePatch/HarmonyPatches.cs @@ -84,7 +84,7 @@ internal class HarmonyPatches { if (QuickMenuHelper.Instance == null) return; QuickMenuHelper.Instance.UpdateWorldAnchors(); - QuickMenuHelper.Instance.ToggleDesktopInputMethod(show); + MSP_MenuInfo.ToggleDesktopInputMethod(show); QuickMenuHelper.Instance.enabled = show; } @@ -103,7 +103,7 @@ internal class HarmonyPatches { if (MainMenuHelper.Instance == null) return; MainMenuHelper.Instance.UpdateWorldAnchors(); - MainMenuHelper.Instance.ToggleDesktopInputMethod(show); + MSP_MenuInfo.ToggleDesktopInputMethod(show); MainMenuHelper.Instance.enabled = show; } @@ -114,4 +114,13 @@ internal class HarmonyPatches { MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform; } + + //only fixes Desktop QM interaction while using independent head input... + //[HarmonyPrefix] + //[HarmonyPatch(typeof(ControllerRay), "LateUpdate")] + //private static void UpdateMenuPositionForInput() + //{ + // MainMenuHelper.Instance.UpdateMenuPosition(); + // QuickMenuHelper.Instance.UpdateMenuPosition(); + //} } \ No newline at end of file diff --git a/MenuScalePatch/Helpers/MainMenuHelper.cs b/MenuScalePatch/Helpers/MainMenuHelper.cs index c5411d1..1c90ee9 100644 --- a/MenuScalePatch/Helpers/MainMenuHelper.cs +++ b/MenuScalePatch/Helpers/MainMenuHelper.cs @@ -44,21 +44,18 @@ public class MainMenuHelper : MonoBehaviour UpdateMenuPosition(); } - void OnDisable() + void OnEnable() { independentHeadTurn = false; returnIndependentHeadTurn = false; prevIndependentHeadTurn = false; } - public void ToggleDesktopInputMethod(bool flag) + void OnDisable() { - if (MetaPort.Instance.isUsingVr) return; - PlayerSetup.Instance._movementSystem.disableCameraControl = flag; - CVRInputManager.Instance.inputEnabled = !flag; - RootLogic.Instance.ToggleMouse(flag); - CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag; - Traverse.Create(CVR_MenuManager.Instance).Field("_desktopMouseMode").SetValue(flag); + independentHeadTurn = false; + returnIndependentHeadTurn = false; + prevIndependentHeadTurn = false; } public void CreateWorldAnchors() @@ -103,6 +100,7 @@ public class MainMenuHelper : MonoBehaviour return; } + float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); bool independentHeadTurnChanged = CVRInputManager.Instance.independentHeadTurn != prevIndependentHeadTurn; if (independentHeadTurnChanged) { @@ -110,10 +108,10 @@ public class MainMenuHelper : MonoBehaviour //if pressing but not already enabled if (prevIndependentHeadTurn) { - if (!independentHeadTurn) + if (!independentHeadTurn && angle == 0f) { UpdateWorldAnchors(); - ToggleDesktopInputMethod(!prevIndependentHeadTurn); + MSP_MenuInfo.ToggleDesktopInputMethod(!prevIndependentHeadTurn); independentHeadTurn = true; } returnIndependentHeadTurn = false; @@ -126,12 +124,11 @@ public class MainMenuHelper : MonoBehaviour if (returnIndependentHeadTurn) { - float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); if (angle == 0f) { independentHeadTurn = false; returnIndependentHeadTurn = false; - ToggleDesktopInputMethod(!prevIndependentHeadTurn); + MSP_MenuInfo.ToggleDesktopInputMethod(!prevIndependentHeadTurn); } } diff --git a/MenuScalePatch/Helpers/QuickMenuHelper.cs b/MenuScalePatch/Helpers/QuickMenuHelper.cs index b99c5a5..a0f467a 100644 --- a/MenuScalePatch/Helpers/QuickMenuHelper.cs +++ b/MenuScalePatch/Helpers/QuickMenuHelper.cs @@ -43,21 +43,18 @@ public class QuickMenuHelper : MonoBehaviour UpdateMenuPosition(); } - void OnDisable() + void OnEnable() { independentHeadTurn = false; returnIndependentHeadTurn = false; prevIndependentHeadTurn = false; } - public void ToggleDesktopInputMethod(bool flag) + void OnDisable() { - if (MetaPort.Instance.isUsingVr) return; - PlayerSetup.Instance._movementSystem.disableCameraControl = flag; - CVRInputManager.Instance.inputEnabled = !flag; - RootLogic.Instance.ToggleMouse(flag); - CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag; - Traverse.Create(CVR_MenuManager.Instance).Field("_desktopMouseMode").SetValue(flag); + independentHeadTurn = false; + returnIndependentHeadTurn = false; + prevIndependentHeadTurn = false; } public void CreateWorldAnchors() @@ -85,6 +82,7 @@ public class QuickMenuHelper : MonoBehaviour return; } + float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); bool independentHeadTurnChanged = CVRInputManager.Instance.independentHeadTurn != prevIndependentHeadTurn; if (independentHeadTurnChanged) { @@ -92,10 +90,10 @@ public class QuickMenuHelper : MonoBehaviour //if pressing but not already enabled if (prevIndependentHeadTurn) { - if (!independentHeadTurn) + if (!independentHeadTurn && angle == 0f) { UpdateWorldAnchors(); - ToggleDesktopInputMethod(!prevIndependentHeadTurn); + MSP_MenuInfo.ToggleDesktopInputMethod(!prevIndependentHeadTurn); independentHeadTurn = true; } returnIndependentHeadTurn = false; @@ -108,12 +106,11 @@ public class QuickMenuHelper : MonoBehaviour if (returnIndependentHeadTurn) { - float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); if (angle == 0f) { independentHeadTurn = false; returnIndependentHeadTurn = false; - ToggleDesktopInputMethod(!prevIndependentHeadTurn); + MSP_MenuInfo.ToggleDesktopInputMethod(!prevIndependentHeadTurn); } } diff --git a/MenuScalePatch/MSP_Menus.cs b/MenuScalePatch/MSP_Menus.cs index d690295..3961816 100644 --- a/MenuScalePatch/MSP_Menus.cs +++ b/MenuScalePatch/MSP_Menus.cs @@ -4,7 +4,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; +using ABI_RC.Core.InteractionSystem; +using ABI_RC.Core.Player; using ABI_RC.Core.Savior; +using ABI_RC.Core; +using ABI_RC.Systems.MovementSystem; +using HarmonyLib; namespace NAK.Melons.MenuScalePatch.Helpers; @@ -23,4 +28,15 @@ public class MSP_MenuInfo public static bool DisableQMHelper_VR; public static bool DisableMMHelper; public static bool DisableMMHelper_VR; + + public static void ToggleDesktopInputMethod(bool flag) + { + if (MetaPort.Instance.isUsingVr) return; + MelonLoader.MelonLogger.Msg("Toggled Desktop Input"); + PlayerSetup.Instance._movementSystem.disableCameraControl = flag; + CVRInputManager.Instance.inputEnabled = !flag; + RootLogic.Instance.ToggleMouse(flag); + CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag; + Traverse.Create(CVR_MenuManager.Instance).Field("_desktopMouseMode").SetValue(flag); + } } \ No newline at end of file From 4a5527d7de0e7c59defcd910c3827487b19e3668 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 21:11:16 -0600 Subject: [PATCH 07/10] i hate all holy shit this fucking bug took me two hours to fix why was the solution so simple... fuck --- MenuScalePatch/HarmonyPatches.cs | 31 ++++++------- MenuScalePatch/Helpers/MainMenuHelper.cs | 56 +---------------------- MenuScalePatch/Helpers/QuickMenuHelper.cs | 56 +---------------------- MenuScalePatch/MSP_Menus.cs | 21 ++++++++- 4 files changed, 38 insertions(+), 126 deletions(-) diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs index d6e1a3d..97e38aa 100644 --- a/MenuScalePatch/HarmonyPatches.cs +++ b/MenuScalePatch/HarmonyPatches.cs @@ -78,13 +78,16 @@ internal class HarmonyPatches } //hook quickmenu open/close - [HarmonyPostfix] + [HarmonyPrefix] [HarmonyPatch(typeof(CVR_MenuManager), "ToggleQuickMenu", new Type[] { typeof(bool) })] - private static void Postfix_CVR_MenuManager_ToggleQuickMenu(bool show) + private static void Postfix_CVR_MenuManager_ToggleQuickMenu(bool show, ref bool ____quickMenuOpen) { if (QuickMenuHelper.Instance == null) return; - QuickMenuHelper.Instance.UpdateWorldAnchors(); - MSP_MenuInfo.ToggleDesktopInputMethod(show); + if (show != ____quickMenuOpen) + { + QuickMenuHelper.Instance.UpdateWorldAnchors(); + MSP_MenuInfo.ToggleDesktopInputMethod(show); + } QuickMenuHelper.Instance.enabled = show; } @@ -97,13 +100,16 @@ internal class HarmonyPatches } //hook menu open/close - [HarmonyPostfix] + [HarmonyPrefix] [HarmonyPatch(typeof(ViewManager), "UiStateToggle", new Type[] { typeof(bool) })] - private static void Postfix_ViewManager_UiStateToggle(bool show) + private static void Postfix_ViewManager_UiStateToggle(bool show, ref bool ____gameMenuOpen) { if (MainMenuHelper.Instance == null) return; - MainMenuHelper.Instance.UpdateWorldAnchors(); - MSP_MenuInfo.ToggleDesktopInputMethod(show); + if (show != ____gameMenuOpen) + { + MainMenuHelper.Instance.UpdateWorldAnchors(); + MSP_MenuInfo.ToggleDesktopInputMethod(show); + } MainMenuHelper.Instance.enabled = show; } @@ -114,13 +120,4 @@ internal class HarmonyPatches { MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform; } - - //only fixes Desktop QM interaction while using independent head input... - //[HarmonyPrefix] - //[HarmonyPatch(typeof(ControllerRay), "LateUpdate")] - //private static void UpdateMenuPositionForInput() - //{ - // MainMenuHelper.Instance.UpdateMenuPosition(); - // QuickMenuHelper.Instance.UpdateMenuPosition(); - //} } \ No newline at end of file diff --git a/MenuScalePatch/Helpers/MainMenuHelper.cs b/MenuScalePatch/Helpers/MainMenuHelper.cs index 1c90ee9..5959276 100644 --- a/MenuScalePatch/Helpers/MainMenuHelper.cs +++ b/MenuScalePatch/Helpers/MainMenuHelper.cs @@ -28,11 +28,6 @@ public class MainMenuHelper : MonoBehaviour public static MainMenuHelper Instance; public Transform worldAnchor; - static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); - private bool independentHeadTurn = false; - private bool returnIndependentHeadTurn = false; - private bool prevIndependentHeadTurn = false; - void Start() { Instance = this; @@ -41,23 +36,10 @@ public class MainMenuHelper : MonoBehaviour void LateUpdate() { + MSP_MenuInfo.HandleIndependentLookInput(); UpdateMenuPosition(); } - void OnEnable() - { - independentHeadTurn = false; - returnIndependentHeadTurn = false; - prevIndependentHeadTurn = false; - } - - void OnDisable() - { - independentHeadTurn = false; - returnIndependentHeadTurn = false; - prevIndependentHeadTurn = false; - } - public void CreateWorldAnchors() { //VR specific anchor @@ -99,39 +81,6 @@ public class MainMenuHelper : MonoBehaviour HandleVRPosition(); return; } - - float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); - bool independentHeadTurnChanged = CVRInputManager.Instance.independentHeadTurn != prevIndependentHeadTurn; - if (independentHeadTurnChanged) - { - prevIndependentHeadTurn = CVRInputManager.Instance.independentHeadTurn; - //if pressing but not already enabled - if (prevIndependentHeadTurn) - { - if (!independentHeadTurn && angle == 0f) - { - UpdateWorldAnchors(); - MSP_MenuInfo.ToggleDesktopInputMethod(!prevIndependentHeadTurn); - independentHeadTurn = true; - } - returnIndependentHeadTurn = false; - } - else - { - returnIndependentHeadTurn = true; - } - } - - if (returnIndependentHeadTurn) - { - if (angle == 0f) - { - independentHeadTurn = false; - returnIndependentHeadTurn = false; - MSP_MenuInfo.ToggleDesktopInputMethod(!prevIndependentHeadTurn); - } - } - HandleDesktopPosition(); } @@ -139,8 +88,7 @@ public class MainMenuHelper : MonoBehaviour public void HandleDesktopPosition() { if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableMMHelper) return; - - Transform activeAnchor = independentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; + Transform activeAnchor = MSP_MenuInfo.independentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor, 0.9f * MSP_MenuInfo.ScaleFactor, 1f); transform.eulerAngles = activeAnchor.eulerAngles; transform.position = activeAnchor.position + activeAnchor.forward * 1f * MSP_MenuInfo.ScaleFactor * MSP_MenuInfo.AspectRatio; diff --git a/MenuScalePatch/Helpers/QuickMenuHelper.cs b/MenuScalePatch/Helpers/QuickMenuHelper.cs index a0f467a..e2b5fce 100644 --- a/MenuScalePatch/Helpers/QuickMenuHelper.cs +++ b/MenuScalePatch/Helpers/QuickMenuHelper.cs @@ -27,11 +27,6 @@ public class QuickMenuHelper : MonoBehaviour public Transform worldAnchor; public Transform handAnchor; - static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); - private bool independentHeadTurn = false; - private bool returnIndependentHeadTurn = false; - private bool prevIndependentHeadTurn = false; - void Start() { Instance = this; @@ -40,23 +35,10 @@ public class QuickMenuHelper : MonoBehaviour void LateUpdate() { + MSP_MenuInfo.HandleIndependentLookInput(); UpdateMenuPosition(); } - void OnEnable() - { - independentHeadTurn = false; - returnIndependentHeadTurn = false; - prevIndependentHeadTurn = false; - } - - void OnDisable() - { - independentHeadTurn = false; - returnIndependentHeadTurn = false; - prevIndependentHeadTurn = false; - } - public void CreateWorldAnchors() { //VR specific anchor @@ -69,7 +51,6 @@ public class QuickMenuHelper : MonoBehaviour public void UpdateWorldAnchors() { if (worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; - worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; worldAnchor.position = MSP_MenuInfo.CameraTransform.position; } @@ -81,39 +62,6 @@ public class QuickMenuHelper : MonoBehaviour HandleVRPosition(); return; } - - float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); - bool independentHeadTurnChanged = CVRInputManager.Instance.independentHeadTurn != prevIndependentHeadTurn; - if (independentHeadTurnChanged) - { - prevIndependentHeadTurn = CVRInputManager.Instance.independentHeadTurn; - //if pressing but not already enabled - if (prevIndependentHeadTurn) - { - if (!independentHeadTurn && angle == 0f) - { - UpdateWorldAnchors(); - MSP_MenuInfo.ToggleDesktopInputMethod(!prevIndependentHeadTurn); - independentHeadTurn = true; - } - returnIndependentHeadTurn = false; - } - else - { - returnIndependentHeadTurn = true; - } - } - - if (returnIndependentHeadTurn) - { - if (angle == 0f) - { - independentHeadTurn = false; - returnIndependentHeadTurn = false; - MSP_MenuInfo.ToggleDesktopInputMethod(!prevIndependentHeadTurn); - } - } - HandleDesktopPosition(); } @@ -122,7 +70,7 @@ public class QuickMenuHelper : MonoBehaviour { if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableQMHelper) return; - Transform activeAnchor = independentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; + Transform activeAnchor = MSP_MenuInfo.independentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); transform.eulerAngles = activeAnchor.eulerAngles; transform.position = activeAnchor.position + activeAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor; diff --git a/MenuScalePatch/MSP_Menus.cs b/MenuScalePatch/MSP_Menus.cs index 3961816..0e56fbf 100644 --- a/MenuScalePatch/MSP_Menus.cs +++ b/MenuScalePatch/MSP_Menus.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Collections.Generic; using System.Linq; using System.Text; @@ -32,11 +33,29 @@ public class MSP_MenuInfo public static void ToggleDesktopInputMethod(bool flag) { if (MetaPort.Instance.isUsingVr) return; - MelonLoader.MelonLogger.Msg("Toggled Desktop Input"); PlayerSetup.Instance._movementSystem.disableCameraControl = flag; CVRInputManager.Instance.inputEnabled = !flag; RootLogic.Instance.ToggleMouse(flag); CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag; Traverse.Create(CVR_MenuManager.Instance).Field("_desktopMouseMode").SetValue(flag); } + + static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); + public static bool independentHeadTurn = false; + + public static void HandleIndependentLookInput() + { + //angle of independent look axis + float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); + bool isPressed = CVRInputManager.Instance.independentHeadTurn; + if (isPressed && !independentHeadTurn) + { + independentHeadTurn = true; + MSP_MenuInfo.ToggleDesktopInputMethod(false); + }else if (!isPressed && independentHeadTurn && angle == 0f) + { + independentHeadTurn = false; + MSP_MenuInfo.ToggleDesktopInputMethod(true); + } + } } \ No newline at end of file From 367a16746963e4395aada669c81362d5b0f1a934 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 21:38:23 -0600 Subject: [PATCH 08/10] polish my pain --- MenuScalePatch/HarmonyPatches.cs | 33 +++++++++++------------ MenuScalePatch/Helpers/MainMenuHelper.cs | 12 ++------- MenuScalePatch/Helpers/QuickMenuHelper.cs | 12 ++------- MenuScalePatch/MSP_Menus.cs | 27 ++++++++++--------- MenuScalePatch/Main.cs | 8 +----- 5 files changed, 35 insertions(+), 57 deletions(-) diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs index 97e38aa..8f601d8 100644 --- a/MenuScalePatch/HarmonyPatches.cs +++ b/MenuScalePatch/HarmonyPatches.cs @@ -1,12 +1,9 @@ using ABI_RC.Core.InteractionSystem; using ABI_RC.Core.Player; using ABI_RC.Core.Savior; -using ABI_RC.Core; -using cohtml; using HarmonyLib; using NAK.Melons.MenuScalePatch.Helpers; using UnityEngine; -using MenuScalePatch.Helpers; namespace NAK.Melons.MenuScalePatch.HarmonyPatches; @@ -25,7 +22,7 @@ internal class HarmonyPatches { [HarmonyPrefix] [HarmonyPatch(typeof(CVR_MenuManager), "SetScale")] - private static void SetQMScale(float avatarHeight, ref float ____scaleFactor, out bool __runOriginal) + private static void Prefix_CVR_MenuManager_SetScale(float avatarHeight, ref float ____scaleFactor, out bool __runOriginal) { ____scaleFactor = avatarHeight / 1.8f; if (MetaPort.Instance.isUsingVr) ____scaleFactor *= 0.5f; @@ -35,7 +32,7 @@ internal class HarmonyPatches [HarmonyPrefix] [HarmonyPatch(typeof(ViewManager), "SetScale")] - private static void CheckMMScale(out bool __runOriginal) + private static void Prefix_ViewManager_SetScale(out bool __runOriginal) { //bitch __runOriginal = false; @@ -47,8 +44,10 @@ internal class HarmonyPatches [HarmonyPatch(typeof(CVR_MenuManager), "UpdateMenuPosition")] private static void Prefix_CVR_MenuManager_UpdateMenuPosition(out bool __runOriginal) { + //fuck u __runOriginal = false; } + [HarmonyPrefix] [HarmonyPatch(typeof(ViewManager), "UpdateMenuPosition")] private static void Prefix_ViewManager_UpdateMenuPosition(ref float ___cachedScreenAspectRatio, out bool __runOriginal) @@ -63,7 +62,7 @@ internal class HarmonyPatches //Set QM stuff [HarmonyPostfix] [HarmonyPatch(typeof(CVR_MenuManager), "Start")] - private static void SetupQMHelper(ref CVR_MenuManager __instance, ref GameObject ____leftVrAnchor) + private static void Postfix_CVR_MenuManager_Start(ref CVR_MenuManager __instance, ref GameObject ____leftVrAnchor) { QuickMenuHelper helper = __instance.quickMenu.gameObject.AddComponent(); helper.handAnchor = ____leftVrAnchor.transform; @@ -72,7 +71,7 @@ internal class HarmonyPatches //Set MM stuff [HarmonyPostfix] [HarmonyPatch(typeof(ViewManager), "Start")] - private static void SetupMMHelper(ref ViewManager __instance) + private static void Postfix_ViewManager_Start(ref ViewManager __instance) { __instance.gameObject.AddComponent(); } @@ -80,7 +79,7 @@ internal class HarmonyPatches //hook quickmenu open/close [HarmonyPrefix] [HarmonyPatch(typeof(CVR_MenuManager), "ToggleQuickMenu", new Type[] { typeof(bool) })] - private static void Postfix_CVR_MenuManager_ToggleQuickMenu(bool show, ref bool ____quickMenuOpen) + private static void Prefix_CVR_MenuManager_ToggleQuickMenu(bool show, ref bool ____quickMenuOpen) { if (QuickMenuHelper.Instance == null) return; if (show != ____quickMenuOpen) @@ -91,14 +90,6 @@ internal class HarmonyPatches QuickMenuHelper.Instance.enabled = show; } - //add independent head movement to important input - [HarmonyPostfix] - [HarmonyPatch(typeof(InputModuleMouseKeyboard), "UpdateImportantInput")] - private static void Postfix_InputModuleMouseKeyboard_UpdateImportantInput(ref CVRInputManager ____inputManager) - { - ____inputManager.independentHeadTurn |= Input.GetKey(KeyCode.LeftAlt); - } - //hook menu open/close [HarmonyPrefix] [HarmonyPatch(typeof(ViewManager), "UiStateToggle", new Type[] { typeof(bool) })] @@ -113,10 +104,18 @@ internal class HarmonyPatches MainMenuHelper.Instance.enabled = show; } + //add independent head movement to important input + [HarmonyPostfix] + [HarmonyPatch(typeof(InputModuleMouseKeyboard), "UpdateImportantInput")] + private static void Postfix_InputModuleMouseKeyboard_UpdateImportantInput(ref CVRInputManager ____inputManager) + { + ____inputManager.independentHeadTurn |= Input.GetKey(KeyCode.LeftAlt); + } + //Support for changing VRMode during runtime. [HarmonyPostfix] [HarmonyPatch(typeof(PlayerSetup), "CalibrateAvatar")] - private static void CheckVRModeOnSwitch() + private static void Postfix_PlayerSetup_CalibrateAvatar() { MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform; } diff --git a/MenuScalePatch/Helpers/MainMenuHelper.cs b/MenuScalePatch/Helpers/MainMenuHelper.cs index 5959276..2df6d1b 100644 --- a/MenuScalePatch/Helpers/MainMenuHelper.cs +++ b/MenuScalePatch/Helpers/MainMenuHelper.cs @@ -1,16 +1,8 @@ -using ABI_RC.Core.InteractionSystem; -using ABI_RC.Core.Player; +using ABI_RC.Core.Player; using ABI_RC.Core.Savior; -using ABI_RC.Core; -using ABI_RC.Systems.MovementSystem; -using cohtml; -using HarmonyLib; -using MelonLoader; using UnityEngine; -using System.Reflection; -using NAK.Melons.MenuScalePatch.Helpers; -namespace MenuScalePatch.Helpers; +namespace NAK.Melons.MenuScalePatch.Helpers; //TODO: Implement desktop ratio scaling back to MM diff --git a/MenuScalePatch/Helpers/QuickMenuHelper.cs b/MenuScalePatch/Helpers/QuickMenuHelper.cs index e2b5fce..834251f 100644 --- a/MenuScalePatch/Helpers/QuickMenuHelper.cs +++ b/MenuScalePatch/Helpers/QuickMenuHelper.cs @@ -1,16 +1,8 @@ -using ABI_RC.Core.InteractionSystem; -using ABI_RC.Core.Player; +using ABI_RC.Core.Player; using ABI_RC.Core.Savior; -using ABI_RC.Core; -using ABI_RC.Systems.MovementSystem; -using cohtml; -using HarmonyLib; -using MelonLoader; using UnityEngine; -using System.Reflection; -using NAK.Melons.MenuScalePatch.Helpers; -namespace MenuScalePatch.Helpers; +namespace NAK.Melons.MenuScalePatch.Helpers; /** diff --git a/MenuScalePatch/MSP_Menus.cs b/MenuScalePatch/MSP_Menus.cs index 0e56fbf..290781c 100644 --- a/MenuScalePatch/MSP_Menus.cs +++ b/MenuScalePatch/MSP_Menus.cs @@ -1,16 +1,11 @@ -using System; -using System.Reflection; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; +using ABI_RC.Core; using ABI_RC.Core.InteractionSystem; using ABI_RC.Core.Player; using ABI_RC.Core.Savior; -using ABI_RC.Core; using ABI_RC.Systems.MovementSystem; using HarmonyLib; +using System.Reflection; +using UnityEngine; namespace NAK.Melons.MenuScalePatch.Helpers; @@ -46,16 +41,22 @@ public class MSP_MenuInfo public static void HandleIndependentLookInput() { //angle of independent look axis - float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); - bool isPressed = CVRInputManager.Instance.independentHeadTurn; + bool isPressed = CVRInputManager.Instance.independentHeadTurn || CVRInputManager.Instance.independentHeadToggle; if (isPressed && !independentHeadTurn) { independentHeadTurn = true; MSP_MenuInfo.ToggleDesktopInputMethod(false); - }else if (!isPressed && independentHeadTurn && angle == 0f) + QuickMenuHelper.Instance.UpdateWorldAnchors(); + MainMenuHelper.Instance.UpdateWorldAnchors(); + } + else if (!isPressed && independentHeadTurn) { - independentHeadTurn = false; - MSP_MenuInfo.ToggleDesktopInputMethod(true); + float angle = (float)ms_followAngleY.GetValue(MovementSystem.Instance); + if (angle == 0f) + { + independentHeadTurn = false; + MSP_MenuInfo.ToggleDesktopInputMethod(true); + } } } } \ No newline at end of file diff --git a/MenuScalePatch/Main.cs b/MenuScalePatch/Main.cs index 812989b..72a78d2 100644 --- a/MenuScalePatch/Main.cs +++ b/MenuScalePatch/Main.cs @@ -1,10 +1,4 @@ -using ABI_RC.Core.InteractionSystem; -using ABI_RC.Core.Player; -using ABI_RC.Core.Savior; -using cohtml; -using HarmonyLib; -using MelonLoader; -using UnityEngine; +using MelonLoader; using NAK.Melons.MenuScalePatch.Helpers; namespace NAK.Melons.MenuScalePatch; From 73bbc2a7c58dcbfbff2c06b833b3d9696b35b1f7 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 3 Jan 2023 22:45:31 -0600 Subject: [PATCH 09/10] a --- MenuScalePatch/Properties/AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MenuScalePatch/Properties/AssemblyInfo.cs b/MenuScalePatch/Properties/AssemblyInfo.cs index ab7045d..64804cf 100644 --- a/MenuScalePatch/Properties/AssemblyInfo.cs +++ b/MenuScalePatch/Properties/AssemblyInfo.cs @@ -25,6 +25,6 @@ using System.Reflection; namespace MenuScalePatch.Properties; internal static class AssemblyInfoParams { - public const string Version = "4.0.1"; + public const string Version = "4.1.1"; public const string Author = "NotAKidoS"; } \ No newline at end of file From 5d4b7e354aa138d2992e2f5783c59f5c7bc65f70 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 2 Feb 2023 22:25:35 -0600 Subject: [PATCH 10/10] i want no life --- MenuScalePatch/HarmonyPatches.cs | 162 +++++++++++++++++++--- MenuScalePatch/Helpers/MainMenuHelper.cs | 20 ++- MenuScalePatch/Helpers/QuickMenuHelper.cs | 17 ++- MenuScalePatch/MSP_Menus.cs | 31 +++-- MenuScalePatch/Main.cs | 27 ++-- MenuScalePatch/MenuScalePatch.csproj | 3 + MenuScalePatch/Properties/AssemblyInfo.cs | 2 +- MenuScalePatch/format.json | 8 +- 8 files changed, 208 insertions(+), 62 deletions(-) diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs index 8f601d8..999c87d 100644 --- a/MenuScalePatch/HarmonyPatches.cs +++ b/MenuScalePatch/HarmonyPatches.cs @@ -3,6 +3,8 @@ using ABI_RC.Core.Player; using ABI_RC.Core.Savior; using HarmonyLib; using NAK.Melons.MenuScalePatch.Helpers; +using System.Reflection; +using System.Reflection.Emit; using UnityEngine; namespace NAK.Melons.MenuScalePatch.HarmonyPatches; @@ -20,43 +22,64 @@ namespace NAK.Melons.MenuScalePatch.HarmonyPatches; [HarmonyPatch] internal class HarmonyPatches { + //stuff needed on start + [HarmonyPostfix] + [HarmonyPatch(typeof(PlayerSetup), "Start")] + private static void Postfix_PlayerSetup_Start() + { + try + { + MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform; + MenuScalePatch.UpdateAllSettings(); + QuickMenuHelper.Instance.CreateWorldAnchors(); + MainMenuHelper.Instance.CreateWorldAnchors(); + } + catch (System.Exception e) + { + MenuScalePatch.Logger.Error(e); + } + } + [HarmonyPrefix] [HarmonyPatch(typeof(CVR_MenuManager), "SetScale")] - private static void Prefix_CVR_MenuManager_SetScale(float avatarHeight, ref float ____scaleFactor, out bool __runOriginal) + private static bool Prefix_CVR_MenuManager_SetScale(float avatarHeight, ref float ____scaleFactor) { ____scaleFactor = avatarHeight / 1.8f; if (MetaPort.Instance.isUsingVr) ____scaleFactor *= 0.5f; MSP_MenuInfo.ScaleFactor = ____scaleFactor; - __runOriginal = false; + if (!MSP_MenuInfo.PlayerAnchorMenus) + { + QuickMenuHelper.Instance.NeedsPositionUpdate = true; + MainMenuHelper.Instance.NeedsPositionUpdate = true; + } + return false; } [HarmonyPrefix] [HarmonyPatch(typeof(ViewManager), "SetScale")] - private static void Prefix_ViewManager_SetScale(out bool __runOriginal) + private static bool Prefix_ViewManager_SetScale() { - //bitch - __runOriginal = false; + return false; } //nuke UpdateMenuPosition methods //there are 2 Jobs calling this each second, which is fucking my shit [HarmonyPrefix] [HarmonyPatch(typeof(CVR_MenuManager), "UpdateMenuPosition")] - private static void Prefix_CVR_MenuManager_UpdateMenuPosition(out bool __runOriginal) + private static bool Prefix_CVR_MenuManager_UpdateMenuPosition() { - //fuck u - __runOriginal = false; + return false; } [HarmonyPrefix] [HarmonyPatch(typeof(ViewManager), "UpdateMenuPosition")] - private static void Prefix_ViewManager_UpdateMenuPosition(ref float ___cachedScreenAspectRatio, out bool __runOriginal) + private static bool Prefix_ViewManager_UpdateMenuPosition(ref float ___cachedScreenAspectRatio) { //this is called once a second, so ill fix their dumb aspect ratio shit float ratio = (float)Screen.width / (float)Screen.height; float clamp = Mathf.Clamp(ratio, 0f, 1.8f); MSP_MenuInfo.AspectRatio = 1.7777779f / clamp; - __runOriginal = false; + return false; } //Set QM stuff @@ -64,8 +87,16 @@ internal class HarmonyPatches [HarmonyPatch(typeof(CVR_MenuManager), "Start")] private static void Postfix_CVR_MenuManager_Start(ref CVR_MenuManager __instance, ref GameObject ____leftVrAnchor) { - QuickMenuHelper helper = __instance.quickMenu.gameObject.AddComponent(); - helper.handAnchor = ____leftVrAnchor.transform; + try + { + QuickMenuHelper helper = __instance.quickMenu.gameObject.AddComponent(); + helper.handAnchor = ____leftVrAnchor.transform; + helper.enabled = false; + } + catch (System.Exception e) + { + MenuScalePatch.Logger.Error(e); + } } //Set MM stuff @@ -73,35 +104,71 @@ internal class HarmonyPatches [HarmonyPatch(typeof(ViewManager), "Start")] private static void Postfix_ViewManager_Start(ref ViewManager __instance) { - __instance.gameObject.AddComponent(); + try + { + MainMenuHelper helper = __instance.gameObject.AddComponent(); + helper.enabled = false; + } + catch (System.Exception e) + { + MenuScalePatch.Logger.Error(e); + } } //hook quickmenu open/close [HarmonyPrefix] [HarmonyPatch(typeof(CVR_MenuManager), "ToggleQuickMenu", new Type[] { typeof(bool) })] - private static void Prefix_CVR_MenuManager_ToggleQuickMenu(bool show, ref bool ____quickMenuOpen) + private static bool Prefix_CVR_MenuManager_ToggleQuickMenu(bool show, ref CVR_MenuManager __instance, ref bool ____quickMenuOpen) { - if (QuickMenuHelper.Instance == null) return; + if (QuickMenuHelper.Instance == null) return true; if (show != ____quickMenuOpen) { - QuickMenuHelper.Instance.UpdateWorldAnchors(); + ____quickMenuOpen = show; + __instance.quickMenu.enabled = show; + __instance.quickMenuAnimator.SetBool("Open", show); + QuickMenuHelper.Instance.enabled = show; + QuickMenuHelper.Instance.UpdateWorldAnchors(show); + //shouldnt run if switching menus on desktop + if (!MetaPort.Instance.isUsingVr) + { + if (!show && MainMenuHelper.Instance.enabled) + { + return false; + } + ViewManager.Instance.UiStateToggle(false); + } MSP_MenuInfo.ToggleDesktopInputMethod(show); + CVRPlayerManager.Instance.ReloadAllNameplates(); } - QuickMenuHelper.Instance.enabled = show; + return false; } //hook menu open/close [HarmonyPrefix] [HarmonyPatch(typeof(ViewManager), "UiStateToggle", new Type[] { typeof(bool) })] - private static void Postfix_ViewManager_UiStateToggle(bool show, ref bool ____gameMenuOpen) + private static bool Postfix_ViewManager_UiStateToggle(bool show, ref ViewManager __instance, ref bool ____gameMenuOpen) { - if (MainMenuHelper.Instance == null) return; + if (MainMenuHelper.Instance == null) return true; if (show != ____gameMenuOpen) { - MainMenuHelper.Instance.UpdateWorldAnchors(); + ____gameMenuOpen = show; + __instance.gameMenuView.enabled = show; + __instance.uiMenuAnimator.SetBool("Open", show); + MainMenuHelper.Instance.enabled = show; + MainMenuHelper.Instance.UpdateWorldAnchors(show); + //shouldnt run if switching menus on desktop + if (!MetaPort.Instance.isUsingVr) + { + if (!show && QuickMenuHelper.Instance.enabled) + { + return false; + } + CVR_MenuManager.Instance.ToggleQuickMenu(false); + } MSP_MenuInfo.ToggleDesktopInputMethod(show); + CVRPlayerManager.Instance.ReloadAllNameplates(); } - MainMenuHelper.Instance.enabled = show; + return false; } //add independent head movement to important input @@ -117,6 +184,57 @@ internal class HarmonyPatches [HarmonyPatch(typeof(PlayerSetup), "CalibrateAvatar")] private static void Postfix_PlayerSetup_CalibrateAvatar() { - MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform; + try + { + MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform; + } + catch (System.Exception e) + { + MenuScalePatch.Logger.Error(e); + } + } + + //[HarmonyTranspiler] + //[HarmonyPatch(typeof(ControllerRay), "LateUpdate")] + private static IEnumerable Transpiler_ControllerRay_UpdateInput( + IEnumerable instructions, ILGenerator il) + { + + // Stop calling move mouse events on the menus, the ones that instantiate and the send the event (easy) + // Makes this: "component.View.MouseEvent(mouseEventData1);" go POOF + instructions = new CodeMatcher(instructions) + .MatchForward(false, + new CodeMatch(OpCodes.Ldloc_S), + new CodeMatch(i => i.opcode == OpCodes.Callvirt && i.operand is MethodInfo { Name: "get_View" }), + new CodeMatch(OpCodes.Ldloc_S), + new CodeMatch(i => i.opcode == OpCodes.Callvirt && i.operand is MethodInfo { Name: "MouseEvent" })) + .Repeat(matcher => matcher + .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Nop)) + .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Nop)) + .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Nop)) + .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Nop)) + ) + .InstructionEnumeration(); + + // Look for the if flag2 and replace flag 2 with false, for the ones that create the event and send inline (hard ;_;) + // Makes this: "if (flag2 && this._mouseDownOnMenu != ControllerRay.Menu.None || ..." into: + // this: "if (false && this._mouseDownOnMenu != ControllerRay.Menu.None || ..." + instructions = new CodeMatcher(instructions) + .MatchForward(false, + new CodeMatch(OpCodes.Ldloc_2), + new CodeMatch(OpCodes.Brfalse), + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(i => + i.opcode == OpCodes.Ldfld && i.operand is FieldInfo { Name: "_mouseDownOnMenu" }), + new CodeMatch(OpCodes.Brtrue), + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(i => + i.opcode == OpCodes.Ldfld && i.operand is FieldInfo { Name: "_mouseDownOnMenu" }), + new CodeMatch(OpCodes.Ldc_I4_1), + new CodeMatch(OpCodes.Bne_Un)) + .SetOpcodeAndAdvance(OpCodes.Ldc_I4_0) // replace flag2 with false + .InstructionEnumeration(); + + return instructions; } } \ No newline at end of file diff --git a/MenuScalePatch/Helpers/MainMenuHelper.cs b/MenuScalePatch/Helpers/MainMenuHelper.cs index 2df6d1b..6930cf6 100644 --- a/MenuScalePatch/Helpers/MainMenuHelper.cs +++ b/MenuScalePatch/Helpers/MainMenuHelper.cs @@ -2,6 +2,7 @@ using ABI_RC.Core.Savior; using UnityEngine; + namespace NAK.Melons.MenuScalePatch.Helpers; //TODO: Implement desktop ratio scaling back to MM @@ -14,22 +15,25 @@ namespace NAK.Melons.MenuScalePatch.Helpers; **/ -[DefaultExecutionOrder(999999)] +[DefaultExecutionOrder(20000)] public class MainMenuHelper : MonoBehaviour { public static MainMenuHelper Instance; public Transform worldAnchor; + public bool NeedsPositionUpdate; - void Start() + void Awake() { Instance = this; - CreateWorldAnchors(); } void LateUpdate() { - MSP_MenuInfo.HandleIndependentLookInput(); - UpdateMenuPosition(); + if (MSP_MenuInfo.UseIndependentHeadTurn) + MSP_MenuInfo.HandleIndependentLookInput(); + if (MSP_MenuInfo.PlayerAnchorMenus) + UpdateMenuPosition(); + if (NeedsPositionUpdate) UpdateMenuPosition(); } public void CreateWorldAnchors() @@ -41,7 +45,7 @@ public class MainMenuHelper : MonoBehaviour worldAnchor = vrAnchor.transform; } - public void UpdateWorldAnchors() + public void UpdateWorldAnchors(bool updateMenuPos = false) { if (worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; @@ -64,10 +68,12 @@ public class MainMenuHelper : MonoBehaviour worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; worldAnchor.position = MSP_MenuInfo.CameraTransform.position; } + if (updateMenuPos) UpdateMenuPosition(); } public void UpdateMenuPosition() { + NeedsPositionUpdate = false; if (MetaPort.Instance.isUsingVr) { HandleVRPosition(); @@ -94,4 +100,4 @@ public class MainMenuHelper : MonoBehaviour transform.position = worldAnchor.position; transform.eulerAngles = worldAnchor.eulerAngles; } -} \ No newline at end of file +} diff --git a/MenuScalePatch/Helpers/QuickMenuHelper.cs b/MenuScalePatch/Helpers/QuickMenuHelper.cs index 834251f..1c713b9 100644 --- a/MenuScalePatch/Helpers/QuickMenuHelper.cs +++ b/MenuScalePatch/Helpers/QuickMenuHelper.cs @@ -12,23 +12,26 @@ namespace NAK.Melons.MenuScalePatch.Helpers; **/ -[DefaultExecutionOrder(999999)] +[DefaultExecutionOrder(20000)] public class QuickMenuHelper : MonoBehaviour { public static QuickMenuHelper Instance; public Transform worldAnchor; public Transform handAnchor; + public bool NeedsPositionUpdate; - void Start() + void Awake() { Instance = this; - CreateWorldAnchors(); } void LateUpdate() { - MSP_MenuInfo.HandleIndependentLookInput(); - UpdateMenuPosition(); + if (MSP_MenuInfo.UseIndependentHeadTurn) + MSP_MenuInfo.HandleIndependentLookInput(); + if (MSP_MenuInfo.PlayerAnchorMenus || MetaPort.Instance.isUsingVr) + UpdateMenuPosition(); + if (NeedsPositionUpdate) UpdateMenuPosition(); } public void CreateWorldAnchors() @@ -40,15 +43,17 @@ public class QuickMenuHelper : MonoBehaviour worldAnchor = vrAnchor.transform; } - public void UpdateWorldAnchors() + public void UpdateWorldAnchors(bool updateMenuPos = false) { if (worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return; worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; worldAnchor.position = MSP_MenuInfo.CameraTransform.position; + if (updateMenuPos) UpdateMenuPosition(); } public void UpdateMenuPosition() { + NeedsPositionUpdate = false; if (MetaPort.Instance.isUsingVr) { HandleVRPosition(); diff --git a/MenuScalePatch/MSP_Menus.cs b/MenuScalePatch/MSP_Menus.cs index 290781c..facd5e0 100644 --- a/MenuScalePatch/MSP_Menus.cs +++ b/MenuScalePatch/MSP_Menus.cs @@ -12,33 +12,38 @@ namespace NAK.Melons.MenuScalePatch.Helpers; public class MSP_MenuInfo { //Shared Info - public static float ScaleFactor = 1f; - public static float AspectRatio = 1f; - public static Transform CameraTransform; + internal static float ScaleFactor = 1f; + internal static float AspectRatio = 1f; + internal static Transform CameraTransform; //Settings...? - public static bool WorldAnchorQM; + internal static bool WorldAnchorQM = false; + internal static bool UseIndependentHeadTurn = true; + internal static bool PlayerAnchorMenus = true; //if other mods need to disable? - public static bool DisableQMHelper; - public static bool DisableQMHelper_VR; - public static bool DisableMMHelper; - public static bool DisableMMHelper_VR; + internal static bool DisableQMHelper; + internal static bool DisableQMHelper_VR; + internal static bool DisableMMHelper; + internal static bool DisableMMHelper_VR; - public static void ToggleDesktopInputMethod(bool flag) + //reflection (traverse sucks ass) + private static readonly FieldInfo _desktopMouseMode = typeof(CVR_MenuManager).GetField("_desktopMouseMode", BindingFlags.NonPublic | BindingFlags.Instance); + + internal static void ToggleDesktopInputMethod(bool flag) { if (MetaPort.Instance.isUsingVr) return; PlayerSetup.Instance._movementSystem.disableCameraControl = flag; CVRInputManager.Instance.inputEnabled = !flag; RootLogic.Instance.ToggleMouse(flag); CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag; - Traverse.Create(CVR_MenuManager.Instance).Field("_desktopMouseMode").SetValue(flag); + _desktopMouseMode.SetValue(CVR_MenuManager.Instance, flag); } - static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); - public static bool independentHeadTurn = false; + internal static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); + internal static bool independentHeadTurn = false; - public static void HandleIndependentLookInput() + internal static void HandleIndependentLookInput() { //angle of independent look axis bool isPressed = CVRInputManager.Instance.independentHeadTurn || CVRInputManager.Instance.independentHeadToggle; diff --git a/MenuScalePatch/Main.cs b/MenuScalePatch/Main.cs index 72a78d2..72eae7d 100644 --- a/MenuScalePatch/Main.cs +++ b/MenuScalePatch/Main.cs @@ -5,22 +5,31 @@ namespace NAK.Melons.MenuScalePatch; public class MenuScalePatch : MelonMod { - private static MelonPreferences_Category m_categoryMenuScalePatch; - private static MelonPreferences_Entry m_entryWorldAnchorVRQM; + internal static MelonLogger.Instance Logger; + internal static MelonPreferences_Category m_categoryMenuScalePatch; + internal static MelonPreferences_Entry + m_entryWorldAnchorVRQM, + m_entryUseIndependentHeadTurn, + m_entryPlayerAnchorMenus; public override void OnInitializeMelon() { m_categoryMenuScalePatch = MelonPreferences.CreateCategory(nameof(MenuScalePatch)); - m_entryWorldAnchorVRQM = m_categoryMenuScalePatch.CreateEntry("World Anchor VR QM", false, description: "Should place QM in World Space while VR."); - + //m_entryWorldAnchorVRQM = m_categoryMenuScalePatch.CreateEntry("World Anchor VR QM", false, description: "Should place QM in World Space while VR."); + m_entryUseIndependentHeadTurn = m_categoryMenuScalePatch.CreateEntry("Use Independent Head Turn", true, description: "Should you be able to use independent head turn in a menu while in Desktop?"); + m_entryPlayerAnchorMenus = m_categoryMenuScalePatch.CreateEntry("Player Anchor Menus", true, description: "Should the menus be anchored to & constantly follow the player?"); + foreach (var setting in m_categoryMenuScalePatch.Entries) { setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); } - } - private void UpdateAllSettings() - { - MSP_MenuInfo.WorldAnchorQM = m_entryWorldAnchorVRQM.Value; + Logger = LoggerInstance; } - private void OnUpdateSettings(object arg1, object arg2) => UpdateAllSettings(); + internal static void UpdateAllSettings() + { + //MSP_MenuInfo.WorldAnchorQM = m_entryWorldAnchorVRQM.Value; + MSP_MenuInfo.UseIndependentHeadTurn = m_entryUseIndependentHeadTurn.Value; + MSP_MenuInfo.PlayerAnchorMenus = m_entryPlayerAnchorMenus.Value; + } + private static void OnUpdateSettings(object arg1, object arg2) => UpdateAllSettings(); } \ No newline at end of file diff --git a/MenuScalePatch/MenuScalePatch.csproj b/MenuScalePatch/MenuScalePatch.csproj index 655b3bd..7293ed3 100644 --- a/MenuScalePatch/MenuScalePatch.csproj +++ b/MenuScalePatch/MenuScalePatch.csproj @@ -21,6 +21,9 @@ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll + + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll diff --git a/MenuScalePatch/Properties/AssemblyInfo.cs b/MenuScalePatch/Properties/AssemblyInfo.cs index 64804cf..34cef9b 100644 --- a/MenuScalePatch/Properties/AssemblyInfo.cs +++ b/MenuScalePatch/Properties/AssemblyInfo.cs @@ -25,6 +25,6 @@ using System.Reflection; namespace MenuScalePatch.Properties; internal static class AssemblyInfoParams { - public const string Version = "4.1.1"; + public const string Version = "4.0.0"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/MenuScalePatch/format.json b/MenuScalePatch/format.json index 02f7943..d91654b 100644 --- a/MenuScalePatch/format.json +++ b/MenuScalePatch/format.json @@ -1,12 +1,12 @@ { "_id": 95, "name": "MenuScalePatch", - "modversion": "3.0.0", + "modversion": "4.0.0", "gameversion": "2022r170", "loaderversion": "0.5.7", "modtype": "Mod", "author": "NotAKidoS", - "description": "Corrects MM and QM position when avatar is being scaled.\n\nDesktop menus will now always follow camera while open.", + "description": "Corrects MM and QM position when avatar is being scaled.\n\nOptional setting to enable Independent Head Turn while in menus.\nOptional setting to force menus to always follow player.", "searchtags": [ "menu", "scale", @@ -16,8 +16,8 @@ "requirements": [ "None" ], - "downloadlink": "https://github.com/NotAKidOnSteam/MenuScalePatch/releases/download/v3.0.0/MenuScalePatch.dll", + "downloadlink": "https://github.com/NotAKidOnSteam/MenuScalePatch/releases/download/v4.0.0/MenuScalePatch.dll", "sourcelink": "https://github.com/NotAKidOnSteam/MenuScalePatch/", - "changelog": "Removed collision scaling feature as it is now native.\nAdjusted QM scaling for VR.\nAdded menu correction for Desktop so you can use menus while moving.\nImmediate viewpoint correction for Desktop during scaling.", + "changelog": "- Added option for menus to be attached to you in Desktop and VR.\n- Added option to use independent head movement while in a menu.", "embedcolor": "804221" } \ No newline at end of file