@Override public boolean onShiftClick(ItemStack stack, int slot, Inventory from) { if (getPlayer().getEngine().getPlatform() == Platform.CLIENT) { throw new IllegalStateException("Shift click handling is handled server side."); } final PlayerInventory inventory = getPlayerInventory(); // From main inventory/quickbar to the dispenser if (from instanceof PlayerMainInventory || from instanceof QuickbarInventory) { for (InventoryConverter conv : this.getInventoryConverters()) { Inventory inv = conv.getInventory(); if (inv instanceof DispenserInventory) { Grid grid = inv.grid(3); final int height = grid.getHeight(); final int length = grid.getLength(); for (int row = height - 1; row >= 0; row--) { int startSlot = length * row; int endSlot = startSlot + length - 1; inv.add(startSlot, endSlot, stack); from.set(slot, stack); if (stack.isEmpty()) { return true; } } } } } // From chest to inventory/quickbar if (from instanceof DispenserInventory) { // To quickbar (reversed) final QuickbarInventory qbar = inventory.getQuickbar(); qbar.add(qbar.size() - 1, 0, stack); from.set(slot, stack); if (stack.isEmpty()) { return true; } // To main inventory (reversed) final Inventory main = inventory.getMain(); for (int row = 0; row < PlayerMainInventory.HEIGHT; row++) { int startSlot = PlayerMainInventory.LENGTH * row; int endSlot = startSlot + PlayerMainInventory.LENGTH - 1; main.add(endSlot, startSlot, stack); from.set(slot, stack); if (stack.isEmpty()) { return true; } } } return false; }
/** * 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; } } } }
/** * Replaces the {@link ItemStack} at the specified slot in this inventory with the specified * ItemStack. * * @param i slot to set the item at * @param item to set in the specified slot * @return the item previously at the slot */ @Override public ItemStack set(int i, ItemStack item) { if (item != null && item.isEmpty()) { item = null; } ItemStack old = get(i); contents[i] = item == null ? null : item.clone(); update(i); return old; }