228 lines
7.1 KiB
C#
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;
|
|
}
|
|
}
|
|
} |