mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 06:19:22 +00:00
Testing Phase
Basics are implemented. Needs playtesting before potential rewrite and implementation of avatar parameters & manual control.
This commit is contained in:
parent
c049d93d55
commit
d033d3750e
8 changed files with 541 additions and 82 deletions
|
@ -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<Animator>();
|
||||
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<GameObject>("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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue