using Godot; using System; using System.Collections.Generic; using System.Linq; using Cirno.Scripts; using Cirno.Scripts.Resources; public partial class InventoryManager : Node2D { public static InventoryManager Instance { get; private set; } public bool RedKeycard { get; set; } private Dictionary _itemsDict = new Dictionary(); public List Items => _itemsDict.Where(x => x.Value.Count > 0).Select(x => x.Value).ToList(); [Signal] public delegate void ItemAddedEventHandler(LootItem item, int currentAmount); [Signal] public delegate void ItemRemovedEventHandler(string itemKey, int currentAmount); [Signal] public delegate void WeaponEquipEventHandler(string itemKey); [Signal] public delegate void ItemUsedEventHandler(LootItem itemKey, int totalCount); [Signal] public delegate void TotalAmmoChangedEventHandler(StringName ammoKey, int count); [Signal] public delegate void LoadedAmmoChangedEventHandler(StringName weaponKey, int count); public override void _Ready() { Instance = this; } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { } public bool TryGetItem(string key, out ItemContainer item) { return _itemsDict.TryGetValue(key, out item); } public bool HasItems(List itemKeys) { return itemKeys.Aggregate(false, (current, item) => current || GetItemCount(item) > 0); } public int GetItemCount(string itemKey) { return _itemsDict.TryGetValue(itemKey, out var itm) ? itm.Count : 0; } public int RemoveItem(string itemKey, int amount) { if (!_itemsDict.TryGetValue(itemKey, out var itm)) return 0; int removed = Math.Min(itm.Count, amount); itm.Count -= amount; if (itm.Count <= 0) { _itemsDict.Remove(itemKey); } EmitSignal(SignalName.ItemRemoved, itemKey, itm.Count); if (itm.Item.Item is ItemTypes.Ammo) { EmitSignal(SignalName.TotalAmmoChanged, itemKey, itm.Count); } return removed; } public bool AddItem(LootItem item) { //var item = new LootItem() { Item = type, Amount = amount }; if (!_itemsDict.TryGetValue(item.ItemKey, out var itm)) { _itemsDict.Add(item.ItemKey, new ItemContainer() { Item = item, Count = item.Amount, }); GD.Print($"Added new ({item.ItemKey}) {item.Item} x{item.Amount}"); EmitSignal(SignalName.ItemAdded, item, item.Amount); } else { if (itm.Count < item.Max) { itm.Count += item.Amount; } else { if (item.PickupIfMaxed) { itm.Count = item.Max; } else { return false; } } EmitSignal(SignalName.ItemAdded, item, itm.Count); } return true; } public void AddRedKeycard() { RedKeycard = true; } public void RemoveRedKeycard() { RedKeycard = false; } public bool UseItem(string itemKey) { if (!_itemsDict.TryGetValue(itemKey, out var itm)) return false; if (itm.Count == 0) return false; GD.Print($"Used item in manager {itemKey}"); switch (itm.Item.Item) { case ItemTypes.Medkit: // Heal case ItemTypes.FrogBomb: // Use Bomb case ItemTypes.Bomb: // Bomb case ItemTypes.Mine: case ItemTypes.Battery: EmitSignal(SignalName.ItemUsed, itm.Item, itm.Count); break; case ItemTypes.Weapon: // Equip weapon EmitSignal(SignalName.WeaponEquip, itm.Item.ItemKey); break; } return true; } public void NotifyLoadedAmmoChange(string weaponDataItemKey, int loadedAmmo) { EmitSignal(SignalName.LoadedAmmoChanged, weaponDataItemKey, loadedAmmo); } } public class ItemContainer { public LootItem Item { get; set; } public int Count { get; set; } }