Add fluid (in)exact mode
This commit is contained in:
@@ -64,9 +64,9 @@ public interface ICraftingPattern {
|
||||
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
|
||||
|
@@ -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<NonNullList<ItemStack>> inputs = new ArrayList<>();
|
||||
private NonNullList<ItemStack> outputs = 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();
|
||||
|
||||
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<ItemStack> possibilities = NonNullList.create();
|
||||
if (input.isEmpty()) {
|
||||
inputs.add(NonNullList.create());
|
||||
} else if (!exact) {
|
||||
NonNullList<ItemStack> 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<FluidStack> 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<FluidStack> getFluidInputs() {
|
||||
public List<NonNullList<FluidStack>> 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<FluidStack> inputs = this.fluidInputs.get(i);
|
||||
List<FluidStack> 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<FluidStack> inputs : this.fluidInputs) {
|
||||
for (FluidStack input : inputs) {
|
||||
result = 31 * result + API.instance().getFluidStackHashCode(input);
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemStack output : this.outputs) {
|
||||
|
@@ -279,7 +279,7 @@ public class CraftingTask implements ICraftingTask {
|
||||
return null;
|
||||
}
|
||||
|
||||
class PossibleInputs {
|
||||
static class PossibleInputs {
|
||||
private List<ItemStack> possibilities;
|
||||
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
|
||||
private ICraftingTaskError calculateInternal(
|
||||
IStackList<ItemStack> 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<FluidStack> 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;
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
|
@@ -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<GridContainer> 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());
|
||||
});
|
||||
|
@@ -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<ITextComponent> tooltip, boolean displayMb, NonNullList<FluidStack> stacks) {
|
||||
public static void addCombinedFluidsToTooltip(List<ITextComponent> tooltip, boolean displayMb, List<FluidStack> stacks) {
|
||||
Set<Integer> combinedIndices = new HashSet<>();
|
||||
|
||||
for (int i = 0; i < stacks.size(); ++i) {
|
||||
|
Reference in New Issue
Block a user