This commit is contained in:
NotAKidoS 2023-02-02 13:02:41 -06:00
parent 24d8c6a3ec
commit 65d325d4fd
11 changed files with 277 additions and 109 deletions

View file

@ -1,7 +1,7 @@
using System.Reflection;
using UnityEngine;
namespace Blackout;
namespace NAK.Melons.Blackout;
/*

View file

@ -26,6 +26,9 @@
<Reference Include="Assembly-CSharp-firstpass">
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
</Reference>
<Reference Include="BTKUILib">
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\BTKUILib.dll</HintPath>
</Reference>
<Reference Include="Cohtml.Runtime">
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll</HintPath>
</Reference>

View file

@ -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<Animator>();
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);
}

View file

@ -3,7 +3,7 @@ using ABI_RC.Core.Savior;
using HarmonyLib;
using MelonLoader;
namespace Blackout;
namespace NAK.Melons.Blackout.HarmonyPatches;
[HarmonyPatch]
internal class HarmonyPatches

View file

@ -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<bool> entry)
{
category.AddToggle(entry.DisplayName, entry.Description, entry.Value).OnValueUpdated += b => entry.Value = b;
}
private static void AddMelonSlider(ref Page page, MelonLoader.MelonPreferences_Entry<float> entry, float min, float max)
{
page.AddSlider(entry.DisplayName, entry.Description, entry.Value, min, max).OnValueUpdated += f => entry.Value = f;
}
}

View file

@ -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);
}

View file

@ -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<bool> m_entryEnabled, m_entryHudMessages, m_entryDropFPSOnSleep;
private static MelonPreferences_Entry<float>
internal static MelonPreferences_Category m_categoryBlackout;
internal static MelonPreferences_Entry<bool>
m_entryEnabled,
m_entryAutoSleepState,
m_entryHudMessages,
m_entryDropFPSOnSleep,
m_entryDrowsyVelocityMultiplier;
internal static MelonPreferences_Entry<float>
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<bool>("Automatic State Change", true, description: "Dim screen when there is no movement for a while.");
m_entryHudMessages = m_categoryBlackout.CreateEntry<bool>("Hud Messages", false, description: "Notify on state change.");
m_entryDropFPSOnSleep = m_categoryBlackout.CreateEntry<bool>("Lower FPS While Sleep", false, description: "Lowers FPS to 5 while in Sleep State.");
m_entryDrowsyThreshold = m_categoryBlackout.CreateEntry<float>("Drowsy Threshold", 1f, description: "Degrees of movement to return partial vision.");
m_entryAwakeThreshold = m_categoryBlackout.CreateEntry<float>("Awake Threshold", 12f, description: "Degrees of movement to return full vision.");
m_categoryBlackout = MelonPreferences.CreateCategory(SettingsCategory);
m_entryEnabled = m_categoryBlackout.CreateEntry<bool>("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<bool>("Hud Messages", true, description: "Notify on state change.");
m_entryDropFPSOnSleep = m_categoryBlackout.CreateEntry<bool>("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<bool>("Drowsy Velocity Multiplier", true, description: "Should head velocity act as a multiplier to Drowsy Dim Strength?");
m_entryAutoSleepState = m_categoryBlackout.CreateEntry<bool>("Auto Sleep State", true, description: "Should the sleep state be used during Automatic State Change?");
m_entryDrowsyThreshold = m_categoryBlackout.CreateEntry<float>("Drowsy Threshold", 2f, description: "Velocity to return partial vision.");
m_entryAwakeThreshold = m_categoryBlackout.CreateEntry<float>("Awake Threshold", 4f, description: "Velocity to return full vision.");
m_entryDrowsyModeTimer = m_categoryBlackout.CreateEntry<float>("Enter Drowsy Time (Minutes)", 3f, description: "How many minutes without movement until enter drowsy mode.");
m_entrySleepModeTimer = m_categoryBlackout.CreateEntry<float>("Enter Sleep Time (Seconds)", 10f, description: "How many seconds without movement until enter sleep mode.");
m_entryDrowsyDimStrength = m_categoryBlackout.CreateEntry<float>("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<float>("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);
}

View file

@ -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";
}

View file

@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace Blackout {
namespace NAK.Melons.Blackout {
using System;

View file

@ -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);
}
}

View file

@ -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"
}