using System; using System.Collections.Generic; using System.Linq; using WingsEmu.DTOs.Bonus; using WingsEmu.Game.Characters; using WingsEmu.Game.Extensions; using WingsEmu.Game.Items; using WingsEmu.Game.Warehouse; using WingsEmu.Packets.Enums; namespace WingsEmu.Game.Inventory; public class PartnerInventoryComponent : IPartnerInventoryComponent { private const int WEAR_SLOTS = 13; private const byte PARTNER_SLOTS = 56; private readonly IPlayerEntity _character; private readonly Dictionary _partnersInventory = new(); private readonly PartnerWarehouseItem[] _warehouseItems = new PartnerWarehouseItem[PARTNER_SLOTS]; public PartnerInventoryComponent(IPlayerEntity character) => _character = character; public IReadOnlyList PartnerGetEquippedItems(short partnerSlot) => !_partnersInventory.TryGetValue(partnerSlot, out PartnerInventoryItem[] items) ? Array.Empty() : items; public IReadOnlyList GetPartnersEquippedItems() { return _partnersInventory.Values.SelectMany(s => s).Where(item => item != null).ToList(); } public void PartnerEquipItem(InventoryItem item, short partnerSlot) { if (item == null) { return; } EquipmentType type = item.ItemInstance.GameItem.EquipmentSlot; if (type == EquipmentType.SecondaryWeapon) { type = EquipmentType.MainWeapon; } var partnerItem = new PartnerInventoryItem { ItemInstance = item.ItemInstance, PartnerSlot = partnerSlot }; if (!_partnersInventory.TryGetValue(partnerSlot, out PartnerInventoryItem[] items)) { items = new PartnerInventoryItem[WEAR_SLOTS]; _partnersInventory[partnerSlot] = items; } items[(byte)type] = partnerItem; } public void PartnerEquipItem(GameItemInstance item, short partnerSlot) { if (item == null) { return; } EquipmentType type = item.GameItem.EquipmentSlot; if (type == EquipmentType.SecondaryWeapon) { type = EquipmentType.MainWeapon; } var partnerItem = new PartnerInventoryItem { ItemInstance = item, PartnerSlot = partnerSlot }; if (!_partnersInventory.TryGetValue(partnerSlot, out PartnerInventoryItem[] items)) { items = new PartnerInventoryItem[WEAR_SLOTS]; _partnersInventory[partnerSlot] = items; } items[(byte)type] = partnerItem; } public void PartnerTakeOffItem(EquipmentType type, short partnerSlot) { if (!_partnersInventory.TryGetValue(partnerSlot, out PartnerInventoryItem[] items)) { items = new PartnerInventoryItem[WEAR_SLOTS]; _partnersInventory[partnerSlot] = items; } items[(byte)type] = null; } public PartnerInventoryItem PartnerGetEquippedItem(EquipmentType type, short partnerSlot) { if (!_partnersInventory.TryGetValue(partnerSlot, out PartnerInventoryItem[] items)) { items = new PartnerInventoryItem[WEAR_SLOTS]; _partnersInventory[partnerSlot] = items; } PartnerInventoryItem item = items[(byte)type]; return item; } public void AddPartnerWarehouseItem(GameItemInstance item, short slot) { var newWarehouseItem = new PartnerWarehouseItem { ItemInstance = item, Slot = slot }; _warehouseItems[newWarehouseItem.Slot] = newWarehouseItem; } public void RemovePartnerWarehouseItem(short slot) { PartnerWarehouseItem partnerWarehouseItem = GetPartnerWarehouseItem(slot); if (partnerWarehouseItem == null) { return; } _warehouseItems[partnerWarehouseItem.Slot] = null; } public PartnerWarehouseItem GetPartnerWarehouseItem(short slot) => _warehouseItems[slot]; public IReadOnlyList PartnerWarehouseItems() => _warehouseItems; public byte GetPartnerWarehouseSlots() => _character.HaveStaticBonus(StaticBonusType.PartnerBackpack) ? PARTNER_SLOTS : (byte)0; public byte GetPartnerWarehouseSlotsWithoutBackpack() => PARTNER_SLOTS; public bool HasSpaceForPartnerWarehouseItem() => _warehouseItems.Count(x => x != null) < PARTNER_SLOTS; public bool HasSpaceForPartnerItemWarehouse(int itemVnum, short amount = 1) { if (!_character.HaveStaticBonus(StaticBonusType.PartnerBackpack)) { return false; } if (!_warehouseItems.Any()) { return true; } PartnerWarehouseItem[] items = _warehouseItems.OrderBy(x => x?.Slot).ToArray(); for (byte i = 0; i < PARTNER_SLOTS; i++) { PartnerWarehouseItem freeSlot = items.FirstOrDefault(x => x != null && x.Slot == i); if (freeSlot == null) { return true; } if (freeSlot.ItemInstance == null) { continue; } if (freeSlot.ItemInstance.GameItem.Id != itemVnum) { continue; } if (freeSlot.ItemInstance.GameItem.IsNotStackableInventoryType() || freeSlot.ItemInstance.Amount + amount > 999) { continue; } return true; } return HasSpaceForPartnerWarehouseItem(); } }