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; }