241 lines
6.9 KiB
C#
241 lines
6.9 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Serialization;
|
|
using Utility;
|
|
|
|
[Serializable]
|
|
public struct DeveloperStats
|
|
{
|
|
public double BaseEfficiency;
|
|
public int Fingers;
|
|
|
|
public double CaffeineDrainFactor;
|
|
public double HungerDrainFactor;
|
|
[FormerlySerializedAs("UrgeToUrinateFillFactor")] public double UrinationDrainFactor;
|
|
|
|
public DeveloperStats(double baseEfficiency, int fingers, double caffeineDrainFactor, double hungerDrainFactor, double urinationDrainFactor)
|
|
{
|
|
BaseEfficiency = baseEfficiency;
|
|
Fingers = fingers;
|
|
CaffeineDrainFactor = caffeineDrainFactor;
|
|
HungerDrainFactor = hungerDrainFactor;
|
|
UrinationDrainFactor = urinationDrainFactor;
|
|
}
|
|
|
|
public static readonly DeveloperStats Default = new DeveloperStats(1.0, 10, 1, 1, 1);
|
|
}
|
|
|
|
public class Developer : MonoBehaviour
|
|
{
|
|
private string _name;
|
|
|
|
[SerializeField]
|
|
private DeveloperStats _baseStats = DeveloperStats.Default;
|
|
|
|
[FormerlySerializedAs("_currentCurrentEfficiency")] [SerializeField, ShowOnly]
|
|
private double _currentEfficiency = 1.0;
|
|
|
|
[SerializeField]
|
|
private int _fingersLeft = 10;
|
|
|
|
[SerializeField]
|
|
private double _caffeineLevel = 1.0;
|
|
|
|
[SerializeField]
|
|
private double _hungerLevel = 1.0;
|
|
|
|
[FormerlySerializedAs("_urgeToUrinateLevel")] [SerializeField]
|
|
private double _urinationDrain = 1.0;
|
|
|
|
[SerializeField, ShowOnly]
|
|
private bool _isSleeping = false;
|
|
|
|
[SerializeField, ShowOnly]
|
|
private bool _isHyperactive = false;
|
|
|
|
[SerializeField, ShowOnly]
|
|
private bool _isOvercaffeinated = false;
|
|
|
|
[SerializeField]
|
|
private DeveloperNeeds _developerNeeds;
|
|
|
|
/// <summary>
|
|
/// Gibt die Grunddaten des Entwicklers zurück.
|
|
/// </summary>
|
|
public DeveloperStats BaseStats => _baseStats;
|
|
|
|
/// <summary>
|
|
/// Gibt die Anzahl der Finger zurück.
|
|
/// </summary>
|
|
public int FingersLeft => _fingersLeft;
|
|
|
|
/// <summary>
|
|
/// Gibt die aktuelle Effizienz des Entwicklers in Prozent zurück.
|
|
/// </summary>
|
|
public double CurrentEfficiency => _currentEfficiency;
|
|
|
|
public string Name => _name;
|
|
|
|
[SerializeField]
|
|
private GameObject _caffeineNeed;
|
|
[SerializeField]
|
|
private GameObject _hungerNeed;
|
|
[SerializeField]
|
|
private GameObject _toiletNeed;
|
|
|
|
void Start()
|
|
{
|
|
_developerNeeds = gameObject.GetComponent<DeveloperNeeds>();
|
|
|
|
_fingersLeft = _baseStats.Fingers;
|
|
}
|
|
|
|
[ContextMenu("Give Drink")]
|
|
private void TestDrink()
|
|
{
|
|
GiveDrink(0.25);
|
|
}
|
|
|
|
[ContextMenu("Give Food")]
|
|
private void TestFood()
|
|
{
|
|
GiveFood(0.25);
|
|
}
|
|
|
|
[ContextMenu("Drain Bladder")]
|
|
private void TestPee()
|
|
{
|
|
Pee(0.25);
|
|
}
|
|
|
|
public void GiveDrink(double caffeineAmount)
|
|
{
|
|
_caffeineLevel += caffeineAmount;
|
|
|
|
if (_caffeineNeed != null && _caffeineLevel > GameManager.Instance.NeedNotificationThreshold)
|
|
{
|
|
NeedFullfilled(_caffeineNeed);
|
|
}
|
|
}
|
|
|
|
public void GiveFood(double foodAmount)
|
|
{
|
|
_hungerLevel += foodAmount;
|
|
|
|
if (_hungerNeed != null && _hungerLevel > GameManager.Instance.NeedNotificationThreshold)
|
|
{
|
|
NeedFullfilled(_hungerNeed);
|
|
}
|
|
}
|
|
|
|
public void Pee(double peeAmount)
|
|
{
|
|
_urinationDrain += peeAmount;
|
|
|
|
if (_toiletNeed != null && _urinationDrain > GameManager.Instance.NeedNotificationThreshold)
|
|
{
|
|
NeedFullfilled(_toiletNeed);
|
|
}
|
|
}
|
|
|
|
public void UpdateStats(double caffeineDrain, double hungerDrain, double urinationDrain)
|
|
{
|
|
_caffeineLevel -= caffeineDrain * _baseStats.CaffeineDrainFactor;
|
|
_hungerLevel -= hungerDrain * _baseStats.HungerDrainFactor;
|
|
_urinationDrain -= urinationDrain * _baseStats.UrinationDrainFactor;
|
|
|
|
_caffeineLevel = Math.Clamp(_caffeineLevel, 0.0, 2.0);
|
|
_hungerLevel = Math.Clamp(_hungerLevel, 0.0, 1.0);
|
|
_urinationDrain = Math.Clamp(_urinationDrain, 0.0, 1.0);
|
|
|
|
_isHyperactive = _caffeineLevel > 1.0;
|
|
_isOvercaffeinated = _caffeineLevel > 1.5;
|
|
_isSleeping = _caffeineLevel <= 0.0;
|
|
|
|
if (_caffeineLevel < GameManager.Instance.NeedNotificationThreshold && _caffeineNeed == null)
|
|
{
|
|
_caffeineNeed = _developerNeeds.SpawnCaffeineNeed();
|
|
}
|
|
|
|
if (_hungerLevel < GameManager.Instance.NeedNotificationThreshold && _hungerNeed == null)
|
|
{
|
|
_hungerNeed = _developerNeeds.SpawnHungerNeed();
|
|
}
|
|
|
|
if (_urinationDrain < GameManager.Instance.NeedNotificationThreshold && _toiletNeed == null)
|
|
{
|
|
// TODO: Go to toilet
|
|
|
|
Debug.Log("Ich muss aufs Klo!");
|
|
|
|
_toiletNeed = _developerNeeds.SpawnToiletNeed();
|
|
}
|
|
|
|
if (_hungerLevel <= 0.0)
|
|
{
|
|
Die();
|
|
}
|
|
}
|
|
|
|
private void NeedFullfilled(GameObject needObject)
|
|
{
|
|
Instantiate(GameManager.Instance.NeedFullfilledParticleEffect, needObject.transform.position, needObject.transform.rotation);
|
|
Destroy(needObject);
|
|
}
|
|
|
|
public void UpdateEfficiency()
|
|
{
|
|
_currentEfficiency = _baseStats.BaseEfficiency * (_fingersLeft / 10.0) * CalculateCaffeineEfficiency() * CalculateHungerEfficiency() * CalculateUrinationEfficiency();
|
|
}
|
|
|
|
// TODO: Es könnte sich als schwierig erweisen, die Effizienz hoch zu halten.
|
|
// Man könnte ggf. die Funktionen so anpassen, dass sie eine ganze Weile 100% Effizienz geben.
|
|
|
|
private double CalculateCaffeineEfficiency()
|
|
{
|
|
if (_isSleeping)
|
|
return 0.0;
|
|
|
|
// Die Formel hat schon recht vielversprechendes Verhalten im Bereich > 1
|
|
//if (_isHyperactive)
|
|
// return 1.0 + (_caffeineLevel - 1.0) * (_caffeineLevel - 1.0);
|
|
|
|
if (_isOvercaffeinated)
|
|
return 0.0;
|
|
|
|
// https://easings.net/#easeOutCubic
|
|
return 1.0 - Math.Pow(1.0 - _caffeineLevel, 3.0);
|
|
}
|
|
|
|
private double CalculateHungerEfficiency()
|
|
{
|
|
// https://easings.net/#easeOutCirc
|
|
return Math.Sqrt(1.0 - Math.Pow(_caffeineLevel - 1.0, 2.0));
|
|
}
|
|
|
|
private double CalculateUrinationEfficiency()
|
|
{
|
|
// https://easings.net/#easeOutExpo
|
|
return Math.Abs(_urinationDrain - 1.0) < 0.0001f ? 1.0 : 1.0 - Math.Pow(2, -10 * _urinationDrain);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Der Entwickler wird verletzt und der Idiot bricht sich ausgerechnet einen Finger...
|
|
/// </summary>
|
|
public void Hurt()
|
|
{
|
|
_fingersLeft--;
|
|
|
|
// Ob er stirbt oder nicht, für uns hat er auf jeden Fall seinen Nutzen verloren.
|
|
if (_fingersLeft == 0)
|
|
Die();
|
|
}
|
|
|
|
private void Die()
|
|
{
|
|
Debug.Log($"{Name} ist verreckt.");
|
|
}
|
|
}
|