diff --git a/Essentials/src/main/java/com/earth2me/essentials/Kit.java b/Essentials/src/main/java/com/earth2me/essentials/Kit.java index e32ade33e33..8331e6abb33 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Kit.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Kit.java @@ -26,6 +26,7 @@ import java.util.GregorianCalendar; import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.logging.Level; import static com.earth2me.essentials.I18n.tlLiteral; @@ -174,10 +175,11 @@ public boolean expandItems(final User user, final List items) throws Exc final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments(); final boolean autoEquip = ess.getSettings().isKitAutoEquip(); final List itemList = new ArrayList<>(); + final Map itemsWithSlot = new HashMap<>(); final List commandQueue = new ArrayList<>(); final List moneyQueue = new ArrayList<>(); final String currencySymbol = ess.getSettings().getCurrencySymbol().isEmpty() ? "$" : ess.getSettings().getCurrencySymbol(); - for (final String kitItem : output.getLines()) { + for (String kitItem : output.getLines()) { if (kitItem.startsWith("$") || kitItem.startsWith(currencySymbol)) { moneyQueue.add(NumberUtil.sanitizeCurrencyString(kitItem, ess)); continue; @@ -191,6 +193,13 @@ public boolean expandItems(final User user, final List items) throws Exc continue; } + int itemSlot = -1; + if (kitItem.startsWith("slot:")) { + final String slotStr = kitItem.substring("slot:".length(), kitItem.indexOf(" ")); + itemSlot = NumberUtil.isInt(slotStr) ? Integer.parseInt(slotStr) : -1; + kitItem = kitItem.substring(kitItem.indexOf(" ") + 1); + } + final ItemStack stack; final SerializationProvider serializationProvider = ess.provider(SerializationProvider.class); @@ -218,7 +227,11 @@ public boolean expandItems(final User user, final List items) throws Exc stack = metaStack.getItemStack(); } - itemList.add(stack); + if (itemSlot == -1 || itemsWithSlot.containsKey(itemSlot)) { + itemList.add(stack); + } else { + itemsWithSlot.put(itemSlot, stack); + } } final int maxStackSize = user.isAuthorized("essentials.oversizedstacks") ? ess.getSettings().getOversizedStackSize() : 0; @@ -227,13 +240,22 @@ public boolean expandItems(final User user, final List items) throws Exc final KitPreExpandItemsEvent itemsEvent = new KitPreExpandItemsEvent(user, kitName, itemList); Bukkit.getPluginManager().callEvent(itemsEvent); - final ItemStack[] itemArray = itemList.toArray(new ItemStack[0]); - - if (!isDropItemsIfFull && !Inventories.hasSpace(user.getBase(), maxStackSize, autoEquip, itemArray)) { + final List totalItems = new ArrayList<>(itemList); + totalItems.addAll(itemsWithSlot.values()); + final ItemStack[] totalItemsArray = totalItems.toArray(new ItemStack[0]); + if (!isDropItemsIfFull && !Inventories.hasSpace(user.getBase(), maxStackSize, autoEquip, totalItemsArray)) { user.sendTl("kitInvFullNoDrop"); return false; } + for (Map.Entry itemWithSlot : itemsWithSlot.entrySet()) { + final ItemStack leftover = Inventories.addItem(user.getBase(), maxStackSize, itemWithSlot.getValue(), itemWithSlot.getKey()); + if (leftover != null) { + itemList.add(leftover); + } + } + + final ItemStack[] itemArray = itemList.toArray(new ItemStack[0]); final Map leftover = Inventories.addItem(user.getBase(), maxStackSize, autoEquip, itemArray); if (!isDropItemsIfFull && !leftover.isEmpty()) { // Inventories#hasSpace should prevent this state from EVER being reached; If it does, something has gone terribly wrong, and we should just give up and hope people report it :( diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java index 7325a75b770..0c5189f82ba 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java @@ -51,13 +51,14 @@ public void run(final Server server, final User user, final String commandLabel, useSerializationProvider = false; } - for (ItemStack is : items) { + for (int i = 0; i < items.length; i++) { + final ItemStack is = items[i]; if (is != null && is.getType() != null && is.getType() != Material.AIR) { final String serialized; if (useSerializationProvider) { - serialized = "@" + Base64Coder.encodeLines(serializationProvider.serializeItem(is)); + serialized = "slot:" + i + " @" + Base64Coder.encodeLines(serializationProvider.serializeItem(is)); } else { - serialized = ess.getItemDb().serialize(is); + serialized = "slot:" + i + " " + ess.getItemDb().serialize(is); } list.add(serialized); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/craftbukkit/Inventories.java b/Essentials/src/main/java/com/earth2me/essentials/craftbukkit/Inventories.java index db754a19426..fe25564f23a 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/craftbukkit/Inventories.java +++ b/Essentials/src/main/java/com/earth2me/essentials/craftbukkit/Inventories.java @@ -142,6 +142,35 @@ public static Map addItem(final Player player, final int max return addItem(player, maxStack, false, items); } + public static ItemStack addItem(final Player player, final int maxStack, ItemStack item, int slot) { + final int itemMax = Math.max(maxStack, item.getMaxStackSize()); + + ItemStack existing = player.getInventory().getItem(slot); + final int existingAmount; + if (isEmpty(existing)) { + existing = item.clone(); + existingAmount = 0; + } else { + existingAmount = existing.getAmount(); + } + + if (!item.isSimilar(existing)) { + return item; + } + + final int amount = item.getAmount(); + if (amount + existingAmount <= itemMax) { + existing.setAmount(amount + existingAmount); + player.getInventory().setItem(slot, existing); + return null; + } + + existing.setAmount(itemMax); + player.getInventory().setItem(slot, existing); + item.setAmount(amount + existingAmount - itemMax); + return item; + } + public static Map addItem(final Player player, final int maxStack, final boolean allowArmor, ItemStack... items) { items = normalizeItems(cloneItems(items)); final Map leftover = new HashMap<>();