using Godot; using System.Collections.Generic; using System.Linq; namespace AceFieldNewHorizon.Scripts.System; public partial class ResourceManager : Node { // Dictionary to store resources with their IDs and quantities private readonly Dictionary _resources = new(); private static readonly StringName LoggerName = "ResourceManager"; // Event for when resource amounts change [Signal] public delegate void OnResourceChangedEventHandler(string resourceId, int newAmount); public override void _Ready() { base._Ready(); GD.Print($"[{LoggerName}] ResourceManager initialized"); } // Add resources of a specific type public void AddResource(string resourceId, int amount = 1) { if (amount <= 0) { GD.PushWarning($"[{LoggerName}] Attempted to add non-positive amount ({amount}) for resource: {resourceId}"); return; } bool isNew = !_resources.ContainsKey(resourceId); if (!_resources.TryAdd(resourceId, amount)) { var oldAmount = _resources[resourceId]; _resources[resourceId] += amount; GD.Print($"[{LoggerName}] Added {amount} {resourceId}. New total: {_resources[resourceId]} (was {oldAmount})"); } else { GD.Print($"[{LoggerName}] Added new resource: {resourceId} with amount: {amount}"); } EmitSignal(nameof(OnResourceChanged), resourceId, _resources[resourceId]); } // Remove resources of a specific type public bool RemoveResource(string resourceId, int amount = 1) { if (amount <= 0) { GD.PushWarning($"[{LoggerName}] Attempted to remove non-positive amount ({amount}) for resource: {resourceId}"); return false; } if (!_resources.ContainsKey(resourceId)) { GD.Print($"[{LoggerName}] Failed to remove {amount} {resourceId}: Resource not found"); return false; } if (_resources[resourceId] < amount) { GD.Print($"[{LoggerName}] Insufficient {resourceId}. Requested: {amount}, Available: {_resources[resourceId]}"); return false; } var oldAmount = _resources[resourceId]; _resources[resourceId] -= amount; GD.Print($"[{LoggerName}] Removed {amount} {resourceId}. New total: {_resources[resourceId]} (was {oldAmount})"); // Remove the entry if quantity reaches zero if (_resources[resourceId] <= 0) { _resources.Remove(resourceId); GD.Print($"[{LoggerName}] Removed resource entry for {resourceId} (reached zero)"); EmitSignal(nameof(OnResourceChanged), resourceId, 0); } else { EmitSignal(nameof(OnResourceChanged), resourceId, _resources[resourceId]); } return true; } // Get the current amount of a specific resource public int GetResourceAmount(string resourceId) { // Silently return 0 for non-existent resources return _resources.GetValueOrDefault(resourceId, 0); } // Check if there are at least 'amount' of a specific resource public bool HasResource(string resourceId, int amount = 1) { if (amount <= 0) return true; // Always true for zero or negative amounts var exists = _resources.TryGetValue(resourceId, out var currentAmount); var hasEnough = exists && currentAmount >= amount; return hasEnough; } // Get all resources as a read-only dictionary public IReadOnlyDictionary GetAllResources() { GD.Print($"[{LoggerName}] Getting all resources. Total types: {_resources.Count}"); return new Dictionary(_resources); } // Clear all resources public void Clear() { GD.Print($"[{LoggerName}] Clearing all resources. Total types before clear: {_resources.Count}"); var keys = new List(_resources.Keys); foreach (var resourceId in keys) { _resources[resourceId] = 0; EmitSignal(nameof(OnResourceChanged), resourceId, 0); } _resources.Clear(); GD.Print($"[{LoggerName}] All resources cleared"); } // Helper method to log current resource state public void LogResourceState() { if (_resources.Count == 0) { GD.Print($"[{LoggerName}] No resources currently stored"); return; } GD.Print($"[{LoggerName}] Current resource state:"); foreach (var (id, amount) in _resources.OrderBy(x => x.Key)) { GD.Print($" - {id}: {amount}"); } } }