using Chickensoft.AutoInject; using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; using System.Collections.Generic; using System.Linq; using Zennysoft.Game.Abstractions; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; [Meta(typeof(IAutoNode)), Id("inventory")] public partial class Inventory : Node, IInventory { public override void _Notification(int what) => this.Notify(what); // TODO: Constants class with export private const int _maxInventorySize = 20; public Inventory() { Items = []; } [Save("inventory_items")] public List Items { get; private set; } public bool TryAdd(InventoryItem inventoryItem) { if (Items.Count >= _maxInventorySize) return false; Items.Add(inventoryItem); return true; } public void Remove(InventoryItem inventoryItem) => Items.Remove(inventoryItem); public void Sort() { var equippedWeapon = Items.OfType().Where(x => x.IsEquipped); var equippedArmor = Items.OfType().Where(x => x.IsEquipped); var equippedAccessory = Items.OfType().Where(x => x.IsEquipped); var equippedItems = new List(); equippedItems.AddRange(equippedWeapon); equippedItems.AddRange(equippedArmor); equippedItems.AddRange(equippedAccessory); var listToSort = Items.Except(equippedItems); var weapons = listToSort.Where(x => x is Weapon).OrderBy(x => x as Weapon, new WeaponComparer()); var armor = listToSort.Where(x => x is Armor).OrderBy(x => x as Armor, new ArmorComparer()); var accessories = listToSort.Where(x => x is Accessory).OrderBy(x => x as Accessory, new AccessoryComparer()); var consumables = listToSort.Where(x => x is ConsumableItem).OrderBy(x => x as ConsumableItem, new ConsumableComparer()); var throwables = listToSort.Where(x => x is ThrowableItem).OrderBy(x => x as ThrowableItem, new ThrowableComparer()); Items = [.. equippedItems, .. weapons, .. armor, .. accessories, .. consumables, .. throwables]; var stackableItems = Items.OfType(); var itemsToStack = stackableItems.GroupBy(x => ((InventoryItem)x).ItemName).Where(x => x.Count() > 1); foreach (var itemStack in itemsToStack) { var firstItem = itemStack.First(); firstItem.SetCount(itemStack.Count()); var itemsToRemove = itemStack.Except([firstItem]).Cast(); Items = [.. Items.Except(itemsToRemove)]; } } public class WeaponComparer : IComparer { public int Compare(Weapon x, Weapon y) { if (x.Damage == y.Damage) return x.ItemName.CompareTo(y.ItemName); return x.Damage < y.Damage ? 1 : -1; } } public class ArmorComparer : IComparer { public int Compare(Armor x, Armor y) { if (x.Defense == y.Defense) return x.ItemName.CompareTo(y.ItemName); return x.Defense < y.Defense ? 1 : -1; } } public class AccessoryComparer : IComparer { public int Compare(Accessory x, Accessory y) { return x.ItemName.CompareTo(y.ItemName); } } public class ConsumableComparer : IComparer { public int Compare(ConsumableItem x, ConsumableItem y) { return x.ItemName.CompareTo(y.ItemName); } } public class ThrowableComparer : IComparer { public int Compare(ThrowableItem x, ThrowableItem y) { return x.ItemName.CompareTo(y.ItemName); } } }