Files
AceField-New-Horizon/Scripts/System/ResourceManager.cs
2025-08-29 00:10:19 +08:00

145 lines
4.7 KiB
C#

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<string, int> _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<string, int> GetAllResources()
{
GD.Print($"[{LoggerName}] Getting all resources. Total types: {_resources.Count}");
return new Dictionary<string, int>(_resources);
}
// Clear all resources
public void Clear()
{
GD.Print($"[{LoggerName}] Clearing all resources. Total types before clear: {_resources.Count}");
var keys = new List<string>(_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}");
}
}
}