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

281 lines
8.7 KiB
C#
Raw Permalink Normal View History

2024-04-05 19:24:26 +02:00
using System;
2024-04-04 12:14:58 +02:00
using System.Collections;
using System.Collections.Generic;
2024-04-04 15:26:31 +02:00
using System.Linq;
using UnityEditor;
2024-04-04 12:14:58 +02:00
using UnityEngine;
using Utility;
using Microsoft.VisualStudio.Utilities;
2024-04-04 12:14:58 +02:00
public partial class GameManager : MonoBehaviourSingleton<GameManager>
2024-04-04 12:14:58 +02:00
{
2024-04-05 19:24:26 +02:00
[SerializeField] private Difficulty _difficulty = Difficulty.Medium;
public GameObject NeedFullfilledParticleEffect;
public GameObject ZombieDeathByDisableParticleEffect;
[SerializeField]
public List<GameObject> Needs = new List<GameObject>();
[SerializeField]
2024-04-07 00:09:53 +02:00
private Character _player;
2024-04-04 15:26:31 +02:00
[SerializeField]
private double _totalGameDurationSeconds;
2024-04-04 15:26:31 +02:00
[SerializeField]
private double _remainingGameDurationSeconds = 0.0;
2024-04-04 15:26:31 +02:00
[SerializeField, ShowOnly]
private double _currentEfficiency = 0.0;
2024-04-05 19:24:26 +02:00
[SerializeField]
private double _generalNeedDrainScaling = 0.001;
2024-04-04 15:26:31 +02:00
[SerializeField]
private List<Developer> _developers = new();
2024-04-04 18:05:27 +02:00
[SerializeField]
private MultiFalsableBool _gameRunning = new(false);
2024-04-05 19:24:26 +02:00
[SerializeField, Tooltip("Der Schwellwert am dem eine Benachrichtigung für das Bedürfnis ausgelöst wird.")]
private double _needNotificationThreshold = 0.25;
[SerializeField]
private DifficultySettings _difficultySettings;
[SerializeField]
2024-04-06 21:43:51 +02:00
private int _maxContextBufferSize = 3;
[SerializeField]
private CircularBuffer<string> _contextBuffer;
public CircularBuffer<string> ContextBuffer => _contextBuffer;
public Difficulty Difficulty => _difficulty;
2024-04-05 19:24:26 +02:00
public double NeedNotificationThreshold => _needNotificationThreshold;
2024-04-07 00:09:53 +02:00
public Character Player => _player;
/// <summary>
/// Die Transform des Spielers.
/// </summary>
public Transform PlayerTransform => _player.transform;
2024-04-05 19:24:26 +02:00
2024-04-04 15:26:31 +02:00
/// <summary>
2024-04-04 18:05:27 +02:00
/// Wie weit das Spiel bereits fortgeschritten ist.
2024-04-04 15:26:31 +02:00
/// </summary>
public double GameProgress => 1.0 - (_remainingGameDurationSeconds / _totalGameDurationSeconds);
2024-04-04 15:26:31 +02:00
/// <summary>
/// Wie Effizient das Team derzeit arbeitet.
/// </summary>
public double CurrentEfficiency => _currentEfficiency;
/// <summary>
2024-04-04 18:05:27 +02:00
/// Wie viele Sekunden das Spiel voraussichtlich noch dauern wird, würde die Effizienz sich nicht verändern.
2024-04-04 15:26:31 +02:00
/// </summary>
public double ExpectedRemainingGameDuration => _remainingGameDurationSeconds / _currentEfficiency;
2024-04-04 18:05:27 +02:00
2024-04-09 02:47:54 +02:00
private bool _isStarted;
2024-04-09 10:30:34 +02:00
private float _randomContextTimer = 20f;
private List<string> _randomContextList = new List<string>() { "The Developer finally fixed a bug that bothered him a lot",
"The Developer tells Gottfried that Richard farted again",
"The Developer is struggling really hard to solve the bug",
"The Developer tells Gottfried about his lovely cat Mautzi",
"The Developer is afraid Zombies might come around",
"The Developer is curious about how Gottfrieds day was so far",
"The Developer blames Gottfried for some random nonsense"};
2024-04-09 02:47:54 +02:00
2024-04-04 18:05:27 +02:00
public bool IsGameRunning => _gameRunning.IsTrue;
2024-04-09 02:47:54 +02:00
public bool IsStarted => _isStarted;
2024-04-04 15:26:31 +02:00
private void Start()
2024-04-04 18:05:27 +02:00
{
2024-04-09 02:47:54 +02:00
//StartGame();
2024-04-04 18:05:27 +02:00
}
2024-04-09 10:30:34 +02:00
private void Update()
{
_randomContextTimer -= Time.deltaTime;
if (_randomContextTimer < 0)
{
_randomContextTimer = 30f;
AddContext(_randomContextList.GetRandomElement());
}
}
2024-04-04 18:05:27 +02:00
/// <summary>
/// Startet ein neues Spiel.
/// </summary>
[ContextMenu("Start Game")]
2024-04-09 02:47:54 +02:00
public void StartGame()
{
2024-04-09 02:47:54 +02:00
_isStarted = true;
TimeManager.Instance.Init();
_contextBuffer = new CircularBuffer<string>(_maxContextBufferSize);
2024-04-06 21:43:51 +02:00
_contextBuffer.Add("The Developer is greatful to work at this office with Gottfried");
_contextBuffer.Add("The Developer excited to develope the new game");
2024-04-05 19:24:26 +02:00
_difficultySettings = _difficulty.GetSettings();
_totalGameDurationSeconds = TimeManager.Instance.CalculateActualDeveloperTime(_difficultySettings, 4);
2024-04-04 18:05:27 +02:00
_remainingGameDurationSeconds = _totalGameDurationSeconds;
2024-04-09 02:47:54 +02:00
ResumeGame();
}
2024-04-04 18:05:27 +02:00
/// <summary>
/// Hebt eine Pausierung auf und setzt das Spiel fort, wenn alle Pausierungen aufgehoben wurden.
/// </summary>
/// <remarks>Hinweis: Für jedes PauseGame muss ein ResumeGame aufgerufen werden.</remarks>
[ContextMenu("Resume Game")]
public void ResumeGame()
{
if (_gameRunning.MakeTruer())
{
InvokeRepeating(nameof(UpdateProgress), 0.0f, 1.0f);
}
}
/// <summary>
/// Pausiert das Spiel. Ist Stapelbar.
/// </summary>
/// <remarks>Hinweis: Für jedes PauseGame muss ein ResumeGame aufgerufen werden.</remarks>
[ContextMenu("Pause Game")]
public void PauseGame()
{
_gameRunning.MakeFalslier();
CancelInvoke(nameof(UpdateProgress));
}
void UpdateProgress()
2024-04-04 12:14:58 +02:00
{
2024-04-04 15:26:31 +02:00
UpdateEfficiency();
UpdateGameDuration();
CheckGameEndConditions();
}
private void CheckGameEndConditions()
{
if (_remainingGameDurationSeconds <= 0.0)
{
EndGame(EndGameCondition.Win_GamePublished);
}
else if (_developers.Count == 0)
{
EndGame(EndGameCondition.Lose_NoDevelopersLeft);
}
else if (TimeManager.Instance.MissedDeadline)
{
EndGame(EndGameCondition.Lose_DeadlineMissed);
}
2024-04-04 15:26:31 +02:00
}
2024-04-08 21:24:13 +02:00
[SerializeField]
private bool _won;
public bool Won => _won;
[SerializeField]
private bool _lost;
public bool Lost => _lost;
private void EndGame(EndGameCondition endGameCondition)
{
if (endGameCondition.IsWin())
{
Debug.Log("You won!");
2024-04-08 21:24:13 +02:00
_won = true;
}
else if (endGameCondition.IsLose())
{
Debug.Log("You lost!");
2024-04-08 21:24:13 +02:00
_lost = true;
}
Debug.Log(endGameCondition.GetEndGameMessage());
PauseGame();
}
2024-04-04 15:26:31 +02:00
void UpdateEfficiency()
{
double developerEfficiency = 0.0f;
// TODO: Und eine weitere absolut nicht handle-bare variable...
2024-04-05 19:24:26 +02:00
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);
2024-04-05 19:24:26 +02:00
foreach (Developer developer in _developers)
{
developer.UpdateStats(caffeineDrain, hungerDrain, urinationDrain, happinessDrain);
developer.UpdateEfficiency();
developerEfficiency += developer.CurrentEfficiency;
}
_currentEfficiency = developerEfficiency;
2024-04-04 15:26:31 +02:00
}
void UpdateGameDuration()
{
// Entwickler Effizienz ist im Grunde wie viele Entwicklersekunden wir pro Sekunde verrichten können.
_remainingGameDurationSeconds -= _currentEfficiency;
2024-04-04 12:14:58 +02:00
}
/// <summary>
/// Returns the context stored in the contextBuffer seperated with ',' as a string
/// </summary>
/// <returns></returns>
public string GetContextAsString()
{
if (_contextBuffer.Count != 0)
{
string output = "";
foreach (string context in _contextBuffer)
{
output += context + ", ";
}
return output;
}
2024-04-06 21:43:51 +02:00
return string.Empty;
}
/// <summary>
/// Adds the given string to the context
/// </summary>
/// <param name="context"></param>
public void AddContext(string context)
{
_contextBuffer.Add(context);
}
2024-04-07 00:12:15 +02:00
/// <summary>
/// Removes the given string from the context
/// </summary>
/// <param name="context"></param>
public void RemoveContext(string context)
{
if ( _contextBuffer.Contains(context) )
{
List<string> contextAsList = _contextBuffer.ToArray().ToList();
_contextBuffer.Clear();
contextAsList.Remove(context);
foreach (var c in contextAsList)
{
_contextBuffer.Add(c);
}
}
}
2024-04-04 12:14:58 +02:00
}