2024-04-06 21:43:51 +02:00
using Microsoft.VisualStudio.Utilities ;
2024-04-05 19:24:26 +02:00
using System ;
2024-04-04 15:26:31 +02:00
using System.Collections ;
using System.Collections.Generic ;
2024-04-06 16:47:41 +02:00
using System.ComponentModel ;
2024-04-06 21:43:51 +02:00
using System.IO ;
2024-04-04 15:26:31 +02:00
using UnityEngine ;
2024-04-04 18:13:08 +02:00
using UnityEngine.Serialization ;
2024-04-04 19:41:19 +02:00
using Utility ;
2024-04-06 00:57:29 +02:00
using Random = UnityEngine . Random ;
2024-04-04 15:26:31 +02:00
2024-04-05 19:24:26 +02:00
[Serializable]
public struct DeveloperStats
{
public double BaseEfficiency ;
public int Fingers ;
public double CaffeineDrainFactor ;
public double HungerDrainFactor ;
2024-04-06 00:57:29 +02:00
public double UrinationDrainFactor ;
public double HappinessDrainFactor ;
2024-04-05 19:24:26 +02:00
2024-04-06 00:57:29 +02:00
// 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 )
2024-04-05 19:24:26 +02:00
{
BaseEfficiency = baseEfficiency ;
Fingers = fingers ;
CaffeineDrainFactor = caffeineDrainFactor ;
HungerDrainFactor = hungerDrainFactor ;
UrinationDrainFactor = urinationDrainFactor ;
2024-04-06 00:57:29 +02:00
HappinessDrainFactor = happinessDrainFactor ;
CoffeePreference = coffeePreference ;
MatePreference = matePreference ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 00:57:29 +02:00
public static readonly DeveloperStats Default = new DeveloperStats ( 1.0 , 10 , 1 , 1 , 1 , 1 , 0.5 , 0.5 ) ;
2024-04-05 19:24:26 +02:00
}
2024-04-04 15:26:31 +02:00
public class Developer : MonoBehaviour
{
2024-04-07 00:09:53 +02:00
[Header("Basis Informationen")]
[SerializeField]
2024-04-04 18:13:08 +02:00
private string _name ;
[SerializeField]
2024-04-05 19:24:26 +02:00
private DeveloperStats _baseStats = DeveloperStats . Default ;
2024-04-04 16:33:12 +02:00
2024-04-07 00:09:53 +02:00
[SerializeField]
private float _talkRange = 2.0f ;
[Header("Aktuelle Informationen")]
2024-04-05 19:32:50 +02:00
[SerializeField, ShowOnly]
2024-04-05 19:24:26 +02:00
private double _currentEfficiency = 1.0 ;
2024-04-04 18:13:08 +02:00
[SerializeField]
private int _fingersLeft = 10 ;
2024-04-05 19:24:26 +02:00
[SerializeField]
private double _caffeineLevel = 1.0 ;
[SerializeField]
private double _hungerLevel = 1.0 ;
2024-04-05 19:32:50 +02:00
[SerializeField]
private double _urgeToUrinateLevel = 1.0 ;
2024-04-05 19:24:26 +02:00
2024-04-06 00:57:29 +02:00
[SerializeField]
private double _happiness = 0.75 ;
2024-04-05 19:24:26 +02:00
[SerializeField, ShowOnly]
private bool _isSleeping = false ;
[SerializeField, ShowOnly]
private bool _isHyperactive = false ;
[SerializeField, ShowOnly]
private bool _isOvercaffeinated = false ;
[SerializeField]
private DeveloperNeeds _developerNeeds ;
2024-04-06 16:47:41 +02:00
2024-04-04 18:13:08 +02:00
/// <summary>
2024-04-05 19:24:26 +02:00
/// Gibt die Grunddaten des Entwicklers zurück.
2024-04-04 18:13:08 +02:00
/// </summary>
2024-04-05 19:24:26 +02:00
public DeveloperStats BaseStats = > _baseStats ;
2024-04-04 18:13:08 +02:00
/// <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>
2024-04-05 19:24:26 +02:00
public double CurrentEfficiency = > _currentEfficiency ;
2024-04-04 18:13:08 +02:00
2024-04-07 20:01:41 +02:00
public double CurrentHappiness = > _happiness ;
public double CurrentUrgeToUrinate = > _urgeToUrinateLevel ;
public double CurrentHunger = > _hungerLevel ;
public double CurrentCaffeination = > _caffeineLevel ;
2024-04-04 18:13:08 +02:00
public string Name = > _name ;
2024-04-06 00:57:29 +02:00
2024-04-05 19:24:26 +02:00
[SerializeField]
private GameObject _caffeineNeed ;
2024-04-06 00:57:29 +02:00
2024-04-06 21:43:51 +02:00
[SerializeField]
private WantedConsumable _wantedDrink ;
2024-04-06 00:57:29 +02:00
2024-04-05 19:24:26 +02:00
[SerializeField]
private GameObject _hungerNeed ;
2024-04-06 00:57:29 +02:00
2024-04-06 21:43:51 +02:00
[SerializeField]
private WantedConsumable _wantedFood ;
2024-04-06 00:57:29 +02:00
2024-04-05 19:24:26 +02:00
[SerializeField]
private GameObject _toiletNeed ;
2024-04-06 21:43:51 +02:00
private List < GameObject > _needList = new List < GameObject > ( ) ;
private bool _isDead = false ;
/// <summary>
/// indicates wether the Dev is dead or not
/// </summary>
public bool IsDead = > _isDead ;
[SerializeField]
private int _maxPrivateContextBufferSize = 2 ;
[SerializeField]
private CircularBuffer < string > _privateContextBuffer ;
/// <summary>
/// Returns the private Context Buffer
/// </summary>
public CircularBuffer < string > PrivateContextBuffer = > _privateContextBuffer ;
// stuff for talking
2024-04-06 16:47:41 +02:00
[SerializeField, ShowOnly]
private float _talkTimer ;
2024-04-06 21:43:51 +02:00
private AudioSource _audioSource ;
private float _talkPauseTime = 15.0f ;
2024-04-06 20:02:57 +02:00
private bool _hasTalkedWhileHyperactive = false ;
private bool _hasTalkedWhileOvercaffeinated = false ;
2024-04-06 22:26:31 +02:00
private bool _hasTalkedBeforeSleeping = false ;
2024-04-06 16:47:41 +02:00
2024-04-05 19:24:26 +02:00
void Start ( )
{
_developerNeeds = gameObject . GetComponent < DeveloperNeeds > ( ) ;
2024-04-06 16:47:41 +02:00
_audioSource = GetComponent < AudioSource > ( ) ;
2024-04-06 22:26:31 +02:00
_talkTimer = Random . Range ( 5.0f , 15.0f ) ;
2024-04-05 19:24:26 +02:00
_fingersLeft = _baseStats . Fingers ;
2024-04-06 21:43:51 +02:00
_privateContextBuffer = new CircularBuffer < string > ( _maxPrivateContextBufferSize ) ;
2024-04-07 14:17:09 +02:00
2024-04-05 19:24:26 +02:00
}
2024-04-06 16:47:41 +02:00
private void Update ( )
{
if ( ! _audioSource . isPlaying )
{
_talkTimer - = Time . deltaTime ;
if ( _talkTimer < 0.0f )
{
_talkTimer = _talkPauseTime ;
TalkIfInRange ( ) ;
}
}
}
2024-04-06 21:43:51 +02:00
[ContextMenu("Hurt him")]
private void TestHurt ( )
{
Hurt ( ) ;
}
2024-04-06 00:57:29 +02:00
[ContextMenu("Give Coffee")]
private void TestCoffee ( )
2024-04-05 19:24:26 +02:00
{
2024-04-06 00:57:29 +02:00
GiveDrink ( 0.3 , WantedConsumable . Coffee ) ;
}
[ContextMenu("Give Mate")]
private void TestMate ( )
{
GiveDrink ( 0.3 , WantedConsumable . Mate ) ;
2024-04-05 19:24:26 +02:00
}
[ContextMenu("Give Food")]
private void TestFood ( )
{
2024-04-06 00:57:29 +02:00
GiveFood ( 0.3 , WantedConsumable . Pizza ) ;
2024-04-05 19:24:26 +02:00
}
2024-04-04 18:13:08 +02:00
2024-04-05 19:24:26 +02:00
[ContextMenu("Drain Bladder")]
private void TestPee ( )
{
2024-04-06 00:57:29 +02:00
Pee ( 0.3 , true ) ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 00:57:29 +02:00
public void GiveDrink ( double caffeineAmount , WantedConsumable drinkType )
2024-04-05 19:24:26 +02:00
{
2024-04-06 00:57:29 +02:00
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 ) ;
2024-04-05 19:24:26 +02:00
if ( _caffeineNeed ! = null & & _caffeineLevel > GameManager . Instance . NeedNotificationThreshold )
{
2024-04-06 18:30:26 +02:00
UpdateNeedPositions ( _caffeineNeed ) ;
_needList . Remove ( _caffeineNeed ) ;
2024-04-05 19:24:26 +02:00
NeedFullfilled ( _caffeineNeed ) ;
2024-04-06 00:57:29 +02:00
_caffeineNeed = null ;
}
if ( _wantedDrink ! = WantedConsumable . None )
{
// TODO: Wie wäre es damit, das nicht fest zu coden?
if ( drinkType = = _wantedDrink )
2024-04-06 20:02:57 +02:00
{
2024-04-06 21:43:51 +02:00
Talk ( $"The Developer thanks Gottfried for the {drinkType.GetAsString()}" , 1 ) ;
2024-04-06 22:26:31 +02:00
_privateContextBuffer . Add ( $"The Developer is greatful for the {drinkType.GetAsString()} Gottfried brought him a while ago" ) ;
2024-04-06 00:57:29 +02:00
_happiness + = 0.2 ;
2024-04-06 20:02:57 +02:00
}
2024-04-06 00:57:29 +02:00
else
2024-04-06 20:02:57 +02:00
{
2024-04-06 21:43:51 +02:00
Talk ( $"The Developer is happy about the caffeine but he blames Gottfried for bringing {drinkType.GetAsString()} because he actaully wanted a {_wantedDrink.GetAsString()} instead" , 0 , true ) ;
2024-04-06 22:26:31 +02:00
_privateContextBuffer . Add ( $"The Developer is still annoyed and reminds Gottfried that he brought him {drinkType.GetAsString()} instead of {_wantedDrink.GetAsString()} a while ago" ) ;
2024-04-06 00:57:29 +02:00
_happiness - = 0.2 ;
2024-04-06 20:02:57 +02:00
}
2024-04-06 00:57:29 +02:00
}
else
{
_happiness + = 0.2 ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 00:57:29 +02:00
2024-04-08 19:08:37 +02:00
_urgeToUrinateLevel - = caffeineAmount / 0.5f ;
2024-04-06 00:57:29 +02:00
_wantedDrink = WantedConsumable . None ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 00:57:29 +02:00
public void GiveFood ( double foodAmount , WantedConsumable foodType )
2024-04-05 19:24:26 +02:00
{
2024-04-06 00:57:29 +02:00
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 ) ;
2024-04-05 19:24:26 +02:00
if ( _hungerNeed ! = null & & _hungerLevel > GameManager . Instance . NeedNotificationThreshold )
{
2024-04-06 18:30:26 +02:00
UpdateNeedPositions ( _hungerNeed ) ;
_needList . Remove ( _hungerNeed ) ;
2024-04-05 19:24:26 +02:00
NeedFullfilled ( _hungerNeed ) ;
2024-04-06 00:57:29 +02:00
_hungerNeed = null ;
2024-04-06 21:43:51 +02:00
Talk ( "The Developer thanks Gottfried for the Pizza" , 1 ) ;
2024-04-06 22:26:31 +02:00
_privateContextBuffer . Add ( $"The Developer is greatful for the Pizza Gottfried brought him a while ago" ) ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 21:43:51 +02:00
2024-04-06 00:57:29 +02:00
if ( _wantedFood ! = WantedConsumable . None )
{
if ( foodType = = _wantedFood )
_happiness + = 0.2 ;
else
_happiness - = 0.2 ;
}
else
{
_happiness + = 0.2 ;
}
2024-04-08 19:08:37 +02:00
_urgeToUrinateLevel - = foodAmount / 0.5f ;
2024-04-06 00:57:29 +02:00
_wantedFood = WantedConsumable . None ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 00:57:29 +02:00
/// <summary>
/// Der Entwickler Pinkelt die angegebene Menge aus.
/// </summary>
/// <param name="peeAmount">Die Menge die ausgepinkelt wird.</param>
/// <param name="onToilet">Wenn true, dann pinkelt der Entwickler auf einer Toilette. Wenn false, dann pinkelt er auf den Boden (was schlecht ist)</param>
public void Pee ( double peeAmount , bool onToilet )
2024-04-05 19:24:26 +02:00
{
2024-04-06 00:57:29 +02:00
_urgeToUrinateLevel = Math . Min ( _urgeToUrinateLevel + = peeAmount , 1.0 ) ;
2024-04-05 19:24:26 +02:00
2024-04-05 19:32:50 +02:00
if ( _toiletNeed ! = null & & _urgeToUrinateLevel > GameManager . Instance . NeedNotificationThreshold )
2024-04-05 19:24:26 +02:00
{
2024-04-06 18:30:26 +02:00
UpdateNeedPositions ( _toiletNeed ) ;
_needList . Remove ( _toiletNeed ) ;
2024-04-05 19:24:26 +02:00
NeedFullfilled ( _toiletNeed ) ;
2024-04-06 00:57:29 +02:00
_toiletNeed = null ;
2024-04-06 21:43:51 +02:00
Talk ( "The Developer finally can go to the toilet" , 1 ) ;
2024-04-06 22:26:31 +02:00
_privateContextBuffer . Add ( $"The developer is grateful that he went to the toilet a while ago" ) ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 00:57:29 +02:00
if ( onToilet )
_happiness + = 0.2 ;
else
_happiness - = 0.2 ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 00:57:29 +02:00
public void UpdateStats ( double caffeineDrain , double hungerDrain , double urinationDrain , double happinessDrain )
2024-04-05 19:24:26 +02:00
{
_caffeineLevel - = caffeineDrain * _baseStats . CaffeineDrainFactor ;
_hungerLevel - = hungerDrain * _baseStats . HungerDrainFactor ;
2024-04-05 19:32:50 +02:00
_urgeToUrinateLevel - = urinationDrain * _baseStats . UrinationDrainFactor ;
2024-04-06 00:57:29 +02:00
_happiness - = happinessDrain * _baseStats . UrinationDrainFactor ;
2024-04-05 19:24:26 +02:00
2024-04-06 00:57:29 +02:00
_caffeineLevel = Math . Max ( _caffeineLevel , 0.0 ) ;
_hungerLevel = Math . Max ( _hungerLevel , 0.0 ) ;
_urgeToUrinateLevel = Math . Max ( _urgeToUrinateLevel , 0.0 ) ;
_happiness = Math . Max ( _happiness , 0.0 ) ;
2024-04-05 19:24:26 +02:00
2024-04-06 20:02:57 +02:00
_isHyperactive = _caffeineLevel > 1.0 & & _caffeineLevel < = 1.5 ;
2024-04-05 19:24:26 +02:00
_isOvercaffeinated = _caffeineLevel > 1.5 ;
_isSleeping = _caffeineLevel < = 0.0 ;
2024-04-06 20:02:57 +02:00
2024-04-05 19:24:26 +02:00
if ( _caffeineLevel < GameManager . Instance . NeedNotificationThreshold & & _caffeineNeed = = null )
{
2024-04-06 00:57:29 +02:00
// TODO: Wir können hier anhand von Präferenz gewichten.
if ( Random . Range ( 0.0f , 1.0f ) > 0.5f )
{
2024-04-06 18:30:26 +02:00
_caffeineNeed = _developerNeeds . SpawnMateNeed ( _needList . Count ) ;
2024-04-06 00:57:29 +02:00
_wantedDrink = WantedConsumable . Mate ;
2024-04-06 18:30:26 +02:00
_needList . Add ( _caffeineNeed ) ;
2024-04-06 00:57:29 +02:00
}
else
{
2024-04-06 18:30:26 +02:00
_caffeineNeed = _developerNeeds . SpawnCoffeeNeed ( _needList . Count ) ;
2024-04-06 00:57:29 +02:00
_wantedDrink = WantedConsumable . Coffee ;
2024-04-06 18:30:26 +02:00
_needList . Add ( _caffeineNeed ) ;
2024-04-06 00:57:29 +02:00
}
2024-04-05 19:24:26 +02:00
}
if ( _hungerLevel < GameManager . Instance . NeedNotificationThreshold & & _hungerNeed = = null )
{
2024-04-06 18:30:26 +02:00
_hungerNeed = _developerNeeds . SpawnHungerNeed ( _needList . Count ) ;
2024-04-06 00:57:29 +02:00
_wantedFood = WantedConsumable . Pizza ;
2024-04-06 18:30:26 +02:00
_needList . Add ( _hungerNeed ) ;
2024-04-05 19:24:26 +02:00
}
2024-04-05 19:32:50 +02:00
if ( _urgeToUrinateLevel < GameManager . Instance . NeedNotificationThreshold & & _toiletNeed = = null )
2024-04-05 19:24:26 +02:00
{
// TODO: Go to toilet
Debug . Log ( "Ich muss aufs Klo!" ) ;
2024-04-06 18:30:26 +02:00
_toiletNeed = _developerNeeds . SpawnToiletNeed ( _needList . Count ) ;
_needList . Add ( _toiletNeed ) ;
2024-04-05 19:24:26 +02:00
}
if ( _hungerLevel < = 0.0 )
{
2024-04-06 21:43:51 +02:00
if ( ! _isDead )
Talk ( $"The developer is starving, The developer is dying, The developer blames Gottfried for letting him starve with his last words" , 0 , true ) ;
2024-04-05 19:24:26 +02:00
Die ( ) ;
}
}
2024-04-06 18:30:26 +02:00
private void UpdateNeedPositions ( GameObject reference )
{
int referenceIndex = _needList . IndexOf ( reference ) ;
if ( referenceIndex = = - 1 )
{
Debug . LogError ( "Reference GameObject not in List." ) ;
return ;
}
for ( int i = referenceIndex + 1 ; i < _needList . Count ; i + + )
{
GameObject currentItem = _needList [ i ] ;
currentItem . GetComponent < SpinningSpinner > ( ) . originalY - = 0.5f ;
}
}
2024-04-05 19:24:26 +02:00
private void NeedFullfilled ( GameObject needObject )
{
Instantiate ( GameManager . Instance . NeedFullfilledParticleEffect , needObject . transform . position , needObject . transform . rotation ) ;
Destroy ( needObject ) ;
}
2024-04-04 16:33:12 +02:00
public void UpdateEfficiency ( )
{
2024-04-06 00:57:29 +02:00
_currentEfficiency = _baseStats . BaseEfficiency * ( _fingersLeft / 10.0 ) * CalculateCaffeineEfficiency ( ) * CalculateHungerEfficiency ( ) * CalculateUrinationEfficiency ( ) * CalculateHappinessEfficiency ( ) ;
2024-04-04 18:13:08 +02:00
}
2024-04-05 19:24:26 +02:00
// TODO: Es könnte sich als schwierig erweisen, die Effizienz hoch zu halten.
2024-04-06 00:57:29 +02:00
// 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 🤯
2024-04-05 19:24:26 +02:00
private double CalculateCaffeineEfficiency ( )
{
if ( _isSleeping )
2024-04-06 22:26:31 +02:00
{
if ( ! _hasTalkedBeforeSleeping )
{
Talk ( "The Developer is very sleepy right now duo to a lack of caffeine, The Developer takes a nap now" , 0 , true ) ;
_privateContextBuffer . Add ( $"The developer took a refreshing nap but is annoyed that Gottfried forgot to bring him any caffeine before the nap" ) ;
_hasTalkedBeforeSleeping = true ;
}
2024-04-05 19:24:26 +02:00
return 0.0 ;
2024-04-06 22:26:31 +02:00
}
else
{
_hasTalkedBeforeSleeping = false ;
}
2024-04-05 19:24:26 +02:00
2024-04-06 20:02:57 +02:00
if ( _isHyperactive )
{
if ( ! _hasTalkedWhileHyperactive )
{
2024-04-07 03:38:32 +02:00
GetComponent < Text2Speech > ( ) . speakingSpeed = 1.3f ;
2024-04-06 22:26:31 +02:00
Talk ( "The Developer is surprisingly productive right now and feels an energyboost duo to caffeine" , 0 , true ) ;
2024-04-06 20:02:57 +02:00
_hasTalkedWhileHyperactive = true ;
}
}
else
{
_hasTalkedWhileHyperactive = false ;
}
2024-04-05 19:24:26 +02:00
if ( _isOvercaffeinated )
2024-04-06 20:02:57 +02:00
{
if ( ! _hasTalkedWhileOvercaffeinated )
{
2024-04-07 03:38:32 +02:00
GetComponent < Text2Speech > ( ) . speakingSpeed = 1.4f ;
2024-04-06 22:26:31 +02:00
Talk ( "The Developer had too much caffeine, The Developer needs a break immediately" , 0 , true ) ;
_privateContextBuffer . Add ( $"The developer overcaffeinated a while ago because Gottfried gave him too much caffeine" ) ;
2024-04-06 20:02:57 +02:00
_hasTalkedWhileOvercaffeinated = true ;
}
2024-04-05 19:24:26 +02:00
return 0.0 ;
2024-04-06 20:02:57 +02:00
}
else
{
_hasTalkedWhileOvercaffeinated = false ;
}
2024-04-07 03:38:32 +02:00
if ( ! _isHyperactive & & ! _isOvercaffeinated )
GetComponent < Text2Speech > ( ) . speakingSpeed = 1.1f ;
2024-04-05 19:24:26 +02:00
// https://easings.net/#easeOutCubic
return 1.0 - Math . Pow ( 1.0 - _caffeineLevel , 3.0 ) ;
}
private double CalculateHungerEfficiency ( )
{
2024-04-06 00:57:29 +02:00
if ( _hungerLevel > 1.0 )
return 1.0 ;
2024-04-05 19:24:26 +02:00
// https://easings.net/#easeOutCirc
2024-04-06 00:57:29 +02:00
return Math . Sqrt ( 1.0 - Math . Pow ( _hungerLevel - 1.0 , 2.0 ) ) ;
2024-04-05 19:24:26 +02:00
}
private double CalculateUrinationEfficiency ( )
{
2024-04-06 00:57:29 +02:00
if ( _urgeToUrinateLevel > 1.0 )
return 1.0 ;
2024-04-05 19:24:26 +02:00
// https://easings.net/#easeOutExpo
2024-04-05 19:32:50 +02:00
return Math . Abs ( _urgeToUrinateLevel - 1.0 ) < 0.0001f ? 1.0 : 1.0 - Math . Pow ( 2 , - 10 * _urgeToUrinateLevel ) ;
2024-04-05 19:24:26 +02:00
}
2024-04-06 00:57:29 +02:00
private double CalculateHappinessEfficiency ( )
{
// 50% bei 0 Happiness, 100% bei 0.75 Happiness, 125% bei 1 Happiness
return 0.5 + _happiness * 2.0 / 3.0 ;
}
2024-04-04 18:13:08 +02:00
/// <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 )
2024-04-06 21:43:51 +02:00
{
if ( ! _isDead )
Talk ( $"The developer lost all his fingers duo to an attack by a monster, The developer is dying, The developer gives a short speech with his last words, The developer blames Gottfried for his death" , 0 , true ) ;
2024-04-04 18:13:08 +02:00
Die ( ) ;
2024-04-06 21:43:51 +02:00
}
else
{
if ( _fingersLeft = = 9 )
Talk ( $"The developer lost a finger duo to an attack by a monster, The developer has {_fingersLeft} left, The developer is in pain, The developer is irrevocably less productive now, The developer blames Gottfried for this" , 0 , true ) ;
else
Talk ( $"The developer lost another finger duo to an attack by a monster, The developer has only {_fingersLeft} left, The developer is in pain, The developer is irrevocably less productive now, The developer blames Gottfried for this" , 0 , true ) ;
2024-04-06 22:26:31 +02:00
if ( Random . Range ( 0 , 3 ) < 2 )
2024-04-06 21:43:51 +02:00
_privateContextBuffer . Add ( $"The developer cries for his {10 - _fingersLeft} lost fingers" ) ;
else
2024-04-06 22:26:31 +02:00
_privateContextBuffer . Add ( $"The developer is greatful he still has {_fingersLeft} fingers even tho he had 10 once" ) ;
2024-04-06 21:43:51 +02:00
}
2024-04-04 18:13:08 +02:00
}
private void Die ( )
{
2024-04-06 21:43:51 +02:00
_isDead = true ;
2024-04-04 18:13:08 +02:00
Debug . Log ( $"{Name} ist verreckt." ) ;
2024-04-04 16:33:12 +02:00
}
2024-04-06 16:47:41 +02:00
private bool IsGottfriedInRange ( )
{
float distanceToPlayer = Vector3 . Distance ( transform . position , GameManager . Instance . PlayerTransform . position ) ;
return distanceToPlayer < = _talkRange ;
2024-04-06 21:43:51 +02:00
}
/// <summary>
/// Returns the context stored in the contextBuffer seperated with ',' as a string
/// </summary>
/// <returns></returns>
public string GetPrivateContextAsString ( )
{
if ( _privateContextBuffer . Count ! = 0 )
{
string output = "" ;
foreach ( string context in _privateContextBuffer )
{
output + = context + ", " ;
}
return output ;
}
return string . Empty ;
}
2024-04-06 16:47:41 +02:00
/// <summary>
/// Starts talking when player is near to the Dev.
/// </summary>
public void TalkIfInRange ( )
{
2024-04-07 03:38:32 +02:00
if ( IsGottfriedInRange ( ) & & ! _isDead & & ! _isSleeping & & ( _needList . Count = = 0 ) )
2024-04-06 16:47:41 +02:00
{
2024-04-06 21:43:51 +02:00
string context = GetPrivateContextAsString ( ) ;
context + = GameManager . Instance . GetContextAsString ( ) ;
Talk ( context ) ;
2024-04-06 16:47:41 +02:00
}
}
/// <summary>
/// Dev starts talking.
/// </summary>
2024-04-06 21:43:51 +02:00
public void Talk ( string context , int shortnessLevel = 0 , bool priority = false )
2024-04-06 16:47:41 +02:00
{
2024-04-06 21:43:51 +02:00
if ( priority )
2024-04-06 20:02:57 +02:00
{
2024-04-06 21:43:51 +02:00
_audioSource . Stop ( ) ;
_audioSource . clip = null ;
2024-04-06 20:02:57 +02:00
}
2024-04-06 16:47:41 +02:00
if ( ! _audioSource . isPlaying )
2024-04-06 21:43:51 +02:00
{
GetComponent < Text2Speech > ( ) . Generate ( context , shortnessLevel ) ;
2024-04-06 16:47:41 +02:00
}
}
2024-04-04 15:26:31 +02:00
}