MinionInventory.java 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package me.lethunderhawk.minion.runtime;
  2. import org.bukkit.Material;
  3. import org.bukkit.configuration.ConfigurationSection;
  4. import org.bukkit.inventory.ItemStack;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. public class MinionInventory {
  8. private ItemStack[] items;
  9. private int maxSize;
  10. public MinionInventory() {
  11. this(9);
  12. }
  13. public MinionInventory(int maxSize) {
  14. this.maxSize = maxSize;
  15. this.items = new ItemStack[maxSize];
  16. }
  17. public void resize(int newSize) {
  18. if (newSize < 0) throw new IllegalArgumentException("Invalid size: " + newSize);
  19. if (newSize == maxSize) return;
  20. ItemStack[] newItems = new ItemStack[newSize];
  21. int copyLimit = Math.min(maxSize, newSize);
  22. // Copy existing items
  23. System.arraycopy(items, 0, newItems, 0, copyLimit);
  24. // Handle overflow if shrinking
  25. if (newSize < maxSize) {
  26. handleOverflowFromArray(items, copyLimit, maxSize);
  27. }
  28. this.items = newItems;
  29. this.maxSize = newSize;
  30. }
  31. /**
  32. *
  33. * @param itemsToAdd The ItemStacks you want to add to this minion
  34. * @return The leftovers if there isn't enough space
  35. */
  36. public Map<Integer, ItemStack> addItem(ItemStack... itemsToAdd) {
  37. Map<Integer, ItemStack> leftover = new HashMap<>();
  38. if (itemsToAdd == null || itemsToAdd.length == 0) {
  39. return leftover;
  40. }
  41. for (int i = 0; i < itemsToAdd.length; i++) {
  42. ItemStack item = itemsToAdd[i];
  43. if (item == null || item.getType() == Material.AIR || item.getAmount() <= 0) {
  44. continue;
  45. }
  46. int maxStackSize = item.getType().getMaxStackSize();
  47. int remainingAmount = item.getAmount();
  48. // Try to merge with existing similar items first
  49. for (int slot = 0; slot < items.length && remainingAmount > 0; slot++) {
  50. ItemStack existingItem = items[slot];
  51. if (existingItem != null && existingItem.isSimilar(item)) {
  52. int existingAmount = existingItem.getAmount();
  53. int spaceAvailable = maxStackSize - existingAmount;
  54. if (spaceAvailable > 0) {
  55. int amountToAdd = Math.min(remainingAmount, spaceAvailable);
  56. existingItem.setAmount(existingAmount + amountToAdd);
  57. remainingAmount -= amountToAdd;
  58. }
  59. }
  60. }
  61. // If still have items remaining, find empty slots
  62. while (remainingAmount > 0) {
  63. int emptySlot = findEmptySlot();
  64. if (emptySlot == -1) { // No more space
  65. ItemStack leftoverItem = item.clone();
  66. leftoverItem.setAmount(remainingAmount);
  67. leftover.put(i, leftoverItem);
  68. break;
  69. }
  70. int amountForNewStack = Math.min(remainingAmount, maxStackSize);
  71. ItemStack newStack = item.clone();
  72. newStack.setAmount(amountForNewStack);
  73. items[emptySlot] = newStack;
  74. remainingAmount -= amountForNewStack;
  75. }
  76. }
  77. return leftover;
  78. }
  79. private int findEmptySlot() {
  80. for (int i = 0; i < items.length; i++) {
  81. ItemStack item = items[i];
  82. if (item == null || item.getType() == Material.AIR) {
  83. return i;
  84. }
  85. }
  86. return -1;
  87. }
  88. public ItemStack removeItem(ItemStack item) {
  89. if (item == null || item.getType() == Material.AIR || item.getAmount() <= 0) {
  90. return null;
  91. }
  92. // If amount is 0 or negative, return null
  93. if (item.getAmount() <= 0) {
  94. return null;
  95. }
  96. int remainingToRemove = item.getAmount();
  97. ItemStack removedItem = item.clone();
  98. removedItem.setAmount(0);
  99. for (int i = 0; i < maxSize && remainingToRemove > 0; i++) {
  100. ItemStack slotItem = items[i];
  101. if (slotItem != null && slotItem.isSimilar(item)) {
  102. int slotAmount = slotItem.getAmount();
  103. if (slotAmount <= remainingToRemove) {
  104. // Remove entire stack
  105. removedItem.setAmount(removedItem.getAmount() + slotAmount);
  106. remainingToRemove -= slotAmount;
  107. items[i] = null; // Clear the slot
  108. } else {
  109. // Remove part of the stack
  110. removedItem.setAmount(removedItem.getAmount() + remainingToRemove);
  111. slotItem.setAmount(slotAmount - remainingToRemove);
  112. remainingToRemove = 0;
  113. }
  114. }
  115. }
  116. // Return null if nothing was removed
  117. if (removedItem.getAmount() <= 0) {
  118. return null;
  119. }
  120. return removedItem;
  121. }
  122. private void handleOverflowFromArray(ItemStack[] items, int copyLimit, int maxSize) {
  123. // do nothing for now.
  124. }
  125. public ItemStack[] getAllItems() {
  126. return items;
  127. }
  128. public ItemStack getItemAtIndex(int i) {
  129. return items[i];
  130. }
  131. public int getMaxStorageItems() {
  132. return maxSize * 64;
  133. }
  134. public void serialize(ConfigurationSection section) {
  135. section.set("size", maxSize);
  136. for (int i = 0; i < items.length; i++) {
  137. if (items[i] != null && items[i].getType() != Material.AIR) {
  138. section.set("items." + i, items[i]);
  139. }
  140. }
  141. }
  142. public static MinionInventory deserialize(ConfigurationSection section) {
  143. int size = section.getInt("size", 9);
  144. MinionInventory inv = new MinionInventory(size);
  145. ConfigurationSection itemsSec = section.getConfigurationSection("items");
  146. if (itemsSec != null) {
  147. for (String key : itemsSec.getKeys(false)) {
  148. int slot = Integer.parseInt(key);
  149. ItemStack item = itemsSec.getItemStack(key);
  150. if (slot >= 0 && slot < size) {
  151. inv.items[slot] = item;
  152. }
  153. }
  154. }
  155. return inv;
  156. }
  157. }