From 7292984d546db79b95192d883af4587440893885 Mon Sep 17 00:00:00 2001 From: Darkere Date: Wed, 9 Jun 2021 18:27:26 +0200 Subject: [PATCH 1/5] allow addons to override autocrafting insertion --- .../ICraftingPatternContainer.java | 27 ++++++ .../apiimpl/autocrafting/task/v6/IoUtil.java | 80 +---------------- .../task/v6/node/ProcessingNode.java | 8 +- .../network/node/CrafterNetworkNode.java | 85 ++++++++++++++++++- 4 files changed, 114 insertions(+), 86 deletions(-) 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; + } } From 3516af186acb83280eb348bca188d94a4be4d951 Mon Sep 17 00:00:00 2001 From: Darkere Date: Wed, 9 Jun 2021 18:39:37 +0200 Subject: [PATCH 2/5] allow for cleaner override --- .../ICraftingPatternContainer.java | 16 ++++++++++---- .../task/v6/node/ProcessingNode.java | 12 +++++----- .../network/node/CrafterNetworkNode.java | 22 +++++++++++++++++-- 3 files changed, 38 insertions(+), 12 deletions(-) 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 d3f1c68df..4f0ef3738 100644 --- a/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java +++ b/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java @@ -134,21 +134,29 @@ public interface ICraftingPatternContainer { * 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); + boolean insertItemsIntoInventory(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); + boolean insertFluidsIntoInventory(Collection> toInsert, Action action); + + /** + * @return whether the container is successfully connected to the inventory it wants to insert to + */ + boolean hasConnectedInventory(); + + /** + * @return whether the container is successfully connected to the fluid inventory it wants to insert to + */ + boolean hasConnectedFluidInventory(); } 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 e96fb3a0c..5a750736a 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 = container.insertIntoInventory(container.getConnectedInventory(), extractedItems.getStacks(), Action.SIMULATE); + canInsertFullAmount = container.insertItemsIntoInventory(extractedItems.getStacks(), Action.SIMULATE); if (canInsertFullAmount) { - canInsertFullAmount = container.insertIntoInventory(container.getConnectedFluidInventory(), extractedFluids.getStacks(), Action.SIMULATE); + canInsertFullAmount = container.insertFluidsIntoInventory(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); - container.insertIntoInventory(container.getConnectedInventory(), extractedItems.getStacks(), Action.PERFORM); - container.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 ee1e8c327..ef7aff966 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 @@ -464,7 +464,9 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC } @Override - public boolean insertIntoInventory(@Nullable IItemHandler dest, Collection> toInsert, Action action) { + public boolean insertItemsIntoInventory(Collection> toInsert, Action action) { + IItemHandler dest = getConnectedInventory(); + if (dest == null) { return false; } @@ -518,7 +520,13 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC } @Override - public boolean insertIntoInventory(IFluidHandler dest, Collection> toInsert, Action action) { + public boolean insertFluidsIntoInventory(Collection> toInsert, Action action) { + IFluidHandler dest = getConnectedFluidInventory(); + + if (dest == null) { + return false; + } + for (StackListEntry entry : toInsert) { int filled = dest.fill(entry.getStack(), action == Action.SIMULATE ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE); @@ -533,4 +541,14 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC return true; } + + @Override + public boolean hasConnectedInventory() { + return getConnectedInventory() != null; + } + + @Override + public boolean hasConnectedFluidInventory() { + return getConnectedFluidInventory() != null; + } } From 0a31d9c22fedcb6ad9be04935f4a8a3b963c09e8 Mon Sep 17 00:00:00 2001 From: Darkere Date: Sun, 13 Jun 2021 15:47:59 +0200 Subject: [PATCH 3/5] add default, fix conflict --- .../api/autocrafting/ICraftingPatternContainer.java | 8 ++++++-- .../apiimpl/network/node/CrafterNetworkNode.java | 10 ---------- 2 files changed, 6 insertions(+), 12 deletions(-) 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 4f0ef3738..bc1875d1a 100644 --- a/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java +++ b/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java @@ -153,10 +153,14 @@ public interface ICraftingPatternContainer { /** * @return whether the container is successfully connected to the inventory it wants to insert to */ - boolean hasConnectedInventory(); + default boolean hasConnectedInventory() { + return getConnectedInventory() != null; + } /** * @return whether the container is successfully connected to the fluid inventory it wants to insert to */ - boolean hasConnectedFluidInventory(); + default boolean hasConnectedFluidInventory() { + return getConnectedFluidInventory() != null; + } } 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 5487be55d..daa9662ed 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 @@ -552,14 +552,4 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC return true; } - - @Override - public boolean hasConnectedInventory() { - return getConnectedInventory() != null; - } - - @Override - public boolean hasConnectedFluidInventory() { - return getConnectedFluidInventory() != null; - } } From 1a5ef68be46accd6a652e0829656d71057041a5c Mon Sep 17 00:00:00 2001 From: Darkere Date: Mon, 20 Sep 2021 17:02:41 +0200 Subject: [PATCH 4/5] fix autocrafting --- .../autocrafting/task/v6/node/ProcessingNode.java | 4 ++-- .../apiimpl/network/node/CrafterNetworkNode.java | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) 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 a3ddedc3b..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.hasConnectedInventory()) || - (!singleFluidSetToRequire.isEmpty() && container.hasConnectedFluidInventory())) { + if ((!singleItemSetToRequire.isEmpty() && !container.hasConnectedInventory()) || + (!singleFluidSetToRequire.isEmpty() && !container.hasConnectedFluidInventory())) { if (allMissingMachine) { this.state = ProcessingState.MACHINE_NONE; } 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 daa9662ed..99d926f42 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 @@ -478,14 +478,15 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC public boolean insertItemsIntoInventory(Collection> toInsert, Action action) { IItemHandler dest = getConnectedInventory(); - if (dest == null) { - return false; - } if (toInsert.isEmpty()) { return true; } + if (dest == null) { + return false; + } + Deque> stacks = new ArrayDeque<>(toInsert); StackListEntry currentEntry = stacks.poll(); @@ -534,6 +535,10 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC public boolean insertFluidsIntoInventory(Collection> toInsert, Action action) { IFluidHandler dest = getConnectedFluidInventory(); + if (toInsert.isEmpty()) { + return true; + } + if (dest == null) { return false; } From 67a12840960ec2c52b7cef6c15ef7d05dd72ab87 Mon Sep 17 00:00:00 2001 From: Darkere Date: Sun, 17 Oct 2021 16:44:00 +0200 Subject: [PATCH 5/5] make crafter insertion method default, so addons do not have to copy our code --- .../ICraftingPatternContainer.java | 123 ++++++++++++++---- .../network/node/CrafterNetworkNode.java | 96 +------------- 2 files changed, 104 insertions(+), 115 deletions(-) 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 bc1875d1a..ac01de77c 100644 --- a/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java +++ b/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/ICraftingPatternContainer.java @@ -11,11 +11,12 @@ 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.Collection; -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. @@ -130,26 +131,6 @@ 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 toInsert A collection of items that should be inserted. - * @param action Action to take - * @return whether the insertion was successful - */ - boolean insertItemsIntoInventory(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 toInsert A collection of fluids that should be inserted. - * @param action Action to take - * @return whether the insertion was successful - */ - boolean insertFluidsIntoInventory(Collection> toInsert, Action action); - /** * @return whether the container is successfully connected to the inventory it wants to insert to */ @@ -163,4 +144,100 @@ public interface ICraftingPatternContainer { 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/network/node/CrafterNetworkNode.java b/src/main/java/com/refinedmods/refinedstorage/apiimpl/network/node/CrafterNetworkNode.java index 99d926f42..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 @@ -6,8 +6,6 @@ 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; @@ -27,22 +25,19 @@ 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.Nonnull; 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; +import java.util.Optional; +import java.util.UUID; public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternContainer { - private static final Logger LOGGER = LogManager.getLogger(CrafterNetworkNode.class); public enum CrafterMode { IGNORE, @@ -474,87 +469,4 @@ public class CrafterNetworkNode extends NetworkNode implements ICraftingPatternC } } - @Override - public 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) { - LOGGER.warn("Inventory unexpectedly didn't accept {}, the remainder has been voided!", current != null ? current.getTranslationKey() : null); - } - - return success; - } - - @Override - public 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) { - LOGGER.warn("Inventory unexpectedly didn't accept all of {}, the remainder has been voided!", entry.getStack().getTranslationKey()); - } - - return false; - } - } - - return true; - } }