GameVsJam/3d Prototyp/Assets/Scripts/NPC_Behavior.cs

226 lines
6.6 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using Unity.PlasticSCM.Editor.WebApi;
using UnityEngine;
public class NPC_Behavior : MonoBehaviour
{
[SerializeField] GameObject confettiEffect;
[SerializeField] private double _caffeineLevel = 0.0; // max 100, min 0
[SerializeField] private double _hungerLevel = 0.0; // max 100, min 0
[SerializeField] private double _happinessLevel = 100.0; // max 100, min 0
[SerializeField] private double _baseDevelopementPower = 100.0; // max 100, min 0
[SerializeField] private double _developementPower = 100.0; // max unlimited, min 0
[SerializeField] double eventRate = 1.0; // max 60, min 0 -> how many events are requested per minute
[SerializeField] private float _startTime = 30.0f;
/// <summary>
/// Gibt das Koffeinlevel des Entwicklers zurück
/// </summary>
public double CaffeineLevel => _caffeineLevel;
/// <summary>
/// Gibt das Hungerlevel des Entwicklers zurück
/// </summary>
public double HungerLevel => _hungerLevel;
/// <summary>
/// Gibt das Zufriedenheitslevel des Entwicklers zurück
/// </summary>
public double HappnessLevel => _happinessLevel;
/// <summary>
/// Gibt die Basisentwicklungskraft des Entwicklers zurück
/// </summary>
public double BaseDevelopementPower => _baseDevelopementPower;
/// <summary>
/// Gibt die jetzige Entwicklungskraft des Entwicklers zurück
/// </summary>
public double DevelopmentPower => _developementPower;
private GameManager _gameManager;
private NPC_EventStack _eventStack;
private Text2Speech _text2Speech;
private AudioSource _audioSource;
[SerializeField] private bool _talk = false;
[SerializeField] private bool _fullfillNeedManually = false;
[SerializeField] private float _timer;
[SerializeField] private float _newNeedDelay = 3.0f;
[SerializeField] private List<string> _lastTenNeeds = new List<string>();
private DeveloperNeeds _developerNeeds;
private float _timeBetweenEvents;
private GameObject _currentNeed = null;
private float _newNeedDelayTimer = 0.0f;
private float _effectCreationTime;
private GameObject _effect;
/// <summary>
/// The name of the current need
/// </summary>
public string CurrentNeed => _lastTenNeeds[_lastTenNeeds.Count - 1];
/// <summary>
/// Indicates if the developer has a need right now
/// </summary>
public bool HasNeed = false;
// Start is called before the first frame update
void Start()
{
_gameManager = GameManager.Instance;
_developerNeeds = GetComponent<DeveloperNeeds>();
_eventStack = GetComponent<NPC_EventStack>();
_text2Speech = GetComponent<Text2Speech>();
_audioSource = GetComponent<AudioSource>();
ResetTimer(_startTime);
}
// Update is called once per frame
void Update()
{
WatchEffect();
_timer -= Time.deltaTime;
if (_newNeedDelayTimer <= 0)
{
if (_timer <= 0 && _currentNeed == null)
{
GenerateNeed();
ResetTimer();
}
}
else
{
_newNeedDelayTimer -= Time.deltaTime;
}
// for Debugging
if (_fullfillNeedManually)
{
_fullfillNeedManually = false;
NeedFullfilled();
}
if (_talk)
{
_talk = false;
Talk();
}
}
private void ResetTimer(float startTime = 0.0f)
{
if (eventRate <= 0)
{
_timeBetweenEvents = float.MaxValue;
}
else
{
_timeBetweenEvents = 60f / (float)eventRate;
if (startTime > 0)
{
_timer = startTime;
}
else
{
_timer = Random.Range(0.5f * _timeBetweenEvents, 1.25f * _timeBetweenEvents);
}
}
}
private void WatchEffect()
{
if (_effect != null && GetEffectLifetime() >= 3.0f)
{
RemoveEffect();
}
}
private float GetEffectLifetime()
{
return Time.time - _effectCreationTime;
}
private bool RemoveEffect()
{
Destroy(_effect);
return _effect != null;
}
public bool GenerateNeed()
{
List<string> needs = new List<string>() { "coffee", "mate", "toilet", "money" };
string need = needs[UnityEngine.Random.Range(0, needs.Count)];
_currentNeed = _developerNeeds.spawnNeed(need);
HasNeed = true;
_lastTenNeeds.Add(need);
if (_lastTenNeeds.Count > 10)
{
_lastTenNeeds.RemoveAt(0);
}
return _currentNeed != null;
}
/// <summary>
/// Deletes the current need and its gameobject.
/// </summary>
/// <returns>bool: wether successfully deleted the gameobject or not</returns>
[ContextMenu("Fullfill Need")]
public bool NeedFullfilled()
{
Destroy(_currentNeed);
if (HasNeed)
{
HasNeed = false;
_newNeedDelayTimer = _newNeedDelay;
_effect = Instantiate(confettiEffect, new Vector3(0.0f, 1.5f, 0.0f), confettiEffect.transform.rotation);
_effect.transform.SetParent(transform, false);
_effectCreationTime = Time.time;
}
return _currentNeed == null;
}
public Dictionary<string, double> GetStats()
{
return new Dictionary<string, double>
{
{ "Caffeine", _caffeineLevel },
{ "Hunger", _hungerLevel },
{ "Happiness", _happinessLevel },
{ "Developement Power", _developementPower }
};
}
public void SetStats(Dictionary<string, double> stats)
{
foreach (string key in stats.Keys)
{
switch (key)
{
case "Caffeine":
_caffeineLevel = stats[key];
break;
case "Hunger":
_hungerLevel = stats[key];
break;
case "Happiness":
_happinessLevel = stats[key];
break;
case "Developement Power":
_developementPower = stats[key];
break;
default:
Debug.LogError("Unknown Stat/Key");
break;
}
}
}
public void Talk()
{
//if (!_audioSource.isPlaying)
//{
string context = _eventStack.GetEntireContext();
_text2Speech.Generate(context);
//}
}
}