ItemContainer.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using System;
  2. using System.Collections;
  3. using System.Runtime.InteropServices.WindowsRuntime;
  4. using UnityEngine;
  5. namespace HQFPSWeapons
  6. {
  7. [Serializable]
  8. public class ItemContainer : IEnumerable
  9. {
  10. public ItemSlot this[int i] { get { return m_Slots[i]; } set { m_Slots[i] = value; } }
  11. // A little hack for now
  12. public int SelectedSlot { get; set; }
  13. /// <summary>Slot count.</summary>
  14. public int Count { get { return m_Slots.Length; } }
  15. public ItemSlot[] Slots { get { return m_Slots; } }
  16. public string Name { get { return m_Name; } }
  17. public ItemContainerFlags Flag { get { return m_Flag; } }
  18. public Transform Parent { get { return m_Parent; } }
  19. public bool IsExpanded { get { return m_IsExpanded; } set { m_IsExpanded = value; } }
  20. [NonSerialized]
  21. public Message<ItemSlot> Changed = new Message<ItemSlot>();
  22. [NonSerialized]
  23. private Transform m_Parent = null;
  24. private string m_Name;
  25. private ItemContainerFlags m_Flag;
  26. private ItemSlot[] m_Slots;
  27. private string[] m_ValidCategories;
  28. private string[] m_RequiredProperties;
  29. private bool m_IsExpanded = true;
  30. public ItemContainer(string name, int size, Transform parent, ItemContainerFlags flag, string[] validCategories = null, string[] validProperties = null)
  31. {
  32. m_Name = name;
  33. m_Slots = new ItemSlot[size];
  34. for(int i = 0;i < m_Slots.Length;i ++)
  35. {
  36. m_Slots[i] = new ItemSlot();
  37. m_Slots[i].Changed.AddListener(OnSlotChanged);
  38. }
  39. m_Flag = flag;
  40. m_ValidCategories = validCategories;
  41. m_RequiredProperties = validProperties;
  42. }
  43. IEnumerator IEnumerable.GetEnumerator()
  44. {
  45. return m_Slots.GetEnumerator();
  46. }
  47. public int AddItem(ItemData itemData, int amount, ItemPropertyList customProperties = null)
  48. {
  49. if(itemData == null || !AllowsItem(itemData))
  50. return 0;
  51. int amountInInventory = GetItemCount(itemData.Name);
  52. if (amountInInventory >= itemData.StackSize)
  53. return 0;
  54. else
  55. amount = Mathf.Min(itemData.StackSize - amountInInventory, amount);
  56. int added = 0;
  57. // Go through each slot and see where we can add the item(s)
  58. for(int i = 0;i < m_Slots.Length;i ++)
  59. {
  60. added += AddToSlot(m_Slots[i], itemData, amount, customProperties);
  61. // We've added all the items, we can stop now
  62. if(added == amount)
  63. return added;
  64. }
  65. return added;
  66. }
  67. public int AddItem(string name, int amount, ItemPropertyList customProperties = null)
  68. {
  69. ItemData itemData;
  70. if(!ItemDatabase.Default.TryGetItem(name, out itemData) || !AllowsItem(itemData))
  71. return 0;
  72. return AddItem(itemData, amount, customProperties);
  73. }
  74. public bool AddItem(SaveableItem item)
  75. {
  76. if(AllowsItem(item))
  77. {
  78. if(item.CurrentStackSize > 1)
  79. return AddItem(item.Data, item.CurrentStackSize, item.Properties) > 0;
  80. else
  81. {
  82. if(m_Slots != null && m_Slots.Length > 0 && !m_Slots[Mathf.Clamp(SelectedSlot, 0, m_Slots.Length - 1)].HasItem)
  83. {
  84. m_Slots[Mathf.Clamp(SelectedSlot, 0, m_Slots.Length - 1)].SetItem(item);
  85. return true;
  86. }
  87. else
  88. {
  89. // Go through each slot and see where we can add the item
  90. for (int i = 0; i < m_Slots.Length; i++)
  91. {
  92. if (!m_Slots[i].HasItem)
  93. {
  94. m_Slots[i].SetItem(item);
  95. return true;
  96. }
  97. }
  98. }
  99. return false;
  100. }
  101. }
  102. else
  103. return false;
  104. }
  105. public int RemoveItem(string name, int amount)
  106. {
  107. int removed = 0;
  108. for(int i = 0;i < m_Slots.Length;i ++)
  109. {
  110. if(m_Slots[i].HasItem && m_Slots[i].Item.Name == name)
  111. {
  112. removed += m_Slots[i].RemoveFromStack(amount - removed);
  113. // We've removed all the items, we can stop now
  114. if(removed == amount)
  115. return removed;
  116. }
  117. }
  118. return removed;
  119. }
  120. public bool RemoveItem(SaveableItem item)
  121. {
  122. for(int i = 0;i < m_Slots.Length;i ++)
  123. if(m_Slots[i].Item == item)
  124. {
  125. m_Slots[i].SetItem(null);
  126. return true;
  127. }
  128. return false;
  129. }
  130. public bool ContainsItem(SaveableItem item)
  131. {
  132. for(int i = 0;i < m_Slots.Length;i ++)
  133. if(m_Slots[i].Item == item)
  134. return true;
  135. return false;
  136. }
  137. public int GetItemCount(string name)
  138. {
  139. int count = 0;
  140. for(int i = 0;i < m_Slots.Length;i ++)
  141. {
  142. if(m_Slots[i].HasItem && m_Slots[i].Item.Name == name)
  143. count += m_Slots[i].Item.CurrentStackSize;
  144. }
  145. return count;
  146. }
  147. public bool AllowsItem(ItemData itemData)
  148. {
  149. bool isFromValidCategories = m_ValidCategories == null || m_ValidCategories.Length == 0;
  150. bool hasValidProperties = true;
  151. if(m_ValidCategories != null)
  152. {
  153. for(int i = 0;i < m_ValidCategories.Length;i ++)
  154. {
  155. if(m_ValidCategories[i] == itemData.Category)
  156. isFromValidCategories = true;
  157. }
  158. }
  159. if(m_RequiredProperties != null)
  160. {
  161. for(int i = 0;i < m_RequiredProperties.Length;i ++)
  162. {
  163. bool hasProperty = false;
  164. for(int p = 0;p < itemData.Properties.Length;p ++)
  165. {
  166. if(itemData.Properties[p].Name == m_RequiredProperties[i])
  167. {
  168. hasProperty = true;
  169. break;
  170. }
  171. }
  172. if(!hasProperty)
  173. {
  174. hasValidProperties = false;
  175. break;
  176. }
  177. }
  178. }
  179. return isFromValidCategories && hasValidProperties;
  180. }
  181. public bool AllowsItem(SaveableItem item)
  182. {
  183. bool isFromValidCategories = m_ValidCategories == null || m_ValidCategories.Length == 0;
  184. bool hasRequiredProperties = true;
  185. if(m_ValidCategories != null)
  186. {
  187. for(int i = 0;i < m_ValidCategories.Length;i ++)
  188. {
  189. if(m_ValidCategories[i] == item.Data.Category)
  190. isFromValidCategories = true;
  191. }
  192. }
  193. if(m_RequiredProperties != null)
  194. {
  195. for(int i = 0;i < m_RequiredProperties.Length;i ++)
  196. {
  197. if(!item.HasProperty(m_RequiredProperties[i]))
  198. hasRequiredProperties = false;
  199. }
  200. }
  201. return isFromValidCategories && hasRequiredProperties;
  202. }
  203. public int GetPositionOfItem(SaveableItem item)
  204. {
  205. for(int i = 0; i < m_Slots.Length; i ++)
  206. if(m_Slots[i].Item == item)
  207. return i;
  208. return -1;
  209. }
  210. public bool ContainerIsFull ()
  211. {
  212. foreach (var slot in m_Slots)
  213. {
  214. if (!slot.HasItem)
  215. return false;
  216. }
  217. return true;
  218. }
  219. private int AddToSlot(ItemSlot slot, ItemData itemData, int amount, ItemPropertyList customProperties = null)
  220. {
  221. if(slot.HasItem && itemData.Name != slot.Item.Name)
  222. return 0;
  223. bool wasEmpty = false;
  224. if(!slot.HasItem)
  225. {
  226. slot.SetItem(new SaveableItem(itemData, 1, customProperties));
  227. amount --;
  228. wasEmpty = true;
  229. }
  230. int addedToStack = slot.AddToStack(amount);
  231. return addedToStack + (wasEmpty ? 1 : 0);
  232. }
  233. private void OnSlotChanged(ItemSlot slot)
  234. {
  235. try
  236. {
  237. Changed.Send(slot);
  238. }
  239. catch { };
  240. }
  241. }
  242. }