diff --git a/LICENSE b/LICENSE index 4480281..c3f4fee 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,10 @@ MIT License +<<<<<<< HEAD Copyright (c) 2023 NotAKidoS +======= +Copyright (c) 2022 NotAKidoS +>>>>>>> MenuScalePatch/main Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/MenuScalePatch/HarmonyPatches.cs b/MenuScalePatch/HarmonyPatches.cs new file mode 100644 index 0000000..445a258 --- /dev/null +++ b/MenuScalePatch/HarmonyPatches.cs @@ -0,0 +1,190 @@ +using ABI_RC.Core; +using ABI_RC.Core.InteractionSystem; +using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; +using HarmonyLib; +using NAK.Melons.MenuScalePatch.Helpers; +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 +**/ + +[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() + { + if (QuickMenuHelper.Instance == null) return true; + return !QuickMenuHelper.Instance.MenuIsOpen; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(ViewManager), "UpdateMenuPosition")] + private static bool Prefix_ViewManager_UpdateMenuPosition(ref float ___cachedScreenAspectRatio) + { + if (MainMenuHelper.Instance == null) return true; + //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 !MainMenuHelper.Instance.MenuIsOpen; + } + + //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; + } + 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 + { + __instance.gameObject.AddComponent(); + } + 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 = true; + __instance.quickMenuAnimator.SetBool("Open", show); + QuickMenuHelper.Instance.MenuIsOpen = show; + QuickMenuHelper.Instance.UpdateWorldAnchors(show); + //shouldnt run if switching menus on desktop + if (!MetaPort.Instance.isUsingVr) + { + if (!show && MainMenuHelper.Instance.MenuIsOpen) + { + 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 Prefix_ViewManager_UiStateToggle(bool show, ref ViewManager __instance, ref bool ____gameMenuOpen) + { + if (MainMenuHelper.Instance == null) return true; + if (show != ____gameMenuOpen) + { + ____gameMenuOpen = show; + __instance.gameMenuView.enabled = true; + __instance.uiMenuAnimator.SetBool("Open", show); + MainMenuHelper.Instance.MenuIsOpen = show; + MainMenuHelper.Instance.UpdateWorldAnchors(show); + //shouldnt run if switching menus on desktop + if (!MetaPort.Instance.isUsingVr) + { + if (!show && QuickMenuHelper.Instance.MenuIsOpen) + { + 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(CVRTools), "ConfigureHudAffinity")] + private static void Postfix_CVRTools_ConfigureHudAffinity() + { + try + { + MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform; + } + catch (System.Exception e) + { + MenuScalePatch.Logger.Error(e); + } + } +} \ No newline at end of file diff --git a/MenuScalePatch/Helpers/MainMenuHelper.cs b/MenuScalePatch/Helpers/MainMenuHelper.cs new file mode 100644 index 0000000..b41ff44 --- /dev/null +++ b/MenuScalePatch/Helpers/MainMenuHelper.cs @@ -0,0 +1,112 @@ +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; + public bool MenuIsOpen; + + void Awake() + { + Instance = this; + } + + void LateUpdate() + { + if (!MenuIsOpen) return; + + if (MSP_MenuInfo.PlayerAnchorMenus || NeedsPositionUpdate) + { + UpdateMenuPosition(); + } + + if (MSP_MenuInfo.UseIndependentHeadTurn) + { + MSP_MenuInfo.HandleIndependentHeadTurnInput(); + } + } + + 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.rotation = MSP_MenuInfo.CameraTransform.rotation; + } + worldAnchor.position = MSP_MenuInfo.CameraTransform.position + MSP_MenuInfo.CameraTransform.forward * 2f * MSP_MenuInfo.ScaleFactor; + } + else + { + worldAnchor.rotation = MSP_MenuInfo.CameraTransform.rotation; + 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.isIndependentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; + transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor, 0.9f * MSP_MenuInfo.ScaleFactor, 1f); + transform.position = activeAnchor.position + activeAnchor.forward * 1f * MSP_MenuInfo.ScaleFactor * MSP_MenuInfo.AspectRatio; + transform.rotation = activeAnchor.rotation; + } + + //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.rotation = worldAnchor.rotation; + } +} diff --git a/MenuScalePatch/Helpers/QuickMenuHelper.cs b/MenuScalePatch/Helpers/QuickMenuHelper.cs new file mode 100644 index 0000000..c5c2aae --- /dev/null +++ b/MenuScalePatch/Helpers/QuickMenuHelper.cs @@ -0,0 +1,100 @@ +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; + public bool MenuIsOpen; + + void Awake() + { + Instance = this; + } + + void LateUpdate() + { + if (!MenuIsOpen) return; + + if (MSP_MenuInfo.PlayerAnchorMenus || NeedsPositionUpdate || MetaPort.Instance.isUsingVr) + { + UpdateMenuPosition(); + } + + if (MSP_MenuInfo.UseIndependentHeadTurn) + { + MSP_MenuInfo.HandleIndependentHeadTurnInput(); + } + } + + 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.rotation = MSP_MenuInfo.CameraTransform.rotation; + 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.isIndependentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform; + transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f); + transform.rotation = activeAnchor.rotation; + 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.position = worldAnchor.position + worldAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor; + transform.rotation = worldAnchor.rotation; + 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..aae26d2 --- /dev/null +++ b/MenuScalePatch/MSP_Menus.cs @@ -0,0 +1,74 @@ +using ABI_RC.Core; +using ABI_RC.Core.InteractionSystem; +using ABI_RC.Core.Savior; +using ABI_RC.Systems.MovementSystem; +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; + + //Debug/Integration + public static bool DisableQMHelper; + public static bool DisableQMHelper_VR; + public static bool DisableMMHelper; + public static bool DisableMMHelper_VR; + + //reflection + internal static readonly FieldInfo _desktopMouseModeQM = typeof(ViewManager).GetField("_desktopMouseMode", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo _desktopMouseModeMM = typeof(CVR_MenuManager).GetField("_desktopMouseMode", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo ms_followAngleX = typeof(MovementSystem).GetField("_followAngleX", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo ms_followAngleY = typeof(MovementSystem).GetField("_followAngleY", BindingFlags.NonPublic | BindingFlags.Instance); + internal static readonly FieldInfo ms_manualAngleX = typeof(MovementSystem).GetField("_manualAngleX", BindingFlags.NonPublic | BindingFlags.Instance); + + internal static bool isIndependentHeadTurn = false; + + internal static void ToggleDesktopInputMethod(bool flag) + { + if (MetaPort.Instance.isUsingVr) return; + + _desktopMouseModeQM.SetValue(ViewManager.Instance, flag); + _desktopMouseModeMM.SetValue(CVR_MenuManager.Instance, flag); + + RootLogic.Instance.ToggleMouse(flag); + CVRInputManager.Instance.inputEnabled = !flag; + CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag; + } + + internal static void HandleIndependentHeadTurnInput() + { + //angle of independent look axis + bool isPressed = CVRInputManager.Instance.independentHeadTurn || CVRInputManager.Instance.independentHeadToggle; + if (isPressed && !isIndependentHeadTurn) + { + isIndependentHeadTurn = true; + MSP_MenuInfo.ToggleDesktopInputMethod(false); + QuickMenuHelper.Instance.UpdateWorldAnchors(); + MainMenuHelper.Instance.UpdateWorldAnchors(); + } + else if (!isPressed && isIndependentHeadTurn) + { + float angleX = (float)ms_followAngleX.GetValue(MovementSystem.Instance); + float angleY = (float)ms_followAngleY.GetValue(MovementSystem.Instance); + float manualAngleX = (float)ms_manualAngleX.GetValue(MovementSystem.Instance); + if (angleY == 0f && angleX == manualAngleX) + { + isIndependentHeadTurn = false; + MSP_MenuInfo.ToggleDesktopInputMethod(true); + QuickMenuHelper.Instance.NeedsPositionUpdate = true; + MainMenuHelper.Instance.NeedsPositionUpdate = true; + } + } + } +} \ No newline at end of file diff --git a/MenuScalePatch/Main.cs b/MenuScalePatch/Main.cs new file mode 100644 index 0000000..3f8387f --- /dev/null +++ b/MenuScalePatch/Main.cs @@ -0,0 +1,35 @@ +using MelonLoader; +using NAK.Melons.MenuScalePatch.Helpers; + +namespace NAK.Melons.MenuScalePatch; + +public class MenuScalePatch : MelonMod +{ + 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_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); + } + + 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 new file mode 100644 index 0000000..72168e2 --- /dev/null +++ b/MenuScalePatch/MenuScalePatch.csproj @@ -0,0 +1,40 @@ + + + + + net472 + enable + latest + false + + + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\0Harmony.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll + + + C:\Program Files (x86)\\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll + + + C:\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 + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll + + + + + + + + + diff --git a/MenuScalePatch/MenuScalePatch.sln b/MenuScalePatch/MenuScalePatch.sln new file mode 100644 index 0000000..57b61f9 --- /dev/null +++ b/MenuScalePatch/MenuScalePatch.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32630.192 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MenuScalePatch", "MenuScalePatch.csproj", "{19D9CD91-0387-4E35-AFCD-BAB15AEC9765}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {19D9CD91-0387-4E35-AFCD-BAB15AEC9765}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19D9CD91-0387-4E35-AFCD-BAB15AEC9765}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19D9CD91-0387-4E35-AFCD-BAB15AEC9765}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19D9CD91-0387-4E35-AFCD-BAB15AEC9765}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4E0D4C6B-166C-4456-BAD7-6A358308116E} + EndGlobalSection +EndGlobal diff --git a/MenuScalePatch/Properties/AssemblyInfo.cs b/MenuScalePatch/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c74bca0 --- /dev/null +++ b/MenuScalePatch/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using MelonLoader; +using NAK.Melons.MenuScalePatch.Properties; +using System.Reflection; + + +[assembly: AssemblyVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyTitle(nameof(NAK.Melons.MenuScalePatch))] +[assembly: AssemblyCompany(AssemblyInfoParams.Author)] +[assembly: AssemblyProduct(nameof(NAK.Melons.MenuScalePatch))] + +[assembly: MelonInfo( + typeof(NAK.Melons.MenuScalePatch.MenuScalePatch), + nameof(NAK.Melons.MenuScalePatch), + AssemblyInfoParams.Version, + AssemblyInfoParams.Author, + downloadLink: "https://github.com/NotAKidOnSteam/MenuScalePatch" +)] + +[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] +[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] +[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] + +namespace NAK.Melons.MenuScalePatch.Properties; +internal static class AssemblyInfoParams +{ + public const string Version = "4.2.6"; + public const string Author = "NotAKidoS"; +} \ No newline at end of file diff --git a/MenuScalePatch/format.json b/MenuScalePatch/format.json new file mode 100644 index 0000000..717ab3b --- /dev/null +++ b/MenuScalePatch/format.json @@ -0,0 +1,23 @@ +{ + "_id": 95, + "name": "MenuScalePatch", + "modversion": "4.2.6", + "gameversion": "2022r170", + "loaderversion": "0.5.7", + "modtype": "Mod", + "author": "NotAKidoS", + "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", + "avatarscale", + "slider" + ], + "requirements": [ + "None" + ], + "downloadlink": "https://github.com/NotAKidOnSteam/MenuScalePatch/releases/download/v4.2.6/MenuScalePatch.dll", + "sourcelink": "https://github.com/NotAKidOnSteam/MenuScalePatch/", + "changelog": "- Fixed hitching & potential crash when opening menu after a long time of it being closed. Don't disable CohtmlView, only enable it.\n- Let game update menu position while its closed.\n- Tweaked independent head turn handling to ensure menu is correctly positioned on recenter if PlayerAnchorMenus is disabled.\n- Undo change to which transform to parent menu anchors.", + "embedcolor": "363020" +} \ No newline at end of file diff --git a/README.md b/README.md index 6da48af..ac5fe1e 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,25 @@ https://user-images.githubusercontent.com/37721153/231921029-f5bf5236-3dbb-4720- ## Relevant Feedback Posts: https://feedback.abinteractive.net/p/grounded-parameter-does-not-fire-immediatly-after-landing +# MenuScalePatch + +Originally forced menu position to update while scaling. Now changes ChilloutVR menu behavior to feel less clunky. + +## 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 ---