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 StateChanged; public static event Action DiceSelected; public static event Action DiceUnselected; public static event EventHandler 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(); roomComponent.RoomExploredByDice += HandleRoomExploredByDice; if (roomComponent is MonsterRoom) { monstersLeft++; } } foreach (Transform diceTransform in diceRoller.dice.transform) { diceTransform.gameObject.GetComponent().DieSelected += HandleDieSelected; diceTransform.gameObject.GetComponent().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; } }