/** * Attempts to empty the specified {@link ItemStack} into the inventory starting at the specified * slot. While iterating through the inventories slots, if a slot is null the remainder of the * ItemStack will be put in the null slot, if a slot is not null but the {@link * org.spout.api.material.Material} of the two ItemStacks do not match, the iteration will * continue to the next slot, and if the slot is not null and the Material of the two ItemStacks * do match the two ItemStacks will attempt to be 'stacked'. After {@link * ItemStack#stack(org.spout.api.inventory.ItemStack)} has been called, if the specified ItemStack * is empty the call will return, otherwise it will continue iterating through the slots until * either the stack is empty, or the iteration has ended. * * @param firstSlot slot to start iteration at (inclusive) * @param lastSlot slot to end iteration at (inclusive) * @param item to attempt to add to the inventory */ public void add(int firstSlot, int lastSlot, ItemStack item) { // First pass try to add to existing stacks, second pass, add to empty slots final boolean reversed = lastSlot < firstSlot; final int incr = reversed ? -1 : 1; for (int pass = 0; pass < 2; pass++) { for (int index = firstSlot; reversed ? (index >= lastSlot) : (index <= lastSlot); index += incr) { ItemStack slot = get(index); if (pass == 1) { if (slot == null) { set(index, item); item.setAmount(0); return; } } if (slot != null && slot.equalsIgnoreSize(item)) { slot.stack(item); set(index, slot); } if (item.isEmpty()) { return; } } } }
/** * Get a block. * * @param item */ @Override public void fetchItem(BaseItem item) throws BlockBagException { final int id = item.getType(); final int damage = item.getDamage(); int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1; assert (amount == 1); boolean usesDamageValue = ItemType.usesDamageValue(id); if (id == BlockID.AIR) { throw new IllegalArgumentException("Can't fetch air block"); } loadInventory(); boolean found = false; for (int slot = 0; slot < items.length; ++slot) { ItemStack bukkitItem = items[slot]; if (bukkitItem == null) { continue; } if (bukkitItem.getMaterial().getId() != id) { // Type id doesn't fit continue; } if (usesDamageValue && bukkitItem.getDamage() != damage) { // Damage value doesn't fit. continue; } int currentAmount = bukkitItem.getAmount(); if (currentAmount < 0) { // Unlimited return; } if (currentAmount > 1) { bukkitItem.setAmount(currentAmount - 1); found = true; } else { items[slot] = null; found = true; } break; } if (!found) { throw new OutOfBlocksException(); } }
/** * Sets the amount of an {@link ItemStack} at the specified slot to the specified amount * * @param slot to set item at * @param amount to set to */ public void setAmount(int slot, int amount) { ItemStack item = get(slot); if (item != null) { if (amount < 1) { item = null; } else { item.setAmount(Math.min(amount, item.getMaxStackSize())); } set(slot, item); } }
/** * Store a block. * * @param item */ @Override public void storeItem(BaseItem item) throws BlockBagException { final int id = item.getType(); final int damage = item.getDamage(); int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1; assert (amount <= 64); boolean usesDamageValue = ItemType.usesDamageValue(id); if (id == BlockID.AIR) { throw new IllegalArgumentException("Can't store air block"); } loadInventory(); int freeSlot = -1; for (int slot = 0; slot < items.length; ++slot) { ItemStack bukkitItem = items[slot]; if (bukkitItem == null) { // Delay using up a free slot until we know there are no stacks // of this item to merge into if (freeSlot == -1) { freeSlot = slot; } continue; } if (bukkitItem.getMaterial().getId() != id) { // Type id doesn't fit continue; } if (usesDamageValue && bukkitItem.getDamage() != damage) { // Damage value doesn't fit. continue; } int currentAmount = bukkitItem.getAmount(); if (currentAmount < 0) { // Unlimited return; } if (currentAmount >= 64) { // Full stack continue; } int spaceLeft = 64 - currentAmount; if (spaceLeft >= amount) { bukkitItem.setAmount(currentAmount + amount); return; } bukkitItem.setAmount(64); amount -= spaceLeft; } if (freeSlot > -1) { items[freeSlot] = new ItemStack(MaterialData.getMaterial((short) id), amount); return; } throw new OutOfSpaceException(id); }