package me.lethunderhawk.minion.runtime; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import java.util.HashMap; import java.util.Map; public class MinionInventory { private ItemStack[] items; private int maxSize; public MinionInventory() { this(9); } public MinionInventory(int maxSize) { this.maxSize = maxSize; this.items = new ItemStack[maxSize]; } public void resize(int newSize) { if (newSize < 0) throw new IllegalArgumentException("Invalid size: " + newSize); if (newSize == maxSize) return; ItemStack[] newItems = new ItemStack[newSize]; int copyLimit = Math.min(maxSize, newSize); // Copy existing items System.arraycopy(items, 0, newItems, 0, copyLimit); // Handle overflow if shrinking if (newSize < maxSize) { handleOverflowFromArray(items, copyLimit, maxSize); } this.items = newItems; this.maxSize = newSize; } /** * * @param itemsToAdd The ItemStacks you want to add to this minion * @return The leftovers if there isn't enough space */ public Map addItem(ItemStack... itemsToAdd) { Map leftover = new HashMap<>(); if (itemsToAdd == null || itemsToAdd.length == 0) { return leftover; } for (int i = 0; i < itemsToAdd.length; i++) { ItemStack item = itemsToAdd[i]; if (item == null || item.getType() == Material.AIR || item.getAmount() <= 0) { continue; } int maxStackSize = item.getType().getMaxStackSize(); int remainingAmount = item.getAmount(); // Try to merge with existing similar items first for (int slot = 0; slot < items.length && remainingAmount > 0; slot++) { ItemStack existingItem = items[slot]; if (existingItem != null && existingItem.isSimilar(item)) { int existingAmount = existingItem.getAmount(); int spaceAvailable = maxStackSize - existingAmount; if (spaceAvailable > 0) { int amountToAdd = Math.min(remainingAmount, spaceAvailable); existingItem.setAmount(existingAmount + amountToAdd); remainingAmount -= amountToAdd; } } } // If still have items remaining, find empty slots while (remainingAmount > 0) { int emptySlot = findEmptySlot(); if (emptySlot == -1) { // No more space ItemStack leftoverItem = item.clone(); leftoverItem.setAmount(remainingAmount); leftover.put(i, leftoverItem); break; } int amountForNewStack = Math.min(remainingAmount, maxStackSize); ItemStack newStack = item.clone(); newStack.setAmount(amountForNewStack); items[emptySlot] = newStack; remainingAmount -= amountForNewStack; } } return leftover; } private int findEmptySlot() { for (int i = 0; i < items.length; i++) { ItemStack item = items[i]; if (item == null || item.getType() == Material.AIR) { return i; } } return -1; } public ItemStack removeItem(ItemStack item) { if (item == null || item.getType() == Material.AIR || item.getAmount() <= 0) { return null; } // If amount is 0 or negative, return null if (item.getAmount() <= 0) { return null; } int remainingToRemove = item.getAmount(); ItemStack removedItem = item.clone(); removedItem.setAmount(0); for (int i = 0; i < maxSize && remainingToRemove > 0; i++) { ItemStack slotItem = items[i]; if (slotItem != null && slotItem.isSimilar(item)) { int slotAmount = slotItem.getAmount(); if (slotAmount <= remainingToRemove) { // Remove entire stack removedItem.setAmount(removedItem.getAmount() + slotAmount); remainingToRemove -= slotAmount; items[i] = null; // Clear the slot } else { // Remove part of the stack removedItem.setAmount(removedItem.getAmount() + remainingToRemove); slotItem.setAmount(slotAmount - remainingToRemove); remainingToRemove = 0; } } } // Return null if nothing was removed if (removedItem.getAmount() <= 0) { return null; } return removedItem; } private void handleOverflowFromArray(ItemStack[] items, int copyLimit, int maxSize) { // do nothing for now. } public ItemStack[] getAllItems() { return items; } public ItemStack getItemAtIndex(int i) { return items[i]; } public int getMaxStorageItems() { return maxSize * 64; } public void serialize(ConfigurationSection section) { section.set("size", maxSize); for (int i = 0; i < items.length; i++) { if (items[i] != null && items[i].getType() != Material.AIR) { section.set("items." + i, items[i]); } } } public static MinionInventory deserialize(ConfigurationSection section) { int size = section.getInt("size", 9); MinionInventory inv = new MinionInventory(size); ConfigurationSection itemsSec = section.getConfigurationSection("items"); if (itemsSec != null) { for (String key : itemsSec.getKeys(false)) { int slot = Integer.parseInt(key); ItemStack item = itemsSec.getItemStack(key); if (slot >= 0 && slot < size) { inv.items[slot] = item; } } } return inv; } }