Add fluid (in)exact mode

This commit is contained in:
raoulvdberge
2019-10-28 19:55:24 +01:00
parent 148dcde872
commit 9ffb9ef2ce
6 changed files with 129 additions and 56 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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));
}

View File

@@ -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());
});

View File

@@ -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) {