summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnowleo <schneeleo@gmail.com>2011-06-12 22:55:08 +0200
committersnowleo <schneeleo@gmail.com>2011-06-12 22:55:08 +0200
commit46cba7a9a7dce806bdbee1505e73da9aa0e6f851 (patch)
tree448b3232831197410e69b140d875eb1409d34bd1
parent246383804a1cf20a87accaa9fabb5149c84104de (diff)
downloadEssentials-46cba7a9a7dce806bdbee1505e73da9aa0e6f851.tar
Essentials-46cba7a9a7dce806bdbee1505e73da9aa0e6f851.tar.gz
Essentials-46cba7a9a7dce806bdbee1505e73da9aa0e6f851.tar.lz
Essentials-46cba7a9a7dce806bdbee1505e73da9aa0e6f851.tar.xz
Essentials-46cba7a9a7dce806bdbee1505e73da9aa0e6f851.zip
Use the correct maxStackSize, when adding things to the inventory.
-rw-r--r--Essentials/src/com/earth2me/essentials/InventoryWorkaround.java131
1 files changed, 126 insertions, 5 deletions
diff --git a/Essentials/src/com/earth2me/essentials/InventoryWorkaround.java b/Essentials/src/com/earth2me/essentials/InventoryWorkaround.java
index e56f0affe..c9b513c15 100644
--- a/Essentials/src/com/earth2me/essentials/InventoryWorkaround.java
+++ b/Essentials/src/com/earth2me/essentials/InventoryWorkaround.java
@@ -3,6 +3,7 @@ package com.earth2me.essentials;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Location;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.Item;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@@ -18,7 +19,7 @@ public final class InventoryWorkaround
private InventoryWorkaround()
{
}
-
+
public static int first(final Inventory inventory, final ItemStack item, final boolean forceDurability, final boolean forceAmount)
{
return next(inventory, item, 0, forceDurability, forceAmount);
@@ -42,6 +43,124 @@ public final class InventoryWorkaround
return -1;
}
+ public int firstPartial(final Inventory cinventory, final ItemStack item, final boolean forceDurability)
+ {
+ if (item == null)
+ {
+ return -1;
+ }
+ final ItemStack[] inventory = cinventory.getContents();
+ for (int i = 0; i < inventory.length; i++)
+ {
+ final ItemStack cItem = inventory[i];
+ if (cItem == null)
+ {
+ continue;
+ }
+ if (item.getTypeId() == cItem.getTypeId() && cItem.getAmount() < cItem.getType().getMaxStackSize() && (!forceDurability || cItem.getDurability() == item.getDurability()))
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public Map<Integer, ItemStack> addItem(final Inventory cinventory, final boolean forceDurability, final ItemStack... items)
+ {
+ final Map<Integer, ItemStack> leftover = new HashMap<Integer, ItemStack>();
+
+ /* TODO: some optimization
+ * - Create a 'firstPartial' with a 'fromIndex'
+ * - Record the lastPartial per Material
+ * - Cache firstEmpty result
+ */
+
+ // combine items
+
+ ItemStack[] combined = new ItemStack[items.length];
+ for (int i = 0; i < items.length; i++)
+ {
+ if (items[i] == null)
+ {
+ continue;
+ }
+ for (int j = 0; j < combined.length; j++)
+ {
+ if (combined[j] == null)
+ {
+ combined[j] = new ItemStack(items[i].getType(), items[i].getAmount(), items[i].getDurability());
+ break;
+ }
+ if (combined[j].getTypeId() == items[i].getTypeId() && (!forceDurability || combined[j].getDurability() == items[i].getDurability()))
+ {
+ combined[j].setAmount(combined[j].getAmount() + items[i].getAmount());
+ break;
+ }
+ }
+ }
+
+
+ for (int i = 0; i < items.length; i++)
+ {
+ final ItemStack item = items[i];
+ while (true)
+ {
+ // Do we already have a stack of it?
+ final int firstPartial = firstPartial(cinventory, item, forceDurability);
+
+ // Drat! no partial stack
+ if (firstPartial == -1)
+ {
+ // Find a free spot!
+ final int firstFree = cinventory.firstEmpty();
+
+ if (firstFree == -1)
+ {
+ // No space at all!
+ leftover.put(i, item);
+ break;
+ }
+ else
+ {
+ // More than a single stack!
+ if (item.getAmount() > item.getType().getMaxStackSize())
+ {
+ cinventory.setItem(firstFree, new CraftItemStack(item.getTypeId(), item.getType().getMaxStackSize(), item.getDurability()));
+ item.setAmount(item.getAmount() - item.getType().getMaxStackSize());
+ }
+ else
+ {
+ // Just store it
+ cinventory.setItem(firstFree, item);
+ break;
+ }
+ }
+ }
+ else
+ {
+ // So, apparently it might only partially fit, well lets do just that
+ final ItemStack partialItem = cinventory.getItem(firstPartial);
+
+ final int amount = item.getAmount();
+ final int partialAmount = partialItem.getAmount();
+ final int maxAmount = partialItem.getType().getMaxStackSize();
+
+ // Check if it fully fits
+ if (amount + partialAmount <= maxAmount)
+ {
+ partialItem.setAmount(amount + partialAmount);
+ break;
+ }
+
+ // It fits partially
+ partialItem.setAmount(maxAmount);
+ item.setAmount(amount + partialAmount - maxAmount);
+ }
+ }
+ }
+ return leftover;
+ }
+
public static Map<Integer, ItemStack> removeItem(final Inventory cinventory, final boolean forceDurability, final ItemStack... items)
{
final Map<Integer, ItemStack> leftover = new HashMap<Integer, ItemStack>();
@@ -182,11 +301,13 @@ public final class InventoryWorkaround
final int stacks = itm.getAmount() / maxStackSize;
final int leftover = itm.getAmount() % maxStackSize;
Item[] itemStacks = new Item[stacks + (leftover > 0 ? 1 : 0)];
- for (int i = 0; i < stacks; i++) {
- itemStacks[i] = loc.getWorld().dropItem(loc, new ItemStack(itm.getType(), maxStackSize, itm.getDurability()));
+ for (int i = 0; i < stacks; i++)
+ {
+ itemStacks[i] = loc.getWorld().dropItem(loc, new ItemStack(itm.getType(), maxStackSize, itm.getDurability()));
}
- if (leftover > 0) {
- itemStacks[stacks] = loc.getWorld().dropItem(loc, new ItemStack(itm.getType(), leftover, itm.getDurability()));
+ if (leftover > 0)
+ {
+ itemStacks[stacks] = loc.getWorld().dropItem(loc, new ItemStack(itm.getType(), leftover, itm.getDurability()));
}
return itemStacks;
}