Inventory.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEngine;
  4. [System.Serializable]
  5. public class InventorySlot
  6. {
  7. public Item item;
  8. public int quantity;
  9. public bool isEquipped;
  10. public InventorySlot(Item item, int quantity = 1, bool equipped = false)
  11. {
  12. this.item = item;
  13. this.quantity = quantity;
  14. this.isEquipped = equipped;
  15. }
  16. }
  17. public class Inventory : MonoBehaviour
  18. {
  19. [Header("Inventory Settings")]
  20. public int maxWeaponSlots = 10;
  21. public int maxArmorSlots = 15;
  22. public int maxMiscSlots = 20;
  23. [SerializeField] private List<InventorySlot> weapons = new List<InventorySlot>();
  24. [SerializeField] private List<InventorySlot> armor = new List<InventorySlot>();
  25. [SerializeField] private List<InventorySlot> miscellaneous = new List<InventorySlot>();
  26. // Equipment slots
  27. [SerializeField] private WeaponItem equippedWeapon;
  28. [SerializeField] private ArmorItem equippedHelmet;
  29. [SerializeField] private ArmorItem equippedChest;
  30. [SerializeField] private ArmorItem equippedLegs;
  31. [SerializeField] private ArmorItem equippedFeet;
  32. [SerializeField] private ArmorItem equippedHands;
  33. [SerializeField] private ArmorItem equippedArms;
  34. [SerializeField] private ArmorItem equippedShield;
  35. public List<InventorySlot> Weapons => weapons;
  36. public List<InventorySlot> Armor => armor;
  37. public List<InventorySlot> Miscellaneous => miscellaneous;
  38. public WeaponItem EquippedWeapon => equippedWeapon;
  39. public bool AddItem(Item item, int quantity = 1)
  40. {
  41. if (item == null) return false;
  42. List<InventorySlot> targetList = GetInventoryListForItem(item);
  43. int maxSlots = GetMaxSlotsForItem(item);
  44. if (targetList == null) return false;
  45. // Check for existing stack if stackable
  46. if (item is MiscellaneousItem miscItem && miscItem.isStackable)
  47. {
  48. var existingSlot = targetList.FirstOrDefault(slot => slot.item == item);
  49. if (existingSlot != null)
  50. {
  51. int maxStack = miscItem.maxStackSize;
  52. int canAdd = Mathf.Min(quantity, maxStack - existingSlot.quantity);
  53. existingSlot.quantity += canAdd;
  54. quantity -= canAdd;
  55. if (quantity <= 0) return true;
  56. }
  57. }
  58. // Add new slot if we have space
  59. if (targetList.Count < maxSlots)
  60. {
  61. targetList.Add(new InventorySlot(item, quantity));
  62. Debug.Log($"Added {quantity}x {item.itemName} to inventory");
  63. return true;
  64. }
  65. Debug.LogWarning($"No space in inventory for {item.itemName}");
  66. return false;
  67. }
  68. public bool RemoveItem(Item item, int quantity = 1)
  69. {
  70. List<InventorySlot> targetList = GetInventoryListForItem(item);
  71. if (targetList == null) return false;
  72. var slot = targetList.FirstOrDefault(s => s.item == item);
  73. if (slot == null) return false;
  74. if (slot.quantity >= quantity)
  75. {
  76. slot.quantity -= quantity;
  77. if (slot.quantity <= 0)
  78. {
  79. targetList.Remove(slot);
  80. }
  81. Debug.Log($"Removed {quantity}x {item.itemName} from inventory");
  82. return true;
  83. }
  84. return false;
  85. }
  86. public bool HasItem(Item item, int quantity = 1)
  87. {
  88. List<InventorySlot> targetList = GetInventoryListForItem(item);
  89. if (targetList == null) return false;
  90. var slot = targetList.FirstOrDefault(s => s.item == item);
  91. return slot != null && slot.quantity >= quantity;
  92. }
  93. public bool EquipWeapon(WeaponItem weapon)
  94. {
  95. if (!HasItem(weapon)) return false;
  96. // Unequip current weapon
  97. if (equippedWeapon != null)
  98. {
  99. UnequipWeapon();
  100. }
  101. equippedWeapon = weapon;
  102. // Mark as equipped in inventory
  103. var slot = weapons.FirstOrDefault(s => s.item == weapon);
  104. if (slot != null)
  105. {
  106. slot.isEquipped = true;
  107. }
  108. Debug.Log($"Equipped {weapon.itemName}");
  109. return true;
  110. }
  111. public bool UnequipWeapon()
  112. {
  113. if (equippedWeapon == null) return false;
  114. // Mark as not equipped in inventory
  115. var slot = weapons.FirstOrDefault(s => s.item == equippedWeapon);
  116. if (slot != null)
  117. {
  118. slot.isEquipped = false;
  119. }
  120. Debug.Log($"Unequipped {equippedWeapon.itemName}");
  121. equippedWeapon = null;
  122. return true;
  123. }
  124. public bool EquipArmor(ArmorItem armorItem)
  125. {
  126. if (!HasItem(armorItem)) return false;
  127. switch (armorItem.armorSlot)
  128. {
  129. case ArmorSlot.Head:
  130. if (equippedHelmet != null) UnequipArmor(equippedHelmet);
  131. equippedHelmet = armorItem;
  132. break;
  133. case ArmorSlot.Chest:
  134. if (equippedChest != null) UnequipArmor(equippedChest);
  135. equippedChest = armorItem;
  136. break;
  137. case ArmorSlot.Legs:
  138. if (equippedLegs != null) UnequipArmor(equippedLegs);
  139. equippedLegs = armorItem;
  140. break;
  141. case ArmorSlot.Feet:
  142. if (equippedFeet != null) UnequipArmor(equippedFeet);
  143. equippedFeet = armorItem;
  144. break;
  145. case ArmorSlot.Hands:
  146. if (equippedHands != null) UnequipArmor(equippedHands);
  147. equippedHands = armorItem;
  148. break;
  149. case ArmorSlot.Arms:
  150. if (equippedArms != null) UnequipArmor(equippedArms);
  151. equippedArms = armorItem;
  152. break;
  153. case ArmorSlot.Shield:
  154. if (equippedShield != null) UnequipArmor(equippedShield);
  155. equippedShield = armorItem;
  156. break;
  157. }
  158. // Mark as equipped in inventory
  159. var slot = armor.FirstOrDefault(s => s.item == armorItem);
  160. if (slot != null)
  161. {
  162. slot.isEquipped = true;
  163. }
  164. Debug.Log($"Equipped {armorItem.itemName}");
  165. return true;
  166. }
  167. public bool UnequipArmor(ArmorItem armorItem)
  168. {
  169. bool wasEquipped = false;
  170. if (equippedHelmet == armorItem) { equippedHelmet = null; wasEquipped = true; }
  171. else if (equippedChest == armorItem) { equippedChest = null; wasEquipped = true; }
  172. else if (equippedLegs == armorItem) { equippedLegs = null; wasEquipped = true; }
  173. else if (equippedFeet == armorItem) { equippedFeet = null; wasEquipped = true; }
  174. else if (equippedHands == armorItem) { equippedHands = null; wasEquipped = true; }
  175. else if (equippedArms == armorItem) { equippedArms = null; wasEquipped = true; }
  176. else if (equippedShield == armorItem) { equippedShield = null; wasEquipped = true; }
  177. if (wasEquipped)
  178. {
  179. // Mark as not equipped in inventory
  180. var slot = armor.FirstOrDefault(s => s.item == armorItem);
  181. if (slot != null)
  182. {
  183. slot.isEquipped = false;
  184. }
  185. Debug.Log($"Unequipped {armorItem.itemName}");
  186. return true;
  187. }
  188. return false;
  189. }
  190. public List<ArmorItem> GetEquippedArmor()
  191. {
  192. var equipped = new List<ArmorItem>();
  193. if (equippedHelmet != null) equipped.Add(equippedHelmet);
  194. if (equippedChest != null) equipped.Add(equippedChest);
  195. if (equippedLegs != null) equipped.Add(equippedLegs);
  196. if (equippedFeet != null) equipped.Add(equippedFeet);
  197. if (equippedHands != null) equipped.Add(equippedHands);
  198. if (equippedArms != null) equipped.Add(equippedArms);
  199. if (equippedShield != null) equipped.Add(equippedShield);
  200. return equipped;
  201. }
  202. public int GetTotalArmorClass()
  203. {
  204. int totalAC = 0;
  205. var equippedArmor = GetEquippedArmor();
  206. foreach (var armor in equippedArmor)
  207. {
  208. totalAC += armor.armorClass;
  209. }
  210. return totalAC;
  211. }
  212. public (int str, int dex, int con, int wis) GetTotalStatModifiers()
  213. {
  214. int str = 0, dex = 0, con = 0, wis = 0;
  215. var equippedArmor = GetEquippedArmor();
  216. foreach (var armor in equippedArmor)
  217. {
  218. str += armor.strengthModifier;
  219. dex += armor.dexterityModifier;
  220. con += armor.constitutionModifier;
  221. wis += armor.wisdomModifier;
  222. }
  223. return (str, dex, con, wis);
  224. }
  225. private List<InventorySlot> GetInventoryListForItem(Item item)
  226. {
  227. switch (item.itemType)
  228. {
  229. case ItemType.Weapon:
  230. return weapons;
  231. case ItemType.Armor:
  232. return armor;
  233. case ItemType.Miscellaneous:
  234. case ItemType.Consumable:
  235. case ItemType.Tool:
  236. case ItemType.Accessory:
  237. return miscellaneous;
  238. default:
  239. return null;
  240. }
  241. }
  242. private int GetMaxSlotsForItem(Item item)
  243. {
  244. switch (item.itemType)
  245. {
  246. case ItemType.Weapon:
  247. return maxWeaponSlots;
  248. case ItemType.Armor:
  249. return maxArmorSlots;
  250. case ItemType.Miscellaneous:
  251. case ItemType.Consumable:
  252. case ItemType.Tool:
  253. case ItemType.Accessory:
  254. return maxMiscSlots;
  255. default:
  256. return 0;
  257. }
  258. }
  259. }