using UnityEngine;
using System.Collections;
using System.Collections.Generic;
///
/// Central manager for game state, death, and respawn logic
///
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 Settings")]
public float deathDelay = 2f; // Time before showing death screen
public float respawnFadeTime = 1f;
public bool resetMonstersOnRespawn = false;
[Header("Respawn Penalties (Optional)")]
public bool applyGoldPenalty = false;
public float goldPenaltyPercent = 0f; // 0 = no penalty
private bool isPlayerDead = false;
private CanvasGroup fadeCanvasGroup;
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
// Create fade overlay if it doesn't exist
CreateFadeOverlay();
}
private void Start()
{
if (cohesionManager == null)
cohesionManager = FindFirstObjectByType();
if (checkpointSystem == null)
checkpointSystem = FindFirstObjectByType();
if (deathScreenUI == null)
deathScreenUI = FindFirstObjectByType();
if (playerMovement == null)
playerMovement = FindFirstObjectByType();
// Verify setup
ValidateSetup();
}
private void ValidateSetup()
{
Debug.Log("=== GameManager Setup Validation ===");
Debug.Log($"Cohesion Manager: {(cohesionManager != null ? "✓ Assigned" : "✗ MISSING")}");
Debug.Log($"Checkpoint System: {(checkpointSystem != null ? "✓ Assigned" : "✗ MISSING")}");
Debug.Log($"Death Screen UI: {(deathScreenUI != null ? "✓ Assigned" : "✗ MISSING")}");
Debug.Log($"Player Movement: {(playerMovement != null ? "✓ Assigned" : "✗ MISSING")}");
if (cohesionManager == null || checkpointSystem == null || deathScreenUI == null || playerMovement == null)
{
Debug.LogError("[GameManager] Some references are missing! Respawn system may not work correctly.");
}
else
{
Debug.Log("[GameManager] All references validated successfully!");
}
}
///
/// Called when all party members have died
///
public void OnPartyWiped()
{
if (isPlayerDead) return; // Prevent multiple triggers
isPlayerDead = true;
Debug.Log("[GameManager] Party wiped! Initiating death sequence...");
StartCoroutine(HandleDeathSequence());
}
private IEnumerator HandleDeathSequence()
{
// Disable player input
if (playerMovement != null)
playerMovement.enabled = false;
// Stop all monster attacks
StopAllMonsterAttacks();
// Wait a moment for dramatic effect
yield return new WaitForSeconds(deathDelay);
// Fade to black
yield return StartCoroutine(FadeToBlack(respawnFadeTime));
// Show death screen
if (deathScreenUI != null)
{
deathScreenUI.Show();
}
else
{
Debug.LogWarning("[GameManager] Death Screen UI not found, auto-respawning...");
RespawnParty();
}
}
///
/// Respawn the party at the last checkpoint
///
public void RespawnParty()
{
Debug.Log("[GameManager] Respawning party...");
StartCoroutine(RespawnSequence());
}
private IEnumerator RespawnSequence()
{
Debug.Log("[GameManager] RespawnSequence started");
// Hide death screen if visible
if (deathScreenUI != null)
{
deathScreenUI.Hide();
Debug.Log("[GameManager] Death screen hidden");
}
// Small delay for UI to hide
yield return new WaitForSeconds(0.2f);
// Load checkpoint data
if (checkpointSystem != null)
{
Debug.Log("[GameManager] Loading checkpoint...");
checkpointSystem.LoadCheckpoint();
}
else
{
Debug.LogWarning("[GameManager] No CheckpointSystem found, performing basic respawn");
BasicRespawn();
}
// Apply penalties if enabled
if (applyGoldPenalty && goldPenaltyPercent > 0)
{
ApplyGoldPenalty();
}
// Reset monsters if enabled
if (resetMonstersOnRespawn)
{
ResetMonsters();
}
// Small delay before fade in
yield return new WaitForSeconds(0.3f);
Debug.Log("[GameManager] Starting fade from black...");
// Fade back from black
yield return StartCoroutine(FadeFromBlack(respawnFadeTime));
Debug.Log("[GameManager] Fade complete, re-enabling player controls");
// Re-enable player input
if (playerMovement != null)
playerMovement.enabled = true;
isPlayerDead = false;
Debug.Log("[GameManager] Respawn complete!");
}
///
/// Basic respawn without checkpoint system - restores party to full health
///
private void BasicRespawn()
{
if (cohesionManager == null || cohesionManager.groupMembers == null)
{
Debug.LogError("[GameManager] Cannot respawn: CohesionManager or group members not found");
return;
}
foreach (var character in cohesionManager.groupMembers)
{
character.currentHP = character.maxHP;
character.currentFatigue = character.maxFatigue;
character.currentMana = character.maxMana;
// Update UI
UIUpdater.Instance?.UpdateCharacterHP(character);
UIUpdater.Instance?.UpdateCharacterFatigue(character);
}
}
private void ApplyGoldPenalty()
{
// TODO: Implement gold system penalty if you have a gold/currency system
Debug.Log($"[GameManager] Gold penalty applied: {goldPenaltyPercent}%");
}
private void StopAllMonsterAttacks()
{
// Find all monster formation groups and stop their attacks
MonsterFormationGroup[] monsterGroups = FindObjectsByType(FindObjectsSortMode.None);
foreach (var group in monsterGroups)
{
// Stop their current behavior immediately
group.StopAllCoroutines();
group.isChasing = false;
group.hasDetectedPlayer = false;
// Stop individual monster animations
foreach (var monster in group.frontRow)
{
if (monster != null)
monster.StopMove();
}
foreach (var monster in group.backRow)
{
if (monster != null)
monster.StopMove();
}
Debug.Log($"[GameManager] Stopped attacks from monster group: {group.gameObject.name}");
}
}
private void ResetMonsters()
{
// Find all monster formation groups and reset them
MonsterFormationGroup[] monsterGroups = FindObjectsByType(FindObjectsSortMode.None);
foreach (var group in monsterGroups)
{
// Stop their current behavior
group.StopAllCoroutines();
group.isChasing = false;
group.hasDetectedPlayer = false;
Debug.Log($"[GameManager] Reset monster group: {group.gameObject.name}");
}
}
#region Fade Effects
private void CreateFadeOverlay()
{
// Create a full-screen black overlay for fade effects
GameObject fadeObj = new GameObject("FadeOverlay");
fadeObj.transform.SetParent(transform);
Canvas canvas = fadeObj.AddComponent