From d03cc697216906643759ed410801bbed95cef137 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 14 Oct 2025 18:53:35 +0200 Subject: [PATCH 1/4] feat: added createCraftingPattern, createProcessingPattern and more to the me bridge --- .../peripheral/MEBridgePeripheral.java | 280 ++++++++++++++++-- .../configuration/PeripheralsConfig.java | 4 + .../common/util/ListUtil.java | 38 +++ .../common/util/StatusConstants.java | 12 +- 4 files changed, 305 insertions(+), 29 deletions(-) create mode 100644 src/main/java/de/srendi/advancedperipherals/common/util/ListUtil.java diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java index 6580dd5a6..4236e02a1 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java @@ -1,49 +1,49 @@ package de.srendi.advancedperipherals.common.addons.computercraft.peripheral; import appeng.api.crafting.IPatternDetails; +import appeng.api.crafting.PatternDetailsHelper; import appeng.api.networking.IGridNode; import appeng.api.networking.IManagedGridNode; import appeng.api.networking.crafting.ICraftingCPU; import appeng.api.networking.crafting.ICraftingService; import appeng.api.stacks.AEFluidKey; import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.GenericStack; import appeng.api.storage.MEStorage; import appeng.crafting.pattern.EncodedPatternItem; -import dan200.computercraft.api.lua.IArguments; -import dan200.computercraft.api.lua.LuaException; -import dan200.computercraft.api.lua.LuaFunction; -import dan200.computercraft.api.lua.LuaTable; -import dan200.computercraft.api.lua.MethodResult; -import dan200.computercraft.api.lua.ObjectLuaTable; +import appeng.parts.encoding.PatternEncodingTerminalPart; +import dan200.computercraft.api.lua.*; import dan200.computercraft.api.peripheral.IComputerAccess; import de.srendi.advancedperipherals.common.addons.APAddon; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.AEApi; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.AECraftJob; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.AEMekanismApi; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.MEFluidHandler; -import de.srendi.advancedperipherals.common.addons.appliedenergistics.MEItemHandler; +import de.srendi.advancedperipherals.common.addons.appliedenergistics.*; import de.srendi.advancedperipherals.common.addons.computercraft.owner.BlockEntityPeripheralOwner; import de.srendi.advancedperipherals.common.blocks.blockentities.MEBridgeEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; import de.srendi.advancedperipherals.common.util.EmptyLuaTable; +import de.srendi.advancedperipherals.common.util.ListUtil; import de.srendi.advancedperipherals.common.util.Pair; import de.srendi.advancedperipherals.common.util.StatusConstants; -import de.srendi.advancedperipherals.common.util.inventory.ChemicalFilter; -import de.srendi.advancedperipherals.common.util.inventory.FluidFilter; -import de.srendi.advancedperipherals.common.util.inventory.FluidUtil; -import de.srendi.advancedperipherals.common.util.inventory.GenericFilter; -import de.srendi.advancedperipherals.common.util.inventory.IStorageSystemPeripheral; -import de.srendi.advancedperipherals.common.util.inventory.InventoryUtil; -import de.srendi.advancedperipherals.common.util.inventory.ItemFilter; +import de.srendi.advancedperipherals.common.util.inventory.*; import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral; import me.ramidzkh.mekae2.ae2.MekanismKey; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.Containers; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.*; +import net.neoforged.fml.util.ObfuscationReflectionHelper; import net.neoforged.neoforge.fluids.capability.IFluidHandler; import net.neoforged.neoforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; public class MEBridgePeripheral extends BasePeripheral> implements IStorageSystemPeripheral { @@ -51,11 +51,13 @@ public class MEBridgePeripheral extends BasePeripheral(tileEntity)); this.bridge = tileEntity; this.node = tileEntity.getActionableNode(); + recipeManager = bridge.getLevel().getRecipeManager(); } public void setNode(IManagedGridNode node) { @@ -147,7 +149,127 @@ protected MethodResult importToME(@NotNull IArguments arguments, IFluidHandler t return MethodResult.of(FluidUtil.moveFluid(targetTank, fluidHandler, filter.getLeft()), null); } - + protected MethodResult removeBlankPatternsAndInsertCreatedPatterns(List patterns) { + if (patterns.isEmpty()) { + return MethodResult.of(StatusConstants.NOT_FOUND.withInfo("No matching recipe for given output")); + } + MEStorage monitor = AEApi.getMonitor(node); + MEItemHandler itemHandler = new MEItemHandler(monitor, bridge); + ItemFilter filter = ItemFilter.fromStack(new ItemStack(blankPattern)); + ItemStack removedBlankPattern = itemHandler.extractItem(filter, patterns.size(), false); + if (removedBlankPattern.getCount() < patterns.size()) { + itemHandler.insertItem(1, removedBlankPattern, false); + return MethodResult.of(StatusConstants.MISSING_BLANK_PATTERN + .withInfo("Missing " + (patterns.size() - removedBlankPattern.getCount()) + + " required blank patterns in the system")); + } + List notInsertedPatterns = patterns.stream() + .map(pattern -> itemHandler.insertItem(1, pattern, false)) + .filter(itemStack -> !itemStack.isEmpty()).toList(); + Containers.dropContents( + bridge.getLevel(), bridge.getBlockPos().above(), + new SimpleContainer(notInsertedPatterns.toArray(ItemStack[]::new))); + return MethodResult.of(StatusConstants.PATTERN_CREATED + .withInfo("Inserted " + (patterns.size() - notInsertedPatterns.size()) + " patterns, " + + notInsertedPatterns.size() + " didn't fit in the system")); + } + protected ItemStack createCraftingPatternForRecipe(RecipeHolder recipe, boolean allowSubstitutes, + boolean allowFluidSubstitutes) { + CraftingRecipe craftingRecipe = recipe.value(); + int width = 3; + int height = 3; + if (recipe.value() instanceof ShapedRecipe shaped) { + width = shaped.getWidth(); + height = shaped.getHeight(); + } + List inputs = new ArrayList<>(9); + for (int i = 0; i < craftingRecipe.getIngredients().size(); i++) { + Ingredient ing = craftingRecipe.getIngredients().get(i); + inputs.add(ing.isEmpty() ? ItemStack.EMPTY : ing.getItems()[0]); + // if next row is new row add missing empty slots to row + if ((i + 1) % width == 0) { + for (int j = width; j < 3; j++) { + inputs.add(ItemStack.EMPTY); + } + } + } + for (int j = height; j < 3; j++) { + inputs.addAll(List.of(ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY)); + } + ItemStack[] inputsArray = inputs.toArray(ItemStack[]::new); + return PatternDetailsHelper.encodeCraftingPattern(recipe, + inputsArray, + craftingRecipe.getResultItem( + bridge.getLevel().registryAccess()), + allowSubstitutes, allowFluidSubstitutes); + } + protected List createCookingPatternsForRecipe(RecipeHolder recipe) { + T cookingRecipe = recipe.value(); + ItemStack resultItem = cookingRecipe.getResultItem(bridge.getLevel().registryAccess()); + GenericStack result = new GenericStack(AEItemKey.of(resultItem), resultItem.getCount()); + List> inputs = cookingRecipe + .getIngredients() + .stream() + .map(Ingredient::getItems) + .map(stackList -> Arrays.stream(stackList) + .map(stack -> new GenericStack(AEItemKey.of(stack), stack.getCount())).toList()) + .toList(); + List patterns = new ArrayList<>(); + for (List combinations : ListUtil.cartesianProduct(inputs)) { + patterns.add(PatternDetailsHelper.encodeProcessingPattern(combinations, List.of(result))); + } + return patterns; + } + protected List createSmithingPatternsForRecipe(RecipeHolder recipe, boolean allowSubstitutes) { + SmithingRecipe smithingRecipe = recipe.value(); + ItemStack resultItem = smithingRecipe.getResultItem(bridge.getLevel().registryAccess()); + AEItemKey result = AEItemKey.of(resultItem); + List patterns = new ArrayList<>(); + Class clazz = smithingRecipe.getClass(); + Field templateField; + Field baseField; + Field additionField; + try { + templateField = ObfuscationReflectionHelper.findField(clazz, "template"); + baseField = ObfuscationReflectionHelper.findField(clazz, "base"); + additionField = ObfuscationReflectionHelper.findField(clazz, "addition"); + List template = + Arrays.stream(((Ingredient) templateField.get(smithingRecipe)).getItems()).map(AEItemKey::of).toList(); + List base = Arrays.stream(((Ingredient) baseField.get(smithingRecipe)).getItems()).map(AEItemKey::of).toList(); + List addition = Arrays.stream(((Ingredient) additionField.get(smithingRecipe)).getItems()).map(AEItemKey::of) + .toList(); + for (List combination : ListUtil.cartesianProduct(List.of(template, base, addition))) { + patterns.add(PatternDetailsHelper.encodeSmithingTablePattern(recipe, combination.get(0), combination.get(1), + combination.get(2), result, allowSubstitutes)); + } + return patterns; + } catch (Exception e) { + return patterns; + } + } + protected ItemStack createStonecuttingPatternForRecipe(RecipeHolder recipe, + boolean allowSubstitutes) { + StonecutterRecipe smithingRecipe = recipe.value(); + ItemStack resultItem = smithingRecipe.getResultItem(bridge.getLevel().registryAccess()); + AEItemKey result = AEItemKey.of(resultItem); + AEItemKey input = AEItemKey.of(smithingRecipe.getIngredients().get(0).getItems()[0]); + return PatternDetailsHelper.encodeStonecuttingPattern(recipe, input, result, allowSubstitutes); + } + protected List createGenericStacksFromLuaTable(Map table) { + List result = new ArrayList<>(); + for (Map subTable : table.values().stream().map(Map.class::cast).toList()) { + ResourceLocation resourceLocation = ResourceLocation.parse(subTable.get(1.0).toString()); + Item item = BuiltInRegistries.ITEM.get(resourceLocation); + int amount = subTable.size() > 1 ? ((Double) subTable.get(2.0)).intValue() : 1; + GenericStack stack = GenericStack.fromItemStack(new ItemStack(item, amount)); + result.add(stack); + } + return result; + } + private boolean filterRecipes(RecipeHolder recipe, String keyRegex) { + return BuiltInRegistries.ITEM.getKey(recipe.value().getResultItem(bridge.getLevel().registryAccess()).getItem()) + .toString().matches(keyRegex); + } private MethodResult notConnected(@Nullable Object defaultValue) { return MethodResult.of(defaultValue, StatusConstants.NOT_CONNECTED.toString()); } @@ -155,7 +277,16 @@ private MethodResult notConnected(@Nullable Object defaultValue) { private boolean isAvailable() { return node.hasGridBooted(); } - + private MethodResult patternEncodingInactive() { + if (!isAvailable()) + return notConnected(null); + if (!APConfig.PERIPHERALS_CONFIG.enableMEBridgePatternCreator.get()) + return MethodResult + .of(StatusConstants.PATTERN_ENCODING_DISABLED.withInfo("Pattern Encoding is disabled in config")); + if (node.getGrid().getActiveMachines(PatternEncodingTerminalPart.class).isEmpty()) + return MethodResult.of(StatusConstants.NOT_CONNECTED.withInfo("Pattern Encoder not connected")); + return null; + } @Override @LuaFunction(mainThread = true) public final boolean isConnected() { @@ -167,7 +298,112 @@ public final boolean isConnected() { public MethodResult isOnline() { return MethodResult.of(node.isOnline()); } - + @LuaFunction(mainThread = true) + public final MethodResult createCraftingPattern(IArguments arguments) throws LuaException { + MethodResult patternEncodingInactive = patternEncodingInactive(); + if (patternEncodingInactive != null) + return patternEncodingInactive; + String recipeOutput = arguments.getString(0); + boolean allowSubstitutes = arguments.optBoolean(1).orElse(true); + boolean allowFluidSubstitutes = arguments.optBoolean(2).orElse(true); + List patterns = recipeManager.getAllRecipesFor(RecipeType.CRAFTING) + .stream() + .filter(r -> filterRecipes(r, recipeOutput)) + .map(r -> createCraftingPatternForRecipe(r, allowSubstitutes, allowFluidSubstitutes)) + .toList(); + return removeBlankPatternsAndInsertCreatedPatterns(patterns); + } + @LuaFunction(mainThread = true) + public final MethodResult createSmeltingPattern(IArguments arguments) throws LuaException { + MethodResult patternEncodingInactive = patternEncodingInactive(); + if (patternEncodingInactive != null) + return patternEncodingInactive; + String recipeOutput = arguments.getString(0); + List patterns = recipeManager.getAllRecipesFor(RecipeType.SMELTING) + .stream() + .filter(r -> filterRecipes(r, recipeOutput)) + .map(this::createCookingPatternsForRecipe) + .flatMap(List::stream) + .toList(); + return removeBlankPatternsAndInsertCreatedPatterns(patterns); + } + @LuaFunction(mainThread = true) + public final MethodResult createBlastingPattern(IArguments arguments) throws LuaException { + MethodResult patternEncodingInactive = patternEncodingInactive(); + if (patternEncodingInactive != null) + return patternEncodingInactive; + String recipeOutput = arguments.getString(0); + List patterns = recipeManager.getAllRecipesFor(RecipeType.BLASTING) + .stream() + .filter(r -> filterRecipes(r, recipeOutput)) + .map(this::createCookingPatternsForRecipe) + .flatMap(List::stream) + .toList(); + return removeBlankPatternsAndInsertCreatedPatterns(patterns); + } + @LuaFunction(mainThread = true) + public final MethodResult createSmokingPattern(IArguments arguments) throws LuaException { + MethodResult patternEncodingInactive = patternEncodingInactive(); + if (patternEncodingInactive != null) + return patternEncodingInactive; + String recipeOutput = arguments.getString(0); + List patterns = recipeManager.getAllRecipesFor(RecipeType.SMOKING) + .stream() + .filter(r -> filterRecipes(r, recipeOutput)) + .map(this::createCookingPatternsForRecipe) + .flatMap(List::stream) + .toList(); + return removeBlankPatternsAndInsertCreatedPatterns(patterns); + } + @LuaFunction(mainThread = true) + public final MethodResult createSmithingPattern(IArguments arguments) throws LuaException { + MethodResult patternEncodingInactive = patternEncodingInactive(); + if (patternEncodingInactive != null) + return patternEncodingInactive; + String recipeOutput = arguments.getString(0); + boolean allowSubstitutes = arguments.optBoolean(1).orElse(true); + List patterns = recipeManager.getAllRecipesFor(RecipeType.SMITHING) + .stream() + .filter(r -> filterRecipes(r, recipeOutput)) + .filter(r -> r.value() instanceof SmithingTransformRecipe) + .flatMap(r -> createSmithingPatternsForRecipe(r, + allowSubstitutes).stream()) + .toList(); + return removeBlankPatternsAndInsertCreatedPatterns(patterns); + } + @LuaFunction(mainThread = true) + public final MethodResult createStonecuttingPattern(IArguments arguments) throws LuaException { + MethodResult patternEncodingInactive = patternEncodingInactive(); + if (patternEncodingInactive != null) + return patternEncodingInactive; + String recipeOutput = arguments.getString(0); + boolean allowSubstitutes = arguments.optBoolean(1).orElse(true); + List patterns = recipeManager.getAllRecipesFor(RecipeType.STONECUTTING) + .stream() + .filter(r -> filterRecipes(r, recipeOutput)) + .map(r -> createStonecuttingPatternForRecipe(r, + allowSubstitutes)) + .toList(); + return removeBlankPatternsAndInsertCreatedPatterns(patterns); + } + @LuaFunction(mainThread = true) + public final MethodResult createProcessingPattern(IArguments arguments) throws LuaException { + MethodResult patternEncodingInactive = patternEncodingInactive(); + if (patternEncodingInactive != null) + return patternEncodingInactive; + Map inputs = arguments.getTable(0); + Map outputs = arguments.getTable(1); + List stackInputs; + List stackOutputs; + try { + stackInputs = this.createGenericStacksFromLuaTable(inputs); + stackOutputs = this.createGenericStacksFromLuaTable(outputs); + } catch (Exception e) { + return MethodResult.of(StatusConstants.NOT_FOUND.withInfo("Invalid input or output items.")); + } + ItemStack pattern = PatternDetailsHelper.encodeProcessingPattern(stackInputs, stackOutputs); + return removeBlankPatternsAndInsertCreatedPatterns(List.of(pattern)); + } @Override @LuaFunction(mainThread = true) public final MethodResult getItem(IArguments arguments) throws LuaException { diff --git a/src/main/java/de/srendi/advancedperipherals/common/configuration/PeripheralsConfig.java b/src/main/java/de/srendi/advancedperipherals/common/configuration/PeripheralsConfig.java index 62a061140..d7e99460e 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/configuration/PeripheralsConfig.java +++ b/src/main/java/de/srendi/advancedperipherals/common/configuration/PeripheralsConfig.java @@ -52,6 +52,8 @@ public class PeripheralsConfig implements IAPConfig { // ME Bridge public final ModConfigSpec.BooleanValue enableMEBridge; + public final ModConfigSpec.BooleanValue enableMEBridgePatternCreator; + public final ModConfigSpec.BooleanValue mePatternCreationRequiresPatternEncoder; public final ModConfigSpec.IntValue meConsumption; // Rs Bridge @@ -156,6 +158,8 @@ public PeripheralsConfig() { pop("ME_Bridge", builder); enableMEBridge = builder.comment("Enable the Me Bridge or not.").define("enableMeBridge", true); + enableMEBridgePatternCreator = builder.comment("Allow the me bridge to create ae2 crafting patterns.").define("enableMEBridgePatternCreator", true); + mePatternCreationRequiresPatternEncoder = builder.comment("If true, the me bridge pattern creation only works if a pattern encoder is placed within the active network.").define("mePatternCreationRequiresPatternEncoder", true); meConsumption = builder.comment("Power consumption per tick.").defineInRange("mePowerConsumption", 10, 0, Integer.MAX_VALUE); pop("RS_Bridge", builder); diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/ListUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/ListUtil.java new file mode 100644 index 000000000..3dd2edd08 --- /dev/null +++ b/src/main/java/de/srendi/advancedperipherals/common/util/ListUtil.java @@ -0,0 +1,38 @@ +package de.srendi.advancedperipherals.common.util; + +import java.util.ArrayList; +import java.util.List; + +public class ListUtil { + /* + * private constructor to hide the public one. + */ + private ListUtil() { + } + + /** + * Used to create all possible combinations of the elements in the given lists. + * @param lists a list of lists with elements to create combinations from + * @param the element type + * @return a list containing all possible combinations in form of element lists with size equals lists.size() + */ + public static List> cartesianProduct(List> lists) { + List> result = new ArrayList<>(); + if (lists == null || lists.isEmpty() || lists.stream().anyMatch(list -> list == null || list.isEmpty())) { + return result; + } + result.addAll(lists.getFirst().stream().map(List::of).toList()); + for (int listIndex = 1; listIndex < lists.size(); listIndex++) { + List> newResult = new ArrayList<>(); + for (T element : lists.get(listIndex)) { + for (List resultList : result) { + List newList = new ArrayList<>(resultList); + newList.add(element); + newResult.add(newList); + } + } + result = newResult; + } + return result; + } +} diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/StatusConstants.java b/src/main/java/de/srendi/advancedperipherals/common/util/StatusConstants.java index 2e9a219ce..2a0db7fe3 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/StatusConstants.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/StatusConstants.java @@ -3,10 +3,8 @@ import de.srendi.advancedperipherals.common.addons.APAddon; /** - * A collection of constants used as return types for several peripherals - */ + A collection of constants used as return types for several peripherals */ public enum StatusConstants { - // Crafting Jobs CALCULATION_STARTED, CRAFTING_STARTED, @@ -34,19 +32,19 @@ public enum StatusConstants { ITEM_NOT_FOUND, // Debug message when an item couldn't be found in an/the target inventory FLUID_NOT_FOUND, CHEMICAL_NOT_FOUND, + // pattern creation + MISSING_BLANK_PATTERN, + PATTERN_CREATED, + PATTERN_ENCODING_DISABLED, // Misc NOT_CONNECTED, NOT_FOUND, // Generic not found state ADDON_NOT_LOADED, UNKNOWN_ERROR; - public String withInfo(String extraInfo) { return this + "_" + extraInfo; } - public String withInfo(APAddon addon) { return this + "_" + addon.getModId(); } - - } From 95624187f2425dbe3e142bbdf7b9c7b234c9aabe Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 14 Oct 2025 18:55:22 +0200 Subject: [PATCH 2/4] style: removed unused import in RSCraftJob.java --- .../common/addons/refinedstorage/RSCraftJob.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/refinedstorage/RSCraftJob.java b/src/main/java/de/srendi/advancedperipherals/common/addons/refinedstorage/RSCraftJob.java index edc4b7f42..6d0ec4fdd 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/refinedstorage/RSCraftJob.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/refinedstorage/RSCraftJob.java @@ -1,6 +1,5 @@ package de.srendi.advancedperipherals.common.addons.refinedstorage; -import com.refinedmods.refinedstorage.api.autocrafting.calculation.CancellationToken; import com.refinedmods.refinedstorage.api.autocrafting.preview.Preview; import com.refinedmods.refinedstorage.api.autocrafting.preview.PreviewType; import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatus; From b009e7b0a6ac67eca5861442a52353781597da56 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 14 Oct 2025 19:17:44 +0200 Subject: [PATCH 3/4] doc: added javadoc for the methods used to create me patterns in MEBridgePeripheral.java --- .../peripheral/MEBridgePeripheral.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java index 4236e02a1..3885ca50a 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java @@ -149,6 +149,13 @@ protected MethodResult importToME(@NotNull IArguments arguments, IFluidHandler t return MethodResult.of(FluidUtil.moveFluid(targetTank, fluidHandler, filter.getLeft()), null); } + /** + * removes blank patterns from the me system matching the number of given patterns and inserts the given patterns afterward. + * patterns that can not be inserted will be dropped at the location of the me bridge. + * @param patterns a list of ae2 patterns as itemStacks + * @return a {@link MethodResult}, NOT_FOUND if the given list is empty, MISSING_BLANK_PATTERN if there aren't enough blank patterns + * in the me system or PATTERN_CREATED if the process was successful. + */ protected MethodResult removeBlankPatternsAndInsertCreatedPatterns(List patterns) { if (patterns.isEmpty()) { return MethodResult.of(StatusConstants.NOT_FOUND.withInfo("No matching recipe for given output")); @@ -173,6 +180,13 @@ protected MethodResult removeBlankPatternsAndInsertCreatedPatterns(List recipe, boolean allowSubstitutes, boolean allowFluidSubstitutes) { CraftingRecipe craftingRecipe = recipe.value(); @@ -203,6 +217,12 @@ protected ItemStack createCraftingPatternForRecipe(RecipeHolder bridge.getLevel().registryAccess()), allowSubstitutes, allowFluidSubstitutes); } + /** + * creates multiple processing patterns for all combinations of inputs for the given cooking recipe + * @param recipe any type of cooking recipe (smelting, blasting, e.g.) + * @return a list of itemStacks with each itemStack representing one pattern + * @param the specific type of the cooking recipe (e.g. smeltingRecipe) + */ protected List createCookingPatternsForRecipe(RecipeHolder recipe) { T cookingRecipe = recipe.value(); ItemStack resultItem = cookingRecipe.getResultItem(bridge.getLevel().registryAccess()); @@ -220,6 +240,12 @@ protected List createCookingPattern } return patterns; } + /** + * creates multiple smithing pattern for all combinations of inputs for the given smithing recipe + * @param recipe a smithingRecipe to create a pattern for + * @param allowSubstitutes whether the me system allows substitutes + * @return a list of itemStacks with each itemStack representing one pattern + */ protected List createSmithingPatternsForRecipe(RecipeHolder recipe, boolean allowSubstitutes) { SmithingRecipe smithingRecipe = recipe.value(); ItemStack resultItem = smithingRecipe.getResultItem(bridge.getLevel().registryAccess()); @@ -247,6 +273,12 @@ protected List createSmithingPatternsForRecipe(RecipeHolder recipe, boolean allowSubstitutes) { StonecutterRecipe smithingRecipe = recipe.value(); @@ -255,6 +287,11 @@ protected ItemStack createStonecuttingPatternForRecipe(RecipeHolder createGenericStacksFromLuaTable(Map table) { List result = new ArrayList<>(); for (Map subTable : table.values().stream().map(Map.class::cast).toList()) { @@ -266,10 +303,17 @@ protected List createGenericStacksFromLuaTable(Map table) { } return result; } + /** + * used to filter recipes based on the resultItems resource location string + * @param recipe the given recipe + * @param keyRegex a regex to match against the recipes resulting item + * @return whether the resultItem of the recipe matches the given regexKey or not + */ private boolean filterRecipes(RecipeHolder recipe, String keyRegex) { return BuiltInRegistries.ITEM.getKey(recipe.value().getResultItem(bridge.getLevel().registryAccess()).getItem()) .toString().matches(keyRegex); } + private MethodResult notConnected(@Nullable Object defaultValue) { return MethodResult.of(defaultValue, StatusConstants.NOT_CONNECTED.toString()); } @@ -277,6 +321,11 @@ private MethodResult notConnected(@Nullable Object defaultValue) { private boolean isAvailable() { return node.hasGridBooted(); } + /** + * tests whether the me system is available, the pattern creation is enabled in the config and an encoding terminal is connected to + * the me system + * @return a methodResult describing the missing requirement or null if every requirement is fulfilled + */ private MethodResult patternEncodingInactive() { if (!isAvailable()) return notConnected(null); @@ -287,6 +336,7 @@ private MethodResult patternEncodingInactive() { return MethodResult.of(StatusConstants.NOT_CONNECTED.withInfo("Pattern Encoder not connected")); return null; } + @Override @LuaFunction(mainThread = true) public final boolean isConnected() { From 92d7df5bb78962032cb4b0578f9d6a5c39f9b84c Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 14 Oct 2025 19:19:13 +0200 Subject: [PATCH 4/4] doc: fixed wrongly ordered javadoc tags --- .../addons/computercraft/peripheral/MEBridgePeripheral.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java index 3885ca50a..5e756a6dd 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/MEBridgePeripheral.java @@ -220,8 +220,8 @@ protected ItemStack createCraftingPatternForRecipe(RecipeHolder /** * creates multiple processing patterns for all combinations of inputs for the given cooking recipe * @param recipe any type of cooking recipe (smelting, blasting, e.g.) - * @return a list of itemStacks with each itemStack representing one pattern * @param the specific type of the cooking recipe (e.g. smeltingRecipe) + * @return a list of itemStacks with each itemStack representing one pattern */ protected List createCookingPatternsForRecipe(RecipeHolder recipe) { T cookingRecipe = recipe.value();