Files
ParanormalEstateAgent/Assets/Scripts/Managers/LevelManager.cs
2026-02-16 17:41:09 +00:00

228 lines
7.1 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using System;
[System.Serializable]
public class Objective
{
public string name;
public string description;
public bool isCompleted;
public int totalItems;
public int checkedItems;
public int brokenItems;
public Objective(string name, string description, int totalItems = 0)
{
this.name = name;
this.description = description;
this.isCompleted = false;
this.totalItems = totalItems;
this.checkedItems = 0;
this.brokenItems = 0;
}
}
public class LevelManager : MonoBehaviour
{
public static LevelManager Instance { get; private set; }
[Header("Level Objectives")]
[SerializeField] private List<Objective> objectives = new List<Objective>();
private Dictionary<string, Objective> objectiveDict = new Dictionary<string, Objective>();
private HashSet<GameObject> checkedObjects = new HashSet<GameObject>();
// Event that UI can subscribe to for showing the review prompt
public event Action<GameObject, Action<bool>> OnRequestReview;
// Event that fires when an objective is completed
public event Action<string> OnObjectiveCompleted;
private GameObject currentReviewObject;
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
InitializeObjectives();
}
private void InitializeObjectives()
{
// Clear existing objectives
objectives.Clear();
objectiveDict.Clear();
checkedObjects.Clear();
// Add all objectives with item counts
AddObjective("doors", "Check all doors open and close", CountObjectsWithTag("Door"));
AddObjective("light_switches", "Check all light switches turn on and off", CountObjectsWithTag("LightSwitch"));
AddObjective("lights", "Check all lights turn on and off", CountObjectsWithTag("Light"));
AddObjective("toilets", "Check toilets work", CountObjectsWithTag("Toilet"));
AddObjective("oven", "Check oven works", CountObjectsWithTag("Oven"));
AddObjective("taps", "Check tap and sinks work", CountObjectsWithTag("Tap"));
AddObjective("no_damage", "Check no damage to property", 1);
}
private int CountObjectsWithTag(string tag)
{
GameObject[] objects = GameObject.FindGameObjectsWithTag(tag);
return objects != null ? objects.Length : 0;
}
private void AddObjective(string key, string description, int totalItems = 0)
{
Objective objective = new Objective(key, description, totalItems);
objectives.Add(objective);
objectiveDict[key] = objective;
}
public void CompleteObjective(string objectiveKey)
{
if (objectiveDict.ContainsKey(objectiveKey))
{
objectiveDict[objectiveKey].isCompleted = true;
Debug.Log($"Objective completed: {objectiveDict[objectiveKey].description}");
OnObjectiveCompleted?.Invoke(objectiveKey);
CheckAllObjectivesComplete();
}
else
{
Debug.LogWarning($"Objective '{objectiveKey}' not found!");
}
}
public bool IsObjectiveComplete(string objectiveKey)
{
return objectiveDict.ContainsKey(objectiveKey) && objectiveDict[objectiveKey].isCompleted;
}
public List<Objective> GetAllObjectives()
{
return objectives;
}
public int GetCompletedCount()
{
int count = 0;
foreach (var objective in objectives)
{
if (objective.isCompleted) count++;
}
return count;
}
private void CheckAllObjectivesComplete()
{
if (GetCompletedCount() == objectives.Count)
{
Debug.Log("All objectives completed!");
OnAllObjectivesComplete();
}
}
private void OnAllObjectivesComplete()
{
// Add logic for what happens when all objectives are complete
// e.g., show completion UI, unlock exit, etc.
}
// Called by objects AFTER their OnInteract() is triggered
public void RequestReview(GameObject reviewObject)
{
// Check if already reviewed
if (checkedObjects.Contains(reviewObject))
{
Debug.Log($"{reviewObject.name} has already been checked!");
return;
}
currentReviewObject = reviewObject;
Debug.Log($"RequestReview: {reviewObject.name} has tag '{reviewObject.tag}'");
// Invoke event for UI to show prompt
if (OnRequestReview != null)
{
OnRequestReview.Invoke(reviewObject, HandleReviewResponse);
}
else
{
Debug.LogError("LevelManager: OnRequestReview event has NO subscribers! UI will not show.");
}
}
// For testing - reset checked objects
[ContextMenu("Reset All Checked Objects")]
public void ResetCheckedObjects()
{
checkedObjects.Clear();
foreach (var objective in objectives)
{
objective.checkedItems = 0;
objective.brokenItems = 0;
objective.isCompleted = false;
}
Debug.Log("All checked objects and progress reset!");
}
private void HandleReviewResponse(bool isBroken)
{
if (currentReviewObject == null) return;
// Mark as checked
checkedObjects.Add(currentReviewObject);
// Determine which objective this belongs to
string objectiveKey = GetObjectiveKeyFromTag(currentReviewObject.tag);
if (!string.IsNullOrEmpty(objectiveKey) && objectiveDict.ContainsKey(objectiveKey))
{
Objective objective = objectiveDict[objectiveKey];
objective.checkedItems++;
if (isBroken)
{
objective.brokenItems++;
Debug.Log($"{currentReviewObject.name} marked as BROKEN");
}
else
{
Debug.Log($"{currentReviewObject.name} marked as OK");
}
// Check if all items for this objective are checked
if (objective.checkedItems >= objective.totalItems && objective.totalItems > 0)
{
CompleteObjective(objectiveKey);
}
Debug.Log($"Progress for '{objectiveKey}': {objective.checkedItems}/{objective.totalItems} ({objective.brokenItems} broken)");
}
else
{
Debug.LogWarning($"No objective found for object '{currentReviewObject.name}' with tag '{currentReviewObject.tag}'");
}
currentReviewObject = null;
}
private string GetObjectiveKeyFromTag(string tag)
{
switch (tag)
{
case "Door": return "doors";
case "LightSwitch": return "light_switches";
case "Light": return "lights";
case "Toilet": return "toilets";
case "Oven": return "oven";
case "Tap": return "taps";
default: return null;
}
}
}