From 08f621355acbb61687016672f53ac2171d6905db Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 04:04:51 -0800 Subject: [PATCH 01/14] add IOreDicts --- .../java/com/cleanroommc/groovyscript/api/IOreDicts.java | 9 +++++++++ .../helper/ingredient/OreDictIngredient.java | 9 ++++++++- .../helper/ingredient/OreDictWildcardIngredient.java | 8 +++++++- 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java diff --git a/src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java b/src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java new file mode 100644 index 000000000..cf61f6fc2 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java @@ -0,0 +1,9 @@ +package com.cleanroommc.groovyscript.api; + +import java.util.List; + +public interface IOreDicts { + + List getOreDicts(); + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/OreDictIngredient.java b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/OreDictIngredient.java index 0ceb3b1ea..3c2e5faab 100644 --- a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/OreDictIngredient.java +++ b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/OreDictIngredient.java @@ -1,7 +1,9 @@ package com.cleanroommc.groovyscript.helper.ingredient; import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.IOreDicts; import com.cleanroommc.groovyscript.compat.vanilla.VanillaModule; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.Ingredient; @@ -11,7 +13,7 @@ import java.util.Iterator; import java.util.List; -public class OreDictIngredient extends IngredientBase implements Iterable { +public class OreDictIngredient extends IngredientBase implements Iterable, IOreDicts { private final String oreDict; private int count = 1; @@ -24,6 +26,11 @@ public String getOreDict() { return oreDict; } + @Override + public List getOreDicts() { + return ImmutableList.of(getOreDict()); + } + @Override public int getAmount() { return count; diff --git a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/OreDictWildcardIngredient.java b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/OreDictWildcardIngredient.java index ca7dd62e4..55b667ba0 100644 --- a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/OreDictWildcardIngredient.java +++ b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/OreDictWildcardIngredient.java @@ -1,6 +1,7 @@ package com.cleanroommc.groovyscript.helper.ingredient; import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.IOreDicts; import com.cleanroommc.groovyscript.core.mixin.OreDictionaryAccessor; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; @@ -11,7 +12,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -public class OreDictWildcardIngredient extends ItemsIngredient { +public class OreDictWildcardIngredient extends ItemsIngredient implements IOreDicts { private final String oreDict; private final List matchingOreDictionaries = new ArrayList<>(); @@ -43,6 +44,11 @@ public String getOreDict() { return oreDict; } + @Override + public List getOreDicts() { + return getMatchingOreDictionaries(); + } + public List getMatchingOreDictionaries() { return ores; } From 289137b026f8500c4ed9531d70496caa97524137 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 04:05:18 -0800 Subject: [PATCH 02/14] IngredientHelper for cartesianProducts for Ores and ItemStacks --- .../helper/ingredient/IngredientHelper.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) 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..edc599b0e 100644 --- a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/IngredientHelper.java +++ b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/IngredientHelper.java @@ -2,7 +2,9 @@ import com.cleanroommc.groovyscript.GroovyScriptConfig; import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.IOreDicts; import com.cleanroommc.groovyscript.sandbox.expand.LambdaClosure; +import com.google.common.collect.Lists; import groovy.lang.Closure; import net.minecraft.block.state.IBlockState; import net.minecraft.item.ItemStack; @@ -14,8 +16,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.Collections; +import java.util.*; public class IngredientHelper { @@ -71,6 +72,38 @@ public static NonNullList toIngredientNonNullList(Collection> cartesianProductOres(@NotNull List inputs) { + List> entries = new ArrayList<>(); + for (var input : inputs) { + if (input instanceof IOreDicts ore) entries.add(ore.getOreDicts()); + else entries.add(Arrays.asList(input.getMatchingStacks())); + } + return Lists.cartesianProduct(entries); + } + + /** + * Converts a List of IIngredients into every combination of matching ItemStacks + * + * @param inputs a list of IIngredients + * @return a list of cartesian product of the matching stacks + */ + public static @NotNull List> cartesianProductItemStacks(@NotNull List inputs) { + List> entries = new ArrayList<>(); + for (var input : inputs) { + entries.add(Arrays.asList(input.getMatchingStacks())); + } + return Lists.cartesianProduct(entries); + } + + public static boolean isEmpty(@Nullable IIngredient ingredient) { return ingredient == null || ingredient.isEmpty(); } From f78a451ad8bc0ef98d0b279b3fca97704eadd206 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 04:05:52 -0800 Subject: [PATCH 03/14] add betweelands mixins --- .../groovyscript/core/LateMixin.java | 1 + .../CrabPotFilterRecipeBubblerAccessor.java | 17 +++++++++++++++++ .../CrabPotFilterRecipeSiltAccessor.java | 17 +++++++++++++++++ .../DruidAltarRecipeAccessor.java | 17 +++++++++++++++++ .../PestleAndMortarRecipeAccessor.java | 17 +++++++++++++++++ .../thebetweenlands/PurifierRecipeAccessor.java | 17 +++++++++++++++++ .../SmokingRackRecipeAccessor.java | 17 +++++++++++++++++ .../SteepingPotRecipesAccessor.java | 16 ++++++++++++++++ .../mixin.groovyscript.thebetweenlands.json | 16 ++++++++++++++++ 9 files changed, 135 insertions(+) create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/CrabPotFilterRecipeBubblerAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/CrabPotFilterRecipeSiltAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/DruidAltarRecipeAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/PestleAndMortarRecipeAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/PurifierRecipeAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/SmokingRackRecipeAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/SteepingPotRecipesAccessor.java create mode 100644 src/main/resources/mixin.groovyscript.thebetweenlands.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..699f655b1 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java @@ -15,6 +15,7 @@ public class LateMixin implements ILateMixinLoader { "appliedenergistics2", "astralsorcery", "betterwithmods", + "thebetweenlands", "bloodmagic", "botania", "calculator", diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/CrabPotFilterRecipeBubblerAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/CrabPotFilterRecipeBubblerAccessor.java new file mode 100644 index 000000000..d4312f9f6 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/CrabPotFilterRecipeBubblerAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.thebetweenlands; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import thebetweenlands.api.recipes.ICrabPotFilterRecipeBubbler; +import thebetweenlands.common.recipe.misc.CrabPotFilterRecipeBubbler; + +import java.util.List; + +@Mixin(value = CrabPotFilterRecipeBubbler.class, remap = false) +public interface CrabPotFilterRecipeBubblerAccessor { + + @Accessor("RECIPES") + static List getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/CrabPotFilterRecipeSiltAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/CrabPotFilterRecipeSiltAccessor.java new file mode 100644 index 000000000..cdd90e89b --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/CrabPotFilterRecipeSiltAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.thebetweenlands; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import thebetweenlands.api.recipes.ICrabPotFilterRecipeSilt; +import thebetweenlands.common.recipe.misc.CrabPotFilterRecipeSilt; + +import java.util.List; + +@Mixin(value = CrabPotFilterRecipeSilt.class, remap = false) +public interface CrabPotFilterRecipeSiltAccessor { + + @Accessor("RECIPES") + static List getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/DruidAltarRecipeAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/DruidAltarRecipeAccessor.java new file mode 100644 index 000000000..2c6e43a39 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/DruidAltarRecipeAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.thebetweenlands; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import thebetweenlands.api.recipes.IDruidAltarRecipe; +import thebetweenlands.common.recipe.misc.DruidAltarRecipe; + +import java.util.ArrayList; + +@Mixin(value = DruidAltarRecipe.class, remap = false) +public interface DruidAltarRecipeAccessor { + + @Accessor("druidAltarRecipes") + static ArrayList getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/PestleAndMortarRecipeAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/PestleAndMortarRecipeAccessor.java new file mode 100644 index 000000000..4db19f074 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/PestleAndMortarRecipeAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.thebetweenlands; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import thebetweenlands.api.recipes.IPestleAndMortarRecipe; +import thebetweenlands.common.recipe.mortar.PestleAndMortarRecipe; + +import java.util.List; + +@Mixin(value = PestleAndMortarRecipe.class, remap = false) +public interface PestleAndMortarRecipeAccessor { + + @Accessor("recipes") + static List getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/PurifierRecipeAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/PurifierRecipeAccessor.java new file mode 100644 index 000000000..a7cd9fd5b --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/PurifierRecipeAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.thebetweenlands; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import thebetweenlands.api.recipes.IPurifierRecipe; +import thebetweenlands.common.recipe.purifier.PurifierRecipe; + +import java.util.List; + +@Mixin(value = PurifierRecipe.class, remap = false) +public interface PurifierRecipeAccessor { + + @Accessor("RECIPES") + static List getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/SmokingRackRecipeAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/SmokingRackRecipeAccessor.java new file mode 100644 index 000000000..005e7ac07 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/SmokingRackRecipeAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.thebetweenlands; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import thebetweenlands.api.recipes.ISmokingRackRecipe; +import thebetweenlands.common.recipe.misc.SmokingRackRecipe; + +import java.util.List; + +@Mixin(value = SmokingRackRecipe.class, remap = false) +public interface SmokingRackRecipeAccessor { + + @Accessor("RECIPES") + static List getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/SteepingPotRecipesAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/SteepingPotRecipesAccessor.java new file mode 100644 index 000000000..26349814b --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/thebetweenlands/SteepingPotRecipesAccessor.java @@ -0,0 +1,16 @@ +package com.cleanroommc.groovyscript.core.mixin.thebetweenlands; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import thebetweenlands.common.recipe.misc.SteepingPotRecipes; + +import java.util.List; + +@Mixin(value = SteepingPotRecipes.class, remap = false) +public interface SteepingPotRecipesAccessor { + + @Accessor("recipes") + static List getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/resources/mixin.groovyscript.thebetweenlands.json b/src/main/resources/mixin.groovyscript.thebetweenlands.json new file mode 100644 index 000000000..2f14d2423 --- /dev/null +++ b/src/main/resources/mixin.groovyscript.thebetweenlands.json @@ -0,0 +1,16 @@ +{ + "package": "com.cleanroommc.groovyscript.core.mixin.thebetweenlands", + "refmap": "mixins.groovyscript.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "CrabPotFilterRecipeBubblerAccessor", + "CrabPotFilterRecipeSiltAccessor", + "DruidAltarRecipeAccessor", + "PestleAndMortarRecipeAccessor", + "PurifierRecipeAccessor", + "SmokingRackRecipeAccessor", + "SteepingPotRecipesAccessor" + ] +} \ No newline at end of file From 98de22a1d2d7e6ac08b0d255c0ff329c091424e0 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 04:06:26 -0800 Subject: [PATCH 04/14] add The Betweenlands compat --- examples/postInit/thebetweenlands.groovy | 221 ++++++++++++++++++ gradle.properties | 1 + .../groovyscript/compat/mods/ModSupport.java | 2 + .../compat/mods/betweenlands/Animator.java | 189 +++++++++++++++ .../mods/betweenlands/Betweenlands.java | 16 ++ .../compat/mods/betweenlands/Compost.java | 88 +++++++ .../betweenlands/CrabPotFilterBubbler.java | 76 ++++++ .../mods/betweenlands/CrabPotFilterSilt.java | 76 ++++++ .../compat/mods/betweenlands/DruidAltar.java | 82 +++++++ .../mods/betweenlands/PestleAndMortar.java | 77 ++++++ .../compat/mods/betweenlands/Purifier.java | 76 ++++++ .../compat/mods/betweenlands/SmokingRack.java | 86 +++++++ .../compat/mods/betweenlands/SteepingPot.java | 179 ++++++++++++++ .../assets/groovyscript/lang/en_us.lang | 46 ++++ 14 files changed, 1215 insertions(+) create mode 100644 examples/postInit/thebetweenlands.groovy create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Animator.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Betweenlands.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Compost.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/CrabPotFilterBubbler.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/CrabPotFilterSilt.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/DruidAltar.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/PestleAndMortar.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Purifier.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SmokingRack.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java diff --git a/examples/postInit/thebetweenlands.groovy b/examples/postInit/thebetweenlands.groovy new file mode 100644 index 000000000..12da81f9c --- /dev/null +++ b/examples/postInit/thebetweenlands.groovy @@ -0,0 +1,221 @@ + +// Auto generated groovyscript example file +// MODS_LOADED: thebetweenlands + +log.info 'mod \'thebetweenlands\' detected, running script' + +// Animator: +// Converts an input item, Life amount from Life Crystals, and Fuel from Sulfur into an output itemstack, summoning an +// entity, a random item from a loottable, or summoning an entity and outputting an itemstack. + +mods.thebetweenlands.animator.removeByEntity(entity('thebetweenlands:sporeling')) +mods.thebetweenlands.animator.removeByInput(item('thebetweenlands:bone_leggings')) +mods.thebetweenlands.animator.removeByLootTable(resource('thebetweenlands:animator/scroll')) +mods.thebetweenlands.animator.removeByOutput(item('thebetweenlands:items_misc:46')) +// mods.thebetweenlands.animator.removeAll() + +mods.thebetweenlands.animator.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond')) + .life(1) + .fuel(1) + .register() + +mods.thebetweenlands.animator.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .lootTable(resource('minecraft:entities/zombie')) + .life(5) + .fuel(1) + .register() + +mods.thebetweenlands.animator.recipeBuilder() + .input(item('minecraft:gold_block')) + .entity(entity('minecraft:zombie').getEntityClass()) + .life(1) + .fuel(5) + .register() + +mods.thebetweenlands.animator.recipeBuilder() + .input(item('minecraft:diamond')) + .entity(entity('minecraft:enderman')) + .output(item('minecraft:clay')) + .life(3) + .fuel(10) + .register() + + +// Compost: +// Converts an input itemstack into an amount of compost. + +mods.thebetweenlands.compost.removeByInput(item('thebetweenlands:items_misc:13')) +// mods.thebetweenlands.compost.removeAll() + +mods.thebetweenlands.compost.recipeBuilder() + .input(item('minecraft:clay')) + .amount(20) + .time(30) + .register() + +mods.thebetweenlands.compost.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .amount(1) + .time(5) + .register() + + +// Crab Pot Filter Bubbler: +// Converts an input item into an output itemstack when a Bubbler Crab is placed inside a Crab Pot Filter. + +mods.thebetweenlands.crab_pot_filter_bubbler.removeByInput(item('thebetweenlands:silt')) +mods.thebetweenlands.crab_pot_filter_bubbler.removeByOutput(item('thebetweenlands:swamp_dirt')) +// mods.thebetweenlands.crab_pot_filter_bubbler.removeAll() + +mods.thebetweenlands.crab_pot_filter_bubbler.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond')) + .register() + +mods.thebetweenlands.crab_pot_filter_bubbler.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay')) + .register() + + +// Crab Pot Filter Silt: +// Converts an input item into an output itemstack when a Silt Crab is placed inside a Crab Pot Filter. + +mods.thebetweenlands.crab_pot_filter_silt.removeByInput(item('thebetweenlands:mud')) +mods.thebetweenlands.crab_pot_filter_silt.removeByOutput(item('thebetweenlands:mud')) +// mods.thebetweenlands.crab_pot_filter_silt.removeAll() + +mods.thebetweenlands.crab_pot_filter_silt.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond')) + .register() + +mods.thebetweenlands.crab_pot_filter_silt.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay')) + .register() + + +// Druid Altar: +// Converts 4 input items into an output itemstack. + +// mods.thebetweenlands.druid_altar.removeByInput(item('thebetweenlands:swamp_talisman:1')) +mods.thebetweenlands.druid_altar.removeByOutput(item('thebetweenlands:swamp_talisman')) +// mods.thebetweenlands.druid_altar.removeAll() + +mods.thebetweenlands.druid_altar.recipeBuilder() + .input(item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay')) + .output(item('minecraft:diamond')) + .register() + +mods.thebetweenlands.druid_altar.recipeBuilder() + .input(item('minecraft:diamond'), item('minecraft:gold_block'), item('minecraft:gold_ingot'), item('minecraft:clay')) + .output(item('minecraft:clay')) + .register() + + +// Pestle And Mortar: +// Converts an input item into an output itemstack in a Pestle and Mortar by using a Pestle tool in the Mortar. + +mods.thebetweenlands.pestle_and_mortar.removeByInput(item('thebetweenlands:limestone')) +mods.thebetweenlands.pestle_and_mortar.removeByOutput(item('thebetweenlands:fish_bait')) +// mods.thebetweenlands.pestle_and_mortar.removeAll() + +mods.thebetweenlands.pestle_and_mortar.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond')) + .register() + +mods.thebetweenlands.pestle_and_mortar.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay')) + .register() + + +// Purifier: +// Converts an input item into an output itemstack, consuming Sulfur and Swamp Water as fuel. + +mods.thebetweenlands.purifier.removeByInput(item('thebetweenlands:items_misc:64')) +mods.thebetweenlands.purifier.removeByOutput(item('thebetweenlands:cragrock')) +// mods.thebetweenlands.purifier.removeAll() + +mods.thebetweenlands.purifier.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond')) + .register() + +mods.thebetweenlands.purifier.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay')) + .register() + + +// Smoking Rack: +// Converts an input item into an output itemstack over a configurable period of time, consuming Fallen Leaves to do so. + +mods.thebetweenlands.smoking_rack.removeByInput(item('thebetweenlands:anadia')) +mods.thebetweenlands.smoking_rack.removeByOutput(item('thebetweenlands:barnacle_smoked')) +// mods.thebetweenlands.smoking_rack.removeAll() + +mods.thebetweenlands.smoking_rack.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond')) + .register() + +mods.thebetweenlands.smoking_rack.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay')) + .time(50) + .register() + + +// Steeping Pot: +// Converts a 1,000mb of fluid into either 1,000mb of a fluid, an output itemstack, or both, consuming up to 4 items from a +// Silk Bundle placed inside the Steeping Pot to do so. The Silk Bundle is converted into a Dirty Silk Bundle in the +// process. The Silk Bundle can only hold specific items, which are also configurable. + +mods.thebetweenlands.steeping_pot.removeAcceptedItem(item('thebetweenlands:items_crushed:5')) +mods.thebetweenlands.steeping_pot.removeByInput(fluid('clean_water')) +mods.thebetweenlands.steeping_pot.removeByInput(item('thebetweenlands:items_crushed:13')) +mods.thebetweenlands.steeping_pot.removeByOutput(fluid('dye_fluid').withNbt(['type': 14])) +// mods.thebetweenlands.steeping_pot.removeByOutput(item('thebetweenlands:limestone')) +// mods.thebetweenlands.steeping_pot.removeAll() +// mods.thebetweenlands.steeping_pot.removeAllAcceptedItem() + +mods.thebetweenlands.steeping_pot.recipeBuilder() + .input(item('minecraft:clay')) + .fluidInput(fluid('water')) + .output(item('minecraft:diamond')) + .register() + +mods.thebetweenlands.steeping_pot.recipeBuilder() + .input(item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay')) + .fluidInput(fluid('lava')) + .fluidOutput(fluid('water')) + .register() + +mods.thebetweenlands.steeping_pot.recipeBuilder() + .input(item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:clay')) + .fluidInput(fluid('lava')) + .output(item('minecraft:diamond')) + .register() + +mods.thebetweenlands.steeping_pot.recipeBuilder() + .input(item('minecraft:diamond')) + .fluidInput(fluid('lava')) + .fluidOutput(fluid('dye_fluid')) + .meta(5) + .register() + +mods.thebetweenlands.steeping_pot.recipeBuilder() + .input(item('minecraft:emerald')) + .fluidInput(fluid('lava')) + .fluidOutput(fluid('water')) + .register() + + +mods.thebetweenlands.steeping_pot.addAcceptedItem(item('minecraft:gold_block')) + diff --git a/gradle.properties b/gradle.properties index ac888afbf..a378e2a10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -25,6 +25,7 @@ debug_aurorian = false debug_avaritia = false debug_better_with_mods = false +debug_betweenlands = false debug_blood_magic = false debug_botania = false debug_botania_tweaks = false 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..6f447800a 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -14,6 +14,7 @@ import com.cleanroommc.groovyscript.compat.mods.atum.Atum; import com.cleanroommc.groovyscript.compat.mods.avaritia.Avaritia; import com.cleanroommc.groovyscript.compat.mods.betterwithmods.BetterWithMods; +import com.cleanroommc.groovyscript.compat.mods.betweenlands.Betweenlands; import com.cleanroommc.groovyscript.compat.mods.bloodmagic.BloodMagic; import com.cleanroommc.groovyscript.compat.mods.botania.Botania; import com.cleanroommc.groovyscript.compat.mods.botaniatweaks.BotaniaTweaks; @@ -92,6 +93,7 @@ public class ModSupport { 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_MODS = new InternalModContainer<>("betterwithmods", "Better With Mods", BetterWithMods::new); + public static final GroovyContainer BETWEENLANDS = new InternalModContainer<>("thebetweenlands", "The Betweenlands", Betweenlands::new, "betweenlands"); 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); public static final GroovyContainer BOTANIA_TWEAKS = new InternalModContainer<>("botania_tweaks", "Botania Tweaks", BotaniaTweaks::new); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Animator.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Animator.java new file mode 100644 index 000000000..62a5e9e90 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Animator.java @@ -0,0 +1,189 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +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.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraft.world.storage.loot.LootContext; +import net.minecraft.world.storage.loot.LootTable; +import net.minecraftforge.fml.common.registry.EntityEntry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.IAnimatorRecipe; +import thebetweenlands.common.recipe.misc.AnimatorRecipe; + +import java.util.Collection; +import java.util.List; + +@RegistryDescription +public class Animator extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).output(item('minecraft:diamond')).life(1).fuel(1)"), + @Example(".input(item('minecraft:gold_ingot')).lootTable(resource('minecraft:entities/zombie')).life(5).fuel(1)"), + @Example(".input(item('minecraft:gold_block')).entity(entity('minecraft:zombie').getEntityClass()).life(1).fuel(5)"), + @Example(".input(item('minecraft:diamond')).entity(entity('minecraft:enderman')).output(item('minecraft:clay')).life(3).fuel(10)"), + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return AnimatorRecipe.getRecipes(); + } + + @MethodDescription(example = @Example("item('thebetweenlands:bone_leggings')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> r instanceof AnimatorRecipe recipe && input.test(recipe.getInput()) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('thebetweenlands:items_misc:46')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> r instanceof AnimatorRecipe recipe && output.test(recipe.getResult(recipe.getInput())) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("resource('thebetweenlands:animator/scroll')")) + public boolean removeByLootTable(ResourceLocation lootTable) { + return getRecipes().removeIf(r -> r instanceof AnimatorRecipe recipe && lootTable.equals(recipe.getLootTable()) && doAddBackup(r)); + } + + @MethodDescription + public boolean removeByEntity(Class entity) { + return getRecipes().removeIf(r -> r instanceof AnimatorRecipe recipe && entity.equals(recipe.getSpawnEntityClass(recipe.getInput())) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("entity('thebetweenlands:sporeling')")) + public boolean removeByEntity(EntityEntry entity) { + return removeByEntity(entity.getEntityClass()); + } + + @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 life; + @Property(comp = @Comp(gte = 0)) + private int fuel; + @Property + private ResourceLocation lootTable; + @Property + private Class entity; + @Property + private ResourceLocation render; + + @RecipeBuilderMethodDescription + public RecipeBuilder life(int life) { + this.life = life; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder fuel(int fuel) { + this.fuel = fuel; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder lootTable(ResourceLocation lootTable) { + this.lootTable = lootTable; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder entity(Class entity) { + this.entity = entity; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder entity(EntityEntry entity) { + return entity(entity.getEntityClass()); + } + + @RecipeBuilderMethodDescription + public RecipeBuilder render(ResourceLocation render) { + this.render = render; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Betweenlands Animator recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 0, 1); + validateFluids(msg); + msg.add(life < 0, "life must be a positive integer greater than 0, yet it was {}", life); + msg.add(fuel < 0, "fuel must be a positive integer greater than 0, yet it was {}", fuel); + if (lootTable != null) { + validateCustom(msg, output, 0, 0, "item output"); + msg.add(entity != null, "entity was defined even though lootTable was defined"); + msg.add(!output.isEmpty(), "output was defined even though lootTable was defined"); + } + msg.add(output.isEmpty() && lootTable == null && entity == null, "output, lootTable, and entity were all not defined. one of them should be defined to properly create the recipe"); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable IAnimatorRecipe register() { + if (!validate()) return null; + AnimatorRecipe recipe = null; + if (lootTable != null) { + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new AnimatorRecipe(stack, fuel, life, lootTable) { + + /** + * In order to get Loot Table recipes to display properly we need to do this. + * This snippet of code is copied a few times in {@link thebetweenlands.common.registries.RecipeRegistry#registerAnimatorRecipes} + * with the only difference being the `lootTable` being used here. + * Don't know why Betweenlands doesn't just make a class to handle it? Seems like it would make sense... + */ + @Override + public @NotNull ItemStack onAnimated(World world, BlockPos pos, ItemStack stack) { + LootTable table = world.getLootTableManager().getLootTableFromLocation(lootTable); + LootContext.Builder lootBuilder = new LootContext.Builder((WorldServer) world); + List loot = table.generateLootForPools(world.rand, lootBuilder.build()); + return loot.isEmpty() ? ItemStack.EMPTY : loot.get(world.rand.nextInt(loot.size())); + } + }; + ModSupport.BETWEENLANDS.get().animator.add(recipe); + } + } else if (entity != null) { + if (output.isEmpty()) { + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new AnimatorRecipe(stack, fuel, life, entity); + recipe.setRenderEntity(render); + ModSupport.BETWEENLANDS.get().animator.add(recipe); + } + } else { + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new AnimatorRecipe(stack, fuel, life, output.get(0), entity); + recipe.setRenderEntity(render); + ModSupport.BETWEENLANDS.get().animator.add(recipe); + } + } + } + ModSupport.BETWEENLANDS.get().animator.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Betweenlands.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Betweenlands.java new file mode 100644 index 000000000..664ed341b --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Betweenlands.java @@ -0,0 +1,16 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; + +public class Betweenlands extends GroovyPropertyContainer { + + public final Animator animator = new Animator(); + public final Compost compost = new Compost(); + public final CrabPotFilterBubbler crabPotFilterBubbler = new CrabPotFilterBubbler(); + public final CrabPotFilterSilt crabPotFilterSilt = new CrabPotFilterSilt(); + public final DruidAltar druidAltar = new DruidAltar(); + public final PestleAndMortar pestleAndMortar = new PestleAndMortar(); + public final Purifier purifier = new Purifier(); + public final SmokingRack smokingRack = new SmokingRack(); + public final SteepingPot steepingPot = new SteepingPot(); +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Compost.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Compost.java new file mode 100644 index 000000000..3312b7afc --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Compost.java @@ -0,0 +1,88 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +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.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.ICompostBinRecipe; +import thebetweenlands.common.recipe.misc.CompostRecipe; + +import java.util.Collection; + +@RegistryDescription +public class Compost extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).amount(20).time(30)"), + @Example(".input(item('minecraft:gold_ingot')).amount(1).time(5)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CompostRecipe.RECIPES; + } + + @MethodDescription(example = @Example("item('thebetweenlands:items_misc:13')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> r instanceof CompostRecipe recipe && input.test(recipe.getInput()) && doAddBackup(r)); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gte = 1)) + private int amount; + @Property(comp = @Comp(gte = 1)) + private int time; + + @RecipeBuilderMethodDescription + public RecipeBuilder amount(int amount) { + this.amount = amount; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder time(int time) { + this.time = time; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Betweenlands Compost recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 0, 0); + validateFluids(msg); + msg.add(amount <= 0, "amount must be a positive integer greater than 0, yet it was {}", amount); + msg.add(time <= 0, "time must be a positive integer greater than 0, yet it was {}", time); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable ICompostBinRecipe register() { + if (!validate()) return null; + ICompostBinRecipe recipe = null; + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new CompostRecipe(amount, time, stack); + ModSupport.BETWEENLANDS.get().compost.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/CrabPotFilterBubbler.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/CrabPotFilterBubbler.java new file mode 100644 index 000000000..da3e42895 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/CrabPotFilterBubbler.java @@ -0,0 +1,76 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +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.thebetweenlands.CrabPotFilterRecipeBubblerAccessor; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.ICrabPotFilterRecipeBubbler; +import thebetweenlands.common.recipe.misc.CrabPotFilterRecipeBubbler; + +import java.util.Collection; + +@RegistryDescription +public class CrabPotFilterBubbler extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).output(item('minecraft:diamond'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay'))") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CrabPotFilterRecipeBubblerAccessor.getRecipes(); + } + + @MethodDescription(example = @Example("item('thebetweenlands:silt')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> input.test(r.getInput()) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('thebetweenlands:swamp_dirt')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.getOutput(r.getInput())) && doAddBackup(r)); + } + + @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 Betweenlands Crab Pot Filter Bubbler recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable ICrabPotFilterRecipeBubbler register() { + if (!validate()) return null; + ICrabPotFilterRecipeBubbler recipe = null; + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new CrabPotFilterRecipeBubbler(output.get(0), stack); + ModSupport.BETWEENLANDS.get().crabPotFilterBubbler.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/CrabPotFilterSilt.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/CrabPotFilterSilt.java new file mode 100644 index 000000000..fee6afaf2 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/CrabPotFilterSilt.java @@ -0,0 +1,76 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +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.thebetweenlands.CrabPotFilterRecipeSiltAccessor; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.ICrabPotFilterRecipeSilt; +import thebetweenlands.common.recipe.misc.CrabPotFilterRecipeSilt; + +import java.util.Collection; + +@RegistryDescription +public class CrabPotFilterSilt extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).output(item('minecraft:diamond'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay'))") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return CrabPotFilterRecipeSiltAccessor.getRecipes(); + } + + @MethodDescription(example = @Example("item('thebetweenlands:mud')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> input.test(r.getInput()) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('thebetweenlands:mud')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.getOutput(r.getInput())) && doAddBackup(r)); + } + + @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 Betweenlands Crab Pot Filter Silt recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable ICrabPotFilterRecipeSilt register() { + if (!validate()) return null; + ICrabPotFilterRecipeSilt recipe = null; + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new CrabPotFilterRecipeSilt(output.get(0), stack); + ModSupport.BETWEENLANDS.get().crabPotFilterSilt.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/DruidAltar.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/DruidAltar.java new file mode 100644 index 000000000..ac0a5c054 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/DruidAltar.java @@ -0,0 +1,82 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +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.thebetweenlands.DruidAltarRecipeAccessor; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.IDruidAltarRecipe; +import thebetweenlands.common.recipe.misc.DruidAltarRecipe; + +import java.util.Collection; + +@RegistryDescription(admonition = @Admonition(value = "groovyscript.wiki.thebetweenlands.druid_altar.note0", type = Admonition.Type.WARNING)) +public class DruidAltar extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay')).output(item('minecraft:diamond'))"), + @Example(".input(item('minecraft:diamond'), item('minecraft:gold_block'), item('minecraft:gold_ingot'), item('minecraft:clay')).output(item('minecraft:clay'))") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return DruidAltarRecipeAccessor.getRecipes(); + } + + @MethodDescription(example = @Example(value = "item('thebetweenlands:swamp_talisman:1')", commented = true)) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> r instanceof DruidAltarRecipe recipe && recipe.getInputs().stream().anyMatch(input) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('thebetweenlands:swamp_talisman')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> r instanceof DruidAltarRecipe recipe && output.test(recipe.getDefaultOutput()) && doAddBackup(r)); + } + + @Property(property = "input", comp = @Comp(eq = 4)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Override + public String getErrorMsg() { + return "Error adding Betweenlands Druid Altar recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 4, 4, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable IDruidAltarRecipe register() { + if (!validate()) return null; + IDruidAltarRecipe recipe = null; + for (var input1 : input.get(0).getMatchingStacks()) { + for (var input2 : input.get(1).getMatchingStacks()) { + for (var input3 : input.get(2).getMatchingStacks()) { + for (var input4 : input.get(3).getMatchingStacks()) { + recipe = new DruidAltarRecipe(input1, input2, input3, input4, output.get(0)); + ModSupport.BETWEENLANDS.get().druidAltar.add(recipe); + } + } + } + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/PestleAndMortar.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/PestleAndMortar.java new file mode 100644 index 000000000..280b4d8fb --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/PestleAndMortar.java @@ -0,0 +1,77 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +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.thebetweenlands.PestleAndMortarRecipeAccessor; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.IPestleAndMortarRecipe; +import thebetweenlands.common.recipe.mortar.PestleAndMortarRecipe; + +import java.util.Collection; + +@RegistryDescription +public class PestleAndMortar extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).output(item('minecraft:diamond'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay'))") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return PestleAndMortarRecipeAccessor.getRecipes(); + } + + @MethodDescription(example = @Example("item('thebetweenlands:limestone')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> input.test(r.getInputs()) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('thebetweenlands:fish_bait')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.getOutput(r.getInputs(), ItemStack.EMPTY)) && doAddBackup(r)); + } + + @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 Betweenlands Pestle And Mortar recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable IPestleAndMortarRecipe register() { + if (!validate()) return null; + IPestleAndMortarRecipe recipe = null; + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new PestleAndMortarRecipe(output.get(0), stack); + ModSupport.BETWEENLANDS.get().pestleAndMortar.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Purifier.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Purifier.java new file mode 100644 index 000000000..12490bfcc --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/Purifier.java @@ -0,0 +1,76 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +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.thebetweenlands.PurifierRecipeAccessor; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.IPurifierRecipe; +import thebetweenlands.common.recipe.purifier.PurifierRecipeStandard; + +import java.util.Collection; + +@RegistryDescription +public class Purifier extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).output(item('minecraft:diamond'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay'))") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return PurifierRecipeAccessor.getRecipes(); + } + + @MethodDescription(example = @Example("item('thebetweenlands:items_misc:64')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> r instanceof PurifierRecipeStandard recipe && input.test(recipe.getInput()) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('thebetweenlands:cragrock')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> r instanceof PurifierRecipeStandard recipe && output.test(r.getOutput(recipe.getInput())) && doAddBackup(r)); + } + + @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 Betweenlands Purifier recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable IPurifierRecipe register() { + if (!validate()) return null; + IPurifierRecipe recipe = null; + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new PurifierRecipeStandard(output.get(0), stack); + ModSupport.BETWEENLANDS.get().purifier.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SmokingRack.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SmokingRack.java new file mode 100644 index 000000000..285550fd1 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SmokingRack.java @@ -0,0 +1,86 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +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.thebetweenlands.SmokingRackRecipeAccessor; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.ISmokingRackRecipe; +import thebetweenlands.common.recipe.misc.SmokingRackRecipe; + +import java.util.Collection; + +@RegistryDescription +public class SmokingRack extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).output(item('minecraft:diamond'))"), + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay')).time(50)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return SmokingRackRecipeAccessor.getRecipes(); + } + + @MethodDescription(example = @Example("item('thebetweenlands:anadia')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> input.test(r.getInput()) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('thebetweenlands:barnacle_smoked')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.getOutput(r.getInput())) && doAddBackup(r)); + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(defaultValue = "1", comp = @Comp(gte = 1)) + private int time = 1; + + @RecipeBuilderMethodDescription + public RecipeBuilder time(int time) { + this.time = time; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Betweenlands Smoking Rack recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + msg.add(time <= 0, "time must be a positive integer greater than 0, yet it was {}", time); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable ISmokingRackRecipe register() { + if (!validate()) return null; + ISmokingRackRecipe recipe = null; + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new SmokingRackRecipe(output.get(0), time, stack); + ModSupport.BETWEENLANDS.get().smokingRack.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java new file mode 100644 index 000000000..a40494063 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java @@ -0,0 +1,179 @@ +package com.cleanroommc.groovyscript.compat.mods.betweenlands; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.IOreDicts; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.core.mixin.thebetweenlands.SteepingPotRecipesAccessor; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.AbstractReloadableStorage; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; +import thebetweenlands.api.recipes.ISteepingPotRecipe; +import thebetweenlands.common.inventory.container.ContainerSilkBundle; +import thebetweenlands.common.recipe.misc.SteepingPotRecipes; +import thebetweenlands.common.registries.FluidRegistry; + +import java.util.Collection; +import java.util.List; + +/** + * While {@link SteepingPotRecipes} does implement the interface {@link ISteepingPotRecipe}, + * the place that stores recipes can only be of the type {@link SteepingPotRecipes}. + */ +@RegistryDescription +public class SteepingPot extends StandardListRegistry { + + private final AbstractReloadableStorage acceptedItemsStorage = new AbstractReloadableStorage<>(); + + private static boolean doesIIngredientContainMatch(IIngredient target, Object[] match) { + for (var o : match) { + if (o instanceof String s) { + return target instanceof IOreDicts ore && ore.getOreDicts().contains(s); + } + if (o instanceof ItemStack stack) { + return target.test(stack); + } + return false; + } + return false; + } + + @Override + @GroovyBlacklist + @ApiStatus.Internal + public void onReload() { + super.onReload(); + var acceptedItems = getAcceptedItems(); + acceptedItems.removeAll(acceptedItemsStorage.removeScripted()); + acceptedItems.addAll(acceptedItemsStorage.restoreFromBackup()); + } + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).fluidInput(fluid('water')).output(item('minecraft:diamond'))"), + @Example(".input(item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay')).fluidInput(fluid('lava')).fluidOutput(fluid('water'))"), + @Example(".input(item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:clay')).fluidInput(fluid('lava')).output(item('minecraft:diamond'))"), + @Example(".input(item('minecraft:diamond')).fluidInput(fluid('lava')).fluidOutput(fluid('dye_fluid')).meta(5)"), + @Example(".input(item('minecraft:emerald')).fluidInput(fluid('lava')).fluidOutput(fluid('water'))"), + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return SteepingPotRecipesAccessor.getRecipes(); + } + + public Collection getAcceptedItems() { + return ContainerSilkBundle.acceptedItems; + } + + @MethodDescription(example = { + @Example("item('thebetweenlands:items_crushed:13')"), @Example("fluid('clean_water')") + }) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> (input.test(r.getInputFluidStack()) || doesIIngredientContainMatch(input, r.getInputs())) && doAddBackup(r)); + } + + @MethodDescription(example = { + @Example(value = "item('thebetweenlands:limestone')", commented = true), @Example("fluid('dye_fluid').withNbt(['type': 14])") + }) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> (output.test(r.getOutputItem()) || output.test(r.getOutputFluidStack())) && doAddBackup(r)); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, priority = 500, example = @Example("item('minecraft:gold_block')")) + public boolean addAcceptedItem(ItemStack entry) { + return entry != null && getAcceptedItems().add(entry) && acceptedItemsStorage.addScripted(entry); + } + + @MethodDescription(priority = 500, example = @Example("item('thebetweenlands:items_crushed:5')")) + public boolean removeAcceptedItem(ItemStack entry) { + return entry != null && getAcceptedItems().removeIf(r -> r == entry) && acceptedItemsStorage.addBackup(entry); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAllAcceptedItem() { + var acceptedItems = getAcceptedItems(); + acceptedItems.forEach(acceptedItemsStorage::addBackup); + acceptedItems.clear(); + } + + @Property(property = "input", comp = @Comp(gte = 1, lte = 4)) + @Property(property = "fluidInput", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(gte = 0, lte = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + // Determines the color and state if relevant between two fluids. + // except one is an enum with 16 values and the other has 11. + // mods truly are amazing. + @Property(comp = @Comp(gte = 0, lte = 15)) + private int meta; + + @RecipeBuilderMethodDescription + public RecipeBuilder meta(int meta) { + this.meta = meta; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Betweenlands Steeping Pot recipe"; + } + + @Override + @GroovyBlacklist + protected int getMaxItemInput() { + return 1; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 4, 0, 1); + validateFluids(msg, 1, 1, 0, 1); + msg.add(output.isEmpty() && fluidOutput.isEmpty(), "either output or fluidOutput must contain an entry, but both were empty"); + msg.add(!output.isEmpty() && !fluidOutput.isEmpty(), "either output or fluidOutput must have have an entry, yet both had an entry"); + if (!fluidOutput.isEmpty()) { + var fluid = fluidOutput.get(0).getFluid(); + if (fluid != FluidRegistry.DYE_FLUID && fluid != FluidRegistry.DRINKABLE_BREW) { + msg.add(meta != 0, "meta has no effect if the fluid is not of type {} or {}, and meta was {} for the fluidOutput {}", FluidRegistry.DYE_FLUID.getName(), FluidRegistry.DRINKABLE_BREW.getName(), meta, fluid.getName()); + } else { + msg.add((meta <= 0 || meta >= 15), "meta must be greater than or equal to 0 and less than or equal to 15 if fluidOutput is of type {} or {}, yet it was {}", FluidRegistry.DYE_FLUID.getName(), FluidRegistry.DRINKABLE_BREW.getName(), meta); + } + } + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable SteepingPotRecipes register() { + if (!validate()) return null; + SteepingPotRecipes recipe = null; + List> inputs = IngredientHelper.cartesianProductOres(input); + + for (var ingredient : input) { + for (var stack : ingredient.getMatchingStacks()) { + ModSupport.BETWEENLANDS.get().steepingPot.addAcceptedItem(stack); + } + } + + if (output.isEmpty()) { + for (var objects : inputs) { + recipe = new SteepingPotRecipes(fluidOutput.get(0), meta, fluidInput.get(0), objects.toArray()); + ModSupport.BETWEENLANDS.get().steepingPot.add(recipe); + } + } else { + for (var objects : inputs) { + recipe = new SteepingPotRecipes(output.get(0), fluidInput.get(0), objects.toArray()); + ModSupport.BETWEENLANDS.get().steepingPot.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..a0d011802 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -2383,6 +2383,7 @@ groovyscript.wiki.thaumcraft.warp.description=Determines if holding an item or e groovyscript.wiki.thaumcraft.warp.addWarp=Adds Warp to the given item in the format `item`, `amount` groovyscript.wiki.thaumcraft.warp.removeWarp=Removes Warp from the given item + # The Aurorian groovyscript.wiki.theaurorian.moonlight_forge.title=Moonlight Forge groovyscript.wiki.theaurorian.moonlight_forge.description=Combines two items to get a third item. Only works at night, and works faster the higher it is placed in the world. @@ -2390,6 +2391,51 @@ groovyscript.wiki.theaurorian.moonlight_forge.removeByInput=Removes a recipe by groovyscript.wiki.theaurorian.scrapper.title=Scrapper groovyscript.wiki.theaurorian.scrapper.description=Turns an input item into an output item. Can be sped up by placing a Crystal on top of it. The crystal has a chance to break every time a recipe is executed. + +# The Betweenlands +groovyscript.wiki.thebetweenlands.animator.title=Animator +groovyscript.wiki.thebetweenlands.animator.description=Converts an input item, Life amount from Life Crystals, and Fuel from Sulfur into an output itemstack, summoning an entity, a random item from a loottable, or summoning an entity and outputting an itemstack. +groovyscript.wiki.thebetweenlands.animator.fuel.value=Sets the fuel consumed +groovyscript.wiki.thebetweenlands.animator.life.value=Sets the life consumed from the life crystal +groovyscript.wiki.thebetweenlands.animator.entity.value=Sets the entity being spawned +groovyscript.wiki.thebetweenlands.animator.render.value=Sets the entity to render, typically the same as the entity to be spawned +groovyscript.wiki.thebetweenlands.animator.lootTable.value=Sets the LootTable used to generate outputs +groovyscript.wiki.thebetweenlands.animator.removeByEntity=Removes all entries that match the given entity +groovyscript.wiki.thebetweenlands.animator.removeByLootTable=Removes all entries that output the given Loot Table + +groovyscript.wiki.thebetweenlands.compost.title=Compost +groovyscript.wiki.thebetweenlands.compost.description=Converts an input itemstack into an amount of compost. +groovyscript.wiki.thebetweenlands.compost.time.value=Sets the time the recipe takes in ticks +groovyscript.wiki.thebetweenlands.compost.amount.value=Sets the amount of compost output + +groovyscript.wiki.thebetweenlands.crab_pot_filter_bubbler.title=Crab Pot Filter Bubbler +groovyscript.wiki.thebetweenlands.crab_pot_filter_bubbler.description=Converts an input item into an output itemstack when a Bubbler Crab is placed inside a Crab Pot Filter. + +groovyscript.wiki.thebetweenlands.crab_pot_filter_silt.title=Crab Pot Filter Silt +groovyscript.wiki.thebetweenlands.crab_pot_filter_silt.description=Converts an input item into an output itemstack when a Silt Crab is placed inside a Crab Pot Filter. + +groovyscript.wiki.thebetweenlands.druid_altar.title=Druid Altar +groovyscript.wiki.thebetweenlands.druid_altar.description=Converts 4 input items into an output itemstack. +groovyscript.wiki.thebetweenlands.druid_altar.note0=The 4 sapling recipe to reactivate the Druid Altar recipe will always appear in JEI, even if it has been removed. Additionally, this recipe cannot be removed via `removeByInput` or `removeByOutput` + +groovyscript.wiki.thebetweenlands.pestle_and_mortar.title=Pestle And Mortar +groovyscript.wiki.thebetweenlands.pestle_and_mortar.description=Converts an input item into an output itemstack in a Pestle and Mortar by using a Pestle tool in the Mortar. + +groovyscript.wiki.thebetweenlands.purifier.title=Purifier +groovyscript.wiki.thebetweenlands.purifier.description=Converts an input item into an output itemstack, consuming Sulfur and Swamp Water as fuel. + +groovyscript.wiki.thebetweenlands.smoking_rack.title=Smoking Rack +groovyscript.wiki.thebetweenlands.smoking_rack.description=Converts an input item into an output itemstack over a configurable period of time, consuming Fallen Leaves to do so. +groovyscript.wiki.thebetweenlands.smoking_rack.time.value=Sets the time the recipe takes times 10 in seconds (3 = 30 seconds) + +groovyscript.wiki.thebetweenlands.steeping_pot.title=Steeping Pot +groovyscript.wiki.thebetweenlands.steeping_pot.description=Converts a 1,000mb of fluid into either 1,000mb of a fluid, an output itemstack, or both, consuming up to 4 items from a Silk Bundle placed inside the Steeping Pot to do so. The Silk Bundle is converted into a Dirty Silk Bundle in the process. The Silk Bundle can only hold specific items, which are also configurable. +groovyscript.wiki.thebetweenlands.steeping_pot.meta.value=Sets the color of the output and the type of output if the fluidOutput is `dye_fluid` or `drinkable_brew` +groovyscript.wiki.thebetweenlands.steeping_pot.addAcceptedItem=Adds the given ItemStack to the accepted item list for the Silk Bundle +groovyscript.wiki.thebetweenlands.steeping_pot.removeAcceptedItem=Removes the given ItemStack from the accepted item list for the Silk Bundle +groovyscript.wiki.thebetweenlands.steeping_pot.removeAllAcceptedItem=Removes all entries from the accepted item list for the Silk Bundle + + # Thermal Expansion groovyscript.wiki.thermalexpansion.energy.value=Sets the energy cost of the recipe From 30afa7a11d024fe077cc262eb07b19886a1a996d Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 18:23:27 -0800 Subject: [PATCH 05/14] comment out item output functionality of Steeping Pot --- examples/postInit/thebetweenlands.groovy | 12 ----- .../compat/mods/betweenlands/SteepingPot.java | 51 ++++++++++++------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/examples/postInit/thebetweenlands.groovy b/examples/postInit/thebetweenlands.groovy index 12da81f9c..c910efbfd 100644 --- a/examples/postInit/thebetweenlands.groovy +++ b/examples/postInit/thebetweenlands.groovy @@ -185,24 +185,12 @@ mods.thebetweenlands.steeping_pot.removeByOutput(fluid('dye_fluid').withNbt(['ty // mods.thebetweenlands.steeping_pot.removeAll() // mods.thebetweenlands.steeping_pot.removeAllAcceptedItem() -mods.thebetweenlands.steeping_pot.recipeBuilder() - .input(item('minecraft:clay')) - .fluidInput(fluid('water')) - .output(item('minecraft:diamond')) - .register() - mods.thebetweenlands.steeping_pot.recipeBuilder() .input(item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay')) .fluidInput(fluid('lava')) .fluidOutput(fluid('water')) .register() -mods.thebetweenlands.steeping_pot.recipeBuilder() - .input(item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:clay')) - .fluidInput(fluid('lava')) - .output(item('minecraft:diamond')) - .register() - mods.thebetweenlands.steeping_pot.recipeBuilder() .input(item('minecraft:diamond')) .fluidInput(fluid('lava')) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java index a40494063..5e3584810 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java @@ -54,10 +54,14 @@ public void onReload() { acceptedItems.addAll(acceptedItemsStorage.restoreFromBackup()); } + /** + * There is currently no support for output recipes in JEI - they throw a NPE error instead of appearing. + * As such, this feature of the RecipeBuilder is commented out + */ @RecipeBuilderDescription(example = { - @Example(".input(item('minecraft:clay')).fluidInput(fluid('water')).output(item('minecraft:diamond'))"), +// @Example(".input(item('minecraft:clay')).fluidInput(fluid('water')).output(item('minecraft:diamond'))"), @Example(".input(item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay'), item('minecraft:clay')).fluidInput(fluid('lava')).fluidOutput(fluid('water'))"), - @Example(".input(item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:clay')).fluidInput(fluid('lava')).output(item('minecraft:diamond'))"), +// @Example(".input(item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:clay')).fluidInput(fluid('lava')).output(item('minecraft:diamond'))"), @Example(".input(item('minecraft:diamond')).fluidInput(fluid('lava')).fluidOutput(fluid('dye_fluid')).meta(5)"), @Example(".input(item('minecraft:emerald')).fluidInput(fluid('lava')).fluidOutput(fluid('water'))"), }) @@ -107,7 +111,9 @@ public void removeAllAcceptedItem() { @Property(property = "input", comp = @Comp(gte = 1, lte = 4)) @Property(property = "fluidInput", comp = @Comp(eq = 1)) - @Property(property = "output", comp = @Comp(gte = 0, lte = 1)) + @Property(property = "fluidOutput", comp = @Comp(eq = 1)) +// @Property(property = "output", comp = @Comp(gte = 0, lte = 1)) +// @Property(property = "fluidOutput", comp = @Comp(gte = 0, lte = 1)) public static class RecipeBuilder extends AbstractRecipeBuilder { // Determines the color and state if relevant between two fluids. @@ -135,10 +141,12 @@ protected int getMaxItemInput() { @Override public void validate(GroovyLog.Msg msg) { - validateItems(msg, 1, 4, 0, 1); - validateFluids(msg, 1, 1, 0, 1); - msg.add(output.isEmpty() && fluidOutput.isEmpty(), "either output or fluidOutput must contain an entry, but both were empty"); - msg.add(!output.isEmpty() && !fluidOutput.isEmpty(), "either output or fluidOutput must have have an entry, yet both had an entry"); + validateItems(msg, 1, 4, 0, 0); + validateFluids(msg, 1, 1, 1, 1); +// validateItems(msg, 1, 4, 0, 1); +// validateFluids(msg, 1, 1, 0, 1); +// msg.add(output.isEmpty() && fluidOutput.isEmpty(), "either output or fluidOutput must contain an entry, but both were empty"); +// msg.add(!output.isEmpty() && !fluidOutput.isEmpty(), "either output or fluidOutput must have an entry, yet both had an entry"); if (!fluidOutput.isEmpty()) { var fluid = fluidOutput.get(0).getFluid(); if (fluid != FluidRegistry.DYE_FLUID && fluid != FluidRegistry.DRINKABLE_BREW) { @@ -153,8 +161,6 @@ public void validate(GroovyLog.Msg msg) { @RecipeBuilderRegistrationMethod public @Nullable SteepingPotRecipes register() { if (!validate()) return null; - SteepingPotRecipes recipe = null; - List> inputs = IngredientHelper.cartesianProductOres(input); for (var ingredient : input) { for (var stack : ingredient.getMatchingStacks()) { @@ -162,17 +168,24 @@ public void validate(GroovyLog.Msg msg) { } } - if (output.isEmpty()) { - for (var objects : inputs) { - recipe = new SteepingPotRecipes(fluidOutput.get(0), meta, fluidInput.get(0), objects.toArray()); - ModSupport.BETWEENLANDS.get().steepingPot.add(recipe); - } - } else { - for (var objects : inputs) { - recipe = new SteepingPotRecipes(output.get(0), fluidInput.get(0), objects.toArray()); - ModSupport.BETWEENLANDS.get().steepingPot.add(recipe); - } + SteepingPotRecipes recipe = null; + List> inputs = IngredientHelper.cartesianProductOres(input); + for (var objects : inputs) { + recipe = new SteepingPotRecipes(fluidOutput.get(0), meta, fluidInput.get(0), objects.toArray()); + ModSupport.BETWEENLANDS.get().steepingPot.add(recipe); } + +// if (output.isEmpty()) { +// for (var objects : inputs) { +// recipe = new SteepingPotRecipes(fluidOutput.get(0), meta, fluidInput.get(0), objects.toArray()); +// ModSupport.BETWEENLANDS.get().steepingPot.add(recipe); +// } +// } else { +// for (var objects : inputs) { +// recipe = new SteepingPotRecipes(output.get(0), fluidInput.get(0), objects.toArray()); +// ModSupport.BETWEENLANDS.get().steepingPot.add(recipe); +// } +// } return recipe; } } From fb9176fdb72543b00ab166c7b56e425cc5403649 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 19:27:55 -0800 Subject: [PATCH 06/14] apply IngredientHelper for cartesian products --- .../groovyscript/compat/mods/cyclic/Hydrator.java | 6 ++---- .../groovyscript/compat/mods/cyclic/Melter.java | 6 ++---- .../groovyscript/compat/mods/cyclic/Packager.java | 6 ++---- .../groovyscript/compat/mods/cyclic/Solidifier.java | 6 ++---- .../compat/mods/primaltech/WoodenBasin.java | 13 ++----------- .../compat/mods/randomthings/Imbuing.java | 8 +++----- 6 files changed, 13 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Hydrator.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Hydrator.java index 88019142e..36810c5e4 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Hydrator.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Hydrator.java @@ -5,18 +5,16 @@ 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 com.google.common.collect.Lists; import com.lothrazar.cyclicmagic.CyclicContent; import com.lothrazar.cyclicmagic.block.hydrator.RecipeHydrate; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; @RegistryDescription public class Hydrator extends StandardListRegistry { @@ -91,7 +89,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable RecipeHydrate register() { if (!validate()) return null; RecipeHydrate recipe = null; - List> cartesian = Lists.cartesianProduct(input.stream().map(x -> Arrays.asList(x.toMcIngredient().getMatchingStacks())).collect(Collectors.toList())); + List> cartesian = IngredientHelper.cartesianProductItemStacks(input); for (List stacks : cartesian) { recipe = new RecipeHydrate(stacks.toArray(new ItemStack[0]), output.get(0), water); ModSupport.CYCLIC.get().hydrator.add(recipe); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Melter.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Melter.java index 2f2cccd95..aa9dd2cb7 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Melter.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Melter.java @@ -4,18 +4,16 @@ 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 com.google.common.collect.Lists; import com.lothrazar.cyclicmagic.CyclicContent; import com.lothrazar.cyclicmagic.block.melter.RecipeMelter; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; @RegistryDescription public class Melter extends StandardListRegistry { @@ -80,7 +78,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable RecipeMelter register() { if (!validate()) return null; RecipeMelter recipe = null; - List> cartesian = Lists.cartesianProduct(input.stream().map(x -> Arrays.asList(x.toMcIngredient().getMatchingStacks())).collect(Collectors.toList())); + List> cartesian = IngredientHelper.cartesianProductItemStacks(input); for (List stacks : cartesian) { recipe = new RecipeMelter(stacks.toArray(new ItemStack[0]), fluidOutput.get(0).getFluid().getName(), fluidOutput.get(0).amount); ModSupport.CYCLIC.get().melter.add(recipe); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Packager.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Packager.java index c2612c9aa..7ce3e770e 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Packager.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Packager.java @@ -4,18 +4,16 @@ 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 com.google.common.collect.Lists; import com.lothrazar.cyclicmagic.CyclicContent; import com.lothrazar.cyclicmagic.block.packager.RecipePackager; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; @RegistryDescription public class Packager extends StandardListRegistry { @@ -80,7 +78,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable RecipePackager register() { if (!validate()) return null; RecipePackager recipe = null; - List> cartesian = Lists.cartesianProduct(input.stream().map(x -> Arrays.asList(x.toMcIngredient().getMatchingStacks())).collect(Collectors.toList())); + List> cartesian = IngredientHelper.cartesianProductItemStacks(input); for (List stacks : cartesian) { recipe = new RecipePackager(output.get(0), stacks.toArray(new ItemStack[0])); ModSupport.CYCLIC.get().packager.add(recipe); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Solidifier.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Solidifier.java index 2a5e82eb7..78dcda1e3 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Solidifier.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/cyclic/Solidifier.java @@ -4,18 +4,16 @@ 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 com.google.common.collect.Lists; import com.lothrazar.cyclicmagic.CyclicContent; import com.lothrazar.cyclicmagic.block.solidifier.RecipeSolidifier; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; @RegistryDescription public class Solidifier extends StandardListRegistry { @@ -83,7 +81,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable RecipeSolidifier register() { if (!validate()) return null; RecipeSolidifier recipe = null; - List> cartesian = Lists.cartesianProduct(input.stream().map(x -> Arrays.asList(x.toMcIngredient().getMatchingStacks())).collect(Collectors.toList())); + List> cartesian = IngredientHelper.cartesianProductItemStacks(input); for (List stacks : cartesian) { recipe = new RecipeSolidifier(stacks.toArray(new ItemStack[0]), output.get(0), fluidInput.get(0).getFluid().getName(), fluidInput.get(0).amount); ModSupport.CYCLIC.get().solidifier.add(recipe); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/primaltech/WoodenBasin.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/primaltech/WoodenBasin.java index c9424c76d..ed4752de1 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/primaltech/WoodenBasin.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/primaltech/WoodenBasin.java @@ -5,10 +5,9 @@ import com.cleanroommc.groovyscript.api.documentation.annotations.*; import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.core.mixin.primal_tech.WoodenBasinRecipesAccessor; -import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; import com.cleanroommc.groovyscript.registry.StandardListRegistry; -import com.google.common.collect.Lists; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; import org.jetbrains.annotations.Nullable; @@ -16,9 +15,7 @@ import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; @RegistryDescription( admonition = @Admonition(type = Admonition.Type.WARNING, value = "groovyscript.wiki.primal_tech.wooden_basin.note0") @@ -96,13 +93,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable WoodenBasinRecipes register() { if (!validate()) return null; WoodenBasinRecipes recipe = null; - List> cartesian = Lists.cartesianProduct( - input.stream() - .map( - x -> x instanceof OreDictIngredient ore - ? Collections.singletonList(ore.getOreDict()) - : Arrays.asList(x.toMcIngredient().getMatchingStacks())) - .collect(Collectors.toList())); + List> cartesian = IngredientHelper.cartesianProductOres(input); for (List entry : cartesian) { recipe = WoodenBasinRecipesAccessor.createWoodenBasinRecipes(output.get(0), fluidInput.get(0), entry.toArray()); ModSupport.PRIMAL_TECH.get().woodenBasin.add(recipe); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Imbuing.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Imbuing.java index 90c112c08..739032a6b 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Imbuing.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Imbuing.java @@ -4,18 +4,16 @@ 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 com.google.common.collect.Lists; import lumien.randomthings.recipes.imbuing.ImbuingRecipe; import lumien.randomthings.recipes.imbuing.ImbuingRecipeHandler; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.Ingredient; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; import java.util.Collection; -import java.util.stream.Collectors; +import java.util.List; @RegistryDescription public class Imbuing extends StandardListRegistry { @@ -77,7 +75,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable ImbuingRecipe register() { if (!validate()) return null; ImbuingRecipe recipe = null; - var cartesian = Lists.cartesianProduct(input.stream().map(IIngredient::toMcIngredient).map(Ingredient::getMatchingStacks).map(Arrays::asList).collect(Collectors.toList())); + List> cartesian = IngredientHelper.cartesianProductItemStacks(input); for (var toImbue : mainInput.getMatchingStacks()) { for (var stacks : cartesian) { recipe = new ImbuingRecipe(toImbue, output.get(0), stacks.toArray(new ItemStack[0])); From 8f33d893cafae88e023de696562f5abfb690a3d0 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 19:37:35 -0800 Subject: [PATCH 07/14] enhance description and add todo for IOreDicts --- .../cleanroommc/groovyscript/api/IOreDicts.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java b/src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java index cf61f6fc2..2ff243962 100644 --- a/src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java +++ b/src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java @@ -2,8 +2,18 @@ import java.util.List; -public interface IOreDicts { +/** + * Indicates that the IIngredient represents one or more oredicts. + */ +public interface IOreDicts extends IIngredient { + // TODO + // There are a large number of places currently in the GroovyScript codebase + // that check if something is "instanceof OreDictIngredient". + // these should be replaced by checks against IOreDicts, + // and surrounding code changed appropriately. + /** + * @return a list of oredict strings + */ List getOreDicts(); - } From e7a7481645823cd64f4e5134af8143aa5688846e Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 21:56:02 -0800 Subject: [PATCH 08/14] move runtimeOnly deps to map --- dependencies.gradle | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 414dfa16c..4ed3fdd53 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -114,6 +114,16 @@ final def mod_dependencies = [ 'woot-244049:2712670' : [project.debug_woot], ] +// Maps mods from CurseMaven to the properties that enable the mod. +// These mods will be enabled at runtime, but will not be compiled. +// Sorted alphabetically. +final Map> runtime_dependencies = [ + 'curse.maven:dropt-284973:3758733' : [project.debug_pyrotech], + 'curse.maven:jei-bees-248370:2490058' : [project.debug_forestry], + 'curse.maven:just-enough-petroleum-291727:2549332' : [project.debug_immersive_petroleum], + 'curse.maven:thaumic_jei-285492:2705304' : [project.debug_thaum], +] + dependencies { embed "org.apache.groovy:groovy:${project.groovy_version}" @@ -143,8 +153,11 @@ dependencies { } } - if (project.debug_thaum.toBoolean()) { - runtimeOnly 'curse.maven:thaumic_jei-285492:2705304' + // enables mods for runtime + runtime_dependencies.each { k, v -> + if (v.any { it.toBoolean() }) { + runtimeOnly rfg.deobf(k) + } } compileOnly 'com.enderio:endercore:0.5.78' @@ -172,19 +185,6 @@ dependencies { runtimeOnly rfg.deobf('curse.maven:industrialcraft_classic-242942:3093607') } - - if (project.debug_forestry.toBoolean()) { - runtimeOnly rfg.deobf('curse.maven:jei-bees-248370:2490058') - } - - if (project.debug_immersive_petroleum.toBoolean()) { - runtimeOnly rfg.deobf('curse.maven:just-enough-petroleum-291727:2549332') - } - - if (project.debug_pyrotech.toBoolean()) { - runtimeOnly rfg.deobf("curse.maven:dropt-284973:3758733") - } - compileOnly rfg.deobf('TechReborn:TechReborn-ModCompatibility-1.12.2:1.4.0.76:universal') if (project.debug_tech_reborn.toBoolean()) { runtimeOnly rfg.deobf('TechReborn:TechReborn-ModCompatibility-1.12.2:1.4.0.76:universal') From 278dcdb8fef0e2ea4dc543fc763016f463ddfe60 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 6 Dec 2024 22:00:05 -0800 Subject: [PATCH 09/14] add some runtime mods for development --- dependencies.gradle | 8 +++++++- gradle.properties | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index 4ed3fdd53..00f35abcc 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -118,10 +118,16 @@ final def mod_dependencies = [ // These mods will be enabled at runtime, but will not be compiled. // Sorted alphabetically. final Map> runtime_dependencies = [ + 'com.cleanroommc:configanytime:3.0' : [project.debug_universal_tweaks], + 'curse.maven:aainfo-573154:3627065' : [project.debug_actually_advanced_info], 'curse.maven:dropt-284973:3758733' : [project.debug_pyrotech], 'curse.maven:jei-bees-248370:2490058' : [project.debug_forestry], 'curse.maven:just-enough-petroleum-291727:2549332' : [project.debug_immersive_petroleum], + 'curse.maven:mouse-tweaks-unofficial-461660:5876158': [project.debug_mouse_tweaks_unofficial], + 'curse.maven:reid-629017:5502915' : [project.debug_roughly_enough_ids], 'curse.maven:thaumic_jei-285492:2705304' : [project.debug_thaum], + 'curse.maven:universal-tweaks-705000:5860191' : [project.debug_universal_tweaks], + 'curse.maven:vintagefix-871198:5536276' : [project.debug_vintagefix], ] dependencies { @@ -156,7 +162,7 @@ dependencies { // enables mods for runtime runtime_dependencies.each { k, v -> if (v.any { it.toBoolean() }) { - runtimeOnly rfg.deobf(k) + runtimeOnly k } } diff --git a/gradle.properties b/gradle.properties index a378e2a10..150e25f03 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,12 @@ debug_generate_examples = false debug_generate_wiki = false debug_generate_and_crash = false +debug_actually_advanced_info = false +debug_mouse_tweaks_unofficial = false +debug_roughly_enough_ids = false +debug_universal_tweaks = false +debug_vintagefix = false + # END SECTION: development environment settings # SECTION: debug mod compat From 54099519da06933693698a11e3bf46344f8733fa Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:40:37 -0800 Subject: [PATCH 10/14] make betweenlands compat compile --- dependencies.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dependencies.gradle b/dependencies.gradle index 00f35abcc..56b717ec0 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -166,6 +166,14 @@ dependencies { } } + compileOnly rfg.deobf('curse.maven:angry-pixel-the-betweenlands-mod-243363:4479688') + if (project.debug_betweenlands) { + // TODO: allow development toggling of the coremod + // until this is resolved, download and install the jar from + // https://www.curseforge.com/minecraft/mc-mods/angry-pixel-the-betweenlands-mod/files/4479688 + // runtimeOnly rfg.deobf('curse.maven:angry-pixel-the-betweenlands-mod-243363:4479688') + } + compileOnly 'com.enderio:endercore:0.5.78' compileOnly 'crazypants:enderio:5.3.72' if (project.debug_enderio.toBoolean()) { From 46ee62ed1442f213d9b496d419023186ec96b11a Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:48:58 -0800 Subject: [PATCH 11/14] fix wording of a comment --- .../groovyscript/compat/mods/betweenlands/SteepingPot.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java index 5e3584810..64dacb983 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/betweenlands/SteepingPot.java @@ -55,8 +55,8 @@ public void onReload() { } /** - * There is currently no support for output recipes in JEI - they throw a NPE error instead of appearing. - * As such, this feature of the RecipeBuilder is commented out + * There is currently no support for item output recipes in JEI - they throw an NPE instead of appearing. + * As such, this functionality and corresponding examples of the RecipeBuilder is commented out. */ @RecipeBuilderDescription(example = { // @Example(".input(item('minecraft:clay')).fluidInput(fluid('water')).output(item('minecraft:diamond'))"), From eb4fd77c4b1641008b75996a372284936a7c82ce Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:57:09 -0800 Subject: [PATCH 12/14] adjust the betweelands in lang file --- .../assets/groovyscript/lang/en_us.lang | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/main/resources/assets/groovyscript/lang/en_us.lang b/src/main/resources/assets/groovyscript/lang/en_us.lang index a0d011802..7a7ddae58 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -547,6 +547,50 @@ groovyscript.wiki.betterwithmods.turntable.rotations.value=Sets the number of ro groovyscript.wiki.betterwithmods.turntable.outputBlock.value=Sets the blockstate that replaces the input block +# The Betweenlands +groovyscript.wiki.thebetweenlands.animator.title=Animator +groovyscript.wiki.thebetweenlands.animator.description=Converts an input item, Life amount from Life Crystals, and Fuel from Sulfur into an output itemstack, summoning an entity, a random item from a loottable, or summoning an entity and outputting an itemstack. +groovyscript.wiki.thebetweenlands.animator.fuel.value=Sets the fuel consumed +groovyscript.wiki.thebetweenlands.animator.life.value=Sets the life consumed from the life crystal +groovyscript.wiki.thebetweenlands.animator.entity.value=Sets the entity being spawned +groovyscript.wiki.thebetweenlands.animator.render.value=Sets the entity to render, typically the same as the entity to be spawned +groovyscript.wiki.thebetweenlands.animator.lootTable.value=Sets the LootTable used to generate outputs +groovyscript.wiki.thebetweenlands.animator.removeByEntity=Removes all entries that match the given entity +groovyscript.wiki.thebetweenlands.animator.removeByLootTable=Removes all entries that output the given Loot Table + +groovyscript.wiki.thebetweenlands.compost.title=Compost +groovyscript.wiki.thebetweenlands.compost.description=Converts an input itemstack into an amount of compost. +groovyscript.wiki.thebetweenlands.compost.time.value=Sets the time the recipe takes in ticks +groovyscript.wiki.thebetweenlands.compost.amount.value=Sets the amount of compost output + +groovyscript.wiki.thebetweenlands.crab_pot_filter_bubbler.title=Crab Pot Filter Bubbler +groovyscript.wiki.thebetweenlands.crab_pot_filter_bubbler.description=Converts an input item into an output itemstack when a Bubbler Crab is placed inside a Crab Pot Filter. + +groovyscript.wiki.thebetweenlands.crab_pot_filter_silt.title=Crab Pot Filter Silt +groovyscript.wiki.thebetweenlands.crab_pot_filter_silt.description=Converts an input item into an output itemstack when a Silt Crab is placed inside a Crab Pot Filter. + +groovyscript.wiki.thebetweenlands.druid_altar.title=Druid Altar +groovyscript.wiki.thebetweenlands.druid_altar.description=Converts 4 input items into an output itemstack. +groovyscript.wiki.thebetweenlands.druid_altar.note0=The 4 sapling recipe to reactivate the Druid Altar recipe will always appear in JEI, even if it has been removed. Additionally, this recipe cannot be removed via `removeByInput` or `removeByOutput` + +groovyscript.wiki.thebetweenlands.pestle_and_mortar.title=Pestle And Mortar +groovyscript.wiki.thebetweenlands.pestle_and_mortar.description=Converts an input item into an output itemstack in a Pestle and Mortar by using a Pestle tool in the Mortar. + +groovyscript.wiki.thebetweenlands.purifier.title=Purifier +groovyscript.wiki.thebetweenlands.purifier.description=Converts an input item into an output itemstack, consuming Sulfur and Swamp Water as fuel. + +groovyscript.wiki.thebetweenlands.smoking_rack.title=Smoking Rack +groovyscript.wiki.thebetweenlands.smoking_rack.description=Converts an input item into an output itemstack over a configurable period of time, consuming Fallen Leaves to do so. +groovyscript.wiki.thebetweenlands.smoking_rack.time.value=Sets the time the recipe takes times 10 in seconds (3 = 30 seconds) + +groovyscript.wiki.thebetweenlands.steeping_pot.title=Steeping Pot +groovyscript.wiki.thebetweenlands.steeping_pot.description=Converts a 1,000mb of fluid into either 1,000mb of a fluid, an output itemstack, or both, consuming up to 4 items from a Silk Bundle placed inside the Steeping Pot to do so. The Silk Bundle is converted into a Dirty Silk Bundle in the process. The Silk Bundle can only hold specific items, which are also configurable. +groovyscript.wiki.thebetweenlands.steeping_pot.meta.value=Sets the color of the output and the type of output if the fluidOutput is `dye_fluid` or `drinkable_brew` +groovyscript.wiki.thebetweenlands.steeping_pot.addAcceptedItem=Adds the given ItemStack to the accepted item list for the Silk Bundle +groovyscript.wiki.thebetweenlands.steeping_pot.removeAcceptedItem=Removes the given ItemStack from the accepted item list for the Silk Bundle +groovyscript.wiki.thebetweenlands.steeping_pot.removeAllAcceptedItem=Removes all entries from the accepted item list for the Silk Bundle + + # Blood Magic groovyscript.wiki.bloodmagic.max_tier.required=less than `AltarTier.MAXTIERS`, which is determined by the config option `enableTierSixEvenThoughThereIsNoContent` @@ -2392,50 +2436,6 @@ groovyscript.wiki.theaurorian.scrapper.title=Scrapper groovyscript.wiki.theaurorian.scrapper.description=Turns an input item into an output item. Can be sped up by placing a Crystal on top of it. The crystal has a chance to break every time a recipe is executed. -# The Betweenlands -groovyscript.wiki.thebetweenlands.animator.title=Animator -groovyscript.wiki.thebetweenlands.animator.description=Converts an input item, Life amount from Life Crystals, and Fuel from Sulfur into an output itemstack, summoning an entity, a random item from a loottable, or summoning an entity and outputting an itemstack. -groovyscript.wiki.thebetweenlands.animator.fuel.value=Sets the fuel consumed -groovyscript.wiki.thebetweenlands.animator.life.value=Sets the life consumed from the life crystal -groovyscript.wiki.thebetweenlands.animator.entity.value=Sets the entity being spawned -groovyscript.wiki.thebetweenlands.animator.render.value=Sets the entity to render, typically the same as the entity to be spawned -groovyscript.wiki.thebetweenlands.animator.lootTable.value=Sets the LootTable used to generate outputs -groovyscript.wiki.thebetweenlands.animator.removeByEntity=Removes all entries that match the given entity -groovyscript.wiki.thebetweenlands.animator.removeByLootTable=Removes all entries that output the given Loot Table - -groovyscript.wiki.thebetweenlands.compost.title=Compost -groovyscript.wiki.thebetweenlands.compost.description=Converts an input itemstack into an amount of compost. -groovyscript.wiki.thebetweenlands.compost.time.value=Sets the time the recipe takes in ticks -groovyscript.wiki.thebetweenlands.compost.amount.value=Sets the amount of compost output - -groovyscript.wiki.thebetweenlands.crab_pot_filter_bubbler.title=Crab Pot Filter Bubbler -groovyscript.wiki.thebetweenlands.crab_pot_filter_bubbler.description=Converts an input item into an output itemstack when a Bubbler Crab is placed inside a Crab Pot Filter. - -groovyscript.wiki.thebetweenlands.crab_pot_filter_silt.title=Crab Pot Filter Silt -groovyscript.wiki.thebetweenlands.crab_pot_filter_silt.description=Converts an input item into an output itemstack when a Silt Crab is placed inside a Crab Pot Filter. - -groovyscript.wiki.thebetweenlands.druid_altar.title=Druid Altar -groovyscript.wiki.thebetweenlands.druid_altar.description=Converts 4 input items into an output itemstack. -groovyscript.wiki.thebetweenlands.druid_altar.note0=The 4 sapling recipe to reactivate the Druid Altar recipe will always appear in JEI, even if it has been removed. Additionally, this recipe cannot be removed via `removeByInput` or `removeByOutput` - -groovyscript.wiki.thebetweenlands.pestle_and_mortar.title=Pestle And Mortar -groovyscript.wiki.thebetweenlands.pestle_and_mortar.description=Converts an input item into an output itemstack in a Pestle and Mortar by using a Pestle tool in the Mortar. - -groovyscript.wiki.thebetweenlands.purifier.title=Purifier -groovyscript.wiki.thebetweenlands.purifier.description=Converts an input item into an output itemstack, consuming Sulfur and Swamp Water as fuel. - -groovyscript.wiki.thebetweenlands.smoking_rack.title=Smoking Rack -groovyscript.wiki.thebetweenlands.smoking_rack.description=Converts an input item into an output itemstack over a configurable period of time, consuming Fallen Leaves to do so. -groovyscript.wiki.thebetweenlands.smoking_rack.time.value=Sets the time the recipe takes times 10 in seconds (3 = 30 seconds) - -groovyscript.wiki.thebetweenlands.steeping_pot.title=Steeping Pot -groovyscript.wiki.thebetweenlands.steeping_pot.description=Converts a 1,000mb of fluid into either 1,000mb of a fluid, an output itemstack, or both, consuming up to 4 items from a Silk Bundle placed inside the Steeping Pot to do so. The Silk Bundle is converted into a Dirty Silk Bundle in the process. The Silk Bundle can only hold specific items, which are also configurable. -groovyscript.wiki.thebetweenlands.steeping_pot.meta.value=Sets the color of the output and the type of output if the fluidOutput is `dye_fluid` or `drinkable_brew` -groovyscript.wiki.thebetweenlands.steeping_pot.addAcceptedItem=Adds the given ItemStack to the accepted item list for the Silk Bundle -groovyscript.wiki.thebetweenlands.steeping_pot.removeAcceptedItem=Removes the given ItemStack from the accepted item list for the Silk Bundle -groovyscript.wiki.thebetweenlands.steeping_pot.removeAllAcceptedItem=Removes all entries from the accepted item list for the Silk Bundle - - # Thermal Expansion groovyscript.wiki.thermalexpansion.energy.value=Sets the energy cost of the recipe From 730be808c382dbcdce1e686d6cd48c08a2abcb75 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:01:15 -0800 Subject: [PATCH 13/14] move strip forge reqs to core buildscript --- dependencies.gradle | 2 -- gradle.properties | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 56b717ec0..51971bdaa 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -204,6 +204,4 @@ dependencies { runtimeOnly rfg.deobf('TechReborn:TechReborn-ModCompatibility-1.12.2:1.4.0.76:universal') } - runtimeOnly 'com.cleanroommc:strip-latest-forge-requirements:1.0' - } diff --git a/gradle.properties b/gradle.properties index 150e25f03..38c6e9aad 100644 --- a/gradle.properties +++ b/gradle.properties @@ -202,7 +202,7 @@ includeCommonDevEnvMods = true # and cannot launch with the forge version required, enable this to strip the forge version requirements from that mod. # This will add 'strip-latest-forge-requirements' as 'runtimeOnlyNonPublishable'. # Requires useMixins or forceEnableMixins to be true, as the mod uses mixins to function. -stripForgeRequirements = false +stripForgeRequirements = true # If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your From 6ce0f8bae1c6be5a9776c07cab7688395eb5e9ee Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:02:01 -0800 Subject: [PATCH 14/14] add toBoolean() --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index 51971bdaa..dea3c8052 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -167,7 +167,7 @@ dependencies { } compileOnly rfg.deobf('curse.maven:angry-pixel-the-betweenlands-mod-243363:4479688') - if (project.debug_betweenlands) { + if (project.debug_betweenlands.toBoolean()) { // TODO: allow development toggling of the coremod // until this is resolved, download and install the jar from // https://www.curseforge.com/minecraft/mc-mods/angry-pixel-the-betweenlands-mod/files/4479688