diff --git a/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java b/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java index bdbd8462c..ac01de77c 100644 --- a/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java +++ b/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java @@ -1,16 +1,22 @@ package com.refinedmods.refinedstorage.api.autocrafting; +import com.refinedmods.refinedstorage.api.util.Action; +import com.refinedmods.refinedstorage.api.util.StackListEntry; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; +import org.apache.logging.log4j.LogManager; import javax.annotation.Nullable; -import java.util.List; -import java.util.UUID; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; /** * Represents a network node that contains crafting patterns. @@ -124,4 +130,114 @@ public interface ICraftingPatternContainer { */ default void onUsedForProcessing() { } + + /** + * @return whether the container is successfully connected to the inventory it wants to insert to + */ + default boolean hasConnectedInventory() { + return getConnectedInventory() != null; + } + + /** + * @return whether the container is successfully connected to the fluid inventory it wants to insert to + */ + default boolean hasConnectedFluidInventory() { + return getConnectedFluidInventory() != null; + } + + /** + * Called by Autocrafting when it uses this crafter in a processing recipe that has items as input + * + * @param toInsert Collection of Itemstack stacklist entries to insert into the inventory + * @param action action to perform + * @return whether insertion was successful + */ + default boolean insertItemsIntoInventory(Collection> toInsert, Action action) { + IItemHandler dest = getConnectedInventory(); + + + if (toInsert.isEmpty()) { + return true; + } + + if (dest == null) { + return false; + } + + Deque> stacks = new ArrayDeque<>(toInsert); + + StackListEntry currentEntry = stacks.poll(); + + ItemStack current = currentEntry != null ? currentEntry.getStack() : null; + + List availableSlots = IntStream.range(0, dest.getSlots()).boxed().collect(Collectors.toList()); + + while (current != null && !availableSlots.isEmpty()) { + ItemStack remainder = ItemStack.EMPTY; + + for (int i = 0; i < availableSlots.size(); ++i) { + int slot = availableSlots.get(i); + + // .copy() is mandatory! + remainder = dest.insertItem(slot, current.copy(), action == Action.SIMULATE); + + // If we inserted *something* + if (remainder.isEmpty() || current.getCount() != remainder.getCount()) { + availableSlots.remove(i); + break; + } + } + + if (remainder.isEmpty()) { // If we inserted successfully, get a next stack. + currentEntry = stacks.poll(); + + current = currentEntry != null ? currentEntry.getStack() : null; + } else if (current.getCount() == remainder.getCount()) { // If we didn't insert anything over ALL these slots, stop here. + break; + } else { // If we didn't insert all, continue with other slots and use our remainder. + current = remainder; + } + } + + boolean success = current == null && stacks.isEmpty(); + + if (!success && action == Action.PERFORM) { + LogManager.getLogger().warn("Inventory unexpectedly didn't accept {}, the remainder has been voided!", current != null ? current.getTranslationKey() : null); + } + + return success; + } + + /** + * Called by Autocrafting when it uses this crafter in a processing recipe that has fluids as input + * + * @param toInsert Collection of Fluidstack stacklist entries to insert into the inventory + * @param action action to perform + * @return whether insertion was successful + */ + default boolean insertFluidsIntoInventory(Collection> toInsert, Action action) { + IFluidHandler dest = getConnectedFluidInventory(); + + if (toInsert.isEmpty()) { + return true; + } + + if (dest == null) { + return false; + } + + for (StackListEntry entry : toInsert) { + int filled = dest.fill(entry.getStack(), action == Action.SIMULATE ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE); + + if (filled != entry.getStack().getAmount()) { + if (action == Action.PERFORM) { + LogManager.getLogger().warn("Inventory unexpectedly didn't accept all of {}, the remainder has been voided!", entry.getStack().getTranslationKey()); + } + + return false; + } + } + + return true; + } } diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/IoUtil.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/IoUtil.java index 5083f2a4c..afdb90e3e 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/IoUtil.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/IoUtil.java @@ -9,18 +9,11 @@ import com.refinedmods.refinedstorage.api.util.StackListEntry; import com.refinedmods.refinedstorage.apiimpl.API; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.items.IItemHandler; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import javax.annotation.Nullable; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.IntStream; +import java.util.ArrayList; +import java.util.List; public final class IoUtil { - private static final Logger LOGGER = LogManager.getLogger(IoUtil.class); private static final int DEFAULT_EXTRACT_FLAGS = IComparer.COMPARE_NBT; private IoUtil() { @@ -66,75 +59,6 @@ public final class IoUtil { return extracted; } - public static boolean insertIntoInventory(@Nullable IItemHandler dest, Collection> toInsert, Action action) { - if (dest == null) { - return false; - } - - if (toInsert.isEmpty()) { - return true; - } - - Deque> stacks = new ArrayDeque<>(toInsert); - - StackListEntry currentEntry = stacks.poll(); - - ItemStack current = currentEntry != null ? currentEntry.getStack() : null; - - List availableSlots = IntStream.range(0, dest.getSlots()).boxed().collect(Collectors.toList()); - - while (current != null && !availableSlots.isEmpty()) { - ItemStack remainder = ItemStack.EMPTY; - - for (int i = 0; i < availableSlots.size(); ++i) { - int slot = availableSlots.get(i); - - // .copy() is mandatory! - remainder = dest.insertItem(slot, current.copy(), action == Action.SIMULATE); - - // If we inserted *something* - if (remainder.isEmpty() || current.getCount() != remainder.getCount()) { - availableSlots.remove(i); - break; - } - } - - if (remainder.isEmpty()) { // If we inserted successfully, get a next stack. - currentEntry = stacks.poll(); - - current = currentEntry != null ? currentEntry.getStack() : null; - } else if (current.getCount() == remainder.getCount()) { // If we didn't insert anything over ALL these slots, stop here. - break; - } else { // If we didn't insert all, continue with other slots and use our remainder. - current = remainder; - } - } - - boolean success = current == null && stacks.isEmpty(); - - if (!success && action == Action.PERFORM) { - LOGGER.warn("Inventory unexpectedly didn't accept {}, the remainder has been voided!", current != null ? current.getTranslationKey() : null); - } - - return success; - } - - public static boolean insertIntoInventory(IFluidHandler dest, Collection> toInsert, Action action) { - for (StackListEntry entry : toInsert) { - int filled = dest.fill(entry.getStack(), action == Action.SIMULATE ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE); - - if (filled != entry.getStack().getAmount()) { - if (action == Action.PERFORM) { - LOGGER.warn("Inventory unexpectedly didn't accept all of {}, the remainder has been voided!", entry.getStack().getTranslationKey()); - } - - return false; - } - } - - return true; - } - public static void extractItemsFromNetwork(IStackList toExtractInitial, INetwork network, IStorageDisk internalStorage) { if (toExtractInitial.isEmpty()) { return; diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/ProcessingNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/ProcessingNode.java index 6c718d520..fc51f65a6 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/ProcessingNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/autocrafting/task/v6/node/ProcessingNode.java @@ -104,8 +104,8 @@ public class ProcessingNode extends Node { allLocked = false; } - if ((!singleItemSetToRequire.isEmpty() && container.getConnectedInventory() == null) || - (!singleFluidSetToRequire.isEmpty() && container.getConnectedFluidInventory() == null)) { + if ((!singleItemSetToRequire.isEmpty() && !container.hasConnectedInventory()) || + (!singleFluidSetToRequire.isEmpty() && !container.hasConnectedFluidInventory())) { if (allMissingMachine) { this.state = ProcessingState.MACHINE_NONE; } @@ -128,9 +128,9 @@ public class ProcessingNode extends Node { boolean canInsertFullAmount = false; if (hasAllRequirements) { - canInsertFullAmount = IoUtil.insertIntoInventory(container.getConnectedInventory(), extractedItems.getStacks(), Action.SIMULATE); + canInsertFullAmount = container.insertItemsIntoInventory(extractedItems.getStacks(), Action.SIMULATE); if (canInsertFullAmount) { - canInsertFullAmount = IoUtil.insertIntoInventory(container.getConnectedFluidInventory(), extractedFluids.getStacks(), Action.SIMULATE); + canInsertFullAmount = container.insertFluidsIntoInventory(extractedFluids.getStacks(), Action.SIMULATE); } } else { break; @@ -151,8 +151,8 @@ public class ProcessingNode extends Node { extractedItems = IoUtil.extractFromInternalItemStorage(requirements.getSingleItemRequirementSet(false), internalStorage, Action.PERFORM); extractedFluids = IoUtil.extractFromInternalFluidStorage(requirements.getSingleFluidRequirementSet(false), internalFluidStorage, Action.PERFORM); - IoUtil.insertIntoInventory(container.getConnectedInventory(), extractedItems.getStacks(), Action.PERFORM); - IoUtil.insertIntoInventory(container.getConnectedFluidInventory(), extractedFluids.getStacks(), Action.PERFORM); + container.insertItemsIntoInventory(extractedItems.getStacks(), Action.PERFORM); + container.insertFluidsIntoInventory(extractedFluids.getStacks(), Action.PERFORM); next(); diff --git a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/CrafterNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/CrafterNetworkNode.java index c79014ab8..5b0adb7f4 100644 --- a/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/CrafterNetworkNode.java +++ b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/CrafterNetworkNode.java @@ -38,6 +38,7 @@ import java.util.Optional; import java.util.UUID; public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternContainer { + public enum CrafterMode { IGNORE, SIGNAL_UNLOCKS_AUTOCRAFTING, @@ -467,4 +468,5 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC markDirty(); } } + }