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..d3f1c68df 100644 --- a/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java +++ b/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java @@ -1,14 +1,19 @@ 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 javax.annotation.Nullable; +import java.util.Collection; import java.util.List; import java.util.UUID; @@ -124,4 +129,26 @@ public interface ICraftingPatternContainer { */ default void onUsedForProcessing() { } + + /** + * Called when the autocrafting system wants to insert items. Will be called with Action.SIMULATE first and if that + * succeeds will be called again with Action.PERFORM + * + * @param dest The ItemHandler to insert into + * @param toInsert A collection of items that should be inserted. + * @param action Action to take + * @return whether the insertion was successful + */ + boolean insertIntoInventory(@Nullable IItemHandler dest, Collection> toInsert, Action action); + + /** + * Called when the autocrafting system wants to insert fluids. Will be called with Action.SIMULATE first and if that + * succeeds will be called again with Action.PERFORM + * + * @param dest The FluidHandler to insert into + * @param toInsert A collection of fluids that should be inserted. + * @param action Action to take + * @return whether the insertion was successful + */ + boolean insertIntoInventory(IFluidHandler dest, Collection> toInsert, Action action); } 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 c56f5fc3b..e96fb3a0c 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 @@ -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.insertIntoInventory(container.getConnectedInventory(), extractedItems.getStacks(), Action.SIMULATE); if (canInsertFullAmount) { - canInsertFullAmount = IoUtil.insertIntoInventory(container.getConnectedFluidInventory(), extractedFluids.getStacks(), Action.SIMULATE); + canInsertFullAmount = container.insertIntoInventory(container.getConnectedFluidInventory(), extractedFluids.getStacks(), Action.SIMULATE); } } @@ -150,8 +150,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.insertIntoInventory(container.getConnectedInventory(), extractedItems.getStacks(), Action.PERFORM); + container.insertIntoInventory(container.getConnectedFluidInventory(), 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 d4f45fa25..ee1e8c327 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 @@ -6,6 +6,8 @@ import com.refinedmods.refinedstorage.api.autocrafting.ICraftingPatternContainer import com.refinedmods.refinedstorage.api.autocrafting.ICraftingPatternProvider; import com.refinedmods.refinedstorage.api.network.INetwork; import com.refinedmods.refinedstorage.api.network.node.INetworkNode; +import com.refinedmods.refinedstorage.api.util.Action; +import com.refinedmods.refinedstorage.api.util.StackListEntry; import com.refinedmods.refinedstorage.apiimpl.API; import com.refinedmods.refinedstorage.inventory.item.BaseItemHandler; import com.refinedmods.refinedstorage.inventory.item.UpgradeItemHandler; @@ -25,18 +27,22 @@ import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.World; import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.wrapper.CombinedInvWrapper; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternContainer { + private static final Logger LOGGER = LogManager.getLogger(CrafterNetworkNode.class); + public enum CrafterMode { IGNORE, SIGNAL_UNLOCKS_AUTOCRAFTING, @@ -456,4 +462,75 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC markDirty(); } } + + @Override + public 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; + } + + @Override + public 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; + } }