Client LuaCsForBarotrauma
BarotraumaShared/SharedSource/Items/ItemInventory.cs
3 using Microsoft.Xna.Framework;
4 using System;
5 using System.Collections.Generic;
6 using System.Linq;
7 
8 namespace Barotrauma
9 {
10  partial class ItemInventory : Inventory
11  {
12  private readonly ItemContainer container;
14  {
15  get { return container; }
16  }
17 
18  public ItemInventory(Item owner, ItemContainer container, int capacity, int slotsPerRow = 5)
19  : base(owner, capacity, slotsPerRow)
20  {
21  this.container = container;
22  }
23 
24  public override int FindAllowedSlot(Item item, bool ignoreCondition = false)
25  {
26  if (ItemOwnsSelf(item)) { return -1; }
27 
28  //item is already in the inventory!
29  if (Contains(item)) { return -1; }
30  if (!container.CanBeContained(item)) { return -1; }
31 
32  //try to stack first
33  for (int i = 0; i < capacity; i++)
34  {
35  if (slots[i].Any() && CanBePutInSlot(item, i, ignoreCondition)) { return i; }
36  }
37 
38  for (int i = 0; i < capacity; i++)
39  {
40  if (CanBePutInSlot(item, i, ignoreCondition)) { return i; }
41  }
42 
43  return -1;
44  }
45 
46  public override bool CanBePutInSlot(Item item, int i, bool ignoreCondition = false)
47  {
48  if (ItemOwnsSelf(item)) { return false; }
49  if (i < 0 || i >= slots.Length) { return false; }
50  if (!container.CanBeContained(item, i)) { return false; }
51  return item != null && slots[i].CanBePut(item, ignoreCondition) && slots[i].Items.Count < container.GetMaxStackSize(i);
52  }
53 
54  public override bool CanBePutInSlot(ItemPrefab itemPrefab, int i, float? condition, int? quality = null)
55  {
56  if (i < 0 || i >= slots.Length) { return false; }
57  if (!container.CanBeContained(itemPrefab, i)) { return false; }
58  return itemPrefab != null && slots[i].CanBePut(itemPrefab, condition, quality) && slots[i].Items.Count < container.GetMaxStackSize(i);
59  }
60 
61  public override int HowManyCanBePut(ItemPrefab itemPrefab, int i, float? condition, bool ignoreItemsInSlot = false)
62  {
63  if (itemPrefab == null) { return 0; }
64  if (i < 0 || i >= slots.Length) { return 0; }
65  if (!container.CanBeContained(itemPrefab, i)) { return 0; }
66  return slots[i].HowManyCanBePut(itemPrefab, maxStackSize: Math.Min(itemPrefab.GetMaxStackSize(this), container.GetMaxStackSize(i)), condition, ignoreItemsInSlot);
67  }
68 
69  public override bool IsFull(bool takeStacksIntoAccount = false)
70  {
71  if (takeStacksIntoAccount)
72  {
73  for (int i = 0; i < capacity; i++)
74  {
75  if (!slots[i].Any()) { return false; }
76  var item = slots[i].FirstOrDefault();
77  if (slots[i].Items.Count < Math.Min(item.Prefab.GetMaxStackSize(this), container.GetMaxStackSize(i))) { return false; }
78  }
79  }
80  else
81  {
82  for (int i = 0; i < capacity; i++)
83  {
84  if (!slots[i].Any()) { return false; }
85  }
86  }
87 
88  return true;
89  }
90 
91  public override bool TryPutItem(Item item, Character user, IEnumerable<InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool ignoreCondition = false)
92  {
93  bool wasPut = base.TryPutItem(item, user, allowedSlots, createNetworkEvent, ignoreCondition);
94 
95  if (wasPut)
96  {
97  foreach (Character c in Character.CharacterList)
98  {
99  if (!c.HeldItems.Contains(item)) { continue; }
100  item.Unequip(c);
101  break;
102  }
103 
104  container.IsActive = true;
105  container.OnItemContained(item);
106 #if SERVER
107  GameMain.Server?.KarmaManager?.OnItemContained(item, container.Item, user);
108 #endif
109  }
110 
111  return wasPut;
112  }
113 
114  public override bool TryPutItem(Item item, int i, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true, bool ignoreCondition = false)
115  {
116  bool wasPut = base.TryPutItem(item, i, allowSwapping, allowCombine, user, createNetworkEvent, ignoreCondition);
117  if (wasPut && item.ParentInventory == this)
118  {
119  foreach (Character c in Character.CharacterList)
120  {
121  if (!c.HeldItems.Contains(item)) { continue; }
122  item.Unequip(c);
123  break;
124  }
125 
126  container.IsActive = true;
127  container.OnItemContained(item);
128 #if SERVER
129  GameMain.Server?.KarmaManager?.OnItemContained(item, container.Item, user);
130 #endif
131  }
132 
133  return wasPut;
134  }
135 
136  protected override void CreateNetworkEvent(Range slotRange)
137  {
138  if (!Item.ItemList.Contains(container.Item))
139  {
140  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();
141  DebugConsole.ThrowError(errorMsg);
142  GameAnalyticsManager.AddErrorEventOnce(
143  "ItemInventory.CreateServerEvent:EventForUninitializedItem" + container.Item.Name + container.Item.ID,
144  GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
145  return;
146  }
147 
148  if (!container.Item.Components.Contains(container))
149  {
150  DebugConsole.Log("Creating a network event for the item \"" + container.Item + "\" failed, ItemContainer not found in components");
151  return;
152  }
153 
154  if (slotRange.Start.Value < 0 || slotRange.End.Value > capacity)
155  {
156  DebugConsole.ThrowError($"Error when creating an inventory event: invalid slot range ({slotRange})\n" + Environment.StackTrace);
157  return;
158  }
159 
160  if (GameMain.NetworkMember != null)
161  {
162  if (GameMain.NetworkMember.IsClient) { syncItemsDelay = 1.0f; }
163  GameMain.NetworkMember.CreateEntityEvent(Owner as INetSerializable, new Item.InventoryStateEventData(container, slotRange));
164  }
165  }
166 
167  public override void RemoveItem(Item item)
168  {
169  base.RemoveItem(item);
170  container.OnItemRemoved(item);
171  }
172  }
173 }
IEnumerable< Item >?? HeldItems
Items the character has in their hand slots. Doesn't return nulls and only returns items held in both...
static NetworkMember NetworkMember
Definition: GameMain.cs:190
int HowManyCanBePut(ItemPrefab itemPrefab, int? maxStackSize=null, float? condition=null, bool ignoreItemsInSlot=false)
Defaults to ItemPrefab.MaxStackSize if null
bool CanBePut(Item item, bool ignoreCondition=false)
readonly int capacity
Capacity, or the number of slots in the inventory.
bool Contains(Item item)
Is the item contained in this inventory. Does not recursively check items inside items.
virtual bool ItemOwnsSelf(Item item)
Returns true if the item owns any of the parent inventories.
static readonly List< Item > ItemList
Item(ItemPrefab itemPrefab, Vector2 position, Submarine submarine, ushort id=Entity.NullEntityID, bool callOnItemLoaded=true)
override bool TryPutItem(Item item, Character user, IEnumerable< InvSlotType > allowedSlots=null, bool createNetworkEvent=true, bool ignoreCondition=false)
If there is room, puts the item in the inventory and returns true, otherwise returns false
override bool IsFull(bool takeStacksIntoAccount=false)
Is there room to put more items in the inventory. Doesn't take stacking into account by default.
override bool CanBePutInSlot(Item item, int i, bool ignoreCondition=false)
Can the item be put in the specified slot.
ItemInventory(Item owner, ItemContainer container, int capacity, int slotsPerRow=5)
override bool CanBePutInSlot(ItemPrefab itemPrefab, int i, float? condition, int? quality=null)
override int HowManyCanBePut(ItemPrefab itemPrefab, int i, float? condition, bool ignoreItemsInSlot=false)
override int FindAllowedSlot(Item item, bool ignoreCondition=false)
override bool TryPutItem(Item item, int i, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent=true, bool ignoreCondition=false)