diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPattern.java b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPattern.java index 9b7708625..747d35978 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPattern.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/autocrafting/ICraftingPattern.java @@ -64,9 +64,9 @@ public interface ICraftingPattern { NonNullList getByproducts(NonNullList took); /** - * @return the fluid inputs + * @return the fluid inputs per slot */ - NonNullList getFluidInputs(); + List> getFluidInputs(); /** * @return the fluid outputs diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java index 603777815..0b51ef07c 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/autocrafting/CraftingPattern.java @@ -7,6 +7,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.API; import com.raoulvdberge.refinedstorage.apiimpl.autocrafting.registry.CraftingTaskFactory; import com.raoulvdberge.refinedstorage.item.PatternItem; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluid; import net.minecraft.inventory.CraftingInventory; import net.minecraft.inventory.container.Container; import net.minecraft.item.Item; @@ -14,6 +15,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.ICraftingRecipe; import net.minecraft.item.crafting.IRecipeType; import net.minecraft.item.crafting.Ingredient; +import net.minecraft.tags.FluidTags; import net.minecraft.tags.ItemTags; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; @@ -34,7 +36,7 @@ public class CraftingPattern implements ICraftingPattern { private List> inputs = new ArrayList<>(); private NonNullList outputs = NonNullList.create(); private NonNullList byproducts = NonNullList.create(); - private NonNullList fluidInputs = NonNullList.create(); + private List> fluidInputs = new ArrayList<>(); private NonNullList fluidOutputs = NonNullList.create(); public CraftingPattern(World world, ICraftingPatternContainer container, ItemStack stack) { @@ -45,38 +47,54 @@ public class CraftingPattern implements ICraftingPattern { if (processing) { for (int i = 0; i < 9; ++i) { - ItemStack input = PatternItem.getInputSlot(stack, i); + { + ItemStack input = PatternItem.getInputSlot(stack, i); - if (input.isEmpty()) { - inputs.add(NonNullList.create()); - } else if (!exact) { - NonNullList possibilities = NonNullList.create(); + if (input.isEmpty()) { + inputs.add(NonNullList.create()); + } else if (!exact) { + NonNullList possibilities = NonNullList.create(); - possibilities.add(input.copy()); + possibilities.add(input.copy()); - for (ResourceLocation owningTag : ItemTags.getCollection().getOwningTags(input.getItem())) { - for (Item element : ItemTags.getCollection().get(owningTag).getAllElements()) { - possibilities.add(new ItemStack(element, input.getCount())); + for (ResourceLocation owningTag : ItemTags.getCollection().getOwningTags(input.getItem())) { + for (Item element : ItemTags.getCollection().get(owningTag).getAllElements()) { + possibilities.add(new ItemStack(element, input.getCount())); + } } + + inputs.add(possibilities); + } else { + inputs.add(NonNullList.from(ItemStack.EMPTY, input)); } - inputs.add(possibilities); - } else { - inputs.add(NonNullList.from(ItemStack.EMPTY, input)); + ItemStack output = PatternItem.getOutputSlot(stack, i); + if (!output.isEmpty()) { + this.valid = true; // As soon as we have one output, we are valid. + + outputs.add(output); + } } - ItemStack output = PatternItem.getOutputSlot(stack, i); - if (!output.isEmpty()) { - this.valid = true; // As soon as we have one output, we are valid. + { + FluidStack fluidInput = PatternItem.getFluidInputSlot(stack, i); + if (fluidInput.isEmpty()) { + fluidInputs.add(NonNullList.create()); + } else if (!exact) { + NonNullList possibilities = NonNullList.create(); - outputs.add(output); - } + possibilities.add(fluidInput.copy()); - FluidStack fluidInput = PatternItem.getFluidInputSlot(stack, i); - if (!fluidInput.isEmpty()) { - this.valid = true; + for (ResourceLocation owningTag : FluidTags.getCollection().getOwningTags(fluidInput.getFluid())) { + for (Fluid element : FluidTags.getCollection().get(owningTag).getAllElements()) { + possibilities.add(new FluidStack(element, fluidInput.getAmount())); + } + } - fluidInputs.add(fluidInput); + fluidInputs.add(possibilities); + } else { + fluidInputs.add(NonNullList.from(FluidStack.EMPTY, fluidInput)); + } } FluidStack fluidOutput = PatternItem.getFluidOutputSlot(stack, i); @@ -222,7 +240,7 @@ public class CraftingPattern implements ICraftingPattern { } @Override - public NonNullList getFluidInputs() { + public List> getFluidInputs() { return fluidInputs; } @@ -269,9 +287,18 @@ public class CraftingPattern implements ICraftingPattern { } for (int i = 0; i < fluidInputs.size(); ++i) { - if (!API.instance().getComparer().isEqual(fluidInputs.get(i), other.getFluidInputs().get(i), IComparer.COMPARE_NBT | IComparer.COMPARE_QUANTITY)) { + List inputs = this.fluidInputs.get(i); + List otherInputs = other.getFluidInputs().get(i); + + if (inputs.size() != otherInputs.size()) { return false; } + + for (int j = 0; j < inputs.size(); ++j) { + if (!API.instance().getComparer().isEqual(inputs.get(j), otherInputs.get(j), IComparer.COMPARE_NBT | IComparer.COMPARE_QUANTITY)) { + return false; + } + } } for (int i = 0; i < outputs.size(); ++i) { @@ -310,8 +337,10 @@ public class CraftingPattern implements ICraftingPattern { } } - for (FluidStack input : this.fluidInputs) { - result = 31 * result + API.instance().getFluidStackHashCode(input); + for (List inputs : this.fluidInputs) { + for (FluidStack input : inputs) { + result = 31 * result + API.instance().getFluidStackHashCode(input); + } } for (ItemStack output : this.outputs) { 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 b376814da..e6fbb90c2 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 @@ -279,7 +279,7 @@ public class CraftingTask implements ICraftingTask { return null; } - class PossibleInputs { + static class PossibleInputs { private List possibilities; private int pos; @@ -321,6 +321,48 @@ public class CraftingTask implements ICraftingTask { } } + static class PossibleFluidInputs { + private List possibilities; + private int pos; + + PossibleFluidInputs(List possibilities) { + this.possibilities = possibilities; + } + + FluidStack get() { + return possibilities.get(pos); + } + + // Return false if we're exhausted. + boolean cycle() { + if (pos + 1 >= possibilities.size()) { + pos = 0; + + return false; + } + + pos++; + + return true; + } + + void sort(IStackList mutatedStorage, IStackList results) { + possibilities.sort((a, b) -> { + FluidStack ar = mutatedStorage.get(a); + FluidStack br = mutatedStorage.get(b); + + return (br == null ? 0 : br.getAmount()) - (ar == null ? 0 : ar.getAmount()); + }); + + possibilities.sort((a, b) -> { + FluidStack ar = results.get(a); + FluidStack br = results.get(b); + + return (br == null ? 0 : br.getAmount()) - (ar == null ? 0 : ar.getAmount()); + }); + } + } + @Nullable private ICraftingTaskError calculateInternal( IStackList mutatedStorage, @@ -436,39 +478,48 @@ public class CraftingTask implements ICraftingTask { } } - for (FluidStack input : pattern.getFluidInputs()) { - FluidStack fromSelf = fluidResults.get(input, IComparer.COMPARE_NBT); - FluidStack fromNetwork = mutatedFluidStorage.get(input, IComparer.COMPARE_NBT); + for (NonNullList inputs : pattern.getFluidInputs()) { + if (inputs.isEmpty()) { + continue; + } - int remaining = input.getAmount(); + PossibleFluidInputs possibleInputs = new PossibleFluidInputs(new ArrayList<>(inputs)); + possibleInputs.sort(mutatedFluidStorage, fluidResults); + + FluidStack possibleInput = possibleInputs.get(); + + FluidStack fromSelf = fluidResults.get(possibleInput, IComparer.COMPARE_NBT); + FluidStack fromNetwork = mutatedFluidStorage.get(possibleInput, IComparer.COMPARE_NBT); + + int remaining = possibleInput.getAmount(); while (remaining > 0) { if (fromSelf != null) { int toTake = Math.min(remaining, fromSelf.getAmount()); - fluidsToExtract.add(input, toTake); + fluidsToExtract.add(possibleInput, toTake); - fluidResults.remove(input, toTake); + fluidResults.remove(possibleInput, toTake); remaining -= toTake; - fromSelf = fluidResults.get(input, IComparer.COMPARE_NBT); + fromSelf = fluidResults.get(possibleInput, IComparer.COMPARE_NBT); } else if (fromNetwork != null) { int toTake = Math.min(remaining, fromNetwork.getAmount()); - this.toTakeFluids.add(input, toTake); + this.toTakeFluids.add(possibleInput, toTake); - fluidsToExtract.add(input, toTake); + fluidsToExtract.add(possibleInput, toTake); mutatedFluidStorage.remove(fromNetwork, toTake); remaining -= toTake; - fromNetwork = mutatedFluidStorage.get(input, IComparer.COMPARE_NBT); + fromNetwork = mutatedFluidStorage.get(possibleInput, IComparer.COMPARE_NBT); - toExtractInitialFluids.add(input); + toExtractInitialFluids.add(possibleInput); } else { - ICraftingPattern subPattern = network.getCraftingManager().getPattern(input); + ICraftingPattern subPattern = network.getCraftingManager().getPattern(possibleInput); if (subPattern != null) { ICraftingPatternChain subPatternChain = patternChainList.getChain(subPattern); @@ -480,22 +531,22 @@ public class CraftingTask implements ICraftingTask { return result; } - fromSelf = fluidResults.get(input, IComparer.COMPARE_NBT); + fromSelf = fluidResults.get(possibleInput, IComparer.COMPARE_NBT); if (fromSelf == null) { throw new IllegalStateException("Recursive fluid calculation didn't yield anything"); } - fromNetwork = mutatedFluidStorage.get(input, IComparer.COMPARE_NBT); + fromNetwork = mutatedFluidStorage.get(possibleInput, IComparer.COMPARE_NBT); subPatternChain.cycle(); } // fromSelf contains the amount crafted after the loop. - this.toCraftFluids.add(input, fromSelf.getAmount()); + this.toCraftFluids.add(possibleInput, fromSelf.getAmount()); } else { - this.missingFluids.add(input, remaining); + this.missingFluids.add(possibleInput, remaining); - fluidsToExtract.add(input, remaining); + fluidsToExtract.add(possibleInput, remaining); remaining = 0; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/item/PatternItem.java b/src/main/java/com/raoulvdberge/refinedstorage/item/PatternItem.java index 7ba741dc2..a44946964 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/item/PatternItem.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/item/PatternItem.java @@ -77,7 +77,7 @@ public class PatternItem extends Item implements ICraftingPatternProvider { tooltip.add(new TranslationTextComponent("misc.refinedstorage.pattern.inputs").setStyle(yellow)); RenderUtils.addCombinedItemsToTooltip(tooltip, true, pattern.getInputs().stream().map(i -> i.size() > 0 ? i.get(0) : ItemStack.EMPTY).collect(Collectors.toList())); - RenderUtils.addCombinedFluidsToTooltip(tooltip, true, pattern.getFluidInputs()); + RenderUtils.addCombinedFluidsToTooltip(tooltip, true, pattern.getFluidInputs().stream().map(i -> i.size() > 0 ? i.get(0) : FluidStack.EMPTY).collect(Collectors.toList())); tooltip.add(new TranslationTextComponent("misc.refinedstorage.pattern.outputs").setStyle(yellow)); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/screen/grid/GridScreen.java b/src/main/java/com/raoulvdberge/refinedstorage/screen/grid/GridScreen.java index 9459348d2..40faffb54 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/screen/grid/GridScreen.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/screen/grid/GridScreen.java @@ -23,7 +23,6 @@ import com.raoulvdberge.refinedstorage.screen.widget.ScrollbarWidget; import com.raoulvdberge.refinedstorage.screen.widget.SearchWidget; import com.raoulvdberge.refinedstorage.screen.widget.TabListWidget; import com.raoulvdberge.refinedstorage.screen.widget.sidebutton.*; -import com.raoulvdberge.refinedstorage.tile.config.IType; import com.raoulvdberge.refinedstorage.tile.data.TileDataManager; import com.raoulvdberge.refinedstorage.tile.grid.GridTile; import com.raoulvdberge.refinedstorage.tile.grid.portable.IPortableGrid; @@ -135,12 +134,7 @@ public class GridScreen extends BaseScreen implements IScreenInfo TileDataManager.setParameter(GridTile.PROCESSING_PATTERN, processingPattern.isChecked()); }); - boolean showExactPatternOption = true; - if (((GridNetworkNode) grid).isProcessingPattern() && ((GridNetworkNode) grid).getType() == IType.FLUIDS) { - showExactPatternOption = false; - } - - if (showExactPatternOption) { + if (((GridNetworkNode) grid).isProcessingPattern()) { exactPattern = addCheckBox(processingPattern.x + processingPattern.getWidth() + 5, y + getTopHeight() + (getVisibleRows() * 18) + 60, I18n.format("misc.refinedstorage.exact"), GridTile.EXACT_PATTERN.getValue(), btn -> { TileDataManager.setParameter(GridTile.EXACT_PATTERN, exactPattern.isChecked()); }); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/util/RenderUtils.java b/src/main/java/com/raoulvdberge/refinedstorage/util/RenderUtils.java index 979b18f17..599fc8828 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/util/RenderUtils.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/util/RenderUtils.java @@ -11,7 +11,6 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.item.ItemStack; -import net.minecraft.util.NonNullList; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.Style; @@ -71,7 +70,7 @@ public final class RenderUtils { } } - public static void addCombinedFluidsToTooltip(List tooltip, boolean displayMb, NonNullList stacks) { + public static void addCombinedFluidsToTooltip(List tooltip, boolean displayMb, List stacks) { Set combinedIndices = new HashSet<>(); for (int i = 0; i < stacks.size(); ++i) {