Skip to content

Commit 620196d

Browse files
committed
Initial pass at reworking ingredients to use neo's SizedIngredient and SizedFluidIngredient. Also fixed the fluid input cache not properly handling component based inputs
1 parent bd477b5 commit 620196d

File tree

18 files changed

+404
-345
lines changed

18 files changed

+404
-345
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ repositories { RepositoryHandler handler ->
412412
exclusiveRepo(handler, 'https://maven.minecraftforge.net/releases/', 'com.github.glitchfiend')
413413
exclusiveRepo(handler, 'https://maven.thiakil.com', 'com.thiakil', 'moze_intel')
414414
exclusiveRepo(handler, 'https://maven.parchmentmc.org/', 'org.parchmentmc.data')
415+
mavenLocal()
415416
}
416417

417418
test {

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ minecraft_version=1.20.6
88
previous_minecraft_version=1.20.1
99
previous_minor_minecraft_version=1.20.4
1010
loader_version_range=[2,)
11-
forge_version=20.6.57-beta
11+
forge_version=20.6.84-beta-fork-feature-fluid-ingredients
1212
mod_version=10.5.20
1313
#This determines the minimum version of forge required to use Mekanism
1414
# Only bump it whenever we need access to a feature in forge that is not available in earlier versions

src/api/java/mekanism/api/chemical/gas/GasStack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public final class GasStack extends ChemicalStack<Gas> {
3737
*
3838
* @since 10.6.0
3939
*/
40-
private static final Codec<Gas> GAS_NON_EMPTY_CODEC = chemicalNonEmptyCodec(MekanismAPI.GAS_REGISTRY);
40+
public static final Codec<Gas> GAS_NON_EMPTY_CODEC = chemicalNonEmptyCodec(MekanismAPI.GAS_REGISTRY);
4141
/**
4242
* A standard map codec for gas stacks that does not accept empty stacks.
4343
*

src/api/java/mekanism/api/chemical/infuse/InfusionStack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public final class InfusionStack extends ChemicalStack<InfuseType> {
3232
*
3333
* @since 10.6.0
3434
*/
35-
private static final Codec<InfuseType> INFUSE_TYPE_NON_EMPTY_CODEC = chemicalNonEmptyCodec(MekanismAPI.INFUSE_TYPE_REGISTRY);
35+
public static final Codec<InfuseType> INFUSE_TYPE_NON_EMPTY_CODEC = chemicalNonEmptyCodec(MekanismAPI.INFUSE_TYPE_REGISTRY);
3636
/**
3737
* A standard map codec for infusion stacks that does not accept empty stacks.
3838
*

src/api/java/mekanism/api/chemical/pigment/PigmentStack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public final class PigmentStack extends ChemicalStack<Pigment> {
3232
*
3333
* @since 10.6.0
3434
*/
35-
private static final Codec<Pigment> PIGMENT_NON_EMPTY_CODEC = chemicalNonEmptyCodec(MekanismAPI.PIGMENT_REGISTRY);
35+
public static final Codec<Pigment> PIGMENT_NON_EMPTY_CODEC = chemicalNonEmptyCodec(MekanismAPI.PIGMENT_REGISTRY);
3636
/**
3737
* A standard map codec for pigment stacks that does not accept empty stacks.
3838
*

src/api/java/mekanism/api/chemical/slurry/SlurryStack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public final class SlurryStack extends ChemicalStack<Slurry> {
3232
*
3333
* @since 10.6.0
3434
*/
35-
private static final Codec<Slurry> SLURRY_NON_EMPTY_CODEC = chemicalNonEmptyCodec(MekanismAPI.SLURRY_REGISTRY);
35+
public static final Codec<Slurry> SLURRY_NON_EMPTY_CODEC = chemicalNonEmptyCodec(MekanismAPI.SLURRY_REGISTRY);
3636
/**
3737
* A standard map codec for slurry stacks that does not accept empty stacks.
3838
*

src/api/java/mekanism/api/recipes/ingredients/creator/IFluidStackIngredientCreator.java

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44
import mekanism.api.annotations.NothingNullByDefault;
55
import mekanism.api.providers.IFluidProvider;
66
import mekanism.api.recipes.ingredients.FluidStackIngredient;
7+
import net.minecraft.core.component.DataComponentPredicate;
8+
import net.minecraft.tags.TagKey;
79
import net.minecraft.world.level.material.Fluid;
810
import net.neoforged.neoforge.fluids.FluidStack;
11+
import net.neoforged.neoforge.fluids.crafting.DataComponentFluidIngredient;
12+
import net.neoforged.neoforge.fluids.crafting.FluidIngredient;
13+
import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient;
914

1015
@NothingNullByDefault
1116
public interface IFluidStackIngredientCreator extends IIngredientCreator<Fluid, FluidStack, FluidStackIngredient> {
@@ -26,6 +31,55 @@ default FluidStackIngredient from(IFluidProvider provider, int amount) {
2631

2732
@Override
2833
default FluidStackIngredient from(Fluid instance, int amount) {
29-
return from(new FluidStack(instance, amount));
34+
return from(SizedFluidIngredient.of(instance, amount));
3035
}
36+
37+
@Override
38+
default FluidStackIngredient from(FluidStack instance) {
39+
Objects.requireNonNull(instance, "FluidStackIngredients cannot be created from a null FluidStack.");
40+
if (instance.isEmpty()) {
41+
throw new IllegalArgumentException("FluidStackIngredients cannot be created using the empty stack.");
42+
}
43+
//Copy the stack to ensure it doesn't get modified afterward
44+
instance = instance.copy();
45+
//Support Components that are on the stack in case it matters
46+
// Note: Only bother making it a data component ingredient if the stack has data, otherwise there is no point in doing the extra checks
47+
DataComponentPredicate predicate = IngredientCreatorAccess.getComponentPatchPredicate(instance.getComponentsPatch());
48+
if (predicate != null) {
49+
return from(DataComponentFluidIngredient.of(false, predicate, instance.getFluidHolder()), instance.getAmount());
50+
}
51+
return from(SizedFluidIngredient.of(instance));
52+
}
53+
54+
@Override
55+
default FluidStackIngredient from(TagKey<Fluid> tag, int amount) {
56+
Objects.requireNonNull(tag, "FluidStackIngredients cannot be created from a null tag.");
57+
return from(SizedFluidIngredient.of(tag, amount));
58+
}
59+
60+
/**
61+
* Creates a Fluid Stack Ingredient that matches a given ingredient and amount.
62+
*
63+
* @param ingredient Ingredient to match.
64+
* @param amount Amount needed.
65+
*
66+
* @throws NullPointerException if the given instance is null.
67+
* @throws IllegalArgumentException if the given instance is empty or an amount smaller than one.
68+
* @since 10.6.0
69+
*/
70+
default FluidStackIngredient from(FluidIngredient ingredient, int amount) {
71+
Objects.requireNonNull(ingredient, "FluidStackIngredients cannot be created from a null fluid ingredient.");
72+
return from(new SizedFluidIngredient(ingredient, amount));
73+
}
74+
75+
/**
76+
* Creates a Fluid Stack Ingredient that matches a given ingredient and amount.
77+
*
78+
* @param ingredient Sized ingredient to match.
79+
*
80+
* @throws NullPointerException if the given instance is null.
81+
* @throws IllegalArgumentException if the given instance is empty.
82+
* @since 10.6.0
83+
*/
84+
FluidStackIngredient from(SizedFluidIngredient ingredient);
3185
}

src/api/java/mekanism/api/recipes/ingredients/creator/IItemStackIngredientCreator.java

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
package mekanism.api.recipes.ingredients.creator;
22

3-
import java.util.Map;
43
import java.util.Objects;
5-
import java.util.Optional;
64
import mekanism.api.annotations.NothingNullByDefault;
75
import mekanism.api.recipes.ingredients.ItemStackIngredient;
86
import net.minecraft.core.Holder;
97
import net.minecraft.core.component.DataComponentPredicate;
10-
import net.minecraft.core.component.DataComponentType;
118
import net.minecraft.tags.TagKey;
129
import net.minecraft.world.item.Item;
1310
import net.minecraft.world.item.ItemStack;
1411
import net.minecraft.world.item.crafting.Ingredient;
1512
import net.minecraft.world.level.ItemLike;
1613
import net.neoforged.neoforge.common.crafting.DataComponentIngredient;
14+
import net.neoforged.neoforge.common.crafting.SizedIngredient;
1715

1816
@NothingNullByDefault
1917
public interface IItemStackIngredientCreator extends IIngredientCreator<Item, ItemStack, ItemStackIngredient> {
@@ -41,17 +39,9 @@ default ItemStackIngredient from(ItemStack stack, int amount) {
4139
stack = stack.copy();
4240
//Support Components that are on the stack in case it matters
4341
// Note: Only bother making it a data component ingredient if the stack has data, otherwise there is no point in doing the extra checks
44-
if (!stack.isComponentsPatchEmpty()) {
45-
DataComponentPredicate.Builder builder = DataComponentPredicate.builder();
46-
for (Map.Entry<DataComponentType<?>, Optional<?>> entry : stack.getComponentsPatch().entrySet()) {
47-
Optional<?> value = entry.getValue();
48-
//Note: We only add if the value is added, we don't check ones that have been removed from default, as that isn't easily feasible
49-
if (value.isPresent()) {
50-
//noinspection rawtypes,unchecked
51-
builder.expect((DataComponentType) entry.getKey(), value);
52-
}
53-
}
54-
return from(DataComponentIngredient.of(false, builder.build(), stack.getItemHolder()), amount);
42+
DataComponentPredicate predicate = IngredientCreatorAccess.getComponentPatchPredicate(stack.getComponentsPatch());
43+
if (predicate != null) {
44+
return from(DataComponentIngredient.of(false, predicate, stack.getItemHolder()), amount);
5545
}
5646
return from(Ingredient.of(stack), amount);
5747
}
@@ -134,6 +124,23 @@ default ItemStackIngredient from(Ingredient ingredient) {
134124
*
135125
* @param ingredient Ingredient to match.
136126
* @param amount Amount needed.
127+
*
128+
* @throws NullPointerException if the given instance is null.
129+
* @throws IllegalArgumentException if the given instance is empty or an amount smaller than one.
130+
*/
131+
default ItemStackIngredient from(Ingredient ingredient, int amount) {
132+
Objects.requireNonNull(ingredient, "ItemStackIngredients cannot be created from a null ingredient.");
133+
return from(new SizedIngredient(ingredient, amount));
134+
}
135+
136+
/**
137+
* Creates an Item Stack Ingredient that matches a given ingredient and amount.
138+
*
139+
* @param ingredient Sized ingredient to match.
140+
*
141+
* @throws NullPointerException if the given instance is null.
142+
* @throws IllegalArgumentException if the given instance is empty.
143+
* @since 10.6.0
137144
*/
138-
ItemStackIngredient from(Ingredient ingredient, int amount);
145+
ItemStackIngredient from(SizedIngredient ingredient);
139146
}

src/api/java/mekanism/api/recipes/ingredients/creator/IngredientCreatorAccess.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package mekanism.api.recipes.ingredients.creator;
22

3+
import java.util.Map;
4+
import java.util.Optional;
35
import mekanism.api.IMekanismAccess;
46
import mekanism.api.chemical.ChemicalType;
57
import mekanism.api.chemical.gas.Gas;
@@ -14,6 +16,10 @@
1416
import mekanism.api.recipes.ingredients.ChemicalStackIngredient.InfusionStackIngredient;
1517
import mekanism.api.recipes.ingredients.ChemicalStackIngredient.PigmentStackIngredient;
1618
import mekanism.api.recipes.ingredients.ChemicalStackIngredient.SlurryStackIngredient;
19+
import net.minecraft.core.component.DataComponentPatch;
20+
import net.minecraft.core.component.DataComponentPredicate;
21+
import net.minecraft.core.component.DataComponentType;
22+
import org.jetbrains.annotations.Nullable;
1723

1824
/**
1925
* Provides access to helpers for creating various types of ingredients.
@@ -80,4 +86,26 @@ public static IChemicalStackIngredientCreator<Pigment, PigmentStack, PigmentStac
8086
public static IChemicalStackIngredientCreator<Slurry, SlurryStack, SlurryStackIngredient> slurry() {
8187
return IMekanismAccess.INSTANCE.slurryStackIngredientCreator();
8288
}
89+
90+
/**
91+
* Private helper to create a predicate out of a component patch.
92+
*
93+
* @since 10.6.0
94+
*/
95+
@Nullable
96+
static DataComponentPredicate getComponentPatchPredicate(DataComponentPatch patch) {
97+
if (!patch.isEmpty()) {
98+
DataComponentPredicate.Builder builder = DataComponentPredicate.builder();
99+
for (Map.Entry<DataComponentType<?>, Optional<?>> entry : patch.entrySet()) {
100+
Optional<?> value = entry.getValue();
101+
//Note: We only add if the value is added, we don't check ones that have been removed from default, as that isn't easily feasible
102+
if (value.isPresent()) {
103+
//noinspection rawtypes,unchecked
104+
builder.expect((DataComponentType) entry.getKey(), value);
105+
}
106+
}
107+
return builder.build();
108+
}
109+
return null;
110+
}
83111
}

src/datagen/main/java/mekanism/common/integration/crafttweaker/example/BaseCrTExampleProvider.java

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
import mekanism.common.recipe.ingredient.chemical.TaggedChemicalStackIngredient;
6060
import mekanism.common.recipe.ingredient.creator.FluidStackIngredientCreator.MultiFluidStackIngredient;
6161
import mekanism.common.recipe.ingredient.creator.FluidStackIngredientCreator.SingleFluidStackIngredient;
62-
import mekanism.common.recipe.ingredient.creator.FluidStackIngredientCreator.TaggedFluidStackIngredient;
6362
import mekanism.common.recipe.ingredient.creator.ItemStackIngredientCreator.MultiItemStackIngredient;
6463
import mekanism.common.recipe.ingredient.creator.ItemStackIngredientCreator.SingleItemStackIngredient;
6564
import net.minecraft.data.CachedOutput;
@@ -71,10 +70,11 @@
7170
import net.minecraft.server.packs.PackType;
7271
import net.minecraft.util.GsonHelper;
7372
import net.minecraft.world.item.ItemStack;
74-
import net.minecraft.world.item.crafting.Ingredient;
7573
import net.minecraft.world.level.ItemLike;
74+
import net.neoforged.neoforge.common.crafting.SizedIngredient;
7675
import net.neoforged.neoforge.common.data.ExistingFileHelper;
7776
import net.neoforged.neoforge.fluids.FluidStack;
77+
import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient;
7878
import org.jetbrains.annotations.NotNull;
7979
import org.jetbrains.annotations.Nullable;
8080

@@ -296,7 +296,7 @@ private void addItemStackIngredientSupport() {
296296
addSupportedConversion(ItemStackIngredient.class, ItemStackIngredient.class, this::getIngredientRepresentation,
297297
(imports, ingredient) -> {
298298
if (ingredient instanceof SingleItemStackIngredient single) {
299-
return MekanismRecipeHandler.basicImplicitIngredient(single.getInputRaw(), single.getAmountRaw());
299+
return MekanismRecipeHandler.basicImplicitIngredient(single.getInputRaw());
300300
}
301301
return null;
302302
});
@@ -305,18 +305,18 @@ private void addItemStackIngredientSupport() {
305305
@Nullable
306306
private String getIngredientRepresentation(CrTImportsComponent imports, ItemStackIngredient ingredient) {
307307
if (ingredient instanceof SingleItemStackIngredient single) {
308-
Ingredient vanillaIngredient = single.getInputRaw();
309-
int amount = single.getAmountRaw();
308+
SizedIngredient vanillaIngredient = single.getInputRaw();
309+
int amount = vanillaIngredient.count();
310310
String representation = null;
311311
if (amount > 1) {
312312
//Special case handling for when we would want to use a different constructor
313-
representation = MekanismRecipeHandler.basicImplicitIngredient(vanillaIngredient, amount, true);
313+
representation = MekanismRecipeHandler.basicImplicitIngredient(vanillaIngredient.ingredient(), amount, true);
314314
if (representation != null) {
315315
amount = 1;
316316
}
317317
}
318318
if (representation == null) {
319-
representation = IIngredient.fromIngredient(vanillaIngredient).getCommandString();
319+
representation = IIngredient.fromIngredient(vanillaIngredient.ingredient()).getCommandString();
320320
}
321321
String path = imports.addImport(CrTConstants.CLASS_ITEM_STACK_INGREDIENT);
322322
if (amount == 1) {
@@ -333,9 +333,7 @@ private void addFluidStackIngredientSupport() {
333333
addSupportedConversion(FluidStackIngredient.class, FluidStackIngredient.class, this::getIngredientRepresentation,
334334
(imports, ingredient) -> {
335335
if (ingredient instanceof SingleFluidStackIngredient single) {
336-
return IFluidStack.of(single.getInputRaw()).getCommandString();
337-
} else if (ingredient instanceof TaggedFluidStackIngredient tagged) {
338-
return CrTUtils.fluidTags().tag(tagged.getTag()).withAmount(tagged.getRawAmount()).getCommandString();
336+
return MekanismRecipeHandler.basicImplicitIngredient(single.getInputRaw());
339337
}
340338
return null;
341339
});
@@ -344,11 +342,25 @@ private void addFluidStackIngredientSupport() {
344342
@Nullable
345343
private String getIngredientRepresentation(CrTImportsComponent imports, FluidStackIngredient ingredient) {
346344
if (ingredient instanceof SingleFluidStackIngredient single) {
347-
String stackRepresentation = IFluidStack.of(single.getInputRaw()).getCommandString();
348-
return imports.addImport(CrTConstants.CLASS_FLUID_STACK_INGREDIENT) + ".from(" + stackRepresentation + ")";
349-
} else if (ingredient instanceof TaggedFluidStackIngredient tagged) {
350-
String tagRepresentation = CrTUtils.fluidTags().tag(tagged.getTag()).getCommandString();
351-
return imports.addImport(CrTConstants.CLASS_FLUID_STACK_INGREDIENT) + ".from(" + tagRepresentation + ", " + tagged.getRawAmount() + ")";
345+
SizedFluidIngredient vanillaIngredient = single.getInputRaw();
346+
int amount = vanillaIngredient.amount();
347+
String representation = null;
348+
if (amount > 1) {
349+
//Special case handling for when we would want to use a different constructor
350+
representation = MekanismRecipeHandler.basicImplicitIngredient(vanillaIngredient.ingredient(), amount, true);
351+
if (representation != null) {
352+
amount = 1;
353+
}
354+
}
355+
if (representation == null) {
356+
//TODO - 1.20.5: Re-evaluate once CrT updates to support Neo's fluid ingredients
357+
//representation = IIngredient.fromIngredient(vanillaIngredient.ingredient()).getCommandString();
358+
}
359+
String path = imports.addImport(CrTConstants.CLASS_FLUID_STACK_INGREDIENT);
360+
if (amount == 1) {
361+
return path + ".from(" + representation + ")";
362+
}
363+
return path + ".from(" + representation + ", " + amount + ")";
352364
} else if (ingredient instanceof MultiFluidStackIngredient multiIngredient) {
353365
return getMultiIngredientRepresentation(imports, CrTConstants.CLASS_FLUID_STACK_INGREDIENT, multiIngredient, this::getIngredientRepresentation);
354366
}

0 commit comments

Comments
 (0)