From 215e9ff1fae9d2b56ab6d3ad5dc374afd528da12 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:18:23 -0800 Subject: [PATCH 1/9] create validateStackSize --- .../mods/actuallyadditions/Empowerer.java | 2 +- .../mods/betterwithmods/HopperFilters.java | 2 +- .../compat/mods/bloodmagic/AlchemyArray.java | 2 +- .../compat/mods/enderio/SliceNSplice.java | 4 +--- .../groovyscript/compat/mods/enderio/Vat.java | 10 +++----- .../compat/mods/forestry/Carpenter.java | 6 ++--- .../mods/forestry/ThermionicFabricator.java | 6 ++--- .../compat/mods/thaumcraft/Crucible.java | 2 +- .../mods/thaumcraft/InfusionCrafting.java | 2 +- .../helper/recipe/AbstractRecipeBuilder.java | 24 ++++++++++++++----- 10 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Empowerer.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Empowerer.java index fa0633d2d..ef95133fb 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Empowerer.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Empowerer.java @@ -182,7 +182,7 @@ public void validate(GroovyLog.Msg msg) { validateItems(msg, 4, 4, 1, 1); validateFluids(msg); msg.add(mainInput == null, "mainInput must be defined"); - msg.add(IngredientHelper.overMaxSize(mainInput, 1), "mainInput must have a stack size of 1"); + validateStackSize(msg, 1, "mainInput", mainInput); msg.add(energyPerStand < 0, "energyPerStand must be a non negative integer, yet it was {}", energyPerStand); msg.add(time <= 0, "time must be an integer greater than 0, yet it was {}", time); msg.add(red < 0 || red > 1, "red must be a float between 0 and 1, yet it was {}", red); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/HopperFilters.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/HopperFilters.java index 5dc16226c..18e8a73d8 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/HopperFilters.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/HopperFilters.java @@ -125,7 +125,7 @@ public void validate(GroovyLog.Msg msg) { validateItems(msg, 0, Integer.MAX_VALUE, 0, 0); validateFluids(msg); msg.add(IngredientHelper.isEmpty(filter), "filter must be defined"); - msg.add(IngredientHelper.overMaxSize(filter, 1), "Filter must have stack size of 1, got {}", filter.getAmount()); + validateStackSize(msg, 1, "filter", filter); } @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/bloodmagic/AlchemyArray.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/bloodmagic/AlchemyArray.java index 6c0578fdf..482356b34 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/bloodmagic/AlchemyArray.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/bloodmagic/AlchemyArray.java @@ -174,7 +174,7 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 1, 1); msg.add(catalyst == null, "Must have a catalyst ItemStack but didn't find any!"); - msg.add(IngredientHelper.overMaxSize(catalyst, 1), "Catalyst must have a stack size of 1!"); + validateStackSize(msg, 1, "catalyst", catalyst); } @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/enderio/SliceNSplice.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/enderio/SliceNSplice.java index 9c74bd82a..cd4479b46 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/enderio/SliceNSplice.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/enderio/SliceNSplice.java @@ -113,9 +113,7 @@ public void validate(GroovyLog.Msg msg) { int inputSize = input.getRealSize(); output.trim(); msg.add(inputSize < 1 || inputSize > 6, () -> "Must have 1 - 6 inputs, but found " + input.size()); - for (IIngredient ingredient : input) { - msg.add(IngredientHelper.overMaxSize(ingredient, 1), "Input {} must have a stack size of 1", ingredient); - } + validateStackSize(msg, 1, "input", input); msg.add(output.size() != 1, () -> "Must have exactly 1 output, but found " + output.size()); validateFluids(msg); if (energy <= 0) energy = 5000; diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/enderio/Vat.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/enderio/Vat.java index 85805cb17..7eb022b30 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/enderio/Vat.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/enderio/Vat.java @@ -9,6 +9,7 @@ import com.cleanroommc.groovyscript.helper.SimpleObjectStream; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.ingredient.IngredientList; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.helper.recipe.IRecipeBuilder; import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; import com.enderio.core.common.util.NNList; @@ -172,13 +173,8 @@ public boolean validate() { GroovyLog.Msg msg = GroovyLog.msg("Error adding EnderIO Vat recipe").error(); msg.add(IngredientHelper.isEmpty(input), () -> "fluid input must not be empty"); msg.add(IngredientHelper.isEmpty(output), () -> "fluid output must not be empty"); - for (IIngredient ingredient : itemInputs1) { - msg.add(IngredientHelper.overMaxSize(ingredient, 1), "First slot input {} must have a stack size of 1", ingredient); - } - for (IIngredient ingredient : itemInputs2) { - msg.add(IngredientHelper.overMaxSize(ingredient, 1), "Second slot input {} must have a stack size of 1", ingredient); - } - + AbstractRecipeBuilder.validateStackSize(msg, 1, "first slot input", itemInputs1); + AbstractRecipeBuilder.validateStackSize(msg, 1, "second slot input", itemInputs2); if (energy <= 0) energy = 5000; if (baseMultiplier <= 0) baseMultiplier = 1; diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java index 0faaac9fd..15b0aac5b 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java @@ -198,10 +198,8 @@ public void validate(GroovyLog.Msg msg) { validateFluids(msg, 0, 1, 0, 0); validateItems(msg, 0, 0, 1, 1); validatePattern(msg, pattern, keys); - for (IIngredient ingredient : keys.values()) { - msg.add(IngredientHelper.overMaxSize(ingredient, 1), "Grid input {} must have a stack size of 1", ingredient); - } - msg.add(IngredientHelper.overMaxSize(box, 1), "Box must have a stack size of 1, got {}", box.getAmount()); + validateStackSize(msg, 1, "grid input", keys.values()); + validateStackSize(msg, 1, "box", box); } @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/ThermionicFabricator.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/ThermionicFabricator.java index cda583507..cd77b80ba 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/ThermionicFabricator.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/ThermionicFabricator.java @@ -162,10 +162,8 @@ public void validate(GroovyLog.Msg msg) { validateItems(msg, 0, 0, 1, 1); validateFluids(msg, 1, 1, 0, 0); Carpenter.validatePattern(msg, pattern, keys); - for (IIngredient ingredient : keys.values()) { - msg.add(IngredientHelper.overMaxSize(ingredient, 1), "Grid input {} must have a stack size of 1", ingredient); - } - msg.add(IngredientHelper.overMaxSize(catalyst, 1), "Box must have a stack size of 1, got {}", catalyst.getAmount()); + validateStackSize(msg, 1, "grid input", keys.values()); + validateStackSize(msg, 1, "catalyst", catalyst); } @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/thaumcraft/Crucible.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/thaumcraft/Crucible.java index fcb6dfb93..e032afad1 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/thaumcraft/Crucible.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/thaumcraft/Crucible.java @@ -185,7 +185,7 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 0, 0, 1, 1); msg.add(IngredientHelper.isEmpty(catalyst), () -> "Catalyst must not be empty"); - msg.add(IngredientHelper.overMaxSize(catalyst, 1), () -> "Catalyst amount must be 1"); + validateStackSize(msg, 1, "catalyst", catalyst); msg.add(aspects.size() == 0, () -> "Aspects must not be empty"); if (researchKey == null) researchKey = ""; } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/thaumcraft/InfusionCrafting.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/thaumcraft/InfusionCrafting.java index 37fd11258..12ecdb47c 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/thaumcraft/InfusionCrafting.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/thaumcraft/InfusionCrafting.java @@ -207,7 +207,7 @@ public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 100, 1, 1); msg.add(IngredientHelper.isEmpty(mainInput), () -> "Main Input must not be empty"); // More than 1 item cannot be placed - msg.add(IngredientHelper.overMaxSize(mainInput, 1), () -> "Main input amount must be 1"); + validateStackSize(msg, 1, "mainInput", mainInput); if (researchKey == null) { researchKey = ""; } diff --git a/src/main/java/com/cleanroommc/groovyscript/helper/recipe/AbstractRecipeBuilder.java b/src/main/java/com/cleanroommc/groovyscript/helper/recipe/AbstractRecipeBuilder.java index 403b9a6c6..47ebe609c 100644 --- a/src/main/java/com/cleanroommc/groovyscript/helper/recipe/AbstractRecipeBuilder.java +++ b/src/main/java/com/cleanroommc/groovyscript/helper/recipe/AbstractRecipeBuilder.java @@ -16,6 +16,7 @@ import net.minecraftforge.fluids.FluidStack; import java.util.Collection; +import java.util.List; public abstract class AbstractRecipeBuilder implements IRecipeBuilder { @@ -175,12 +176,7 @@ public void validateItems(GroovyLog.Msg msg, int minInput, int maxInput, int min output.trim(); validateCustom(msg, input, minInput, maxInput, "item input"); validateCustom(msg, output, minOutput, maxOutput, "item output"); - if (GroovyScriptConfig.compat.checkInputStackCounts) { - int maxAmountAllowed = getMaxItemInput(); - for (IIngredient ingredient : input) { - msg.add(IngredientHelper.overMaxSize(ingredient, maxAmountAllowed), "Expected stack size of {} for {}, got {}", maxAmountAllowed, ingredient, ingredient.getAmount()); - } - } + validateStackSize(msg, getMaxItemInput(), "input", input); } @GroovyBlacklist @@ -193,6 +189,22 @@ public void validateFluids(GroovyLog.Msg msg) { validateFluids(msg, 0, 0, 0, 0); } + @GroovyBlacklist + public static void validateStackSize(GroovyLog.Msg msg, int maxAmountAllowed, String name, Iterable ingredients) { + if (!GroovyScriptConfig.compat.checkInputStackCounts) return; + for (var ingredient : ingredients) { + msg.add(IngredientHelper.overMaxSize(ingredient, maxAmountAllowed), "Expected stack size of {} for {} in {}, got {}", maxAmountAllowed, ingredient, name, ingredient.getAmount()); + } + } + + @GroovyBlacklist + public static void validateStackSize(GroovyLog.Msg msg, int maxAmountAllowed, String name, IIngredient... ingredients) { + if (!GroovyScriptConfig.compat.checkInputStackCounts) return; + for (var ingredient : ingredients) { + msg.add(IngredientHelper.overMaxSize(ingredient, maxAmountAllowed), "Expected stack size of {} for {} in {}, got {}", maxAmountAllowed, ingredient, name, ingredient.getAmount()); + } + } + @GroovyBlacklist public static void validateCustom(GroovyLog.Msg msg, Collection collection, int min, int max, String type) { validateCustom(msg, collection.size(), min, max, type); From cde93d1adc9bf188d078fff839a6fd226c017241 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:18:50 -0800 Subject: [PATCH 2/9] remove incorrect annotations from BWM recipeBuilder --- .../groovyscript/compat/mods/betterwithmods/Cauldron.java | 1 - .../groovyscript/compat/mods/betterwithmods/Crucible.java | 1 - .../cleanroommc/groovyscript/compat/mods/betterwithmods/Saw.java | 1 - .../groovyscript/compat/mods/betterwithmods/Turntable.java | 1 - 4 files changed, 4 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Cauldron.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Cauldron.java index 949bfac1d..e13d0f1fe 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Cauldron.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Cauldron.java @@ -22,7 +22,6 @@ public class Cauldron extends StandardListRegistry { @Example(".input(item('minecraft:clay')).output(item('minecraft:diamond')).heat(2)"), @Example(".input(item('minecraft:diamond')).output(item('minecraft:gold_ingot') * 16).ignoreHeat()") }) - @RecipeBuilderMethodDescription public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Crucible.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Crucible.java index 04bf83028..900e5ec2a 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Crucible.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Crucible.java @@ -24,7 +24,6 @@ public class Crucible extends StandardListRegistry { @Example(".input(item('minecraft:clay')).output(item('minecraft:diamond')).heat(2)"), @Example(".input(item('minecraft:diamond')).output(item('minecraft:gold_ingot') * 16).ignoreHeat()") }) - @RecipeBuilderMethodDescription public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Saw.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Saw.java index b485982a6..c9abbdc5f 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Saw.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Saw.java @@ -19,7 +19,6 @@ public class Saw extends StandardListRegistry { @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond_block')).output(item('minecraft:gold_ingot') * 16)")) - @RecipeBuilderMethodDescription public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Turntable.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Turntable.java index 4f74b95c2..fa7e70e51 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Turntable.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithmods/Turntable.java @@ -24,7 +24,6 @@ public class Turntable extends StandardListRegistry { @Example(".input(item('minecraft:gold_block')).outputBlock(blockstate('minecraft:clay')).output(item('minecraft:gold_ingot') * 5).rotations(5)"), @Example(".input(item('minecraft:clay')).output(item('minecraft:gold_ingot')).rotations(2)") }) - @RecipeBuilderMethodDescription public RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } From 3881e32099509d60efdc0601a23342866444aac2 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:19:04 -0800 Subject: [PATCH 3/9] create toItemStack from IBlockState --- .../groovyscript/helper/ingredient/IngredientHelper.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/IngredientHelper.java b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/IngredientHelper.java index 8a7631a21..1048a5dcb 100644 --- a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/IngredientHelper.java +++ b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/IngredientHelper.java @@ -39,6 +39,15 @@ public static ItemStack toItemStack(IIngredient ingredient) { return (ItemStack) (Object) ingredient; } + public static ItemStack toItemStack(IBlockState state) { + return toItemStack(state, 1); + } + + public static ItemStack toItemStack(IBlockState state, int amount) { + var block = state.getBlock(); + return new ItemStack(block, amount, block.getMetaFromState(state)); + } + public static FluidStack toFluidStack(IIngredient ingredient) { return (FluidStack) ingredient; } From 1fe74987ca819ad1b67d6e21a65b6893cb9071bc Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:19:39 -0800 Subject: [PATCH 4/9] add BWA BWE debug --- dependencies.gradle | 10 ++++++++-- gradle.properties | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 414dfa16c..a9a619cd6 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -44,8 +44,9 @@ final def mod_dependencies = [ 'the-aurorian-352137:4981736' : [project.debug_aurorian], 'avaritia_1_10-261348:3143349' : [project.debug_avaritia], 'atum-2-59621:3116599' : [project.debug_atum], - 'bwm-core-294335:2624990' : [project.debug_better_with_mods], - 'bwm-suite-246760:3289033' : [project.debug_better_with_mods], + 'better-with-addons-268326:2899407' : [project.debug_better_with_addons], + 'bwm-core-294335:2624990' : [project.debug_better_with_addons, project.debug_better_with_mods], + 'bwm-suite-246760:3289033' : [project.debug_better_with_addons, project.debug_better_with_mods], 'blood-magic-224791:2822288' : [project.debug_blood_magic], 'guide-api-228832:2645992' : [project.debug_blood_magic, project.debug_woot], 'botania-225643:3330934' : [project.debug_botania, project.debug_botania_tweaks, project.debug_botanic_additions, project.debug_extra_botany], @@ -143,6 +144,11 @@ dependencies { } } + compileOnly rfg.deobf('curse.maven:better-with-everything-896908:5202745') + if (!(project.debug_better_with_addons.toBoolean() || project.debug_better_with_mods.toBoolean()) && project.debug_better_with_everything.toBoolean()) { + runtimeOnly rfg.deobf('curse.maven:better-with-everything-896908:5202745') + } + if (project.debug_thaum.toBoolean()) { runtimeOnly 'curse.maven:thaumic_jei-285492:2705304' } diff --git a/gradle.properties b/gradle.properties index ac888afbf..a83fe109b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,6 +24,8 @@ debug_atum = false debug_aurorian = false debug_avaritia = false +debug_better_with_addons = false +debug_better_with_everything = false debug_better_with_mods = false debug_blood_magic = false debug_botania = false From 963d390b86366fc1654cd5812eeb541cfa6355a6 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:20:56 -0800 Subject: [PATCH 5/9] add betterwithaddons mixins --- .../groovyscript/core/LateMixin.java | 1 + .../betterwithaddons/BWAJEIPluginMixin.java | 37 +++++++++++++++++++ .../betterwithaddons/RotHandlerAccessor.java | 17 +++++++++ .../betterwithaddons/RotInfoAccessor.java | 22 +++++++++++ .../TileEntityLureTreeAccessor.java | 17 +++++++++ .../mixin.groovyscript.betterwithaddons.json | 13 +++++++ 6 files changed, 107 insertions(+) create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/BWAJEIPluginMixin.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/RotHandlerAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/RotInfoAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/TileEntityLureTreeAccessor.java create mode 100644 src/main/resources/mixin.groovyscript.betterwithaddons.json diff --git a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java index 865ac9426..2a3c4204d 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java @@ -14,6 +14,7 @@ public class LateMixin implements ILateMixinLoader { "advancedmortars", "appliedenergistics2", "astralsorcery", + "betterwithaddons", "betterwithmods", "bloodmagic", "botania", diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/BWAJEIPluginMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/BWAJEIPluginMixin.java new file mode 100644 index 000000000..6eb4a2fd0 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/BWAJEIPluginMixin.java @@ -0,0 +1,37 @@ +package com.cleanroommc.groovyscript.core.mixin.betterwithaddons; + +import betterwithaddons.interaction.jei.BWAJEIPlugin; +import com.cleanroommc.groovyscript.compat.mods.jei.ShapedRecipeWrapper; +import com.cleanroommc.groovyscript.compat.vanilla.ShapedCraftingRecipe; +import com.cleanroommc.groovyscript.compat.vanilla.ShapelessCraftingRecipe; +import mezz.jei.api.IJeiHelpers; +import mezz.jei.api.recipe.IRecipeWrapper; +import mezz.jei.plugins.vanilla.crafting.ShapelessRecipeWrapper; +import net.minecraft.item.crafting.IRecipe; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(value = BWAJEIPlugin.class, remap = false) +public abstract class BWAJEIPluginMixin { + + /** + * @reason This method only handles specific JEI Recipe Wrappers. This means that if there is an unknown IRecipe + * it cannot be handled. Thus, if the recipe is not a Vanilla, Forge, or CraftTweaker, it will return null + * and not display anything. + *

+ * Furthermore, due to the reference to CraftTweaker recipes, + * if CraftTweaker (an optional dependancy) is not installed, + * calling this method will generate a {@link ClassNotFoundException}. + *

+ * To resolve this we need to Inject before they are referenced, + * and the HEAD is the most logical place for it. + * @author WaitingIdly + */ + @Inject(method = "getCraftingRecipeWrapper", at = @At(value = "HEAD", ordinal = 0), cancellable = true) + private void useCustomGroovyScriptRecipe(IJeiHelpers jeiHelpers, IRecipe baseRecipe, CallbackInfoReturnable cir) { + if (baseRecipe instanceof ShapelessCraftingRecipe r) cir.setReturnValue(new ShapelessRecipeWrapper<>(jeiHelpers, r)); + if (baseRecipe instanceof ShapedCraftingRecipe r) cir.setReturnValue(new ShapedRecipeWrapper(jeiHelpers, r)); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/RotHandlerAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/RotHandlerAccessor.java new file mode 100644 index 000000000..362a2026a --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/RotHandlerAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.betterwithaddons; + +import betterwithaddons.handler.RotHandler; +import com.google.common.collect.Multimap; +import net.minecraft.item.Item; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + + +@Mixin(value = RotHandler.class, remap = false) +public interface RotHandlerAccessor { + + @Accessor("rottingItems") + static Multimap getRottingItems() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/RotInfoAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/RotInfoAccessor.java new file mode 100644 index 000000000..b65ca97c9 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/RotInfoAccessor.java @@ -0,0 +1,22 @@ +package com.cleanroommc.groovyscript.core.mixin.betterwithaddons; + +import betterwithaddons.handler.RotHandler; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(value = RotHandler.RotInfo.class, remap = false) +public interface RotInfoAccessor { + + @Accessor("itemStack") + ItemStack getItemStack(); + + @Accessor("rottedStack") + ItemStack getRottedStack(); + + @Accessor("baseName") + String getBaseName(); + + @Accessor("spoilTime") + long getSpoilTime(); +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/TileEntityLureTreeAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/TileEntityLureTreeAccessor.java new file mode 100644 index 000000000..b8d86982a --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/betterwithaddons/TileEntityLureTreeAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.betterwithaddons; + +import betterwithaddons.tileentity.TileEntityLureTree; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.ArrayList; + +@Mixin(value = TileEntityLureTree.class, remap = false) +public interface TileEntityLureTreeAccessor { + + @Accessor("BLACKLIST") + static ArrayList> getBlacklist() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/resources/mixin.groovyscript.betterwithaddons.json b/src/main/resources/mixin.groovyscript.betterwithaddons.json new file mode 100644 index 000000000..e523d651d --- /dev/null +++ b/src/main/resources/mixin.groovyscript.betterwithaddons.json @@ -0,0 +1,13 @@ +{ + "package": "com.cleanroommc.groovyscript.core.mixin.betterwithaddons", + "refmap": "mixins.groovyscript.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "BWAJEIPluginMixin", + "RotHandlerAccessor", + "RotInfoAccessor", + "TileEntityLureTreeAccessor" + ] +} \ No newline at end of file From 0afd38f8f686faad11bb792d1523fe417072a8df Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:21:51 -0800 Subject: [PATCH 6/9] implement BWA content --- .../groovyscript/compat/mods/ModSupport.java | 2 + .../betterwithaddons/BetterWithAddons.java | 44 +++++ .../mods/betterwithaddons/DryingBox.java | 85 ++++++++++ .../compat/mods/betterwithaddons/FireNet.java | 86 ++++++++++ .../compat/mods/betterwithaddons/Infuser.java | 56 +++++++ .../InfuserRecipeBuilder.java | 110 ++++++++++++ .../mods/betterwithaddons/LureTree.java | 118 +++++++++++++ .../compat/mods/betterwithaddons/Packing.java | 94 +++++++++++ .../compat/mods/betterwithaddons/Rotting.java | 158 ++++++++++++++++++ .../compat/mods/betterwithaddons/SandNet.java | 99 +++++++++++ .../mods/betterwithaddons/SoakingBox.java | 85 ++++++++++ .../compat/mods/betterwithaddons/Spindle.java | 95 +++++++++++ .../compat/mods/betterwithaddons/Tatara.java | 84 ++++++++++ .../mods/betterwithaddons/Transmutation.java | 94 +++++++++++ .../mods/betterwithaddons/WaterNet.java | 88 ++++++++++ .../assets/groovyscript/lang/en_us.lang | 56 +++++++ 16 files changed, 1354 insertions(+) create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/BetterWithAddons.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/DryingBox.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/FireNet.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Infuser.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/InfuserRecipeBuilder.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/LureTree.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Packing.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Rotting.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/SandNet.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/SoakingBox.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Spindle.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Tatara.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Transmutation.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/WaterNet.java diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java index a2e660f2c..402a06cee 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -13,6 +13,7 @@ import com.cleanroommc.groovyscript.compat.mods.astralsorcery.AstralSorcery; import com.cleanroommc.groovyscript.compat.mods.atum.Atum; import com.cleanroommc.groovyscript.compat.mods.avaritia.Avaritia; +import com.cleanroommc.groovyscript.compat.mods.betterwithaddons.BetterWithAddons; import com.cleanroommc.groovyscript.compat.mods.betterwithmods.BetterWithMods; import com.cleanroommc.groovyscript.compat.mods.bloodmagic.BloodMagic; import com.cleanroommc.groovyscript.compat.mods.botania.Botania; @@ -91,6 +92,7 @@ public class ModSupport { public static final GroovyContainer ASTRAL_SORCERY = new InternalModContainer<>("astralsorcery", "Astral Sorcery", AstralSorcery::new, "astral"); public static final GroovyContainer ATUM = new InternalModContainer<>("atum", "Atum 2", Atum::new); public static final GroovyContainer AVARITIA = new InternalModContainer<>("avaritia", "Avaritia", Avaritia::new); + public static final GroovyContainer BETTER_WITH_ADDONS = new InternalModContainer<>("betterwithaddons", "Better With Addons", BetterWithAddons::new); public static final GroovyContainer BETTER_WITH_MODS = new InternalModContainer<>("betterwithmods", "Better With Mods", BetterWithMods::new); public static final GroovyContainer BLOOD_MAGIC = new InternalModContainer<>("bloodmagic", "Blood Magic: Alchemical Wizardry", BloodMagic::new, "bm"); public static final GroovyContainer BOTANIA = new InternalModContainer<>("botania", "Botania", Botania::new); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/BetterWithAddons.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/BetterWithAddons.java new file mode 100644 index 000000000..c401df4dc --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/BetterWithAddons.java @@ -0,0 +1,44 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.util.IngredientSized; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; +import net.minecraft.item.crafting.Ingredient; +import net.minecraftforge.fml.common.Loader; + +public class BetterWithAddons extends GroovyPropertyContainer { + + public final DryingBox dryingBox = new DryingBox(); + public final FireNet fireNet = new FireNet(); + public final Infuser infuser = new Infuser(); + public final LureTree lureTree = new LureTree(); + public final Packing packing; + public final Rotting rotting = new Rotting(); + public final SandNet sandNet = new SandNet(); + public final SoakingBox soakingBox = new SoakingBox(); + public final Spindle spindle = new Spindle(); + public final Tatara tatara = new Tatara(); + public final Transmutation transmutation = new Transmutation(); + public final WaterNet waterNet = new WaterNet(); + + public BetterWithAddons() { + // the format of "PackingRecipe" has changed, and we cannot build against both. + packing = isBetterWithEverything() ? null : new Packing(); + } + + /** + * Because Better With Addons checks if the ingredient is an instanceof {@link betterwithaddons.util.IHasSize IHasSize} + * to determine if the Ingredient has an amount, we have to use their custom Ingredient. + *

+ * If this isn't used, then the recipe may appear correctly in JEI but will actually only consume 1 when done in-game. + */ + public static Ingredient fromIIngredient(IIngredient ingredient) { + return new IngredientSized(ingredient.toMcIngredient(), ingredient.getAmount()); + } + + public static boolean isBetterWithEverything() { + var entry = Loader.instance().getIndexedModList().get("betterwithmods"); + if (entry == null) return false; + return entry.getMetadata().authorList.contains("ACGaming"); // TODO identify a better way to do this, if one exists + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/DryingBox.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/DryingBox.java new file mode 100644 index 000000000..e674627ca --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/DryingBox.java @@ -0,0 +1,85 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.block.EriottoMod.BlockCherryBox; +import betterwithaddons.crafting.manager.CraftingManagerDryingBox; +import betterwithaddons.crafting.recipes.CherryBoxRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class DryingBox extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay') * 4)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerDryingBox.instance().getRecipes(); + } + + @MethodDescription(example = @Example("item('betterwithaddons:japanmat:2')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeInputs()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('minecraft:sponge')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeOutputs()) { + if (output.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Drying Box recipe"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable CherryBoxRecipe register() { + if (!validate()) return null; + CherryBoxRecipe recipe = new CherryBoxRecipe(BlockCherryBox.CherryBoxType.DRYING, BetterWithAddons.fromIIngredient(input.get(0)), output.get(0)); + ModSupport.BETTER_WITH_ADDONS.get().dryingBox.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/FireNet.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/FireNet.java new file mode 100644 index 000000000..b6fc35518 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/FireNet.java @@ -0,0 +1,86 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.block.EriottoMod.BlockNettedScreen; +import betterwithaddons.crafting.manager.CraftingManagerFireNet; +import betterwithaddons.crafting.recipes.NetRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription(admonition = @Admonition("groovyscript.wiki.betterwithaddons.fire_net.note0")) +public class FireNet extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay') * 4, item('minecraft:diamond'), item('minecraft:diamond') * 2)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerFireNet.getInstance().getRecipes(); + } + + @MethodDescription(example = @Example("item('betterwithaddons:iron_sand')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getInput()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('betterwithaddons:japanmat:12')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getOutput()) { + if (output.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(gte = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Fire Net recipe"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, Integer.MAX_VALUE); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable NetRecipe register() { + if (!validate()) return null; + NetRecipe recipe = new NetRecipe(BlockNettedScreen.SifterType.FIRE, BetterWithAddons.fromIIngredient(input.get(0)), 0, output.toArray(new ItemStack[0])); + ModSupport.BETTER_WITH_ADDONS.get().fireNet.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Infuser.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Infuser.java new file mode 100644 index 000000000..4e2644afb --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Infuser.java @@ -0,0 +1,56 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.crafting.manager.CraftingManagerInfuser; +import betterwithaddons.crafting.recipes.infuser.InfuserRecipe; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.Example; +import com.cleanroommc.groovyscript.api.documentation.annotations.MethodDescription; +import com.cleanroommc.groovyscript.api.documentation.annotations.RecipeBuilderDescription; +import com.cleanroommc.groovyscript.api.documentation.annotations.RegistryDescription; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; + +import java.util.Collection; + +@RegistryDescription +public class Infuser extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".output(item('minecraft:stone')).matrix('BXX', 'X B').key('B', item('minecraft:stone')).key('X', item('minecraft:gold_ingot')).spirits(1).mirrored()"), + @Example(".output(item('minecraft:diamond') * 32).matrix([[item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')]]).spirits(6)") + }) + public InfuserRecipeBuilder.Shaped shapedBuilder() { + return new InfuserRecipeBuilder.Shaped(); + } + + @RecipeBuilderDescription(example = { + @Example(".output(item('minecraft:clay') * 8).input(item('minecraft:stone'), item('minecraft:stone'), item('minecraft:stone'))"), + @Example(".output(item('minecraft:clay') * 32).input(item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond')).spirits(8)") + }) + public InfuserRecipeBuilder.Shapeless shapelessBuilder() { + return new InfuserRecipeBuilder.Shapeless(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerInfuser.getInstance().getRecipeList(); + } + + @MethodDescription(example = @Example("item('betterwithaddons:japanmat:16')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var ingredient : r.internal.getIngredients()) { + for (var stack : ingredient.getMatchingStacks()) { + if (input.test(stack)) { + return doAddBackup(r); + } + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('betterwithaddons:ya')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.internal.getRecipeOutput()) && doAddBackup(r)); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/InfuserRecipeBuilder.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/InfuserRecipeBuilder.java new file mode 100644 index 000000000..b6b745ea8 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/InfuserRecipeBuilder.java @@ -0,0 +1,110 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.crafting.recipes.infuser.InfuserRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.documentation.annotations.Comp; +import com.cleanroommc.groovyscript.api.documentation.annotations.Property; +import com.cleanroommc.groovyscript.api.documentation.annotations.RecipeBuilderMethodDescription; +import com.cleanroommc.groovyscript.api.documentation.annotations.RecipeBuilderRegistrationMethod; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.compat.vanilla.ShapedCraftingRecipe; +import com.cleanroommc.groovyscript.compat.vanilla.ShapelessCraftingRecipe; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.registry.AbstractCraftingRecipeBuilder; + +public interface InfuserRecipeBuilder { + + @RecipeBuilderMethodDescription + InfuserRecipeBuilder spirits(int spirits); + + class Shaped extends AbstractCraftingRecipeBuilder.AbstractShaped implements InfuserRecipeBuilder { + + @Property(comp = @Comp(gte = 0)) + protected int spirits; + + public Shaped() { + super(3, 3); + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_infuser_shaped_"; + } + + @Override + @RecipeBuilderMethodDescription + public Shaped spirits(int spirits) { + this.spirits = spirits; + return this; + } + + public boolean validate() { + GroovyLog.Msg msg = GroovyLog.msg("Error adding shaped Infuser Crafting recipe").error(); + msg.add((keyBasedMatrix == null || keyBasedMatrix.length == 0) && (ingredientMatrix == null || ingredientMatrix.isEmpty()), () -> "No matrix was defined"); + msg.add(keyBasedMatrix != null && ingredientMatrix != null, () -> "A key based matrix AND a ingredient based matrix was defined. This is not allowed!"); + msg.add(IngredientHelper.isEmpty(this.output), () -> "Output must not be empty"); + msg.add(spirits < 0, "spirits must be a nonnegative integer, yet it was {}", spirits); + return !msg.postIfNotEmpty(); + } + + @Override + @RecipeBuilderRegistrationMethod + public InfuserRecipe register() { + if (!validate()) return null; + GroovyLog.Msg msg = GroovyLog.msg("Error adding shaped Infuser Crafting recipe").error(); + + ShapedCraftingRecipe recipe = null; + if (keyBasedMatrix != null) { + recipe = validateShape(msg, errors, keyBasedMatrix, keyMap, ((width1, height1, ingredients) -> new ShapedCraftingRecipe(output, ingredients, width1, height1, mirrored, recipeFunction, recipeAction))); + } else if (ingredientMatrix != null) { + recipe = validateShape(msg, ingredientMatrix, ((width1, height1, ingredients) -> new ShapedCraftingRecipe(output.copy(), ingredients, width1, height1, mirrored, recipeFunction, recipeAction))); + } + if (msg.postIfNotEmpty()) return null; + + InfuserRecipe external = new InfuserRecipe(recipe, this.spirits); + ModSupport.BETTER_WITH_ADDONS.get().infuser.add(external); + return external; + } + } + + class Shapeless extends AbstractCraftingRecipeBuilder.AbstractShapeless implements InfuserRecipeBuilder { + + @Property(comp = @Comp(gte = 0)) + protected int spirits; + + public Shapeless() { + super(3, 3); + } + + @Override + public String getRecipeNamePrefix() { + return "groovyscript_infuser_shapeless_"; + } + + @Override + @RecipeBuilderMethodDescription + public Shapeless spirits(int spirits) { + this.spirits = spirits; + return this; + } + + public boolean validate() { + GroovyLog.Msg msg = GroovyLog.msg("Error adding shapeless Infuser Crafting recipe").error(); + msg.add(IngredientHelper.isEmpty(this.output), () -> "Output must not be empty"); + msg.add(ingredients.isEmpty(), () -> "inputs must not be empty"); + msg.add(ingredients.size() > width * height, () -> "maximum inputs are " + (width * height) + " but found " + ingredients.size()); + msg.add(spirits < 0, "spirits must be a nonnegative integer, yet it was {}", spirits); + return !msg.postIfNotEmpty(); + } + + @Override + @RecipeBuilderRegistrationMethod + public InfuserRecipe register() { + if (!validate()) return null; + ShapelessCraftingRecipe recipe = new ShapelessCraftingRecipe(output, ingredients, recipeFunction, recipeAction); + InfuserRecipe external = new InfuserRecipe(recipe, this.spirits); + ModSupport.BETTER_WITH_ADDONS.get().infuser.add(external); + return external; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/LureTree.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/LureTree.java new file mode 100644 index 000000000..7a816ff50 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/LureTree.java @@ -0,0 +1,118 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.tileentity.TileEntityLureTree; +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.core.mixin.betterwithaddons.TileEntityLureTreeAccessor; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.AbstractReloadableStorage; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.entity.Entity; +import net.minecraftforge.fml.common.registry.EntityEntry; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription(category = RegistryDescription.Category.ENTRIES, admonition = @Admonition(value = "groovyscript.wiki.betterwithaddons.lure_tree.note0", type = Admonition.Type.INFO)) +public class LureTree extends StandardListRegistry { + + private final AbstractReloadableStorage> blacklistStorage = new AbstractReloadableStorage<>(); + + @Override + @GroovyBlacklist + @ApiStatus.Internal + public void onReload() { + super.onReload(); + getBlacklist().removeAll(blacklistStorage.removeScripted()); + getBlacklist().addAll(blacklistStorage.restoreFromBackup()); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).food(1000)"), + @Example(".input(item('minecraft:gold_ingot')).food(4)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return TileEntityLureTree.getTreeFoods(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public Collection> getBlacklist() { + return TileEntityLureTreeAccessor.getBlacklist(); + } + + @MethodDescription(example = @Example("item('minecraft:rotten_flesh')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> input.test(r.stack) && doAddBackup(r)); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public boolean addBlacklist(Class entity) { + return getBlacklist().add(entity) && blacklistStorage.addScripted(entity); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("entity('minecraft:chicken')")) + public boolean addBlacklist(EntityEntry entity) { + return addBlacklist(entity.getEntityClass()); + } + + @MethodDescription + public boolean removeBlacklist(Class entity) { + return getBlacklist().removeIf(r -> entity.equals(r) && blacklistStorage.addBackup(r)); + } + + @MethodDescription + public boolean removeBlacklist(EntityEntry entity) { + return removeBlacklist(entity.getEntityClass()); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gte = 0)) + private int food; + + @RecipeBuilderMethodDescription + public RecipeBuilder food(int food) { + this.food = food; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Lure Tree entry"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 0, 0); + validateFluids(msg); + msg.add(food < 0, "food must be greater than or equal to 0, yet it was {}", food); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable TileEntityLureTree.TreeFood register() { + if (!validate()) return null; + TileEntityLureTree.TreeFood recipe = null; + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new TileEntityLureTree.TreeFood(stack, food); + ModSupport.BETTER_WITH_ADDONS.get().lureTree.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Packing.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Packing.java new file mode 100644 index 000000000..0e973d0de --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Packing.java @@ -0,0 +1,94 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.crafting.manager.CraftingManagerPacking; +import betterwithaddons.crafting.recipes.PackingRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class Packing extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:gold_ingot')).compress(blockstate('minecraft:clay'))"), + @Example(".input(item('minecraft:clay') * 10).compress(blockstate('minecraft:diamond_block'))"), + @Example(".input(item('minecraft:diamond')).compress(blockstate('minecraft:dirt')).jeiOutput(item('minecraft:diamond') * 64)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerPacking.getInstance().getRecipes(); + } + + @MethodDescription(example = @Example("blockstate('minecraft:gravel')")) + public boolean removeByOutput(IBlockState output) { + return getRecipes().removeIf(r -> output.equals(r.output) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('minecraft:clay_ball')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeInputs()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(not = "null")) + private IBlockState compress; + @Property(defaultValue = "compress as ItemStack", comp = @Comp(not = "null")) + private ItemStack jeiOutput; + + @RecipeBuilderMethodDescription + public RecipeBuilder compress(IBlockState compress) { + this.compress = compress; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder jeiOutput(ItemStack jeiOutput) { + this.jeiOutput = jeiOutput; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Packing recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 0, 0); + validateFluids(msg); + msg.add(compress == null, "compress cannot be null, yet it was"); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable PackingRecipe register() { + if (!validate()) return null; + PackingRecipe recipe = new PackingRecipe(BetterWithAddons.fromIIngredient(input.get(0)), compress); + recipe.setJeiOutput(IngredientHelper.isEmpty(jeiOutput) ? IngredientHelper.toItemStack(compress) : jeiOutput); + ModSupport.BETTER_WITH_ADDONS.get().packing.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Rotting.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Rotting.java new file mode 100644 index 000000000..22be4e306 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Rotting.java @@ -0,0 +1,158 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.handler.RotHandler; +import betterwithaddons.handler.RotHandler.RotInfo; +import betterwithaddons.interaction.InteractionBWA; +import betterwithaddons.item.ModItems; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.core.mixin.betterwithaddons.RotHandlerAccessor; +import com.cleanroommc.groovyscript.core.mixin.betterwithaddons.RotInfoAccessor; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import com.google.common.collect.Multimap; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +@RegistryDescription(category = RegistryDescription.Category.ENTRIES, admonition = @Admonition(value = "groovyscript.wiki.betterwithaddons.rotting.note0", type = Admonition.Type.WARNING)) +public class Rotting extends VirtualizedRegistry> { + + private static Item toKey(RotInfo recipe) { + return ((RotInfoAccessor) recipe).getItemStack().getItem(); + } + + private static Map.Entry toEntry(RotInfo recipe) { + return Pair.of(toKey(recipe), recipe); + } + + @Override + public boolean isEnabled() { + return InteractionBWA.ROTTEN_FOOD; + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:gold_ingot'))"), + @Example(".input(item('placeholdername:snack')).time(100).key('groovy_example').rotted(item('minecraft:clay') * 4)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(recipe -> getEntries().entries().removeIf(r -> r.getKey().equals(recipe.getKey()) && r.getValue().equals(recipe.getValue()))); + restoreFromBackup().forEach(r -> getEntries().put(r.getKey(), r.getValue())); + } + + public Multimap getEntries() { + return RotHandlerAccessor.getRottingItems(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, priority = 500) + public boolean add(RotInfo recipe) { + return recipe != null && getEntries().put(toKey(recipe), recipe) && doAddScripted(toEntry(recipe)); + } + + @MethodDescription(priority = 500) + public boolean add(Map.Entry recipe) { + return recipe != null && getEntries().put(recipe.getKey(), recipe.getValue()) && doAddScripted(recipe); + } + + @MethodDescription(priority = 500) + public boolean remove(Map.Entry recipe) { + return recipe != null && getEntries().entries().removeIf(r -> r == recipe) && doAddBackup(recipe); + } + + @MethodDescription(priority = 500) + public boolean remove(RotInfo recipe) { + return recipe != null && getEntries().entries().removeIf(r -> r.getValue() == recipe) && doAddBackup(toEntry(recipe)); + } + + @MethodDescription(example = @Example("item('betterwithaddons:food_cooked_rice')")) + public boolean removeByInput(IIngredient input) { + return getEntries().entries().removeIf(r -> input.test(((RotInfoAccessor) r.getValue()).getItemStack()) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('minecraft:rotten_flesh')")) + public boolean removeByOutput(IIngredient output) { + return getEntries().entries().removeIf(r -> output.test(((RotInfoAccessor) r.getValue()).getRottedStack()) && doAddBackup(r)); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + var recipes = getEntries(); + recipes.entries().forEach(this::addBackup); + recipes.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream> streamRecipes() { + return new SimpleObjectStream<>(getEntries().entries()).setRemover(this::remove); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(defaultValue = "InteractionBWA.MISC_ROT_TIME", comp = @Comp(gte = 1)) + private long time = InteractionBWA.MISC_ROT_TIME; + @Property(defaultValue = "food", comp = @Comp(not = "null")) + private String key = "food"; + @Property(defaultValue = "new ItemStack(ModItems.ROTTEN_FOOD)", comp = @Comp(not = "empty")) + private ItemStack rotted = new ItemStack(ModItems.ROTTEN_FOOD); + + @RecipeBuilderMethodDescription + public RecipeBuilder time(long time) { + this.time = time; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder key(String key) { + this.key = key; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder rotted(ItemStack rotted) { + this.rotted = rotted; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Rotting recipe"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 0, 0); + validateFluids(msg); + msg.add(time < 0, "time must be greater than or equal to 0, yet it was {}", time); + msg.add(rotted == null || rotted.isEmpty(), "rotted cannot be null or empty, yet it was"); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable RotHandler.RotInfo register() { + if (!validate()) return null; + RotHandler.RotInfo recipe = null; + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new RotHandler.RotInfo(stack, time, key, rotted); + ModSupport.BETTER_WITH_ADDONS.get().rotting.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/SandNet.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/SandNet.java new file mode 100644 index 000000000..5ebc2ea55 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/SandNet.java @@ -0,0 +1,99 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.block.EriottoMod.BlockNettedScreen; +import betterwithaddons.crafting.manager.CraftingManagerSandNet; +import betterwithaddons.crafting.recipes.NetRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class SandNet extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay'))"), + @Example(".input(item('minecraft:diamond')).output(item('minecraft:gold_ingot')).sand(2)"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay') * 4, item('minecraft:diamond'), item('minecraft:diamond') * 2).sand(5)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerSandNet.getInstance().getRecipes(); + } + + @MethodDescription(example = @Example("item('minecraft:iron_ingot')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getInput()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @MethodDescription(example = { + @Example("item('minecraft:sand')"), @Example("item('betterwithaddons:iron_sand')") + }) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getOutput()) { + if (output.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(gte = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gte = 0, lte = 8)) + private int sand; + + @RecipeBuilderMethodDescription + public RecipeBuilder sand(int sand) { + this.sand = sand; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Sand Net recipe"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, Integer.MAX_VALUE); + validateFluids(msg); + msg.add(sand < 0 || sand > 8, "sand must be greater than or equal to 0 and less than or equal to 8, yet it was {}", sand); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable NetRecipe register() { + if (!validate()) return null; + NetRecipe recipe = new NetRecipe(BlockNettedScreen.SifterType.SAND, BetterWithAddons.fromIIngredient(input.get(0)), sand, output.toArray(new ItemStack[0])); + ModSupport.BETTER_WITH_ADDONS.get().sandNet.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/SoakingBox.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/SoakingBox.java new file mode 100644 index 000000000..7f4bd8930 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/SoakingBox.java @@ -0,0 +1,85 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.block.EriottoMod.BlockCherryBox; +import betterwithaddons.crafting.manager.CraftingManagerSoakingBox; +import betterwithaddons.crafting.recipes.CherryBoxRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class SoakingBox extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay') * 4)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerSoakingBox.instance().getRecipes(); + } + + @MethodDescription(example = @Example("item('betterwithaddons:bamboo')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeInputs()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('betterwithaddons:japanmat:8')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeOutputs()) { + if (output.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Soaking Box recipe"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable CherryBoxRecipe register() { + if (!validate()) return null; + CherryBoxRecipe recipe = new CherryBoxRecipe(BlockCherryBox.CherryBoxType.SOAKING, BetterWithAddons.fromIIngredient(input.get(0)), output.get(0)); + ModSupport.BETTER_WITH_ADDONS.get().soakingBox.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Spindle.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Spindle.java new file mode 100644 index 000000000..7ba87f7a3 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Spindle.java @@ -0,0 +1,95 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.crafting.manager.CraftingManagerSpindle; +import betterwithaddons.crafting.recipes.SpindleRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class Spindle extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay'))"), + @Example(".input(item('minecraft:clay') * 3).output(item('minecraft:diamond')).popoff()"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay') * 4)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerSpindle.getInstance().getRecipes(); + } + + @MethodDescription(example = @Example("item('minecraft:vine')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeInputs()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('betterwithaddons:bolt')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getOutput()) { + if (output.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(gte = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property + private boolean popoff; + + @RecipeBuilderMethodDescription + public RecipeBuilder popoff(boolean popoff) { + this.popoff = popoff; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder popoff() { + return this.popoff(!popoff); + } + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Spindle recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, Integer.MAX_VALUE); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable SpindleRecipe register() { + if (!validate()) return null; + SpindleRecipe recipe = new SpindleRecipe(popoff, BetterWithAddons.fromIIngredient(input.get(0)), output.toArray(new ItemStack[0])); + ModSupport.BETTER_WITH_ADDONS.get().spindle.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Tatara.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Tatara.java new file mode 100644 index 000000000..bca79cf67 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Tatara.java @@ -0,0 +1,84 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.crafting.manager.CraftingManagerTatara; +import betterwithaddons.crafting.recipes.SmeltingRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class Tatara extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay') * 4)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerTatara.instance().getRecipes(); + } + + @MethodDescription(example = @Example("item('betterwithaddons:japanmat:20')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeInputs()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('betterwithaddons:kera')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeOutputs()) { + if (output.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Tatara recipe"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable SmeltingRecipe register() { + if (!validate()) return null; + SmeltingRecipe recipe = new SmeltingRecipe(BetterWithAddons.fromIIngredient(input.get(0)), output.get(0)); + ModSupport.BETTER_WITH_ADDONS.get().tatara.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Transmutation.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Transmutation.java new file mode 100644 index 000000000..85a268a5f --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/Transmutation.java @@ -0,0 +1,94 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.crafting.manager.CraftingManagerInfuserTransmutation; +import betterwithaddons.crafting.recipes.infuser.TransmutationRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class Transmutation extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay')).spirits(0)"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay') * 4).spirits(5)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerInfuserTransmutation.getInstance().getRecipes(); + } + + @MethodDescription(example = @Example("item('minecraft:reeds')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeInputs()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('betterwithaddons:crop_rice')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getRecipeOutputs()) { + if (output.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gte = 0)) + private int spirits; + + @RecipeBuilderMethodDescription + public RecipeBuilder spirits(int spirits) { + this.spirits = spirits; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Transmutation recipe"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + msg.add(spirits < 0, "spirits must be greater than or equal to 0, yet it was {}", spirits); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable TransmutationRecipe register() { + if (!validate()) return null; + TransmutationRecipe recipe = new TransmutationRecipe(BetterWithAddons.fromIIngredient(input.get(0)), spirits, output.get(0)); + ModSupport.BETTER_WITH_ADDONS.get().transmutation.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/WaterNet.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/WaterNet.java new file mode 100644 index 000000000..39f21d325 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/WaterNet.java @@ -0,0 +1,88 @@ +package com.cleanroommc.groovyscript.compat.mods.betterwithaddons; + +import betterwithaddons.block.EriottoMod.BlockNettedScreen; +import betterwithaddons.crafting.manager.CraftingManagerWaterNet; +import betterwithaddons.crafting.recipes.NetRecipe; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class WaterNet extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay') * 4, item('minecraft:diamond'), item('minecraft:diamond') * 2)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CraftingManagerWaterNet.getInstance().getRecipes(); + } + + @MethodDescription(example = @Example("item('betterwithaddons:iron_sand')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getInput()) { + if (input.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @MethodDescription(example = { + @Example("item('betterwithaddons:food_sashimi')"), @Example("item('betterwithaddons:food_fugu_sac')") + }) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> { + for (var itemstack : r.getOutput()) { + if (output.test(itemstack)) { + return doAddBackup(r); + } + } + return false; + }); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(gte = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Override + public String getErrorMsg() { + return "Error adding Better With Addons Water Net recipe"; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, Integer.MAX_VALUE); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable NetRecipe register() { + if (!validate()) return null; + NetRecipe recipe = new NetRecipe(BlockNettedScreen.SifterType.WATER, BetterWithAddons.fromIIngredient(input.get(0)), 0, output.toArray(new ItemStack[0])); + ModSupport.BETTER_WITH_ADDONS.get().waterNet.add(recipe); + return recipe; + } + } +} diff --git a/src/main/resources/assets/groovyscript/lang/en_us.lang b/src/main/resources/assets/groovyscript/lang/en_us.lang index 42d32fc42..22f42ce02 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -490,6 +490,62 @@ groovyscript.wiki.atum.spinning_wheel.description=Converts three input items int groovyscript.wiki.atum.spinning_wheel.rotations.value=Sets the amount of rotation required to convert the input into the output +# Better With Addons +groovyscript.wiki.betterwithaddons.drying_box.title=Drying Unit +groovyscript.wiki.betterwithaddons.drying_box.description=Converts an input item into an output itemstack if placed within the appropriate multiblock. The multiblock is Sandstone directly below the Drying Box, 8 Sand around the Drying Box, and a Dead Bush placed on the Sand. Only functions in a non-snowy biome with sky access during the day, and functions twice as fast when in a hot biome. + +groovyscript.wiki.betterwithaddons.fire_net.title=Fire Net +groovyscript.wiki.betterwithaddons.fire_net.description=Converts an input item into any number of output itemstacks if placed within the appropriate multiblock. The multiblock is Lava or Fire directly below the Netted Screen, 8 Stone Brick around the Lava or Fire, and 8 Slat Blocks placed around the Netted Screen. +groovyscript.wiki.betterwithaddons.fire_net.note0=Because the Fire Net needs Lava/Fire below the net to work, items that are output below the net will be destroyed. + +groovyscript.wiki.betterwithaddons.infuser.title=Ancestral Infusion Crafting +groovyscript.wiki.betterwithaddons.infuser.description=Converts a custom crafting recipe an output itemstack, consuming Spirits from the Infused Soul Sand placed below the Ancestral Infuser if placed within the appropriate multiblock. The multiblock is either Soul Sand or Infused Soul Sand placed below the Ancestral Infuser and exclusively air blocks adjacent to the Infuser and Soul Sand blocks. +groovyscript.wiki.betterwithaddons.infuser.spirits.value=Sets the amount of spirits consumed + +groovyscript.wiki.betterwithaddons.lure_tree.title=Alicio Tree Foods +groovyscript.wiki.betterwithaddons.lure_tree.description=Converts an input item into an amount of food for the tree to gradually consume, eventually summoning a random creature nearby. +groovyscript.wiki.betterwithaddons.lure_tree.note0=The creature spawned will be a passive animal, and undesirable animals can be blacklisted. The blacklist has no entries by default. +groovyscript.wiki.betterwithaddons.lure_tree.food.value=Sets the value of the food +groovyscript.wiki.betterwithaddons.lure_tree.addBlacklist=Adds the given Entity to the blacklist +groovyscript.wiki.betterwithaddons.lure_tree.removeBlacklist=Removes the given Entity from the blacklist +groovyscript.wiki.betterwithaddons.lure_tree.getBlacklist=Returns a list of all blacklisted classes that the Alicio Tree cannot spawn + +groovyscript.wiki.betterwithaddons.packing.title=Packing +groovyscript.wiki.betterwithaddons.packing.description=Converts an input itemstack in the form of a EntityItems into an IBlockState after a piston extends if the piston and location the EntityItems are in are fully surrounded by solid blocks. +groovyscript.wiki.betterwithaddons.packing.compress.value=Sets the IBlockState that the input is compacted into +groovyscript.wiki.betterwithaddons.packing.jeiOutput.value=Sets output that appears in JEI, but has no bearing on the actual recipe + +groovyscript.wiki.betterwithaddons.rotting.title=Rotting Food +groovyscript.wiki.betterwithaddons.rotting.description=Converts an input item into an output itemstack after the given time has passed. Has the ability to customize the terminology used to indicate the age. +groovyscript.wiki.betterwithaddons.rotting.note0=When an item (regardless of metadata) is the input of any entry in the Rotting map, all items will gain a new NBT tag with the day they were obtained. This may be them annoying to interact with. +groovyscript.wiki.betterwithaddons.rotting.add=Adds the given entry to the Rotting map +groovyscript.wiki.betterwithaddons.rotting.key.value=Sets the base key for the lang keys used to localize the stage the rotting is at +groovyscript.wiki.betterwithaddons.rotting.time.value=Sets how long the item takes to rot +groovyscript.wiki.betterwithaddons.rotting.rotted.value=Sets the item the rotted item turns into when the time has passed +groovyscript.wiki.betterwithaddons.rotting.remove=Removes the given entry from the Rotting map + +groovyscript.wiki.betterwithaddons.sand_net.title=Sand Net +groovyscript.wiki.betterwithaddons.sand_net.description=Converts an input item into any number of output itemstacks if placed within the appropriate multiblock. The multiblock is a Slat Block directly below the Netted Screen, 8 Water Blocks around the Water, and 8 Slat Blocks placed around the Netted Screen. +groovyscript.wiki.betterwithaddons.sand_net.sand.value=Sets the amount of sand consumed when the recipe is processed + +groovyscript.wiki.betterwithaddons.soaking_box.title=Soaking Unit +groovyscript.wiki.betterwithaddons.soaking_box.description=Converts an input item into an output itemstack if placed within the appropriate multiblock. The multiblock is Ice directly above the Soaking Box, 8 Water around the Soaking Box, and Water directly below the Soaking Box. + +groovyscript.wiki.betterwithaddons.spindle.title=Spindle +groovyscript.wiki.betterwithaddons.spindle.description=Converts an input itemstack into an output itemstack, with the ability to consume the Spindle, when placed against a Spinning Wheel powered by Mechanical Power. +groovyscript.wiki.betterwithaddons.spindle.popoff.value=Sets if the Spindle will break and be consumed when crafting + +groovyscript.wiki.betterwithaddons.tatara.title=Tatara +groovyscript.wiki.betterwithaddons.tatara.description=Converts an input item into an output itemstack if placed within the appropriate multiblock while fueled by Rice Ashes. The multiblock is Lava or Fire directly below the Tatara, 8 Clay around the Lava or Fire, 9 Nether Brick above the Tatara, 4 Stone Brick diagonal to the Tatara and two Iron Blocks across from each other adjacent to the Tatara. + +groovyscript.wiki.betterwithaddons.transmutation.title=Ancestral Infusion Transmutation +groovyscript.wiki.betterwithaddons.transmutation.description=Converts an input item into an output itemstack, consuming Spirits from the Infused Soul Sand placed below the Ancestral Infuser if placed within the appropriate multiblock. The multiblock is either Soul Sand or Infused Soul Sand placed below the Ancestral Infuser and exclusively air blocks adjacent to the Infuser and Soul Sand blocks. +groovyscript.wiki.betterwithaddons.transmutation.spirits.value=Sets the amount of spirits consumed + +groovyscript.wiki.betterwithaddons.water_net.title=Water Net +groovyscript.wiki.betterwithaddons.water_net.description=Converts an input item into any number of output itemstacks if placed within the appropriate multiblock. The multiblock is a Water Block directly below the Netted Screen, 8 Sakura Planks around the Water Block, and 8 Slat Blocks placed around the Netted Screen. + + # Better With Mods groovyscript.wiki.betterwithmods.anvil_crafting.title=Anvil Crafting groovyscript.wiki.betterwithmods.anvil_crafting.description=Similar to a normal crafting table, but 4x4 instead. From 72b0b4729816fd8d91b63977c1f7aa55af218a76 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:22:01 -0800 Subject: [PATCH 7/9] examples for BWA --- examples/postInit/betterwithaddons.groovy | 260 ++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 examples/postInit/betterwithaddons.groovy diff --git a/examples/postInit/betterwithaddons.groovy b/examples/postInit/betterwithaddons.groovy new file mode 100644 index 000000000..09363b5b0 --- /dev/null +++ b/examples/postInit/betterwithaddons.groovy @@ -0,0 +1,260 @@ + +// Auto generated groovyscript example file +// MODS_LOADED: betterwithaddons + +log.info 'mod \'betterwithaddons\' detected, running script' + +// Drying Unit: +// Converts an input item into an output itemstack if placed within the appropriate multiblock. The multiblock is Sandstone +// directly below the Drying Box, 8 Sand around the Drying Box, and a Dead Bush placed on the Sand. Only functions in a +// non-snowy biome with sky access during the day, and functions twice as fast when in a hot biome. + +mods.betterwithaddons.drying_box.removeByInput(item('betterwithaddons:japanmat:2')) +mods.betterwithaddons.drying_box.removeByOutput(item('minecraft:sponge')) +// mods.betterwithaddons.drying_box.removeAll() + +mods.betterwithaddons.drying_box.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:clay')) + .register() + +mods.betterwithaddons.drying_box.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 4) + .register() + + +// Fire Net: +// Converts an input item into any number of output itemstacks if placed within the appropriate multiblock. The multiblock +// is Lava or Fire directly below the Netted Screen, 8 Stone Brick around the Lava or Fire, and 8 Slat Blocks placed around +// the Netted Screen. + +mods.betterwithaddons.fire_net.removeByInput(item('betterwithaddons:iron_sand')) +mods.betterwithaddons.fire_net.removeByOutput(item('betterwithaddons:japanmat:12')) +// mods.betterwithaddons.fire_net.removeAll() + +mods.betterwithaddons.fire_net.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:clay')) + .register() + +mods.betterwithaddons.fire_net.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 4, item('minecraft:diamond'), item('minecraft:diamond') * 2) + .register() + + +// Ancestral Infusion Crafting: +// Converts a custom crafting recipe an output itemstack, consuming Spirits from the Infused Soul Sand placed below the +// Ancestral Infuser if placed within the appropriate multiblock. The multiblock is either Soul Sand or Infused Soul Sand +// placed below the Ancestral Infuser and exclusively air blocks adjacent to the Infuser and Soul Sand blocks. + +mods.betterwithaddons.infuser.removeByInput(item('betterwithaddons:japanmat:16')) +mods.betterwithaddons.infuser.removeByOutput(item('betterwithaddons:ya')) +// mods.betterwithaddons.infuser.removeAll() + +mods.betterwithaddons.infuser.shapedBuilder() + .output(item('minecraft:stone')) + .matrix('BXX', + 'X B') + .key('B', item('minecraft:stone')) + .key('X', item('minecraft:gold_ingot')) + .spirits(1) + .mirrored() + .register() + +mods.betterwithaddons.infuser.shapedBuilder() + .output(item('minecraft:diamond') * 32) + .matrix([[item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')], + [item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')], + [item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')]]) + .spirits(6) + .register() + +mods.betterwithaddons.infuser.shapelessBuilder() + .output(item('minecraft:clay') * 8) + .input(item('minecraft:stone'), item('minecraft:stone'), item('minecraft:stone')) + .register() + +mods.betterwithaddons.infuser.shapelessBuilder() + .output(item('minecraft:clay') * 32) + .input(item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond'), item('minecraft:diamond')) + .spirits(8) + .register() + + +// Alicio Tree Foods: +// Converts an input item into an amount of food for the tree to gradually consume, eventually summoning a random creature +// nearby. + +mods.betterwithaddons.lure_tree.removeByInput(item('minecraft:rotten_flesh')) +// mods.betterwithaddons.lure_tree.removeAll() + +mods.betterwithaddons.lure_tree.recipeBuilder() + .input(item('minecraft:diamond')) + .food(1000) + .register() + +mods.betterwithaddons.lure_tree.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .food(4) + .register() + + +mods.betterwithaddons.lure_tree.addBlacklist(entity('minecraft:chicken')) + +// Rotting Food: +// Converts an input item into an output itemstack after the given time has passed. Has the ability to customize the +// terminology used to indicate the age. + +mods.betterwithaddons.rotting.removeByInput(item('betterwithaddons:food_cooked_rice')) +mods.betterwithaddons.rotting.removeByOutput(item('minecraft:rotten_flesh')) +// mods.betterwithaddons.rotting.removeAll() + +mods.betterwithaddons.rotting.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .register() + +mods.betterwithaddons.rotting.recipeBuilder() + .input(item('placeholdername:snack')) + .time(100) + .key('groovy_example') + .rotted(item('minecraft:clay') * 4) + .register() + + +// Sand Net: +// Converts an input item into any number of output itemstacks if placed within the appropriate multiblock. The multiblock +// is a Slat Block directly below the Netted Screen, 8 Water Blocks around the Water, and 8 Slat Blocks placed around the +// Netted Screen. + +mods.betterwithaddons.sand_net.removeByInput(item('minecraft:iron_ingot')) +mods.betterwithaddons.sand_net.removeByOutput(item('minecraft:sand')) +mods.betterwithaddons.sand_net.removeByOutput(item('betterwithaddons:iron_sand')) +// mods.betterwithaddons.sand_net.removeAll() + +mods.betterwithaddons.sand_net.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:clay')) + .register() + +mods.betterwithaddons.sand_net.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:gold_ingot')) + .sand(2) + .register() + +mods.betterwithaddons.sand_net.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 4, item('minecraft:diamond'), item('minecraft:diamond') * 2) + .sand(5) + .register() + + +// Soaking Unit: +// Converts an input item into an output itemstack if placed within the appropriate multiblock. The multiblock is Ice +// directly above the Soaking Box, 8 Water around the Soaking Box, and Water directly below the Soaking Box. + +mods.betterwithaddons.soaking_box.removeByInput(item('betterwithaddons:bamboo')) +mods.betterwithaddons.soaking_box.removeByOutput(item('betterwithaddons:japanmat:8')) +// mods.betterwithaddons.soaking_box.removeAll() + +mods.betterwithaddons.soaking_box.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:clay')) + .register() + +mods.betterwithaddons.soaking_box.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 4) + .register() + + +// Spindle: +// Converts an input itemstack into an output itemstack, with the ability to consume the Spindle, when placed against a +// Spinning Wheel powered by Mechanical Power. + +mods.betterwithaddons.spindle.removeByInput(item('minecraft:vine')) +mods.betterwithaddons.spindle.removeByOutput(item('betterwithaddons:bolt')) +// mods.betterwithaddons.spindle.removeAll() + +mods.betterwithaddons.spindle.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:clay')) + .register() + +mods.betterwithaddons.spindle.recipeBuilder() + .input(item('minecraft:clay') * 3) + .output(item('minecraft:diamond')) + .popoff() + .register() + +mods.betterwithaddons.spindle.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 4) + .register() + + +// Tatara: +// Converts an input item into an output itemstack if placed within the appropriate multiblock while fueled by Rice Ashes. +// The multiblock is Lava or Fire directly below the Tatara, 8 Clay around the Lava or Fire, 9 Nether Brick above the +// Tatara, 4 Stone Brick diagonal to the Tatara and two Iron Blocks across from each other adjacent to the Tatara. + +mods.betterwithaddons.tatara.removeByInput(item('betterwithaddons:japanmat:20')) +mods.betterwithaddons.tatara.removeByOutput(item('betterwithaddons:kera')) +// mods.betterwithaddons.tatara.removeAll() + +mods.betterwithaddons.tatara.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:clay')) + .register() + +mods.betterwithaddons.tatara.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 4) + .register() + + +// Ancestral Infusion Transmutation: +// Converts an input item into an output itemstack, consuming Spirits from the Infused Soul Sand placed below the Ancestral +// Infuser if placed within the appropriate multiblock. The multiblock is either Soul Sand or Infused Soul Sand placed +// below the Ancestral Infuser and exclusively air blocks adjacent to the Infuser and Soul Sand blocks. + +mods.betterwithaddons.transmutation.removeByInput(item('minecraft:reeds')) +mods.betterwithaddons.transmutation.removeByOutput(item('betterwithaddons:crop_rice')) +// mods.betterwithaddons.transmutation.removeAll() + +mods.betterwithaddons.transmutation.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:clay')) + .spirits(0) + .register() + +mods.betterwithaddons.transmutation.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 4) + .spirits(5) + .register() + + +// Water Net: +// Converts an input item into any number of output itemstacks if placed within the appropriate multiblock. The multiblock +// is a Water Block directly below the Netted Screen, 8 Sakura Planks around the Water Block, and 8 Slat Blocks placed +// around the Netted Screen. + +mods.betterwithaddons.water_net.removeByInput(item('betterwithaddons:iron_sand')) +mods.betterwithaddons.water_net.removeByOutput(item('betterwithaddons:food_sashimi')) +mods.betterwithaddons.water_net.removeByOutput(item('betterwithaddons:food_fugu_sac')) +// mods.betterwithaddons.water_net.removeAll() + +mods.betterwithaddons.water_net.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:clay')) + .register() + +mods.betterwithaddons.water_net.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 4, item('minecraft:diamond'), item('minecraft:diamond') * 2) + .register() + + From dcc3f5bd42fa8fe04eb90e8065e476bbe3c4674e Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:22:29 -0800 Subject: [PATCH 8/9] remove some unused imports --- .../cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java | 1 - .../groovyscript/compat/mods/forestry/ThermionicFabricator.java | 1 - .../groovyscript/helper/recipe/AbstractRecipeBuilder.java | 1 - 3 files changed, 3 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java index 15b0aac5b..95da5e16f 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/Carpenter.java @@ -5,7 +5,6 @@ import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.core.mixin.forestry.CarpenterRecipeManagerAccessor; import com.cleanroommc.groovyscript.helper.SimpleObjectStream; -import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import forestry.api.recipes.ICarpenterRecipe; diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/ThermionicFabricator.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/ThermionicFabricator.java index cd77b80ba..60628b300 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/ThermionicFabricator.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/forestry/ThermionicFabricator.java @@ -6,7 +6,6 @@ import com.cleanroommc.groovyscript.core.mixin.forestry.FabricatorRecipeManagerAccessor; import com.cleanroommc.groovyscript.helper.Alias; import com.cleanroommc.groovyscript.helper.SimpleObjectStream; -import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import forestry.api.recipes.IFabricatorRecipe; diff --git a/src/main/java/com/cleanroommc/groovyscript/helper/recipe/AbstractRecipeBuilder.java b/src/main/java/com/cleanroommc/groovyscript/helper/recipe/AbstractRecipeBuilder.java index 47ebe609c..239ae8ccc 100644 --- a/src/main/java/com/cleanroommc/groovyscript/helper/recipe/AbstractRecipeBuilder.java +++ b/src/main/java/com/cleanroommc/groovyscript/helper/recipe/AbstractRecipeBuilder.java @@ -16,7 +16,6 @@ import net.minecraftforge.fluids.FluidStack; import java.util.Collection; -import java.util.List; public abstract class AbstractRecipeBuilder implements IRecipeBuilder { From a012a4c7aad0cddc8421376e9b2c1b4e72cdbfb0 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 1 Dec 2024 08:37:15 -0800 Subject: [PATCH 9/9] it shouldnt matter, but check betterwithaddons --- .../compat/mods/betterwithaddons/BetterWithAddons.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/BetterWithAddons.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/BetterWithAddons.java index c401df4dc..39fba6f0a 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/BetterWithAddons.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betterwithaddons/BetterWithAddons.java @@ -37,7 +37,7 @@ public static Ingredient fromIIngredient(IIngredient ingredient) { } public static boolean isBetterWithEverything() { - var entry = Loader.instance().getIndexedModList().get("betterwithmods"); + var entry = Loader.instance().getIndexedModList().get("betterwithaddons"); if (entry == null) return false; return entry.getMetadata().authorList.contains("ACGaming"); // TODO identify a better way to do this, if one exists }