using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// GAME 1303 Tier 1 — Counts everything the player has collected, by ItemType.
///
/// SETUP
/// - One empty GameObject in the scene with this script.
/// - Persist Across Scenes: ON for games where you carry items between levels
/// (Commission Witch, Zap Attack); OFF for single-level games.
/// - OnCountChanged(itemType, newCount) -> HUDController.UpdateItemCount
/// - OnScoreChanged(score) -> HUD score text
///
/// From other scripts:
/// CollectionTracker.Instance.GetCount(nightshade) >= 3 // Door/Lock, RecipeChecker
/// CollectionTracker.Instance.Spend(coin, 10) // shops
/// </summary>
public class CollectionTracker : MonoBehaviour
{
public static CollectionTracker Instance { get; private set; }
public bool persistAcrossScenes = false;
[Header("Events")]
public UnityEvent<ItemType, int> OnCountChanged;
public UnityEvent<int> OnScoreChanged;
public int Score { get; private set; }
private readonly Dictionary<ItemType, int> counts = new Dictionary<ItemType, int>();
void Awake()
{
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
Instance = this;
if (persistAcrossScenes) DontDestroyOnLoad(gameObject);
}
public void Add(ItemType type, int amount = 1)
{
if (type == null) return;
counts.TryGetValue(type, out int current);
counts[type] = current + amount;
OnCountChanged?.Invoke(type, counts[type]);
if (type.scoreValue != 0)
{
Score += type.scoreValue * amount;
OnScoreChanged?.Invoke(Score);
}
}
/// <summary>Remove items. Returns false (and removes nothing) if you don't have enough.</summary>
public bool Spend(ItemType type, int amount)
{
if (GetCount(type) < amount) return false;
counts[type] -= amount;
OnCountChanged?.Invoke(type, counts[type]);
return true;
}
public int GetCount(ItemType type)
{
return type != null && counts.TryGetValue(type, out int c) ? c : 0;
}
public bool Has(ItemType type, int amount = 1) => GetCount(type) >= amount;
public void ResetAll()
{
counts.Clear();
Score = 0;
OnScoreChanged?.Invoke(0);
}
}