using UnityEngine; using System.Collections; public class GameManager : MonoBehaviour { public static GameManager Instance { get; private set; } [Header("References")] public TeamCohesionManager cohesionManager; public CheckpointSystem checkpointSystem; public DeathScreenUI deathScreenUI; public GridMovement playerMovement; [Header("Death & Respawn Settings")] public float deathDelay = 2f; public float respawnFadeTime = 1f; public bool resetMonstersOnRespawn = false; [Header("Optional Penalties")] public bool applyGoldPenalty = false; public float goldPenaltyPercent = 0f; private bool isPlayerDead = false; private CanvasGroup fadeCanvasGroup; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; CreateFadeOverlay(); } private void Start() { FindReferences(); ValidateSetup(); } private void FindReferences() { if (cohesionManager == null) cohesionManager = FindFirstObjectByType(); if (checkpointSystem == null) checkpointSystem = FindFirstObjectByType(); if (deathScreenUI == null) deathScreenUI = FindFirstObjectByType(); if (playerMovement == null) playerMovement = FindFirstObjectByType(); } private void ValidateSetup() { bool hasAllReferences = cohesionManager != null && checkpointSystem != null && deathScreenUI != null && playerMovement != null; } public void OnPartyWiped() { if (isPlayerDead) return; isPlayerDead = true; StartCoroutine(HandleDeathSequence()); } private IEnumerator HandleDeathSequence() { if (playerMovement != null) playerMovement.enabled = false; StopAllMonsterAttacks(); yield return new WaitForSeconds(deathDelay); yield return StartCoroutine(FadeToBlack(respawnFadeTime)); if (deathScreenUI != null) { deathScreenUI.Show(); } else { RespawnParty(); } } public void RespawnParty() { StartCoroutine(RespawnSequence()); } private IEnumerator RespawnSequence() { if (deathScreenUI != null) deathScreenUI.Hide(); yield return new WaitForSeconds(0.2f); if (checkpointSystem != null) { checkpointSystem.LoadCheckpoint(); } else { BasicRespawn(); } if (applyGoldPenalty && goldPenaltyPercent > 0) ApplyGoldPenalty(); if (resetMonstersOnRespawn) ResetMonsters(); yield return new WaitForSeconds(0.3f); yield return StartCoroutine(FadeFromBlack(respawnFadeTime)); if (playerMovement != null) playerMovement.enabled = true; isPlayerDead = false; } private void BasicRespawn() { if (cohesionManager == null || cohesionManager.groupMembers == null) return; foreach (var character in cohesionManager.groupMembers) { character.currentHP = character.maxHP; character.currentFatigue = character.maxFatigue; character.currentMana = character.maxMana; UIUpdater.Instance?.UpdateCharacterHP(character); UIUpdater.Instance?.UpdateCharacterFatigue(character); } } private void StopAllMonsterAttacks() { MonsterFormationGroup[] monsterGroups = FindObjectsByType(FindObjectsSortMode.None); foreach (var group in monsterGroups) { group.StopAllCoroutines(); group.isChasing = false; group.hasDetectedPlayer = false; foreach (var monster in group.frontRow) { if (monster != null) monster.StopMove(); } foreach (var monster in group.backRow) { if (monster != null) monster.StopMove(); } } } private void ResetMonsters() { MonsterFormationGroup[] monsterGroups = FindObjectsByType(FindObjectsSortMode.None); foreach (var group in monsterGroups) { group.StopAllCoroutines(); group.isChasing = false; group.hasDetectedPlayer = false; } } private void ApplyGoldPenalty() { // TODO: Implement gold penalty when currency system exists } private void CreateFadeOverlay() { GameObject fadeObj = new GameObject("FadeOverlay"); fadeObj.transform.SetParent(transform); Canvas canvas = fadeObj.AddComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvas.sortingOrder = 100; fadeCanvasGroup = fadeObj.AddComponent(); fadeCanvasGroup.alpha = 0f; fadeCanvasGroup.interactable = false; fadeCanvasGroup.blocksRaycasts = false; GameObject panel = new GameObject("BlackPanel"); panel.transform.SetParent(fadeObj.transform, false); UnityEngine.UI.Image image = panel.AddComponent(); image.color = Color.black; RectTransform rect = panel.GetComponent(); rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.sizeDelta = Vector2.zero; } private IEnumerator FadeToBlack(float duration) { float elapsed = 0f; while (elapsed < duration) { elapsed += Time.deltaTime; fadeCanvasGroup.alpha = Mathf.Lerp(0f, 1f, elapsed / duration); yield return null; } fadeCanvasGroup.alpha = 1f; } private IEnumerator FadeFromBlack(float duration) { float elapsed = 0f; while (elapsed < duration) { elapsed += Time.deltaTime; fadeCanvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / duration); yield return null; } fadeCanvasGroup.alpha = 0f; } public bool IsPlayerDead() => isPlayerDead; }