using System.Collections;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// GAME 1303 Tier 1 — Handles death, lives, and respawning at the last checkpoint.
///
/// SETUP
/// 1. One empty GameObject in the scene named "RespawnManager" with this script.
/// 2. Drag the player into the Player slot (or leave empty — it finds the "Player" tag).
/// 3. On the player's Health component, add an OnDied event -> RespawnManager.OnPlayerDied.
/// 4. Lives: set Use Lives = true and Starting Lives = 3 for Cutthroat Course style;
/// leave it false for unlimited (Zap Attack style).
/// 5. When lives run out, OnGameOver fires — hook SceneLoader.ReloadCurrent or a Game Over UI.
///
/// The player's starting position is used as the first checkpoint automatically.
/// </summary>
public class RespawnManager : MonoBehaviour
{
public static RespawnManager Instance { get; private set; }
[Header("References")]
public GameObject player;
[Header("Timing")]
[Tooltip("Delay before the player reappears — lets the death animation/SFX play.")]
public float respawnDelay = 1f;
[Header("Lives")]
public bool useLives = false;
public int startingLives = 3;
[Header("Events")]
public UnityEvent<int> OnLivesChanged; // HUD
public UnityEvent OnRespawned;
public UnityEvent OnGameOver;
public int Lives { get; private set; }
public Checkpoint CurrentCheckpoint { get; private set; }
private Vector3 fallbackSpawn;
private Health playerHealth;
private PlayerController2D controller;
private bool respawning;
void Awake()
{
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
Instance = this;
}
void Start()
{
if (player == null) player = GameObject.FindGameObjectWithTag("Player");
if (player == null) { Debug.LogWarning("RespawnManager: no Player found."); return; }
playerHealth = player.GetComponent<Health>();
controller = player.GetComponent<PlayerController2D>();
fallbackSpawn = player.transform.position;
Lives = startingLives;
OnLivesChanged?.Invoke(Lives);
}
public void SetCheckpoint(Checkpoint cp)
{
if (CurrentCheckpoint != null) CurrentCheckpoint.Deactivate();
CurrentCheckpoint = cp;
cp.Activate();
}
/// <summary>Wire this to the player's Health.OnDied event.</summary>
public void OnPlayerDied()
{
if (respawning) return;
if (useLives)
{
Lives--;
OnLivesChanged?.Invoke(Lives);
if (Lives <= 0)
{
OnGameOver?.Invoke();
return;
}
}
StartCoroutine(RespawnRoutine());
}
IEnumerator RespawnRoutine()
{
respawning = true;
if (controller != null) controller.InputEnabled = false;
yield return new WaitForSeconds(respawnDelay);
RespawnPlayerNow();
respawning = false;
}
/// <summary>Teleport the player to the checkpoint and restore them immediately.</summary>
public void RespawnPlayerNow()
{
Vector3 pos = CurrentCheckpoint != null ? CurrentCheckpoint.SpawnPosition : fallbackSpawn;
player.transform.position = pos;
if (controller != null)
{
controller.ResetMotion();
controller.InputEnabled = true;
}
playerHealth?.ResetHealth();
OnRespawned?.Invoke();
}
}