diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/Blackout/Blackout.csproj b/Blackout/Blackout.csproj new file mode 100644 index 0000000..5bbb158 --- /dev/null +++ b/Blackout/Blackout.csproj @@ -0,0 +1,55 @@ + + + + + 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 + + + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll + + + ..\..\..\..\..\..\..\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 + + + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AssetBundleModule.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 + + + + + + + + + diff --git a/Blackout/Blackout.sln b/Blackout/Blackout.sln new file mode 100644 index 0000000..4433874 --- /dev/null +++ b/Blackout/Blackout.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}") = "Blackout", "Blackout.csproj", "{1D5ABEE5-ACFA-4B0C-9195-968FA3DFEECD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1D5ABEE5-ACFA-4B0C-9195-968FA3DFEECD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D5ABEE5-ACFA-4B0C-9195-968FA3DFEECD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D5ABEE5-ACFA-4B0C-9195-968FA3DFEECD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D5ABEE5-ACFA-4B0C-9195-968FA3DFEECD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {698498B4-20BF-45AF-A7A3-2F8091D6AE7E} + EndGlobalSection +EndGlobal diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs new file mode 100644 index 0000000..e843bf1 --- /dev/null +++ b/Blackout/BlackoutController.cs @@ -0,0 +1,112 @@ +using ABI.CCK.Components; +using ABI_RC.Core.Player; +using ABI_RC.Systems.IK; +using ABI_RC.Systems.IK.SubSystems; +using HarmonyLib; +using MelonLoader; +using RootMotion.FinalIK; +using UnityEngine; +using UnityEngine.Events; + +namespace Blackout; + +/* + + Functionality heavily inspired by VRSleeper on Booth: https://booth.pm/ja/items/2151940 + + There are three states of "blackout": + + 0 - Awake (no effect) + 1 - Drowsy (partial effect) + 2 - Sleep (full effect) + +*/ + +public class BlackoutController : MonoBehaviour +{ + public int BlackoutState = 0; + + //degrees of movement to give partial vision + public float drowsyThreshold = 1f; + //degrees of movement to give complete vision + public float wakeThreshold = 12f; + + //how long without movement until the screen dims + public float enterSleepTime = 3f; // MINUTES + //how long should the wake state last before return + public float returnSleepTime = 10f; // SECONDS + + //private BlackoutController instance; + private Quaternion oldHeadRotation = Quaternion.identity; + private float lastAwakeTime = 0f; + private int nextUpdate = 1; + + void Update() + { + //only run once a second, angularMovement is "smoothed out" at high FPS otherwise + float curTime = Time.time; + if (!(curTime >= nextUpdate)) return; + nextUpdate = Mathf.FloorToInt(curTime) + 1; + + //get difference between last frame rotation and current rotation + Quaternion currentHeadRotation = PlayerSetup.Instance.GetActiveCamera().transform.rotation; + float angularMovement = Quaternion.Angle(oldHeadRotation, currentHeadRotation); + oldHeadRotation = currentHeadRotation; + + // These are SOFT movements + if (angularMovement > drowsyThreshold) + { + lastAwakeTime = curTime; + if (BlackoutState == 2) + { + BlackoutState = 1; + MelonLogger.Msg("Exited Sleep state and entered Drowsy state."); + } + } + + // These are HARD movements + if (angularMovement > wakeThreshold) + { + lastAwakeTime = curTime; + + if (BlackoutState == 0) return; + BlackoutState = 0; + MelonLogger.Msg("Exited anystate and entered Awake state."); + } + + MelonLogger.Msg($"BlackoutState " + BlackoutState); + MelonLogger.Msg($"curTime " + curTime); + MelonLogger.Msg($"lastAwakeTime " + lastAwakeTime); + + if (BlackoutState == 2) return; + + //check if we should enter/return to sleep mode + if (curTime > lastAwakeTime + (BlackoutState == 0 ? enterSleepTime * 60 : returnSleepTime)) + { + BlackoutState = 2; + MelonLogger.Msg("Entered sleep state."); + } + } + + void Start() + { + MelonLogger.Msg(Application.streamingAssetsPath); + + var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "blackoutfader")); + if (myLoadedAssetBundle == null) + { + Debug.Log("Failed to load AssetBundle!"); + return; + } + + var prefab = myLoadedAssetBundle.LoadAsset("MyObject"); + Instantiate(prefab); + + myLoadedAssetBundle.Unload(false); + + prefab.transform.parent = PlayerSetup.Instance.GetActiveCamera().transform; + prefab.transform.localPosition = Vector3.zero; + prefab.transform.localRotation = Quaternion.identity; + prefab.transform.localScale = Vector3.zero; + } +} \ No newline at end of file diff --git a/Blackout/Main.cs b/Blackout/Main.cs new file mode 100644 index 0000000..98800a2 --- /dev/null +++ b/Blackout/Main.cs @@ -0,0 +1,59 @@ +using ABI.CCK.Components; +using ABI_RC.Core.Player; +using ABI_RC.Systems.IK; +using ABI_RC.Systems.IK.SubSystems; +using HarmonyLib; +using MelonLoader; +using RootMotion.FinalIK; +using UnityEngine; +using UnityEngine.Events; + +namespace Blackout; + +public class Blackout : MelonMod +{ + BlackoutController m_blackoutController = null; + + private static MelonPreferences_Category m_categoryBlackout; + private static MelonPreferences_Entry m_entryEnabled; + private static MelonPreferences_Entry m_entryDrowsyThreshold; + private static MelonPreferences_Entry m_entryAwakeThreshold; + private static MelonPreferences_Entry m_entryEnterSleepTime; + private static MelonPreferences_Entry m_entryReturnSleepTime; + + public override void OnApplicationStart() + { + m_categoryBlackout = MelonPreferences.CreateCategory(nameof(Blackout)); + m_entryEnabled = m_categoryBlackout.CreateEntry("Enabled", true, description: "Dim screen when sleeping."); + m_entryDrowsyThreshold = m_categoryBlackout.CreateEntry("Drowsy Threshold", 1f, description: "Degrees of movement to return partial vision."); + m_entryAwakeThreshold = m_categoryBlackout.CreateEntry("Awake Threshold", 12f, description: "Degrees of movement to return full vision."); + m_entryEnterSleepTime = m_categoryBlackout.CreateEntry("Enter Sleep Time", 3f, description: "How many minutes without movement until enter sleep mode."); + m_entryReturnSleepTime = m_categoryBlackout.CreateEntry("Return Sleep Time", 10f, description: "How many seconds should the wake state last before return."); + m_categoryBlackout.SaveToFile(false); + + m_entryEnabled.OnValueChangedUntyped += OnEnabled; + MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer()); + } + + System.Collections.IEnumerator WaitForLocalPlayer() + { + while (PlayerSetup.Instance == null) + yield return null; + + m_blackoutController = PlayerSetup.Instance.gameObject.AddComponent(); + } + + public void OnEnabled() + { + if (!m_blackoutController) return; + m_blackoutController.enabled = m_entryEnabled.Value; + } + public void OnUpdateSettings() + { + if (!m_blackoutController) return; + m_blackoutController.drowsyThreshold = m_entryDrowsyThreshold.Value; + m_blackoutController.wakeThreshold = m_entryAwakeThreshold.Value; + m_blackoutController.enterSleepTime = m_entryEnterSleepTime.Value; + m_blackoutController.returnSleepTime = m_entryReturnSleepTime.Value; + } +} \ No newline at end of file diff --git a/Blackout/Properties/AssemblyInfo.cs b/Blackout/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..659ebc4 --- /dev/null +++ b/Blackout/Properties/AssemblyInfo.cs @@ -0,0 +1,30 @@ +using MelonLoader; +using System.Reflection; +using Blackout.Properties; + + +[assembly: AssemblyVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] +[assembly: AssemblyTitle(nameof(Blackout))] +[assembly: AssemblyCompany(AssemblyInfoParams.Author)] +[assembly: AssemblyProduct(nameof(Blackout))] + +[assembly: MelonInfo( + typeof(Blackout.Blackout), + nameof(Blackout), + AssemblyInfoParams.Version, + AssemblyInfoParams.Author, + downloadLink: "https://github.com/NotAKidOnSteam/Blackout" +)] + +[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] +[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] +[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] + +namespace Blackout.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/Blackout/format.json b/Blackout/format.json new file mode 100644 index 0000000..4477fd1 --- /dev/null +++ b/Blackout/format.json @@ -0,0 +1,23 @@ +{ + "_id": 95, + "name": "Blackout", + "modversion": "1.1.0", + "gameversion": "2022r168", + "loaderversion": "0.5.4", + "modtype": "Mod", + "author": "NotAKidoS", + "description": "Corrects MM and QM position when avatar is scaled.\nAdditional option to scale player collision.", + "searchtags": [ + "menu", + "scale", + "avatarscale", + "slider" + ], + "requirements": [ + "None" + ], + "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r2/Blackout.dll", + "sourcelink": "https://github.com/NotAKidOnSteam/Blackout/", + "changelog": "Added option to scale player collision. Fixed some VR specific issues.", + "embedcolor": "804221" +} \ No newline at end of file