diff --git a/docs/ADDING_RECIPES.md b/docs/ADDING_RECIPES.md index d7ec522c1..23b57263d 100644 --- a/docs/ADDING_RECIPES.md +++ b/docs/ADDING_RECIPES.md @@ -28,8 +28,8 @@ ServerEvents.recipes(event => { // add all the inputs and outputs: .itemIn("64x #minecraft:logs_that_burn") .itemOut("64x minecraft:charcoal") - .fluidIn("modern_industrialization:oxygen", 1000) - .fluidOut("modern_industrialization:creosote", 5000) + .fluidIn("1000x modern_industrialization:oxygen") + .fluidOut("5000x modern_industrialization:creosote") }) ``` diff --git a/src/client/java/aztech/modern_industrialization/compat/viewer/abstraction/ViewerCategory.java b/src/client/java/aztech/modern_industrialization/compat/viewer/abstraction/ViewerCategory.java index 7b7b85ff1..7c4447bc5 100644 --- a/src/client/java/aztech/modern_industrialization/compat/viewer/abstraction/ViewerCategory.java +++ b/src/client/java/aztech/modern_industrialization/compat/viewer/abstraction/ViewerCategory.java @@ -38,6 +38,7 @@ import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.level.ItemLike; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import org.jetbrains.annotations.Nullable; /** @@ -111,6 +112,8 @@ public interface SlotBuilder { SlotBuilder fluid(FluidVariant fluid, long amount, float probability); + SlotBuilder fluid(FluidIngredient ingredient, long amount, float probability); + default SlotBuilder item(ItemStack stack) { return item(stack, 1); } diff --git a/src/client/java/aztech/modern_industrialization/compat/viewer/impl/emi/ViewerCategoryEmi.java b/src/client/java/aztech/modern_industrialization/compat/viewer/impl/emi/ViewerCategoryEmi.java index b565bbed4..f54d858d2 100644 --- a/src/client/java/aztech/modern_industrialization/compat/viewer/impl/emi/ViewerCategoryEmi.java +++ b/src/client/java/aztech/modern_industrialization/compat/viewer/impl/emi/ViewerCategoryEmi.java @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +import java.util.stream.Stream; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; @@ -46,6 +47,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import org.jetbrains.annotations.Nullable; class ViewerCategoryEmi extends EmiRecipeCategory { @@ -165,6 +167,19 @@ public ViewerCategory.SlotBuilder fluid(FluidVariant fluid, long amount, float p return this; } + @Override + public ViewerCategory.SlotBuilder fluid(FluidIngredient ingredient, long amount, float probability) { + isFluid = true; + hasBackground = false; + ing = EmiIngredient.of( + Stream.of(ingredient.getStacks()) + .map(fs -> EmiStack.of(fs.getFluid(), fs.getComponentsPatch())) + .toList(), + amount); + processProbability(probability); + return this; + } + private void processProbability(float probability) { if (probability == 0) { markCatalyst(); diff --git a/src/client/java/aztech/modern_industrialization/compat/viewer/impl/jei/ViewerCategoryJei.java b/src/client/java/aztech/modern_industrialization/compat/viewer/impl/jei/ViewerCategoryJei.java index 2df3382a9..4183c32c5 100644 --- a/src/client/java/aztech/modern_industrialization/compat/viewer/impl/jei/ViewerCategoryJei.java +++ b/src/client/java/aztech/modern_industrialization/compat/viewer/impl/jei/ViewerCategoryJei.java @@ -51,6 +51,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.neoforged.neoforge.fluids.FluidType; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import org.jetbrains.annotations.Nullable; class ViewerCategoryJei extends AbstractRecipeCategory { @@ -135,6 +136,18 @@ public ViewerCategory.SlotBuilder fluid(FluidVariant fluid, long amount, float p return this; } + @Override + public ViewerCategory.SlotBuilder fluid(FluidIngredient ingredient, long amount, float probability) { + for (var fs : ingredient.getStacks()) { + slotBuilder.addFluidStack(fs.getFluid(), amount, fs.getComponentsPatch()); + } + // This call displays the full sprite (instead of JEI's partial rendering) + slotBuilder.setFluidRenderer(1, false, 16, 16); + addProbability(slotBuilder, probability); + slotBuilder.setBackground(fluidSlot, -1, -1); + return this; + } + private ViewerCategory.SlotBuilder items(List stacks, float probability) { slotBuilder.addItemStacks(stacks); addProbability(slotBuilder, probability); diff --git a/src/client/java/aztech/modern_industrialization/compat/viewer/impl/rei/ViewerCategoryRei.java b/src/client/java/aztech/modern_industrialization/compat/viewer/impl/rei/ViewerCategoryRei.java index 03dfe47b7..89eef055d 100644 --- a/src/client/java/aztech/modern_industrialization/compat/viewer/impl/rei/ViewerCategoryRei.java +++ b/src/client/java/aztech/modern_industrialization/compat/viewer/impl/rei/ViewerCategoryRei.java @@ -52,6 +52,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import org.jetbrains.annotations.Nullable; class ViewerCategoryRei implements DisplayCategory.ViewerDisplay> { @@ -173,6 +174,16 @@ public ViewerCategory.SlotBuilder fluid(FluidVariant fluid, long amount, float p return this; } + @Override + public ViewerCategory.SlotBuilder fluid(FluidIngredient ingredient, long amount, float probability) { + isFluid = true; + hasBackground = false; + for (var fs : ingredient.getStacks()) { + ing.add(ReiSlotUtil.createFluidEntryStack(FluidVariant.of(fs), amount, probability, input)); + } + return this; + } + private ViewerCategory.SlotBuilder items(List stacks, float probability) { for (var stack : stacks) { ing.add(EntryStacks.of(stack).tooltip(ReiSlotUtil.getProbabilitySetting(probability, input))); diff --git a/src/client/java/aztech/modern_industrialization/compat/viewer/usage/MachineCategory.java b/src/client/java/aztech/modern_industrialization/compat/viewer/usage/MachineCategory.java index d46155083..24337a210 100644 --- a/src/client/java/aztech/modern_industrialization/compat/viewer/usage/MachineCategory.java +++ b/src/client/java/aztech/modern_industrialization/compat/viewer/usage/MachineCategory.java @@ -150,7 +150,7 @@ private void addFluidInputs(LayoutBuilder builder, MachineRecipe recipe) { if (i < recipe.fluidInputs.size()) { var input = recipe.fluidInputs.get(i); - slot.fluid(FluidVariant.of(input.fluid()), input.amount(), input.probability()); + slot.fluid(input.fluid(), input.amount(), input.probability()); } else { slot.variant(FluidVariant.blank()); } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/FluidInputComponent.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/FluidInputComponent.java index 3b659c1fe..f804265b6 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/FluidInputComponent.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/FluidInputComponent.java @@ -25,6 +25,7 @@ import aztech.modern_industrialization.MI; import aztech.modern_industrialization.machines.recipe.MachineRecipe; +import dev.latvian.mods.kubejs.core.RegistryObjectKJS; import dev.latvian.mods.kubejs.fluid.FluidWrapper; import dev.latvian.mods.kubejs.recipe.KubeRecipe; import dev.latvian.mods.kubejs.recipe.component.SimpleRecipeComponent; @@ -33,8 +34,6 @@ import dev.latvian.mods.kubejs.recipe.match.ReplacementMatchInfo; import dev.latvian.mods.kubejs.util.RegistryAccessContainer; import dev.latvian.mods.rhino.Context; -import net.minecraft.world.level.material.Fluids; -import net.neoforged.neoforge.fluids.FluidStack; public class FluidInputComponent extends SimpleRecipeComponent { public static final FluidInputComponent FLUID_INPUT = new FluidInputComponent(); @@ -45,21 +44,21 @@ public FluidInputComponent() { @Override public MachineRecipe.FluidInput wrap(Context cx, KubeRecipe recipe, Object from) { - var fs = FluidWrapper.wrap(RegistryAccessContainer.of(cx), from); - return new MachineRecipe.FluidInput(fs.getFluid(), fs.getAmount(), 1); + var fs = FluidWrapper.wrapSizedIngredient(RegistryAccessContainer.of(cx), from); + return new MachineRecipe.FluidInput(fs.ingredient(), fs.amount(), 1); } @Override public boolean matches(Context cx, KubeRecipe recipe, MachineRecipe.FluidInput value, ReplacementMatchInfo match) { - return match.match() instanceof FluidMatch m && m.matches(cx, new FluidStack(value.fluid(), 1), match.exact()); + return match.match() instanceof FluidMatch m && m.matches(cx, value.fluid(), match.exact()); } @Override public MachineRecipe.FluidInput replace(Context cx, KubeRecipe recipe, MachineRecipe.FluidInput original, ReplacementMatchInfo match, Object with) { if (matches(cx, recipe, original, match)) { - var fs = FluidWrapper.wrap(RegistryAccessContainer.of(cx), with); - return new MachineRecipe.FluidInput(fs.getFluid(), original.amount(), original.probability()); + var fi = FluidWrapper.wrapIngredient(RegistryAccessContainer.of(cx), with); + return new MachineRecipe.FluidInput(fi, original.amount(), original.probability()); } else { return original; } @@ -67,13 +66,13 @@ public MachineRecipe.FluidInput replace(Context cx, KubeRecipe recipe, MachineRe @Override public boolean isEmpty(MachineRecipe.FluidInput value) { - return value.amount() <= 0 || value.fluid().isSame(Fluids.EMPTY); + return value.amount() <= 0 || value.fluid().isEmpty(); } @Override public void buildUniqueId(UniqueIdBuilder builder, MachineRecipe.FluidInput value) { if (!isEmpty(value)) { - builder.append(value.fluid().builtInRegistryHolder().getKey().location()); + builder.append(((RegistryObjectKJS) value.fluid().getStacks()[0].getFluid()).kjs$getIdLocation()); } } } diff --git a/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/MachineKubeRecipe.java b/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/MachineKubeRecipe.java index ef0e5d5cb..87f0e7f5a 100644 --- a/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/MachineKubeRecipe.java +++ b/src/main/java/aztech/modern_industrialization/compat/kubejs/recipe/MachineKubeRecipe.java @@ -27,16 +27,23 @@ import aztech.modern_industrialization.machines.recipe.MachineRecipe; import aztech.modern_industrialization.machines.recipe.condition.MachineProcessCondition; import aztech.modern_industrialization.thirdparty.fabrictransfer.api.item.ItemVariant; +import com.mojang.logging.LogUtils; import dev.latvian.mods.kubejs.recipe.KubeRecipe; import dev.latvian.mods.kubejs.recipe.RecipeKey; import dev.latvian.mods.kubejs.recipe.schema.KubeRecipeFactory; import java.util.ArrayList; import java.util.List; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.material.Fluid; import net.neoforged.neoforge.common.crafting.SizedIngredient; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; +import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; +import org.slf4j.Logger; public class MachineKubeRecipe extends KubeRecipe implements ProcessConditionHelper { + private static final Logger LOGGER = LogUtils.getLogger(); public static final KubeRecipeFactory FACTORY = new KubeRecipeFactory(MI.id("machine"), MachineKubeRecipe.class, MachineKubeRecipe::new); private MachineKubeRecipe addToList(RecipeKey> key, T element) { @@ -64,19 +71,73 @@ public MachineKubeRecipe itemOut(ItemStack output, float chance) { return addToList(MachineRecipeSchema.ITEM_OUTPUTS, new MachineRecipe.ItemOutput(ItemVariant.of(output), output.getCount(), chance)); } - public MachineKubeRecipe fluidIn(Fluid fluid, long mbs) { - return fluidIn(fluid, mbs, 1F); + public MachineKubeRecipe fluidIn(SizedFluidIngredient ingredient) { + return fluidInInternal(ingredient, 1F); // skip chance == 1 check } - public MachineKubeRecipe fluidIn(Fluid fluid, long mbs, float probability) { - return addToList(MachineRecipeSchema.FLUID_INPUTS, new MachineRecipe.FluidInput(fluid, mbs, probability)); + public MachineKubeRecipe fluidIn(SizedFluidIngredient ingredient, float chance) { + // TODO: remove this mess once we don't need to worry about backwards compat anymore. + if ((ingredient.amount() == 1 || ingredient.amount() == 1000) && chance > 1) { + LOGGER.warn("fluidIn with separate fluid and amount is deprecated. Use fluidIn(\"%dx %s\") notation instead.".formatted( + (int) chance, + BuiltInRegistries.FLUID.getKey(ingredient.ingredient().getStacks()[0].getFluid()))); + return fluidIn(new SizedFluidIngredient(ingredient.ingredient(), (int) chance)); + } else if (ingredient.amount() == 1000 && chance == 1) { + throw new IllegalArgumentException( + "fluidIn(\"some_fluid\", 1) is ambiguous. Use either fluidIn(\"1x some_fluid\") or fluidIn(\"some_fluid\") depending on what you meant."); + } + + return fluidInInternal(ingredient, chance); + } + + private MachineKubeRecipe fluidInInternal(SizedFluidIngredient ingredient, float chance) { + if (chance > 1) { + throw new IllegalArgumentException("Fluid input chance must be between 0 and 1. It is " + chance); + } + return addToList(MachineRecipeSchema.FLUID_INPUTS, new MachineRecipe.FluidInput(ingredient.ingredient(), ingredient.amount(), chance)); + } + + public MachineKubeRecipe fluidOut(FluidStack output) { + return fluidOutInternal(output, 1F); // skip chance == 1 check + } + + public MachineKubeRecipe fluidOut(FluidStack output, float chance) { + // TODO: remove this mess once we don't need to worry about backwards compat anymore. + if ((output.getAmount() == 1 || output.getAmount() == 1000) && chance > 1) { + LOGGER.warn("fluidOut with separate fluid and amount is deprecated. Use fluidOut(\"%dx %s\") notation instead.".formatted( + (int) chance, + BuiltInRegistries.FLUID.getKey(output.getFluid()))); + return fluidOut(output.copyWithAmount((int) chance)); + } else if (output.getAmount() == 1000 && chance == 1) { + throw new IllegalArgumentException( + "fluidOut(\"some_fluid\", 1) is ambiguous. Use either fluidOut(\"1x some_fluid\") or fluidOut(\"some_fluid\") depending on what you meant."); + } + + return fluidOutInternal(output, chance); + } + + private MachineKubeRecipe fluidOutInternal(FluidStack output, float chance) { + if (!output.isComponentsPatchEmpty()) { + throw new IllegalArgumentException("FluidStack components are not supported in machine recipe outputs."); + } + return addToList(MachineRecipeSchema.FLUID_OUTPUTS, new MachineRecipe.FluidOutput(output.getFluid(), output.getAmount(), chance)); } - public MachineKubeRecipe fluidOut(Fluid fluid, long mbs) { - return fluidOut(fluid, mbs, 1F); + @Deprecated(forRemoval = true) + public MachineKubeRecipe fluidIn(FluidIngredient fluid, long mbs, float probability) { + LOGGER.warn("fluidIn with separate fluid and amount is deprecated. Use fluidIn(\"%dx %s\", %f) notation instead.".formatted( + mbs, + BuiltInRegistries.FLUID.getKey(fluid.getStacks()[0].getFluid()), + probability)); + return fluidIn(new SizedFluidIngredient(fluid, (int) mbs), probability); } + @Deprecated(forRemoval = true) public MachineKubeRecipe fluidOut(Fluid fluid, long mbs, float probability) { + LOGGER.warn("fluidOut with separate fluid and amount is deprecated. Use fluidOut(\"%dx %s\", %f) notation instead.".formatted( + mbs, + BuiltInRegistries.FLUID.getKey(fluid), + probability)); return addToList(MachineRecipeSchema.FLUID_OUTPUTS, new MachineRecipe.FluidOutput(fluid, mbs, probability)); } diff --git a/src/main/java/aztech/modern_industrialization/machines/components/CrafterComponent.java b/src/main/java/aztech/modern_industrialization/machines/components/CrafterComponent.java index a02d175ca..147ead746 100644 --- a/src/main/java/aztech/modern_industrialization/machines/components/CrafterComponent.java +++ b/src/main/java/aztech/modern_industrialization/machines/components/CrafterComponent.java @@ -58,6 +58,9 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.level.material.Fluid; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.FluidUtil; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import org.jetbrains.annotations.Nullable; public class CrafterComponent implements IComponent.ServerOnly, CrafterAccess { @@ -474,7 +477,7 @@ protected boolean takeFluidInputs(MachineRecipe recipe, boolean simulate) { } long remainingAmount = input.amount(); for (ConfigurableFluidStack stack : stacks) { - if (stack.getResource().equals(FluidVariant.of(input.fluid()))) { + if (fluidIngredientMatch(stack.getResource(), input.fluid())) { long taken = Math.min(remainingAmount, stack.getAmount()); if (taken > 0 && !simulate) { behavior.getStatsOrDummy().addUsedFluids(stack.getResource().getFluid(), taken); @@ -491,6 +494,17 @@ protected boolean takeFluidInputs(MachineRecipe recipe, boolean simulate) { return ok; } + private boolean fluidIngredientMatch(FluidVariant resource, FluidIngredient ingredient) { + if (ingredient.isSimple()) { + for (var stack : ingredient.getStacks()) { + return resource.equals(FluidVariant.of(stack.getFluid())); + } + return false; + } else { + return ingredient.test(resource.toStack(1)); + } + } + protected boolean putItemOutputs(MachineRecipe recipe, boolean simulate, boolean toggleLock) { List baseList = inventory.getItemOutputs(); List stacks = simulate ? ConfigurableItemStack.copyList(baseList) : baseList; @@ -682,10 +696,38 @@ public void lockRecipe(ResourceLocation recipeId, net.minecraft.world.entity.pla // FLUID INPUTS outer: for (MachineRecipe.FluidInput input : recipe.value().fluidInputs) { for (ConfigurableFluidStack stack : this.inventory.getFluidInputs()) { - if (stack.isLockedTo(input.fluid())) + if (stack.getLockedInstance() != null && input.fluid().test(new FluidStack(stack.getLockedInstance(), 1))) continue outer; } - AbstractConfigurableStack.playerLockNoOverride(input.fluid(), this.inventory.getFluidInputs()); + Fluid targetFluid = null; + // Find the first match in the player inventory + for (int i = 0; i < inventory.getContainerSize(); i++) { + var playerStack = FluidUtil.getFluidContained(inventory.getItem(i)).orElse(FluidStack.EMPTY); + if (!playerStack.isEmpty() && input.fluid().test(new FluidStack(playerStack.getFluid(), 1))) { + targetFluid = playerStack.getFluid(); + break; + } + } + if (targetFluid == null) { + // Find the first match that is an item from MI + for (Fluid fluid : input.getInputFluids()) { + ResourceLocation id = BuiltInRegistries.FLUID.getKey(fluid); + if (id.getNamespace().equals(MI.ID)) { + targetFluid = fluid; + break; + } + } + } + if (targetFluid == null) { + // If there is only one value in the tag, pick that one + if (input.getInputFluids().size() == 1) { + targetFluid = input.getInputFluids().get(0); + } + } + + if (targetFluid != null) { + AbstractConfigurableStack.playerLockNoOverride(targetFluid, this.inventory.getFluidInputs()); + } } // FLUID OUTPUTS outer: for (MachineRecipe.FluidOutput output : recipe.value().fluidOutputs) { diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/MIRecipeJson.java b/src/main/java/aztech/modern_industrialization/machines/recipe/MIRecipeJson.java index 189764fef..080da6e27 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/MIRecipeJson.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/MIRecipeJson.java @@ -37,6 +37,7 @@ import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.material.Fluid; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; @SuppressWarnings({ "FieldCanBeLocal", "unused", "MismatchedQueryAndUpdateOfCollection" }) public class MIRecipeJson> { @@ -149,7 +150,7 @@ public T addFluidInput(Fluid fluid, int amount, float probability) { if (id.equals(BuiltInRegistries.FLUID.getDefaultKey())) { throw new RuntimeException("Could not find id for fluid " + fluid); } - recipe.fluidInputs.add(new MachineRecipe.FluidInput(fluid, amount, probability)); + recipe.fluidInputs.add(new MachineRecipe.FluidInput(FluidIngredient.of(fluid), amount, probability)); return (T) this; } diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/MachineRecipe.java b/src/main/java/aztech/modern_industrialization/machines/recipe/MachineRecipe.java index 08fbb01b1..2244e231e 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/MachineRecipe.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/MachineRecipe.java @@ -54,6 +54,8 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.material.Fluid; import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs; public class MachineRecipe implements Recipe { @@ -227,22 +229,31 @@ public List getInputItems() { } } - public record FluidInput(Fluid fluid, long amount, float probability) { + public record FluidInput(FluidIngredient fluid, long amount, float probability) { + @Deprecated(forRemoval = true) + public FluidInput(Fluid fluid, long amount, float probability) { + this(FluidIngredient.of(fluid), amount, probability); + } + public static final Codec CODEC = RecordCodecBuilder.create( g -> g.group( - BuiltInRegistries.FLUID.byNameCodec().fieldOf("fluid").forGetter(FluidInput::fluid), + FluidIngredient.MAP_CODEC_NONEMPTY.forGetter(FluidInput::fluid), NeoForgeExtraCodecs.optionalFieldAlwaysWrite(MIExtraCodecs.POSITIVE_LONG, "amount", 1L).forGetter(FluidInput::amount), MIExtraCodecs.FLOAT_01.optionalFieldOf("probability", 1f).forGetter(FluidInput::probability)) .apply(g, FluidInput::new)); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.registry(Registries.FLUID), + FluidIngredient.STREAM_CODEC, FluidInput::fluid, ByteBufCodecs.VAR_LONG, FluidInput::amount, ByteBufCodecs.FLOAT, FluidInput::probability, FluidInput::new); + + public List getInputFluids() { + return Arrays.stream(fluid.getStacks()).map(FluidStack::getFluid).distinct().collect(Collectors.toList()); + } } public record ItemOutput(ItemVariant variant, int amount, float probability) { diff --git a/src/main/java/aztech/modern_industrialization/machines/recipe/RecipeConversions.java b/src/main/java/aztech/modern_industrialization/machines/recipe/RecipeConversions.java index 4fe2e9bcf..d922a1a06 100644 --- a/src/main/java/aztech/modern_industrialization/machines/recipe/RecipeConversions.java +++ b/src/main/java/aztech/modern_industrialization/machines/recipe/RecipeConversions.java @@ -39,6 +39,7 @@ import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.ComposterBlock; import net.neoforged.neoforge.fluids.FluidType; +import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import org.jetbrains.annotations.Nullable; public class RecipeConversions { @@ -67,7 +68,7 @@ public static RecipeHolder ofStonecutting(RecipeHolder