Files
GameJamDungeon/Zennysoft.Game.Ma/src/items/Inventory.cs
2025-03-11 16:00:46 -07:00

113 lines
3.4 KiB
C#

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<InventoryItem> 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<Weapon>().Where(x => x.IsEquipped);
var equippedArmor = Items.OfType<Armor>().Where(x => x.IsEquipped);
var equippedAccessory = Items.OfType<Accessory>().Where(x => x.IsEquipped);
var equippedItems = new List<InventoryItem>();
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<IStackable>();
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<InventoryItem>();
Items = [.. Items.Except(itemsToRemove)];
}
}
public class WeaponComparer : IComparer<Weapon>
{
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<Armor>
{
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<Accessory>
{
public int Compare(Accessory x, Accessory y)
{
return x.ItemName.CompareTo(y.ItemName);
}
}
public class ConsumableComparer : IComparer<ConsumableItem>
{
public int Compare(ConsumableItem x, ConsumableItem y)
{
return x.ItemName.CompareTo(y.ItemName);
}
}
public class ThrowableComparer : IComparer<ThrowableItem>
{
public int Compare(ThrowableItem x, ThrowableItem y)
{
return x.ItemName.CompareTo(y.ItemName);
}
}
}