From e3c78a5583dbbfcff3d2692b5df41f371c760ea0 Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:31:28 +0800 Subject: [PATCH] More Recipe Recycling Improvements --- .../groovy-tests/recipeRecyclingTests.groovy | 23 +++++-- .../nomilabs/groovy/GroovyHelpers.java | 20 +----- .../nomilabs/groovy/ReplaceRecipe.java | 67 ++++++++++++++++++- 3 files changed, 83 insertions(+), 27 deletions(-) diff --git a/src/main/groovy-tests/recipeRecyclingTests.groovy b/src/main/groovy-tests/recipeRecyclingTests.groovy index 1aa6c316..c0d8cea7 100644 --- a/src/main/groovy-tests/recipeRecyclingTests.groovy +++ b/src/main/groovy-tests/recipeRecyclingTests.groovy @@ -7,24 +7,35 @@ import static com.nomiceu.nomilabs.groovy.GroovyHelpers.RecipeRecyclingHelpers.* // output item, ignoring count, including meta, is the same as the old output item, ignoring count, including meta // Also don't work recursively, each item that depends on these needs to be changed too -// Change a recipe's output & input +// Change a recipe's output & input, replacing by name replaceRecipeShaped("casing_assembly_control", item('gregtech:multiblock_casing', 3) * 1, [ [ore('circuitLuv'), metaitem('plate.high_power_integrated_circuit'), ore('circuitLuv')], [metaitem('sensor.iv'), metaitem('frameIridium'), metaitem('emitter.iv')], [ore('circuitLuv'), metaitem('electric.motor.iv'), ore('circuitLuv')] ]) -// Just change a recipe's output +// Change a recipe's output & input, replacing by output +replaceRecipeShaped(item('gregtech:multiblock_casing', 4) * 2, item('gregtech:multiblock_casing', 4) * 1, [ + [ore('circuitLuv'), metaitem('plate.high_power_integrated_circuit'), ore('circuitLuv')], + [metaitem('sensor.iv'), metaitem('frameIridium'), metaitem('emitter.iv')], + [ore('circuitLuv'), metaitem('electric.motor.iv'), ore('circuitLuv')] +]) + +// Just change a recipe's output, replacing by name replaceRecipeOutput("assembly_line", metaitem('assembly_line') * 4) -// Just change a recipe's input +// Just change a recipe's output, replacing by output +replaceRecipeOutput(metaitem('circuit_assembler.uv'), metaitem('circuit_assembler.uv') * 4) + +// Just change a recipe's input, replacing by name replaceRecipeInput("casing_lv", [ [metaitem('plateWroughtIron'), metaitem('plateWroughtIron'), metaitem('plateWroughtIron')], [metaitem('plateWroughtIron'), ore('toolWrench'), metaitem('plateWroughtIron')], [metaitem('plateWroughtIron'), metaitem('plateWroughtIron'), metaitem('plateWroughtIron')] ]) -replaceRecipeInput("electric_motor_hv", [ +// Just change a recipe's input, replacing by output +replaceRecipeInput(metaitem('electric.motor.hv'), [ [metaitem('plateWroughtIron'), metaitem('plateWroughtIron'), metaitem('plateWroughtIron')], [metaitem('plateWroughtIron'), ore('toolWrench'), metaitem('plateWroughtIron')], [metaitem('plateWroughtIron'), metaitem('plateWroughtIron'), metaitem('plateWroughtIron')] @@ -42,5 +53,5 @@ createRecipe(metaitem('battery_buffer.uhv.8'), [ [null, metaitem('battery_buffer.uv.8'), null], [null, null, null]]) -// Add / Change recycling to a stack -changeStackRecycling(metaitem('battery_buffer.uhv.16'), [metaitem('battery_buffer.uv.16'), metaitem('charger.uv')]) \ No newline at end of file +// Add / Change recycling to a stack, including fluids, although fluids are not included in recycling calculations +changeStackRecycling(metaitem('battery_buffer.uhv.16'), [metaitem('battery_buffer.uv.16'), metaitem('charger.uv'), fluid('soldering_alloy') * 1152]) \ No newline at end of file diff --git a/src/main/java/com/nomiceu/nomilabs/groovy/GroovyHelpers.java b/src/main/java/com/nomiceu/nomilabs/groovy/GroovyHelpers.java index d86f333b..ab26762e 100644 --- a/src/main/java/com/nomiceu/nomilabs/groovy/GroovyHelpers.java +++ b/src/main/java/com/nomiceu/nomilabs/groovy/GroovyHelpers.java @@ -91,42 +91,24 @@ private static FluidStack toFluidStack(Fluid fluid) { return new FluidStack(fluid, 1); } } - public static class RecipeRecyclingHelpers { - public static void replaceRecipeShaped(ResourceLocation name, ItemStack output, List> inputs) { - ReplaceRecipe.replaceRecipeShaped(name, output, inputs); - } + public static class RecipeRecyclingHelpers extends ReplaceRecipe { public static void replaceRecipeShaped(String name, ItemStack output, List> inputs) { if (name.contains(":")) replaceRecipeShaped(new ResourceLocation(name), output, inputs); else replaceRecipeShaped(GTUtility.gregtechId(name), output, inputs); } - public static void replaceRecipeOutput(ResourceLocation name, ItemStack output) { - ReplaceRecipe.replaceRecipeOutput(name, output); - } public static void replaceRecipeOutput(String name, ItemStack output) { if (name.contains(":")) replaceRecipeOutput(new ResourceLocation(name), output); else replaceRecipeOutput(GTUtility.gregtechId(name), output); } - public static void replaceRecipeInput(ResourceLocation name, List> inputs) { - ReplaceRecipe.replaceRecipeInput(name, inputs); - } public static void replaceRecipeInput(String name, List> inputs) { if (name.contains(":")) replaceRecipeInput(new ResourceLocation(name), inputs); else replaceRecipeInput(GTUtility.gregtechId(name), inputs); } - public static void createRecipe(String name, ItemStack output, List> inputs) { - ReplaceRecipe.createRecipe(name, output, inputs); - } - public static void createRecipe(ItemStack output, List> inputs) { - ReplaceRecipe.createRecipe(output, inputs); - } - public static void changeStackRecycling(ItemStack output, List ingredients) { - ReplaceRecipe.changeStackRecycling(output, ingredients); - } } } diff --git a/src/main/java/com/nomiceu/nomilabs/groovy/ReplaceRecipe.java b/src/main/java/com/nomiceu/nomilabs/groovy/ReplaceRecipe.java index 034342e1..a2d5eff0 100644 --- a/src/main/java/com/nomiceu/nomilabs/groovy/ReplaceRecipe.java +++ b/src/main/java/com/nomiceu/nomilabs/groovy/ReplaceRecipe.java @@ -5,12 +5,14 @@ import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; import com.cleanroommc.groovyscript.registry.ReloadableRegistryManager; import com.google.common.collect.ImmutableList; +import com.nomiceu.nomilabs.util.ItemTagMeta; import com.nomiceu.nomilabs.util.LabsNames; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; import gregtech.api.recipes.RecyclingHandler; import gregtech.api.recipes.category.GTRecipeCategory; import gregtech.api.recipes.category.RecipeCategories; +import gregtech.api.recipes.ingredients.GTRecipeFluidInput; import gregtech.api.recipes.ingredients.GTRecipeInput; import gregtech.api.recipes.ingredients.GTRecipeItemInput; import gregtech.api.recipes.ingredients.GTRecipeOreInput; @@ -22,12 +24,12 @@ import net.minecraft.item.crafting.IRecipe; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.crafting.IShapedRecipe; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.registry.ForgeRegistries; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; @@ -58,6 +60,10 @@ public static void replaceRecipeShaped(ResourceLocation name, ItemStack output, registerRecycling(output, inputs); } + public static void replaceRecipeShaped(ItemStack oldOutput, ItemStack newOutput, List> inputs) { + replaceRecipeShaped(getRecipeName(oldOutput), newOutput, inputs); + } + public static void replaceRecipeOutput(ResourceLocation name, ItemStack newOutput) { IShapedRecipe originalRecipe = validate(name, newOutput, true); var originalCount = originalRecipe.getRecipeOutput().getCount(); @@ -75,6 +81,10 @@ public static void replaceRecipeOutput(ResourceLocation name, ItemStack newOutpu LabsVirtualizedRegistries.REPLACE_RECIPE_MANAGER.registerOre(newOutput, new ItemMaterialInfo(newMaterials)); } + public static void replaceRecipeOutput(ItemStack oldOutput, ItemStack newOutput) { + replaceRecipeOutput(getRecipeName(oldOutput), newOutput); + } + public static void replaceRecipeInput(ResourceLocation name, List> newInputs) { IRecipe originalRecipe = validate(name, ItemStack.EMPTY, false); var originalOutput = originalRecipe.getRecipeOutput(); @@ -83,6 +93,10 @@ public static void replaceRecipeInput(ResourceLocation name, List> newInputs) { + replaceRecipeInput(getRecipeName(oldOutput), newInputs); + } + public static void createRecipe(String name, ItemStack output, List> input) { crafting.addShaped(LabsNames.makeGroovyName(name), output, input); registerRecycling(output, input); @@ -95,7 +109,13 @@ public static void createRecipe(ItemStack output, List> input) public static void changeStackRecycling(ItemStack output, List ingredients) { - registerRecycling(output, Collections.singletonList(ingredients)); + List gtInputs = new ArrayList<>(); + for (var input : ingredients) { + var gtInput = ofGroovyIngredientIncludingFluids(input); + if (gtInput != null) + gtInputs.add(gtInput); + } + LabsVirtualizedRegistries.REPLACE_RECIPE_MANAGER.registerOre(output, RecyclingHandler.getRecyclingIngredients(gtInputs, output.getCount())); } private static IShapedRecipe validate(ResourceLocation name, ItemStack output, boolean validateOutput) { @@ -119,6 +139,17 @@ private static IShapedRecipe validate(ResourceLocation name, ItemStack output, b return shapedRecipe; } + private static boolean isRecipeValid(ResourceLocation name) { + IRecipe originalRecipe = ForgeRegistries.RECIPES.getValue(name); + if (originalRecipe == null) + return false; + + if (!(originalRecipe instanceof IShapedRecipe)) + return false; + + return !originalRecipe.isDynamic(); + } + private static void registerRecycling(ItemStack output, List> inputs) { List gtInputs = new ArrayList<>(); for (var inputList : inputs) { @@ -154,4 +185,36 @@ private static GTRecipeInput ofGroovyIngredient(IIngredient ingredient) { } return null; } + + // TODO Remove? GTRecipeFluidInputs are not included in recycling calculations + @Nullable + private static GTRecipeInput ofGroovyIngredientIncludingFluids(IIngredient ingredient) { + var gtInput = ofGroovyIngredient(ingredient); + if (gtInput != null) return gtInput; + if ((Object) ingredient instanceof FluidStack stack) { + return new GTRecipeFluidInput(stack); + } + return null; + } + + private static ResourceLocation getRecipeName(ItemStack oldOutput) { + ResourceLocation name = null; + for (IRecipe recipe : ForgeRegistries.RECIPES) { + if (recipe.getRegistryName() != null && + isRecipeValid(recipe.getRegistryName()) && + ItemTagMeta.compare(recipe.getRecipeOutput(), oldOutput) && + recipe.getRecipeOutput().getCount() == oldOutput.getCount()) { + if (name == null) { + name = recipe.getRegistryName(); + continue; + } + throw new IllegalArgumentException("Error Finding Recipes for Output " + oldOutput + ":" + + "Too Many Recipes for Output. Max: 1."); + } + } + if (name == null) + throw new IllegalArgumentException("Error Finding Recipes for Output " + oldOutput + ":" + + "No recipes for Output. Requires: 1. Recipes must not be dynamic, and have the exact same stack, including count, metadata and tag."); + return name; + } }