package advancedsystemsmanager.flow.execution.commands; import advancedsystemsmanager.api.execution.IBuffer; import advancedsystemsmanager.api.execution.IBufferElement; import advancedsystemsmanager.api.execution.Key; import advancedsystemsmanager.api.tileentities.IInternalInventory; import advancedsystemsmanager.flow.FlowComponent; import advancedsystemsmanager.flow.execution.Executor; import advancedsystemsmanager.flow.menus.Menu; import advancedsystemsmanager.flow.menus.MenuContainer; import advancedsystemsmanager.flow.menus.MenuItem; import advancedsystemsmanager.flow.menus.MenuTargetInventory; import advancedsystemsmanager.flow.setting.Setting; import advancedsystemsmanager.reference.Names; import advancedsystemsmanager.reference.Null; import advancedsystemsmanager.registry.CommandRegistry; import advancedsystemsmanager.registry.SystemTypeRegistry; import advancedsystemsmanager.util.SystemCoord; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; import net.minecraft.item.ItemStack; import java.util.*; public class CommandItemOutput extends CommandOutput<ItemStack> { public CommandItemOutput() { super(ITEM_OUTPUT, Names.ITEM_OUTPUT, null); } @Override @SuppressWarnings("unchecked") public void execute(FlowComponent command, int connectionId, Executor executor) { if (executor.containsBuffer(IBuffer.CRAFT_HIGH)) outputFromBuffer(command, executor.getBuffer(IBuffer.CRAFT_HIGH)); if (executor.containsBuffer(IBuffer.ITEM)) outputFromBuffer(command, executor.getBuffer(IBuffer.ITEM)); if (executor.containsBuffer(IBuffer.CRAFT_LOW)) outputFromBuffer(command, executor.getBuffer(IBuffer.CRAFT_LOW)); } @Override protected void outputFromBuffer(FlowComponent component, IBuffer<ItemStack> buffer) { MenuItem menuItem = (MenuItem)component.menus.get(2); List<Setting<ItemStack>> validSettings = getValidSettings(menuItem.getSettings()); List<Integer> validSides = new ArrayList<Integer>(); MenuTargetInventory target = ((MenuTargetInventory)component.getMenus().get(1)); Map<IInventory, Set<Integer>> cachedSlots = new HashMap<IInventory, Set<Integer>>(); for (int i = 0; i < target.activatedDirections.length; i++) if (target.activatedDirections[i]) validSides.add(i); List<SystemCoord> blocks = getContainers(component.manager, (MenuContainer)component.menus.get(0)); CommandRegistry.CONDITION.searchForStuff(blocks, validSettings, target, null); for (SystemCoord block : blocks) { IInventory inventory = block.getTileEntity() instanceof IInternalInventory ? Null.NULL_INVENTORY : (IInventory) block.getTileEntity(); Iterator<Map.Entry<Key<ItemStack>, IBufferElement<ItemStack>>> iterator = buffer.getOrderedIterator(); while (iterator.hasNext()) { IBufferElement<ItemStack> itemBufferElement = iterator.next().getValue(); Setting<ItemStack> setting = isValid(validSettings, itemBufferElement.getContent()); boolean whitelist = menuItem.useWhiteList(); boolean outputCounter = setting != null && setting.isLimitedByAmount(); if (!isValidSetting(whitelist, setting)) continue; ItemStack itemStack = itemBufferElement.getContent(); if (block.getTileEntity() instanceof IInternalInventory) { IInternalInventory internal = (IInternalInventory) block.getTileEntity(); int moveCount = Math.min(internal.getAmountToInsert(itemStack), itemStack.stackSize); if (moveCount > 0) { moveCount = Math.min(itemBufferElement.getSizeLeft(), moveCount); moveCount = itemBufferElement.getMaxWithSetting(moveCount); if (moveCount > 0) { itemBufferElement.reduceBufferAmount(moveCount); if (setting != null && setting.isLimitedByAmount()) { setting.reduceAmount(moveCount); } ItemStack toInsert = itemStack.copy(); toInsert.stackSize = moveCount; internal.insertItemStack(toInsert); if (itemBufferElement.getSizeLeft() == 0) { iterator.remove(); } itemBufferElement.onUpdate(); } } } else { Set<Integer> slots; if (!cachedSlots.containsKey(inventory)) { slots = new TreeSet<Integer>(); for (int side : validSides) { int start = target.advancedDirections[side] ? target.getStart(side) : 0; int end = target.advancedDirections[side] ? target.getEnd(side) : inventory.getSizeInventory() - 1; if (inventory instanceof ISidedInventory) { for (int slot : ((ISidedInventory) inventory).getAccessibleSlotsFromSide(side)) slots.add(slot); } else { for (int slot = start; slot <= end; slot++) slots.add(slot); } } cachedSlots.put(inventory, slots); } else { slots = cachedSlots.get(inventory); } if (slots.isEmpty()) { cachedSlots.remove(inventory); break; } for (int slot : slots) { if (inventory.isItemValidForSlot(slot, itemStack)) { ItemStack itemInSlot = inventory.getStackInSlot(slot); boolean newItem = itemInSlot == null; if (newItem || itemInSlot.isItemEqual(itemStack) && ItemStack.areItemStackTagsEqual(itemStack, itemInSlot) && itemStack.isStackable()) { int itemCountInSlot = newItem ? 0 : itemInSlot.stackSize; int moveCount = Math.min(itemBufferElement.getSizeLeft(), Math.min(inventory.getInventoryStackLimit(), itemStack.getMaxStackSize()) - itemCountInSlot); moveCount = itemBufferElement.getMaxWithSetting(moveCount); if (outputCounter) { moveCount = Math.min(moveCount, setting.getAmountLeft()); } if (moveCount > 0) { if (newItem) { itemInSlot = itemStack.copy(); itemInSlot.stackSize = 0; } itemBufferElement.reduceBufferAmount(moveCount); if (outputCounter) { setting.reduceAmount(moveCount); } itemInSlot.stackSize += moveCount; if (newItem) { inventory.setInventorySlotContents(slot, itemInSlot); } boolean done = false; if (itemBufferElement.getSizeLeft() == 0) { iterator.remove(); done = true; } itemBufferElement.onUpdate(); if (done) { break; } } } } } } } } } @Override public void getMenus(FlowComponent component, List<Menu> menus) { menus.add(new MenuContainer(component, SystemTypeRegistry.INVENTORY)); menus.add(new MenuTargetInventory(component)); menus.add(new MenuItem(component, false)); } }