From 83c101f5eeaad4bc81d595fddc751b547f9bf6aa Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Mon, 20 Mar 2023 15:17:36 -0500 Subject: [PATCH] i dont know what im doing implement shit fix for shit problem --- BadAnimatorFix/BadAnimatorFix.cs | 72 +++++++++++++++++++++++ BadAnimatorFix/BadAnimatorFix.csproj | 70 ++++++++++++++++++++++ BadAnimatorFix/BadAnimatorFix.sln | 25 ++++++++ BadAnimatorFix/HarmonyPatches.cs | 63 ++++++++++++++++++++ BadAnimatorFix/Main.cs | 47 +++++++++++++++ BadAnimatorFix/Properties/AssemblyInfo.cs | 30 ++++++++++ BadAnimatorFix/format.json | 23 ++++++++ 7 files changed, 330 insertions(+) create mode 100644 BadAnimatorFix/BadAnimatorFix.cs create mode 100644 BadAnimatorFix/BadAnimatorFix.csproj create mode 100644 BadAnimatorFix/BadAnimatorFix.sln create mode 100644 BadAnimatorFix/HarmonyPatches.cs create mode 100644 BadAnimatorFix/Main.cs create mode 100644 BadAnimatorFix/Properties/AssemblyInfo.cs create mode 100644 BadAnimatorFix/format.json diff --git a/BadAnimatorFix/BadAnimatorFix.cs b/BadAnimatorFix/BadAnimatorFix.cs new file mode 100644 index 0000000..15a4bb2 --- /dev/null +++ b/BadAnimatorFix/BadAnimatorFix.cs @@ -0,0 +1,72 @@ +using UnityEngine; +using UnityEngine.Playables; + +namespace NAK.Melons.BadAnimatorFix; + +public class BadAnimatorFix : MonoBehaviour +{ + private float stateLimit = 20f; + private Animator animator; + private Playable playable; + + private void Start() + { + animator = GetComponent(); + playable = animator.playableGraph.GetRootPlayable(0); + } + + private void Update() + { + if (!BadAnimatorFixMod.EntryEnabled.Value) return; + if (playable.IsValid() && GetTime() > BadAnimatorFixMod.EntryPlayableTimeLimit.Value) + { + RewindAnimator(); + BadAnimatorFixMod.Logger.Msg($"Rewound animator and playable {animator}."); + } + } + + private double GetTime() + { + return PlayableExtensions.IsValid(playable) ? PlayableExtensions.GetTime(playable) : -1; + } + + private void RewindAnimator() + { + PlayableExtensions.SetTime(playable, 0); + for (int i = 0; i < animator.layerCount; i++) + { + AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(i); + AnimatorTransitionInfo transitionInfo = animator.GetAnimatorTransitionInfo(i); + // Skip if mid-transition + if (transitionInfo.fullPathHash != 0) continue; + // Skip if anim doesn't loop, or hasn't looped enough + if (stateInfo.normalizedTime <= stateLimit) continue; + // Rewind state, with 10f as buffer, to account for reasonable use of ExitTime + float offset = 10f + (stateInfo.normalizedTime % 1f); + animator.Play(stateInfo.fullPathHash, i, offset); + } + } + + private float GetNormalizedTime() + { + float time = 0f; + for (int i = 0; i < animator.layerCount; i++) + { + AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(i); + time += stateInfo.normalizedTime; + } + return time; + } + + private float GetMaxNormalizedTime() + { + float time = 0f; + for (int i = 0; i < animator.layerCount; i++) + { + AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(i); + if (time < stateInfo.normalizedTime) + time = stateInfo.normalizedTime; + } + return time; + } +} diff --git a/BadAnimatorFix/BadAnimatorFix.csproj b/BadAnimatorFix/BadAnimatorFix.csproj new file mode 100644 index 0000000..e4c8455 --- /dev/null +++ b/BadAnimatorFix/BadAnimatorFix.csproj @@ -0,0 +1,70 @@ + + + + + netstandard2.1 + 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\Assembly-CSharp-firstpass.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Aura2_Core.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.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\SteamVR.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\UIExpansionKit.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Unity.Postprocessing.Runtime.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Unity.TextMeshPro.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 + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.VRModule.dll + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.XRModule.dll + + + + + + + + + diff --git a/BadAnimatorFix/BadAnimatorFix.sln b/BadAnimatorFix/BadAnimatorFix.sln new file mode 100644 index 0000000..83f9cfb --- /dev/null +++ b/BadAnimatorFix/BadAnimatorFix.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}") = "BadAnimatorFix", "BadAnimatorFix.csproj", "{36FB9A18-B03E-45F6-9EF5-A276D2FFFC2B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36FB9A18-B03E-45F6-9EF5-A276D2FFFC2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {36FB9A18-B03E-45F6-9EF5-A276D2FFFC2B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36FB9A18-B03E-45F6-9EF5-A276D2FFFC2B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {36FB9A18-B03E-45F6-9EF5-A276D2FFFC2B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {61C931D9-0377-4934-BF85-FCEB9A40547E} + EndGlobalSection +EndGlobal diff --git a/BadAnimatorFix/HarmonyPatches.cs b/BadAnimatorFix/HarmonyPatches.cs new file mode 100644 index 0000000..11bac03 --- /dev/null +++ b/BadAnimatorFix/HarmonyPatches.cs @@ -0,0 +1,63 @@ +using ABI.CCK.Components; +using ABI_RC.Core.InteractionSystem; +using HarmonyLib; +using UnityEngine; + +namespace NAK.Melons.BadAnimatorFix.HarmonyPatches; + +internal class AnimatorPatches +{ + [HarmonyPostfix] + [HarmonyPatch(typeof(CVRAvatar), "Start")] + private static void Post_CVRAvatar_Start(CVRAvatar __instance) + { + if (!BadAnimatorFixMod.EntryCVRAvatar.Value) return; + AddBadAnimatorFixComponentIfAnimatorExists(__instance.gameObject); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(CVRSpawnable), "Start")] + private static void Post_CVRSpawnable_Start(CVRSpawnable __instance) + { + if (!BadAnimatorFixMod.EntryCVRSpawnable.Value) return; + AddBadAnimatorFixComponentIfAnimatorExists(__instance.gameObject); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(CVRWorld), "Start")] + private static void Post_CVRWorld_Start(CVRWorld __instance) + { + if (!BadAnimatorFixMod.EntryCVRWorld.Value) return; + AddBadAnimatorFixComponentIfAnimatorExists(__instance.gameObject); + } + + //Set QM stuff + [HarmonyPostfix] + [HarmonyPatch(typeof(CVR_MenuManager), "Start")] + private static void Postfix_CVR_MenuManager_Start(ref CVR_MenuManager __instance, ref GameObject ____leftVrAnchor) + { + if (!BadAnimatorFixMod.EntryMenus.Value) return; + AddBadAnimatorFixComponentIfAnimatorExists(__instance.gameObject); + } + + //Set MM stuff + [HarmonyPostfix] + [HarmonyPatch(typeof(ViewManager), "Start")] + private static void Postfix_ViewManager_Start(ref ViewManager __instance) + { + if (!BadAnimatorFixMod.EntryMenus.Value) return; + AddBadAnimatorFixComponentIfAnimatorExists(__instance.gameObject); + } + + private static void AddBadAnimatorFixComponentIfAnimatorExists(GameObject gameObject) + { + if (!BadAnimatorFixMod.EntryEnabled.Value) return; + Animator[] animators = gameObject.GetComponentsInChildren(); + foreach (Animator animator in animators.Where(a => a.gameObject.GetComponent() == null)) + { + if (animator.runtimeAnimatorController != null) + animator.gameObject.AddComponent(); + } + } +} + diff --git a/BadAnimatorFix/Main.cs b/BadAnimatorFix/Main.cs new file mode 100644 index 0000000..14463ac --- /dev/null +++ b/BadAnimatorFix/Main.cs @@ -0,0 +1,47 @@ +using MelonLoader; + +namespace NAK.Melons.BadAnimatorFix; + +public class BadAnimatorFixMod : MelonMod +{ + internal static MelonLogger.Instance Logger; + public const string SettingsCategory = "BadAnimatorFix"; + public static readonly MelonPreferences_Category CategoryBadAnimatorFix = MelonPreferences.CreateCategory(SettingsCategory); + + public static readonly MelonPreferences_Entry EntryEnabled = + CategoryBadAnimatorFix.CreateEntry("Enabled", true, description: "Toggle BadAnimatorFix entirely. Requires avatar/spawnable/world reload."); + + public static readonly MelonPreferences_Entry EntryCVRAvatar = + CategoryBadAnimatorFix.CreateEntry("Add to CVRAvatar", true, description: "Should BadAnimatorFix run for CVRAvatar? Requires avatar reload."); + + public static readonly MelonPreferences_Entry EntryCVRSpawnable = + CategoryBadAnimatorFix.CreateEntry("Add to CVRSpawnable", false, description: "Should BadAnimatorFix run for CVRSpawnable? Requires spawnable reload."); + + public static readonly MelonPreferences_Entry EntryCVRWorld = + CategoryBadAnimatorFix.CreateEntry("Add to CVRWorld", false, description: "Should BadAnimatorFix run for CVRWorld? Requires world reload."); + + public static readonly MelonPreferences_Entry EntryMenus = + CategoryBadAnimatorFix.CreateEntry("Add to Menus", false, description: "Should BadAnimatorFix run for QM & MM? Requires game restart."); + + public static readonly MelonPreferences_Entry EntryPlayableTimeLimit = + CategoryBadAnimatorFix.CreateEntry("Playable Time Limit", 600f, description: "How long in seconds can a Playable play for before rewinding its states."); + + public override void OnInitializeMelon() + { + Logger = LoggerInstance; + ApplyPatches(typeof(HarmonyPatches.AnimatorPatches)); + } + + private void ApplyPatches(Type type) + { + try + { + HarmonyInstance.PatchAll(type); + } + catch (Exception e) + { + Logger.Msg($"Failed while patching {type.Name}!"); + Logger.Error(e); + } + } +} \ No newline at end of file diff --git a/BadAnimatorFix/Properties/AssemblyInfo.cs b/BadAnimatorFix/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4b98794 --- /dev/null +++ b/BadAnimatorFix/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using MelonLoader; +using NAK.Melons.BadAnimatorFix.Properties; +using System.Reflection; + +[assembly: AssemblyVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyTitle(nameof(NAK.Melons.BadAnimatorFix))] +[assembly: AssemblyCompany(AssemblyInfoParams.Author)] +[assembly: AssemblyProduct(nameof(NAK.Melons.BadAnimatorFix))] + +[assembly: MelonInfo( + typeof(NAK.Melons.BadAnimatorFix.BadAnimatorFixMod), + nameof(NAK.Melons.BadAnimatorFix), + AssemblyInfoParams.Version, + AssemblyInfoParams.Author, + downloadLink: "https://github.com/NotAKidOnSteam/BadAnimatorFix" +)] + +[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] +[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] +[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] +[assembly: HarmonyDontPatchAll] + +namespace NAK.Melons.BadAnimatorFix.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/BadAnimatorFix/format.json b/BadAnimatorFix/format.json new file mode 100644 index 0000000..7d05f54 --- /dev/null +++ b/BadAnimatorFix/format.json @@ -0,0 +1,23 @@ +{ + "_id": -1, + "name": "TrackedControllerFix", + "modversion": "1.0.0", + "gameversion": "2022r170", + "loaderversion": "0.5.7", + "modtype": "Mod", + "author": "NotAKidoS", + "description": "Allows your controllers to track while the SteamVR overlay is open. This also fixes Quest/Touch controllers feeling slow during fast movements.", + "searchtags": [ + "vr", + "quest", + "controller", + "tracking" + ], + "requirements": [ + "None" + ], + "downloadlink": "https://github.com/NotAKidOnSteam/TrackedControllerFix/releases/download/v1.0.0/TrackedControllerFix.dll", + "sourcelink": "https://github.com/NotAKidOnSteam/TrackedControllerFix/", + "changelog": "Initial Release", + "embedcolor": "3498db" +} \ No newline at end of file