Files
2025-05-29 22:31:40 +03:00

207 lines
5.9 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Localization;
public class Sanity : MonoBehaviour
{
private static Sanity _instance;
public static Sanity GetInstance() => _instance;
[Header("Sanity Values")]
[SerializeField] private float _sanity = 500f;
[SerializeField] private float _sanityMaxValue = 500f;
[SerializeField] private float sanityDropSpeed = 2f;
[SerializeField] private float sanityDropSpeedInGhostUniverse = 4f;
[SerializeField] private float restoreSpeed = 25f;
[Header("Sanity Thresholds")]
[SerializeField] private float minorHallucinationsValue = 350f;
[SerializeField] private float majorHallucinationsValue = 150f;
[Header("Sanity Modifiers")]
public float sanityDropMultiplierWhenWatched = 1.2f;
[Header("States")]
public bool IsInLightSource;
public bool sanityEventIsTakingPlace;
public bool shouldUpdateSanityState = true;
private bool _canDisplayMessageSanityIsDecreasingFast = true;
public enum SanityState { Sane, MinorHallucinations, MajorHallucinations, Insane }
public SanityState mentalState = SanityState.Sane;
public event UnityAction OnSane;
public event UnityAction OnMinorHallucinations;
public event UnityAction OnMajorHallucinations;
public event UnityAction OnInsane;
[Header("Localization")]
public LocalizedString sanityIsDeteriorating;
public float currentSanity => _sanity;
public float SanityMaxValue => _sanityMaxValue;
public void SetSanity(float value)
{
_sanity = Mathf.Clamp(value, 0f, _sanityMaxValue);
}
public float sanityDropSpeedValue
{
get => sanityDropSpeed;
set => sanityDropSpeed = Mathf.Max(0f, value);
}
public float sanityDropSpeedInGhostUniverseValue => sanityDropSpeedInGhostUniverse;
public float sanityDropSpeedDefaultValue => sanityDropSpeed;
public void sanityChangeMaxValueAtRuntime(float newSanityMaxValue)
{
_sanityMaxValue = newSanityMaxValue;
_sanity = Mathf.Clamp(_sanity, 0f, _sanityMaxValue);
UIManager.GetInstance().sanityDuration = _sanity;
}
private void Awake()
{
if (_instance == null)
{
_instance = this;
}
_sanity = _sanityMaxValue;
UIManager.GetInstance().sanityDuration = _sanity;
UIManager.GetInstance().startTime = _sanity;
}
private void Update()
{
UpdateSanity();
EvaluateSanityState();
UIManager.GetInstance().SanityMeterUI.material.SetFloat("_CurrentSanityValue", _sanity);
HandleSanityWarnings();
}
private void UpdateSanity()
{
if (sanityEventIsTakingPlace) return;
bool isWatched = EyesManager.GetInstance()?.IsPlayerWatched() ?? false;
float decay = AlternateUniverseManager.GetInstance().IsInGhostUniverse ? sanityDropSpeedInGhostUniverse : sanityDropSpeed;
float finalDecay = decay;
if (isWatched)
{
finalDecay *= sanityDropMultiplierWhenWatched;
}
if (!IsInLightSource)
{
_sanity -= finalDecay * Time.deltaTime;
}
else
{
if (isWatched)
{
// Ακόμα και αν είναι σε φως, αλλά παρακολουθείται, να χάνει sanity
_sanity -= finalDecay * Time.deltaTime;
}
else
{
_sanity += restoreSpeed * Time.deltaTime;
}
}
_sanity = Mathf.Clamp(_sanity, 0f, _sanityMaxValue);
}
private void EvaluateSanityState()
{
SanityState newState;
if (_sanity > minorHallucinationsValue)
newState = SanityState.Sane;
else if (_sanity > majorHallucinationsValue)
newState = SanityState.MinorHallucinations;
else if (_sanity > 0)
newState = SanityState.MajorHallucinations;
else
newState = SanityState.Insane;
if (mentalState != newState)
{
mentalState = newState;
TriggerStateEvent(newState);
}
}
private void TriggerStateEvent(SanityState state)
{
switch (state)
{
case SanityState.Sane:
OnSane?.Invoke();
break;
case SanityState.MinorHallucinations:
OnMinorHallucinations?.Invoke();
break;
case SanityState.MajorHallucinations:
OnMajorHallucinations?.Invoke();
break;
case SanityState.Insane:
OnInsane?.Invoke();
break;
}
}
public void UsePill(float restoreAmount = -1f)
{
if (restoreAmount < 0f) restoreAmount = _sanityMaxValue;
_sanity += restoreAmount;
_sanity = Mathf.Clamp(_sanity, 0f, _sanityMaxValue);
PlayerHealthManager.GetInstance().PillUsed = false;
Debug.Log("Pills used");
}
private void HandleSanityWarnings()
{
if (_sanity <= 200f && _canDisplayMessageSanityIsDecreasingFast)
{
UIManager.GetInstance().StartCoroutine(UIManager.GetInstance().DisplayMessage(sanityIsDeteriorating));
_canDisplayMessageSanityIsDecreasingFast = false;
}
else if (_sanity > 200f)
{
_canDisplayMessageSanityIsDecreasingFast = true;
}
}
private void OnTriggerEnter(Collider col)
{
if (!AlternateUniverseManager.GetInstance().IsInGhostUniverse && col.CompareTag("LightSource"))
{
IsInLightSource = true;
}
}
private void OnTriggerStay(Collider col)
{
if (!AlternateUniverseManager.GetInstance().IsInGhostUniverse && col.CompareTag("LightSource"))
{
IsInLightSource = true;
}
}
private void OnTriggerExit(Collider col)
{
if (col.CompareTag("LightSource"))
{
IsInLightSource = false;
}
}
}