From 3365ce82700172a4b6fc71bc820d1d16a546b31b Mon Sep 17 00:00:00 2001 From: Tristen Allen <1288716+Spyboticsguy@users.noreply.github.com> Date: Fri, 14 Nov 2025 15:02:54 -0500 Subject: [PATCH] Fix potion-based fluid recipes. Creators-of-Create/Create@58876e2 migrated from a custom ingredient handler for fluids to NeoForge's `SizedFluidIngredient`. In some places, references were updated to use a `SizedFluidIngredient` containing a `DataComponentFluidIngredient` in order to preserve behaviors which would require the presence of specific components in fluid ingredients (the previous behavior). In other places, references were updated to use `SizedFluidIngredient.of(FluidStack stack)`, which discards components when creating the fluid ingredient. This resulted in Creators-of-Create/Create#9474, where potion recipes were effectively created such that a non-fluid potion ingredient could be mixed with _any_ potion base to create (one of) the possible outputs when brewing a potion with said ingredient. This change updates the potion-mixing recipes logic to use a `DataComponentFluidIngredient` as the base fluid ingredient inside the `SizedFluidIngredient`, fixing Creators-of-Create/Create#9474. This change also updates JEI integration code to similarly use `DataComponentFluidIngredients`, fixing visualization issues with potion-bottle and potion-application (e.g., redstone from cinder flour) recipes. Adds tests to verify potion brewing and potion-application recipes function as intended. --- .../compat/jei/category/SpoutCategory.java | 9 +++++++-- .../fluids/potion/PotionMixingRecipes.java | 3 ++- .../gametest/CreateGameTestHelper.java | 1 + .../gametest/tests/TestProcessing.java | 19 ++++++++++++++++++ .../gametest/processing/potion_brewing.nbt | Bin 0 -> 3360 bytes .../gametest/processing/spout_crafting.nbt | Bin 0 -> 1763 bytes 6 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/data/create/structure/gametest/processing/potion_brewing.nbt create mode 100644 src/main/resources/data/create/structure/gametest/processing/spout_crafting.nbt diff --git a/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java index 132c512fa7..5b16d92889 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java @@ -34,6 +34,7 @@ import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.capability.IFluidHandler.FluidAction; import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem; +import net.neoforged.neoforge.fluids.crafting.DataComponentFluidIngredient; import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; @ParametersAreNonnullByDefault @@ -52,9 +53,11 @@ public static void consumeRecipes(Consumer> consumer FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack); Ingredient bottle = Ingredient.of(Items.GLASS_BOTTLE); ResourceLocation id = Create.asResource("potions"); + SizedFluidIngredient fluidIngredient = new SizedFluidIngredient( + DataComponentFluidIngredient.of(false, fluidFromPotionItem), fluidFromPotionItem.getAmount()); FillingRecipe recipe = new StandardProcessingRecipe.Builder<>(FillingRecipe::new, id) .withItemIngredients(bottle) - .withFluidIngredients(SizedFluidIngredient.of(fluidFromPotionItem)) + .withFluidIngredients(fluidIngredient) .withSingleItemOutput(stack) .build(); consumer.accept(new RecipeHolder<>(id, recipe)); @@ -93,9 +96,11 @@ public static void consumeRecipes(Consumer> consumer ResourceLocation fluidName = RegisteredObjectsHelper.getKeyOrThrow(fluidCopy.getFluid()); ResourceLocation id = Create.asResource("fill_" + itemName.getNamespace() + "_" + itemName.getPath() + "_with_" + fluidName.getNamespace() + "_" + fluidName.getPath()); + SizedFluidIngredient fluidIngredient = new SizedFluidIngredient( + DataComponentFluidIngredient.of(false, fluidCopy), fluidCopy.getAmount()); FillingRecipe recipe = new StandardProcessingRecipe.Builder<>(FillingRecipe::new, id) .withItemIngredients(bucket) - .withFluidIngredients(SizedFluidIngredient.of(fluidCopy)) + .withFluidIngredients(fluidIngredient) .withSingleItemOutput(container) .build(); consumer.accept(new RecipeHolder<>(id, recipe)); diff --git a/src/main/java/com/simibubi/create/content/fluids/potion/PotionMixingRecipes.java b/src/main/java/com/simibubi/create/content/fluids/potion/PotionMixingRecipes.java index 8aeb8a90d9..afd2dfc95c 100644 --- a/src/main/java/com/simibubi/create/content/fluids/potion/PotionMixingRecipes.java +++ b/src/main/java/com/simibubi/create/content/fluids/potion/PotionMixingRecipes.java @@ -30,6 +30,7 @@ import net.neoforged.neoforge.common.brewing.BrewingRecipe; import net.neoforged.neoforge.common.brewing.IBrewingRecipe; import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.crafting.DataComponentFluidIngredient; import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; public class PotionMixingRecipes { @@ -149,7 +150,7 @@ private static RecipeHolder createRecipe(String id, Ingredient ing ResourceLocation recipeId = Create.asResource(id); MixingRecipe recipe = new Builder<>(MixingRecipe::new, recipeId) .require(ingredient) - .require(SizedFluidIngredient.of(fromFluid)) + .require(new SizedFluidIngredient(DataComponentFluidIngredient.of(false, fromFluid), fromFluid.getAmount())) .output(toFluid) .requiresHeat(HeatCondition.HEATED) .build(); diff --git a/src/main/java/com/simibubi/create/infrastructure/gametest/CreateGameTestHelper.java b/src/main/java/com/simibubi/create/infrastructure/gametest/CreateGameTestHelper.java index b73cac0185..f5c20c8b72 100644 --- a/src/main/java/com/simibubi/create/infrastructure/gametest/CreateGameTestHelper.java +++ b/src/main/java/com/simibubi/create/infrastructure/gametest/CreateGameTestHelper.java @@ -66,6 +66,7 @@ public class CreateGameTestHelper extends GameTestHelper { public static final int TEN_SECONDS = 10 * TICKS_PER_SECOND; public static final int FIFTEEN_SECONDS = 15 * TICKS_PER_SECOND; public static final int TWENTY_SECONDS = 20 * TICKS_PER_SECOND; + public static final int THIRTY_SECONDS = 30 * TICKS_PER_SECOND; private CreateGameTestHelper(GameTestInfo testInfo) { super(testInfo); diff --git a/src/main/java/com/simibubi/create/infrastructure/gametest/tests/TestProcessing.java b/src/main/java/com/simibubi/create/infrastructure/gametest/tests/TestProcessing.java index 151e32902b..921915d3c1 100644 --- a/src/main/java/com/simibubi/create/infrastructure/gametest/tests/TestProcessing.java +++ b/src/main/java/com/simibubi/create/infrastructure/gametest/tests/TestProcessing.java @@ -42,6 +42,25 @@ public static void brassMixing2(CreateGameTestHelper helper) { helper.succeedWhen(() -> helper.assertContainerContains(output, AllItems.BRASS_INGOT.get())); } + @GameTest(template = "potion_brewing", timeoutTicks = CreateGameTestHelper.THIRTY_SECONDS) + public static void potionBrewing(CreateGameTestHelper helper) { + BlockPos chest = new BlockPos(8, 3, 5); + BlockPos potionLever = new BlockPos(2, 3, 4); + BlockPos bottleLever = new BlockPos(7, 3, 2); + ItemStack expected = PotionContents.createItemStack(Items.POTION, Potions.HEALING); + + helper.pullLever(potionLever); + helper.whenSecondsPassed(15, () -> helper.pullLever(bottleLever)); + helper.succeedWhen(() -> helper.assertContainerContains(chest, expected)); + } + + @GameTest(template = "spout_crafting", timeoutTicks = CreateGameTestHelper.TEN_SECONDS) + public static void spoutCrafting(CreateGameTestHelper helper) { + BlockPos chest = new BlockPos(5, 3, 1); + helper.pullLever(2, 3, 2); + helper.succeedWhen(() -> helper.assertContainerContains(chest, Items.REDSTONE)); + } + @GameTest(template = "crushing_wheel_crafting", timeoutTicks = CreateGameTestHelper.TEN_SECONDS) public static void crushingWheelCrafting(CreateGameTestHelper helper) { BlockPos chest = new BlockPos(1, 4, 3); diff --git a/src/main/resources/data/create/structure/gametest/processing/potion_brewing.nbt b/src/main/resources/data/create/structure/gametest/processing/potion_brewing.nbt new file mode 100644 index 0000000000000000000000000000000000000000..a93e6c942ca3e20107e30c1d803e18b4c62400b8 GIT binary patch literal 3360 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 bb3E54buaNeAF}dn*1#JvxbwT+w`}<@JcPhk literal 0 HcmV?d00001 diff --git a/src/main/resources/data/create/structure/gametest/processing/spout_crafting.nbt b/src/main/resources/data/create/structure/gametest/processing/spout_crafting.nbt new file mode 100644 index 0000000000000000000000000000000000000000..e7f272232d2048c5dba7e7429fc3c18f6a0ac9ba GIT binary patch literal 1763 zcmZ{gX)xOf7>8X;>Lyjk5)E~1wc{pB9E-4&w6UdIT3W|g^p7--P}gc~91WALo2sme zx~bBJ(4yLnAT+L0LQ+T2O4A~x*3!=G^vk{{8)bw-MW%-3AG2yX!q&9Wikdd3BDNwuUuoIX&S56p&}Qo;er4w4 zk&>-9!&#RyJ@v2i385S>^yKrLPBQs=9CMwn2e%{<7d2wkvPQ5V0;_@qf>ejH(IvWv@m?N|WIp4V zc^rmmowmb&OW(ImpTak1+TS!5{tx@<2Ic_eQ9rbbTw;BhL;?};BLW$DPYiMYaCUI56jI&|O;^w6b^g?+_=KrHPG z@Od%UN`og3HLZg_Sp77-)>pvAa`E#AA3HF*@B|q!X$3r#ACN))Kh0|ZGvJFYBLm2I zDLDl1oY)uq=Wyf+KoHFX2iwTWPnxLg$cqw_bNLF8Sgt+q0QVP#*djfhNw>JzMM^ z7K2I31*5M$9L#1AdlKy4(wDcEW#6-HxdO@XVN{MfH952Qb3O1aXeb2{>T zwk{+kdo@s4eg^#VFa)d7oBrKnrk~Igve5dzLF#t0B#*Hw(p)0Kn-+OJC-ngc?EOuD z*E%eZAj7-jxf~SO$-$Ekwetch(c(k%4*YD23Q~R%-8VaOr>X+*ZmDx+n#t}oLZ3wsvmJw7t zG5a#%>gLISh#dBL2PMXk%}VX-dcjzg+G+jDO;8HlwHn;h{YtRC{A905HhGu3=D#oC z7jE=$Pq=5NJgXF5kl=gjHWqLA&pc(H7!wVJxTh>Ik*#))yz;JbqWM z)r+$GhQ~81_Piw1sE+RnVrY4pUXnIqJ51AHcdfHSUb?iBf}3c?)zn1WvyaZZq|4zH z`jzZ6^dx80MhFbsnciyQ`0r<|6GIBDBB%0K6e(fjbFeGsMgL+fQqznynarpk;OL zHUh`O%Ytc2#Sx-imGVoi=YP>E4@&xeN-sS3rSLq3S%wuam51+;No&N-n?{y)_eLC| z1ik}Hi_~-H*5na#BX&hO}wqKchU39_Z7LY8w zu39{{wNFi5g5zrDqxh%}(b4gsgr9?)b9LY{*vaSYnwLDGOMefv-+4N*<8}_E#rt4H zgStnGL|dV53gcpxFCGgs^+1+Vz_&+O8js8DVT#iEIsWz-9Bq)AV38~pXq>gX=k$-< zaJT#J#$fwD!d=%rPy4LPM3zG^g^`UOQIr&{tu(Z*vA`KmB+}yIyY^3hTh8sI! zMydlBq)-Lk?&MA{yudlQb+NZ`JM8>ttL&-fq59Ro`#*a}o1Us;rRyf1jIo`Su)y#& Nv&~EmR`rC0{sk`RYMKB5 literal 0 HcmV?d00001