PuzzleGame/PuzzleGameProject/Assets/Scripts/GameManager.cs
2025-03-04 17:02:03 +01:00

242 lines
6.6 KiB
C#

using System;
using UnityEngine;
using Object = UnityEngine.Object;
using System.Collections.Generic;
using Abilities;
using DungeonSelection;
using TMPro;
using Unity.VisualScripting;
public class EndOfGameEventArgs : EventArgs
{
public EndOfGameEventArgs(
string message,
bool died,
int diamonds,
int pointsFromHealth,
int finalScore)
{
Message = message;
Died = died;
Diamonds = diamonds;
PointsFromHealth = pointsFromHealth;
FinalScore = finalScore;
}
public bool Died { get; private set; }
public int Diamonds { get; private set; }
public readonly int DiamondsMultiplier = 3;
public int PointsFromHealth { get; private set; }
public int FinalScore { get; private set; }
public string Message { get; private set; }
}
public enum GameState
{
RollDice,
PickRoomOne,
PickRoomTwo,
PickDiceOne,
PickDiceTwo,
}
public class GameManager : MonoBehaviour
{
[SerializeField] public static GameState State;
[SerializeField] private GameObject rooms;
[SerializeField] private DiceRoller diceRoller;
[SerializeField] private PassManager passManager;
[SerializeField] private Player player;
[SerializeField] private DungeonData dungeonData;
private DicePair _dicePairOne = new();
private DicePair _dicePairTwo = new();
private int monstersLeft = 0; // Includes boss monster. Used for detecting end of game.
public static event Action<GameState> StateChanged;
public static event Action<DicePair> DiceSelected;
public static event Action DiceUnselected;
public static event EventHandler<EndOfGameEventArgs> EndOfGame;
private void OnEnable()
{
MonsterRoom.MonsterRoomExplored += HandleMonsterRoomExplored;
player.Died += HandlePlayerDied;
}
private void OnDisable()
{
MonsterRoom.MonsterRoomExplored -= HandleMonsterRoomExplored;
player.Died -= HandlePlayerDied;
}
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
DiceRoller.diceRolled += DiceRolled;
passManager.PassRequested += PassRequested;
rooms = GameObject.FindWithTag("RoomsParent");
foreach (Transform roomTransform in rooms.transform)
{
Room roomComponent = roomTransform.gameObject.GetComponent<Room>();
roomComponent.RoomExploredByDice += HandleRoomExploredByDice;
if (roomComponent is MonsterRoom)
{
monstersLeft++;
}
}
foreach (Transform diceTransform in diceRoller.dice.transform)
{
diceTransform.gameObject.GetComponent<Die>().DieSelected += HandleDieSelected;
diceTransform.gameObject.GetComponent<Die>().DieUnselected += HandleDieUnselected;
}
StartNewTurn();
}
private void ChangeState(GameState stateToChangeTo) {
if (State != stateToChangeTo)
{
State = stateToChangeTo;
StateChanged?.Invoke(State);
}
}
private void StartNewTurn()
{
ChangeState(GameState.RollDice);
diceRoller.Enable();
diceRoller.ResetDice();
_dicePairOne = new DicePair();
_dicePairTwo = new DicePair();
}
void HandleRoomExploredByDice(Room room) {
if (State == GameState.PickRoomOne)
{
ChangeState(GameState.PickDiceTwo);
}
else
{
StartNewTurn();
}
}
private void HandleDieSelected(Die die) {
switch (State)
{
case GameState.PickDiceOne:
_dicePairOne.SelectDie(die);
if (_dicePairOne.AreBothDiceSelected())
{
ChangeState(GameState.PickRoomOne);
DiceSelected?.Invoke(_dicePairOne);
}
break;
case GameState.PickDiceTwo:
_dicePairTwo.SelectDie(die);
if (_dicePairTwo.AreBothDiceSelected())
{
ChangeState(GameState.PickRoomTwo);
DiceSelected?.Invoke(_dicePairTwo);
}
break;
default:
return;
}
}
private void HandleDieUnselected(Die die) {
switch (State)
{
case GameState.PickDiceOne:
case GameState.PickRoomOne:
if (State == GameState.PickRoomOne)
{
ChangeState(GameState.PickDiceOne);
}
_dicePairOne.UnselectDie(die);
DiceUnselected?.Invoke();
break;
case GameState.PickDiceTwo:
case GameState.PickRoomTwo:
if (State == GameState.PickRoomTwo)
{
ChangeState(GameState.PickDiceTwo);
}
_dicePairTwo.UnselectDie(die);
DiceUnselected?.Invoke();
break;
}
}
private void PassTurn() {
player.TakeDamage(1);
StartNewTurn();
}
private void DiceRolled(object sender, EventArgs e)
{
if (State == GameState.RollDice)
{
diceRoller.Disable();
ChangeState(GameState.PickDiceOne);
}
}
private void PassRequested(object sender, EventArgs e) {
switch (State)
{
case GameState.PickDiceOne:
case GameState.PickDiceTwo:
case GameState.PickRoomOne:
case GameState.PickRoomTwo:
PassTurn();
break;
default:
return;
}
}
private void HandleMonsterRoomExplored()
{
monstersLeft--;
if (monstersLeft <= 0)
{
ResolveEndOfGame(true);
}
}
private void HandlePlayerDied()
{
ResolveEndOfGame(false);
}
private void ResolveEndOfGame(bool allMonstersKilled)
{
string message;
if (allMonstersKilled)
{
message = dungeonData.WinMessage;
}
else
{
message = dungeonData.DieMessage;
}
int finalScore = CalculateScore();
Debug.Log($"Final score: {finalScore}");
EndOfGame?.Invoke(this, new EndOfGameEventArgs(
message,
!allMonstersKilled,
player.GetDiamondCount(),
player.GetHealthScore(),
finalScore));
}
private int CalculateScore()
{
int sum = 0;
sum += player.GetDiamondCount() * 3;
sum += player.GetHealthScore();
return sum;
}
}