diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStep.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStep.java index 320d63bda..aa27be50a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStep.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStep.java @@ -1,21 +1,22 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; +import com.raoulvdberge.refinedstorage.RSUtils; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternContainer; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPatternProvider; import com.raoulvdberge.refinedstorage.api.autocrafting.task.ICraftingStep; import com.raoulvdberge.refinedstorage.api.network.INetworkMaster; import com.raoulvdberge.refinedstorage.api.util.IComparer; +import com.raoulvdberge.refinedstorage.api.util.IFluidStackList; +import com.raoulvdberge.refinedstorage.api.util.IItemStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fluids.FluidStack; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; public abstract class CraftingStep implements ICraftingStep { @@ -156,4 +157,58 @@ public abstract class CraftingStep implements ICraftingStep { return tag; } + + protected enum AvailableType { ITEM, FLUID } + + protected AvailableType isItemAvailable(IItemStackList items, IFluidStackList fluids, ItemStack stack, ItemStack actualStack, int compare) { + if (actualStack == null || actualStack.stackSize == 0 || !items.trackedRemove(actualStack, stack.stackSize, true)) { + FluidStack fluidInItem = RSUtils.getFluidFromStack(stack, true); + + if (fluidInItem != null && RSUtils.hasFluidBucket(fluidInItem)) { + FluidStack fluidStack = fluids.get(fluidInItem, compare); + ItemStack bucket = items.get(RSUtils.EMPTY_BUCKET, compare); + if (bucket != null && fluidStack != null && fluids.trackedRemove(fluidStack, fluidInItem.amount, true) && items.trackedRemove(bucket, 1, true)) { + return AvailableType.FLUID; + } + } + return null; + } + return AvailableType.ITEM; + } + + protected boolean extractItems(IItemStackList actualInputs, int compare, Deque toInsertItems) { + for (ItemStack insertStack : getToInsert()) { + // This will be a tool, like a hammer + if (insertStack.isItemStackDamageable()) { + compare &= ~IComparer.COMPARE_DAMAGE; + } else { + compare |= IComparer.COMPARE_DAMAGE; + } + + ItemStack input = network.extractItem(insertStack, insertStack.stackSize, compare, false); + if (input != null) { + actualInputs.add(input); + } else { + boolean abort = true; + FluidStack fluidInItem = RSUtils.getFluidFromStack(insertStack, true); + if (fluidInItem != null) { + FluidStack fluidStack = network.extractFluid(fluidInItem, fluidInItem.amount, compare, false); + ItemStack bucketStack = network.extractItem(RSUtils.EMPTY_BUCKET, 1, compare, false); + if (fluidStack != null && fluidStack.amount == fluidInItem.amount && bucketStack != null) { + abort = false; + actualInputs.add(insertStack.copy()); + } + } + + if (abort){ + // Abort task re-insert taken stacks and reset state + toInsertItems.addAll(actualInputs.getStacks()); + startedProcessing = false; + return false; + } + } + } + + return true; + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStepCraft.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStepCraft.java index 433dd9412..480bea119 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStepCraft.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStepCraft.java @@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.api.util.IFluidStackList; import com.raoulvdberge.refinedstorage.api.util.IItemStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.apiimpl.util.ItemStackList; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; @@ -50,17 +51,7 @@ public class CraftingStepCraft extends CraftingStep { } ItemStack actualStack = items.get(stack, compare); - - if (actualStack == null || actualStack.stackSize == 0 || !items.trackedRemove(actualStack, stack.stackSize, true)) { - FluidStack fluidInItem = RSUtils.getFluidFromStack(stack, true); - - if (fluidInItem != null && RSUtils.hasFluidBucket(fluidInItem)) { - FluidStack fluidStack = fluids.get(fluidInItem, compare); - ItemStack bucket = items.get(RSUtils.EMPTY_BUCKET, compare); - if (bucket != null && fluidStack != null && fluids.trackedRemove(fluidStack, fluidInItem.amount, true) && items.trackedRemove(bucket, 1, true)) { - continue; - } - } + if (isItemAvailable(items, fluids, stack, actualStack, compare) == null) { items.undo(); fluids.undo(); return false; @@ -75,58 +66,20 @@ public class CraftingStepCraft extends CraftingStep { public void execute(Deque toInsertItems, Deque toInsertFluids) { IItemStackList actualInputs = API.instance().createItemStackList(); int compare = CraftingTask.DEFAULT_COMPARE | (getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0); - for (ItemStack insertStack : getToInsert()) { - // This will be a tool, like a hammer - if (insertStack.isItemStackDamageable()) { - compare &= ~IComparer.COMPARE_DAMAGE; - } else { - compare |= IComparer.COMPARE_DAMAGE; - } + if (extractItems(actualInputs, compare, toInsertItems)) { - FluidStack fluidInItem = RSUtils.getFluidFromStack(insertStack, true); - if (fluidInItem != null) { - network.extractFluid(fluidInItem, fluidInItem.amount, compare, false); - network.extractItem(RSUtils.EMPTY_BUCKET, 1, compare, false); - actualInputs.add(insertStack.copy()); - } else { - ItemStack input = network.extractItem(insertStack, insertStack.stackSize, compare, false); - if (input != null) { - actualInputs.add(input); - } else { - // Abort task re-insert taken stacks and reset state - toInsertItems.addAll(actualInputs.getStacks()); - startedProcessing = false; - return; + ItemStack[] took = ItemStackList.toCraftingGrid(actualInputs, toInsert, compare); + + for (ItemStack byproduct : (pattern.isOredict() ? pattern.getByproducts(took) : pattern.getByproducts())) { + if (byproduct != null) { + toInsertItems.add(byproduct.copy()); } } - } - ItemStack[] took = new ItemStack[9]; - for (int i = 0; i < toInsert.size(); i++) { - ItemStack input = toInsert.get(i); - if (input != null) { - // This will be a tool, like a hammer - if (input.isItemStackDamageable()) { - compare &= ~IComparer.COMPARE_DAMAGE; - } else { - compare |= IComparer.COMPARE_DAMAGE; + for (ItemStack output : (pattern.isOredict() ? pattern.getOutputs(took) : pattern.getOutputs())) { + if (output != null) { + toInsertItems.add(output.copy()); } - ItemStack actualInput = actualInputs.get(input, compare); - ItemStack taken = ItemHandlerHelper.copyStackWithSize(actualInput, input.stackSize); - took[i] = taken; - actualInputs.remove(taken, true); - } - } - - for (ItemStack byproduct : (pattern.isOredict() ? pattern.getByproducts(took) : pattern.getByproducts())) { - if (byproduct != null) { - toInsertItems.add(byproduct.copy()); - } - } - - for (ItemStack output : (pattern.isOredict() ? pattern.getOutputs(took) : pattern.getOutputs())) { - if (output != null) { - toInsertItems.add(output.copy()); } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStepProcess.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStepProcess.java index 5bdcc402f..b6dee0775 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStepProcess.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/task/CraftingStepProcess.java @@ -1,16 +1,19 @@ package com.raoulvdberge.refinedstorage.apiimpl.autocrafting.task; +import com.raoulvdberge.refinedstorage.RSUtils; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.network.INetworkMaster; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.api.util.IFluidStackList; import com.raoulvdberge.refinedstorage.api.util.IItemStackList; +import com.raoulvdberge.refinedstorage.apiimpl.API; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; +import java.util.ArrayDeque; import java.util.Deque; import java.util.LinkedList; import java.util.List; @@ -31,18 +34,33 @@ public class CraftingStepProcess extends CraftingStep { @Override public boolean canStartProcessing(IItemStackList items, IFluidStackList fluids) { IItemHandler inventory = getPattern().getContainer().getFacingInventory(); + int compare = CraftingTask.DEFAULT_COMPARE | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0); if (inventory != null) { Deque toInsert = new LinkedList<>(); for (ItemStack stack : getToInsert()) { - ItemStack actualStack = items.get(stack, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT | (pattern.isOredict() ? IComparer.COMPARE_OREDICT : 0)); - ItemStack removeStack = ItemHandlerHelper.copyStackWithSize(actualStack, stack.stackSize); - if (actualStack == null || actualStack.stackSize == 0 || !items.trackedRemove(removeStack, true)) { + // This will be a tool, like a hammer + if (stack.isItemStackDamageable()) { + compare &= ~IComparer.COMPARE_DAMAGE; + } else { + compare |= IComparer.COMPARE_DAMAGE; + } + + ItemStack actualStack = items.get(stack, compare); + AvailableType type = isItemAvailable(items, fluids, stack, actualStack, compare); + + if (type == AvailableType.ITEM) { + toInsert.add(ItemHandlerHelper.copyStackWithSize(actualStack, stack.stackSize)); + } else if (type == AvailableType.FLUID) { + toInsert.add(ItemHandlerHelper.copyStackWithSize(stack, stack.stackSize)); + } else { items.undo(); + fluids.undo(); return false; } - toInsert.add(removeStack.copy()); } + items.undo(); + fluids.undo(); return insertSimulation(inventory, toInsert); } return false; @@ -56,11 +74,13 @@ public class CraftingStepProcess extends CraftingStep { @Override public void execute(Deque toInsertItems, Deque toInsertFluids) { - IItemHandler inventory = getPattern().getContainer().getFacingInventory(); + IItemStackList actualInputs = API.instance().createItemStackList(); int compare = CraftingTask.DEFAULT_COMPARE | (getPattern().isOredict() ? IComparer.COMPARE_OREDICT : 0); - for (ItemStack insertStack : getToInsert()) { - ItemStack tookStack = network.extractItem(insertStack, insertStack.stackSize, compare, false); - ItemHandlerHelper.insertItem(inventory, tookStack, false); + if (extractItems(actualInputs, compare, toInsertItems)) { + IItemHandler inventory = getPattern().getContainer().getFacingInventory(); + if (insertSimulation(inventory, new ArrayDeque<>(actualInputs.getStacks()))) { + actualInputs.getStacks().forEach(stack -> ItemHandlerHelper.insertItem(inventory, stack, false)); + } } } 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 357f60d6a..7e755a82d 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 @@ -16,6 +16,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.craftingmonitor.*; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementFluidStack; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.preview.CraftingPreviewElementItemStack; +import com.raoulvdberge.refinedstorage.apiimpl.util.ItemStackList; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; @@ -216,24 +217,10 @@ public class CraftingTask implements ICraftingTask { steps.add(new CraftingStepCraft(network, pattern, usedStacks)); } - ItemStack[] took = new ItemStack[9]; + ItemStack[] took = null; if (missing.isEmpty()) { if (!pattern.isProcessing()) { - for (int i = 0; i < usedStacks.size(); i++) { - ItemStack input = usedStacks.get(i); - if (input != null) { - // This will be a tool, like a hammer - if (input.isItemStackDamageable()) { - compare &= ~IComparer.COMPARE_DAMAGE; - } else { - compare |= IComparer.COMPARE_DAMAGE; - } - ItemStack actualInput = actualInputs.get(input, compare); - ItemStack taken = ItemHandlerHelper.copyStackWithSize(actualInput, input.stackSize); - took[i] = taken; - actualInputs.remove(taken, true); - } - } + took = ItemStackList.toCraftingGrid(actualInputs, usedStacks, compare); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/ItemStackList.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/ItemStackList.java index d93d4e67d..ae859ef6c 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/ItemStackList.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/util/ItemStackList.java @@ -157,4 +157,25 @@ public class ItemStackList implements IItemStackList { public String toString() { return stacks.toString(); } + + + public static ItemStack[] toCraftingGrid(IItemStackList list, List grid, int compare) { + ItemStack[] took = new ItemStack[9]; + for (int i = 0; i < grid.size(); i++) { + ItemStack input = grid.get(i); + if (input != null) { + // This will be a tool, like a hammer + if (input.isItemStackDamageable()) { + compare &= ~IComparer.COMPARE_DAMAGE; + } else { + compare |= IComparer.COMPARE_DAMAGE; + } + ItemStack actualInput = list.get(input, compare); + ItemStack taken = ItemHandlerHelper.copyStackWithSize(actualInput, input.stackSize); + took[i] = taken; + list.remove(taken, true); + } + } + return took; + } }