From 7596239b32323922d242c2afd251f0e27ad80637 Mon Sep 17 00:00:00 2001 From: raoulvdberge Date: Thu, 9 Aug 2018 21:28:19 +0200 Subject: [PATCH] New autocrafting system, again. --- .../api/autocrafting/ICraftingManager.java | 4 +- .../api/autocrafting/task/ICraftingTask.java | 10 - .../refinedstorage/api/network/INetwork.java | 21 +- .../apiimpl/autocrafting/CraftingManager.java | 24 +- .../registry/CraftingTaskFactory.java | 2 +- .../apiimpl/autocrafting/task/Crafting.java | 30 + .../autocrafting/task/CraftingTask.java | 737 ++++++++++-------- .../apiimpl/autocrafting/task/Processing.java | 53 ++ .../autocrafting/task/ProcessingState.java | 9 + .../task/extractor/CraftingExtractor.java | 179 ----- .../extractor/CraftingExtractorStack.java | 79 -- .../extractor/CraftingExtractorStatus.java | 9 - .../task/inserter/CraftingInserter.java | 101 --- .../task/inserter/CraftingInserterItem.java | 25 - .../inserter/CraftingInserterItemStatus.java | 6 - .../autocrafting/task/step/CraftingStep.java | 74 -- .../task/step/CraftingStepCraft.java | 109 --- .../task/step/CraftingStepProcess.java | 175 ----- 18 files changed, 511 insertions(+), 1136 deletions(-) create mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/Crafting.java create mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/Processing.java create mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/ProcessingState.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractor.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractorStack.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractorStatus.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserter.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserterItem.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserterItemStatus.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStep.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStepCraft.java delete mode 100644 src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStepProcess.java diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java index 0cbe4bad1..2da0e3196 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingManager.java @@ -101,14 +101,14 @@ public interface ICraftingManager { * * @param stack the stack */ - void track(ItemStack stack, int size); + int track(ItemStack stack, int size); /** * Tracks an incoming stack. * * @param stack the stack */ - void track(FluidStack stack, int size); + int track(FluidStack stack, int size); /** * @return a list of crafting patterns in this network, do NOT modify this list diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java index ac80fa14e..3c4307866 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/task/ICraftingTask.java @@ -56,7 +56,6 @@ public interface ICraftingTask { * Called when a stack is inserted into the system through {@link com.raoulvdberge.refinedstorage.api.network.INetwork#insertItemTracked(ItemStack, int)}. * * @param stack the stack - * @return the size remaining, decremented by the crafting task when it was relevant to it */ int onTrackedInsert(ItemStack stack, int size); @@ -64,7 +63,6 @@ public interface ICraftingTask { * Called when a stack is inserted into the system through {@link com.raoulvdberge.refinedstorage.api.network.INetwork#insertFluidTracked(FluidStack, int)}. * * @param stack the stack - * @return the size remaining, decremented by the crafting task when it was relevant to it */ int onTrackedInsert(FluidStack stack, int size); @@ -95,14 +93,6 @@ public interface ICraftingTask { */ ICraftingPattern getPattern(); - /** - * Used to check if the crafting task has recursive elements (eg. block needs 9 ingots, ingots are crafted by a block). - * {@link ICraftingTask#calculate()} must be run before this! - * - * @return true if no recursion was found, false otherwise - */ - boolean isValid(); - /** * @return the time in ms when this task has started */ diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetwork.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetwork.java index 3cd707ad7..27c950669 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetwork.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetwork.java @@ -108,14 +108,15 @@ public interface INetwork { * @param size the amount of that prototype that has to be inserted * @return null if the insert was successful, or a stack with the remainder */ + @Nullable default ItemStack insertItemTracked(@Nonnull ItemStack stack, int size) { - ItemStack remainder = insertItem(stack, size, Action.PERFORM); + int remainder = getCraftingManager().track(stack, size); - int inserted = remainder == null ? size : (size - remainder.getCount()); + if (remainder == 0) { + return null; + } - getCraftingManager().track(stack, inserted); - - return remainder; + return insertItem(stack, remainder, Action.PERFORM); } /** @@ -178,13 +179,13 @@ public interface INetwork { */ @Nullable default FluidStack insertFluidTracked(@Nonnull FluidStack stack, int size) { - FluidStack remainder = insertFluid(stack, size, Action.PERFORM); + int remainder = getCraftingManager().track(stack, size); - int inserted = remainder == null ? size : (size - remainder.amount); + if (remainder == 0) { + return null; + } - getCraftingManager().track(stack, inserted); - - return remainder; + return insertFluid(stack, remainder, Action.PERFORM); } /** diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java index 1b49ec872..de69ae95e 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingManager.java @@ -152,7 +152,9 @@ public class CraftingManager implements ICraftingManager { } this.tasksToCancel.clear(); - this.tasksToAdd.stream().filter(ICraftingTask::isValid).forEach(t -> tasks.put(t.getId(), t)); + for (ICraftingTask task : this.tasksToAdd) { + this.tasks.put(task.getId(), task); + } this.tasksToAdd.clear(); boolean anyFinished = false; @@ -275,37 +277,29 @@ public class CraftingManager implements ICraftingManager { } @Override - public void track(ItemStack stack, int size) { - int initialSize = size; - + public int track(ItemStack stack, int size) { for (ICraftingTask task : tasks.values()) { size = task.onTrackedInsert(stack, size); if (size == 0) { - break; + return 0; } } - if (size != initialSize) { - this.onTaskChanged(); - } + return size; } @Override - public void track(FluidStack stack, int size) { - int initialSize = size; - + public int track(FluidStack stack, int size) { for (ICraftingTask task : tasks.values()) { size = task.onTrackedInsert(stack, size); if (size == 0) { - break; + return 0; } } - if (size != initialSize) { - this.onTaskChanged(); - } + return size; } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java index 7b87a9b54..c3f8e12e7 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/registry/CraftingTaskFactory.java @@ -22,6 +22,6 @@ public class CraftingTaskFactory implements ICraftingTaskFactory { @Override public ICraftingTask createFromNbt(INetwork network, NBTTagCompound tag) throws CraftingTaskReadException { - return new CraftingTask(network, tag); + throw new CraftingTaskReadException("Persistence isn't implemented yet, ignoring..."); // TODO: Persistence } } \ No newline at end of file diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/Crafting.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/Crafting.java new file mode 100644 index 000000000..4f7c17872 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/Crafting.java @@ -0,0 +1,30 @@ +package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; + +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; +import com.raoulvdberge.refinedstorage.api.util.IStackList; +import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; + +class Crafting { + private ICraftingPattern pattern; + private NonNullList took; + private IStackList toExtract; + + public Crafting(ICraftingPattern pattern, NonNullList took, IStackList toExtract) { + this.pattern = pattern; + this.took = took; + this.toExtract = toExtract; + } + + public ICraftingPattern getPattern() { + return pattern; + } + + public NonNullList getTook() { + return took; + } + + public IStackList getToExtract() { + return toExtract; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java index cb568ee61..b54f45692 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingTask.java @@ -1,12 +1,17 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; -import com.raoulvdberge.refinedstorage.api.autocrafting.*; +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChain; +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternChainList; import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElement; import com.raoulvdberge.refinedstorage.api.autocrafting.craftingmonitor.ICraftingMonitorElementList; import com.raoulvdberge.refinedstorage.api.autocrafting.preview.ICraftingPreviewElement; -import com.raoulvdberge.refinedstorage.api.autocrafting.task.*; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingRequestInfo; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTask; +import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingTaskError; import com.raoulvdberge.refinedstorage.api.network.INetwork; -import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; +import com.raoulvdberge.refinedstorage.api.storage.IStorage; +import com.raoulvdberge.refinedstorage.api.util.Action; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.api.util.IStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; @@ -16,57 +21,34 @@ import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.Craf import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.CraftingMonitorElementText; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStatus; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserter; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserterItem; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserterItemStatus; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step.CraftingStep; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step.CraftingStepCraft; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step.CraftingStepProcess; -import com.raoulvdberge.refinedstorage.util.StackUtils; +import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.StorageDiskFluid; +import com.raoulvdberge.refinedstorage.apiimpl.storage.disk.StorageDiskItem; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; import net.minecraft.util.NonNullList; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraftforge.common.util.Constants; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.ItemHandlerHelper; -import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nullable; import java.util.*; public class CraftingTask implements ICraftingTask { - private static final long CALCULATION_TIMEOUT_MS = 5000; - - private static final String NBT_REQUESTED = "Requested"; - private static final String NBT_QUANTITY = "Quantity"; - private static final String NBT_PATTERN = "Pattern"; - private static final String NBT_STEPS = "Steps"; - private static final String NBT_INSERTER = "Inserter"; - private static final String NBT_TICKS = "Ticks"; - private static final String NBT_ID = "Id"; - private static final String NBT_MISSING = "Missing"; - private static final String NBT_EXECUTION_STARTED = "ExecutionStarted"; - - private static final String NBT_PATTERN_STACK = "Stack"; - private static final String NBT_PATTERN_CONTAINER_POS = "ContainerPos"; - private INetwork network; private ICraftingRequestInfo requested; private int quantity; private ICraftingPattern pattern; - private List steps = new LinkedList<>(); - private CraftingInserter inserter; - private Set patternsUsed = new HashSet<>(); - private int ticks = 0; - private long calculationStarted = -1; - private long executionStarted = -1; private UUID id = UUID.randomUUID(); + private int ticks; + private long executionStarted = -1; + + private IStorage internalStorage; + private IStorage internalFluidStorage; + + private IStackList toExtractInitial = API.instance().createItemStackList(); + private IStackList toExtractInitialFluids = API.instance().createFluidStackList(); + + private List crafting = new ArrayList<>(); + private List processing = new ArrayList<>(); private IStackList toTake = API.instance().createItemStackList(); private IStackList toTakeFluids = API.instance().createFluidStackList(); @@ -79,58 +61,17 @@ public class CraftingTask implements ICraftingTask { public CraftingTask(INetwork network, ICraftingRequestInfo requested, int quantity, ICraftingPattern pattern) { this.network = network; - this.inserter = new CraftingInserter(network); this.requested = requested; this.quantity = quantity; this.pattern = pattern; - } - public CraftingTask(INetwork network, NBTTagCompound tag) throws CraftingTaskReadException { - this.network = network; - - this.requested = API.instance().createCraftingRequestInfo(tag.getCompoundTag(NBT_REQUESTED)); - this.quantity = tag.getInteger(NBT_QUANTITY); - this.pattern = readPatternFromNbt(tag.getCompoundTag(NBT_PATTERN), network.world()); - this.inserter = new CraftingInserter(network, tag.getTagList(NBT_INSERTER, Constants.NBT.TAG_COMPOUND)); - this.ticks = tag.getInteger(NBT_TICKS); - this.id = tag.getUniqueId(NBT_ID); - - NBTTagList steps = tag.getTagList(NBT_STEPS, Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < steps.tagCount(); ++i) { - NBTTagCompound stepTag = steps.getCompoundTagAt(i); - - this.steps.add(CraftingStep.readFromNbt(network, inserter, stepTag)); - } - - NBTTagList missing = tag.getTagList(NBT_MISSING, Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < missing.tagCount(); ++i) { - ItemStack missingItem = StackUtils.deserializeStackFromNbt(missing.getCompoundTagAt(i)); - - if (missingItem.isEmpty()) { - throw new CraftingTaskReadException("Missing item is empty"); - } - - this.missing.add(missingItem); - } - - if (tag.hasKey(NBT_EXECUTION_STARTED)) { - this.executionStarted = tag.getLong(NBT_EXECUTION_STARTED); - } + this.internalStorage = new StorageDiskItem(network.world(), -1); + this.internalFluidStorage = new StorageDiskFluid(network.world(), -1); } @Override @Nullable public ICraftingTaskError calculate() { - if (calculationStarted != -1) { - throw new IllegalStateException("Task already calculated!"); - } - - if (executionStarted != -1) { - throw new IllegalStateException("Task already started!"); - } - - this.calculationStarted = System.currentTimeMillis(); - int qty = this.quantity; int qtyPerCraft = getQuantityPerCraft(); int crafted = 0; @@ -141,52 +82,17 @@ public class CraftingTask implements ICraftingTask { IStackList storage = network.getItemStorageCache().getList().copy(); IStackList fluidStorage = network.getFluidStorageCache().getList().copy(); - // Items that are being handled in other tasks aren't available to us. - for (ICraftingTask task : network.getCraftingManager().getTasks()) { - if (task instanceof CraftingTask) { - for (CraftingStep step : ((CraftingTask) task).steps) { - CraftingExtractor extractor = null; - - if (step instanceof CraftingStepCraft) { - extractor = ((CraftingStepCraft) step).getExtractor(); - } else if (step instanceof CraftingStepProcess) { - extractor = ((CraftingStepProcess) step).getExtractor(); - } - - if (extractor != null) { - for (CraftingExtractorStack inUse : extractor.getStacks()) { - ItemStack inUseItem = inUse.getItem(); - - if (inUseItem != null) { - storage.remove(inUseItem); - } else { - FluidStack inUseFluid = inUse.getFluid(); - - if (inUseFluid != null) { - fluidStorage.remove(inUseFluid); - } else { - throw new IllegalStateException("Extractor stack is neither a fluid or an item!"); - } - } - } - } - } - } - } - ICraftingPatternChainList patternChainList = network.getCraftingManager().createPatternChainList(); ICraftingPatternChain patternChain = patternChainList.getChain(pattern); while (qty > 0) { - Pair result = calculateInternal(storage, fluidStorage, results, fluidResults, patternChainList, patternChain.current()); + ICraftingTaskError result = calculateInternal(storage, fluidStorage, results, fluidResults, patternChainList, patternChain.current()); - if (result.getRight() != null) { - return result.getRight(); + if (result != null) { + return result; } - this.steps.add(result.getLeft()); - qty -= qtyPerCraft; crafted += qtyPerCraft; @@ -203,7 +109,8 @@ public class CraftingTask implements ICraftingTask { return null; } - private Pair calculateInternal( + @Nullable + private ICraftingTaskError calculateInternal( IStackList mutatedStorage, IStackList mutatedFluidStorage, IStackList results, @@ -211,14 +118,6 @@ public class CraftingTask implements ICraftingTask { ICraftingPatternChainList patternChainList, ICraftingPattern pattern) { - if (System.currentTimeMillis() - calculationStarted > CALCULATION_TIMEOUT_MS) { - return Pair.of(null, new CraftingTaskError(CraftingTaskErrorType.TOO_COMPLEX)); - } - - if (!patternsUsed.add(pattern)) { - return Pair.of(null, new CraftingTaskError(CraftingTaskErrorType.RECURSIVE, pattern)); - } - IStackList itemsToExtract = API.instance().createItemStackList(); IStackList fluidsToExtract = API.instance().createFluidStackList(); @@ -292,6 +191,8 @@ public class CraftingTask implements ICraftingTask { took.set(took.size() - 1, ItemHandlerHelper.copyStackWithSize(fromNetwork, possibleInput.getCount())); fromNetwork = mutatedStorage.get(possibleInput, flags); + + toExtractInitial.add(took.get(took.size() - 1)); } else { ICraftingPattern subPattern = network.getCraftingManager().getPattern(possibleInput); @@ -299,14 +200,12 @@ public class CraftingTask implements ICraftingTask { ICraftingPatternChain subPatternChain = patternChainList.getChain(subPattern); while ((fromSelf == null ? 0 : fromSelf.getCount()) < remaining) { - Pair result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current()); + ICraftingTaskError result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current()); - if (result.getRight() != null) { - return Pair.of(null, result.getRight()); + if (result != null) { + return result; } - this.steps.add(result.getLeft()); - fromSelf = results.get(possibleInput, flags); if (fromSelf == null) { throw new IllegalStateException("Recursive calculation didn't yield anything"); @@ -359,6 +258,8 @@ public class CraftingTask implements ICraftingTask { remaining -= toTake; fromNetwork = mutatedFluidStorage.get(input, IComparer.COMPARE_NBT); + + toExtractInitialFluids.add(input); } else { ICraftingPattern subPattern = network.getCraftingManager().getPattern(input); @@ -366,14 +267,12 @@ public class CraftingTask implements ICraftingTask { ICraftingPatternChain subPatternChain = patternChainList.getChain(subPattern); while ((fromSelf == null ? 0 : fromSelf.amount) < remaining) { - Pair result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current()); + ICraftingTaskError result = calculateInternal(mutatedStorage, mutatedFluidStorage, results, fluidResults, patternChainList, subPatternChain.current()); - if (result.getRight() != null) { - return Pair.of(null, result.getRight()); + if (result != null) { + return result; } - this.steps.add(result.getLeft()); - fromSelf = fluidResults.get(input, IComparer.COMPARE_NBT); if (fromSelf == null) { throw new IllegalStateException("Recursive fluid calculation didn't yield anything"); @@ -397,31 +296,307 @@ public class CraftingTask implements ICraftingTask { } } - patternsUsed.remove(pattern); - if (pattern.isProcessing()) { + IStackList itemsToReceive = API.instance().createItemStackList(); + IStackList fluidsToReceive = API.instance().createFluidStackList(); + for (ItemStack output : pattern.getOutputs()) { results.add(output); + + itemsToReceive.add(output); } for (FluidStack output : pattern.getFluidOutputs()) { fluidResults.add(output); + + fluidsToReceive.add(output); } - return Pair.of(new CraftingStepProcess(pattern, network, new ArrayList<>(itemsToExtract.getStacks()), new ArrayList<>(fluidsToExtract.getStacks())), null); + processing.add(new Processing(pattern, itemsToReceive, fluidsToReceive, new ArrayList<>(itemsToExtract.getStacks()), new ArrayList<>(fluidsToExtract.getStacks()))); } else { if (!fluidsToExtract.isEmpty()) { throw new IllegalStateException("Cannot extract fluids in normal pattern!"); } + crafting.add(new Crafting(pattern, took, itemsToExtract)); + results.add(pattern.getOutput(took)); for (ItemStack byproduct : pattern.getByproducts(took)) { results.add(byproduct); } - - return Pair.of(new CraftingStepCraft(pattern, inserter, network, new ArrayList<>(itemsToExtract.getStacks()), took), null); } + + return null; + } + + private static int getTickInterval(int speedUpgrades) { + switch (speedUpgrades) { + case 0: + return 10; + case 1: + return 8; + case 2: + return 6; + case 3: + return 4; + case 4: + return 2; + default: + return 2; + } + } + + private void extractInitial() { + if (!toExtractInitial.isEmpty()) { + List toRemove = new ArrayList<>(); + + for (ItemStack toExtract : toExtractInitial.getStacks()) { + ItemStack result = network.extractItem(toExtract, toExtract.getCount(), getFlags(toExtract), Action.PERFORM); + + if (result != null) { + internalStorage.insert(toExtract, toExtract.getCount(), Action.PERFORM); + + toRemove.add(result); + } + } + + for (ItemStack stack : toRemove) { + toExtractInitial.remove(stack); + } + + if (!toRemove.isEmpty()) { + network.getCraftingManager().onTaskChanged(); + } + } + + if (!toExtractInitialFluids.isEmpty()) { + List toRemove = new ArrayList<>(); + + for (FluidStack toExtract : toExtractInitialFluids.getStacks()) { + FluidStack result = network.extractFluid(toExtract, toExtract.amount, Action.PERFORM); + + if (result != null) { + internalFluidStorage.insert(toExtract, toExtract.amount, Action.PERFORM); + + toRemove.add(result); + } + } + + for (FluidStack stack : toRemove) { + toExtractInitialFluids.remove(stack); + } + + if (!toRemove.isEmpty()) { + network.getCraftingManager().onTaskChanged(); + } + } + } + + private void updateCrafting() { + Iterator it = crafting.iterator(); + + while (it.hasNext()) { + Crafting c = it.next(); + + if (ticks % getTickInterval(c.getPattern().getContainer().getSpeedUpgradeCount()) == 0) { + boolean hasAll = true; + + for (ItemStack need : c.getToExtract().getStacks()) { + ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.SIMULATE); + + if (result == null || result.getCount() != need.getCount()) { + hasAll = false; + + break; + } + } + + if (hasAll) { + for (ItemStack need : c.getToExtract().getStacks()) { + ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.PERFORM); + + if (result == null || result.getCount() != need.getCount()) { + throw new IllegalStateException("Extractor check lied"); + } + } + + ItemStack output = c.getPattern().getOutput(c.getTook()); + this.internalStorage.insert(output, output.getCount(), Action.PERFORM); + + for (ItemStack byp : c.getPattern().getByproducts(c.getTook())) { + this.internalStorage.insert(byp, byp.getCount(), Action.PERFORM); + } + + it.remove(); + + network.getCraftingManager().onTaskChanged(); + + return; + } + } + } + } + + private void updateProcessing() { + Iterator it = processing.iterator(); + + while (it.hasNext()) { + Processing p = it.next(); + + if (p.getState() == ProcessingState.PROCESSED) { + it.remove(); + + network.getCraftingManager().onTaskChanged(); + + continue; + } + + if (p.getState() == ProcessingState.EXTRACTED_ALL) { + continue; + } + + if (ticks % getTickInterval(p.getPattern().getContainer().getSpeedUpgradeCount()) == 0) { + ProcessingState originalState = p.getState(); + + boolean hasAll = true; + + for (ItemStack need : p.getItemsToPut()) { + if (p.getPattern().getContainer().getConnectedInventory() == null) { + p.setState(ProcessingState.MACHINE_NONE); + } else { + ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.SIMULATE); + + if (result == null || result.getCount() != need.getCount()) { + hasAll = false; + + break; + } else if (!ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, true).isEmpty()) { + p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT); + + break; + } else { + p.setState(ProcessingState.READY); + } + } + } + + for (FluidStack need : p.getFluidsToPut()) { + if (p.getPattern().getContainer().getConnectedFluidInventory() == null) { + p.setState(ProcessingState.MACHINE_NONE); + } else { + FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.SIMULATE); + + if (result == null || result.amount != need.amount) { + hasAll = false; + + break; + } else if (p.getPattern().getContainer().getConnectedFluidInventory().fill(result, false) != result.amount) { + p.setState(ProcessingState.MACHINE_DOES_NOT_ACCEPT); + + break; + } else if (p.getState() == ProcessingState.READY) { // If the items were ok. + p.setState(ProcessingState.READY); + } + } + } + + if (p.getState() == ProcessingState.READY && hasAll) { + for (ItemStack need : p.getItemsToPut()) { + ItemStack result = this.internalStorage.extract(need, need.getCount(), getFlags(need), Action.PERFORM); + if (result == null || result.getCount() != need.getCount()) { + throw new IllegalStateException("Could not extract from the internal inventory even though we could"); + } + + if (!ItemHandlerHelper.insertItem(p.getPattern().getContainer().getConnectedInventory(), result, false).isEmpty()) { + throw new IllegalStateException("Can't fill up inventory even though we could"); + } + } + + for (FluidStack need : p.getFluidsToPut()) { + FluidStack result = this.internalFluidStorage.extract(need, need.amount, IComparer.COMPARE_NBT, Action.PERFORM); + if (result == null || result.amount != need.amount) { + throw new IllegalStateException("Could not extract from the internal inventory even though we could"); + } + + if (p.getPattern().getContainer().getConnectedFluidInventory().fill(result, true) != result.amount) { + throw new IllegalStateException("Can't fill up inventory even though we could"); + } + } + + p.setState(ProcessingState.EXTRACTED_ALL); + } + + if (originalState != p.getState()) { + network.getCraftingManager().onTaskChanged(); + } + } + } + } + + @Override + public boolean update() { + if (executionStarted == -1) { + executionStarted = System.currentTimeMillis(); + } + + ++ticks; + + extractInitial(); + + if (this.crafting.isEmpty() && this.processing.isEmpty()) { + List toPerform = new ArrayList<>(); + + for (ItemStack stack : internalStorage.getStacks()) { + ItemStack remainder = network.insertItem(stack, stack.getCount(), Action.PERFORM); + + toPerform.add(() -> { + if (remainder == null) { + internalStorage.extract(stack, stack.getCount(), IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, Action.PERFORM); + } else { + internalStorage.extract(stack, stack.getCount() - remainder.getCount(), IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, Action.PERFORM); + } + }); + } + + for (FluidStack stack : internalFluidStorage.getStacks()) { + FluidStack remainder = network.insertFluid(stack, stack.amount, Action.PERFORM); + + toPerform.add(() -> { + if (remainder == null) { + internalFluidStorage.extract(stack, stack.amount, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, Action.PERFORM); + } else { + internalFluidStorage.extract(stack, stack.amount - remainder.amount, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, Action.PERFORM); + } + }); + } + + // Prevent CME. + toPerform.forEach(Runnable::run); + + return internalStorage.getStacks().isEmpty() && internalFluidStorage.getStacks().isEmpty(); + } else { + updateCrafting(); + updateProcessing(); + + return false; + } + } + + @Override + public void onCancelled() { + for (ItemStack remainder : internalStorage.getStacks()) { + network.insertItem(remainder, remainder.getCount(), Action.PERFORM); + } + + for (FluidStack remainder : internalFluidStorage.getStacks()) { + network.insertFluid(remainder, remainder.amount, Action.PERFORM); + } + } + + @Override + public int getQuantity() { + return quantity; } @Override @@ -449,43 +624,12 @@ public class CraftingTask implements ICraftingTask { return qty; } - @Override - public boolean update() { - if (executionStarted == -1) { - executionStarted = System.currentTimeMillis(); + private static int getFlags(ItemStack stack) { + if (stack.getItem().isDamageable()) { + return IComparer.COMPARE_NBT; } - boolean allCompleted = true; - - if (ticks % getTickInterval(pattern.getContainer().getSpeedUpgradeCount()) == 0) { - inserter.insertOne(); - } - - for (CraftingStep step : steps) { - if (!step.isCompleted()) { - allCompleted = false; - - if (ticks % getTickInterval(step.getPattern().getContainer().getSpeedUpgradeCount()) == 0 && step.canExecute() && step.execute()) { - step.setCompleted(); - - network.getCraftingManager().onTaskChanged(); - } - } - } - - ticks++; - - return allCompleted && inserter.getItems().isEmpty(); - } - - @Override - public void onCancelled() { - inserter.insertAll(); - } - - @Override - public int getQuantity() { - return quantity; + return IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE; } @Override @@ -495,12 +639,32 @@ public class CraftingTask implements ICraftingTask { @Override public int onTrackedInsert(ItemStack stack, int size) { - for (CraftingStep step : steps) { - if (step instanceof CraftingStepProcess) { - size = ((CraftingStepProcess) step).onTrackedItemInserted(stack, size); + for (Processing p : this.processing) { + if (p.getState() != ProcessingState.EXTRACTED_ALL) { + continue; + } + + ItemStack content = p.getItemsToReceive().get(stack); + + if (content != null) { + int needed = content.getCount(); + + if (needed > size) { + needed = size; + } + + p.getItemsToReceive().remove(stack, needed); + + size -= needed; + + if (p.getItemsToReceive().isEmpty() && p.getFluidsToReceive().isEmpty()) { + p.setState(ProcessingState.PROCESSED); + } + + internalStorage.insert(stack, needed, Action.PERFORM); if (size == 0) { - break; + return 0; } } } @@ -510,12 +674,32 @@ public class CraftingTask implements ICraftingTask { @Override public int onTrackedInsert(FluidStack stack, int size) { - for (CraftingStep step : steps) { - if (step instanceof CraftingStepProcess) { - size = ((CraftingStepProcess) step).onTrackedFluidInserted(stack, size); + for (Processing p : this.processing) { + if (p.getState() != ProcessingState.EXTRACTED_ALL) { + continue; + } + + FluidStack content = p.getFluidsToReceive().get(stack); + + if (content != null) { + int needed = content.amount; + + if (needed > size) { + needed = size; + } + + p.getFluidsToReceive().remove(stack, needed); + + size -= needed; + + if (p.getItemsToReceive().isEmpty() && p.getFluidsToReceive().isEmpty()) { + p.setState(ProcessingState.PROCESSED); + } + + internalFluidStorage.insert(stack, needed, Action.PERFORM); if (size == 0) { - break; + return 0; } } } @@ -523,11 +707,16 @@ public class CraftingTask implements ICraftingTask { return size; } + @Override + public NBTTagCompound writeToNbt(NBTTagCompound tag) { + return new NBTTagCompound(); + } + @Override public List getCraftingMonitorElements() { ICraftingMonitorElementList elements = API.instance().createCraftingMonitorElementList(); - if (!missing.isEmpty() || !missingFluids.isEmpty()) { + if (!missing.isEmpty() && !missingFluids.isEmpty()) { elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.missing", 5)); } @@ -547,81 +736,32 @@ public class CraftingTask implements ICraftingTask { elements.commit(); } - if (!inserter.getItems().isEmpty()) { - elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_inserting", 5)); - - for (CraftingInserterItem item : inserter.getItems()) { - ICraftingMonitorElement element = new CraftingMonitorElementItemRender(item.getStack(), item.getStack().getCount(), 0); - - if (item.getStatus() == CraftingInserterItemStatus.FULL) { - element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.network_full", CraftingMonitorElementColor.COLOR_ERROR); - } - - elements.add(element); - } - - elements.commit(); - } - - if (steps.stream().anyMatch(s -> s instanceof CraftingStepCraft && !s.isCompleted() && !((CraftingStepCraft) s).getExtractor().getStacks().isEmpty())) { + if (!this.crafting.isEmpty()) { elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.items_crafting", 5)); - for (CraftingStep step : steps) { - if (step instanceof CraftingStepCraft && !step.isCompleted()) { - CraftingExtractor extractor = ((CraftingStepCraft) step).getExtractor(); - - for (int i = 0; i < extractor.getStacks().size(); ++i) { - // Assume we have an item here. - CraftingExtractorStack stack = extractor.getStacks().get(i); - - ICraftingMonitorElement element = new CraftingMonitorElementItemRender(stack.getItem(), stack.getItem().getCount(), 0); - - if (stack.getStatus() == CraftingExtractorStatus.MISSING) { - element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.waiting_for_items", CraftingMonitorElementColor.COLOR_INFO); - } - - elements.add(element); - } + for (Crafting c : this.crafting) { + for (ItemStack s : c.getToExtract().getStacks()) { + elements.add(new CraftingMonitorElementItemRender(s, s.getCount(), 0)); } } elements.commit(); } - if (steps.stream().anyMatch(s -> s instanceof CraftingStepProcess && !s.isCompleted())) { + if (!this.processing.isEmpty()) { elements.directAdd(new CraftingMonitorElementText("gui.refinedstorage:crafting_monitor.processing", 5)); - for (CraftingStep step : steps) { - if (step instanceof CraftingStepProcess && !step.isCompleted()) { - CraftingExtractor extractor = ((CraftingStepProcess) step).getExtractor(); - - for (int i = 0; i < extractor.getStacks().size(); ++i) { - CraftingExtractorStack stack = extractor.getStacks().get(i); - - if (stack.getItem() == null) { - continue; - } - - elements.add(wrapAccordingToStatus(new CraftingMonitorElementItemRender(stack.getItem(), stack.getItem().getCount(), 0), stack)); - } + for (Processing p : this.processing) { + for (ItemStack s : p.getItemsToReceive().getStacks()) { + elements.add(wrapAccordingToState(new CraftingMonitorElementItemRender(s, s.getCount(), 0), p.getState(), false)); } } elements.commit(); - for (CraftingStep step : steps) { - if (step instanceof CraftingStepProcess && !step.isCompleted()) { - CraftingExtractor extractor = ((CraftingStepProcess) step).getExtractor(); - - for (int i = 0; i < extractor.getStacks().size(); ++i) { - CraftingExtractorStack stack = extractor.getStacks().get(i); - - if (stack.getItem() != null) { - continue; - } - - elements.add(wrapAccordingToStatus(new CraftingMonitorElementFluidRender(stack.getFluid(), stack.getFluid().amount, 0), stack)); - } + for (Processing p : this.processing) { + for (FluidStack s : p.getFluidsToReceive().getStacks()) { + elements.add(wrapAccordingToState(new CraftingMonitorElementFluidRender(s, s.amount, 0), p.getState(), true)); } } @@ -631,15 +771,14 @@ public class CraftingTask implements ICraftingTask { return elements.getElements(); } - private ICraftingMonitorElement wrapAccordingToStatus(ICraftingMonitorElement element, CraftingExtractorStack stack) { - if (stack.getStatus() == CraftingExtractorStatus.MISSING) { - element = new CraftingMonitorElementColor(element, stack.getFluid() != null ? "gui.refinedstorage:crafting_monitor.waiting_for_fluids" : "gui.refinedstorage:crafting_monitor.waiting_for_items", CraftingMonitorElementColor.COLOR_INFO); - } else if (stack.getStatus() == CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT) { - element = new CraftingMonitorElementColor(element, stack.getFluid() != null ? "gui.refinedstorage:crafting_monitor.machine_does_not_accept_fluid" : "gui.refinedstorage:crafting_monitor.machine_does_not_accept_item", CraftingMonitorElementColor.COLOR_ERROR); - } else if (stack.getStatus() == CraftingExtractorStatus.MACHINE_NONE) { - element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.machine_none", CraftingMonitorElementColor.COLOR_ERROR); - } else if (stack.getStatus() == CraftingExtractorStatus.EXTRACTED) { - element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.inserted_into_machine", CraftingMonitorElementColor.COLOR_SUCCESS); + private ICraftingMonitorElement wrapAccordingToState(ICraftingMonitorElement element, ProcessingState state, boolean fluid) { + switch (state) { + case MACHINE_NONE: + element = new CraftingMonitorElementColor(element, "gui.refinedstorage:crafting_monitor.machine_none", CraftingMonitorElementColor.COLOR_ERROR); + break; + case MACHINE_DOES_NOT_ACCEPT: + element = new CraftingMonitorElementColor(element, fluid ? "gui.refinedstorage:crafting_monitor.machine_does_not_accept_fluid" : "gui.refinedstorage:crafting_monitor.machine_does_not_accept_item", CraftingMonitorElementColor.COLOR_ERROR); + break; } return element; @@ -749,11 +888,6 @@ public class CraftingTask implements ICraftingTask { return pattern; } - @Override - public boolean isValid() { - return true; - } - @Override public long getExecutionStarted() { return executionStarted; @@ -768,83 +902,4 @@ public class CraftingTask implements ICraftingTask { public UUID getId() { return id; } - - @Override - public NBTTagCompound writeToNbt(NBTTagCompound tag) { - tag.setTag(NBT_REQUESTED, requested.writeToNbt()); - tag.setInteger(NBT_QUANTITY, quantity); - tag.setTag(NBT_PATTERN, writePatternToNbt(pattern)); - tag.setTag(NBT_INSERTER, inserter.writeToNbt()); - tag.setInteger(NBT_TICKS, ticks); - tag.setUniqueId(NBT_ID, id); - tag.setLong(NBT_EXECUTION_STARTED, executionStarted); - - NBTTagList steps = new NBTTagList(); - for (CraftingStep step : this.steps) { - steps.appendTag(step.writeToNbt()); - } - - tag.setTag(NBT_STEPS, steps); - - NBTTagList missing = new NBTTagList(); - for (ItemStack missingItem : this.missing.getStacks()) { - missing.appendTag(StackUtils.serializeStackToNbt(missingItem)); - } - - tag.setTag(NBT_MISSING, missing); - - return tag; - } - - private int getTickInterval(int speedUpgrades) { - switch (speedUpgrades) { - case 0: - return 10; - case 1: - return 8; - case 2: - return 6; - case 3: - return 4; - case 4: - return 2; - default: - return 2; - } - } - - public static NBTTagCompound writePatternToNbt(ICraftingPattern pattern) { - NBTTagCompound tag = new NBTTagCompound(); - - tag.setTag(NBT_PATTERN_STACK, pattern.getStack().serializeNBT()); - tag.setLong(NBT_PATTERN_CONTAINER_POS, pattern.getContainer().getPosition().toLong()); - - return tag; - } - - public static ICraftingPattern readPatternFromNbt(NBTTagCompound tag, World world) throws CraftingTaskReadException { - BlockPos containerPos = BlockPos.fromLong(tag.getLong(NBT_PATTERN_CONTAINER_POS)); - - INetworkNode node = API.instance().getNetworkNodeManager(world).getNode(containerPos); - - if (node instanceof ICraftingPatternContainer) { - ItemStack stack = new ItemStack(tag.getCompoundTag(NBT_PATTERN_STACK)); - - if (stack.getItem() instanceof ICraftingPatternProvider) { - return ((ICraftingPatternProvider) stack.getItem()).create(world, stack, (ICraftingPatternContainer) node); - } else { - throw new CraftingTaskReadException("Pattern stack is not a crafting pattern provider"); - } - } else { - throw new CraftingTaskReadException("Crafting pattern container doesn't exist anymore"); - } - } - - public static int getFlags(ItemStack stack) { - if (stack.getItem().isDamageable()) { - return IComparer.COMPARE_NBT; - } - - return IComparer.COMPARE_NBT | IComparer.COMPARE_DAMAGE; - } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/Processing.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/Processing.java new file mode 100644 index 000000000..d0429fbfa --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/Processing.java @@ -0,0 +1,53 @@ +package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; + +import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; +import com.raoulvdberge.refinedstorage.api.util.IStackList; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import java.util.List; + +class Processing { + private ICraftingPattern pattern; + private IStackList itemsToReceive; + private IStackList fluidsToReceive; + private List itemsToPut; + private List fluidsToPut; + private ProcessingState state = ProcessingState.READY; + + public Processing(ICraftingPattern pattern, IStackList itemsToReceive, IStackList fluidsToReceive, List itemsToPut, List fluidsToPut) { + this.pattern = pattern; + this.itemsToReceive = itemsToReceive; + this.fluidsToReceive = fluidsToReceive; + this.itemsToPut = itemsToPut; + this.fluidsToPut = fluidsToPut; + } + + public ICraftingPattern getPattern() { + return pattern; + } + + public IStackList getItemsToReceive() { + return itemsToReceive; + } + + public IStackList getFluidsToReceive() { + return fluidsToReceive; + } + + public List getItemsToPut() { + return itemsToPut; + } + + public List getFluidsToPut() { + return fluidsToPut; + } + + public void setState(ProcessingState state) { + this.state = state; + } + + public ProcessingState getState() { + return state; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/ProcessingState.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/ProcessingState.java new file mode 100644 index 000000000..023938a42 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/ProcessingState.java @@ -0,0 +1,9 @@ +package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; + +enum ProcessingState { + READY, + EXTRACTED_ALL, + MACHINE_NONE, + MACHINE_DOES_NOT_ACCEPT, + PROCESSED +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractor.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractor.java deleted file mode 100644 index 0423aa205..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractor.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor; - -import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException; -import com.raoulvdberge.refinedstorage.api.network.INetwork; -import com.raoulvdberge.refinedstorage.api.util.Action; -import com.raoulvdberge.refinedstorage.api.util.IComparer; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagList; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.ItemHandlerHelper; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; - -public class CraftingExtractor { - private INetwork network; - private List stacks; - private boolean processing; - - public CraftingExtractor(INetwork network, List stacks, boolean processing) { - this.network = network; - this.stacks = stacks; - this.processing = processing; - } - - public CraftingExtractor(INetwork network, NBTTagList tag, boolean processing) throws CraftingTaskReadException { - this.network = network; - this.processing = processing; - - this.stacks = new ArrayList<>(); - - for (int i = 0; i < tag.tagCount(); ++i) { - this.stacks.add(new CraftingExtractorStack(tag.getCompoundTagAt(i))); - } - } - - public List getStacks() { - return stacks; - } - - public void updateStatus(@Nullable IItemHandler processingInventory, @Nullable IFluidHandler processingFluidInventory) { - boolean updated = false; - - for (CraftingExtractorStack stack : stacks) { - if (stack.getStatus() != CraftingExtractorStatus.EXTRACTED) { - CraftingExtractorStatus previousStatus = stack.getStatus(); - - if (stack.getItem() != null) { - ItemStack item = stack.getItem(); - - ItemStack inNetwork = network.extractItem(item, item.getCount(), CraftingTask.getFlags(item), Action.SIMULATE); - - if (inNetwork == null || inNetwork.getCount() < item.getCount()) { - stack.setStatus(CraftingExtractorStatus.MISSING); - } else { - stack.setStatus(CraftingExtractorStatus.AVAILABLE); - - if (processing) { - if (processingInventory == null) { - stack.setStatus(CraftingExtractorStatus.MACHINE_NONE); - } else if (!ItemHandlerHelper.insertItem(processingInventory, item, true).isEmpty()) { - stack.setStatus(CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT); - } - } - } - } else { - FluidStack fluid = stack.getFluid(); - - FluidStack inNetwork = network.extractFluid(fluid, fluid.amount, IComparer.COMPARE_NBT, Action.SIMULATE); - - if (inNetwork == null || inNetwork.amount < fluid.amount) { - stack.setStatus(CraftingExtractorStatus.MISSING); - } else { - stack.setStatus(CraftingExtractorStatus.AVAILABLE); - - if (processingFluidInventory == null) { - stack.setStatus(CraftingExtractorStatus.MACHINE_NONE); - } else if (processingFluidInventory.fill(fluid, false) != fluid.amount) { - stack.setStatus(CraftingExtractorStatus.MACHINE_DOES_NOT_ACCEPT); - } - } - } - - if (previousStatus != stack.getStatus()) { - updated = true; - } - } - } - - if (updated) { - network.getCraftingManager().onTaskChanged(); - } - } - - public boolean isAllAvailable() { - return !stacks.isEmpty() && stacks.stream().allMatch(s -> s.getStatus() == CraftingExtractorStatus.AVAILABLE || s.getStatus() == CraftingExtractorStatus.EXTRACTED); - } - - public boolean isAllExtracted() { - return !stacks.isEmpty() && stacks.stream().allMatch(s -> s.getStatus() == CraftingExtractorStatus.EXTRACTED); - } - - public void extractOne(@Nullable IItemHandler processingInventory, @Nullable IFluidHandler processingFluidInventory) { - boolean changed = false; - - for (CraftingExtractorStack stack : stacks) { - if (stack.getStatus() == CraftingExtractorStatus.AVAILABLE) { - if (stack.getItem() != null) { - ItemStack item = stack.getItem(); - - ItemStack extracted = network.extractItem(item, item.getCount(), CraftingTask.getFlags(item), Action.PERFORM); - if (extracted == null) { - throw new IllegalStateException("Did not extract anything while available"); - } - - if (processing) { - if (processingInventory == null) { - throw new IllegalStateException("Processing inventory is null"); - } - - ItemStack remainder = ItemHandlerHelper.insertItem(processingInventory, extracted, false); - if (!remainder.isEmpty()) { - throw new IllegalStateException("The processing inventory gave back a remainder while it previously stated it could handle all"); - } - } - - stack.setStatus(CraftingExtractorStatus.EXTRACTED); - - changed = true; - } else { - FluidStack fluid = stack.getFluid(); - - FluidStack extracted = network.extractFluid(fluid, fluid.amount, IComparer.COMPARE_NBT, Action.PERFORM); - if (extracted == null) { - throw new IllegalStateException("Did not extract any fluids while available"); - } - - if (processingFluidInventory == null) { - throw new IllegalStateException("Processing fluid inventory is null"); - } - - int filled = processingFluidInventory.fill(fluid, true); - if (filled != fluid.amount) { - throw new IllegalStateException("The processing fluid inventory gave back a remainder while it previously stated it could handle all"); - } - - stack.setStatus(CraftingExtractorStatus.EXTRACTED); - - changed = true; - } - - // For processing patterns we want to insert all items at once to avoid conflicts with other crafting steps. - if (!processing) { - return; - } else { - updateStatus(processingInventory, processingFluidInventory); - } - } - } - - if (changed) { - network.getCraftingManager().onTaskChanged(); - } - } - - public NBTTagList writeToNbt() { - NBTTagList list = new NBTTagList(); - - for (CraftingExtractorStack stack : stacks) { - list.appendTag(stack.writeToNbt()); - } - - return list; - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractorStack.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractorStack.java deleted file mode 100644 index 75b7d0140..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractorStack.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor; - -import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException; -import com.raoulvdberge.refinedstorage.util.StackUtils; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.FluidStack; - -import javax.annotation.Nullable; - -public class CraftingExtractorStack { - private static final String NBT_FLUID = "Fluid"; - private static final String NBT_STACK = "Stack"; - private static final String NBT_STATUS = "Status"; - - private ItemStack item; - private FluidStack fluid; - private CraftingExtractorStatus status = CraftingExtractorStatus.MISSING; - - public CraftingExtractorStack(ItemStack item) { - this.item = item; - } - - public CraftingExtractorStack(FluidStack fluid) { - this.fluid = fluid; - } - - public CraftingExtractorStack(NBTTagCompound tag) throws CraftingTaskReadException { - if (!tag.getBoolean(NBT_FLUID)) { - item = StackUtils.deserializeStackFromNbt(tag.getCompoundTag(NBT_STACK)); - - if (item.isEmpty()) { - throw new CraftingTaskReadException("Extractor stack is empty"); - } - } else { - fluid = FluidStack.loadFluidStackFromNBT(tag.getCompoundTag(NBT_STACK)); - - if (fluid == null) { - throw new CraftingTaskReadException("Extractor fluid stack is empty"); - } - } - - status = CraftingExtractorStatus.values()[tag.getInteger(NBT_STATUS)]; - } - - @Nullable - public ItemStack getItem() { - return item; - } - - @Nullable - public FluidStack getFluid() { - return fluid; - } - - public NBTTagCompound writeToNbt() { - NBTTagCompound tag = new NBTTagCompound(); - - tag.setBoolean(NBT_FLUID, fluid != null); - - if (fluid != null) { - tag.setTag(NBT_STACK, fluid.writeToNBT(new NBTTagCompound())); - } else { - tag.setTag(NBT_STACK, StackUtils.serializeStackToNbt(item)); - } - - tag.setInteger(NBT_STATUS, status.ordinal()); - - return tag; - } - - public CraftingExtractorStatus getStatus() { - return status; - } - - public void setStatus(CraftingExtractorStatus status) { - this.status = status; - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractorStatus.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractorStatus.java deleted file mode 100644 index 7843d7963..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/extractor/CraftingExtractorStatus.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor; - -public enum CraftingExtractorStatus { - AVAILABLE, - MISSING, - EXTRACTED, - MACHINE_NONE, - MACHINE_DOES_NOT_ACCEPT -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserter.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserter.java deleted file mode 100644 index 1947a80fe..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserter.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter; - -import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException; -import com.raoulvdberge.refinedstorage.api.network.INetwork; -import com.raoulvdberge.refinedstorage.api.util.Action; -import com.raoulvdberge.refinedstorage.util.StackUtils; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; - -import java.util.ArrayDeque; -import java.util.Collection; -import java.util.Deque; - -public class CraftingInserter { - private static final String NBT_ITEM = "Item"; - private static final String NBT_STATUS = "Status"; - - private INetwork network; - private Deque items = new ArrayDeque<>(); - - public CraftingInserter(INetwork network) { - this.network = network; - } - - public CraftingInserter(INetwork network, NBTTagList list) throws CraftingTaskReadException { - this(network); - - for (int i = 0; i < list.tagCount(); ++i) { - NBTTagCompound itemTag = list.getCompoundTagAt(i); - - ItemStack stack = StackUtils.deserializeStackFromNbt(itemTag.getCompoundTag(NBT_ITEM)); - - if (stack.isEmpty()) { - throw new CraftingTaskReadException("Inserter has empty stack"); - } - - CraftingInserterItemStatus status = CraftingInserterItemStatus.values()[itemTag.getInteger(NBT_STATUS)]; - - items.push(new CraftingInserterItem(stack, status)); - } - } - - public void insert(ItemStack stack) { - items.addLast(new CraftingInserterItem(stack, CraftingInserterItemStatus.WAITING)); - - network.getCraftingManager().onTaskChanged(); - } - - public void insertOne() { - CraftingInserterItem item = items.peekFirst(); - - if (item != null) { - CraftingInserterItemStatus currentStatus = item.getStatus(); - - if (network.insertItem(item.getStack(), item.getStack().getCount(), Action.SIMULATE) == null) { - ItemStack inserted = network.insertItem(item.getStack(), item.getStack().getCount(), Action.PERFORM); - if (inserted != null) { - throw new IllegalStateException("Could not insert item"); - } - - items.pop(); - - network.getCraftingManager().onTaskChanged(); - } else if (currentStatus != CraftingInserterItemStatus.FULL) { - item.setStatus(CraftingInserterItemStatus.FULL); - - network.getCraftingManager().onTaskChanged(); - } - } - } - - public void insertAll() { - while (!items.isEmpty()) { - CraftingInserterItem item = items.pop(); - - network.insertItem(item.getStack(), item.getStack().getCount(), Action.PERFORM); - } - - network.getCraftingManager().onTaskChanged(); - } - - public Collection getItems() { - return items; - } - - public NBTTagList writeToNbt() { - NBTTagList list = new NBTTagList(); - - for (CraftingInserterItem item : items) { - NBTTagCompound tag = new NBTTagCompound(); - - tag.setTag(NBT_ITEM, StackUtils.serializeStackToNbt(item.getStack())); - tag.setInteger(NBT_STATUS, item.getStatus().ordinal()); - - list.appendTag(tag); - } - - return list; - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserterItem.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserterItem.java deleted file mode 100644 index 86cd22cfd..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserterItem.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter; - -import net.minecraft.item.ItemStack; - -public class CraftingInserterItem { - private ItemStack stack; - private CraftingInserterItemStatus status; - - public CraftingInserterItem(ItemStack stack, CraftingInserterItemStatus status) { - this.stack = stack; - this.status = status; - } - - public ItemStack getStack() { - return stack; - } - - public CraftingInserterItemStatus getStatus() { - return status; - } - - public void setStatus(CraftingInserterItemStatus status) { - this.status = status; - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserterItemStatus.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserterItemStatus.java deleted file mode 100644 index 2b28ba43b..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/inserter/CraftingInserterItemStatus.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter; - -public enum CraftingInserterItemStatus { - WAITING, - FULL -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStep.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStep.java deleted file mode 100644 index ab2c4c907..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStep.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step; - -import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; -import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException; -import com.raoulvdberge.refinedstorage.api.network.INetwork; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.CraftingTask; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserter; -import net.minecraft.nbt.NBTTagCompound; - -public abstract class CraftingStep { - private static final String NBT_PATTERN = "Pattern"; - private static final String NBT_COMPLETED = "Completed"; - private static final String NBT_TYPE = "Type"; - - protected ICraftingPattern pattern; - private boolean completed; - - public CraftingStep(ICraftingPattern pattern) { - this.pattern = pattern; - } - - public abstract boolean canExecute(); - - public abstract boolean execute(); - - public ICraftingPattern getPattern() { - return pattern; - } - - public boolean isCompleted() { - return completed; - } - - public void setCompleted() { - this.completed = true; - } - - public abstract String getType(); - - public NBTTagCompound writeToNbt() { - NBTTagCompound tag = new NBTTagCompound(); - - tag.setTag(NBT_PATTERN, CraftingTask.writePatternToNbt(pattern)); - tag.setBoolean(NBT_COMPLETED, completed); - tag.setString(NBT_TYPE, getType()); - - return tag; - } - - public static CraftingStep readFromNbt(INetwork network, CraftingInserter inserter, NBTTagCompound tag) throws CraftingTaskReadException { - ICraftingPattern pattern = CraftingTask.readPatternFromNbt(tag.getCompoundTag(NBT_PATTERN), network.world()); - boolean completed = tag.getBoolean(NBT_COMPLETED); - String type = tag.getString(NBT_TYPE); - - CraftingStep step; - - switch (type) { - case CraftingStepCraft.TYPE: - step = new CraftingStepCraft(pattern, inserter, network, tag); - break; - case CraftingStepProcess.TYPE: - step = new CraftingStepProcess(pattern, network, tag); - break; - default: - throw new CraftingTaskReadException("Unknown crafting step type"); - } - - if (completed) { - step.setCompleted(); - } - - return step; - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStepCraft.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStepCraft.java deleted file mode 100644 index e58d8104a..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStepCraft.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step; - -import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; -import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException; -import com.raoulvdberge.refinedstorage.api.network.INetwork; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.inserter.CraftingInserter; -import com.raoulvdberge.refinedstorage.util.StackUtils; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.NonNullList; -import net.minecraftforge.common.util.Constants; - -import java.util.List; -import java.util.stream.Collectors; - -public class CraftingStepCraft extends CraftingStep { - public static final String TYPE = "craft"; - - private static final String NBT_EXTRACTOR = "Extractor"; - private static final String NBT_TOOK = "Took"; - - private CraftingInserter inserter; - private CraftingExtractor extractor; - - private NonNullList took; - - public CraftingStepCraft(ICraftingPattern pattern, CraftingInserter inserter, INetwork network, List toExtract, NonNullList took) { - super(pattern); - - if (pattern.isProcessing()) { - throw new IllegalArgumentException("Cannot pass processing pattern to craft handler"); - } - - this.inserter = inserter; - this.extractor = new CraftingExtractor(network, toExtract.stream().map(CraftingExtractorStack::new).collect(Collectors.toList()), false); - this.took = took; - } - - public CraftingStepCraft(ICraftingPattern pattern, CraftingInserter inserter, INetwork network, NBTTagCompound tag) throws CraftingTaskReadException { - super(pattern); - - if (pattern.isProcessing()) { - throw new IllegalArgumentException("Cannot pass processing pattern to craft handler"); - } - - this.inserter = inserter; - this.extractor = new CraftingExtractor(network, tag.getTagList(NBT_EXTRACTOR, Constants.NBT.TAG_COMPOUND), false); - - this.took = NonNullList.create(); - - NBTTagList tookList = tag.getTagList(NBT_TOOK, Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < tookList.tagCount(); ++i) { - took.add(StackUtils.deserializeStackFromNbt(tookList.getCompoundTagAt(i))); // Took stack can be empty - } - } - - @Override - public boolean canExecute() { - extractor.updateStatus(null, null); - - return extractor.isAllAvailable(); - } - - @Override - public boolean execute() { - extractor.extractOne(null, null); - - boolean allExtracted = extractor.isAllExtracted(); - - if (allExtracted) { - inserter.insert(pattern.getOutput(took)); - - for (ItemStack byproduct : pattern.getByproducts(took)) { - inserter.insert(byproduct); - } - } - - return allExtracted; - } - - @Override - public String getType() { - return TYPE; - } - - @Override - public NBTTagCompound writeToNbt() { - NBTTagCompound tag = super.writeToNbt(); - - tag.setTag(NBT_EXTRACTOR, extractor.writeToNbt()); - - NBTTagList took = new NBTTagList(); - - for (ItemStack stack : this.took) { - took.appendTag(StackUtils.serializeStackToNbt(stack)); - } - - tag.setTag(NBT_TOOK, took); - - return tag; - } - - public CraftingExtractor getExtractor() { - return extractor; - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStepProcess.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStepProcess.java deleted file mode 100644 index afbe3e09b..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/step/CraftingStepProcess.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.step; - -import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; -import com.raoulvdberge.refinedstorage.api.autocrafting.task.CraftingTaskReadException; -import com.raoulvdberge.refinedstorage.api.network.INetwork; -import com.raoulvdberge.refinedstorage.api.util.IStackList; -import com.raoulvdberge.refinedstorage.apiimpl.API; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractor; -import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task.extractor.CraftingExtractorStack; -import com.raoulvdberge.refinedstorage.util.StackUtils; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraftforge.common.util.Constants; -import net.minecraftforge.fluids.FluidStack; - -import java.util.ArrayList; -import java.util.List; - -public class CraftingStepProcess extends CraftingStep { - public static final String TYPE = "process"; - - private static final String NBT_EXTRACTOR = "Extractor"; - private static final String NBT_TO_RECEIVE = "ToReceive"; - private static final String NBT_TO_RECEIVE_FLUIDS = "ToReceiveFluids"; - - private CraftingExtractor extractor; - - private IStackList itemsToReceive = API.instance().createItemStackList(); - private IStackList fluidsToReceive = API.instance().createFluidStackList(); - - public CraftingStepProcess(ICraftingPattern pattern, INetwork network, List toExtract, List fluidsToExtract) { - super(pattern); - - if (!pattern.isProcessing()) { - throw new IllegalArgumentException("Cannot pass non-processing pattern to processing handler"); - } - - List stacks = new ArrayList<>(); - - for (ItemStack item : toExtract) { - stacks.add(new CraftingExtractorStack(item)); - } - - for (FluidStack fluid : fluidsToExtract) { - stacks.add(new CraftingExtractorStack(fluid)); - } - - this.extractor = new CraftingExtractor(network, stacks, true); - - for (ItemStack output : pattern.getOutputs()) { - this.itemsToReceive.add(output); - } - - for (FluidStack output : pattern.getFluidOutputs()) { - this.fluidsToReceive.add(output); - } - } - - public CraftingStepProcess(ICraftingPattern pattern, INetwork network, NBTTagCompound tag) throws CraftingTaskReadException { - super(pattern); - - if (!pattern.isProcessing()) { - throw new IllegalArgumentException("Cannot pass non-processing pattern to processing handler"); - } - - this.extractor = new CraftingExtractor(network, tag.getTagList(NBT_EXTRACTOR, Constants.NBT.TAG_COMPOUND), true); - - NBTTagList toReceiveList = tag.getTagList(NBT_TO_RECEIVE, Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < toReceiveList.tagCount(); ++i) { - ItemStack toReceive = StackUtils.deserializeStackFromNbt(toReceiveList.getCompoundTagAt(i)); - - if (toReceive.isEmpty()) { - throw new CraftingTaskReadException("Item to receive is empty"); - } - - this.itemsToReceive.add(toReceive); - } - - NBTTagList toReceiveFluidsList = tag.getTagList(NBT_TO_RECEIVE_FLUIDS, Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < toReceiveFluidsList.tagCount(); ++i) { - FluidStack toReceive = FluidStack.loadFluidStackFromNBT(toReceiveFluidsList.getCompoundTagAt(i)); - - if (toReceive == null) { - throw new CraftingTaskReadException("Fluid to receive is null"); - } - - this.fluidsToReceive.add(toReceive); - } - } - - @Override - public boolean canExecute() { - extractor.updateStatus(pattern.getContainer().getConnectedInventory(), pattern.getContainer().getConnectedFluidInventory()); - - return extractor.isAllAvailable(); - } - - public int onTrackedItemInserted(ItemStack stack, int size) { - if (!extractor.isAllExtracted()) { - return size; - } - - ItemStack inList = itemsToReceive.get(stack); - if (inList == null) { - return size; - } - - int toExtract = Math.min(size, inList.getCount()); - - itemsToReceive.remove(stack, toExtract); - - return size - toExtract; - } - - public int onTrackedFluidInserted(FluidStack stack, int size) { - if (!extractor.isAllExtracted()) { - return size; - } - - FluidStack inList = fluidsToReceive.get(stack); - if (inList == null) { - return size; - } - - int toExtract = Math.min(size, inList.amount); - - fluidsToReceive.remove(stack, toExtract); - - return size - toExtract; - } - - @Override - public boolean execute() { - if (!extractor.isAllExtracted()) { - extractor.extractOne(pattern.getContainer().getConnectedInventory(), pattern.getContainer().getConnectedFluidInventory()); - } - - return extractor.isAllExtracted() && itemsToReceive.isEmpty() && fluidsToReceive.isEmpty(); - } - - @Override - public String getType() { - return TYPE; - } - - @Override - public NBTTagCompound writeToNbt() { - NBTTagCompound tag = super.writeToNbt(); - - tag.setTag(NBT_EXTRACTOR, extractor.writeToNbt()); - - NBTTagList toReceive = new NBTTagList(); - - for (ItemStack toReceiveStack : itemsToReceive.getStacks()) { - toReceive.appendTag(StackUtils.serializeStackToNbt(toReceiveStack)); - } - - tag.setTag(NBT_TO_RECEIVE, toReceive); - - NBTTagList toReceiveFluids = new NBTTagList(); - - for (FluidStack toReceiveStack : fluidsToReceive.getStacks()) { - toReceiveFluids.appendTag(toReceiveStack.writeToNBT(new NBTTagCompound())); - } - - tag.setTag(NBT_TO_RECEIVE_FLUIDS, toReceiveFluids); - - return tag; - } - - public CraftingExtractor getExtractor() { - return extractor; - } -}