diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs new file mode 100644 index 0000000..999c87d --- /dev/null +++ b/MenuScalePatch/HarmonyPatches.cs @@ -0,0 +1,240 @@ +using ABI_RC.Core.InteractionSystem; +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; + +/** + 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 +{ + //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 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; + if (!MSP_MenuInfo.PlayerAnchorMenus) + { + QuickMenuHelper.Instance.NeedsPositionUpdate = true; + MainMenuHelper.Instance.NeedsPositionUpdate = true; + } + return false; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(ViewManager), "SetScale")] + private static bool Prefix_ViewManager_SetScale() + { + 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 bool Prefix_CVR_MenuManager_UpdateMenuPosition() + { + return false; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(ViewManager), "UpdateMenuPosition")] + 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; + return false; + } + + //Set QM stuff + [HarmonyPostfix] + [HarmonyPatch(typeof(CVR_MenuManager), "Start")] + private static void Postfix_CVR_MenuManager_Start(ref CVR_MenuManager __instance, ref GameObject ____leftVrAnchor) + { + 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 + [HarmonyPostfix] + [HarmonyPatch(typeof(ViewManager), "Start")] + private static void Postfix_ViewManager_Start(ref ViewManager __instance) + { + 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 bool Prefix_CVR_MenuManager_ToggleQuickMenu(bool show, ref CVR_MenuManager __instance, ref bool ____quickMenuOpen) + { + if (QuickMenuHelper.Instance == null) return true; + if (show != ____quickMenuOpen) + { + ____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(); + } + return false; + } + + //hook menu open/close + [HarmonyPrefix] + [HarmonyPatch(typeof(ViewManager), "UiStateToggle", new Type[] { typeof(bool) })] + private static bool Postfix_ViewManager_UiStateToggle(bool show, ref ViewManager __instance, ref bool ____gameMenuOpen) + { + if (MainMenuHelper.Instance == null) return true; + if (show != ____gameMenuOpen) + { + ____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(); + } + return false; + } + + //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 Postfix_PlayerSetup_CalibrateAvatar() + { + 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 new file mode 100644 index 0000000..6930cf6 --- /dev/null +++ b/MenuScalePatch/Helpers/MainMenuHelper.cs @@ -0,0 +1,103 @@ +using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; +using UnityEngine; + + +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(20000)] +public class MainMenuHelper : MonoBehaviour +{ + public static MainMenuHelper Instance; + public Transform worldAnchor; + public bool NeedsPositionUpdate; + + void Awake() + { + Instance = this; + } + + void LateUpdate() + { + if (MSP_MenuInfo.UseIndependentHeadTurn) + MSP_MenuInfo.HandleIndependentLookInput(); + if (MSP_MenuInfo.PlayerAnchorMenus) + UpdateMenuPosition(); + if (NeedsPositionUpdate) UpdateMenuPosition(); + } + + 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; + worldAnchor = vrAnchor.transform; + } + + public void UpdateWorldAnchors(bool updateMenuPos = false) + { + if (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) + { + worldAnchor.rotation = Quaternion.LookRotation(MSP_MenuInfo.CameraTransform.forward, Vector3.up); + } + else + { + worldAnchor.eulerAngles = MSP_MenuInfo.CameraTransform.eulerAngles; + } + worldAnchor.position = MSP_MenuInfo.CameraTransform.position + MSP_MenuInfo.CameraTransform.forward * 2f * MSP_MenuInfo.ScaleFactor; + } + else + { + 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(); + return; + } + HandleDesktopPosition(); + } + + //Desktop Main Menu + public void HandleDesktopPosition() + { + if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableMMHelper) return; + 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; + } + + //VR Main Menu + public void HandleVRPosition() + { + 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; + } +} diff --git a/MenuScalePatch/Helpers/QuickMenuHelper.cs b/MenuScalePatch/Helpers/QuickMenuHelper.cs new file mode 100644 index 0000000..1c713b9 --- /dev/null +++ b/MenuScalePatch/Helpers/QuickMenuHelper.cs @@ -0,0 +1,92 @@ +using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; +using UnityEngine; + +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(20000)] +public class QuickMenuHelper : MonoBehaviour +{ + public static QuickMenuHelper Instance; + public Transform worldAnchor; + public Transform handAnchor; + public bool NeedsPositionUpdate; + + void Awake() + { + Instance = this; + } + + void LateUpdate() + { + if (MSP_MenuInfo.UseIndependentHeadTurn) + MSP_MenuInfo.HandleIndependentLookInput(); + if (MSP_MenuInfo.PlayerAnchorMenus || MetaPort.Instance.isUsingVr) + UpdateMenuPosition(); + if (NeedsPositionUpdate) UpdateMenuPosition(); + } + + 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; + worldAnchor = vrAnchor.transform; + } + + 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(); + return; + } + HandleDesktopPosition(); + } + + //Desktop Quick Menu + public void HandleDesktopPosition() + { + if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableQMHelper) return; + + 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; + } + + //VR Quick Menu + public void HandleVRPosition() + { + if (handAnchor == null || MSP_MenuInfo.DisableQMHelper_VR) return; + + if (MSP_MenuInfo.WorldAnchorQM) + { + 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; + } + 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/MSP_Menus.cs b/MenuScalePatch/MSP_Menus.cs new file mode 100644 index 0000000..facd5e0 --- /dev/null +++ b/MenuScalePatch/MSP_Menus.cs @@ -0,0 +1,67 @@ +using ABI_RC.Core; +using ABI_RC.Core.InteractionSystem; +using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; +using ABI_RC.Systems.MovementSystem; +using HarmonyLib; +using System.Reflection; +using UnityEngine; + +namespace NAK.Melons.MenuScalePatch.Helpers; + +public class MSP_MenuInfo +{ + //Shared Info + internal static float ScaleFactor = 1f; + internal static float AspectRatio = 1f; + internal static Transform CameraTransform; + + //Settings...? + internal static bool WorldAnchorQM = false; + internal static bool UseIndependentHeadTurn = true; + internal static bool PlayerAnchorMenus = true; + + //if other mods need to disable? + internal static bool DisableQMHelper; + internal static bool DisableQMHelper_VR; + internal static bool DisableMMHelper; + internal static bool DisableMMHelper_VR; + + //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; + _desktopMouseMode.SetValue(CVR_MenuManager.Instance, flag); + } + + internal static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); + internal static bool independentHeadTurn = false; + + internal static void HandleIndependentLookInput() + { + //angle of independent look axis + bool isPressed = CVRInputManager.Instance.independentHeadTurn || CVRInputManager.Instance.independentHeadToggle; + if (isPressed && !independentHeadTurn) + { + independentHeadTurn = true; + MSP_MenuInfo.ToggleDesktopInputMethod(false); + QuickMenuHelper.Instance.UpdateWorldAnchors(); + MainMenuHelper.Instance.UpdateWorldAnchors(); + } + else if (!isPressed && independentHeadTurn) + { + 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 e8da0bd..72eae7d 100644 --- a/MenuScalePatch/Main.cs +++ b/MenuScalePatch/Main.cs @@ -1,104 +1,35 @@ -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 MenuScalePatch; +namespace NAK.Melons.MenuScalePatch; public class MenuScalePatch : MelonMod { - [HarmonyPatch] - private class HarmonyPatches + 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() { - 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."); + 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) { - Transform rotationPivot = PlayerSetup.Instance._movementSystem.rotationPivot; - if (!MetaPort.Instance.isUsingVr) - { - menuTransform.eulerAngles = rotationPivot.eulerAngles; - } - menuTransform.position = rotationPivot.position + rotationPivot.forward * 1f * scale; - adjustedMenuPosition = true; + setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); } - [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; - } + Logger = LoggerInstance; } + 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 bb32f6d..7293ed3 100644 --- a/MenuScalePatch/MenuScalePatch.csproj +++ b/MenuScalePatch/MenuScalePatch.csproj @@ -18,14 +18,11 @@ ..\..\..\..\..\..\..\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 + + ..\..\..\..\..\..\..\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 @@ -33,9 +30,6 @@ 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 - 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/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 diff --git a/README.md b/README.md index b28519e..4a8dc6c 100644 --- a/README.md +++ b/README.md @@ -1,10 +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. -also forces menu positions to be constantly updated while open on desktop +## 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) +* 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