From 12e61c8a5d75bb2d17ac932968a327b64bbd4ec3 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:39:55 -0800 Subject: [PATCH] add Random Things compat (#253) * Random Things * uni <3 !!!! * dont log uni if no inputs --- dependencies.gradle | 1 + examples/postInit/randomthings.groovy | 47 ++++++++++ gradle.properties | 1 + .../groovyscript/compat/mods/ModSupport.java | 2 + .../compat/mods/randomthings/Anvil.java | 84 +++++++++++++++++ .../compat/mods/randomthings/Imbuing.java | 90 +++++++++++++++++++ .../mods/randomthings/RandomThings.java | 10 +++ .../assets/groovyscript/lang/en_us.lang | 14 +++ 8 files changed, 249 insertions(+) create mode 100644 examples/postInit/randomthings.groovy create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Anvil.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Imbuing.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/RandomThings.java diff --git a/dependencies.gradle b/dependencies.gradle index 6ab3f9ef9..4cbea18e2 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -97,6 +97,7 @@ final def mod_dependencies = [ 'projecte-226410:2702991' : [project.debug_projecte], 'athenaeum-284350:4633750' : [project.debug_pyrotech], 'pyrotech-306676:4956838' : [project.debug_pyrotech], + 'random-things-59816:2905241' : [project.debug_random_things], 'mystical_world-282940:3460961' : [project.debug_roots], 'patchouli-306770:3162874' : [project.debug_roots, project.debug_natures_aura, project.debug_prodigytech], 'prodigytech-297414:2769520' : [project.debug_prodigytech], diff --git a/examples/postInit/randomthings.groovy b/examples/postInit/randomthings.groovy new file mode 100644 index 000000000..2702ea6fe --- /dev/null +++ b/examples/postInit/randomthings.groovy @@ -0,0 +1,47 @@ + +// Auto generated groovyscript example file +// MODS_LOADED: randomthings + +log.info 'mod \'randomthings\' detected, running script' + +// Anvil Crafting: +// Converts two itemstacks into an itemstack in the Vanilla Anvil. + +mods.randomthings.anvil.removeByInput(item('randomthings:obsidianskull')) +mods.randomthings.anvil.removeByOutput(item('randomthings:lavawader')) +// mods.randomthings.anvil.removeAll() + +mods.randomthings.anvil.recipeBuilder() + .input(item('minecraft:diamond_sword'), item('minecraft:boat')) + .output(item('minecraft:diamond')) + .cost(1) + .register() + +mods.randomthings.anvil.recipeBuilder() + .input(item('minecraft:iron_sword'), item('minecraft:boat')) + .output(item('minecraft:gold_ingot') * 16) + .cost(50) + .register() + + +// Imbuing Station: +// Converts four itemstacks into an itemstack in the Random Things Imbuing Station. + +mods.randomthings.imbuing.removeByInput(item('minecraft:coal')) +mods.randomthings.imbuing.removeByInput(item('minecraft:cobblestone')) +mods.randomthings.imbuing.removeByOutput(item('randomthings:imbue:3')) +// mods.randomthings.imbuing.removeAll() + +mods.randomthings.imbuing.recipeBuilder() + .mainInput(item('minecraft:clay')) + .input(item('minecraft:clay'), item('minecraft:gold_ingot'), item('minecraft:gold_block')) + .output(item('minecraft:diamond') * 8) + .register() + +mods.randomthings.imbuing.recipeBuilder() + .mainInput(item('minecraft:diamond')) + .input(item('minecraft:clay'), item('minecraft:gold_ingot'), item('minecraft:diamond')) + .output(item('minecraft:gold_ingot')) + .register() + + diff --git a/gradle.properties b/gradle.properties index b3e1ccef9..6728ffcbb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -73,6 +73,7 @@ debug_prodigytech = false debug_projecte = false debug_pyrotech = false +debug_random_things = false debug_roots = false debug_rustic = 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 fd17502cc..a7fe7e7a1 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -50,6 +50,7 @@ import com.cleanroommc.groovyscript.compat.mods.prodigytech.ProdigyTech; import com.cleanroommc.groovyscript.compat.mods.projecte.ProjectE; import com.cleanroommc.groovyscript.compat.mods.pyrotech.PyroTech; +import com.cleanroommc.groovyscript.compat.mods.randomthings.RandomThings; import com.cleanroommc.groovyscript.compat.mods.roots.Roots; import com.cleanroommc.groovyscript.compat.mods.rustic.Rustic; import com.cleanroommc.groovyscript.compat.mods.tcomplement.TinkersComplement; @@ -126,6 +127,7 @@ public class ModSupport { public static final GroovyContainer PRODIGY_TECH = new InternalModContainer<>("prodigytech", "Prodigy Tech", ProdigyTech::new); public static final GroovyContainer PROJECT_E = new InternalModContainer<>("projecte", "ProjectE", ProjectE::new); public static final GroovyContainer PYROTECH = new InternalModContainer<>("pyrotech", "Pyrotech", PyroTech::new); + public static final GroovyContainer RANDOM_THINGS = new InternalModContainer<>("randomthings", "Random Things", RandomThings::new); public static final GroovyContainer ROOTS = new InternalModContainer<>("roots", "Roots 3", Roots::new); public static final GroovyContainer RUSTIC = new InternalModContainer<>("rustic", "Rustic", Rustic::new); public static final GroovyContainer TECH_REBORN = new InternalModContainer<>("techreborn", "Tech Reborn", TechReborn::new); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Anvil.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Anvil.java new file mode 100644 index 000000000..f89fedcc8 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Anvil.java @@ -0,0 +1,84 @@ +package com.cleanroommc.groovyscript.compat.mods.randomthings; + +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 lumien.randomthings.recipes.anvil.AnvilRecipe; +import lumien.randomthings.recipes.anvil.AnvilRecipeHandler; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription(admonition = { + @Admonition(value = "groovyscript.wiki.randomthings.anvil.note0", type = Admonition.Type.TIP), + @Admonition(value = "groovyscript.wiki.randomthings.anvil.note1", type = Admonition.Type.WARNING), + @Admonition(value = "groovyscript.wiki.randomthings.anvil.note2", type = Admonition.Type.BUG, format = Admonition.Format.STANDARD), +}) +public class Anvil extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:diamond_sword'), item('minecraft:boat')).output(item('minecraft:diamond')).cost(1)"), + @Example(".input(item('minecraft:iron_sword'), item('minecraft:boat')).output(item('minecraft:gold_ingot') * 16).cost(50)") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return AnvilRecipeHandler.getAllRecipes(); + } + + @MethodDescription(example = @Example("item('randomthings:obsidianskull')")) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> (input.test(r.getFirst()) || input.test(r.getSecond())) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('randomthings:lavawader')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.getOutput()) && doAddBackup(r)); + } + + @Property(property = "input", comp = @Comp(eq = 2)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gt = 0)) + private int cost; + + @RecipeBuilderMethodDescription + public RecipeBuilder cost(int cost) { + this.cost = cost; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Random Things Anvil recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 2, 2, 1, 1); + validateFluids(msg); + msg.add(cost <= 0, "cost must be greater than 0, yet it was {}", cost); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable AnvilRecipe register() { + if (!validate()) return null; + AnvilRecipe recipe = null; + for (var input1 : input.get(0).getMatchingStacks()) { + for (var input2 : input.get(1).getMatchingStacks()) { + recipe = new AnvilRecipe(input1, input2, output.get(0), cost); + ModSupport.RANDOM_THINGS.get().anvil.add(recipe); + } + } + return 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 new file mode 100644 index 000000000..90c112c08 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/Imbuing.java @@ -0,0 +1,90 @@ +package com.cleanroommc.groovyscript.compat.mods.randomthings; + +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 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; + +@RegistryDescription +public class Imbuing extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".mainInput(item('minecraft:clay')).input(item('minecraft:clay'), item('minecraft:gold_ingot'), item('minecraft:gold_block')).output(item('minecraft:diamond') * 8)"), + @Example(".mainInput(item('minecraft:diamond')).input(item('minecraft:clay'), item('minecraft:gold_ingot'), item('minecraft:diamond')).output(item('minecraft:gold_ingot'))") + }) + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return ImbuingRecipeHandler.imbuingRecipes; + } + + @MethodDescription(example = { + @Example("item('minecraft:cobblestone')"), @Example("item('minecraft:coal')") + }) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> (input.test(r.toImbue()) || r.getIngredients().stream().anyMatch(input)) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('randomthings:imbue:3')")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.getResult()) && doAddBackup(r)); + } + + @Property(property = "input", comp = @Comp(eq = 3, unique = "groovyscript.wiki.randomthings.imbuing.input.required")) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(not = "null")) + private IIngredient mainInput; + + @RecipeBuilderMethodDescription + public RecipeBuilder mainInput(IIngredient mainInput) { + this.mainInput = mainInput; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Random Things Imbuing recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 3, 3, 1, 1); + validateFluids(msg); + msg.add(mainInput == null, "mainInput must be defined"); + var uni = input.stream().distinct().count(); + msg.add(uni > 0 && uni < 3, "each input must be unique, yet only {}/3 of the inputs were unique. mainInput is not considered", uni); + } + + @Override + @RecipeBuilderRegistrationMethod + 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())); + for (var toImbue : mainInput.getMatchingStacks()) { + for (var stacks : cartesian) { + recipe = new ImbuingRecipe(toImbue, output.get(0), stacks.toArray(new ItemStack[0])); + ModSupport.RANDOM_THINGS.get().imbuing.add(recipe); + } + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/RandomThings.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/RandomThings.java new file mode 100644 index 000000000..951f67367 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/randomthings/RandomThings.java @@ -0,0 +1,10 @@ +package com.cleanroommc.groovyscript.compat.mods.randomthings; + +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; + +public class RandomThings extends GroovyPropertyContainer { + + public final Imbuing imbuing = new Imbuing(); + public final Anvil anvil = new Anvil(); + +} diff --git a/src/main/resources/assets/groovyscript/lang/en_us.lang b/src/main/resources/assets/groovyscript/lang/en_us.lang index a67e0de42..6298f425a 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -1901,6 +1901,20 @@ groovyscript.wiki.projecte.transmutation.output.value=Sets the normal output blo groovyscript.wiki.projecte.transmutation.altOutput.value=Sets the shift output blockstate +# Random Things +groovyscript.wiki.randomthings.anvil.title=Anvil Crafting +groovyscript.wiki.randomthings.anvil.description=Converts two itemstacks into an itemstack in the Vanilla Anvil. +groovyscript.wiki.randomthings.anvil.note0=Internally this uses a more restricted version of `AnvilUpdateEvent`, so consider using an event listener for that instead. +groovyscript.wiki.randomthings.anvil.note1=Consumes the entire stack in the Anvil, regardless of the amount actually required. To avoid issues, consider only using unstackable items. +groovyscript.wiki.randomthings.anvil.note2=When crafting any recipe done via this, if the output of the Anvil was picked up via clicking it, it will not be craftable again until restarting the game. Can be fixed with a mixin from Universal Tweaks. +groovyscript.wiki.randomthings.anvil.cost.value=Sets the cost of the recipe in levels consumed + +groovyscript.wiki.randomthings.imbuing.title=Imbuing Station +groovyscript.wiki.randomthings.imbuing.description=Converts four itemstacks into an itemstack in the Random Things Imbuing Station. +groovyscript.wiki.randomthings.imbuing.mainInput.value=Sets the center IIngredient +groovyscript.wiki.randomthings.imbuing.input.required=each input item used must be unique + + # Roots groovyscript.wiki.roots.animal_harvest.title=Animal Harvest groovyscript.wiki.roots.animal_harvest.description=Animal Harvest is a ritual that drops items from nearby mob's based on that mobs loottable without harming the mob. Only applies to allowed mobs.