From 29083049323efdeb89fc69d033a5bd3826fef023 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 14:26:27 -0500 Subject: [PATCH 01/11] Upon preroll, destroy ranged ingredient. --- .../gtceu/api/recipe/GTRecipe.java | 21 ++- .../recipe/ingredient/IRangedIngredient.java | 4 +- .../IntProviderFluidIngredient.java | 7 +- .../ingredient/IntProviderIngredient.java | 7 +- .../IntProviderFluidIngredientTest.java | 129 ++---------------- .../ingredient/IntProviderIngredientTest.java | 125 ++--------------- 6 files changed, 50 insertions(+), 243 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index b336fbe3199..09d1214f3ae 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -235,10 +235,23 @@ public ChanceLogic getChanceLogicForCapability(RecipeCapability cap, IO io, b } public void doPrerolls(IdentityHashMap, Object2IntMap> chanceCaches) { - var rangedContents = getFullContents(); - for (Content item : rangedContents) { - if (item.content() instanceof IRangedIngredient ranged) - ranged.rollSampledCount(); + for (var handler : inputs.values()) { + for (var iterator = handler.listIterator(); iterator.hasNext();) { + var content = iterator.next(); + if (content.content() instanceof IRangedIngredient ranged) { + ranged.rollSampledCount(); + iterator.set(new Content(ranged.replace(), content.chance(), content.maxChance())); + } + } + } + for (var handler : outputs.values()) { + for (var iterator = handler.listIterator(); iterator.hasNext();) { + var content = iterator.next(); + if (content.content() instanceof IRangedIngredient ranged) { + ranged.rollSampledCount(); + iterator.set(new Content(ranged.replace(), content.chance(), content.maxChance())); + } + } } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java index 5f3575731bb..6d575e51744 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java @@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull; -public interface IRangedIngredient { +public interface IRangedIngredient { IntProvider getCountProvider(); @@ -15,6 +15,8 @@ public interface IRangedIngredient { void setSampledCount(int count); + T replace(); + /** * If this ingredient has not yet had its count rolled, rolls it and returns the roll. * If it has, returns the existing roll. diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java index 88b9e929175..ec8d46ac9e0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java @@ -28,7 +28,7 @@ * and either an {@link IntProvider} or {@code int, int} range bounds (inclusive). * Functions similarly to {@link IntProviderIngredient}. */ -public class IntProviderFluidIngredient extends FluidIngredient implements IRangedIngredient { +public class IntProviderFluidIngredient extends FluidIngredient implements IRangedIngredient { public static final Codec CODEC = ExtraCodecs.JSON .xmap(IntProviderFluidIngredient::fromJson, IntProviderFluidIngredient::toJson); @@ -156,6 +156,11 @@ public void setSampledCount(int count) { super.setAmount(count); } + @Override + public FluidIngredient replace() { + return new FluidIngredient(inner.values, getAmount(), inner.nbt); + } + /** * @param inner {@link FluidIngredient} * @param provider usually as {@link UniformInt#of(int, int)} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java index af9bafd5e11..1ef2fb4d5ae 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java @@ -33,7 +33,7 @@ * and an {@link IntProvider}. * Functions similarly to {@link IntProviderFluidIngredient}. */ -public class IntProviderIngredient extends Ingredient implements IRangedIngredient { +public class IntProviderIngredient extends Ingredient implements IRangedIngredient { public static final ResourceLocation TYPE = GTCEu.id("int_provider"); public static final ItemStack[] EMPTY_STACK_ARRAY = new ItemStack[0]; @@ -166,6 +166,11 @@ public void setSampledCount(int count) { this.setAmount(count); } + @Override + public SizedIngredient replace() { + return SizedIngredient.create(inner, getAmount()); + } + /** * Resets the random roll on this ingredient */ diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java index 1c500ea77c0..5cfc54c9193 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java @@ -32,6 +32,8 @@ import net.minecraftforge.gametest.GameTestHolder; import net.minecraftforge.gametest.PrefixGameTestTemplate; +import appeng.server.testworld.Test; + /** * Test cases: * Do many passes of most tests as a safeguard against bad rolls @@ -261,76 +263,6 @@ public static void rangedIngredientJsonTest(GameTestHelper helper) { helper.succeed(); } - // Test for singleblock machine with ranged fluid input. - // Forcibly sabotages the first recipe run, setting its output amount to 0 to ensure that doesn't break the recipe. - // This is specifically a test for #3593 / #3594 - @GameTest(template = "singleblock_charged_cr", batch = "RangedFluidIngredients") - public static void singleblockRangedFluidOutputSabotaged(GameTestHelper helper) { - SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( - helper.getBlockEntity(new BlockPos(0, 1, 0))); - - machine.setRecipeType(CR_RECIPE_TYPE); - NotifiableFluidTank fluidIn = (NotifiableFluidTank) machine - .getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP).get(0); - NotifiableFluidTank fluidOut = (NotifiableFluidTank) machine - .getCapabilitiesFlat(IO.OUT, FluidRecipeCapability.CAP).get(0); - - fluidIn.setFluidInTank(0, new FluidStack(CR_OUT, REPLICAS)); - // 1t to turn on, 2t per recipe run - // get the result of each roll independently - int[] addedRolls = new int[REPLICAS]; - - helper.runAfterDelay(2, () -> { - if (machine.getRecipeLogic().getLastRecipe().getOutputContents(FluidRecipeCapability.CAP).get(0) - .content() instanceof IntProviderFluidIngredient ingredient) { - ingredient.setSampledCount(0); - - if (ingredient.getSampledCount() != 0) { - helper.fail("Singleblock Ranged Fluid Output sabotage failed! " + - "Output count not was altered!"); - } - } else { - helper.fail("Singleblock Ranged Fluid Output sabotage failed! " + - "Recipe logic did not contain a Ranged Output!"); - } - }); - for (int i = 0; i < REPLICAS; i++) { - final int finalI = i; // lambda preserve you - helper.runAfterDelay(2 * i + 3, () -> { - addedRolls[finalI] = (int) fluidOut.getTotalContentAmount(); - }); - } - // check the results of all rolls together - helper.runAfterDelay(REPLICAS * 2 + 1, () -> { - FluidStack results = fluidOut.getFluidInTank(0); - helper.assertFalse((results.getAmount() == REPLICAS * 0), - "Sabotaged Singleblock CR rolled min value on every roll! " + - "This is the failure this sabotage was intended to induce."); - helper.assertFalse((results.getAmount() == REPLICAS * 9), - "Sabotaged Singleblock CR rolled max value on every roll (how??)"); - helper.assertTrue(TestUtils.isFluidWithinRange(results, REPLICAS, REPLICAS * 9), - "Sabotaged Singleblock CR didn't produce correct number of fluids, produced [" + - results.getAmount() + "] not [" + REPLICAS + "-" + (REPLICAS * 9) + "]"); - - // check if all the rolls were equal, but not min/max - int[] rolls = new int[REPLICAS]; - rolls[0] = addedRolls[0]; - boolean allEqual = false; - for (int i = 1; i < REPLICAS; i++) { - rolls[i] = addedRolls[i] - addedRolls[i - 1]; - if (rolls[i] == rolls[i - 1]) { - allEqual = true; - } else { - allEqual = false; - break; - } - } - helper.assertFalse(allEqual, - "Sabotaged Singleblock CR rolled the same value on every input roll (rolled " + rolls[0] + ")"); - helper.succeed(); - }); - } - // Failure Test for singleblock machine with ranged fluid input // Provides too little input fluid, should not run recipes. @GameTest(template = "singleblock_charged_cr", batch = "RangedFluidIngredients") @@ -379,7 +311,6 @@ public static void singleblockRangedFluidOutputPreroll(GameTestHelper helper) { fluidIn.setFluidInTank(0, new FluidStack(CR_OUT, REPLICAS)); // 1t to turn on, 2t per recipe run // get the result of each preroll independently - int[] prerolls = new int[REPLICAS]; for (int i = 0; i < REPLICAS; i++) { final int finalI = i; // lambda preserve you helper.runAfterDelay(2 * i + 1, () -> { @@ -388,31 +319,12 @@ public static void singleblockRangedFluidOutputPreroll(GameTestHelper helper) { var outputPrerolls = machine.recipeLogic.getLastRecipe().outputs.get(FluidRecipeCapability.CAP); helper.assertFalse(outputPrerolls.size() == 0, "Singleblock fluid CR Preroll's recipe output contained no fluids!"); - prerolls[finalI] = ((IRangedIngredient) (outputPrerolls.get(0).content())).getAmount();; - }); - } - // get the result of each roll independently - int[] addedRolls = new int[REPLICAS]; - for (int i = 0; i < REPLICAS; i++) { - final int finalI = i; // lambda preserve you - helper.runAfterDelay(2 * i + 3, () -> { - addedRolls[finalI] = fluidOut.getFluidInTank(0).getAmount(); + helper.assertFalse(outputPrerolls.get(0).content() instanceof IRangedIngredient, + "Singleblock fluid CR Preroll's recipe failed to preroll and replace its " + + "ranged ingredient!"); }); } - // check the results of all rolls together - helper.runAfterDelay(REPLICAS * 2 + 10, () -> { - // check if all the rolls were equal, but not min/max - int[] rolls = new int[REPLICAS]; - rolls[0] = addedRolls[0]; - helper.assertFalse(prerolls[0] != rolls[0], "Singleblock fluid CR Preroll failed on run 0"); - - for (int i = 1; i < REPLICAS; i++) { - rolls[i] = addedRolls[i] - addedRolls[i - 1]; - helper.assertFalse(prerolls[i] != rolls[i], - "Singleblock fluid CR Preroll failed on run [" + i + "]"); - } - helper.succeed(); - }); + TestUtils.succeedAfterTest(helper); } // Test for singleblock machine with ranged fluid input @@ -1100,7 +1012,6 @@ public static void multiblockLCentRangedFluidOutputPreroll16ParallelBatched(Game BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); final NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; - final NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; int batches = 16; int parallels = 16; @@ -1110,7 +1021,6 @@ public static void multiblockLCentRangedFluidOutputPreroll16ParallelBatched(Game fluidIn.setFluidInTank(0, new FluidStack(LCENT_OUT, batches * parallels)); // 1t to turn on, 64t per recipe run, 10t buffer for sanity - int[] prerolls = new int[MULTI_REPLICAS]; for (int i = 0; i < MULTI_REPLICAS; i++) { final int finalI = i; // lambda preserve you helper.runAfterDelay(75 * finalI + 20, () -> { @@ -1120,32 +1030,13 @@ public static void multiblockLCentRangedFluidOutputPreroll16ParallelBatched(Game .get(FluidRecipeCapability.CAP); helper.assertFalse(outputPrerolls.size() == 0, "Multiblock LCent fluid Preroll's recipe output contained no fluids!"); - prerolls[finalI] = ((IRangedIngredient) (outputPrerolls.get(0).content())).getAmount();; - }); - } - // check the results of all rolls together - // repeat recipe MULTI_REPLICAS times - int[] addedRolls = new int[MULTI_REPLICAS]; - for (int i = 1; i <= MULTI_REPLICAS; i++) { - final int finalI = i; // lambda preserve you - helper.runAfterDelay(75 * finalI, () -> { - addedRolls[finalI - 1] = fluidOut.getFluidInTank(0).getAmount(); + helper.assertFalse(outputPrerolls.get(0).content() instanceof IRangedIngredient, + "Multiblock LCent fluid Preroll's recipe failed to preroll and replace its " + + "ranged ingredient!"); // reset for a rerun fluidIn.setFluidInTank(0, new FluidStack(LCENT_OUT, batches * parallels)); }); } - - helper.runAfterDelay(1 + 75 * MULTI_REPLICAS, () -> { - int[] rolls = new int[MULTI_REPLICAS]; - rolls[0] = addedRolls[0]; - helper.assertFalse(prerolls[0] != rolls[0], "Multiblock LCent fluid Preroll failed on run 0"); - - for (int i = 1; i < MULTI_REPLICAS; i++) { - rolls[i] = addedRolls[i] - addedRolls[i - 1]; - helper.assertFalse(prerolls[i] != rolls[i], - "Multiblock LCent fluid Preroll failed on run [" + i + "]"); - } - helper.succeed(); - }); + TestUtils.succeedAfterTest(helper); } } diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java index 180207687bb..ad404501c3b 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java @@ -255,77 +255,6 @@ public static void rangedIngredientJsonTest(GameTestHelper helper) { helper.succeed(); } - // Test for singleblock machine with ranged item input. - // Forcibly sabotages the first recipe run, setting its output amount to 0 to ensure that doesn't break the recipe. - // This is specifically a test for #3593 / #3594 - @GameTest(template = "singleblock_charged_cr", batch = "RangedIngredients") - public static void singleblockRangedItemOutputSabotaged(GameTestHelper helper) { - SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( - helper.getBlockEntity(new BlockPos(0, 1, 0))); - - machine.setRecipeType(CR_RECIPE_TYPE); - NotifiableItemStackHandler itemIn = (NotifiableItemStackHandler) machine - .getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).get(0); - NotifiableItemStackHandler itemOut = (NotifiableItemStackHandler) machine - .getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).get(0); - - itemIn.setStackInSlot(0, CR_OUT.copyWithCount(REPLICAS)); - // 1t to turn on, 2t per recipe run - // get the result of each roll independently - int[] addedRolls = new int[REPLICAS]; - - helper.runAfterDelay(2, () -> { - if (machine.getRecipeLogic().getLastRecipe().getOutputContents(ItemRecipeCapability.CAP).get(0) - .content() instanceof IntProviderIngredient ingredient) { - ingredient.setSampledCount(0); - - if (ingredient.getSampledCount() != 0) { - helper.fail("Singleblock Ranged Item Output sabotage failed! " + - "Output count not was altered!"); - } - } else { - helper.fail("Singleblock Ranged Item Output sabotage failed! " + - "Recipe logic did not contain a Ranged Output!"); - } - }); - for (int i = 0; i < REPLICAS; i++) { - final int finalI = i; // lambda preserve you - helper.runAfterDelay(2 * i + 3, () -> { - addedRolls[finalI] = itemOut.getStackInSlot(0).getCount(); - }); - } - // check the results of all rolls together - helper.runAfterDelay(REPLICAS * 2 + 1, () -> { - ItemStack results = itemOut.getStackInSlot(0); - helper.assertFalse((results.getCount() == REPLICAS * 0), - "Sabotaged Singleblock CR rolled min value on every roll! " + - "This is the failure this sabotage was intended to induce."); - helper.assertFalse((results.getCount() == REPLICAS * 9), - "Sabotaged Singleblock CR rolled max value on every roll (how??)"); - - helper.assertTrue(TestUtils.isItemWithinRange(results, REPLICAS, REPLICAS * 9), - "Sabotaged Singleblock CR didn't produce correct number of items, produced [" + - results.getCount() + "] not [" + REPLICAS + "-" + (REPLICAS * 9) + "]"); - - // check if all the rolls were equal, but not min/max - int[] rolls = new int[REPLICAS]; - rolls[0] = addedRolls[0]; - boolean allEqual = false; - for (int i = 1; i < REPLICAS; i++) { - rolls[i] = addedRolls[i] - addedRolls[i - 1]; - if (rolls[i] == rolls[i - 1]) { - allEqual = true; - } else { - allEqual = false; - break; - } - } - helper.assertFalse(allEqual, - "Sabotaged Singleblock CR rolled the same value on every input roll (rolled " + rolls[0] + ")"); - helper.succeed(); - }); - } - // Failure Test for singleblock machine with ranged item input // Provides too few input items, should not run recipes. @GameTest(template = "singleblock_charged_cr", batch = "RangedIngredients") @@ -372,7 +301,6 @@ public static void singleblockRangedItemOutputPreroll(GameTestHelper helper) { itemIn.setStackInSlot(0, CR_OUT.copyWithCount(REPLICAS)); // 1t to turn on, 2t per recipe run // get the result of each preroll independently - int[] prerolls = new int[REPLICAS]; for (int i = 0; i < REPLICAS; i++) { final int finalI = i; // lambda preserve you helper.runAfterDelay(2 * i + 1, () -> { @@ -381,30 +309,12 @@ public static void singleblockRangedItemOutputPreroll(GameTestHelper helper) { var outputPrerolls = machine.recipeLogic.getLastRecipe().outputs.get(ItemRecipeCapability.CAP); helper.assertFalse(outputPrerolls.size() == 0, "Singleblock item CR Preroll's recipe output contained no items!"); - prerolls[finalI] = ((IRangedIngredient) (outputPrerolls.get(0).content())).getAmount();; - }); - } - // get the result of each roll independently - int[] addedRolls = new int[REPLICAS]; - for (int i = 0; i < REPLICAS; i++) { - final int finalI = i; // lambda preserve you - helper.runAfterDelay(2 * i + 3, () -> { - addedRolls[finalI] = itemOut.getStackInSlot(0).getCount(); + helper.assertFalse(outputPrerolls.get(0).content() instanceof IRangedIngredient, + "Singleblock item CR Preroll's recipe failed to preroll and replace its " + + "ranged ingredient!"); }); } - // check the results of all rolls together - helper.runAfterDelay(REPLICAS * 2 + 10, () -> { - // check if all the rolls matched their preroll - int[] rolls = new int[REPLICAS]; - rolls[0] = addedRolls[0]; - helper.assertFalse(prerolls[0] != rolls[0], "Singleblock item CR Preroll failed on run 0"); - for (int i = 1; i < REPLICAS; i++) { - rolls[i] = addedRolls[i] - addedRolls[i - 1]; - helper.assertFalse(prerolls[i] != rolls[i], - "Singleblock CR Preroll failed on run [" + i + "]"); - } - helper.succeed(); - }); + TestUtils.succeedAfterTest(helper); } // Test for singleblock machine with ranged item input @@ -1107,7 +1017,6 @@ public static void multiblockLCentRangedItemOutputPreroll16ParallelBatched(GameT // 1t to turn on, 64t per recipe run, 10t buffer for sanity // 16 parallels - int[] prerolls = new int[MULTI_REPLICAS]; for (int i = 0; i < MULTI_REPLICAS; i++) { final int finalI = i; // lambda preserve you helper.runAfterDelay(75 * finalI + 20, () -> { @@ -1117,17 +1026,9 @@ public static void multiblockLCentRangedItemOutputPreroll16ParallelBatched(GameT .get(ItemRecipeCapability.CAP); helper.assertFalse(outputPrerolls.size() == 0, "Multiblock LCent item Preroll's recipe output contained no items!"); - prerolls[finalI] = ((IRangedIngredient) (outputPrerolls.get(0).content())).getAmount();; - }); - } - // check the results of all rolls together - // repeat recipe MULTI_REPLICAS times - int[] rolls = new int[MULTI_REPLICAS]; - for (int i = 1; i <= MULTI_REPLICAS; i++) { - final int finalI = i; // lambda preserve you - helper.runAfterDelay(75 * finalI, () -> { - int resultCount = (int) Math.round(itemOut.getTotalContentAmount()); - rolls[finalI - 1] = resultCount; + helper.assertFalse(outputPrerolls.get(0).content() instanceof IRangedIngredient, + "Multiblock LCent item Preroll's recipe failed to preroll and replace its " + + "ranged ingredient!"); // reset for a rerun for (int j = 0; j < batches; j++) { @@ -1139,16 +1040,6 @@ public static void multiblockLCentRangedItemOutputPreroll16ParallelBatched(GameT } }); } - - helper.runAfterDelay(1 + 75 * MULTI_REPLICAS, () -> { - - helper.assertFalse(prerolls[0] != rolls[0], "Multiblock LCent item Preroll failed on run 0"); - - for (int i = 1; i < REPLICAS; i++) { - helper.assertFalse(prerolls[i] != rolls[i], - "Multiblock LCent item Preroll failed on run [" + i + "]"); - } - helper.succeed(); - }); + TestUtils.succeedAfterTest(helper); } } From aec1c65f4f321fa2c25229982797b3c70d3b5e55 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 14:49:30 -0500 Subject: [PATCH 02/11] Upon trying to illegally get the items of a ranged ingredient, Throw IllegalCallerException. TODO: replace this with something less destructive. --- .../recipe/ingredient/IRangedIngredient.java | 2 - .../IntProviderFluidIngredient.java | 43 +++----------- .../ingredient/IntProviderIngredient.java | 58 ++++--------------- .../IntProviderFluidIngredientTest.java | 2 - 4 files changed, 17 insertions(+), 88 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java index 6d575e51744..881f1f34b6e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java @@ -30,8 +30,6 @@ default int rollSampledCount() { int rollSampledCount(@NotNull RandomSource random); - int getAmount(); - /** * @return the average roll of this ranged amount */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java index ec8d46ac9e0..c598b07a40a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java @@ -38,6 +38,7 @@ public class IntProviderFluidIngredient extends FluidIngredient implements IRang /** * The last result of {@link IntProviderFluidIngredient#getSampledCount()}. -1 if not rolled. */ + @Setter @Getter protected int sampledCount = -1; /** @@ -45,14 +46,11 @@ public class IntProviderFluidIngredient extends FluidIngredient implements IRang */ @Getter private final FluidIngredient inner; - @Setter - protected FluidStack[] fluidStacks = null; protected IntProviderFluidIngredient(FluidIngredient inner, IntProvider provider) { super(inner.values, provider.getMaxValue(), inner.nbt); this.inner = inner; this.countProvider = provider; - setAmount(provider.getMaxValue()); } protected IntProviderFluidIngredient(FluidIngredient inner, IntProvider provider, int sampledCount) { @@ -60,20 +58,18 @@ protected IntProviderFluidIngredient(FluidIngredient inner, IntProvider provider this.inner = inner; this.countProvider = provider; this.sampledCount = sampledCount; - setAmount(isRolled() ? sampledCount : provider.getMaxValue()); } @Override public IntProviderFluidIngredient copy() { IntProviderFluidIngredient ipfi = new IntProviderFluidIngredient(this.inner, this.countProvider); ipfi.setSampledCount(this.sampledCount); - ipfi.setAmount(this.getAmount()); return ipfi; } @Override public boolean isEmpty() { - return this.getAmount() == 0 || super.isEmpty(); + return inner.isEmpty(); } /** @@ -84,23 +80,7 @@ public boolean isEmpty() { */ @Override public FluidStack[] getStacks() { - if (changed || fluidStacks == null) { - changed = false; - if (!isRolled()) { - setAmount(rollSampledCount()); - if (getAmount() == 0) { - fluidStacks = EMPTY_STACK_ARRAY; - return EMPTY_STACK_ARRAY; - } - } - var innerStacks = inner.getStacks(); - this.fluidStacks = new FluidStack[innerStacks.length]; - for (int i = 0; i < fluidStacks.length; i++) { - fluidStacks[i] = innerStacks[i].copy(); - fluidStacks[i].setAmount(getAmount()); - } - } - return fluidStacks; + throw new IllegalCallerException("can't Get Fluids of a ranged ingredient"); } /** @@ -127,9 +107,8 @@ public FluidStack[] getStacks() { public int rollSampledCount(@NotNull RandomSource random) { if (!isRolled()) { sampledCount = countProvider.sample(random); - this.setAmount(sampledCount); } - return getAmount(); + return sampledCount; } /** @@ -144,21 +123,13 @@ public double getMidRoll() { */ public void reset() { sampledCount = -1; - super.setAmount(getMaxRoll()); - fluidStacks = null; - } - - /** - * Also sets the Amount of this ingredient - */ - public void setSampledCount(int count) { - this.sampledCount = count; - super.setAmount(count); } @Override public FluidIngredient replace() { - return new FluidIngredient(inner.values, getAmount(), inner.nbt); + if (!isRolled()) + throw new IllegalCallerException("Ranged Ingredient was replaced without being rolled!"); + return new FluidIngredient(inner.values, getSampledCount(), inner.nbt); } /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java index 1ef2fb4d5ae..1ffd729e6c1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java @@ -43,6 +43,7 @@ public class IntProviderIngredient extends Ingredient implements IRangedIngredie /** * The last result of {@link IntProviderIngredient#rollSampledCount(RandomSource)}. -1 if not rolled. */ + @Setter @Getter protected int sampledCount = -1; /** @@ -50,29 +51,22 @@ public class IntProviderIngredient extends Ingredient implements IRangedIngredie */ @Getter protected final Ingredient inner; - @Setter - protected ItemStack[] itemStacks = null; - @Getter - private int amount; - private boolean changed = true; protected IntProviderIngredient(Ingredient inner, IntProvider countProvider) { super(Stream.empty()); this.inner = inner; this.countProvider = countProvider; - this.amount = getMaxRoll(); } - protected IntProviderIngredient(Ingredient inner, IntProvider countProvider, int sampledCount, int amount) { + protected IntProviderIngredient(Ingredient inner, IntProvider countProvider, int sampledCount) { super(Stream.empty()); this.inner = inner; this.countProvider = countProvider; this.sampledCount = sampledCount; - this.amount = amount; } public IntProviderIngredient copy() { - return new IntProviderIngredient(this.inner, this.countProvider, this.sampledCount, this.amount); + return new IntProviderIngredient(this.inner, this.countProvider, this.sampledCount); } /** @@ -107,28 +101,9 @@ public boolean test(@Nullable ItemStack stack) { */ @Override public ItemStack @NotNull [] getItems() { - if (changed || itemStacks == null) { - changed = false; - if (!isRolled()) { - setAmount(rollSampledCount()); - if (getAmount() == 0) { - itemStacks = EMPTY_STACK_ARRAY; - return EMPTY_STACK_ARRAY; - } - } - var innerStacks = inner.getItems(); - this.itemStacks = new ItemStack[innerStacks.length]; - for (int i = 0; i < itemStacks.length; i++) { - itemStacks[i] = innerStacks[i].copyWithCount(getAmount()); - } - } - return itemStacks; + throw new IllegalCallerException("can't Get Items of a ranged ingredient"); } - public void setAmount(int amount) { - this.amount = amount; - this.changed = true; - } /** * Gets a {@link ItemStack} containing the maximum possible output from this {@link IntProviderIngredient}. @@ -153,22 +128,15 @@ public void setAmount(int amount) { public int rollSampledCount(@NotNull RandomSource random) { if (!isRolled()) { sampledCount = countProvider.sample(random); - this.setAmount(sampledCount); } return sampledCount; } - /** - * Also sets the Amount of this ingredient - */ - public void setSampledCount(int count) { - this.sampledCount = count; - this.setAmount(count); - } - @Override public SizedIngredient replace() { - return SizedIngredient.create(inner, getAmount()); + if (!isRolled()) + throw new IllegalCallerException("Ranged Ingredient was replaced without being rolled!"); + return SizedIngredient.create(inner, getSampledCount()); } /** @@ -176,8 +144,6 @@ public SizedIngredient replace() { */ public void reset() { sampledCount = -1; - setAmount(getMaxRoll()); - itemStacks = null; } @Override @@ -187,7 +153,7 @@ public void reset() { @Override public boolean isEmpty() { - return this.getAmount() == 0 || inner.isEmpty(); + return inner.isEmpty(); } @Override @@ -224,7 +190,6 @@ public static IntProviderIngredient fromJson(JsonObject json) { .getOrThrow(false, GTCEu.LOGGER::error)); json.add("ingredient", inner.toJson()); json.addProperty("sampledCount", sampledCount); - json.addProperty("amount", amount); return json; } @@ -236,8 +201,7 @@ public static IntProviderIngredient fromJson(JsonObject json) { IntProvider provider = IntProvider.CODEC.parse(NbtOps.INSTANCE, nbt.get("provider")) .getOrThrow(false, GTCEu.LOGGER::error); int sampledCount = nbt.getInt("sampledCount"); - int amount = nbt.getInt("amount"); - return new IntProviderIngredient(Ingredient.fromNetwork(buffer), provider, sampledCount, amount); + return new IntProviderIngredient(Ingredient.fromNetwork(buffer), provider, sampledCount); } @Override @@ -246,8 +210,7 @@ public static IntProviderIngredient fromJson(JsonObject json) { .getOrThrow(false, GTCEu.LOGGER::error); Ingredient inner = Ingredient.fromJson(json.get("ingredient")); int sampledCount = json.getAsJsonPrimitive("sampledCount").getAsInt(); - int amount = json.getAsJsonPrimitive("amount").getAsInt(); - return new IntProviderIngredient(inner, provider, sampledCount, amount); + return new IntProviderIngredient(inner, provider, sampledCount); } @Override @@ -256,7 +219,6 @@ public void write(FriendlyByteBuf buffer, IntProviderIngredient ingredient) { wrapper.put("provider", IntProvider.CODEC.encodeStart(NbtOps.INSTANCE, ingredient.countProvider) .getOrThrow(false, GTCEu.LOGGER::error)); wrapper.putInt("sampledCount", ingredient.sampledCount); - wrapper.putInt("amount", ingredient.amount); buffer.writeNbt(wrapper); ingredient.inner.toNetwork(buffer); } diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java index 5cfc54c9193..46cf505a804 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java @@ -32,8 +32,6 @@ import net.minecraftforge.gametest.GameTestHolder; import net.minecraftforge.gametest.PrefixGameTestTemplate; -import appeng.server.testworld.Test; - /** * Test cases: * Do many passes of most tests as a safeguard against bad rolls From bf48c2a7987aa0776088fe6023714435c692bd42 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 16:02:01 -0500 Subject: [PATCH 03/11] fix tests --- .../IntProviderFluidIngredientTest.java | 53 +++++------------- .../ingredient/IntProviderIngredientTest.java | 56 ++++++------------- 2 files changed, 29 insertions(+), 80 deletions(-) diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java index 46cf505a804..0ec322dd2af 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java @@ -217,47 +217,20 @@ public static void rangedFluidIngredientTestEqualTest(GameTestHelper helper) { @GameTest(template = "empty", batch = "RangedFluidIngredients") public static void rangedFluidIngredientGetStacksTest(GameTestHelper helper) { var ingredient = IntProviderFluidIngredient.of(GTMaterials.Water.getFluid(1), 1, 500000); - var stacks = ingredient.getStacks(); - helper.assertTrue(stacks.length == 1, - "IntProviderFluidIngredient should only return 1 fluid when made with 1 fluid"); + try{ + ingredient.getStacks(); + helper.fail("A ranged fluid ingredient should not return fluids!"); + }catch (IllegalCallerException ignored){} + try{ + ingredient.replace().getStacks(); + helper.fail("A ranged fluid ingredient cannot be replaced without being rolled!"); + }catch (IllegalCallerException ignored){} + ingredient.rollSampledCount(); + var stacks = ingredient.replace().getStacks(); + helper.assertTrue(stacks.length == 1, "Replaced IntProviderFluidIngredient should only " + + "return 1 fluid when made with 1 fluid"); helper.assertTrue(stacks[0].isFluidEqual(GTMaterials.Water.getFluid(1)), - "IntProviderFluidIngredient should have fluid equal to what it was made with"); - helper.assertTrue(stacks[0].isFluidStackIdentical(ingredient.getStacks()[0]), - "IntProviderFluidIngredient.getStacks shouldn't change between getStacks calls"); - ingredient.reset(); - helper.assertFalse(stacks[0].isFluidStackIdentical(ingredient.getStacks()[0]), - "IntProviderFluidIngredient.getStacks should have changed after rerolling"); - helper.succeed(); - } - - // test for IntProviderFluidIngredient.toJson() - @GameTest(template = "empty", batch = "RangedFluidIngredients") - public static void rangedIngredientJsonTest(GameTestHelper helper) { - var ingredient = IntProviderFluidIngredient.of(GTMaterials.Water.getFluid(1), 1, 500000); - - // serialize/deserialize before rolling count - var jsonPreRoll = ingredient.toJson(); - var ingredientDeserializedPreRoll = IntProviderFluidIngredient.fromJson(jsonPreRoll); - - var stacks = ingredient.getStacks(); - var stacksDeserializedPreRoll = ingredientDeserializedPreRoll.getStacks(); - - // serialize/deserialize after rolling count - var jsonPostRoll = ingredient.toJson(); - var ingredientDeserializedPostRoll = IntProviderFluidIngredient.fromJson(jsonPostRoll); - var stacksDeserializedPostRoll = ingredientDeserializedPostRoll.getStacks(); - - helper.assertTrue( - stacks.length == stacksDeserializedPreRoll.length && stacks.length == stacksDeserializedPostRoll.length, - "IntProviderFluidIngredient should only return 1 fluid when made with 1 fluid, even after serializing"); - helper.assertTrue(stacksDeserializedPreRoll[0].isFluidEqual(GTMaterials.Water.getFluid(1)), - "IntProviderFluidIngredient should have fluid equal to what it was made with after serializing"); - helper.assertTrue(stacksDeserializedPostRoll[0].isFluidEqual(GTMaterials.Water.getFluid(1)), - "IntProviderFluidIngredient should have fluid equal to what it was made with after serializing"); - helper.assertFalse(TestUtils.areFluidStacksEqual(stacksDeserializedPreRoll, ingredient.getStacks()), - "IntProviderFluidIngredient.getStacks should be different if it wasn't rolled before serializing"); - helper.assertTrue(TestUtils.areFluidStacksEqual(stacksDeserializedPostRoll, ingredient.getStacks()), - "IntProviderFluidIngredient.getStacks shouldn't change between getStacks calls if it was rolled before serializing"); + "Replaced IntProviderFluidIngredient should have fluid equal to what it was made with"); helper.succeed(); } diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java index ad404501c3b..3f78a954437 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java @@ -16,10 +16,12 @@ import com.gregtechceu.gtceu.common.machine.multiblock.part.ParallelHatchPartMachine; import com.gregtechceu.gtceu.gametest.util.TestUtils; +import io.netty.buffer.ByteBuf; import net.minecraft.core.BlockPos; import net.minecraft.gametest.framework.BeforeBatch; import net.minecraft.gametest.framework.GameTest; import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.world.item.ItemStack; @@ -208,50 +210,24 @@ public static void rangedIngredientTestEqualTest(GameTestHelper helper) { helper.succeed(); } - // test for IntProviderIngredient.getStacks() + // test for IntProviderIngredient.replace().getStacks() @GameTest(template = "empty", batch = "RangedIngredients") public static void rangedIngredientGetStacksTest(GameTestHelper helper) { var ingredient = IntProviderIngredient.of(new ItemStack(Items.BRICK, 1), UniformInt.of(1, 5000)); - var stacks = ingredient.getItems(); - helper.assertTrue(stacks.length == 1, "IntProviderIngredient should only return 1 item when made with 1 item"); + try{ + ingredient.getItems(); + helper.fail("A ranged ingredient should not return items!"); + }catch (IllegalCallerException ignored){} + try{ + ingredient.replace().getItems(); + helper.fail("A ranged ingredient cannot be replaced without being rolled!"); + }catch (IllegalCallerException ignored){} + ingredient.rollSampledCount(); + var stacks = ingredient.replace().getItems(); + helper.assertTrue(stacks.length == 1, "Replaced IntProviderIngredient should only " + + "return 1 item when made with 1 item"); helper.assertTrue(stacks[0].is(new ItemStack(Items.BRICK, 1).getItem()), - "IntProviderIngredient should have item equal to what it was made with"); - helper.assertTrue(TestUtils.areItemStacksEqual(stacks, ingredient.getItems()), - "IntProviderIngredient.getItems shouldn't change between getStacks calls"); - ingredient.reset(); - helper.assertFalse(TestUtils.areItemStacksEqual(stacks, ingredient.getItems()), - "IntProviderIngredient.getItems should have changed after rerolling"); - helper.succeed(); - } - - // test for IntProviderIngredient.toJson() - @GameTest(template = "empty", batch = "RangedIngredients") - public static void rangedIngredientJsonTest(GameTestHelper helper) { - var ingredient = IntProviderIngredient.of(new ItemStack(Items.BRICK, 1), UniformInt.of(1, 5000)); - - // serialize/deserialize before rolling count - var jsonPreRoll = ingredient.toJson(); - var ingredientDeserializedPreRoll = IntProviderIngredient.fromJson(jsonPreRoll); - - var stacks = ingredient.getItems(); - var stacksDeserializedPreRoll = ingredientDeserializedPreRoll.getItems(); - - // serialize/deserialize after rolling count - var jsonPostRoll = ingredient.toJson(); - var ingredientDeserializedPostRoll = IntProviderIngredient.fromJson(jsonPostRoll); - var stacksDeserializedPostRoll = ingredientDeserializedPostRoll.getItems(); - - helper.assertTrue( - stacks.length == stacksDeserializedPreRoll.length && stacks.length == stacksDeserializedPostRoll.length, - "IntProviderIngredient should only return 1 item when made with 1 item, even after serializing"); - helper.assertTrue(stacksDeserializedPreRoll[0].is(new ItemStack(Items.BRICK, 1).getItem()), - "IntProviderIngredient should have item equal to what it was made with after serializing"); - helper.assertTrue(stacksDeserializedPostRoll[0].is(new ItemStack(Items.BRICK, 1).getItem()), - "IntProviderIngredient should have item equal to what it was made with after serializing"); - helper.assertFalse(TestUtils.areItemStacksEqual(stacksDeserializedPreRoll, ingredient.getItems()), - "IntProviderIngredient.getItems should be different if it wasn't rolled before serializing"); - helper.assertTrue(TestUtils.areItemStacksEqual(stacksDeserializedPostRoll, ingredient.getItems()), - "IntProviderIngredient.getItems shouldn't change between getItems calls if it was rolled before serializing"); + "Replaced IntProviderIngredient should have item equal to what it was made with"); helper.succeed(); } From 5a51f80522a4a10c755685a72f5d99f9846f8dce Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 16:24:38 -0500 Subject: [PATCH 04/11] revert a few getMaxRoll() checks. Spotless. --- .../api/capability/recipe/FluidRecipeCapability.java | 4 +++- .../com/gregtechceu/gtceu/api/recipe/RecipeHelper.java | 4 +++- .../api/recipe/ingredient/IntProviderIngredient.java | 1 - .../multiblock/electric/AssemblyLineMachine.java | 5 ++++- .../multiblock/electric/DistillationTowerMachine.java | 4 ++-- .../kjs/recipe/components/GTRecipeComponents.java | 4 +++- .../ingredient/IntProviderFluidIngredientTest.java | 8 ++++---- .../recipe/ingredient/IntProviderIngredientTest.java | 10 ++++------ 8 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java index 7754859593a..1db210ce895 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java @@ -179,7 +179,9 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe for (Content content : inputs) { FluidIngredient ing = of(content.content()); - int amount = ing.getAmount(); + int amount; + if (ing instanceof IRangedIngredient provider) amount = provider.getMaxRoll(); + else amount = ing.getAmount(); if (content.chance() == 0) { nonConsumables.addTo(ing, amount); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index 1648ecf4537..b8ebc067ba1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -11,6 +11,7 @@ import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.EnergyStack; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; +import com.gregtechceu.gtceu.api.recipe.ingredient.IRangedIngredient; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; import com.gregtechceu.gtceu.utils.GTUtil; @@ -400,6 +401,7 @@ public static int getRatioForDistillery(FluidIngredient fluidInput, FluidIngredi } public static boolean isFluidStackDivisibleForDistillery(FluidIngredient fluidStack, int divisor) { - return fluidStack.getAmount() % divisor == 0 && fluidStack.getAmount() / divisor >= 25; + int amount = (fluidStack instanceof IRangedIngredient ranged ? ranged.getMaxRoll() : fluidStack.getAmount()); + return amount % divisor == 0 && amount / divisor >= 25; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java index 1ffd729e6c1..bc01557dc79 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java @@ -104,7 +104,6 @@ public boolean test(@Nullable ItemStack stack) { throw new IllegalCallerException("can't Get Items of a ranged ingredient"); } - /** * Gets a {@link ItemStack} containing the maximum possible output from this {@link IntProviderIngredient}. * Mainly used for things like Recipe provider simulations to see if there is enough inventory space to handle diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java index b652cf42cea..23748c9bec8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java @@ -18,6 +18,7 @@ import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; +import com.gregtechceu.gtceu.api.recipe.ingredient.IRangedIngredient; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.config.ConfigHolder; @@ -152,7 +153,9 @@ private boolean checkFluidInputs(GTRecipe recipe, boolean isTick) { for (int i = 0; i < inputsSize; i++) { var fluidStack = fluidInventory.get(i); FluidIngredient recipeStack = FluidRecipeCapability.CAP.of(fluidInputs.get(i).content()); - if (!recipeStack.test(fluidStack) || (recipeStack.getAmount()) > fluidStack.getAmount()) { + if (!recipeStack.test(fluidStack) || + (recipeStack instanceof IRangedIngredient ? ((IRangedIngredient) recipeStack).getMaxRoll() : + recipeStack.getAmount()) > fluidStack.getAmount()) { return false; } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index 19e6c5ebeba..355f0084e1a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -13,7 +13,7 @@ import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; -import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; +import com.gregtechceu.gtceu.api.recipe.ingredient.IRangedIngredient; import com.gregtechceu.gtceu.api.recipe.modifier.ParallelLogic; import com.gregtechceu.gtceu.api.sync_system.annotations.SaveField; import com.gregtechceu.gtceu.api.sync_system.annotations.SyncToClient; @@ -141,7 +141,7 @@ public int limitFluidParallel(GTRecipe recipe, int multiplier, boolean tick) { .map(Content::content) .map(FluidRecipeCapability.CAP::of) .filter(i -> !i.isEmpty()) - .mapToInt(FluidIngredient::getAmount) + .mapToInt((i -> i instanceof IRangedIngredient ? ((IRangedIngredient) i).getMaxRoll() : i.getAmount())) .max() .orElse(0); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/GTRecipeComponents.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/GTRecipeComponents.java index 474708c1fc3..1f3aa7b27da 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/GTRecipeComponents.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/GTRecipeComponents.java @@ -8,6 +8,7 @@ import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.ingredient.EnergyStack; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; +import com.gregtechceu.gtceu.api.recipe.ingredient.IRangedIngredient; import com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderFluidIngredient; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.common.data.GTRecipeCapabilities; @@ -400,7 +401,8 @@ public FluidIngredientJS(Fluid fluid, int amount, @Nullable CompoundTag nbt) { @Override public long kjs$getAmount() { - return ingredient.getAmount(); + return (ingredient instanceof IRangedIngredient ? ((IRangedIngredient) ingredient).getMaxRoll() : + ingredient.getAmount()); } @Override diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java index 0ec322dd2af..0c9656b4bd5 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java @@ -217,14 +217,14 @@ public static void rangedFluidIngredientTestEqualTest(GameTestHelper helper) { @GameTest(template = "empty", batch = "RangedFluidIngredients") public static void rangedFluidIngredientGetStacksTest(GameTestHelper helper) { var ingredient = IntProviderFluidIngredient.of(GTMaterials.Water.getFluid(1), 1, 500000); - try{ + try { ingredient.getStacks(); helper.fail("A ranged fluid ingredient should not return fluids!"); - }catch (IllegalCallerException ignored){} - try{ + } catch (IllegalCallerException ignored) {} + try { ingredient.replace().getStacks(); helper.fail("A ranged fluid ingredient cannot be replaced without being rolled!"); - }catch (IllegalCallerException ignored){} + } catch (IllegalCallerException ignored) {} ingredient.rollSampledCount(); var stacks = ingredient.replace().getStacks(); helper.assertTrue(stacks.length == 1, "Replaced IntProviderFluidIngredient should only " + diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java index 3f78a954437..e0d811c6b53 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java @@ -16,12 +16,10 @@ import com.gregtechceu.gtceu.common.machine.multiblock.part.ParallelHatchPartMachine; import com.gregtechceu.gtceu.gametest.util.TestUtils; -import io.netty.buffer.ByteBuf; import net.minecraft.core.BlockPos; import net.minecraft.gametest.framework.BeforeBatch; import net.minecraft.gametest.framework.GameTest; import net.minecraft.gametest.framework.GameTestHelper; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.world.item.ItemStack; @@ -214,14 +212,14 @@ public static void rangedIngredientTestEqualTest(GameTestHelper helper) { @GameTest(template = "empty", batch = "RangedIngredients") public static void rangedIngredientGetStacksTest(GameTestHelper helper) { var ingredient = IntProviderIngredient.of(new ItemStack(Items.BRICK, 1), UniformInt.of(1, 5000)); - try{ + try { ingredient.getItems(); helper.fail("A ranged ingredient should not return items!"); - }catch (IllegalCallerException ignored){} - try{ + } catch (IllegalCallerException ignored) {} + try { ingredient.replace().getItems(); helper.fail("A ranged ingredient cannot be replaced without being rolled!"); - }catch (IllegalCallerException ignored){} + } catch (IllegalCallerException ignored) {} ingredient.rollSampledCount(); var stacks = ingredient.replace().getItems(); helper.assertTrue(stacks.length == 1, "Replaced IntProviderIngredient should only " + From 52208b5b17e14d2607e283a77900b5e3b023ff63 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 16:44:38 -0500 Subject: [PATCH 05/11] replace throw with logger.warn --- .../recipe/ingredient/IntProviderFluidIngredient.java | 7 ++++--- .../api/recipe/ingredient/IntProviderIngredient.java | 7 ++++--- .../ingredient/IntProviderFluidIngredientTest.java | 11 +++-------- .../recipe/ingredient/IntProviderIngredientTest.java | 11 +++-------- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java index c598b07a40a..982bdb90f58 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java @@ -80,7 +80,8 @@ public boolean isEmpty() { */ @Override public FluidStack[] getStacks() { - throw new IllegalCallerException("can't Get Fluids of a ranged ingredient"); + GTCEu.LOGGER.warn("Cannot get stacks of a Ranged Fluid Ingredient!"); + return EMPTY_STACK_ARRAY; } /** @@ -128,8 +129,8 @@ public void reset() { @Override public FluidIngredient replace() { if (!isRolled()) - throw new IllegalCallerException("Ranged Ingredient was replaced without being rolled!"); - return new FluidIngredient(inner.values, getSampledCount(), inner.nbt); + GTCEu.LOGGER.warn("Ranged fluid ingredient was replaced without being rolled!"); + return new FluidIngredient(inner.values, rollSampledCount(), inner.nbt); } /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java index bc01557dc79..0225419ecc8 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java @@ -101,7 +101,8 @@ public boolean test(@Nullable ItemStack stack) { */ @Override public ItemStack @NotNull [] getItems() { - throw new IllegalCallerException("can't Get Items of a ranged ingredient"); + GTCEu.LOGGER.warn("Cannot get items of a Ranged Ingredient!"); + return EMPTY_STACK_ARRAY; } /** @@ -134,8 +135,8 @@ public int rollSampledCount(@NotNull RandomSource random) { @Override public SizedIngredient replace() { if (!isRolled()) - throw new IllegalCallerException("Ranged Ingredient was replaced without being rolled!"); - return SizedIngredient.create(inner, getSampledCount()); + GTCEu.LOGGER.warn("Ranged ingredient was replaced without being rolled!"); + return SizedIngredient.create(inner, rollSampledCount()); } /** diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java index 0c9656b4bd5..008e289730d 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java @@ -217,14 +217,9 @@ public static void rangedFluidIngredientTestEqualTest(GameTestHelper helper) { @GameTest(template = "empty", batch = "RangedFluidIngredients") public static void rangedFluidIngredientGetStacksTest(GameTestHelper helper) { var ingredient = IntProviderFluidIngredient.of(GTMaterials.Water.getFluid(1), 1, 500000); - try { - ingredient.getStacks(); - helper.fail("A ranged fluid ingredient should not return fluids!"); - } catch (IllegalCallerException ignored) {} - try { - ingredient.replace().getStacks(); - helper.fail("A ranged fluid ingredient cannot be replaced without being rolled!"); - } catch (IllegalCallerException ignored) {} + // This will print a "Cannot get stacks" warning to the log. Ignore it. + helper.assertFalse(ingredient.getStacks().length == 0, "A ranged fluid ingredient " + + "should not return items!"); ingredient.rollSampledCount(); var stacks = ingredient.replace().getStacks(); helper.assertTrue(stacks.length == 1, "Replaced IntProviderFluidIngredient should only " + diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java index e0d811c6b53..838e1763faf 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java @@ -212,14 +212,9 @@ public static void rangedIngredientTestEqualTest(GameTestHelper helper) { @GameTest(template = "empty", batch = "RangedIngredients") public static void rangedIngredientGetStacksTest(GameTestHelper helper) { var ingredient = IntProviderIngredient.of(new ItemStack(Items.BRICK, 1), UniformInt.of(1, 5000)); - try { - ingredient.getItems(); - helper.fail("A ranged ingredient should not return items!"); - } catch (IllegalCallerException ignored) {} - try { - ingredient.replace().getItems(); - helper.fail("A ranged ingredient cannot be replaced without being rolled!"); - } catch (IllegalCallerException ignored) {} + // This will print a "Cannot get items" warning to the log. Ignore it. + helper.assertFalse(ingredient.getItems().length == 0, "A ranged ingredient " + + "should not return items!"); ingredient.rollSampledCount(); var stacks = ingredient.replace().getItems(); helper.assertTrue(stacks.length == 1, "Replaced IntProviderIngredient should only " + From ec749f2e9cfa460ade95fdac514a3e0365939256 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 16:47:25 -0500 Subject: [PATCH 06/11] no, that's true. --- .../api/recipe/ingredient/IntProviderFluidIngredientTest.java | 2 +- .../gtceu/api/recipe/ingredient/IntProviderIngredientTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java index 008e289730d..5007df41faa 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java @@ -218,7 +218,7 @@ public static void rangedFluidIngredientTestEqualTest(GameTestHelper helper) { public static void rangedFluidIngredientGetStacksTest(GameTestHelper helper) { var ingredient = IntProviderFluidIngredient.of(GTMaterials.Water.getFluid(1), 1, 500000); // This will print a "Cannot get stacks" warning to the log. Ignore it. - helper.assertFalse(ingredient.getStacks().length == 0, "A ranged fluid ingredient " + + helper.assertTrue(ingredient.getStacks().length == 0, "A ranged fluid ingredient " + "should not return items!"); ingredient.rollSampledCount(); var stacks = ingredient.replace().getStacks(); diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java index 838e1763faf..30f4f11e785 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java @@ -213,7 +213,7 @@ public static void rangedIngredientTestEqualTest(GameTestHelper helper) { public static void rangedIngredientGetStacksTest(GameTestHelper helper) { var ingredient = IntProviderIngredient.of(new ItemStack(Items.BRICK, 1), UniformInt.of(1, 5000)); // This will print a "Cannot get items" warning to the log. Ignore it. - helper.assertFalse(ingredient.getItems().length == 0, "A ranged ingredient " + + helper.assertTrue(ingredient.getItems().length == 0, "A ranged ingredient " + "should not return items!"); ingredient.rollSampledCount(); var stacks = ingredient.replace().getItems(); From 5221677c85bbc9c2aa511f4097bec5280b8710d9 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 19:10:09 -0500 Subject: [PATCH 07/11] genericize the error --- .../gtceu/api/recipe/ingredient/IRangedIngredient.java | 7 ++++++- .../api/recipe/ingredient/IntProviderFluidIngredient.java | 3 +-- .../gtceu/api/recipe/ingredient/IntProviderIngredient.java | 3 +-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java index 881f1f34b6e..44221770e07 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.recipe.ingredient; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; import net.minecraft.util.RandomSource; @@ -15,7 +16,11 @@ public interface IRangedIngredient { void setSampledCount(int count); - T replace(); + default T replace(){ + if (!isRolled()) + GTCEu.LOGGER.warn("Ranged ingredient was replaced without being rolled!"); + return null; + } /** * If this ingredient has not yet had its count rolled, rolls it and returns the roll. diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java index 982bdb90f58..1898697771f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java @@ -128,8 +128,7 @@ public void reset() { @Override public FluidIngredient replace() { - if (!isRolled()) - GTCEu.LOGGER.warn("Ranged fluid ingredient was replaced without being rolled!"); + IRangedIngredient.super.replace(); return new FluidIngredient(inner.values, rollSampledCount(), inner.nbt); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java index 0225419ecc8..09110469f6d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java @@ -134,8 +134,7 @@ public int rollSampledCount(@NotNull RandomSource random) { @Override public SizedIngredient replace() { - if (!isRolled()) - GTCEu.LOGGER.warn("Ranged ingredient was replaced without being rolled!"); + IRangedIngredient.super.replace(); return SizedIngredient.create(inner, rollSampledCount()); } From a4310ab742bb7df122fbac02767a5608a8502e54 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 19:14:58 -0500 Subject: [PATCH 08/11] Properly handle per-tick ingredient prerolls. I feel like this could be done more efficiently. --- .../gtceu/api/machine/trait/RecipeLogic.java | 8 ++++- .../gtceu/api/recipe/GTRecipe.java | 35 ++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index ba498a83020..7886c63ec2c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -400,7 +400,13 @@ public ActionResult handleTickRecipe(GTRecipe recipe) { var result = RecipeHelper.matchTickRecipe(getRLMachine(), recipe); if (!result.isSuccess()) return result; - recipe.doTickPrerolls(this.chanceCaches); + if (lastDisplayedRecipe == null) { + GTCEu.LOGGER.warn("Last Displayed Recipe is null! Ingredients may roll incorrectly."); + this.lastDisplayedRecipe = lastRecipe.copy(); + syncDataHolder.markClientSyncFieldDirty("lastDisplayedRecipe"); + markLastRecipeDirty(); + } + recipe.doTickPrerolls(this.chanceCaches, this.lastDisplayedRecipe); result = handleTickRecipeIO(recipe, IO.IN); if (!result.isSuccess()) return result; diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index 09d1214f3ae..20e079bcea4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.recipe; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; @@ -255,11 +256,35 @@ public void doPrerolls(IdentityHashMap, Object2IntMap> ch } } - public void doTickPrerolls(IdentityHashMap, Object2IntMap> chanceCaches) { - var rangedContents = getFullTickContents(); - for (Content item : rangedContents) { - if (item.content() instanceof IRangedIngredient ranged) - ranged.rollSampledCount(); + public void doTickPrerolls(IdentityHashMap, Object2IntMap> chanceCaches, GTRecipe lastDisplayedRecipe) { + if (!this.hasTick()) return; + + this.tickInputs.clear(); + this.tickOutputs.clear(); + + for (var capability : lastDisplayedRecipe.tickInputs.keySet()) { + var handler = lastDisplayedRecipe.tickInputs.get(capability); + for (var iterator = handler.listIterator(); iterator.hasNext();) { + var content = iterator.next(); + if (content.content() instanceof IRangedIngredient ranged) { + ranged.rollSampledCount(); + content = new Content(ranged.replace(), content.chance(), content.maxChance()); + iterator.set(content); + } + tickInputs.computeIfAbsent(capability, c -> new ArrayList<>()).add(content); + } + } + for (var capability : lastDisplayedRecipe.tickOutputs.keySet()) { + var handler = lastDisplayedRecipe.tickOutputs.get(capability); + for (var iterator = handler.listIterator(); iterator.hasNext();) { + var content = iterator.next(); + if (content.content() instanceof IRangedIngredient ranged) { + ranged.rollSampledCount(); + content = new Content(ranged.replace(), content.chance(), content.maxChance()); + iterator.set(content); + } + tickOutputs.computeIfAbsent(capability, c -> new ArrayList<>()).add(content); + } } } From f426e5cc299c695b27adb75b1106b077b7c61587 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 19:15:33 -0500 Subject: [PATCH 09/11] spotless --- src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java | 4 ++-- .../gtceu/api/recipe/ingredient/IRangedIngredient.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index 20e079bcea4..ead76f51ddf 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -1,6 +1,5 @@ package com.gregtechceu.gtceu.api.recipe; -import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; @@ -256,7 +255,8 @@ public void doPrerolls(IdentityHashMap, Object2IntMap> ch } } - public void doTickPrerolls(IdentityHashMap, Object2IntMap> chanceCaches, GTRecipe lastDisplayedRecipe) { + public void doTickPrerolls(IdentityHashMap, Object2IntMap> chanceCaches, + GTRecipe lastDisplayedRecipe) { if (!this.hasTick()) return; this.tickInputs.clear(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java index 44221770e07..8d9c1691d5e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java @@ -16,7 +16,7 @@ public interface IRangedIngredient { void setSampledCount(int count); - default T replace(){ + default T replace() { if (!isRolled()) GTCEu.LOGGER.warn("Ranged ingredient was replaced without being rolled!"); return null; From bc8e523a2a6e915ecff4fa5fadb14ecd48408436 Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Thu, 2 Jul 2026 19:25:31 -0500 Subject: [PATCH 10/11] no that's not what we want to do --- src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index ead76f51ddf..0317ba8c17e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -269,7 +269,6 @@ public void doTickPrerolls(IdentityHashMap, Object2IntMap if (content.content() instanceof IRangedIngredient ranged) { ranged.rollSampledCount(); content = new Content(ranged.replace(), content.chance(), content.maxChance()); - iterator.set(content); } tickInputs.computeIfAbsent(capability, c -> new ArrayList<>()).add(content); } @@ -281,7 +280,6 @@ public void doTickPrerolls(IdentityHashMap, Object2IntMap if (content.content() instanceof IRangedIngredient ranged) { ranged.rollSampledCount(); content = new Content(ranged.replace(), content.chance(), content.maxChance()); - iterator.set(content); } tickOutputs.computeIfAbsent(capability, c -> new ArrayList<>()).add(content); } From d0e14ee0dbffa332038c571953bccc91a67d6a8b Mon Sep 17 00:00:00 2001 From: DilithiumThoride Date: Sun, 5 Jul 2026 02:50:00 -0500 Subject: [PATCH 11/11] apply review comments (1/2) --- .../com/gregtechceu/gtceu/api/recipe/GTRecipe.java | 10 ++++++---- .../gtceu/api/recipe/ingredient/IRangedIngredient.java | 4 ++-- .../recipe/ingredient/IntProviderFluidIngredient.java | 4 ++-- .../api/recipe/ingredient/IntProviderIngredient.java | 4 ++-- .../ingredient/IntProviderFluidIngredientTest.java | 2 +- .../recipe/ingredient/IntProviderIngredientTest.java | 2 +- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index 0317ba8c17e..9bd9d4ee472 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -240,7 +240,7 @@ public void doPrerolls(IdentityHashMap, Object2IntMap> ch var content = iterator.next(); if (content.content() instanceof IRangedIngredient ranged) { ranged.rollSampledCount(); - iterator.set(new Content(ranged.replace(), content.chance(), content.maxChance())); + iterator.set(new Content(ranged.collapse(), content.chance(), content.maxChance())); } } } @@ -249,7 +249,7 @@ public void doPrerolls(IdentityHashMap, Object2IntMap> ch var content = iterator.next(); if (content.content() instanceof IRangedIngredient ranged) { ranged.rollSampledCount(); - iterator.set(new Content(ranged.replace(), content.chance(), content.maxChance())); + iterator.set(new Content(ranged.collapse(), content.chance(), content.maxChance())); } } } @@ -268,7 +268,8 @@ public void doTickPrerolls(IdentityHashMap, Object2IntMap var content = iterator.next(); if (content.content() instanceof IRangedIngredient ranged) { ranged.rollSampledCount(); - content = new Content(ranged.replace(), content.chance(), content.maxChance()); + content = new Content(ranged.collapse(), content.chance(), content.maxChance()); + ranged.reset(); } tickInputs.computeIfAbsent(capability, c -> new ArrayList<>()).add(content); } @@ -279,7 +280,8 @@ public void doTickPrerolls(IdentityHashMap, Object2IntMap var content = iterator.next(); if (content.content() instanceof IRangedIngredient ranged) { ranged.rollSampledCount(); - content = new Content(ranged.replace(), content.chance(), content.maxChance()); + content = new Content(ranged.collapse(), content.chance(), content.maxChance()); + ranged.reset(); } tickOutputs.computeIfAbsent(capability, c -> new ArrayList<>()).add(content); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java index 8d9c1691d5e..c0b936a4fd5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java @@ -16,9 +16,9 @@ public interface IRangedIngredient { void setSampledCount(int count); - default T replace() { + default T collapse() { if (!isRolled()) - GTCEu.LOGGER.warn("Ranged ingredient was replaced without being rolled!"); + GTCEu.LOGGER.warn("Ranged ingredient was collapsed without being rolled!"); return null; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java index 1898697771f..3d1e1d16869 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java @@ -127,8 +127,8 @@ public void reset() { } @Override - public FluidIngredient replace() { - IRangedIngredient.super.replace(); + public FluidIngredient collapse() { + IRangedIngredient.super.collapse(); return new FluidIngredient(inner.values, rollSampledCount(), inner.nbt); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java index 09110469f6d..9de22cdb596 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java @@ -133,8 +133,8 @@ public int rollSampledCount(@NotNull RandomSource random) { } @Override - public SizedIngredient replace() { - IRangedIngredient.super.replace(); + public SizedIngredient collapse() { + IRangedIngredient.super.collapse(); return SizedIngredient.create(inner, rollSampledCount()); } diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java index 5007df41faa..b37e22ab9dd 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java @@ -221,7 +221,7 @@ public static void rangedFluidIngredientGetStacksTest(GameTestHelper helper) { helper.assertTrue(ingredient.getStacks().length == 0, "A ranged fluid ingredient " + "should not return items!"); ingredient.rollSampledCount(); - var stacks = ingredient.replace().getStacks(); + var stacks = ingredient.collapse().getStacks(); helper.assertTrue(stacks.length == 1, "Replaced IntProviderFluidIngredient should only " + "return 1 fluid when made with 1 fluid"); helper.assertTrue(stacks[0].isFluidEqual(GTMaterials.Water.getFluid(1)), diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java index 30f4f11e785..9fd771de78c 100644 --- a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java @@ -216,7 +216,7 @@ public static void rangedIngredientGetStacksTest(GameTestHelper helper) { helper.assertTrue(ingredient.getItems().length == 0, "A ranged ingredient " + "should not return items!"); ingredient.rollSampledCount(); - var stacks = ingredient.replace().getItems(); + var stacks = ingredient.collapse().getItems(); helper.assertTrue(stacks.length == 1, "Replaced IntProviderIngredient should only " + "return 1 item when made with 1 item"); helper.assertTrue(stacks[0].is(new ItemStack(Items.BRICK, 1).getItem()),