diff --git a/3d Prototyp/Assets/Scripts/Developer.cs b/3d Prototyp/Assets/Scripts/Developer.cs
index 33a1006d..580ca1a0 100644
--- a/3d Prototyp/Assets/Scripts/Developer.cs
+++ b/3d Prototyp/Assets/Scripts/Developer.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using Utility;
+using Random = UnityEngine.Random;
[Serializable]
public struct DeveloperStats
@@ -13,18 +14,26 @@ public struct DeveloperStats
public double CaffeineDrainFactor;
public double HungerDrainFactor;
- [FormerlySerializedAs("UrgeToUrinateFillFactor")] public double UrinationDrainFactor;
+ public double UrinationDrainFactor;
+ public double HappinessDrainFactor;
- public DeveloperStats(double baseEfficiency, int fingers, double caffeineDrainFactor, double hungerDrainFactor, double urinationDrainFactor)
+ // TODO: Not yet used
+ public double CoffeePreference;
+ public double MatePreference;
+
+ public DeveloperStats(double baseEfficiency, int fingers, double caffeineDrainFactor, double hungerDrainFactor, double urinationDrainFactor, double happinessDrainFactor, double coffeePreference, double matePreference)
{
BaseEfficiency = baseEfficiency;
Fingers = fingers;
CaffeineDrainFactor = caffeineDrainFactor;
HungerDrainFactor = hungerDrainFactor;
UrinationDrainFactor = urinationDrainFactor;
+ HappinessDrainFactor = happinessDrainFactor;
+ CoffeePreference = coffeePreference;
+ MatePreference = matePreference;
}
- public static readonly DeveloperStats Default = new DeveloperStats(1.0, 10, 1, 1, 1);
+ public static readonly DeveloperStats Default = new DeveloperStats(1.0, 10, 1, 1, 1, 1, 0.5, 0.5);
}
public class Developer : MonoBehaviour
@@ -49,6 +58,9 @@ public class Developer : MonoBehaviour
[SerializeField]
private double _urgeToUrinateLevel = 1.0;
+ [SerializeField]
+ private double _happiness = 0.75;
+
[SerializeField, ShowOnly]
private bool _isSleeping = false;
@@ -78,10 +90,27 @@ public class Developer : MonoBehaviour
public string Name => _name;
+ [Serializable, Flags]
+ public enum WantedConsumable
+ {
+ None,
+ Food = 0x01,
+ Drink = 0x02,
+ Coffee = Drink | 0x04,
+ Mate = Drink | 0x08,
+ Pizza = Food | 0x10
+ }
+
[SerializeField]
private GameObject _caffeineNeed;
+
+ [SerializeField] private WantedConsumable _wantedDrink;
+
[SerializeField]
private GameObject _hungerNeed;
+
+ [SerializeField] private WantedConsumable _wantedFood;
+
[SerializeField]
private GameObject _toiletNeed;
@@ -92,63 +121,121 @@ public class Developer : MonoBehaviour
_fingersLeft = _baseStats.Fingers;
}
- [ContextMenu("Give Drink")]
- private void TestDrink()
+ [ContextMenu("Give Coffee")]
+ private void TestCoffee()
{
- GiveDrink(0.25);
+ GiveDrink(0.3, WantedConsumable.Coffee);
+ }
+
+ [ContextMenu("Give Mate")]
+ private void TestMate()
+ {
+ GiveDrink(0.3, WantedConsumable.Mate);
}
[ContextMenu("Give Food")]
private void TestFood()
{
- GiveFood(0.25);
+ GiveFood(0.3, WantedConsumable.Pizza);
}
[ContextMenu("Drain Bladder")]
private void TestPee()
{
- Pee(0.25);
+ Pee(0.3, true);
}
- public void GiveDrink(double caffeineAmount)
+ public void GiveDrink(double caffeineAmount, WantedConsumable drinkType)
{
- _caffeineLevel += caffeineAmount;
+ if (!drinkType.HasFlag(WantedConsumable.Drink))
+ throw new ArgumentException(nameof(drinkType),
+ $"{nameof(drinkType)} must be a value with the \"{WantedConsumable.Drink}\" flag");
+
+ _caffeineLevel = Math.Min(_caffeineLevel + caffeineAmount, 2.0);
if (_caffeineNeed != null && _caffeineLevel > GameManager.Instance.NeedNotificationThreshold)
{
NeedFullfilled(_caffeineNeed);
+ _caffeineNeed = null;
}
+
+ if (_wantedDrink != WantedConsumable.None)
+ {
+ // TODO: Wie wäre es damit, das nicht fest zu coden?
+ if (drinkType == _wantedDrink)
+ _happiness += 0.2;
+ else
+ _happiness -= 0.2;
+ }
+ else
+ {
+ _happiness += 0.2;
+ }
+
+ _wantedDrink = WantedConsumable.None;
}
- public void GiveFood(double foodAmount)
+ public void GiveFood(double foodAmount, WantedConsumable foodType)
{
- _hungerLevel += foodAmount;
+ if (!foodType.HasFlag(WantedConsumable.Food))
+ throw new ArgumentException(nameof(foodType),
+ $"{nameof(foodType)} must be a value with the \"{WantedConsumable.Food}\" flag");
+
+ _hungerLevel = Math.Min(_hungerLevel + foodAmount, 1.0);
if (_hungerNeed != null && _hungerLevel > GameManager.Instance.NeedNotificationThreshold)
{
NeedFullfilled(_hungerNeed);
+ _hungerNeed = null;
}
+
+ if (_wantedFood != WantedConsumable.None)
+ {
+ if (foodType == _wantedFood)
+ _happiness += 0.2;
+ else
+ _happiness -= 0.2;
+ }
+ else
+ {
+ _happiness += 0.2;
+ }
+
+ _wantedFood = WantedConsumable.None;
}
- public void Pee(double peeAmount)
+ ///
+ /// Der Entwickler Pinkelt die angegebene Menge aus.
+ ///
+ /// Die Menge die ausgepinkelt wird.
+ /// Wenn true, dann pinkelt der Entwickler auf einer Toilette. Wenn false, dann pinkelt er auf den Boden (was schlecht ist)
+ public void Pee(double peeAmount, bool onToilet)
{
- _urgeToUrinateLevel += peeAmount;
+ _urgeToUrinateLevel = Math.Min(_urgeToUrinateLevel += peeAmount, 1.0);
if (_toiletNeed != null && _urgeToUrinateLevel > GameManager.Instance.NeedNotificationThreshold)
{
NeedFullfilled(_toiletNeed);
+ _toiletNeed = null;
}
+
+ if (onToilet)
+ _happiness += 0.2;
+ else
+ _happiness -= 0.2;
}
- public void UpdateStats(double caffeineDrain, double hungerDrain, double urinationDrain)
+ public void UpdateStats(double caffeineDrain, double hungerDrain, double urinationDrain, double happinessDrain)
{
_caffeineLevel -= caffeineDrain * _baseStats.CaffeineDrainFactor;
_hungerLevel -= hungerDrain * _baseStats.HungerDrainFactor;
_urgeToUrinateLevel -= urinationDrain * _baseStats.UrinationDrainFactor;
+ _happiness -= happinessDrain * _baseStats.UrinationDrainFactor;
- _caffeineLevel = Math.Clamp(_caffeineLevel, 0.0, 2.0);
- _hungerLevel = Math.Clamp(_hungerLevel, 0.0, 1.0);
- _urgeToUrinateLevel = Math.Clamp(_urgeToUrinateLevel, 0.0, 1.0);
+ _caffeineLevel = Math.Max(_caffeineLevel, 0.0);
+ _hungerLevel = Math.Max(_hungerLevel, 0.0);
+ _urgeToUrinateLevel = Math.Max(_urgeToUrinateLevel, 0.0);
+ _happiness = Math.Max(_happiness, 0.0);
_isHyperactive = _caffeineLevel > 1.0;
_isOvercaffeinated = _caffeineLevel > 1.5;
@@ -156,12 +243,24 @@ public class Developer : MonoBehaviour
if (_caffeineLevel < GameManager.Instance.NeedNotificationThreshold && _caffeineNeed == null)
{
- _caffeineNeed = _developerNeeds.SpawnCaffeineNeed();
+ // TODO: Wir können hier anhand von Präferenz gewichten.
+
+ if (Random.Range(0.0f, 1.0f) > 0.5f)
+ {
+ _caffeineNeed = _developerNeeds.SpawnMateNeed();
+ _wantedDrink = WantedConsumable.Mate;
+ }
+ else
+ {
+ _caffeineNeed = _developerNeeds.SpawnCoffeeNeed();
+ _wantedDrink = WantedConsumable.Coffee;
+ }
}
if (_hungerLevel < GameManager.Instance.NeedNotificationThreshold && _hungerNeed == null)
{
_hungerNeed = _developerNeeds.SpawnHungerNeed();
+ _wantedFood = WantedConsumable.Pizza;
}
if (_urgeToUrinateLevel < GameManager.Instance.NeedNotificationThreshold && _toiletNeed == null)
@@ -187,11 +286,12 @@ public class Developer : MonoBehaviour
public void UpdateEfficiency()
{
- _currentEfficiency = _baseStats.BaseEfficiency * (_fingersLeft / 10.0) * CalculateCaffeineEfficiency() * CalculateHungerEfficiency() * CalculateUrinationEfficiency();
+ _currentEfficiency = _baseStats.BaseEfficiency * (_fingersLeft / 10.0) * CalculateCaffeineEfficiency() * CalculateHungerEfficiency() * CalculateUrinationEfficiency() * CalculateHappinessEfficiency();
}
// 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.
+ // Man könnte ggf. die Funktionen so anpassen, dass sie eine ganze Weile 100% Effizienz geben.
+ // TODO: Das auch nur ansatzweise zu balancieren wird wiztig 🤯
private double CalculateCaffeineEfficiency()
{
@@ -211,16 +311,28 @@ public class Developer : MonoBehaviour
private double CalculateHungerEfficiency()
{
+ if (_hungerLevel > 1.0)
+ return 1.0;
+
// https://easings.net/#easeOutCirc
- return Math.Sqrt(1.0 - Math.Pow(_caffeineLevel - 1.0, 2.0));
+ return Math.Sqrt(1.0 - Math.Pow(_hungerLevel - 1.0, 2.0));
}
private double CalculateUrinationEfficiency()
{
+ if (_urgeToUrinateLevel > 1.0)
+ return 1.0;
+
// https://easings.net/#easeOutExpo
return Math.Abs(_urgeToUrinateLevel - 1.0) < 0.0001f ? 1.0 : 1.0 - Math.Pow(2, -10 * _urgeToUrinateLevel);
}
+ private double CalculateHappinessEfficiency()
+ {
+ // 50% bei 0 Happiness, 100% bei 0.75 Happiness, 125% bei 1 Happiness
+ return 0.5 + _happiness * 2.0 / 3.0;
+ }
+
///
/// Der Entwickler wird verletzt und der Idiot bricht sich ausgerechnet einen Finger...
///
diff --git a/3d Prototyp/Assets/Scripts/DeveloperNeeds.cs b/3d Prototyp/Assets/Scripts/DeveloperNeeds.cs
index a4fb8c6e..7b4705b6 100644
--- a/3d Prototyp/Assets/Scripts/DeveloperNeeds.cs
+++ b/3d Prototyp/Assets/Scripts/DeveloperNeeds.cs
@@ -25,7 +25,8 @@ public class DeveloperNeeds : MonoBehaviour
// TODO: Enums statt strings verwenden
// TODO: Multiple Needs möglich übereinander anzeigen?
- public GameObject SpawnCaffeineNeed() => spawnNeed(Random.Range(0.0f, 1.0f) < 0.5f ? "coffee" : "mate");
+ public GameObject SpawnCoffeeNeed() => spawnNeed("coffee");
+ public GameObject SpawnMateNeed() => spawnNeed("mate");
public GameObject SpawnToiletNeed() => spawnNeed("toilet");
public GameObject SpawnHungerNeed() => spawnNeed("hunger");
public GameObject SpawnMoneyNeed() => spawnNeed("money");
diff --git a/3d Prototyp/Assets/Scripts/GameManager.cs b/3d Prototyp/Assets/Scripts/GameManager.cs
index 07fa0257..d5f56050 100644
--- a/3d Prototyp/Assets/Scripts/GameManager.cs
+++ b/3d Prototyp/Assets/Scripts/GameManager.cs
@@ -147,13 +147,15 @@ public partial class GameManager : MonoBehaviourSingleton
{
double developerEfficiency = 0.0f;
+ // TODO: Und eine weitere absolut nicht handle-bare variable...
double caffeineDrain = _generalNeedDrainScaling * Math.Pow(2, _difficultySettings.CaffeineDrainScaling * GameProgress);
double hungerDrain = _generalNeedDrainScaling * Math.Pow(2, _difficultySettings.HungerDrainScaling * GameProgress);
double urinationDrain = _generalNeedDrainScaling * Math.Pow(2, _difficultySettings.UrinationDrainScaling * GameProgress);
+ double happinessDrain = _generalNeedDrainScaling * Math.Pow(2, _difficultySettings.HappinessDrainScaling * GameProgress);
foreach (Developer developer in _developers)
{
- developer.UpdateStats(caffeineDrain, hungerDrain, urinationDrain);
+ developer.UpdateStats(caffeineDrain, hungerDrain, urinationDrain, happinessDrain);
developer.UpdateEfficiency();
developerEfficiency += developer.CurrentEfficiency;
}
diff --git a/3d Prototyp/Assets/Scripts/Utility/Difficulty.cs b/3d Prototyp/Assets/Scripts/Utility/Difficulty.cs
index 5d3f47d8..19423308 100644
--- a/3d Prototyp/Assets/Scripts/Utility/Difficulty.cs
+++ b/3d Prototyp/Assets/Scripts/Utility/Difficulty.cs
@@ -22,6 +22,7 @@ namespace Utility
public double CaffeineDrainScaling { get; protected set; }
public double HungerDrainScaling { get; protected set; }
public double UrinationDrainScaling { get; protected set; }
+ public double HappinessDrainScaling { get; protected set; }
}
public class EasyDifficulty : DifficultySettings
@@ -42,6 +43,7 @@ namespace Utility
CaffeineDrainScaling = 1.5;
HungerDrainScaling = 1.5;
UrinationDrainScaling = 1.5;
+ HappinessDrainScaling = 1.5;
}
}