From 553da7edb3f46c11ec6e3410598035e2c61b4e5d Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Sun, 24 Sep 2023 06:14:55 -0500 Subject: [PATCH] [EzGrab] Fixes for 2023r172. Add Curve & Tuned Curve options. --- EzCurls/InputModuleCurlAdjuster.cs | 47 +++++++++++++++++++++--- EzCurls/Main.cs | 41 ++++++++++++++++++--- EzGrab/EzGrab.csproj | 2 ++ EzGrab/Main.cs | 58 ++++++++++++++++++++++++++++++ EzGrab/Properties/AssemblyInfo.cs | 29 +++++++++++++++ EzGrab/format.json | 23 ++++++++++++ 6 files changed, 191 insertions(+), 9 deletions(-) create mode 100644 EzGrab/EzGrab.csproj create mode 100644 EzGrab/Main.cs create mode 100644 EzGrab/Properties/AssemblyInfo.cs create mode 100644 EzGrab/format.json diff --git a/EzCurls/InputModuleCurlAdjuster.cs b/EzCurls/InputModuleCurlAdjuster.cs index 3f26da3..d3d2842 100644 --- a/EzCurls/InputModuleCurlAdjuster.cs +++ b/EzCurls/InputModuleCurlAdjuster.cs @@ -1,5 +1,5 @@ -using ABI_RC.Core.Savior; -using ABI_RC.Systems.IK.SubSystems; +using ABI_RC.Systems.InputManagement; +using UnityEngine; namespace NAK.EzCurls; @@ -20,15 +20,27 @@ internal class InputModuleCurlAdjuster : CVRInputModule public float CurlSimilarityThreshold = 0.5f; public float CurlSmoothingFactor = 0.4f; - public new void Start() + // Curve control + public bool UseCurveControl = false; + public AnimationCurve DensityCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0)); + + // Tuned Curve control + public bool UseTunedCurveControl = false; + private readonly AnimationCurve TunedDensityCurve = new AnimationCurve( + new Keyframe(0, 0), // Start at (0, 0) + new Keyframe(0.5f, 0.5f), // Normal behavior up to (0.3, 0.3) + new Keyframe(0.85f, 0.6f), // Only 0.1f movement from 0.5 to 0.9 + new Keyframe(1, 1) // Normal behavior from 0.9 to 1 + ); + + public override void ModuleAdded() { Instance = this; - base.Start(); + base.ModuleAdded(); EzCurls.OnSettingsChanged(); } public override void UpdateInput() => DoCurlAdjustments(); - public override void UpdateImportantInput() => DoCurlAdjustments(); private void DoCurlAdjustments() { @@ -83,6 +95,20 @@ internal class InputModuleCurlAdjuster : CVRInputModule SnapCurls(ref _inputManager.fingerCurlRightRing); SnapCurls(ref _inputManager.fingerCurlRightPinky); } + + + if (UseCurveControl) + { + AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftIndex); + AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftMiddle); + AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftRing); + AdjustCurlUsingCurve(ref _inputManager.fingerCurlLeftPinky); + + AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightIndex); + AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightMiddle); + AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightRing); + AdjustCurlUsingCurve(ref _inputManager.fingerCurlRightPinky); + } } private void SnapCurls(ref float fingerCurl) @@ -158,4 +184,15 @@ internal class InputModuleCurlAdjuster : CVRInputModule float dist = curlValue - 0.5f; return 1.0f - 4 * dist * dist; } + + // middle of curve is more "dense" + private void AdjustCurlUsingCurve(ref float fingerCurl) + { + if (UseTunedCurveControl) + { + fingerCurl = TunedDensityCurve.Evaluate(fingerCurl); + return; + } + fingerCurl = DensityCurve.Evaluate(fingerCurl); + } } \ No newline at end of file diff --git a/EzCurls/Main.cs b/EzCurls/Main.cs index 103c952..7d050ce 100644 --- a/EzCurls/Main.cs +++ b/EzCurls/Main.cs @@ -1,6 +1,9 @@ using ABI_RC.Core.Savior; using MelonLoader; using System.Reflection; +using ABI_RC.Systems.InputManagement; +using ABI_RC.Systems.InputManagement.InputModules; +using UnityEngine; namespace NAK.EzCurls; @@ -47,12 +50,33 @@ public class EzCurls : MelonMod public static readonly MelonPreferences_Entry EntryCurlSmoothingFactor = Category.CreateEntry("CurlSmoothingFactor", 0.5f, description: "The multiplier for curl smoothing."); + + // Curve control settings + public static readonly MelonPreferences_Entry EntryUseCurveControl = + Category.CreateEntry("UseCurveControl", false, + description: "Enable curve control mode to make the midrange of the curl more dense."); + + public static readonly MelonPreferences_Entry EntryUseTunedCurveControl = + Category.CreateEntry("UseTunedCurveControl", false, + description: "Enables a pre-tuned curve."); + + public static readonly MelonPreferences_Entry EntryCurveMin = + Category.CreateEntry("CurveMin", 0.0f, + description: "The minimum value of the density curve."); + + public static readonly MelonPreferences_Entry EntryCurveMiddle = + Category.CreateEntry("CurveMiddle", 0.5f, + description: "The middle value of the density curve."); + + public static readonly MelonPreferences_Entry EntryCurveMax = + Category.CreateEntry("CurveMax", 1.0f, + description: "The maximum value of the density curve."); public override void OnInitializeMelon() { HarmonyInstance.Patch( - typeof(InputModuleSteamVR).GetMethod(nameof(InputModuleSteamVR.Start)), - prefix: new HarmonyLib.HarmonyMethod(typeof(EzCurls).GetMethod(nameof(OnInputModuleSteamVRStart_Prefix), BindingFlags.NonPublic | BindingFlags.Static)) + typeof(CVRInputModule_XR).GetMethod(nameof(CVRInputModule_XR.ModuleAdded)), + postfix: new HarmonyLib.HarmonyMethod(typeof(EzCurls).GetMethod(nameof(OnCVRInputModule_XRModuleAdded_Postfix), BindingFlags.NonPublic | BindingFlags.Static)) ); foreach (MelonPreferences_Entry setting in Category.Entries) @@ -76,10 +100,19 @@ public class EzCurls : MelonMod InputModuleCurlAdjuster.Instance.DontSmoothExtremes = EntryDontSmoothExtremes.Value; InputModuleCurlAdjuster.Instance.CurlSimilarityThreshold = EntryCurlSimilarityThreshold.Value; InputModuleCurlAdjuster.Instance.CurlSmoothingFactor = EntryCurlSmoothingFactor.Value; + + // curve control + InputModuleCurlAdjuster.Instance.UseCurveControl = EntryUseCurveControl.Value; + InputModuleCurlAdjuster.Instance.UseTunedCurveControl = EntryUseTunedCurveControl.Value; + InputModuleCurlAdjuster.Instance.DensityCurve = new AnimationCurve( + new Keyframe(0, EntryCurveMin.Value), + new Keyframe(0.5f, EntryCurveMiddle.Value), + new Keyframe(1, EntryCurveMax.Value) + ); } - private static void OnInputModuleSteamVRStart_Prefix(ref InputModuleSteamVR __instance) + private static void OnCVRInputModule_XRModuleAdded_Postfix() { - __instance.gameObject.AddComponent(); + CVRInputManager.Instance.AddInputModule(new InputModuleCurlAdjuster()); } } \ No newline at end of file diff --git a/EzGrab/EzGrab.csproj b/EzGrab/EzGrab.csproj new file mode 100644 index 0000000..66a50a8 --- /dev/null +++ b/EzGrab/EzGrab.csproj @@ -0,0 +1,2 @@ + + diff --git a/EzGrab/Main.cs b/EzGrab/Main.cs new file mode 100644 index 0000000..4b25c23 --- /dev/null +++ b/EzGrab/Main.cs @@ -0,0 +1,58 @@ +using MelonLoader; +using System.Reflection; +using ABI_RC.Systems.InputManagement.InputModules; +using ABI_RC.Systems.InputManagement.XR; + +namespace NAK.EzGrab; + +public class EzGrab : MelonMod +{ + private const string SettingsCategory = nameof(EzGrab); + + private static readonly MelonPreferences_Category Category = + MelonPreferences.CreateCategory(SettingsCategory); + + private static readonly MelonPreferences_Entry EntryEnabled = + Category.CreateEntry("Enabled", true, + description: "Should EzGrab be enabled?"); + + private static readonly MelonPreferences_Entry EntryReleaseWeight = + Category.CreateEntry("Release Weight", 0.1f, + description: "The release weight for grip up to fire."); + + public override void OnInitializeMelon() + { + HarmonyInstance.Patch( + typeof(CVRInputModule_XR).GetMethod(nameof(CVRInputModule_XR.Update_Grip)), + prefix: new HarmonyLib.HarmonyMethod(typeof(EzGrab).GetMethod(nameof(OnCVRInputModule_XR_Prefix), BindingFlags.NonPublic)) + ); + } + + private static void OnCVRInputModule_XR_Prefix(CVRXRModule module, ref CVRInputModule_XR __instance) + { + if (module.Type != EXRControllerType.Index || !EntryEnabled.Value) return; + + float gripValue = module.Grip; + float gripThreshold = __instance._indexGripThreshold; + float releaseThreshold = EntryReleaseWeight.Value; + + if (module.IsLeftHand) + { + float lastGripLeft = __instance._lastGripLeft; + if ((gripValue < gripThreshold && lastGripLeft >= gripThreshold) && + !(gripValue < releaseThreshold && lastGripLeft >= releaseThreshold)) + { + __instance._lastGripLeft = 0f; + } + } + else + { + float lastGripRight = __instance._lastGripRight; + if ((gripValue < gripThreshold && lastGripRight >= gripThreshold) && + !(gripValue < releaseThreshold && lastGripRight >= releaseThreshold)) + { + __instance._lastGripRight = 0f; + } + } + } +} \ No newline at end of file diff --git a/EzGrab/Properties/AssemblyInfo.cs b/EzGrab/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..648994a --- /dev/null +++ b/EzGrab/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using MelonLoader; +using NAK.EzGrab.Properties; +using System.Reflection; + +[assembly: AssemblyVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyTitle(nameof(NAK.EzGrab))] +[assembly: AssemblyCompany(AssemblyInfoParams.Author)] +[assembly: AssemblyProduct(nameof(NAK.EzGrab))] + +[assembly: MelonInfo( + typeof(NAK.EzGrab.EzGrab), + nameof(NAK.EzGrab), + AssemblyInfoParams.Version, + AssemblyInfoParams.Author, + downloadLink: "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/EzGrab" +)] + +[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] +[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] +[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] + +namespace NAK.EzGrab.Properties; +internal static class AssemblyInfoParams +{ + public const string Version = "1.0.0"; + public const string Author = "NotAKidoS"; +} \ No newline at end of file diff --git a/EzGrab/format.json b/EzGrab/format.json new file mode 100644 index 0000000..15f3f72 --- /dev/null +++ b/EzGrab/format.json @@ -0,0 +1,23 @@ +{ + "_id": -1, + "name": "EzCurls", + "modversion": "1.0.0", + "gameversion": "2022r170p1", + "loaderversion": "0.6.1", + "modtype": "Mod", + "author": "NotAKidoS", + "description": "A mod that should hopefully make finger curls more predictable.", + "searchtags": [ + "aas", + "sync", + "naked", + "buffer" + ], + "requirements": [ + "UIExpansionKit" + ], + "downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r13/EzCurls.dll", + "sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/EzCurls/", + "changelog": "- Initial CVRMG release", + "embedcolor": "7d7d7d" +} \ No newline at end of file