diff --git a/CommonApi/src/main/java/mezz/jei/api/ingredients/IIngredientType.java b/CommonApi/src/main/java/mezz/jei/api/ingredients/IIngredientType.java index 43ec5b6ef..96df9c247 100644 --- a/CommonApi/src/main/java/mezz/jei/api/ingredients/IIngredientType.java +++ b/CommonApi/src/main/java/mezz/jei/api/ingredients/IIngredientType.java @@ -39,8 +39,9 @@ default String getUid() { */ default Optional castIngredient(@Nullable Object ingredient) { Class ingredientClass = getIngredientClass(); - return Optional.ofNullable(ingredient) - .filter(ingredientClass::isInstance) - .map(ingredientClass::cast); + if (ingredientClass.isInstance(ingredient)) { + return Optional.of(ingredientClass.cast(ingredient)); + } + return Optional.empty(); } } diff --git a/Library/src/main/java/mezz/jei/library/ingredients/IngredientManager.java b/Library/src/main/java/mezz/jei/library/ingredients/IngredientManager.java index cde058bd4..46d7da338 100644 --- a/Library/src/main/java/mezz/jei/library/ingredients/IngredientManager.java +++ b/Library/src/main/java/mezz/jei/library/ingredients/IngredientManager.java @@ -178,11 +178,10 @@ public Optional> createTypedIngredient(IIngredientType ITypedIngredient normalizeTypedIngredient(ITypedIngredient typedIngredient) { + ErrorUtil.checkNotNull(typedIngredient, "typedIngredient"); IIngredientType type = typedIngredient.getType(); IIngredientHelper ingredientHelper = getIngredientHelper(type); - V ingredient = typedIngredient.getIngredient(); - V normalized = ingredientHelper.normalizeIngredient(ingredient); - return TypedIngredient.createUnvalidated(type, normalized); + return TypedIngredient.normalize(typedIngredient, ingredientHelper); } @SuppressWarnings("removal") diff --git a/Library/src/main/java/mezz/jei/library/ingredients/TypedIngredient.java b/Library/src/main/java/mezz/jei/library/ingredients/TypedIngredient.java index cde144c38..555f9648d 100644 --- a/Library/src/main/java/mezz/jei/library/ingredients/TypedIngredient.java +++ b/Library/src/main/java/mezz/jei/library/ingredients/TypedIngredient.java @@ -2,10 +2,14 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; +import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.ingredients.IIngredientHelper; import mezz.jei.api.ingredients.IIngredientType; import mezz.jei.api.ingredients.ITypedIngredient; import mezz.jei.api.runtime.IIngredientManager; +import mezz.jei.library.ingredients.itemStacks.NormalizedTypedItemStack; +import mezz.jei.library.ingredients.itemStacks.TypedItemStack; +import net.minecraft.world.item.ItemStack; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; @@ -28,8 +32,31 @@ private static void checkParameters(IIngredientType ingredientType, T ing } } + public static ITypedIngredient normalize(ITypedIngredient typedIngredient, IIngredientHelper ingredientHelper) { + IIngredientType type = typedIngredient.getType(); + + if (type == VanillaTypes.ITEM_STACK) { + @SuppressWarnings("unchecked") + ITypedIngredient cast = (ITypedIngredient) typedIngredient; + ITypedIngredient normalized = NormalizedTypedItemStack.normalize(cast); + @SuppressWarnings("unchecked") + ITypedIngredient castNormalized = (ITypedIngredient) normalized; + return castNormalized; + } + + T ingredient = typedIngredient.getIngredient(); + T normalized = ingredientHelper.normalizeIngredient(ingredient); + return createUnvalidated(type, normalized); + } + public static ITypedIngredient createUnvalidated(IIngredientType ingredientType, T ingredient) { - checkParameters(ingredientType, ingredient); + if (ingredientType == VanillaTypes.ITEM_STACK) { + ITypedIngredient typedIngredient = TypedItemStack.create((ItemStack) ingredient); + @SuppressWarnings("unchecked") + ITypedIngredient castIngredient = (ITypedIngredient) typedIngredient; + return castIngredient; + } + return new TypedIngredient<>(ingredientType, ingredient); } @@ -54,7 +81,6 @@ public static Optional> createAndFilterInvalid( if (ingredient == null) { return Optional.empty(); } - checkParameters(ingredientType, ingredient); IIngredientHelper ingredientHelper = ingredientManager.getIngredientHelper(ingredientType); return createAndFilterInvalid(ingredientHelper, ingredientType, ingredient, normalize); @@ -102,7 +128,7 @@ public static Optional> createAndFilterInvalid( throw new IllegalArgumentException("Crashed when checking if ingredient is valid. Ingredient Info: " + ingredientInfo, e); } - TypedIngredient typedIngredient = new TypedIngredient<>(ingredientType, ingredient); + ITypedIngredient typedIngredient = createUnvalidated(ingredientType, ingredient); return Optional.of(typedIngredient); } @@ -116,6 +142,7 @@ public static Optional> deepCopy(IIngredientManager ingr private final T ingredient; private TypedIngredient(IIngredientType ingredientType, T ingredient) { + checkParameters(ingredientType, ingredient); this.ingredientType = ingredientType; this.ingredient = ingredient; } diff --git a/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/NormalizedTypedItem.java b/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/NormalizedTypedItem.java new file mode 100644 index 000000000..19688c709 --- /dev/null +++ b/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/NormalizedTypedItem.java @@ -0,0 +1,34 @@ +package mezz.jei.library.ingredients.itemStacks; + +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.ingredients.IIngredientType; +import mezz.jei.api.ingredients.ITypedIngredient; +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import java.util.Optional; + +record NormalizedTypedItem(Holder itemHolder) implements ITypedIngredient { + @Override + public ItemStack getIngredient() { + return new ItemStack(itemHolder); + } + + @Override + public Optional getItemStack() { + return Optional.of(getIngredient()); + } + + @Override + public IIngredientType getType() { + return VanillaTypes.ITEM_STACK; + } + + @Override + public String toString() { + return "SimpleItemStack{" + + "itemHolder=" + itemHolder + + '}'; + } +} diff --git a/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/NormalizedTypedItemStack.java b/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/NormalizedTypedItemStack.java new file mode 100644 index 000000000..384b6a4ef --- /dev/null +++ b/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/NormalizedTypedItemStack.java @@ -0,0 +1,71 @@ +package mezz.jei.library.ingredients.itemStacks; + +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.ingredients.IIngredientType; +import mezz.jei.api.ingredients.ITypedIngredient; +import net.minecraft.core.Holder; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import java.util.Optional; + +public record NormalizedTypedItemStack( + Holder itemHolder, + DataComponentPatch dataComponentPatch +) implements ITypedIngredient { + public static ITypedIngredient normalize(ITypedIngredient typedIngredient) { + switch (typedIngredient) { + case NormalizedTypedItemStack normalized -> { + return normalized; + } + case NormalizedTypedItem normalized -> { + return normalized; + } + case TypedItemStack typedItemStack -> { + return create(typedItemStack.itemHolder(), typedItemStack.dataComponentPatch()); + } + default -> { + ItemStack itemStack = typedIngredient.getIngredient(); + return create(itemStack.getItemHolder(), itemStack.getComponentsPatch()); + } + } + } + + public static ITypedIngredient create(Holder itemHolder, DataComponentPatch dataComponentPatch) { + if (dataComponentPatch.isEmpty()) { + return new NormalizedTypedItem(itemHolder); + } + return new NormalizedTypedItemStack(itemHolder, dataComponentPatch); + } + + public static ITypedIngredient create(ItemStack itemStack) { + return create( + itemStack.getItemHolder(), + itemStack.getComponentsPatch() + ); + } + + @Override + public ItemStack getIngredient() { + return new ItemStack(itemHolder, 1, dataComponentPatch); + } + + @Override + public Optional getItemStack() { + return Optional.of(getIngredient()); + } + + @Override + public IIngredientType getType() { + return VanillaTypes.ITEM_STACK; + } + + @Override + public String toString() { + return "NormalizedTypedItemStack{" + + "itemHolder=" + itemHolder + + ", dataComponentPatch=" + dataComponentPatch + + '}'; + } +} diff --git a/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/TypedItemStack.java b/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/TypedItemStack.java new file mode 100644 index 000000000..28a1301e9 --- /dev/null +++ b/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/TypedItemStack.java @@ -0,0 +1,52 @@ +package mezz.jei.library.ingredients.itemStacks; + +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.ingredients.IIngredientType; +import mezz.jei.api.ingredients.ITypedIngredient; +import net.minecraft.core.Holder; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import java.util.Optional; + +public record TypedItemStack( + Holder itemHolder, + DataComponentPatch dataComponentPatch, + int count +) implements ITypedIngredient { + public static ITypedIngredient create(ItemStack ingredient) { + if (ingredient.getCount() == 1) { + return NormalizedTypedItemStack.create(ingredient); + } + return new TypedItemStack( + ingredient.getItemHolder(), + ingredient.getComponentsPatch(), + ingredient.getCount() + ); + } + + @Override + public ItemStack getIngredient() { + return new ItemStack(itemHolder, count, dataComponentPatch); + } + + @Override + public Optional getItemStack() { + return Optional.of(getIngredient()); + } + + @Override + public IIngredientType getType() { + return VanillaTypes.ITEM_STACK; + } + + @Override + public String toString() { + return "TypedItemStack{" + + "itemHolder=" + itemHolder + + ", dataComponentPatch=" + dataComponentPatch + + ", count=" + count + + '}'; + } +} diff --git a/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/package-info.java b/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/package-info.java new file mode 100644 index 000000000..4250247f6 --- /dev/null +++ b/Library/src/main/java/mezz/jei/library/ingredients/itemStacks/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package mezz.jei.library.ingredients.itemStacks; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault;