From 59edb38208519f9fd495c1a02b079ae37ca445bd Mon Sep 17 00:00:00 2001 From: zeng-git <95841646+zeng-github01@users.noreply.github.com> Date: Fri, 24 May 2024 18:51:37 +0800 Subject: [PATCH] Add ore dictionary support for Inscriber recipes in JEI (#430) --- .../appeng/api/features/IInscriberRecipe.java | 25 +++++++++--- .../api/features/IInscriberRecipeBuilder.java | 20 +++++++--- .../implementations/ContainerInscriber.java | 40 +++++++++++++------ .../inscriber/InscriberInscribeRecipe.java | 3 +- .../registries/inscriber/InscriberRecipe.java | 21 +++++----- .../inscriber/InscriberRegistry.java | 21 +++++----- .../crafttweaker/InscriberRecipes.java | 32 +++++---------- .../modules/jei/InscriberRecipeWrapper.java | 11 +++-- .../recipes/handlers/InscriberHandler.java | 34 ++++++---------- .../java/appeng/tile/misc/TileInscriber.java | 28 ++++++------- 10 files changed, 127 insertions(+), 108 deletions(-) diff --git a/src/api/java/appeng/api/features/IInscriberRecipe.java b/src/api/java/appeng/api/features/IInscriberRecipe.java index 810c6138f..a57ed6fa9 100644 --- a/src/api/java/appeng/api/features/IInscriberRecipe.java +++ b/src/api/java/appeng/api/features/IInscriberRecipe.java @@ -19,12 +19,11 @@ package appeng.api.features; -import java.util.List; -import java.util.Optional; +import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; - -import net.minecraft.item.ItemStack; +import java.util.List; +import java.util.Optional; /** @@ -57,21 +56,35 @@ public interface IInscriberRecipe @Nonnull ItemStack getOutput(); + + @Nonnull + List getTopInputs(); + /** * gets the top optional * * @return item which is used top */ + @Deprecated @Nonnull - Optional getTopOptional(); + default Optional getTopOptional(){ + return getTopInputs().isEmpty() ? Optional.empty() : Optional.of(getTopInputs().get(0)); + } + + + @Nonnull + List getBottomInputs(); /** * gets the bottom optional * * @return item which is used bottom */ + @Deprecated @Nonnull - Optional getBottomOptional(); + default Optional getBottomOptional() { + return getBottomInputs().isEmpty() ? Optional.empty() : Optional.of(getBottomInputs().get(0)); + } /** * type of inscriber process diff --git a/src/api/java/appeng/api/features/IInscriberRecipeBuilder.java b/src/api/java/appeng/api/features/IInscriberRecipeBuilder.java index a8ad18c38..9d4e39310 100644 --- a/src/api/java/appeng/api/features/IInscriberRecipeBuilder.java +++ b/src/api/java/appeng/api/features/IInscriberRecipeBuilder.java @@ -19,11 +19,11 @@ package appeng.api.features; -import java.util.Collection; +import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; - -import net.minecraft.item.ItemStack; +import java.util.Collection; +import java.util.Collections; /** @@ -66,7 +66,7 @@ public interface IInscriberRecipeBuilder * @return currently used builder */ @Nonnull - IInscriberRecipeBuilder withTopOptional( @Nonnull ItemStack topOptional ); + IInscriberRecipeBuilder withTopOptional(@Nonnull Collection topOptional ); /** * Creates an inscriber recipe with bot. @@ -77,7 +77,7 @@ public interface IInscriberRecipeBuilder * @return currently used builder */ @Nonnull - IInscriberRecipeBuilder withBottomOptional( @Nonnull ItemStack bottomOptional ); + IInscriberRecipeBuilder withBottomOptional( @Nonnull Collection bottomOptional ); /** * Creates an inscriber recipe with type. @@ -104,4 +104,14 @@ public interface IInscriberRecipeBuilder */ @Nonnull IInscriberRecipe build(); + + @Deprecated + default IInscriberRecipeBuilder withTopOptional(@Nonnull ItemStack topOptional){ + return withTopOptional(Collections.singleton(topOptional)); + } + + @Deprecated + default IInscriberRecipeBuilder withBottomOptional(@Nonnull ItemStack bottomOptional){ + return withBottomOptional(Collections.singleton(bottomOptional)); + } } diff --git a/src/main/java/appeng/container/implementations/ContainerInscriber.java b/src/main/java/appeng/container/implementations/ContainerInscriber.java index 6a393e1bc..aebd8d432 100644 --- a/src/main/java/appeng/container/implementations/ContainerInscriber.java +++ b/src/main/java/appeng/container/implementations/ContainerInscriber.java @@ -116,15 +116,19 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres boolean matches = false; for (final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes()) { - final boolean matchA = !top - .isEmpty() && (Platform.itemComparisons().isSameItem(top, recipe.getTopOptional().orElse(ItemStack.EMPTY)) || Platform - .itemComparisons() - .isSameItem(top, recipe.getBottomOptional().orElse(ItemStack.EMPTY))); - final boolean matchB = !bot - .isEmpty() && (Platform.itemComparisons().isSameItem(bot, recipe.getTopOptional().orElse(ItemStack.EMPTY)) || Platform - .itemComparisons() - .isSameItem(bot, recipe.getBottomOptional().orElse(ItemStack.EMPTY))); + // Check if plateA matches any item in the list of top components of the recipe + final boolean matchA = top.isEmpty() && recipe.getTopInputs().isEmpty() || + recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(top, topItem)) && + (bot.isEmpty() && recipe.getBottomInputs().isEmpty() || + recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(bot, bottomItem))); + // Check if plateB matches any item in the list of top components of the recipe + final boolean matchB = bot.isEmpty() && recipe.getTopInputs().isEmpty() || + recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(bot, topItem)) && + (top.isEmpty() && recipe.getBottomInputs().isEmpty() || + recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(top, bottomItem))); + + // If either matchA or matchB is true, iterate through the recipe's inputs if (matchA || matchB) { matches = true; for (final ItemStack option : recipe.getInputs()) { @@ -152,10 +156,22 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres // everything else for (final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes()) { boolean isValid = false; - if (Platform.itemComparisons().isSameItem(otherSlot, recipe.getTopOptional().orElse(ItemStack.EMPTY))) { - isValid = Platform.itemComparisons().isSameItem(is, recipe.getBottomOptional().orElse(ItemStack.EMPTY)); - } else if (Platform.itemComparisons().isSameItem(otherSlot, recipe.getBottomOptional().orElse(ItemStack.EMPTY))) { - isValid = Platform.itemComparisons().isSameItem(is, recipe.getTopOptional().orElse(ItemStack.EMPTY)); + // Check if otherSlot matches any item in the top component list + boolean matchTop = recipe.getTopInputs().stream() + .anyMatch(topItem -> Platform.itemComparisons().isSameItem(otherSlot, topItem)); + + // Check if otherSlot matches any item in the bottom component list + boolean matchBottom = recipe.getBottomInputs().stream() + .anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(otherSlot, bottomItem)); + + if (matchTop) { + // If otherSlot matches a top component, check if 'is' matches any item in the bottom component list + isValid = recipe.getBottomInputs().stream() + .anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(is, bottomItem)); + } else if (matchBottom) { + // If otherSlot matches a bottom component, check if 'is' matches any item in the top component list + isValid = recipe.getTopInputs().stream() + .anyMatch(topItem -> Platform.itemComparisons().isSameItem(is, topItem)); } if (isValid) { diff --git a/src/main/java/appeng/core/features/registries/inscriber/InscriberInscribeRecipe.java b/src/main/java/appeng/core/features/registries/inscriber/InscriberInscribeRecipe.java index d70792aa5..b93da6c63 100644 --- a/src/main/java/appeng/core/features/registries/inscriber/InscriberInscribeRecipe.java +++ b/src/main/java/appeng/core/features/registries/inscriber/InscriberInscribeRecipe.java @@ -25,6 +25,7 @@ import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Collection; +import java.util.List; /** @@ -35,7 +36,7 @@ import java.util.Collection; * @since rv2 */ public class InscriberInscribeRecipe extends InscriberRecipe { - InscriberInscribeRecipe(@Nonnull final Collection inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot) { + InscriberInscribeRecipe(@Nonnull final Collection inputs, @Nonnull final ItemStack output, @Nullable final List top, @Nullable final List bot) { super(inputs, output, top, bot, InscriberProcessType.INSCRIBE); } } diff --git a/src/main/java/appeng/core/features/registries/inscriber/InscriberRecipe.java b/src/main/java/appeng/core/features/registries/inscriber/InscriberRecipe.java index 2c63dd8c1..8f8c83658 100644 --- a/src/main/java/appeng/core/features/registries/inscriber/InscriberRecipe.java +++ b/src/main/java/appeng/core/features/registries/inscriber/InscriberRecipe.java @@ -28,7 +28,6 @@ import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Optional; /** @@ -46,21 +45,21 @@ public class InscriberRecipe implements IInscriberRecipe { private final ItemStack output; @Nonnull - private final Optional maybeTop; + private final List maybeTop; @Nonnull - private final Optional maybeBot; + private final List maybeBot; @Nonnull private final InscriberProcessType type; - InscriberRecipe(@Nonnull final Collection inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot, @Nonnull final InscriberProcessType type) { + InscriberRecipe(@Nonnull final Collection inputs, @Nonnull final ItemStack output, @Nullable final List top, @Nullable final List bot, @Nonnull final InscriberProcessType type) { this.inputs = new ArrayList<>(inputs.size()); this.inputs.addAll(inputs); this.output = output; - this.maybeTop = Optional.ofNullable(top); - this.maybeBot = Optional.ofNullable(bot); + this.maybeTop = top; + this.maybeBot = bot; this.type = type; } @@ -79,13 +78,13 @@ public class InscriberRecipe implements IInscriberRecipe { @Nonnull @Override - public final Optional getTopOptional() { + public final List getTopInputs() { return this.maybeTop; } @Nonnull @Override - public final Optional getBottomOptional() { + public final List getBottomInputs() { return this.maybeBot; } @@ -112,10 +111,10 @@ public class InscriberRecipe implements IInscriberRecipe { if (!this.output.equals(that.getOutput())) { return false; } - if (!this.maybeTop.equals(that.getTopOptional())) { + if (!this.maybeTop.equals(that.getTopInputs())) { return false; } - if (!this.maybeBot.equals(that.getBottomOptional())) { + if (!this.maybeBot.equals(that.getBottomInputs())) { return false; } return this.type == that.getProcessType(); @@ -130,4 +129,6 @@ public class InscriberRecipe implements IInscriberRecipe { result = 31 * result + this.type.hashCode(); return result; } + + } diff --git a/src/main/java/appeng/core/features/registries/inscriber/InscriberRegistry.java b/src/main/java/appeng/core/features/registries/inscriber/InscriberRegistry.java index a3c583e04..23cf4a754 100644 --- a/src/main/java/appeng/core/features/registries/inscriber/InscriberRegistry.java +++ b/src/main/java/appeng/core/features/registries/inscriber/InscriberRegistry.java @@ -75,9 +75,8 @@ public final class InscriberRegistry implements IInscriberRegistry { Preconditions.checkNotNull(recipe, "Tried to add (null) as inscriber recipe to the registry."); if (this.recipes.add(recipe)) { - recipe.getTopOptional().ifPresent(this.optionals::add); - recipe.getBottomOptional().ifPresent(this.optionals::add); - + this.optionals.addAll(recipe.getTopInputs()); + this.optionals.addAll(recipe.getBottomInputs()); this.inputs.addAll(recipe.getInputs()); return true; @@ -110,8 +109,8 @@ public final class InscriberRegistry implements IInscriberRegistry { private static final class Builder implements IInscriberRecipeBuilder { private List inputs; private ItemStack output; - private ItemStack topOptional; - private ItemStack bottomOptional; + private List topOptional; + private List bottomOptional; private InscriberProcessType type; @Nonnull @@ -139,22 +138,22 @@ public final class InscriberRegistry implements IInscriberRegistry { @Nonnull @Override - public Builder withTopOptional(@Nonnull final ItemStack topOptional) { + public Builder withTopOptional(@Nonnull final Collection topOptional) { Preconditions.checkNotNull(topOptional); - Preconditions.checkArgument(!topOptional.isEmpty()); - this.topOptional = topOptional; + this.topOptional = new ArrayList<>(topOptional.size()); + this.topOptional.addAll(topOptional); return this; } @Nonnull @Override - public Builder withBottomOptional(@Nonnull final ItemStack bottomOptional) { + public Builder withBottomOptional(@Nonnull final Collection bottomOptional) { Preconditions.checkNotNull(bottomOptional); - Preconditions.checkArgument(!bottomOptional.isEmpty()); - this.bottomOptional = bottomOptional; + this.bottomOptional = new ArrayList<>(bottomOptional.size()); + this.bottomOptional.addAll(bottomOptional); return this; } diff --git a/src/main/java/appeng/integration/modules/crafttweaker/InscriberRecipes.java b/src/main/java/appeng/integration/modules/crafttweaker/InscriberRecipes.java index 1d688d039..4335436dc 100644 --- a/src/main/java/appeng/integration/modules/crafttweaker/InscriberRecipes.java +++ b/src/main/java/appeng/integration/modules/crafttweaker/InscriberRecipes.java @@ -31,9 +31,7 @@ import net.minecraft.item.ItemStack; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenMethod; -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; @@ -49,25 +47,15 @@ public class InscriberRecipes { return; } - Collection topList = CTModule.toStacks(top).orElse(Collections.singleton(ItemStack.EMPTY)); - Collection bottomList = CTModule.toStacks(bottom).orElse(Collections.singleton(ItemStack.EMPTY)); - - for (ItemStack topStack : topList) { - for (ItemStack bottomStack : bottomList) { - final IInscriberRecipeBuilder builder = AEApi.instance().registries().inscriber().builder(); - builder.withProcessType(inscribe ? InscriberProcessType.INSCRIBE : InscriberProcessType.PRESS) - .withOutput(CTModule.toStack(output)) - .withInputs(inStacks.get()); - - if (!topStack.isEmpty()) { - builder.withTopOptional(topStack); - } - if (!bottomStack.isEmpty()) { - builder.withBottomOptional(bottomStack); - } - CTModule.MODIFICATIONS.add(new Add(builder.build())); - } - } + List topList = new ArrayList<>(CTModule.toStacks(top).orElse(Collections.singleton(ItemStack.EMPTY))); + List bottomList = new ArrayList<>(CTModule.toStacks(bottom).orElse(Collections.singleton(ItemStack.EMPTY))); + final IInscriberRecipeBuilder builder = AEApi.instance().registries().inscriber().builder(); + builder.withProcessType(inscribe ? InscriberProcessType.INSCRIBE : InscriberProcessType.PRESS). + withTopOptional(topList). + withBottomOptional(bottomList). + withOutput(CTModule.toStack(output)) + .withInputs(inStacks.get()); + CTModule.MODIFICATIONS.add(new Add(builder.build())); } @ZenMethod diff --git a/src/main/java/appeng/integration/modules/jei/InscriberRecipeWrapper.java b/src/main/java/appeng/integration/modules/jei/InscriberRecipeWrapper.java index f0fa4cbc4..b95282e88 100644 --- a/src/main/java/appeng/integration/modules/jei/InscriberRecipeWrapper.java +++ b/src/main/java/appeng/integration/modules/jei/InscriberRecipeWrapper.java @@ -21,11 +21,11 @@ package appeng.integration.modules.jei; import appeng.api.features.IInscriberRecipe; import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.ingredients.VanillaTypes; import mezz.jei.api.recipe.IRecipeWrapper; import net.minecraft.item.ItemStack; import java.util.ArrayList; -import java.util.Collections; import java.util.List; @@ -40,11 +40,10 @@ class InscriberRecipeWrapper implements IRecipeWrapper { @Override public void getIngredients(IIngredients ingredients) { List> inputSlots = new ArrayList<>(3); - inputSlots.add(Collections.singletonList(this.recipe.getTopOptional().orElse(ItemStack.EMPTY))); + inputSlots.add(this.recipe.getTopInputs()); inputSlots.add(this.recipe.getInputs()); - inputSlots.add(Collections.singletonList(this.recipe.getBottomOptional().orElse(ItemStack.EMPTY))); - ingredients.setInputLists(ItemStack.class, inputSlots); - - ingredients.setOutput(ItemStack.class, this.recipe.getOutput()); + inputSlots.add(this.recipe.getBottomInputs()); + ingredients.setInputLists(VanillaTypes.ITEM, inputSlots); + ingredients.setOutput(VanillaTypes.ITEM, this.recipe.getOutput()); } } diff --git a/src/main/java/appeng/recipes/handlers/InscriberHandler.java b/src/main/java/appeng/recipes/handlers/InscriberHandler.java index 63ec9dee0..953bb1d23 100644 --- a/src/main/java/appeng/recipes/handlers/InscriberHandler.java +++ b/src/main/java/appeng/recipes/handlers/InscriberHandler.java @@ -14,6 +14,7 @@ import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.common.crafting.JsonContext; import java.util.Arrays; +import java.util.Collections; import java.util.List; @@ -27,34 +28,25 @@ public class InscriberHandler implements IAERecipeFactory { JsonObject ingredients = JsonUtils.getJsonObject(json, "ingredients"); List middle = Arrays.asList(CraftingHelper.getIngredient(ingredients.get("middle"), ctx).getMatchingStacks()); - ItemStack[] top = new ItemStack[]{null}; + List top = Collections.emptyList(); if (ingredients.has("top")) { - top = CraftingHelper.getIngredient(JsonUtils.getJsonObject(ingredients, "top"), ctx).getMatchingStacks(); + top = Arrays.asList(CraftingHelper.getIngredient(JsonUtils.getJsonObject(ingredients, "top"), ctx).getMatchingStacks()); } - ItemStack[] bottom = new ItemStack[]{null}; + List bottom = Collections.emptyList(); if (ingredients.has("bottom")) { - bottom = CraftingHelper.getIngredient(JsonUtils.getJsonObject(ingredients, "bottom"), ctx).getMatchingStacks(); + bottom = Arrays.asList(CraftingHelper.getIngredient(JsonUtils.getJsonObject(ingredients, "bottom"), ctx).getMatchingStacks()); } final IInscriberRegistry reg = AEApi.instance().registries().inscriber(); - for (int i = 0; i < top.length; ++i) { - for (int j = 0; j < bottom.length; ++j) { - final IInscriberRecipeBuilder builder = reg.builder(); - builder.withOutput(result); - builder.withProcessType("press".equals(mode) ? InscriberProcessType.PRESS : InscriberProcessType.INSCRIBE); - builder.withInputs(middle); - - if (top[i] != null) { - builder.withTopOptional(top[i]); - } - if (bottom[j] != null) { - builder.withBottomOptional(bottom[j]); - } - - reg.addRecipe(builder.build()); - } + if (!top.isEmpty() || !bottom.isEmpty()) { + final IInscriberRecipeBuilder builder = reg.builder(); + builder.withOutput(result); + builder.withProcessType("press".equals(mode) ? InscriberProcessType.PRESS : InscriberProcessType.INSCRIBE); + builder.withTopOptional(top); + builder.withInputs(middle); + builder.withBottomOptional(bottom); + reg.addRecipe(builder.build()); } } - } diff --git a/src/main/java/appeng/tile/misc/TileInscriber.java b/src/main/java/appeng/tile/misc/TileInscriber.java index e78e5a5a2..8bcdc7252 100644 --- a/src/main/java/appeng/tile/misc/TileInscriber.java +++ b/src/main/java/appeng/tile/misc/TileInscriber.java @@ -65,6 +65,7 @@ import net.minecraftforge.items.IItemHandlerModifiable; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.IOException; +import java.util.Collections; import java.util.EnumSet; import java.util.List; @@ -281,20 +282,19 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable, for (final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes()) { - final boolean matchA = (plateA.isEmpty() && !recipe.getTopOptional().isPresent()) || (Platform.itemComparisons() - .isSameItem(plateA, - recipe.getTopOptional().orElse(ItemStack.EMPTY))) && // and... - ((plateB.isEmpty() && !recipe.getBottomOptional().isPresent()) || (Platform.itemComparisons() - .isSameItem(plateB, - recipe.getBottomOptional().orElse(ItemStack.EMPTY)))); + // Check if plateA matches any item in the list of top components of the recipe + final boolean matchA = plateA.isEmpty() && recipe.getTopInputs().isEmpty() || + recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(plateA, topItem)) && + (plateB.isEmpty() && recipe.getBottomInputs().isEmpty() || + recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(plateB, bottomItem))); - final boolean matchB = (plateB.isEmpty() && !recipe.getTopOptional().isPresent()) || (Platform.itemComparisons() - .isSameItem(plateB, - recipe.getTopOptional().orElse(ItemStack.EMPTY))) && // and... - ((plateA.isEmpty() && !recipe.getBottomOptional().isPresent()) || (Platform.itemComparisons() - .isSameItem(plateA, - recipe.getBottomOptional().orElse(ItemStack.EMPTY)))); + // Check if plateB matches any item in the list of top components of the recipe + final boolean matchB = plateB.isEmpty() && recipe.getTopInputs().isEmpty() || + recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(plateB, topItem)) && + (plateA.isEmpty() && recipe.getBottomInputs().isEmpty() || + recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(plateA, bottomItem))); + // If either matchA or matchB is true, iterate through the recipe's inputs if (matchA || matchB) { for (final ItemStack option : recipe.getInputs()) { if (Platform.itemComparisons().isSameItem(input, option)) { @@ -476,11 +476,11 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable, builder.withInputs(inputs).withOutput(renamedItem).withProcessType(type); if (!plateA.isEmpty()) { - builder.withTopOptional(plateA); + builder.withTopOptional(Collections.singletonList(plateA)); } if (!plateB.isEmpty()) { - builder.withBottomOptional(plateB); + builder.withBottomOptional(Collections.singletonList(plateB)); } return builder.build();