using UnityEngine;
using System.Collections.Generic;
///
/// Manages checkpoint saving and loading for respawn system
///
public class CheckpointSystem : MonoBehaviour
{
public static CheckpointSystem Instance { get; private set; }
[Header("References")]
public TeamCohesionManager cohesionManager;
public Transform playerTransform;
public GridMovement playerMovement;
[Header("Checkpoint Settings")]
public bool autoSaveOnCheckpoint = true;
public float checkpointRadius = 3f;
// Saved checkpoint data
private Vector3 savedPlayerPosition;
private Quaternion savedPlayerRotation;
private int savedFloorLevel;
private List savedCharacters = new List();
private bool hasCheckpoint = false;
[System.Serializable]
private class SavedCharacterData
{
public CharacterInGroup character;
public int hp;
public int fatigue;
public int mana;
public int gridX;
public int gridY;
public SavedCharacterData(CharacterInGroup chara)
{
character = chara;
hp = chara.currentHP;
fatigue = chara.currentFatigue;
mana = chara.currentMana;
gridX = chara.gridX;
gridY = chara.gridY;
}
}
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
}
private void Start()
{
if (cohesionManager == null)
cohesionManager = FindFirstObjectByType();
if (playerTransform == null)
{
GameObject player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
playerTransform = player.transform;
}
if (playerMovement == null)
playerMovement = FindFirstObjectByType();
}
///
/// Save current game state as a checkpoint
///
public void SaveCheckpoint()
{
if (playerTransform == null)
{
Debug.LogWarning("[CheckpointSystem] Cannot save checkpoint: playerTransform is null");
return;
}
if (cohesionManager == null)
{
Debug.LogWarning("[CheckpointSystem] Cannot save checkpoint: cohesionManager is null");
return;
}
// Save player position and rotation
savedPlayerPosition = playerTransform.position;
savedPlayerRotation = playerTransform.rotation;
// Save floor level if available
if (playerMovement != null)
savedFloorLevel = playerMovement.currentFloorLevel;
// Save all character data
savedCharacters.Clear();
foreach (var character in cohesionManager.groupMembers)
{
savedCharacters.Add(new SavedCharacterData(character));
}
hasCheckpoint = true;
Debug.Log($"[CheckpointSystem] ✓ Checkpoint saved at {savedPlayerPosition} with {savedCharacters.Count} characters");
}
///
/// Save checkpoint at specific position
///
public void SaveCheckpointAt(Vector3 position, Quaternion rotation)
{
savedPlayerPosition = position;
savedPlayerRotation = rotation;
if (playerMovement != null)
savedFloorLevel = playerMovement.currentFloorLevel;
// Save all character data
savedCharacters.Clear();
if (cohesionManager != null)
{
foreach (var character in cohesionManager.groupMembers)
{
savedCharacters.Add(new SavedCharacterData(character));
}
}
hasCheckpoint = true;
Debug.Log($"[CheckpointSystem] Manual checkpoint saved at {savedPlayerPosition}");
}
///
/// Load the last checkpoint and restore party
///
public void LoadCheckpoint()
{
if (!hasCheckpoint)
{
Debug.LogWarning("[CheckpointSystem] No checkpoint to load, using default spawn");
LoadDefaultSpawn();
return;
}
Debug.Log("[CheckpointSystem] Loading checkpoint...");
// Restore player position
if (playerTransform != null)
{
playerTransform.position = savedPlayerPosition;
playerTransform.rotation = savedPlayerRotation;
}
// Restore floor level
if (playerMovement != null)
playerMovement.currentFloorLevel = savedFloorLevel;
// Restore all characters
RestoreCharacters();
Debug.Log($"[CheckpointSystem] Checkpoint loaded: {savedCharacters.Count} characters restored");
}
private void RestoreCharacters()
{
if (cohesionManager == null)
{
Debug.LogError("[CheckpointSystem] CohesionManager not found!");
return;
}
// Clear any dead characters from the current party
cohesionManager.groupMembers.Clear();
// Restore all saved characters
foreach (var saved in savedCharacters)
{
CharacterInGroup character = saved.character;
// Restore stats to saved values (full health at checkpoint)
character.currentHP = character.maxHP; // Always restore to full HP
character.currentFatigue = character.maxFatigue; // Full stamina
character.currentMana = character.maxMana; // Full mana
// Restore grid position
character.gridX = saved.gridX;
character.gridY = saved.gridY;
// Add back to party
cohesionManager.groupMembers.Add(character);
Debug.Log($"[CheckpointSystem] Restored character: {character.characterName} with {character.currentHP}/{character.maxHP} HP");
}
// Recreate UI for all characters
RecreatePartyUI();
Debug.Log($"[CheckpointSystem] Finished restoring {savedCharacters.Count} characters");
}
///
/// Recreate the party UI after respawn
///
private void RecreatePartyUI()
{
Debug.Log("[CheckpointSystem] Recreating party UI...");
PartyUIManager partyUI = FindFirstObjectByType();
if (partyUI != null)
{
// Rebuild UI for all characters using existing method
partyUI.DisplayPartyUI();
Debug.Log("[CheckpointSystem] Party UI recreated successfully");
}
else
{
Debug.LogWarning("[CheckpointSystem] PartyUIManager not found, cannot recreate UI");
}
}
///
/// Load default spawn point if no checkpoint exists
///
private void LoadDefaultSpawn()
{
// Use current position as default or find a spawn point
GameObject spawnPoint = GameObject.FindGameObjectWithTag("SpawnPoint");
if (spawnPoint != null && playerTransform != null)
{
playerTransform.position = spawnPoint.transform.position;
playerTransform.rotation = spawnPoint.transform.rotation;
Debug.Log("[CheckpointSystem] Loaded default spawn point");
}
else if (playerTransform != null)
{
// Just restore characters at current position
Debug.Log("[CheckpointSystem] No spawn point, restoring at current position");
}
// Restore all party members to full health
if (cohesionManager != null)
{
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);
}
}
}
///
/// Check if player is near a checkpoint trigger
///
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Checkpoint") && autoSaveOnCheckpoint)
{
SaveCheckpoint();
// Optional: Show checkpoint saved message
Debug.Log("[CheckpointSystem] Checkpoint reached!");
}
}
public bool HasCheckpoint() => hasCheckpoint;
public Vector3 GetCheckpointPosition() => savedPlayerPosition;
}