From d0f70b1454d3073ae4be479d2d67b8d2f4b3725c Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Wed, 12 Oct 2022 09:10:42 -0500 Subject: [PATCH 01/19] Initial commit --- .gitignore | 350 +++++++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE | 21 ++++ README.md | 2 + 3 files changed, 373 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dfcfd56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,350 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..262b1ec --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 NotAKidoS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..dac61c6 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Blackout +dims screen when still (best for vr sleeping) From c049d93d5538e13aad64a64eb96d33d0fdac4914 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Wed, 12 Oct 2022 09:18:48 -0500 Subject: [PATCH 02/19] base logic everything but the actual dimming- shoulda figured that out first huh --- .gitattributes | 2 + Blackout/Blackout.csproj | 55 ++++++++++++++ Blackout/Blackout.sln | 25 +++++++ Blackout/BlackoutController.cs | 112 ++++++++++++++++++++++++++++ Blackout/Main.cs | 59 +++++++++++++++ Blackout/Properties/AssemblyInfo.cs | 30 ++++++++ Blackout/format.json | 23 ++++++ 7 files changed, 306 insertions(+) create mode 100644 .gitattributes create mode 100644 Blackout/Blackout.csproj create mode 100644 Blackout/Blackout.sln create mode 100644 Blackout/BlackoutController.cs create mode 100644 Blackout/Main.cs create mode 100644 Blackout/Properties/AssemblyInfo.cs create mode 100644 Blackout/format.json 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 From d033d3750e8d47260bc45b0effafc00332a41d80 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Wed, 12 Oct 2022 22:46:17 -0500 Subject: [PATCH 03/19] Testing Phase Basics are implemented. Needs playtesting before potential rewrite and implementation of avatar parameters & manual control. --- Blackout/AssetHandler.cs | 95 ++++++++ Blackout/Blackout.csproj | 23 ++ Blackout/BlackoutController.cs | 224 ++++++++++++++----- Blackout/Main.cs | 80 ++++--- Blackout/Properties/AssemblyInfo.cs | 4 +- Blackout/Resource1.Designer.cs | 73 ++++++ Blackout/Resource1.resx | 124 ++++++++++ Blackout/resources/blackout_controller.asset | Bin 0 -> 13454 bytes 8 files changed, 541 insertions(+), 82 deletions(-) create mode 100644 Blackout/AssetHandler.cs create mode 100644 Blackout/Resource1.Designer.cs create mode 100644 Blackout/Resource1.resx create mode 100644 Blackout/resources/blackout_controller.asset diff --git a/Blackout/AssetHandler.cs b/Blackout/AssetHandler.cs new file mode 100644 index 0000000..7d213ee --- /dev/null +++ b/Blackout/AssetHandler.cs @@ -0,0 +1,95 @@ +using System.Reflection; +using UnityEngine; + +namespace Blackout; + +/* + + Kindly stolen from SDraw's leap motion mod. (MIT) + https://github.com/SDraw/ml_mods_cvr/blob/master/ml_lme/AssetsHandler.cs + + *thank u sdraw, i wont be murderer now* + +*/ + + +static class AssetsHandler +{ + static readonly List ms_assets = new List() + { + "blackout_controller.asset" + }; + + static Dictionary ms_loadedAssets = new Dictionary(); + static Dictionary ms_loadedObjects = new Dictionary(); + + public static void Load() + { + Assembly l_assembly = Assembly.GetExecutingAssembly(); + string l_assemblyName = l_assembly.GetName().Name; + + foreach (string l_assetName in ms_assets) + { + try + { + Stream l_assetStream = l_assembly.GetManifestResourceStream(l_assemblyName + ".resources." + l_assetName); + if (l_assetStream != null) + { + MemoryStream l_memorySteam = new MemoryStream((int)l_assetStream.Length); + l_assetStream.CopyTo(l_memorySteam); + AssetBundle l_assetBundle = AssetBundle.LoadFromMemory(l_memorySteam.ToArray(), 0); + if (l_assetBundle != null) + { + l_assetBundle.hideFlags |= HideFlags.DontUnloadUnusedAsset; + ms_loadedAssets.Add(l_assetName, l_assetBundle); + } + else + MelonLoader.MelonLogger.Warning("Unable to load bundled '" + l_assetName + "' asset"); + } + else + MelonLoader.MelonLogger.Warning("Unable to get bundled '" + l_assetName + "' asset stream"); + } + catch (System.Exception e) + { + MelonLoader.MelonLogger.Warning("Unable to load bundled '" + l_assetName + "' asset, reason: " + e.Message); + } + } + } + + public static GameObject GetAsset(string p_name) + { + GameObject l_result = null; + if (ms_loadedObjects.ContainsKey(p_name)) + { + l_result = UnityEngine.Object.Instantiate(ms_loadedObjects[p_name]); + l_result.SetActive(true); + l_result.hideFlags |= HideFlags.DontUnloadUnusedAsset; + } + else + { + foreach (var l_pair in ms_loadedAssets) + { + if (l_pair.Value.Contains(p_name)) + { + GameObject l_bundledObject = (GameObject)l_pair.Value.LoadAsset(p_name, typeof(GameObject)); + if (l_bundledObject != null) + { + ms_loadedObjects.Add(p_name, l_bundledObject); + l_result = UnityEngine.Object.Instantiate(l_bundledObject); + l_result.SetActive(true); + l_result.hideFlags |= HideFlags.DontUnloadUnusedAsset; + } + break; + } + } + } + return l_result; + } + + public static void Unload() + { + foreach (var l_pair in ms_loadedAssets) + UnityEngine.Object.Destroy(l_pair.Value); + ms_loadedAssets.Clear(); + } +} \ No newline at end of file diff --git a/Blackout/Blackout.csproj b/Blackout/Blackout.csproj index 5bbb158..6b9471a 100644 --- a/Blackout/Blackout.csproj +++ b/Blackout/Blackout.csproj @@ -8,6 +8,14 @@ false + + + + + + + + C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\0Harmony.dll @@ -47,6 +55,21 @@ + + + True + True + Resource1.resx + + + + + + ResXFileCodeGenerator + Resource1.Designer.cs + + + diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs index e843bf1..a583775 100644 --- a/Blackout/BlackoutController.cs +++ b/Blackout/BlackoutController.cs @@ -1,12 +1,7 @@ -using ABI.CCK.Components; -using ABI_RC.Core.Player; -using ABI_RC.Systems.IK; -using ABI_RC.Systems.IK.SubSystems; -using HarmonyLib; +using ABI_RC.Core.Player; +using ABI_RC.Core.UI; using MelonLoader; -using RootMotion.FinalIK; using UnityEngine; -using UnityEngine.Events; namespace Blackout; @@ -20,11 +15,21 @@ namespace Blackout; 1 - Drowsy (partial effect) 2 - Sleep (full effect) + After staying still for DrowsyModeTimer (minutes), you enter DrowsyMode. + This mode dims the screen to your selected dimming strength. + After continuing to stay still for SleepModeTimer (seconds), you enter SleepMode. + This mode overrenders mostly everything with black. + + Slight movement while in SleepMode will place you in DrowsyMode until SleepModeTimer is reached again. + Hard movement once entering DrowsyMode will fully wake you and return complete vision. + */ public class BlackoutController : MonoBehaviour { - public int BlackoutState = 0; + public static BlackoutController Instance; + + public BlackoutState CurrentState = BlackoutState.Awake; //degrees of movement to give partial vision public float drowsyThreshold = 1f; @@ -32,81 +37,190 @@ public class BlackoutController : MonoBehaviour public float wakeThreshold = 12f; //how long without movement until the screen dims - public float enterSleepTime = 3f; // MINUTES + public float DrowsyModeTimer = 3f; // MINUTES //how long should the wake state last before return - public float returnSleepTime = 10f; // SECONDS + public float SleepModeTimer = 10f; // SECONDS + + //how much does DrowsyMode affect the screen + public float DrowsyDimStrength = 0.5f; + + //this is uh, not work well- might rewrite now that i know how this should work + public bool HudMessages = false; + + public enum BlackoutState + { + Awake = 0, + Drowsy, + Sleeping, + } - //private BlackoutController instance; private Quaternion oldHeadRotation = Quaternion.identity; + private float angularMovement = 0f; + private float curTime = 0f; private float lastAwakeTime = 0f; private int nextUpdate = 1; + private Animator blackoutAnimator; + + public void ChangeBlackoutState(BlackoutState newState) + { + if (!blackoutAnimator) return; + if (newState == CurrentState) return; + + lastAwakeTime = curTime; + + switch (newState) + { + case BlackoutState.Awake: + blackoutAnimator.SetBool("BlackoutState.Drowsy", false); + blackoutAnimator.SetBool("BlackoutState.Sleeping", false); + blackoutAnimator.SetFloat("BlackoutSetting.DrowsyPartial", DrowsyDimStrength); + break; + case BlackoutState.Drowsy: + blackoutAnimator.SetBool("BlackoutState.Drowsy", true); + blackoutAnimator.SetBool("BlackoutState.Sleeping", false); + blackoutAnimator.SetFloat("BlackoutSetting.DrowsyPartial", DrowsyDimStrength); + break; + case BlackoutState.Sleeping: + blackoutAnimator.SetBool("BlackoutState.Drowsy", false); + blackoutAnimator.SetBool("BlackoutState.Sleeping", true); + blackoutAnimator.SetFloat("BlackoutSetting.DrowsyPartial", DrowsyDimStrength); + break; + default: + break; + } + BlackoutState prevState = CurrentState; + CurrentState = newState; + SendHUDMessage($"Exiting {prevState} and entering {newState} state."); + } void Update() { //only run once a second, angularMovement is "smoothed out" at high FPS otherwise - float curTime = Time.time; + //for the sake of responsivness while user is in a sleepy state, this might be removed to prevent confusion... + 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); + angularMovement = Quaternion.Angle(oldHeadRotation, currentHeadRotation); oldHeadRotation = currentHeadRotation; - // These are SOFT movements + //handle current state + switch (CurrentState) + { + case BlackoutState.Awake: + HandleAwakeState(); + break; + case BlackoutState.Drowsy: + HandleDrowsyState(); + break; + case BlackoutState.Sleeping: + HandleSleepingState(); + break; + default: + break; + } + + //debug + //MelonLogger.Msg("curTime " + curTime); + //MelonLogger.Msg("lastAwakeTime " + lastAwakeTime); + //MelonLogger.Msg("timeleft " + GetNextStateTimer()); + //MelonLogger.Msg("current state " + CurrentState); + } + + //initialize BlackoutInstance object + void Start() + { + Instance = this; + + GameObject blackoutAsset = AssetsHandler.GetAsset("Assets/BundledAssets/Blackout/Blackout.prefab"); + GameObject blackoutGO = Instantiate(blackoutAsset, new Vector3(0, 0, 0), Quaternion.identity); + + if (blackoutGO != null) + { + blackoutGO.name = "BlackoutInstance"; + blackoutAnimator = blackoutGO.GetComponent(); + SetupBlackoutInstance(); + } + } + + void OnEnabled() + { + if (!blackoutAnimator) return; + blackoutAnimator.gameObject.SetActive(true); + } + + void OnDisabled() + { + ChangeBlackoutState(BlackoutState.Awake); + if (!blackoutAnimator) return; + blackoutAnimator.gameObject.SetActive(false); + } + + public void SetupBlackoutInstance() + { + blackoutAnimator.transform.parent = PlayerSetup.Instance.GetActiveCamera().transform; + blackoutAnimator.transform.localPosition = Vector3.zero; + blackoutAnimator.transform.localRotation = Quaternion.identity; + blackoutAnimator.transform.localScale = Vector3.one; + } + + private float GetNextStateTimer() + { + switch (CurrentState) + { + case BlackoutState.Awake: + return (lastAwakeTime + DrowsyModeTimer * 60 - curTime); + case BlackoutState.Drowsy: + return (lastAwakeTime + SleepModeTimer - curTime); + case BlackoutState.Sleeping: + return 0f; + default: + return 0f; + } + } + + //broken, needs to run next frame + private void SendHUDMessage(string message) + { + MelonLogger.Msg(message); + if (!CohtmlHud.Instance || !HudMessages) return; + CohtmlHud.Instance.ViewDropTextImmediate("Blackout", message, GetNextStateTimer().ToString() + " seconds till next state change."); + } + + private void HandleAwakeState() + { + //small movement should reset sleep timer if (angularMovement > drowsyThreshold) { lastAwakeTime = curTime; - if (BlackoutState == 2) - { - BlackoutState = 1; - MelonLogger.Msg("Exited Sleep state and entered Drowsy state."); - } } - - // These are HARD movements + //enter drowsy mode after few minutes + if (curTime > lastAwakeTime + DrowsyModeTimer * 60) + { + ChangeBlackoutState(BlackoutState.Drowsy); + } + } + private void HandleDrowsyState() + { + //hard movement should exit drowsy state if (angularMovement > wakeThreshold) { - lastAwakeTime = curTime; - - if (BlackoutState == 0) return; - BlackoutState = 0; - MelonLogger.Msg("Exited anystate and entered Awake state."); + ChangeBlackoutState(BlackoutState.Awake); } - - 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)) + //enter full sleep mode + if (curTime > lastAwakeTime + SleepModeTimer) { - BlackoutState = 2; - MelonLogger.Msg("Entered sleep state."); + ChangeBlackoutState(BlackoutState.Sleeping); } } - - void Start() + private void HandleSleepingState() { - MelonLogger.Msg(Application.streamingAssetsPath); - - var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "blackoutfader")); - if (myLoadedAssetBundle == null) + //small movement should enter drowsy state + if (angularMovement > drowsyThreshold) { - Debug.Log("Failed to load AssetBundle!"); - return; + ChangeBlackoutState(BlackoutState.Drowsy); } - - 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 index 98800a2..e4fa78a 100644 --- a/Blackout/Main.cs +++ b/Blackout/Main.cs @@ -1,59 +1,89 @@ -using ABI.CCK.Components; -using ABI_RC.Core.Player; -using ABI_RC.Systems.IK; -using ABI_RC.Systems.IK.SubSystems; +using ABI_RC.Core.Player; using HarmonyLib; using MelonLoader; -using RootMotion.FinalIK; using UnityEngine; -using UnityEngine.Events; namespace Blackout; public class Blackout : MelonMod { - BlackoutController m_blackoutController = null; - + private static bool inVR; 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; + private static MelonPreferences_Entry m_entryEnabled, m_entryHudMessages; + //private static MelonPreferences_Entry m_entryVROnly; + private static MelonPreferences_Entry + m_entryDrowsyThreshold, m_entryAwakeThreshold, + m_entryDrowsyModeTimer, m_entrySleepModeTimer, + m_entryDrowsyDimStrength; public override void OnApplicationStart() { m_categoryBlackout = MelonPreferences.CreateCategory(nameof(Blackout)); m_entryEnabled = m_categoryBlackout.CreateEntry("Enabled", true, description: "Dim screen when sleeping."); + m_entryHudMessages = m_categoryBlackout.CreateEntry("Hud Messages", false, description: "Notify on state change."); 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_entryDrowsyModeTimer = m_categoryBlackout.CreateEntry("Enter Drowsy Time", 3f, description: "How many minutes without movement until enter drowsy mode."); + m_entrySleepModeTimer = m_categoryBlackout.CreateEntry("Enter Sleep Time", 10f, description: "How many seconds without movement until enter sleep mode."); + m_entryDrowsyDimStrength = m_categoryBlackout.CreateEntry("Drowsy Dim Strength", 0.5f, description: "How strong of a dimming effect should drowsy mode have."); + //m_entryVROnly = m_categoryBlackout.CreateEntry("VR Only", false, description: "Only enable mod in VR."); m_categoryBlackout.SaveToFile(false); m_entryEnabled.OnValueChangedUntyped += OnEnabled; + m_entryHudMessages.OnValueChangedUntyped += OnUpdateSettings; + m_entryDrowsyThreshold.OnValueChangedUntyped += OnUpdateSettings; + m_entryAwakeThreshold.OnValueChangedUntyped += OnUpdateSettings; + m_entryDrowsyModeTimer.OnValueChangedUntyped += OnUpdateSettings; + m_entrySleepModeTimer.OnValueChangedUntyped += OnUpdateSettings; + m_entryDrowsyDimStrength.OnValueChangedUntyped += OnUpdateSettings; + //m_entryVROnly.OnValueChangedUntyped += OnUpdateSettings; MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer()); } System.Collections.IEnumerator WaitForLocalPlayer() { + //load blackout_controller.asset + AssetsHandler.Load(); + while (PlayerSetup.Instance == null) yield return null; - m_blackoutController = PlayerSetup.Instance.gameObject.AddComponent(); + inVR = PlayerSetup.Instance._inVr; + PlayerSetup.Instance.gameObject.AddComponent(); + + //update BlackoutController settings after it initializes + yield return new WaitForEndOfFrame(); + OnUpdateSettings(); } - public void OnEnabled() + private void OnEnabled() { - if (!m_blackoutController) return; - m_blackoutController.enabled = m_entryEnabled.Value; + if (!BlackoutController.Instance) return; + BlackoutController.Instance.enabled = m_entryEnabled.Value; } - public void OnUpdateSettings() + private 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; + if (!BlackoutController.Instance) return; + BlackoutController.Instance.drowsyThreshold = m_entryDrowsyThreshold.Value; + BlackoutController.Instance.wakeThreshold = m_entryAwakeThreshold.Value; + BlackoutController.Instance.DrowsyModeTimer = m_entryDrowsyModeTimer.Value; + BlackoutController.Instance.SleepModeTimer = m_entrySleepModeTimer.Value; + BlackoutController.Instance.DrowsyDimStrength = m_entryDrowsyDimStrength.Value; + BlackoutController.Instance.HudMessages = m_entryHudMessages.Value; + } + + //Support for changing VRMode during runtime. + [HarmonyPatch] + private class HarmonyPatches + { + [HarmonyPostfix] + [HarmonyPatch(typeof(PlayerSetup), "CalibrateAvatar")] + private static void CheckVRModeSwitch() + { + if (inVR != PlayerSetup.Instance._inVr) + { + BlackoutController.Instance.SetupBlackoutInstance(); + } + } } } \ No newline at end of file diff --git a/Blackout/Properties/AssemblyInfo.cs b/Blackout/Properties/AssemblyInfo.cs index 659ebc4..728d4a7 100644 --- a/Blackout/Properties/AssemblyInfo.cs +++ b/Blackout/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ -using MelonLoader; +using Blackout.Properties; +using MelonLoader; using System.Reflection; -using Blackout.Properties; [assembly: AssemblyVersion(AssemblyInfoParams.Version)] diff --git a/Blackout/Resource1.Designer.cs b/Blackout/Resource1.Designer.cs new file mode 100644 index 0000000..5c2b3b3 --- /dev/null +++ b/Blackout/Resource1.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Blackout { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resource1 { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resource1() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Blackout.Resource1", typeof(Resource1).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] blackout_controller { + get { + object obj = ResourceManager.GetObject("blackout_controller", resourceCulture); + return ((byte[])(obj)); + } + } + } +} diff --git a/Blackout/Resource1.resx b/Blackout/Resource1.resx new file mode 100644 index 0000000..4003b7c --- /dev/null +++ b/Blackout/Resource1.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Resources\blackout_controller.asset;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Blackout/resources/blackout_controller.asset b/Blackout/resources/blackout_controller.asset new file mode 100644 index 0000000000000000000000000000000000000000..52e58cc994c225d484455efb230d12097c265d96 GIT binary patch literal 13454 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 literal 0 HcmV?d00001 From e6784b967e2b43058d3c58b962a8ef5a77e26022 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 02:00:05 -0500 Subject: [PATCH 04/19] Initial Release Added UIExpansionKit support, moved Harmony patches to own cs, added accidental feature that disables automatic state change, added option to lower FPS while in sleep state. --- Blackout/Blackout.csproj | 3 +++ Blackout/BlackoutController.cs | 28 ++++++++++++-------- Blackout/HarmonyPatches.cs | 19 ++++++++++++++ Blackout/Main.cs | 45 ++++++++++++++++++--------------- Blackout/UIExpansionKitAddon.cs | 15 +++++++++++ 5 files changed, 80 insertions(+), 30 deletions(-) create mode 100644 Blackout/HarmonyPatches.cs create mode 100644 Blackout/UIExpansionKitAddon.cs diff --git a/Blackout/Blackout.csproj b/Blackout/Blackout.csproj index 6b9471a..60c5870 100644 --- a/Blackout/Blackout.csproj +++ b/Blackout/Blackout.csproj @@ -38,6 +38,9 @@ C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\SteamVR.dll + + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\UIExpansionKit.dll + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs index a583775..6906192 100644 --- a/Blackout/BlackoutController.cs +++ b/Blackout/BlackoutController.cs @@ -1,5 +1,6 @@ using ABI_RC.Core.Player; using ABI_RC.Core.UI; +using ABI_RC.Core.Savior; using MelonLoader; using UnityEngine; @@ -47,6 +48,9 @@ public class BlackoutController : MonoBehaviour //this is uh, not work well- might rewrite now that i know how this should work public bool HudMessages = false; + //lower FPS while in sleep mode + public bool DropFPSOnSleep = false; + public enum BlackoutState { Awake = 0, @@ -60,6 +64,7 @@ public class BlackoutController : MonoBehaviour private float lastAwakeTime = 0f; private int nextUpdate = 1; private Animator blackoutAnimator; + private int targetFPS; public void ChangeBlackoutState(BlackoutState newState) { @@ -91,6 +96,7 @@ public class BlackoutController : MonoBehaviour BlackoutState prevState = CurrentState; CurrentState = newState; SendHUDMessage($"Exiting {prevState} and entering {newState} state."); + ChangeTargetFPS(); } void Update() @@ -144,18 +150,10 @@ public class BlackoutController : MonoBehaviour SetupBlackoutInstance(); } } - - void OnEnabled() - { - if (!blackoutAnimator) return; - blackoutAnimator.gameObject.SetActive(true); - } - - void OnDisabled() + + void OnDisable() { ChangeBlackoutState(BlackoutState.Awake); - if (!blackoutAnimator) return; - blackoutAnimator.gameObject.SetActive(false); } public void SetupBlackoutInstance() @@ -189,6 +187,16 @@ public class BlackoutController : MonoBehaviour CohtmlHud.Instance.ViewDropTextImmediate("Blackout", message, GetNextStateTimer().ToString() + " seconds till next state change."); } + private void ChangeTargetFPS() + { + if (!DropFPSOnSleep) return; + + //store target FPS to restore, i check each time just in case it changed + targetFPS = MetaPort.Instance.settings.GetSettingInt("GraphicsFramerateTarget", 0); + + Application.targetFrameRate = (CurrentState == BlackoutState.Sleeping) ? 5 : targetFPS; + } + private void HandleAwakeState() { //small movement should reset sleep timer diff --git a/Blackout/HarmonyPatches.cs b/Blackout/HarmonyPatches.cs new file mode 100644 index 0000000..00dd3e8 --- /dev/null +++ b/Blackout/HarmonyPatches.cs @@ -0,0 +1,19 @@ +using HarmonyLib; +using ABI_RC.Core.Player; + +namespace Blackout; + +[HarmonyPatch] +internal class HarmonyPatches +{ + //Support for changing VRMode during runtime. + [HarmonyPostfix] + [HarmonyPatch(typeof(PlayerSetup), "CalibrateAvatar")] + private static void CheckVRModeOnSwitch() + { + if (Blackout.inVR != PlayerSetup.Instance._inVr) + { + BlackoutController.Instance.SetupBlackoutInstance(); + } + } +} \ No newline at end of file diff --git a/Blackout/Main.cs b/Blackout/Main.cs index e4fa78a..2f8f7f0 100644 --- a/Blackout/Main.cs +++ b/Blackout/Main.cs @@ -7,11 +7,13 @@ namespace Blackout; public class Blackout : MelonMod { - private static bool inVR; - private static MelonPreferences_Category m_categoryBlackout; - private static MelonPreferences_Entry m_entryEnabled, m_entryHudMessages; - //private static MelonPreferences_Entry m_entryVROnly; - private static MelonPreferences_Entry + public const string SettingsCategory = "Blackout"; + + internal static bool inVR; + internal static MelonPreferences_Category m_categoryBlackout; + internal static MelonPreferences_Entry m_entryEnabled, m_entryHudMessages, m_entryDropFPSOnSleep; + //internal static MelonPreferences_Entry m_entryVROnly; + internal static MelonPreferences_Entry m_entryDrowsyThreshold, m_entryAwakeThreshold, m_entryDrowsyModeTimer, m_entrySleepModeTimer, m_entryDrowsyDimStrength; @@ -19,8 +21,9 @@ public class Blackout : MelonMod public override void OnApplicationStart() { m_categoryBlackout = MelonPreferences.CreateCategory(nameof(Blackout)); - m_entryEnabled = m_categoryBlackout.CreateEntry("Enabled", true, description: "Dim screen when sleeping."); + m_entryEnabled = m_categoryBlackout.CreateEntry("Automatic State Change", true, description: "Dim screen when there is no movement for a while."); m_entryHudMessages = m_categoryBlackout.CreateEntry("Hud Messages", false, description: "Notify on state change."); + m_entryDropFPSOnSleep = m_categoryBlackout.CreateEntry("Lower FPS While Sleep", false, description: "Lowers FPS to 5 while in Sleep State."); 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_entryDrowsyModeTimer = m_categoryBlackout.CreateEntry("Enter Drowsy Time", 3f, description: "How many minutes without movement until enter drowsy mode."); @@ -29,8 +32,12 @@ public class Blackout : MelonMod //m_entryVROnly = m_categoryBlackout.CreateEntry("VR Only", false, description: "Only enable mod in VR."); m_categoryBlackout.SaveToFile(false); + //please tell me a better way to do this + //this is fucking + //gross pleas etell me how to do this but not like this m_entryEnabled.OnValueChangedUntyped += OnEnabled; m_entryHudMessages.OnValueChangedUntyped += OnUpdateSettings; + m_entryDropFPSOnSleep.OnValueChangedUntyped += OnUpdateSettings; m_entryDrowsyThreshold.OnValueChangedUntyped += OnUpdateSettings; m_entryAwakeThreshold.OnValueChangedUntyped += OnUpdateSettings; m_entryDrowsyModeTimer.OnValueChangedUntyped += OnUpdateSettings; @@ -38,6 +45,13 @@ public class Blackout : MelonMod m_entryDrowsyDimStrength.OnValueChangedUntyped += OnUpdateSettings; //m_entryVROnly.OnValueChangedUntyped += OnUpdateSettings; MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer()); + + //UIExpansionKit addon + if (MelonHandler.Mods.Any(it => it.Info.Name == "UI Expansion Kit")) + { + MelonLogger.Msg("Initializing UIExpansionKit support."); + UiExtensionsAddon.Init(); + } } System.Collections.IEnumerator WaitForLocalPlayer() @@ -70,20 +84,11 @@ public class Blackout : MelonMod BlackoutController.Instance.SleepModeTimer = m_entrySleepModeTimer.Value; BlackoutController.Instance.DrowsyDimStrength = m_entryDrowsyDimStrength.Value; BlackoutController.Instance.HudMessages = m_entryHudMessages.Value; + BlackoutController.Instance.DropFPSOnSleep = m_entryDropFPSOnSleep.Value; } - //Support for changing VRMode during runtime. - [HarmonyPatch] - private class HarmonyPatches - { - [HarmonyPostfix] - [HarmonyPatch(typeof(PlayerSetup), "CalibrateAvatar")] - private static void CheckVRModeSwitch() - { - if (inVR != PlayerSetup.Instance._inVr) - { - BlackoutController.Instance.SetupBlackoutInstance(); - } - } - } + //UIExpansionKit actions + public static void AwakeState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); + public static void DrowsyState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Drowsy); + public static void SleepingState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Sleeping); } \ No newline at end of file diff --git a/Blackout/UIExpansionKitAddon.cs b/Blackout/UIExpansionKitAddon.cs new file mode 100644 index 0000000..f38bccb --- /dev/null +++ b/Blackout/UIExpansionKitAddon.cs @@ -0,0 +1,15 @@ +using System.Runtime.CompilerServices; +using UIExpansionKit.API; + +namespace Blackout; +public static class UiExtensionsAddon +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Init() + { + var settings = ExpansionKitApi.GetSettingsCategory(Blackout.SettingsCategory); + settings.AddSimpleButton("Awake State", Blackout.AwakeState); + settings.AddSimpleButton("Drowsy State", Blackout.DrowsyState); + settings.AddSimpleButton("Sleep State", Blackout.SleepingState); + } +} \ No newline at end of file From e500ac2d0bb4366388c81b00591f457b1c1ce7f3 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 02:00:34 -0500 Subject: [PATCH 05/19] clean ran clean on it --- Blackout/BlackoutController.cs | 4 ++-- Blackout/HarmonyPatches.cs | 4 ++-- Blackout/Main.cs | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs index 6906192..e5f245c 100644 --- a/Blackout/BlackoutController.cs +++ b/Blackout/BlackoutController.cs @@ -1,6 +1,6 @@ using ABI_RC.Core.Player; -using ABI_RC.Core.UI; using ABI_RC.Core.Savior; +using ABI_RC.Core.UI; using MelonLoader; using UnityEngine; @@ -150,7 +150,7 @@ public class BlackoutController : MonoBehaviour SetupBlackoutInstance(); } } - + void OnDisable() { ChangeBlackoutState(BlackoutState.Awake); diff --git a/Blackout/HarmonyPatches.cs b/Blackout/HarmonyPatches.cs index 00dd3e8..4b35fb6 100644 --- a/Blackout/HarmonyPatches.cs +++ b/Blackout/HarmonyPatches.cs @@ -1,5 +1,5 @@ -using HarmonyLib; -using ABI_RC.Core.Player; +using ABI_RC.Core.Player; +using HarmonyLib; namespace Blackout; diff --git a/Blackout/Main.cs b/Blackout/Main.cs index 2f8f7f0..065f1ae 100644 --- a/Blackout/Main.cs +++ b/Blackout/Main.cs @@ -1,5 +1,4 @@ using ABI_RC.Core.Player; -using HarmonyLib; using MelonLoader; using UnityEngine; From eb5a3ec6a5018975a4cab0880911c9bc7522aca2 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 02:17:30 -0500 Subject: [PATCH 06/19] Update README.md --- README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dac61c6..9f22742 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,59 @@ # Blackout -dims screen when still (best for vr sleeping) + + 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) + + After staying still for DrowsyModeTimer (minutes), you enter DrowsyMode. + This mode dims the screen to your selected dimming strength. + After continuing to stay still for SleepModeTimer (seconds), you enter SleepMode. + This mode over renders mostly everything with black. + + Slight movement while in SleepMode will place you in DrowsyMode until SleepModeTimer is reached again. + Hard movement once entering DrowsyMode will fully wake you and return complete vision. + + Auto state changing can be disabled. This allows you to use UIExpansionKit to manually change Blackout states. + + Supports DesktopVRSwitch~ if that releases. + +**Settings** + +* Hud Messages - Sends hud notification on state change. +* Lower FPS While Sleep - Caps FPS to 5 while in Sleep State. +* Drowsy Dim Strength - How strong of a dimming effect should drowsy mode have. + +//Automatic State Change related stuff +* Automatic State Change - Dim screen when there is no movement for a while. +* Drowsy Threshold - Degrees of movement to return partial vision. +* Awake Threshold - Degrees of movement to return full vision. +* Enter Drowsy Time - How many minutes without movement until enter drowsy mode. +* Enter Sleep Time - How many seconds without movement until enter sleep mode. + +--- + +Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI. +https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games + +> I am not affiliated with ABI in any official capacity, these mods are not endorsed or outright permitted by ABI and are subject to scrutiny. + +> Neither I nor these mods are in any way affiliated with Alpha Blend Interactive and/or ChilloutVR. Using these modifications might cause issues with the performance, security or stability of the game. Use at your own risk. + +> Any modifications that are not approved can get your ABI account terminated and such this modification is following the "modding guidelines" at the best it could be. +> They reserve the right to punish users using my mod. +> If you are scared of using modifications in your game do not install mods. + +> I do not affiliate ABI and the mod is not supported by ABI. + +> Me and this modification are in no affiliation with ABI and not supported by ABI. + +> This mod is not affiliated with Alpha Blend Interactive. The mod comes with no warranty. Use at your own risk, as I am not responsible for any misuse. + +> I'm not affiliated with Alpha Blend Interactive and this mod is not officially supported by the game. + +> When releasing mods to the public, it is required to state, that the mod authors and modification are in no affiliation with ABI and not supported by ABI. :trollface: + +> i ran out of places to steal disclaimers from From 6b1dbc2b926d30d24e71a827f2f0c5089a45c595 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 02:17:54 -0500 Subject: [PATCH 07/19] Update format.json --- Blackout/format.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Blackout/format.json b/Blackout/format.json index 4477fd1..05e3dd0 100644 --- a/Blackout/format.json +++ b/Blackout/format.json @@ -1,23 +1,23 @@ { "_id": 95, "name": "Blackout", - "modversion": "1.1.0", + "modversion": "1.0.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.", + "description": "Dim screen after set time of sitting still. Should be nice for VR sleeping.\nOptions for lowering FPS while sleeping, manual control via UIX, and customizing movement thresholds for finetuning.", "searchtags": [ - "menu", - "scale", - "avatarscale", - "slider" + "black", + "dimmer", + "sleeping", + "sleeper" ], "requirements": [ "None" ], - "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r2/Blackout.dll", + "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r1/Blackout.dll", "sourcelink": "https://github.com/NotAKidOnSteam/Blackout/", - "changelog": "Added option to scale player collision. Fixed some VR specific issues.", - "embedcolor": "804221" + "changelog": "Initial release.", + "embedcolor": "#0d1117" } \ No newline at end of file From 7932f1865eb97e296966213340aa4e0e814621f6 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 02:18:14 -0500 Subject: [PATCH 08/19] Update format.json --- Blackout/format.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Blackout/format.json b/Blackout/format.json index 05e3dd0..a86278b 100644 --- a/Blackout/format.json +++ b/Blackout/format.json @@ -1,5 +1,5 @@ { - "_id": 95, + "_id": -1, "name": "Blackout", "modversion": "1.0.0", "gameversion": "2022r168", From dcc4320ffa9286c0c101167a60f959311ba86c01 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 02:24:58 -0500 Subject: [PATCH 09/19] yea i stole the embed color from github darkmode --- Blackout/format.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Blackout/format.json b/Blackout/format.json index a86278b..bb2ebe7 100644 --- a/Blackout/format.json +++ b/Blackout/format.json @@ -6,7 +6,7 @@ "loaderversion": "0.5.4", "modtype": "Mod", "author": "NotAKidoS", - "description": "Dim screen after set time of sitting still. Should be nice for VR sleeping.\nOptions for lowering FPS while sleeping, manual control via UIX, and customizing movement thresholds for finetuning.", + "description": "Dim screen after set time of sitting still. Should be nice for VR sleeping.\n\nNotable Options:\n Cap FPS while sleeping.\nManual control via UIX\nConfigurable dimming strength.", "searchtags": [ "black", "dimmer", @@ -19,5 +19,5 @@ "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r1/Blackout.dll", "sourcelink": "https://github.com/NotAKidOnSteam/Blackout/", "changelog": "Initial release.", - "embedcolor": "#0d1117" + "embedcolor": "#161b22" } \ No newline at end of file From 329b3bcbdf4d0b11c575a8e2c784b36775b1bab1 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 03:14:42 -0500 Subject: [PATCH 10/19] smol tweak to reenable behavior Reenabling autodetection should reset the timer so you don't immediatly transition into a new state. --- Blackout/BlackoutController.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs index e5f245c..217c6b6 100644 --- a/Blackout/BlackoutController.cs +++ b/Blackout/BlackoutController.cs @@ -151,6 +151,12 @@ public class BlackoutController : MonoBehaviour } } + void OnEnable() + { + curTime = Time.time; + lastAwakeTime = curTime; + } + void OnDisable() { ChangeBlackoutState(BlackoutState.Awake); From 35bcc74e3b540cab05a5b9a904e86d06c27b7e2f Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 14:00:04 -0500 Subject: [PATCH 11/19] small polish tweaks, update to melon 5.5 --- Blackout/BlackoutController.cs | 52 +++++++-------- Blackout/HarmonyPatches.cs | 1 + Blackout/Main.cs | 63 ++++++++++--------- Blackout/Properties/AssemblyInfo.cs | 2 +- Blackout/resources/blackout_controller.asset | Bin 13454 -> 13708 bytes 5 files changed, 60 insertions(+), 58 deletions(-) diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs index 217c6b6..c3c1f2e 100644 --- a/Blackout/BlackoutController.cs +++ b/Blackout/BlackoutController.cs @@ -2,6 +2,7 @@ using ABI_RC.Core.Savior; using ABI_RC.Core.UI; using MelonLoader; +using System.Text; using UnityEngine; namespace Blackout; @@ -78,17 +79,17 @@ public class BlackoutController : MonoBehaviour case BlackoutState.Awake: blackoutAnimator.SetBool("BlackoutState.Drowsy", false); blackoutAnimator.SetBool("BlackoutState.Sleeping", false); - blackoutAnimator.SetFloat("BlackoutSetting.DrowsyPartial", DrowsyDimStrength); + blackoutAnimator.SetFloat("BlackoutSetting.DrowsyStrength", DrowsyDimStrength); break; case BlackoutState.Drowsy: blackoutAnimator.SetBool("BlackoutState.Drowsy", true); blackoutAnimator.SetBool("BlackoutState.Sleeping", false); - blackoutAnimator.SetFloat("BlackoutSetting.DrowsyPartial", DrowsyDimStrength); + blackoutAnimator.SetFloat("BlackoutSetting.DrowsyStrength", DrowsyDimStrength); break; case BlackoutState.Sleeping: blackoutAnimator.SetBool("BlackoutState.Drowsy", false); blackoutAnimator.SetBool("BlackoutState.Sleeping", true); - blackoutAnimator.SetFloat("BlackoutSetting.DrowsyPartial", DrowsyDimStrength); + blackoutAnimator.SetFloat("BlackoutSetting.DrowsyStrength", DrowsyDimStrength); break; default: break; @@ -99,6 +100,22 @@ public class BlackoutController : MonoBehaviour ChangeTargetFPS(); } + //initialize BlackoutInstance object + void Start() + { + Instance = this; + + GameObject blackoutAsset = AssetsHandler.GetAsset("Assets/BundledAssets/Blackout/Blackout.prefab"); + GameObject blackoutGO = Instantiate(blackoutAsset, new Vector3(0, 0, 0), Quaternion.identity); + + if (blackoutGO == null) return; + + blackoutGO.name = "BlackoutInstance"; + blackoutAnimator = blackoutGO.GetComponent(); + SetupBlackoutInstance(); + } + + //Automatic State Change void Update() { //only run once a second, angularMovement is "smoothed out" at high FPS otherwise @@ -127,28 +144,6 @@ public class BlackoutController : MonoBehaviour default: break; } - - //debug - //MelonLogger.Msg("curTime " + curTime); - //MelonLogger.Msg("lastAwakeTime " + lastAwakeTime); - //MelonLogger.Msg("timeleft " + GetNextStateTimer()); - //MelonLogger.Msg("current state " + CurrentState); - } - - //initialize BlackoutInstance object - void Start() - { - Instance = this; - - GameObject blackoutAsset = AssetsHandler.GetAsset("Assets/BundledAssets/Blackout/Blackout.prefab"); - GameObject blackoutGO = Instantiate(blackoutAsset, new Vector3(0, 0, 0), Quaternion.identity); - - if (blackoutGO != null) - { - blackoutGO.name = "BlackoutInstance"; - blackoutAnimator = blackoutGO.GetComponent(); - SetupBlackoutInstance(); - } } void OnEnable() @@ -190,7 +185,12 @@ public class BlackoutController : MonoBehaviour { MelonLogger.Msg(message); if (!CohtmlHud.Instance || !HudMessages) return; - CohtmlHud.Instance.ViewDropTextImmediate("Blackout", message, GetNextStateTimer().ToString() + " seconds till next state change."); + + StringBuilder secondmessage = new StringBuilder(); + if (enabled) + secondmessage = new StringBuilder(GetNextStateTimer().ToString() + " seconds till next state change."); + + CohtmlHud.Instance.ViewDropTextImmediate("Blackout", message, secondmessage.ToString()); } private void ChangeTargetFPS() diff --git a/Blackout/HarmonyPatches.cs b/Blackout/HarmonyPatches.cs index 4b35fb6..51f9793 100644 --- a/Blackout/HarmonyPatches.cs +++ b/Blackout/HarmonyPatches.cs @@ -14,6 +14,7 @@ internal class HarmonyPatches if (Blackout.inVR != PlayerSetup.Instance._inVr) { BlackoutController.Instance.SetupBlackoutInstance(); + BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); } } } \ No newline at end of file diff --git a/Blackout/Main.cs b/Blackout/Main.cs index 065f1ae..03badb4 100644 --- a/Blackout/Main.cs +++ b/Blackout/Main.cs @@ -1,23 +1,21 @@ using ABI_RC.Core.Player; using MelonLoader; -using UnityEngine; namespace Blackout; public class Blackout : MelonMod { - public const string SettingsCategory = "Blackout"; - internal static bool inVR; - internal static MelonPreferences_Category m_categoryBlackout; - internal static MelonPreferences_Entry m_entryEnabled, m_entryHudMessages, m_entryDropFPSOnSleep; - //internal static MelonPreferences_Entry m_entryVROnly; - internal static MelonPreferences_Entry + internal const string SettingsCategory = "Blackout"; + + private static MelonPreferences_Category m_categoryBlackout; + private static MelonPreferences_Entry m_entryEnabled, m_entryHudMessages, m_entryDropFPSOnSleep; + private static MelonPreferences_Entry m_entryDrowsyThreshold, m_entryAwakeThreshold, m_entryDrowsyModeTimer, m_entrySleepModeTimer, m_entryDrowsyDimStrength; - public override void OnApplicationStart() + public override void OnInitializeMelon() { m_categoryBlackout = MelonPreferences.CreateCategory(nameof(Blackout)); m_entryEnabled = m_categoryBlackout.CreateEntry("Automatic State Change", true, description: "Dim screen when there is no movement for a while."); @@ -28,29 +26,25 @@ public class Blackout : MelonMod m_entryDrowsyModeTimer = m_categoryBlackout.CreateEntry("Enter Drowsy Time", 3f, description: "How many minutes without movement until enter drowsy mode."); m_entrySleepModeTimer = m_categoryBlackout.CreateEntry("Enter Sleep Time", 10f, description: "How many seconds without movement until enter sleep mode."); m_entryDrowsyDimStrength = m_categoryBlackout.CreateEntry("Drowsy Dim Strength", 0.5f, description: "How strong of a dimming effect should drowsy mode have."); - //m_entryVROnly = m_categoryBlackout.CreateEntry("VR Only", false, description: "Only enable mod in VR."); m_categoryBlackout.SaveToFile(false); - //please tell me a better way to do this - //this is fucking - //gross pleas etell me how to do this but not like this - m_entryEnabled.OnValueChangedUntyped += OnEnabled; - m_entryHudMessages.OnValueChangedUntyped += OnUpdateSettings; - m_entryDropFPSOnSleep.OnValueChangedUntyped += OnUpdateSettings; - m_entryDrowsyThreshold.OnValueChangedUntyped += OnUpdateSettings; - m_entryAwakeThreshold.OnValueChangedUntyped += OnUpdateSettings; - m_entryDrowsyModeTimer.OnValueChangedUntyped += OnUpdateSettings; - m_entrySleepModeTimer.OnValueChangedUntyped += OnUpdateSettings; - m_entryDrowsyDimStrength.OnValueChangedUntyped += OnUpdateSettings; - //m_entryVROnly.OnValueChangedUntyped += OnUpdateSettings; - MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer()); + m_entryEnabled.OnEntryValueChangedUntyped.Subscribe(OnUpdateEnabled); + m_entryHudMessages.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + m_entryDropFPSOnSleep.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + m_entryDrowsyThreshold.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + m_entryAwakeThreshold.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + m_entryDrowsyModeTimer.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + m_entrySleepModeTimer.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + m_entryDrowsyDimStrength.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); //UIExpansionKit addon - if (MelonHandler.Mods.Any(it => it.Info.Name == "UI Expansion Kit")) + if (MelonMod.RegisteredMelons.Any(it => it.Info.Name == "UI Expansion Kit")) { MelonLogger.Msg("Initializing UIExpansionKit support."); UiExtensionsAddon.Init(); } + + MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer()); } System.Collections.IEnumerator WaitForLocalPlayer() @@ -65,8 +59,10 @@ public class Blackout : MelonMod PlayerSetup.Instance.gameObject.AddComponent(); //update BlackoutController settings after it initializes - yield return new WaitForEndOfFrame(); - OnUpdateSettings(); + while (BlackoutController.Instance == null) + yield return null; + + UpdateAllSettings(); } private void OnEnabled() @@ -74,20 +70,25 @@ public class Blackout : MelonMod if (!BlackoutController.Instance) return; BlackoutController.Instance.enabled = m_entryEnabled.Value; } - private void OnUpdateSettings() + + private void UpdateAllSettings() { if (!BlackoutController.Instance) return; + BlackoutController.Instance.enabled = m_entryEnabled.Value; + BlackoutController.Instance.HudMessages = m_entryHudMessages.Value; + BlackoutController.Instance.DropFPSOnSleep = m_entryDropFPSOnSleep.Value; BlackoutController.Instance.drowsyThreshold = m_entryDrowsyThreshold.Value; BlackoutController.Instance.wakeThreshold = m_entryAwakeThreshold.Value; BlackoutController.Instance.DrowsyModeTimer = m_entryDrowsyModeTimer.Value; BlackoutController.Instance.SleepModeTimer = m_entrySleepModeTimer.Value; BlackoutController.Instance.DrowsyDimStrength = m_entryDrowsyDimStrength.Value; - BlackoutController.Instance.HudMessages = m_entryHudMessages.Value; - BlackoutController.Instance.DropFPSOnSleep = m_entryDropFPSOnSleep.Value; } + private void OnUpdateEnabled(object arg1, object arg2) => OnEnabled(); + private void OnUpdateSettings(object arg1, object arg2) => UpdateAllSettings(); + //UIExpansionKit actions - public static void AwakeState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); - public static void DrowsyState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Drowsy); - public static void SleepingState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Sleeping); + internal static void AwakeState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); + internal static void DrowsyState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Drowsy); + internal static void SleepingState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Sleeping); } \ No newline at end of file diff --git a/Blackout/Properties/AssemblyInfo.cs b/Blackout/Properties/AssemblyInfo.cs index 728d4a7..a30c5c7 100644 --- a/Blackout/Properties/AssemblyInfo.cs +++ b/Blackout/Properties/AssemblyInfo.cs @@ -25,6 +25,6 @@ using System.Reflection; namespace Blackout.Properties; internal static class AssemblyInfoParams { - public const string Version = "1.0.0"; + public const string Version = "1.0.1"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/Blackout/resources/blackout_controller.asset b/Blackout/resources/blackout_controller.asset index 52e58cc994c225d484455efb230d12097c265d96..8c44df3f5bcd19e8f08b8d5010d7e89ee04057fc 100644 GIT binary patch delta 13699 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 delta 13443 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 From 64ebec25675a29111e266060f8d07f875d869d0f Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Fri, 14 Oct 2022 14:39:43 -0500 Subject: [PATCH 12/19] bruh i forgor log vrmode --- Blackout/HarmonyPatches.cs | 1 + Blackout/format.json | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Blackout/HarmonyPatches.cs b/Blackout/HarmonyPatches.cs index 51f9793..a78b1e9 100644 --- a/Blackout/HarmonyPatches.cs +++ b/Blackout/HarmonyPatches.cs @@ -13,6 +13,7 @@ internal class HarmonyPatches { if (Blackout.inVR != PlayerSetup.Instance._inVr) { + Blackout.inVR = PlayerSetup.Instance._inVr; BlackoutController.Instance.SetupBlackoutInstance(); BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); } diff --git a/Blackout/format.json b/Blackout/format.json index bb2ebe7..e67650f 100644 --- a/Blackout/format.json +++ b/Blackout/format.json @@ -1,9 +1,9 @@ { - "_id": -1, + "_id": 106, "name": "Blackout", - "modversion": "1.0.0", + "modversion": "1.0.1", "gameversion": "2022r168", - "loaderversion": "0.5.4", + "loaderversion": "0.5.5", "modtype": "Mod", "author": "NotAKidoS", "description": "Dim screen after set time of sitting still. Should be nice for VR sleeping.\n\nNotable Options:\n Cap FPS while sleeping.\nManual control via UIX\nConfigurable dimming strength.", @@ -16,8 +16,8 @@ "requirements": [ "None" ], - "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r1/Blackout.dll", + "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r2/Blackout.dll", "sourcelink": "https://github.com/NotAKidOnSteam/Blackout/", - "changelog": "Initial release.", + "changelog": "Update to Melonloader 0.5.5.", "embedcolor": "#161b22" } \ No newline at end of file From 5b52a31b5d9ff830d7011e4b4f55626855f4e666 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Mon, 17 Oct 2022 20:00:40 -0500 Subject: [PATCH 13/19] Fix mirror & shader queue..? --- Blackout/BlackoutController.cs | 21 +++++++++++++++++-- Blackout/resources/blackout_controller.asset | Bin 13708 -> 13702 bytes 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs index c3c1f2e..d4faf30 100644 --- a/Blackout/BlackoutController.cs +++ b/Blackout/BlackoutController.cs @@ -59,6 +59,7 @@ public class BlackoutController : MonoBehaviour Sleeping, } + private GameObject activeModeCam; private Quaternion oldHeadRotation = Quaternion.identity; private float angularMovement = 0f; private float curTime = 0f; @@ -125,7 +126,7 @@ public class BlackoutController : MonoBehaviour nextUpdate = Mathf.FloorToInt(curTime) + 1; //get difference between last frame rotation and current rotation - Quaternion currentHeadRotation = PlayerSetup.Instance.GetActiveCamera().transform.rotation; + Quaternion currentHeadRotation = activeModeCam.transform.rotation; angularMovement = Quaternion.Angle(oldHeadRotation, currentHeadRotation); oldHeadRotation = currentHeadRotation; @@ -150,16 +151,32 @@ public class BlackoutController : MonoBehaviour { curTime = Time.time; lastAwakeTime = curTime; + Camera.onPreRender += OnPreRender; + Camera.onPostRender += OnPostRender; } void OnDisable() { ChangeBlackoutState(BlackoutState.Awake); + Camera.onPreRender -= OnPreRender; + Camera.onPostRender -= OnPostRender; + } + + void OnPreRender(Camera cam) + { + if (cam != activeModeCam.GetComponent()) return; + blackoutAnimator.transform.localScale = Vector3.zero; + } + + void OnPostRender(Camera cam) + { + blackoutAnimator.transform.localScale = Vector3.one; } public void SetupBlackoutInstance() { - blackoutAnimator.transform.parent = PlayerSetup.Instance.GetActiveCamera().transform; + activeModeCam = PlayerSetup.Instance.GetActiveCamera(); + blackoutAnimator.transform.parent = activeModeCam.transform; blackoutAnimator.transform.localPosition = Vector3.zero; blackoutAnimator.transform.localRotation = Quaternion.identity; blackoutAnimator.transform.localScale = Vector3.one; diff --git a/Blackout/resources/blackout_controller.asset b/Blackout/resources/blackout_controller.asset index 8c44df3f5bcd19e8f08b8d5010d7e89ee04057fc..b9205609d495f10eaa239a0df6bb39809e999f1f 100644 GIT binary patch delta 1132 zcmV-y1e5!WYldr(B>{$!CMN*}u}BNSQ_dmbKGN5z`SAGdazt~$Kx4t}a+gR0U3a+Xe}~fi zmg^TEg=+vlLIgT(EQ0nk1imlS=CHPasn4$n)ilO!kU2iTfhQWj4JP=JxP9J(-NnnM z!LTdN*#?Q3?gc`e8ET8o$@xkax4ZE`Tg!GLj0IJyv)AGm$c2wM-v4yCQ4YrhXKtUE zpT{=t|CJenB*@*57)n4w8Oeefe^Wu!gEmmMuPPZ*ZELRLT_hfb0nH4u2w|?PiRAP? zeMiK_Gi|zwGf<2P-&k8EARr zdRN}qWu-#@q64>58oeq^iVs_0OnmtlV1c-iY@{tcexgtqu)4{b+Ol@Ne^gJRs6S_g z-zLQT+*gvVuYk+cn}PdH>vjed z%)(WR69^|ukQU%|$yyOcdZj-7?v)S4H;&ZYuqVz+rPeeBNUsmp8hTb_I%Jss7@j6{ z3O#50n7W!vX3Ei3J5DgE`}XVJCe6(_Ve;%~*A!LOE9O-6$z7*te53Hxi73WV*x-p zb-+_pom!=rR-f}l953dZlT&bjL)tKZ!tZ7aOF$Qr`mBOSSjSh{;9xO4kZQk_A)fdy z$aB1h24yv3=k2IXe}_6RTi|-Y!2Tlpr;R(_bgCMfg4zr8cJihapOPpj?!EZEs8Dx9 zjY1FG1rg7PWGlSqzNhx+7NQjs0I3-v0w~`*fPOZ?tIDv%8KjQVFAi_quFJQ ziu?b(Q=$GzT4jTd@EjtzoS&^W?k&nU$Q=K$?NXTHEbeyi+Yj$jqGq$xk2HRo$shsv yl0NRWx2?<3txbC7W4J^RX!g{AUMP}V3UE2`b&9S;Mlo|Xx{|)CMN+4u}k3!Sk^ zKV6T(L=6QGMxECvxBamcC!%sjM|%6s%}IpB_}AI! zW(~bt)N@eaFFcWxf+%viT4SA$f3r&<)+mG@Kd#(rpM_|{rT-ar9-(uNte&sxpjK)a zKJw%Z=99@FMt=#cknQ(FPSLq#catte@-VE8cqNf5u5^{ zt~x>IkfF)_^df0Lg^}L9NN=UHJzkrNqG6Z~DMI?~s3!&hv>Ez8u2QlaY#cD5wtK$* zwIeV9R~3?o-I5(OT`-v73_7s&#@rpNTn9u4nG*zU#xYw7$nmbmmvlp4s;%Z6c7K`F zzy{nrt@RFcFNRkee=Z#&Yjxg{?fSxYdnGPwZAp6+lrUumcr1ZDWQ`!zK~Ncr2xZ3n z)ygCe4o_(lmGWZ`?A}})dxgTqKtKfzDYY6j@$vjqp(de}mrTb9Um-a{bYKxSY4f7OZ!%UnYN1?_$yIIu~^q{U1J0Uxq$;Vc?n2)x%fnAWh6tYT2Z4|MIYI EF$hL2@&Et; From d2bcf619d83b613c13c14c761405f8fbfcee907c Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Mon, 17 Oct 2022 23:01:19 -0500 Subject: [PATCH 14/19] fix shader queue of sleep mode. shader queue was -1000...? but now matches dimmer mode at 4000. --- Blackout/resources/blackout_controller.asset | Bin 13702 -> 13708 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Blackout/resources/blackout_controller.asset b/Blackout/resources/blackout_controller.asset index b9205609d495f10eaa239a0df6bb39809e999f1f..415a7d810fb570397855558d26eebe49c28960a0 100644 GIT binary patch delta 95 zcmV-l0HFVdYm94{|)CMN+4u}<+cO@8qV5sx6c;lXGQ7p8wx&F|5Ry6Nqi BEhGQ{ delta 89 zcmV-f0H*(pYldr(B>{$!CMN*}u}<+cN9|IW;ww;E vwYROy(XCB-=3}@-5NP()fLL`E@lHo8N%u|-h-(ALP@r3o#2 From f789182d4f49ea30adff4b64c53859182fd90fa5 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 18 Oct 2022 21:37:59 -0500 Subject: [PATCH 15/19] bump --- Blackout/Properties/AssemblyInfo.cs | 2 +- Blackout/format.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Blackout/Properties/AssemblyInfo.cs b/Blackout/Properties/AssemblyInfo.cs index a30c5c7..6757bc4 100644 --- a/Blackout/Properties/AssemblyInfo.cs +++ b/Blackout/Properties/AssemblyInfo.cs @@ -25,6 +25,6 @@ using System.Reflection; namespace Blackout.Properties; internal static class AssemblyInfoParams { - public const string Version = "1.0.1"; + public const string Version = "1.0.2"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/Blackout/format.json b/Blackout/format.json index e67650f..464b644 100644 --- a/Blackout/format.json +++ b/Blackout/format.json @@ -1,8 +1,8 @@ { "_id": 106, "name": "Blackout", - "modversion": "1.0.1", - "gameversion": "2022r168", + "modversion": "1.0.2", + "gameversion": "2022r169p1", "loaderversion": "0.5.5", "modtype": "Mod", "author": "NotAKidoS", @@ -16,8 +16,8 @@ "requirements": [ "None" ], - "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r2/Blackout.dll", + "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r3/Blackout.dll", "sourcelink": "https://github.com/NotAKidOnSteam/Blackout/", - "changelog": "Update to Melonloader 0.5.5.", + "changelog": "Fix render queue of sleep mode. Made effect 2x bigger to accommodate extreme FOV & avatar scale. Attempt to render only in active camera.", "embedcolor": "#161b22" } \ No newline at end of file From 2b4f306040587b511075f1842434c006c93f0956 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 25 Oct 2022 15:57:27 -0500 Subject: [PATCH 16/19] Fix PreRender --- Blackout/BlackoutController.cs | 14 +++++++------- Blackout/Main.cs | 4 ++-- Blackout/Properties/AssemblyInfo.cs | 2 +- Blackout/format.json | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs index d4faf30..150afd3 100644 --- a/Blackout/BlackoutController.cs +++ b/Blackout/BlackoutController.cs @@ -59,7 +59,7 @@ public class BlackoutController : MonoBehaviour Sleeping, } - private GameObject activeModeCam; + private Camera activeModeCam; private Quaternion oldHeadRotation = Quaternion.identity; private float angularMovement = 0f; private float curTime = 0f; @@ -114,6 +114,10 @@ public class BlackoutController : MonoBehaviour blackoutGO.name = "BlackoutInstance"; blackoutAnimator = blackoutGO.GetComponent(); SetupBlackoutInstance(); + + //we dont want this to ever disable (unless in awake state maybe? + Camera.onPreRender += OnPreRender; + Camera.onPostRender += OnPostRender; } //Automatic State Change @@ -151,20 +155,16 @@ public class BlackoutController : MonoBehaviour { curTime = Time.time; lastAwakeTime = curTime; - Camera.onPreRender += OnPreRender; - Camera.onPostRender += OnPostRender; } void OnDisable() { ChangeBlackoutState(BlackoutState.Awake); - Camera.onPreRender -= OnPreRender; - Camera.onPostRender -= OnPostRender; } void OnPreRender(Camera cam) { - if (cam != activeModeCam.GetComponent()) return; + if (cam == activeModeCam) return; blackoutAnimator.transform.localScale = Vector3.zero; } @@ -175,7 +175,7 @@ public class BlackoutController : MonoBehaviour public void SetupBlackoutInstance() { - activeModeCam = PlayerSetup.Instance.GetActiveCamera(); + activeModeCam = PlayerSetup.Instance.GetActiveCamera().GetComponent(); blackoutAnimator.transform.parent = activeModeCam.transform; blackoutAnimator.transform.localPosition = Vector3.zero; blackoutAnimator.transform.localRotation = Quaternion.identity; diff --git a/Blackout/Main.cs b/Blackout/Main.cs index 03badb4..e1ac4a4 100644 --- a/Blackout/Main.cs +++ b/Blackout/Main.cs @@ -23,8 +23,8 @@ public class Blackout : MelonMod m_entryDropFPSOnSleep = m_categoryBlackout.CreateEntry("Lower FPS While Sleep", false, description: "Lowers FPS to 5 while in Sleep State."); 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_entryDrowsyModeTimer = m_categoryBlackout.CreateEntry("Enter Drowsy Time", 3f, description: "How many minutes without movement until enter drowsy mode."); - m_entrySleepModeTimer = m_categoryBlackout.CreateEntry("Enter Sleep Time", 10f, description: "How many seconds without movement until enter sleep mode."); + m_entryDrowsyModeTimer = m_categoryBlackout.CreateEntry("Enter Drowsy Time (Minutes)", 3f, description: "How many minutes without movement until enter drowsy mode."); + m_entrySleepModeTimer = m_categoryBlackout.CreateEntry("Enter Sleep Time (Seconds)", 10f, description: "How many seconds without movement until enter sleep mode."); m_entryDrowsyDimStrength = m_categoryBlackout.CreateEntry("Drowsy Dim Strength", 0.5f, description: "How strong of a dimming effect should drowsy mode have."); m_categoryBlackout.SaveToFile(false); diff --git a/Blackout/Properties/AssemblyInfo.cs b/Blackout/Properties/AssemblyInfo.cs index 6757bc4..f50fc51 100644 --- a/Blackout/Properties/AssemblyInfo.cs +++ b/Blackout/Properties/AssemblyInfo.cs @@ -25,6 +25,6 @@ using System.Reflection; namespace Blackout.Properties; internal static class AssemblyInfoParams { - public const string Version = "1.0.2"; + public const string Version = "1.0.3"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/Blackout/format.json b/Blackout/format.json index 464b644..0455ec4 100644 --- a/Blackout/format.json +++ b/Blackout/format.json @@ -1,7 +1,7 @@ { "_id": 106, "name": "Blackout", - "modversion": "1.0.2", + "modversion": "1.0.3", "gameversion": "2022r169p1", "loaderversion": "0.5.5", "modtype": "Mod", @@ -16,8 +16,8 @@ "requirements": [ "None" ], - "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r3/Blackout.dll", + "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r4/Blackout.dll", "sourcelink": "https://github.com/NotAKidOnSteam/Blackout/", - "changelog": "Fix render queue of sleep mode. Made effect 2x bigger to accommodate extreme FOV & avatar scale. Attempt to render only in active camera.", + "changelog": "Fixed rendering in every camera other than player camera. Should now behave in both automatic and manual modes.", "embedcolor": "#161b22" } \ No newline at end of file From 24d8c6a3eced1c663a6ff054756ad558e44170b0 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Tue, 22 Nov 2022 18:21:38 -0600 Subject: [PATCH 17/19] Tweak for latest experimental. Replaced PlayerSetup _inVr check. --- Blackout/HarmonyPatches.cs | 7 +++++-- Blackout/Main.cs | 15 ++++++--------- Blackout/Properties/AssemblyInfo.cs | 2 +- Blackout/format.json | 10 +++++----- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Blackout/HarmonyPatches.cs b/Blackout/HarmonyPatches.cs index a78b1e9..1387e9e 100644 --- a/Blackout/HarmonyPatches.cs +++ b/Blackout/HarmonyPatches.cs @@ -1,5 +1,7 @@ using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; using HarmonyLib; +using MelonLoader; namespace Blackout; @@ -11,9 +13,10 @@ internal class HarmonyPatches [HarmonyPatch(typeof(PlayerSetup), "CalibrateAvatar")] private static void CheckVRModeOnSwitch() { - if (Blackout.inVR != PlayerSetup.Instance._inVr) + if (Blackout.inVR != MetaPort.Instance.isUsingVr) { - Blackout.inVR = PlayerSetup.Instance._inVr; + MelonLogger.Msg("VRMode change detected! Reinitializing Blackout Instance..."); + Blackout.inVR = MetaPort.Instance.isUsingVr; BlackoutController.Instance.SetupBlackoutInstance(); BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); } diff --git a/Blackout/Main.cs b/Blackout/Main.cs index e1ac4a4..b4926a3 100644 --- a/Blackout/Main.cs +++ b/Blackout/Main.cs @@ -1,4 +1,5 @@ using ABI_RC.Core.Player; +using ABI_RC.Core.Savior; using MelonLoader; namespace Blackout; @@ -28,14 +29,10 @@ public class Blackout : MelonMod m_entryDrowsyDimStrength = m_categoryBlackout.CreateEntry("Drowsy Dim Strength", 0.5f, description: "How strong of a dimming effect should drowsy mode have."); m_categoryBlackout.SaveToFile(false); - m_entryEnabled.OnEntryValueChangedUntyped.Subscribe(OnUpdateEnabled); - m_entryHudMessages.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); - m_entryDropFPSOnSleep.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); - m_entryDrowsyThreshold.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); - m_entryAwakeThreshold.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); - m_entryDrowsyModeTimer.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); - m_entrySleepModeTimer.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); - m_entryDrowsyDimStrength.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + foreach (var setting in m_categoryBlackout.Entries) + { + setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + } //UIExpansionKit addon if (MelonMod.RegisteredMelons.Any(it => it.Info.Name == "UI Expansion Kit")) @@ -55,7 +52,7 @@ public class Blackout : MelonMod while (PlayerSetup.Instance == null) yield return null; - inVR = PlayerSetup.Instance._inVr; + inVR = MetaPort.Instance.isUsingVr; PlayerSetup.Instance.gameObject.AddComponent(); //update BlackoutController settings after it initializes diff --git a/Blackout/Properties/AssemblyInfo.cs b/Blackout/Properties/AssemblyInfo.cs index f50fc51..c79bb81 100644 --- a/Blackout/Properties/AssemblyInfo.cs +++ b/Blackout/Properties/AssemblyInfo.cs @@ -25,6 +25,6 @@ using System.Reflection; namespace Blackout.Properties; internal static class AssemblyInfoParams { - public const string Version = "1.0.3"; + public const string Version = "1.0.4"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/Blackout/format.json b/Blackout/format.json index 0455ec4..eb09686 100644 --- a/Blackout/format.json +++ b/Blackout/format.json @@ -1,9 +1,9 @@ { "_id": 106, "name": "Blackout", - "modversion": "1.0.3", - "gameversion": "2022r169p1", - "loaderversion": "0.5.5", + "modversion": "1.0.4", + "gameversion": "2022r169", + "loaderversion": "0.5.7", "modtype": "Mod", "author": "NotAKidoS", "description": "Dim screen after set time of sitting still. Should be nice for VR sleeping.\n\nNotable Options:\n Cap FPS while sleeping.\nManual control via UIX\nConfigurable dimming strength.", @@ -16,8 +16,8 @@ "requirements": [ "None" ], - "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r4/Blackout.dll", + "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r5/Blackout.dll", "sourcelink": "https://github.com/NotAKidOnSteam/Blackout/", - "changelog": "Fixed rendering in every camera other than player camera. Should now behave in both automatic and manual modes.", + "changelog": "Small tweak to fix VRMode change detection with latest experimental.", "embedcolor": "#161b22" } \ No newline at end of file From 65d325d4fd9d77ce5f5fdbab56dee1f43f0e210d Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 2 Feb 2023 13:02:41 -0600 Subject: [PATCH 18/19] bump --- Blackout/AssetHandler.cs | 2 +- Blackout/Blackout.csproj | 3 + Blackout/BlackoutController.cs | 180 +++++++++++++------ Blackout/HarmonyPatches.cs | 2 +- Blackout/Integrations/BTKUIAddon.cs | 63 +++++++ Blackout/Integrations/UIExpansionKitAddon.cs | 29 +++ Blackout/Main.cs | 62 ++++--- Blackout/Properties/AssemblyInfo.cs | 15 +- Blackout/Resource1.Designer.cs | 2 +- Blackout/UIExpansionKitAddon.cs | 15 -- Blackout/format.json | 13 +- 11 files changed, 277 insertions(+), 109 deletions(-) create mode 100644 Blackout/Integrations/BTKUIAddon.cs create mode 100644 Blackout/Integrations/UIExpansionKitAddon.cs delete mode 100644 Blackout/UIExpansionKitAddon.cs diff --git a/Blackout/AssetHandler.cs b/Blackout/AssetHandler.cs index 7d213ee..db52492 100644 --- a/Blackout/AssetHandler.cs +++ b/Blackout/AssetHandler.cs @@ -1,7 +1,7 @@ using System.Reflection; using UnityEngine; -namespace Blackout; +namespace NAK.Melons.Blackout; /* diff --git a/Blackout/Blackout.csproj b/Blackout/Blackout.csproj index 60c5870..52398a9 100644 --- a/Blackout/Blackout.csproj +++ b/Blackout/Blackout.csproj @@ -26,6 +26,9 @@ ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll + + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\BTKUILib.dll + ..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll diff --git a/Blackout/BlackoutController.cs b/Blackout/BlackoutController.cs index 150afd3..790024c 100644 --- a/Blackout/BlackoutController.cs +++ b/Blackout/BlackoutController.cs @@ -5,7 +5,7 @@ using MelonLoader; using System.Text; using UnityEngine; -namespace Blackout; +namespace NAK.Melons.Blackout; /* @@ -30,28 +30,37 @@ namespace Blackout; public class BlackoutController : MonoBehaviour { public static BlackoutController Instance; - + + // The current state of the player's consciousness. public BlackoutState CurrentState = BlackoutState.Awake; - //degrees of movement to give partial vision - public float drowsyThreshold = 1f; - //degrees of movement to give complete vision - public float wakeThreshold = 12f; + // Should the states automatically change based on time? + public bool AutomaticStateChange = true; + // Should the sleep state be automatically transitioned to? Some may prefer drowsy state only due to dimming. + public bool AutoSleepState = true; - //how long without movement until the screen dims - public float DrowsyModeTimer = 3f; // MINUTES - //how long should the wake state last before return - public float SleepModeTimer = 10f; // SECONDS + // The minimum amount of movement required to partially restore vision. + public float drowsyThreshold = 2f; + // The minimum amount of movement required to fully restore vision. + public float wakeThreshold = 4f; - //how much does DrowsyMode affect the screen - public float DrowsyDimStrength = 0.5f; + // The amount of time the player must remain still to enter drowsy state (in minutes). + public float DrowsyModeTimer = 3f; + // The amount of time the player must remain in drowsy state before entering sleep state (in seconds). + public float SleepModeTimer = 10f; - //this is uh, not work well- might rewrite now that i know how this should work - public bool HudMessages = false; + // The amount by which DrowsyMode affects the screen. + public float DrowsyDimStrength = 0.6f; + // Should DrowsyDimStrength be affected by velocity? + public bool DrowsyVelocityMultiplier = true; - //lower FPS while in sleep mode + // Whether to display HUD messages. + public bool HudMessages = true; + + // Whether to lower the frame rate while in sleep mode. public bool DropFPSOnSleep = false; + // The available states of consciousness. public enum BlackoutState { Awake = 0, @@ -60,14 +69,16 @@ public class BlackoutController : MonoBehaviour } private Camera activeModeCam; - private Quaternion oldHeadRotation = Quaternion.identity; - private float angularMovement = 0f; + private Vector3 headVelocity = Vector3.zero; + private Vector3 lastHeadPos = Vector3.zero; private float curTime = 0f; private float lastAwakeTime = 0f; - private int nextUpdate = 1; private Animator blackoutAnimator; private int targetFPS; + public void ChangeBlackoutStateFromInt(int state) => ChangeBlackoutState((BlackoutState)state); + + // Changes the player's state of consciousness. public void ChangeBlackoutState(BlackoutState newState) { if (!blackoutAnimator) return; @@ -75,47 +86,61 @@ public class BlackoutController : MonoBehaviour lastAwakeTime = curTime; + // Update the blackout animator based on the new state. switch (newState) { case BlackoutState.Awake: blackoutAnimator.SetBool("BlackoutState.Drowsy", false); blackoutAnimator.SetBool("BlackoutState.Sleeping", false); - blackoutAnimator.SetFloat("BlackoutSetting.DrowsyStrength", DrowsyDimStrength); + drowsyMagnitude = 0f; break; case BlackoutState.Drowsy: blackoutAnimator.SetBool("BlackoutState.Drowsy", true); blackoutAnimator.SetBool("BlackoutState.Sleeping", false); - blackoutAnimator.SetFloat("BlackoutSetting.DrowsyStrength", DrowsyDimStrength); + drowsyMagnitude = 0f; break; case BlackoutState.Sleeping: blackoutAnimator.SetBool("BlackoutState.Drowsy", false); blackoutAnimator.SetBool("BlackoutState.Sleeping", true); - blackoutAnimator.SetFloat("BlackoutSetting.DrowsyStrength", DrowsyDimStrength); + drowsyMagnitude = 1f; break; default: break; } + + // Update the current state and send a HUD message if enabled. BlackoutState prevState = CurrentState; CurrentState = newState; SendHUDMessage($"Exiting {prevState} and entering {newState} state."); ChangeTargetFPS(); } - //initialize BlackoutInstance object + public void AdjustDrowsyDimStrength(float multiplier = 1f) + { + blackoutAnimator.SetFloat("BlackoutSetting.DrowsyStrength", DrowsyDimStrength * multiplier); + } + + // Initialize the BlackoutInstance object. void Start() { Instance = this; + // Get the blackout asset and instantiate it. GameObject blackoutAsset = AssetsHandler.GetAsset("Assets/BundledAssets/Blackout/Blackout.prefab"); GameObject blackoutGO = Instantiate(blackoutAsset, new Vector3(0, 0, 0), Quaternion.identity); - - if (blackoutGO == null) return; - blackoutGO.name = "BlackoutInstance"; + + // Get the blackout animator component. blackoutAnimator = blackoutGO.GetComponent(); + if (!blackoutAnimator) + { + MelonLogger.Error("Blackout: Could not find blackout animator component!"); + return; + } + SetupBlackoutInstance(); - //we dont want this to ever disable (unless in awake state maybe? + //we dont want this to ever disable Camera.onPreRender += OnPreRender; Camera.onPostRender += OnPostRender; } @@ -123,41 +148,45 @@ public class BlackoutController : MonoBehaviour //Automatic State Change void Update() { - //only run once a second, angularMovement is "smoothed out" at high FPS otherwise - //for the sake of responsivness while user is in a sleepy state, this might be removed to prevent confusion... - curTime = Time.time; - if (!(curTime >= nextUpdate)) return; - nextUpdate = Mathf.FloorToInt(curTime) + 1; + //get the current position of the player's head + Vector3 curHeadPos = activeModeCam.transform.position; + //calculate the player's head velocity by taking the difference in position + headVelocity = (curHeadPos - lastHeadPos) / Time.deltaTime; + //store the current head position for use in the next frame + lastHeadPos = curHeadPos; - //get difference between last frame rotation and current rotation - Quaternion currentHeadRotation = activeModeCam.transform.rotation; - angularMovement = Quaternion.Angle(oldHeadRotation, currentHeadRotation); - oldHeadRotation = currentHeadRotation; - - //handle current state - switch (CurrentState) + if (AutomaticStateChange) { - case BlackoutState.Awake: - HandleAwakeState(); - break; - case BlackoutState.Drowsy: - HandleDrowsyState(); - break; - case BlackoutState.Sleeping: - HandleSleepingState(); - break; - default: - break; + curTime = Time.time; + //handle current state + switch (CurrentState) + { + case BlackoutState.Awake: + HandleAwakeState(); + break; + case BlackoutState.Drowsy: + HandleDrowsyState(); + break; + case BlackoutState.Sleeping: + HandleSleepingState(); + break; + default: + break; + } + } + else + { + CalculateDimmingMultiplier(); } } - void OnEnable() + public void OnEnable() { curTime = Time.time; lastAwakeTime = curTime; } - void OnDisable() + public void OnDisable() { ChangeBlackoutState(BlackoutState.Awake); } @@ -204,8 +233,17 @@ public class BlackoutController : MonoBehaviour if (!CohtmlHud.Instance || !HudMessages) return; StringBuilder secondmessage = new StringBuilder(); - if (enabled) - secondmessage = new StringBuilder(GetNextStateTimer().ToString() + " seconds till next state change."); + if (AutomaticStateChange) + { + if (CurrentState == BlackoutState.Drowsy && !AutoSleepState) + { + secondmessage = new StringBuilder("AutoSleepState is disabled. Staying in Drowsy State."); + } + else + { + secondmessage = new StringBuilder(GetNextStateTimer().ToString() + " seconds till next state change."); + } + } CohtmlHud.Instance.ViewDropTextImmediate("Blackout", message, secondmessage.ToString()); } @@ -223,7 +261,7 @@ public class BlackoutController : MonoBehaviour private void HandleAwakeState() { //small movement should reset sleep timer - if (angularMovement > drowsyThreshold) + if (headVelocity.magnitude > drowsyThreshold) { lastAwakeTime = curTime; } @@ -233,23 +271,51 @@ public class BlackoutController : MonoBehaviour ChangeBlackoutState(BlackoutState.Drowsy); } } + + public float fadeSpeed = 0.8f; // The speed at which the value fades back to 0 or increases + public float minimumThreshold = 0.5f; // The minimum value that the drowsy magnitude can have + public float drowsyMagnitude = 0f; + + private void CalculateDimmingMultiplier() + { + if (!DrowsyVelocityMultiplier) + { + AdjustDrowsyDimStrength(); + return; + } + + float normalizedMagnitude = headVelocity.magnitude / wakeThreshold; + float targetMagnitude = 1f - normalizedMagnitude; + targetMagnitude = Mathf.Max(targetMagnitude, minimumThreshold); + drowsyMagnitude = Mathf.Lerp(drowsyMagnitude, targetMagnitude, fadeSpeed * Time.deltaTime); + AdjustDrowsyDimStrength(drowsyMagnitude); + } + private void HandleDrowsyState() { //hard movement should exit drowsy state - if (angularMovement > wakeThreshold) + if (headVelocity.magnitude > wakeThreshold) { ChangeBlackoutState(BlackoutState.Awake); + return; + } + //small movement should reset sleep timer + if (headVelocity.magnitude > drowsyThreshold) + { + lastAwakeTime = curTime; } //enter full sleep mode - if (curTime > lastAwakeTime + SleepModeTimer) + if (AutoSleepState && curTime > lastAwakeTime + SleepModeTimer) { ChangeBlackoutState(BlackoutState.Sleeping); } + CalculateDimmingMultiplier(); } + private void HandleSleepingState() { //small movement should enter drowsy state - if (angularMovement > drowsyThreshold) + if (headVelocity.magnitude > drowsyThreshold) { ChangeBlackoutState(BlackoutState.Drowsy); } diff --git a/Blackout/HarmonyPatches.cs b/Blackout/HarmonyPatches.cs index 1387e9e..eb53c70 100644 --- a/Blackout/HarmonyPatches.cs +++ b/Blackout/HarmonyPatches.cs @@ -3,7 +3,7 @@ using ABI_RC.Core.Savior; using HarmonyLib; using MelonLoader; -namespace Blackout; +namespace NAK.Melons.Blackout.HarmonyPatches; [HarmonyPatch] internal class HarmonyPatches diff --git a/Blackout/Integrations/BTKUIAddon.cs b/Blackout/Integrations/BTKUIAddon.cs new file mode 100644 index 0000000..e0fb660 --- /dev/null +++ b/Blackout/Integrations/BTKUIAddon.cs @@ -0,0 +1,63 @@ +using BTKUILib; +using BTKUILib.UIObjects; +using System.Runtime.CompilerServices; + +namespace NAK.Melons.Blackout; + +public static class BTKUIAddon +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Init() + { + //Add myself to the Misc Menu + Page miscPage = QuickMenuAPI.MiscTabPage; + Category miscCategory = miscPage.AddCategory(Blackout.SettingsCategory); + + AddMelonToggle(ref miscCategory, Blackout.m_entryEnabled); + + //Add my own page to not clog up Misc Menu + + Page blackoutPage = miscCategory.AddPage("Blackout Settings", "", "Configure the settings for Blackout.", "Blackout"); + blackoutPage.MenuTitle = "Blackout Settings"; + blackoutPage.MenuSubtitle = "Dim screen after set time of sitting still, or configure with manual control. Should be nice for VR sleeping."; + + Category blackoutCategory = blackoutPage.AddCategory("Blackout"); + + AddMelonToggle(ref blackoutCategory, Blackout.m_entryEnabled); + + //manual state changing + var state_Awake = blackoutCategory.AddButton("Awake State", null, "Enter the Awake State."); + state_Awake.OnPress += () => BlackoutController.Instance?.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); + var state_Drowsy = blackoutCategory.AddButton("Drowsy State", null, "Enter the Drowsy State."); + state_Drowsy.OnPress += () => BlackoutController.Instance?.ChangeBlackoutState(BlackoutController.BlackoutState.Drowsy); + var state_Sleeping = blackoutCategory.AddButton("Sleeping State", null, "Enter the Sleeping State."); + state_Sleeping.OnPress += () => BlackoutController.Instance?.ChangeBlackoutState(BlackoutController.BlackoutState.Sleeping); + + //dimming strength + AddMelonSlider(ref blackoutPage, Blackout.m_entryDrowsyDimStrength, 0f, 1f); + + //velocity dim multiplier + AddMelonToggle(ref blackoutCategory, Blackout.m_entryDrowsyVelocityMultiplier); + + //hud messages + AddMelonToggle(ref blackoutCategory, Blackout.m_entryHudMessages); + + //lower fps while sleep (desktop) + AddMelonToggle(ref blackoutCategory, Blackout.m_entryDropFPSOnSleep); + + //auto sleep state + AddMelonToggle(ref blackoutCategory, Blackout.m_entryAutoSleepState); + + //i will add the rest of the settings once BTKUILib supports int input + } + + private static void AddMelonToggle(ref Category category, MelonLoader.MelonPreferences_Entry entry) + { + category.AddToggle(entry.DisplayName, entry.Description, entry.Value).OnValueUpdated += b => entry.Value = b; + } + + private static void AddMelonSlider(ref Page page, MelonLoader.MelonPreferences_Entry entry, float min, float max) + { + page.AddSlider(entry.DisplayName, entry.Description, entry.Value, min, max).OnValueUpdated += f => entry.Value = f; + } +} \ No newline at end of file diff --git a/Blackout/Integrations/UIExpansionKitAddon.cs b/Blackout/Integrations/UIExpansionKitAddon.cs new file mode 100644 index 0000000..3e6a4a6 --- /dev/null +++ b/Blackout/Integrations/UIExpansionKitAddon.cs @@ -0,0 +1,29 @@ +using System.Runtime.CompilerServices; +using UIExpansionKit.API; + +namespace NAK.Melons.Blackout; +public static class UIExpansionKitAddon +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Init() + { + /** + ive spent hours debugging this, and no matter what the buttons wont actually call the actions + from logging shit to straight up closing the game, nothing + + implementing btkuilib support, but gonna leave this shit as a reminder why to not use uiexpansionkit + also because it **used to work**... a game update broke it and uiexpansionkit hasnt updated since + + what pisses me off more, is that DesktopVRSwitch works, and that was originally copied from Blackout -_- + https://github.com/NotAKidOnSteam/DesktopVRSwitch/blob/main/DesktopVRSwitch/UIExpansionKitAddon.cs + **/ + var settings = ExpansionKitApi.GetSettingsCategory(Blackout.SettingsCategory); + settings.AddSimpleButton("Awake State", AwakeState); + settings.AddSimpleButton("Drowsy State", DrowsyState); + settings.AddSimpleButton("Sleep State", SleepingState); + } + //UIExpansionKit actions + internal static void AwakeState() => BlackoutController.Instance?.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); + internal static void DrowsyState() => BlackoutController.Instance?.ChangeBlackoutState(BlackoutController.BlackoutState.Drowsy); + internal static void SleepingState() => BlackoutController.Instance?.ChangeBlackoutState(BlackoutController.BlackoutState.Sleeping); +} \ No newline at end of file diff --git a/Blackout/Main.cs b/Blackout/Main.cs index b4926a3..fbc473b 100644 --- a/Blackout/Main.cs +++ b/Blackout/Main.cs @@ -2,43 +2,58 @@ using ABI_RC.Core.Savior; using MelonLoader; -namespace Blackout; +namespace NAK.Melons.Blackout; public class Blackout : MelonMod { internal static bool inVR; internal const string SettingsCategory = "Blackout"; - private static MelonPreferences_Category m_categoryBlackout; - private static MelonPreferences_Entry m_entryEnabled, m_entryHudMessages, m_entryDropFPSOnSleep; - private static MelonPreferences_Entry + internal static MelonPreferences_Category m_categoryBlackout; + internal static MelonPreferences_Entry + m_entryEnabled, + m_entryAutoSleepState, + m_entryHudMessages, + m_entryDropFPSOnSleep, + m_entryDrowsyVelocityMultiplier; + internal static MelonPreferences_Entry m_entryDrowsyThreshold, m_entryAwakeThreshold, m_entryDrowsyModeTimer, m_entrySleepModeTimer, m_entryDrowsyDimStrength; public override void OnInitializeMelon() { - m_categoryBlackout = MelonPreferences.CreateCategory(nameof(Blackout)); - m_entryEnabled = m_categoryBlackout.CreateEntry("Automatic State Change", true, description: "Dim screen when there is no movement for a while."); - m_entryHudMessages = m_categoryBlackout.CreateEntry("Hud Messages", false, description: "Notify on state change."); - m_entryDropFPSOnSleep = m_categoryBlackout.CreateEntry("Lower FPS While Sleep", false, description: "Lowers FPS to 5 while in Sleep State."); - 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_categoryBlackout = MelonPreferences.CreateCategory(SettingsCategory); + m_entryEnabled = m_categoryBlackout.CreateEntry("Automatic State Change", true, description: "Should the screen automatically dim if head is still for enough time?"); + m_entryEnabled.OnEntryValueChangedUntyped.Subscribe(OnUpdateEnabled); + m_entryHudMessages = m_categoryBlackout.CreateEntry("Hud Messages", true, description: "Notify on state change."); + m_entryDropFPSOnSleep = m_categoryBlackout.CreateEntry("Limit FPS While Sleep", false, description: "Limits FPS to 5 while in Sleep State. This only works in Desktop, as SteamVR/HMD handles VR FPS."); + m_entryDrowsyVelocityMultiplier = m_categoryBlackout.CreateEntry("Drowsy Velocity Multiplier", true, description: "Should head velocity act as a multiplier to Drowsy Dim Strength?"); + m_entryAutoSleepState = m_categoryBlackout.CreateEntry("Auto Sleep State", true, description: "Should the sleep state be used during Automatic State Change?"); + m_entryDrowsyThreshold = m_categoryBlackout.CreateEntry("Drowsy Threshold", 2f, description: "Velocity to return partial vision."); + m_entryAwakeThreshold = m_categoryBlackout.CreateEntry("Awake Threshold", 4f, description: "Velocity to return full vision."); m_entryDrowsyModeTimer = m_categoryBlackout.CreateEntry("Enter Drowsy Time (Minutes)", 3f, description: "How many minutes without movement until enter drowsy mode."); m_entrySleepModeTimer = m_categoryBlackout.CreateEntry("Enter Sleep Time (Seconds)", 10f, description: "How many seconds without movement until enter sleep mode."); - m_entryDrowsyDimStrength = m_categoryBlackout.CreateEntry("Drowsy Dim Strength", 0.5f, description: "How strong of a dimming effect should drowsy mode have."); - m_categoryBlackout.SaveToFile(false); + m_entryDrowsyDimStrength = m_categoryBlackout.CreateEntry("Drowsy Dim Strength", 0.6f, description: "How strong of a dimming effect should drowsy mode have."); foreach (var setting in m_categoryBlackout.Entries) { - setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); + if (!setting.OnEntryValueChangedUntyped.GetSubscribers().Any()) + setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings); } //UIExpansionKit addon if (MelonMod.RegisteredMelons.Any(it => it.Info.Name == "UI Expansion Kit")) { MelonLogger.Msg("Initializing UIExpansionKit support."); - UiExtensionsAddon.Init(); + UIExpansionKitAddon.Init(); + } + + //BTKUILib addon + if (MelonMod.RegisteredMelons.Any(it => it.Info.Name == "BTKUILib")) + { + MelonLogger.Msg("Initializing BTKUILib support."); + BTKUIAddon.Init(); } MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer()); @@ -60,32 +75,37 @@ public class Blackout : MelonMod yield return null; UpdateAllSettings(); + OnEnabled(); } private void OnEnabled() { if (!BlackoutController.Instance) return; - BlackoutController.Instance.enabled = m_entryEnabled.Value; + if (m_entryEnabled.Value) + { + BlackoutController.Instance.OnEnable(); + } + else + { + BlackoutController.Instance.OnDisable(); + } + BlackoutController.Instance.AutomaticStateChange = m_entryEnabled.Value; } private void UpdateAllSettings() { if (!BlackoutController.Instance) return; - BlackoutController.Instance.enabled = m_entryEnabled.Value; BlackoutController.Instance.HudMessages = m_entryHudMessages.Value; + BlackoutController.Instance.AutoSleepState = m_entryAutoSleepState.Value; BlackoutController.Instance.DropFPSOnSleep = m_entryDropFPSOnSleep.Value; BlackoutController.Instance.drowsyThreshold = m_entryDrowsyThreshold.Value; BlackoutController.Instance.wakeThreshold = m_entryAwakeThreshold.Value; BlackoutController.Instance.DrowsyModeTimer = m_entryDrowsyModeTimer.Value; BlackoutController.Instance.SleepModeTimer = m_entrySleepModeTimer.Value; BlackoutController.Instance.DrowsyDimStrength = m_entryDrowsyDimStrength.Value; + BlackoutController.Instance.DrowsyVelocityMultiplier = m_entryDrowsyVelocityMultiplier.Value; } private void OnUpdateEnabled(object arg1, object arg2) => OnEnabled(); private void OnUpdateSettings(object arg1, object arg2) => UpdateAllSettings(); - - //UIExpansionKit actions - internal static void AwakeState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Awake); - internal static void DrowsyState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Drowsy); - internal static void SleepingState() => BlackoutController.Instance.ChangeBlackoutState(BlackoutController.BlackoutState.Sleeping); } \ No newline at end of file diff --git a/Blackout/Properties/AssemblyInfo.cs b/Blackout/Properties/AssemblyInfo.cs index c79bb81..e69e1a5 100644 --- a/Blackout/Properties/AssemblyInfo.cs +++ b/Blackout/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using Blackout.Properties; +using NAK.Melons.Blackout.Properties; using MelonLoader; using System.Reflection; @@ -6,13 +6,13 @@ using System.Reflection; [assembly: AssemblyVersion(AssemblyInfoParams.Version)] [assembly: AssemblyFileVersion(AssemblyInfoParams.Version)] [assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)] -[assembly: AssemblyTitle(nameof(Blackout))] +[assembly: AssemblyTitle(nameof(NAK.Melons.Blackout))] [assembly: AssemblyCompany(AssemblyInfoParams.Author)] -[assembly: AssemblyProduct(nameof(Blackout))] +[assembly: AssemblyProduct(nameof(NAK.Melons.Blackout))] [assembly: MelonInfo( - typeof(Blackout.Blackout), - nameof(Blackout), + typeof(NAK.Melons.Blackout.Blackout), + nameof(NAK.Melons.Blackout), AssemblyInfoParams.Version, AssemblyInfoParams.Author, downloadLink: "https://github.com/NotAKidOnSteam/Blackout" @@ -21,10 +21,11 @@ using System.Reflection; [assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")] [assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)] [assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)] +[assembly: MelonOptionalDependencies("UIExpansionKit", "BTKUILib")] -namespace Blackout.Properties; +namespace NAK.Melons.Blackout.Properties; internal static class AssemblyInfoParams { - public const string Version = "1.0.4"; + public const string Version = "2.0.0"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/Blackout/Resource1.Designer.cs b/Blackout/Resource1.Designer.cs index 5c2b3b3..0378e77 100644 --- a/Blackout/Resource1.Designer.cs +++ b/Blackout/Resource1.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace Blackout { +namespace NAK.Melons.Blackout { using System; diff --git a/Blackout/UIExpansionKitAddon.cs b/Blackout/UIExpansionKitAddon.cs deleted file mode 100644 index f38bccb..0000000 --- a/Blackout/UIExpansionKitAddon.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Runtime.CompilerServices; -using UIExpansionKit.API; - -namespace Blackout; -public static class UiExtensionsAddon -{ - [MethodImpl(MethodImplOptions.NoInlining)] - public static void Init() - { - var settings = ExpansionKitApi.GetSettingsCategory(Blackout.SettingsCategory); - settings.AddSimpleButton("Awake State", Blackout.AwakeState); - settings.AddSimpleButton("Drowsy State", Blackout.DrowsyState); - settings.AddSimpleButton("Sleep State", Blackout.SleepingState); - } -} \ No newline at end of file diff --git a/Blackout/format.json b/Blackout/format.json index eb09686..5f2e9f7 100644 --- a/Blackout/format.json +++ b/Blackout/format.json @@ -1,12 +1,12 @@ { "_id": 106, "name": "Blackout", - "modversion": "1.0.4", - "gameversion": "2022r169", + "modversion": "2.0.0", + "gameversion": "2022r170", "loaderversion": "0.5.7", "modtype": "Mod", "author": "NotAKidoS", - "description": "Dim screen after set time of sitting still. Should be nice for VR sleeping.\n\nNotable Options:\n Cap FPS while sleeping.\nManual control via UIX\nConfigurable dimming strength.", + "description": "Dim screen after set time of sitting still. Should be nice for VR sleeping.\n\nNotable Options:\n Cap FPS while sleeping.\nManual control via BTKUILib\nConfigurable dimming strength.", "searchtags": [ "black", "dimmer", @@ -14,10 +14,11 @@ "sleeper" ], "requirements": [ - "None" + "BTKUILib", + "UIExpansionKit" ], - "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/r5/Blackout.dll", + "downloadlink": "https://github.com/NotAKidOnSteam/Blackout/releases/download/v2.0.0/Blackout.dll", "sourcelink": "https://github.com/NotAKidOnSteam/Blackout/", - "changelog": "Small tweak to fix VRMode change detection with latest experimental.", + "changelog": "- Added BTKUILib support.\n- Added dimming strength velocity multiplier option.\n- Added option to not use Automatic Sleep State.\n- Dimming strengh now updates in realtime when configuring.", "embedcolor": "#161b22" } \ No newline at end of file From 2dbc52326c9523096a30aadcc5b38324c2e11cba Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidOnSteam@users.noreply.github.com> Date: Thu, 9 Feb 2023 23:00:37 -0600 Subject: [PATCH 19/19] Update README.md --- README.md | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 9f22742..aa7439f 100644 --- a/README.md +++ b/README.md @@ -38,22 +38,8 @@ Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI. https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games -> I am not affiliated with ABI in any official capacity, these mods are not endorsed or outright permitted by ABI and are subject to scrutiny. +> This mod is an independent creation and is not affiliated with, supported by or approved by Alpha Blend Interactive. -> Neither I nor these mods are in any way affiliated with Alpha Blend Interactive and/or ChilloutVR. Using these modifications might cause issues with the performance, security or stability of the game. Use at your own risk. +> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use. -> Any modifications that are not approved can get your ABI account terminated and such this modification is following the "modding guidelines" at the best it could be. -> They reserve the right to punish users using my mod. -> If you are scared of using modifications in your game do not install mods. - -> I do not affiliate ABI and the mod is not supported by ABI. - -> Me and this modification are in no affiliation with ABI and not supported by ABI. - -> This mod is not affiliated with Alpha Blend Interactive. The mod comes with no warranty. Use at your own risk, as I am not responsible for any misuse. - -> I'm not affiliated with Alpha Blend Interactive and this mod is not officially supported by the game. - -> When releasing mods to the public, it is required to state, that the mod authors and modification are in no affiliation with ABI and not supported by ABI. :trollface: - -> i ran out of places to steal disclaimers from +> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.