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