174 lines
6.6 KiB
C#
174 lines
6.6 KiB
C#
using Barotrauma.Items.Components;
|
|
using Barotrauma.Networking;
|
|
using Microsoft.Xna.Framework;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Barotrauma
|
|
{
|
|
partial class ItemInventory : Inventory
|
|
{
|
|
private readonly ItemContainer container;
|
|
public ItemContainer Container
|
|
{
|
|
get { return container; }
|
|
}
|
|
|
|
public ItemInventory(Item owner, ItemContainer container, int capacity, int slotsPerRow = 5)
|
|
: base(owner, capacity, slotsPerRow)
|
|
{
|
|
this.container = container;
|
|
}
|
|
|
|
public override int FindAllowedSlot(Item item, bool ignoreCondition = false)
|
|
{
|
|
if (ItemOwnsSelf(item)) { return -1; }
|
|
|
|
//item is already in the inventory!
|
|
if (Contains(item)) { return -1; }
|
|
if (!container.CanBeContained(item)) { return -1; }
|
|
|
|
//try to stack first
|
|
for (int i = 0; i < capacity; i++)
|
|
{
|
|
if (slots[i].Any() && CanBePutInSlot(item, i, ignoreCondition)) { return i; }
|
|
}
|
|
|
|
for (int i = 0; i < capacity; i++)
|
|
{
|
|
if (CanBePutInSlot(item, i, ignoreCondition)) { return i; }
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
public override bool CanBePutInSlot(Item item, int i, bool ignoreCondition = false)
|
|
{
|
|
if (ItemOwnsSelf(item)) { return false; }
|
|
if (i < 0 || i >= slots.Length) { return false; }
|
|
if (!container.CanBeContained(item, i)) { return false; }
|
|
return item != null && slots[i].CanBePut(item, ignoreCondition) && slots[i].Items.Count < container.GetMaxStackSize(i);
|
|
}
|
|
|
|
public override bool CanBePutInSlot(ItemPrefab itemPrefab, int i, float? condition, int? quality = null)
|
|
{
|
|
if (i < 0 || i >= slots.Length) { return false; }
|
|
if (!container.CanBeContained(itemPrefab, i)) { return false; }
|
|
return itemPrefab != null && slots[i].CanBePut(itemPrefab, condition, quality) && slots[i].Items.Count < container.GetMaxStackSize(i);
|
|
}
|
|
|
|
public override int HowManyCanBePut(ItemPrefab itemPrefab, int i, float? condition, bool ignoreItemsInSlot = false)
|
|
{
|
|
if (itemPrefab == null) { return 0; }
|
|
if (i < 0 || i >= slots.Length) { return 0; }
|
|
if (!container.CanBeContained(itemPrefab, i)) { return 0; }
|
|
return slots[i].HowManyCanBePut(itemPrefab, maxStackSize: Math.Min(itemPrefab.GetMaxStackSize(this), container.GetMaxStackSize(i)), condition, ignoreItemsInSlot);
|
|
}
|
|
|
|
public override bool IsFull(bool takeStacksIntoAccount = false)
|
|
{
|
|
if (takeStacksIntoAccount)
|
|
{
|
|
for (int i = 0; i < capacity; i++)
|
|
{
|
|
if (!slots[i].Any()) { return false; }
|
|
var item = slots[i].FirstOrDefault();
|
|
if (slots[i].Items.Count < Math.Min(item.Prefab.GetMaxStackSize(this), container.GetMaxStackSize(i))) { return false; }
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < capacity; i++)
|
|
{
|
|
if (!slots[i].Any()) { return false; }
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override bool TryPutItem(Item item, Character user, IEnumerable<InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool ignoreCondition = false)
|
|
{
|
|
bool wasPut = base.TryPutItem(item, user, allowedSlots, createNetworkEvent, ignoreCondition);
|
|
|
|
if (wasPut)
|
|
{
|
|
foreach (Character c in Character.CharacterList)
|
|
{
|
|
if (!c.HeldItems.Contains(item)) { continue; }
|
|
item.Unequip(c);
|
|
break;
|
|
}
|
|
|
|
container.IsActive = true;
|
|
container.OnItemContained(item);
|
|
#if SERVER
|
|
GameMain.Server?.KarmaManager?.OnItemContained(item, container.Item, user);
|
|
#endif
|
|
}
|
|
|
|
return wasPut;
|
|
}
|
|
|
|
public override bool TryPutItem(Item item, int i, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true, bool ignoreCondition = false)
|
|
{
|
|
bool wasPut = base.TryPutItem(item, i, allowSwapping, allowCombine, user, createNetworkEvent, ignoreCondition);
|
|
if (wasPut && item.ParentInventory == this)
|
|
{
|
|
foreach (Character c in Character.CharacterList)
|
|
{
|
|
if (!c.HeldItems.Contains(item)) { continue; }
|
|
item.Unequip(c);
|
|
break;
|
|
}
|
|
|
|
container.IsActive = true;
|
|
container.OnItemContained(item);
|
|
#if SERVER
|
|
GameMain.Server?.KarmaManager?.OnItemContained(item, container.Item, user);
|
|
#endif
|
|
}
|
|
|
|
return wasPut;
|
|
}
|
|
|
|
protected override void CreateNetworkEvent(Range slotRange)
|
|
{
|
|
if (!Item.ItemList.Contains(container.Item))
|
|
{
|
|
string errorMsg = "Attempted to create a network event for an item (" + container.Item.Name + ") that hasn't been fully initialized yet.\n" + Environment.StackTrace.CleanupStackTrace();
|
|
DebugConsole.ThrowError(errorMsg);
|
|
GameAnalyticsManager.AddErrorEventOnce(
|
|
"ItemInventory.CreateServerEvent:EventForUninitializedItem" + container.Item.Name + container.Item.ID,
|
|
GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
|
return;
|
|
}
|
|
|
|
if (!container.Item.Components.Contains(container))
|
|
{
|
|
DebugConsole.Log("Creating a network event for the item \"" + container.Item + "\" failed, ItemContainer not found in components");
|
|
return;
|
|
}
|
|
|
|
if (slotRange.Start.Value < 0 || slotRange.End.Value > capacity)
|
|
{
|
|
DebugConsole.ThrowError($"Error when creating an inventory event: invalid slot range ({slotRange})\n" + Environment.StackTrace);
|
|
return;
|
|
}
|
|
|
|
if (GameMain.NetworkMember != null)
|
|
{
|
|
if (GameMain.NetworkMember.IsClient) { syncItemsDelay = 1.0f; }
|
|
GameMain.NetworkMember.CreateEntityEvent(Owner as INetSerializable, new Item.InventoryStateEventData(container, slotRange));
|
|
}
|
|
}
|
|
|
|
public override void RemoveItem(Item item)
|
|
{
|
|
base.RemoveItem(item);
|
|
container.OnItemRemoved(item);
|
|
}
|
|
}
|
|
}
|