using UnityEngine;
using System.Collections;
///
/// Central manager for game state, death, and respawn logic.
/// Handles party wipe detection, death sequence, and respawn coordination.
///
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;
#region Initialization
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;
if (!hasAllReferences)
{
Debug.LogError("[GameManager] Missing references! Respawn system may not work.");
}
}
#endregion
#region Death & Respawn
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
{
Debug.LogWarning("[GameManager] Death Screen UI not found, auto-respawning");
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
{
Debug.LogWarning("[GameManager] CheckpointSystem not found, basic respawn");
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);
}
}
#endregion
#region Monster Management
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
}
#endregion
#region Fade Effects
private void CreateFadeOverlay()
{
GameObject fadeObj = new GameObject("FadeOverlay");
fadeObj.transform.SetParent(transform);
Canvas canvas = fadeObj.AddComponent