From 4f222ebd19a27a74ca44e05def248decd43a99a7 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Tue, 27 May 2025 19:38:32 -0700 Subject: [PATCH 01/12] add material object mapper --- .../mapper/ObjectMapperManager.java | 6 ++++ .../groovyscript/mapper/ObjectMappers.java | 31 ++++++++++++------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java index c5d71cd2e..56778eed5 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java @@ -16,6 +16,7 @@ import groovy.lang.ExpandoMetaClass; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.block.Block; +import net.minecraft.block.material.Material; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.enchantment.Enchantment; import net.minecraft.init.Blocks; @@ -119,6 +120,11 @@ public static void init() { .docOfType("block") .textureBinder(TextureBinder.of(ItemStack::new, TextureBinder.ofItem())) .register(); + ObjectMapper.builder("material", Material.class) + .parser(ObjectMappers::parseBlockMaterial) + .completerOfNames(ObjectMappers::getMaterialNames) + .docOfType("block material") + .register(); /*ObjectMapper.builder("blockstate", IBlockState.class) .parser(ObjectMappers::parseBlockState) .addSignature(String.class) diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java index 6869cc3b1..6fec97ef6 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java @@ -202,21 +202,28 @@ public static Result parseTextFormatting(String mainArg, Object. private static Map materials; - public static Result parseBlockMaterial(String mainArg, Object... args) { - if (materials == null) { - materials = new Object2ObjectOpenHashMap<>(); - for (Field field : Material.class.getFields()) { - if ((field.getModifiers() & Modifier.STATIC) != 0 && field.getType() == Material.class) { - try { - Material material = (Material) field.get(null); - materials.put(field.getName(), material); - materials.put(field.getName().toLowerCase(Locale.ROOT), material); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } + private static void generateMaterials() { + if (materials != null) return; + materials = new Object2ObjectOpenHashMap<>(); + for (Field field : Material.class.getFields()) { + if ((field.getModifiers() & Modifier.STATIC) != 0 && field.getType() == Material.class) { + try { + Material material = (Material) field.get(null); + materials.put(field.getName(), material); + materials.put(field.getName().toLowerCase(Locale.ROOT), material); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); } } } + } + + public static Collection getMaterialNames() { + return materials.keySet(); + } + + public static Result parseBlockMaterial(String mainArg, Object... args) { + generateMaterials(); Material material = materials.get(mainArg); return material == null ? Result.error() : Result.some(material); } From b06eac583d5d63ba9e716cec4575193230bf0e73 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Tue, 27 May 2025 19:39:13 -0700 Subject: [PATCH 02/12] add fluidstacklist to iingredient list method --- .../groovyscript/helper/ingredient/FluidStackList.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/FluidStackList.java b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/FluidStackList.java index 47a9d34f6..9258e7ee5 100644 --- a/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/FluidStackList.java +++ b/src/main/java/com/cleanroommc/groovyscript/helper/ingredient/FluidStackList.java @@ -1,9 +1,11 @@ package com.cleanroommc.groovyscript.helper.ingredient; +import com.cleanroommc.groovyscript.api.IIngredient; import net.minecraftforge.fluids.FluidStack; import java.util.ArrayList; import java.util.Collection; +import java.util.List; public class FluidStackList extends ArrayList { @@ -43,4 +45,9 @@ public void copyElements() { } } } + + @SuppressWarnings("unchecked") + public List asIIngredientList() { + return (List) (Object) this; + } } From 88c74b444c97d9b74b443bc8ef2208a4bf5c68d7 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Tue, 27 May 2025 19:39:42 -0700 Subject: [PATCH 03/12] add erebus dep --- dependencies.gradle | 1 + gradle.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/dependencies.gradle b/dependencies.gradle index 7cb201253..dfd1c4f58 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -66,6 +66,7 @@ final def mod_dependencies = [ 'brandons_core-231382:3408276' : [project.debug_draconic_evolution], 'draconic_evolution-223565:3431261' : [project.debug_draconic_evolution], 'redstone_flux-270789:2920436' : [project.debug_draconic_evolution, project.debug_thermal], + 'the-erebus-220698:3211974' : [project.debug_erebus], 'essentialcraft-4-unofficial-254817:5416404' : [project.debug_essentialcraft_4], 'dummycore-unofficial-266491:2611426' : [project.debug_essentialcraft_4], 'cyclops-core-232758:3159497' : [project.debug_evilcraft, project.debug_integrated_dynamics], diff --git a/gradle.properties b/gradle.properties index 10ffb67fd..ebabc9e83 100644 --- a/gradle.properties +++ b/gradle.properties @@ -51,6 +51,7 @@ debug_cyclic = false debug_draconic_evolution = false debug_enderio = false +debug_erebus = false debug_essentialcraft_4 = false debug_evilcraft = false debug_extended_crafting = false From f31ef8adde0f10a1e948e527071c2fde8662c3f3 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Tue, 27 May 2025 19:39:59 -0700 Subject: [PATCH 04/12] add jer and jem for jei support for erebus --- dependencies.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dependencies.gradle b/dependencies.gradle index dfd1c4f58..a4207e13b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -131,7 +131,9 @@ final Map> runtime_dependencies = [ '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-magiculture-940521:5796192': [project.debug_erebus], 'curse.maven:just-enough-petroleum-291727:2549332' : [project.debug_immersive_petroleum], + 'curse.maven:just-enough-resources-240630:4440935' : [project.debug_erebus], '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], From 7b7b5438017862a7b04438ffbd0d719a11e6a1bd Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Tue, 27 May 2025 19:40:14 -0700 Subject: [PATCH 05/12] add mixins for erebus --- .../groovyscript/core/LateMixin.java | 1 + .../erebus/ComposterRegistryAccessor.java | 28 +++++++++++++++++++ .../mixin/erebus/ComposterRegistryMixin.java | 23 +++++++++++++++ .../erebus/OfferingAltarRecipeAccessor.java | 23 +++++++++++++++ .../erebus/SmoothieMakerRecipeAccessor.java | 24 ++++++++++++++++ .../resources/mixin.groovyscript.erebus.json | 13 +++++++++ 6 files changed, 112 insertions(+) create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/ComposterRegistryAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/ComposterRegistryMixin.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/OfferingAltarRecipeAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/SmoothieMakerRecipeAccessor.java create mode 100644 src/main/resources/mixin.groovyscript.erebus.json diff --git a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java index 26c630fc2..194362903 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java @@ -18,6 +18,7 @@ public class LateMixin implements ILateMixinLoader { "betterwithmods", "thebetweenlands", "bloodmagic", + "erebus", "botania", "calculator", "draconicevolution", diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/ComposterRegistryAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/ComposterRegistryAccessor.java new file mode 100644 index 000000000..b8e350ba6 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/ComposterRegistryAccessor.java @@ -0,0 +1,28 @@ +package com.cleanroommc.groovyscript.core.mixin.erebus; + +import erebus.recipes.ComposterRegistry; +import net.minecraft.block.material.Material; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(value = ComposterRegistry.class, remap = false) +public interface ComposterRegistryAccessor { + + @Accessor("compostableMaterials") + static List getMaterial() { + throw new UnsupportedOperationException(); + } + + @Accessor("registry") + static List getRegistry() { + throw new UnsupportedOperationException(); + } + + @Accessor("blacklist") + static List getBlacklist() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/ComposterRegistryMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/ComposterRegistryMixin.java new file mode 100644 index 000000000..0dcbfbbef --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/ComposterRegistryMixin.java @@ -0,0 +1,23 @@ +package com.cleanroommc.groovyscript.core.mixin.erebus; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import erebus.recipes.ComposterRegistry; +import net.minecraft.block.material.Material; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import java.util.ArrayList; +import java.util.List; + +@Mixin(value = ComposterRegistry.class, remap = false) +public abstract class ComposterRegistryMixin { + + /** + * @reason ensure the list of valid materials is mutable for GroovyScript compat + * @author WaitingIdly + */ + @ModifyExpressionValue(method = "", at = @At(value = "INVOKE", target = "Ljava/util/Arrays;asList([Ljava/lang/Object;)Ljava/util/List;")) + private static List mutableMaterial(List original) { + return new ArrayList<>(original); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/OfferingAltarRecipeAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/OfferingAltarRecipeAccessor.java new file mode 100644 index 000000000..22ee91d43 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/OfferingAltarRecipeAccessor.java @@ -0,0 +1,23 @@ +package com.cleanroommc.groovyscript.core.mixin.erebus; + +import erebus.recipes.OfferingAltarRecipe; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.List; + +@Mixin(value = OfferingAltarRecipe.class, remap = false) +public interface OfferingAltarRecipeAccessor { + + @Invoker("") + static OfferingAltarRecipe createOfferingAltarRecipe(ItemStack output, Object... inputs) { + throw new UnsupportedOperationException(); + } + + @Accessor("list") + static List getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/SmoothieMakerRecipeAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/SmoothieMakerRecipeAccessor.java new file mode 100644 index 000000000..1b47aacfe --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/erebus/SmoothieMakerRecipeAccessor.java @@ -0,0 +1,24 @@ +package com.cleanroommc.groovyscript.core.mixin.erebus; + +import erebus.recipes.SmoothieMakerRecipe; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.List; + +@Mixin(value = SmoothieMakerRecipe.class, remap = false) +public interface SmoothieMakerRecipeAccessor { + + @Invoker("") + static SmoothieMakerRecipe createSmoothieMakerRecipe(ItemStack output, ItemStack container, FluidStack[] fluids, Object... input) { + throw new UnsupportedOperationException(); + } + + @Accessor("recipes") + static List getRecipes() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/resources/mixin.groovyscript.erebus.json b/src/main/resources/mixin.groovyscript.erebus.json new file mode 100644 index 000000000..cedf6f245 --- /dev/null +++ b/src/main/resources/mixin.groovyscript.erebus.json @@ -0,0 +1,13 @@ +{ + "package": "com.cleanroommc.groovyscript.core.mixin.erebus", + "refmap": "mixins.groovyscript.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "ComposterRegistryAccessor", + "ComposterRegistryMixin", + "OfferingAltarRecipeAccessor", + "SmoothieMakerRecipeAccessor" + ] +} \ No newline at end of file From db7337e3bf01419c4e7d004353d40361b0b95a34 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Tue, 27 May 2025 19:41:25 -0700 Subject: [PATCH 06/12] add erebus compat --- examples/postInit/erebus.groovy | 75 ++++++++++ .../groovyscript/compat/mods/ModSupport.java | 2 + .../compat/mods/erebus/Composter.java | 108 +++++++++++++++ .../compat/mods/erebus/Erebus.java | 11 ++ .../compat/mods/erebus/OfferingAltar.java | 91 ++++++++++++ .../compat/mods/erebus/Smoothie.java | 129 ++++++++++++++++++ .../assets/groovyscript/lang/en_us.lang | 26 ++++ 7 files changed, 442 insertions(+) create mode 100644 examples/postInit/erebus.groovy create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Composter.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Erebus.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/OfferingAltar.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Smoothie.java diff --git a/examples/postInit/erebus.groovy b/examples/postInit/erebus.groovy new file mode 100644 index 000000000..c34ca4bc3 --- /dev/null +++ b/examples/postInit/erebus.groovy @@ -0,0 +1,75 @@ + +// Auto generated groovyscript example file +// MODS_LOADED: erebus + +log.info 'mod \'erebus\' detected, running script' + +// Organic Composter: +// Converts valid items into compost. The Blacklist blocks all ItemStacks on it from being used, the Material list allows +// any Blocks using the valid Materials to be converted, and the Registry contains any valid ItemStacks. The conversion +// takes 10 seconds, and is fueled by erebus wall plants. + +// mods.erebus.composter.removeFromBlacklist(item('erebus:wall_plants', 1)) +mods.erebus.composter.removeFromMaterial(material('sponge')) +mods.erebus.composter.removeFromRegistry(item('minecraft:stick')) +// mods.erebus.composter.removeAllFromBlacklist() +// mods.erebus.composter.removeAllFromMaterial() +// mods.erebus.composter.removeAllFromRegistry() + +mods.erebus.composter.addBlacklist(item('erebus:wall_plants', 7)) +mods.erebus.composter.addBlacklist(item('erebus:wall_plants_cultivated', 7)) +mods.erebus.composter.addMaterial(material('tnt')) +mods.erebus.composter.addRegistry(item('minecraft:gold_ingot')) + +// Offering Altar: +// Converts up to 3 input itemstacks into an output itemstack. + +// mods.erebus.offering_altar.removeByInput(item('minecraft:emerald')) +mods.erebus.offering_altar.removeByOutput(item('erebus:materials', 38)) +// mods.erebus.offering_altar.removeAll() + +mods.erebus.offering_altar.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay')) + .register() + +mods.erebus.offering_altar.recipeBuilder() + .input(item('minecraft:stone'), ore('gemDiamond'), item('minecraft:clay')) + .output(item('minecraft:gold_ingot')) + .register() + + +// Smoothie-matic: +// Converts a container item, up to 4 input items, and up to 4 input fluidstacks into an output itemstack. + +mods.erebus.smoothie.removeByContainer(item('minecraft:bucket')) +mods.erebus.smoothie.removeByInput(fluid('honey')) +mods.erebus.smoothie.removeByInput(item('erebus:materials', 18)) +mods.erebus.smoothie.removeByOutput(item('erebus:materials', 21)) +// mods.erebus.smoothie.removeAll() + +mods.erebus.smoothie.recipeBuilder() + .container(item('minecraft:diamond')) + .output(item('minecraft:gold_ingot')) + .register() + +mods.erebus.smoothie.recipeBuilder() + .container(item('minecraft:clay')) + .input(item('minecraft:clay')) + .output(item('minecraft:gold_ingot')) + .register() + +mods.erebus.smoothie.recipeBuilder() + .container(item('minecraft:gold_block')) + .fluidInput(fluid('water') * 5000) + .output(item('minecraft:gold_ingot')) + .register() + +mods.erebus.smoothie.recipeBuilder() + .container(item('minecraft:stone')) + .input(item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')) + .fluidInput(fluid('lava') * 500, fluid('formic_acid') * 500, fluid('honey') * 500, fluid('milk') * 500) + .output(item('minecraft:clay') * 5) + .register() + + 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 e32c4df48..8c0361ddf 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -29,6 +29,7 @@ import com.cleanroommc.groovyscript.compat.mods.cyclic.Cyclic; import com.cleanroommc.groovyscript.compat.mods.draconicevolution.DraconicEvolution; import com.cleanroommc.groovyscript.compat.mods.enderio.EnderIO; +import com.cleanroommc.groovyscript.compat.mods.erebus.Erebus; import com.cleanroommc.groovyscript.compat.mods.essentialcraft.EssentialCraft; import com.cleanroommc.groovyscript.compat.mods.evilcraft.EvilCraft; import com.cleanroommc.groovyscript.compat.mods.extendedcrafting.ExtendedCrafting; @@ -118,6 +119,7 @@ public class ModSupport { public static final GroovyContainer CYCLIC = new InternalModContainer<>("cyclicmagic", "Cyclic", Cyclic::new, "cyclic"); public static final GroovyContainer DRACONIC_EVOLUTION = new InternalModContainer<>("draconicevolution", "Draconic Evolution", DraconicEvolution::new, "de"); public static final GroovyContainer ENDER_IO = new InternalModContainer<>("enderio", "Ender IO", EnderIO::new, "eio"); + public static final GroovyContainer EREBUS = new InternalModContainer<>("erebus", "The Erebus", Erebus::new); public static final GroovyContainer ESSENTIALCRAFT = new InternalModContainer<>("essentialcraft", "EssentialCraft 4", EssentialCraft::new, "ec4"); public static final GroovyContainer EVILCRAFT = new InternalModContainer<>("evilcraft", "EvilCraft", EvilCraft::new); public static final GroovyContainer EXTENDED_CRAFTING = new InternalModContainer<>("extendedcrafting", "Extended Crafting", ExtendedCrafting::new); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Composter.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Composter.java new file mode 100644 index 000000000..5b62b66c0 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Composter.java @@ -0,0 +1,108 @@ +package com.cleanroommc.groovyscript.compat.mods.erebus; + +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.IScriptReloadable; +import com.cleanroommc.groovyscript.api.documentation.annotations.Admonition; +import com.cleanroommc.groovyscript.api.documentation.annotations.Example; +import com.cleanroommc.groovyscript.api.documentation.annotations.MethodDescription; +import com.cleanroommc.groovyscript.api.documentation.annotations.RegistryDescription; +import com.cleanroommc.groovyscript.core.mixin.erebus.ComposterRegistryAccessor; +import com.cleanroommc.groovyscript.registry.AbstractReloadableStorage; +import com.cleanroommc.groovyscript.registry.NamedRegistry; +import net.minecraft.block.material.Material; +import net.minecraft.item.ItemStack; + +import java.util.List; + +@RegistryDescription(category = RegistryDescription.Category.ENTRIES, admonition = { + @Admonition(value = "groovyscript.wiki.erebus.composter.note0", type = Admonition.Type.BUG), @Admonition("groovyscript.wiki.erebus.composter.note1") +}) +public class Composter extends NamedRegistry implements IScriptReloadable { + + private final AbstractReloadableStorage materialStorage = new AbstractReloadableStorage<>(); + private final AbstractReloadableStorage registryStorage = new AbstractReloadableStorage<>(); + private final AbstractReloadableStorage blacklistStorage = new AbstractReloadableStorage<>(); + + private static List getMaterial() { + return ComposterRegistryAccessor.getMaterial(); + } + + private static List getRegistry() { + return ComposterRegistryAccessor.getRegistry(); + } + + private static List getBlacklist() { + return ComposterRegistryAccessor.getBlacklist(); + } + + @Override + public void onReload() { + var material = getMaterial(); + var registry = getRegistry(); + var blacklist = getBlacklist(); + material.removeAll(materialStorage.removeScripted()); + material.addAll(materialStorage.restoreFromBackup()); + registry.removeAll(registryStorage.removeScripted()); + registry.addAll(registryStorage.restoreFromBackup()); + blacklist.removeAll(blacklistStorage.removeScripted()); + blacklist.addAll(blacklistStorage.restoreFromBackup()); + } + + @Override + public void afterScriptLoad() {} + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("material('tnt')")) + public boolean addMaterial(Material material) { + return getMaterial().add(material) && materialStorage.addScripted(material); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("item('minecraft:gold_ingot')")) + public boolean addRegistry(ItemStack stack) { + return getRegistry().add(stack) && registryStorage.addScripted(stack); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = { + @Example("item('erebus:wall_plants', 7)"), + @Example("item('erebus:wall_plants_cultivated', 7)") + }) + public boolean addBlacklist(ItemStack stack) { + return getBlacklist().add(stack) && blacklistStorage.addScripted(stack); + } + + @MethodDescription(example = @Example("material('sponge')")) + public boolean removeFromMaterial(Material material) { + return getMaterial().removeIf(r -> material == r && materialStorage.addBackup(r)); + } + + @MethodDescription(example = @Example("item('minecraft:stick')")) + public boolean removeFromRegistry(IIngredient ingredient) { + return getRegistry().removeIf(r -> ingredient.test(r) && registryStorage.addBackup(r)); + } + + @MethodDescription(example = @Example(value = "item('erebus:wall_plants', 1)", commented = true)) + public boolean removeFromBlacklist(IIngredient ingredient) { + return getBlacklist().removeIf(r -> ingredient.test(r) && blacklistStorage.addBackup(r)); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAllFromMaterial() { + var entries = getMaterial(); + entries.forEach(materialStorage::addBackup); + entries.clear(); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAllFromRegistry() { + var entries = getRegistry(); + entries.forEach(registryStorage::addBackup); + entries.clear(); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAllFromBlacklist() { + var entries = getBlacklist(); + entries.forEach(blacklistStorage::addBackup); + entries.clear(); + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Erebus.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Erebus.java new file mode 100644 index 000000000..f8c9bc7a8 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Erebus.java @@ -0,0 +1,11 @@ +package com.cleanroommc.groovyscript.compat.mods.erebus; + +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; + +public class Erebus extends GroovyPropertyContainer { + + public final Composter composter = new Composter(); + public final Smoothie smoothie = new Smoothie(); + public final OfferingAltar offeringAltar = new OfferingAltar(); + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/OfferingAltar.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/OfferingAltar.java new file mode 100644 index 000000000..6c658d5ed --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/OfferingAltar.java @@ -0,0 +1,91 @@ +package com.cleanroommc.groovyscript.compat.mods.erebus; + +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.erebus.OfferingAltarRecipeAccessor; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import erebus.recipes.OfferingAltarRecipe; +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; + +@RegistryDescription +public class OfferingAltar extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:gold_ingot')).output(item('minecraft:clay'))"), + @Example(".input(item('minecraft:stone'), ore('gemDiamond'), item('minecraft:clay')).output(item('minecraft:gold_ingot'))") + }) + public OfferingAltar.RecipeBuilder recipeBuilder() { + return new OfferingAltar.RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return OfferingAltarRecipeAccessor.getRecipes(); + } + + @MethodDescription(example = @Example(value = "item('minecraft:emerald')", commented = true)) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (Object object : r.getInputs()) { + if (object instanceof ItemStack stack && input.test(stack)) return doAddBackup(r); + else if (object instanceof String s) { + if (input instanceof IOreDicts d && d.getOreDicts().contains(s)) { + return true; + } else if (OreDictionary.getOres(s, false).stream().anyMatch(input)) { + return true; + } + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('erebus:materials', 38)")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.getOutput()) && doAddBackup(r)); + } + + @Property(property = "input", comp = @Comp(gte = 1, lte = 3)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public String getErrorMsg() { + return "Error adding Erebus Offering Altar Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 3, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable OfferingAltarRecipe register() { + if (!validate()) return null; + OfferingAltarRecipe recipe = null; + var inputs = IngredientHelper.cartesianProductOres(input); + for (List objects : inputs) { + recipe = OfferingAltarRecipeAccessor.createOfferingAltarRecipe(output.get(0), objects.toArray()); + ModSupport.EREBUS.get().offeringAltar.add(recipe); + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Smoothie.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Smoothie.java new file mode 100644 index 000000000..11cdecac1 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Smoothie.java @@ -0,0 +1,129 @@ +package com.cleanroommc.groovyscript.compat.mods.erebus; + +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.erebus.SmoothieMakerRecipeAccessor; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import erebus.recipes.SmoothieMakerRecipe; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.oredict.OreDictionary; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +@RegistryDescription +public class Smoothie extends StandardListRegistry { + + @RecipeBuilderDescription(example = { + @Example(".container(item('minecraft:diamond')).output(item('minecraft:gold_ingot'))"), + @Example(".container(item('minecraft:clay')).input(item('minecraft:clay')).output(item('minecraft:gold_ingot'))"), + @Example(".container(item('minecraft:gold_block')).fluidInput(fluid('water') * 5000).output(item('minecraft:gold_ingot'))"), + @Example(".container(item('minecraft:stone')).input(item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')).fluidInput(fluid('lava') * 500, fluid('formic_acid') * 500, fluid('honey') * 500, fluid('milk') * 500).output(item('minecraft:clay') * 5)") + }) + public Smoothie.RecipeBuilder recipeBuilder() { + return new Smoothie.RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return SmoothieMakerRecipeAccessor.getRecipes(); + } + + @MethodDescription(example = {@Example("item('erebus:materials', 18)"), @Example("fluid('honey')")}) + public boolean removeByInput(IIngredient input) { + return getRecipes().removeIf(r -> { + for (FluidStack fluid : r.getFluids()) { + if (input.test(fluid)) return doAddBackup(r); + } + for (Object object : r.getInputs()) { + if (object instanceof ItemStack stack && input.test(stack)) return doAddBackup(r); + else if (object instanceof String s) { + if (input instanceof IOreDicts d && d.getOreDicts().contains(s)) { + return true; + } else if (OreDictionary.getOres(s, false).stream().anyMatch(input)) { + return true; + } + } + } + return false; + }); + } + + @MethodDescription(example = @Example("item('minecraft:bucket')")) + public boolean removeByContainer(IIngredient container) { + return getRecipes().removeIf(r -> container.test(r.getContainer()) && doAddBackup(r)); + } + + @MethodDescription(example = @Example("item('erebus:materials', 21)")) + public boolean removeByOutput(IIngredient output) { + return getRecipes().removeIf(r -> output.test(r.getOutput()) && doAddBackup(r)); + } + + @Property(property = "input", comp = @Comp(gte = 0, lte = 4)) + @Property(property = "fluidInput", comp = @Comp(gte = 0, lte = 4, unique = "groovyscript.wiki.erebus.smoothie.fluidInput.required")) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private static final int MAX_FLUID_CAPACITY = 16_000; + @Property(comp = @Comp(not = "null")) + private ItemStack container; + + @RecipeBuilderMethodDescription + public RecipeBuilder container(ItemStack container) { + this.container = container; + return this; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public String getErrorMsg() { + return "Error adding Erebus Smoothie Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 0, 4, 1, 1); + validateFluids(msg, 0, 4, 0, 0); + msg.add(IngredientHelper.isEmpty(container), "container must not be empty"); + validateStackSize(msg, getMaxItemInput(), "container", IngredientHelper.toIIngredient(container)); + validateStackSize(msg, getMaxItemInput(), "output", IngredientHelper.toIIngredient(output.getOrEmpty(0))); + validateStackSize(msg, MAX_FLUID_CAPACITY, "fluidInput", fluidInput.asIIngredientList()); + + // ensure no duplicate fluids + Set set = new ObjectOpenHashSet<>(); + for (var fluidStack : fluidInput) { + if (!set.add(fluidStack.getFluid())) { + msg.add("duplicate fluids cannot be handled correctly, and duplicate fluid {} was detected", fluidStack.getFluid()); + break; + } + } + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable SmoothieMakerRecipe register() { + if (!validate()) return null; + SmoothieMakerRecipe recipe = null; + var inputs = IngredientHelper.cartesianProductOres(input); + for (List objects : inputs) { + recipe = SmoothieMakerRecipeAccessor.createSmoothieMakerRecipe(output.get(0), container, fluidInput.toArray(new FluidStack[0]), objects.toArray()); + ModSupport.EREBUS.get().smoothie.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 a26101856..ecb002ae5 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -1205,6 +1205,32 @@ groovyscript.wiki.enderio.vat.multipliers2.value=Sets the multiplier applied to groovyscript.wiki.enderio.vat.baseMultiplier.value=Sets the base amount of fluid output groovyscript.wiki.enderio.vat.energy.value=Sets the energy cost of the recipe + +# Erebus +groovyscript.wiki.erebus.composter.title=Organic Composter +groovyscript.wiki.erebus.composter.description=Converts valid items into compost. The Blacklist blocks all ItemStacks on it from being used, the Material list allows any Blocks using the valid Materials to be converted, and the Registry contains any valid ItemStacks. The conversion takes 10 seconds, and is fueled by erebus wall plants. +groovyscript.wiki.erebus.composter.note0=The Blacklist is supposed to have 2 entries by default - `erebus:wall_plants@1` and `erebus:wall_plants_cultivated@1` - however it is initialized prior to blocks or items being registered, and so contains two empty itemstacks instead. Furthermore, it is likely that using the metadata **1** is also a bug, as only metadata **7** is used as fuel. +groovyscript.wiki.erebus.composter.note1=Items extending `ItemFood` and `ItemSeed` will always be valid items unless added to the blacklist. +groovyscript.wiki.erebus.composter.addBlacklist=Add the given ItemStack to the Composter Blacklist +groovyscript.wiki.erebus.composter.addMaterial=Add the given Material to the Composter Material list +groovyscript.wiki.erebus.composter.addRegistry=Add the given ItemStack to the Composter Registry +groovyscript.wiki.erebus.composter.removeAllFromBlacklist=Removes all entries from the Blacklist +groovyscript.wiki.erebus.composter.removeAllFromMaterial=Removes all entries from the Material list +groovyscript.wiki.erebus.composter.removeAllFromRegistry=Removes all entries from the Registry +groovyscript.wiki.erebus.composter.removeFromBlacklist=Removes all matching ItemStacks from the Blacklist +groovyscript.wiki.erebus.composter.removeFromMaterial=Removes the provided Material from the Material list +groovyscript.wiki.erebus.composter.removeFromRegistry=Removes all matching ItemStacks from the Registry + +groovyscript.wiki.erebus.offering_altar.title=Offering Altar +groovyscript.wiki.erebus.offering_altar.description=Converts up to 3 input itemstacks into an output itemstack. + +groovyscript.wiki.erebus.smoothie.title=Smoothie-matic +groovyscript.wiki.erebus.smoothie.description=Converts a container item, up to 4 input items, and up to 4 input fluidstacks into an output itemstack. +groovyscript.wiki.erebus.smoothie.fluidInput.required=no fluid inputs can have a duplicate fluid type +groovyscript.wiki.erebus.smoothie.container.value=Sets the container itemstack required +groovyscript.wiki.erebus.smoothie.removeByContainer=Removes all recipes matching the provided container + + # EssentialCraft groovyscript.wiki.essentialcraft.demon_trade.title=Demon Trade groovyscript.wiki.essentialcraft.demon_trade.description=Adds an item that can be sold to Demons to obtain Ackronite. Note that each demon that spawns has a random item that it can accept, and will not accept any other item. From 7cc6c1d6e6906a177c508d9b3c00eb8272f625d3 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:21:24 -0700 Subject: [PATCH 07/12] modify material handling --- .../mapper/ObjectMapperManager.java | 4 +- .../groovyscript/mapper/ObjectMappers.java | 35 +----------- .../mapper/ObjectParserHelper.java | 53 +++++++++++++++++++ 3 files changed, 57 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java index 56778eed5..7c773c256 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java @@ -121,8 +121,8 @@ public static void init() { .textureBinder(TextureBinder.of(ItemStack::new, TextureBinder.ofItem())) .register(); ObjectMapper.builder("material", Material.class) - .parser(ObjectMappers::parseBlockMaterial) - .completerOfNames(ObjectMappers::getMaterialNames) + .parser(IObjectParser.wrapStringGetter(ObjectParserHelper.MATERIALS::get)) + .completerOfNames(ObjectParserHelper.MATERIALS::keySet) .docOfType("block material") .register(); /*ObjectMapper.builder("blockstate", IBlockState.class) diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java index 6fec97ef6..421c959be 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java @@ -6,9 +6,7 @@ import com.cleanroommc.groovyscript.core.mixin.VillagerProfessionAccessor; import com.google.common.base.Optional; import com.google.common.collect.Iterators; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.block.Block; -import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; @@ -26,9 +24,8 @@ import net.minecraftforge.fml.common.registry.VillagerRegistry; import org.jetbrains.annotations.NotNull; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.*; +import java.util.Arrays; +import java.util.Iterator; import static com.cleanroommc.groovyscript.mapper.ObjectMapperManager.SPLITTER; import static com.cleanroommc.groovyscript.mapper.ObjectMapperManager.WILDCARD; @@ -200,34 +197,6 @@ public static Result parseTextFormatting(String mainArg, Object. return textformat == null ? Result.error() : Result.some(textformat); } - private static Map materials; - - private static void generateMaterials() { - if (materials != null) return; - materials = new Object2ObjectOpenHashMap<>(); - for (Field field : Material.class.getFields()) { - if ((field.getModifiers() & Modifier.STATIC) != 0 && field.getType() == Material.class) { - try { - Material material = (Material) field.get(null); - materials.put(field.getName(), material); - materials.put(field.getName().toLowerCase(Locale.ROOT), material); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - } - } - - public static Collection getMaterialNames() { - return materials.keySet(); - } - - public static Result parseBlockMaterial(String mainArg, Object... args) { - generateMaterials(); - Material material = materials.get(mainArg); - return material == null ? Result.error() : Result.some(material); - } - public static @NotNull Result parseNBT(String mainArg, Object... args) { try { return Result.some(JsonToNBT.getTagFromJson(mainArg)); diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java new file mode 100644 index 000000000..01e893587 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java @@ -0,0 +1,53 @@ +package com.cleanroommc.groovyscript.mapper; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.block.material.Material; +import net.minecraftforge.fml.common.registry.ForgeRegistries; + +import java.util.Map; + +public class ObjectParserHelper { + + public static final Map MATERIALS; + + static { + MATERIALS = new ImmutableMap.Builder() + .put("AIR", Material.AIR) + .put("GRASS", Material.GRASS) + .put("GROUND", Material.GROUND) + .put("WOOD", Material.WOOD) + .put("ROCK", Material.ROCK) + .put("IRON", Material.IRON) + .put("ANVIL", Material.ANVIL) + .put("WATER", Material.WATER) + .put("LAVA", Material.LAVA) + .put("LEAVES", Material.LEAVES) + .put("PLANTS", Material.PLANTS) + .put("VINE", Material.VINE) + .put("SPONGE", Material.SPONGE) + .put("CLOTH", Material.CLOTH) + .put("FIRE", Material.FIRE) + .put("SAND", Material.SAND) + .put("CIRCUITS", Material.CIRCUITS) + .put("CARPET", Material.CARPET) + .put("GLASS", Material.GLASS) + .put("REDSTONE_LIGHT", Material.REDSTONE_LIGHT) + .put("TNT", Material.TNT) + .put("CORAL", Material.CORAL) + .put("ICE", Material.ICE) + .put("PACKED_ICE", Material.PACKED_ICE) + .put("SNOW", Material.SNOW) + .put("CRAFTED_SNOW", Material.CRAFTED_SNOW) + .put("CACTUS", Material.CACTUS) + .put("CLAY", Material.CLAY) + .put("GOURD", Material.GOURD) + .put("DRAGON_EGG", Material.DRAGON_EGG) + .put("PORTAL", Material.PORTAL) + .put("CAKE", Material.CAKE) + .put("WEB", Material.WEB) + .put("PISTON", Material.PISTON) + .put("BARRIER", Material.BARRIER) + .put("STRUCTURE_VOID", Material.STRUCTURE_VOID) + .build(); + } +} From 283822176163f39728c4f045b600460c807b9c1e Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:21:52 -0700 Subject: [PATCH 08/12] adjust villager career handling --- .../groovyscript/mapper/ObjectMapperManager.java | 16 ++-------------- .../groovyscript/mapper/ObjectMappers.java | 15 --------------- .../groovyscript/mapper/ObjectParserHelper.java | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java index 7c773c256..b23bdb9cc 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java @@ -7,7 +7,6 @@ import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; import com.cleanroommc.groovyscript.core.mixin.CreativeTabsAccessor; import com.cleanroommc.groovyscript.core.mixin.OreDictionaryAccessor; -import com.cleanroommc.groovyscript.core.mixin.VillagerProfessionAccessor; import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; import com.cleanroommc.groovyscript.helper.ingredient.OreDictWildcardIngredient; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; @@ -175,20 +174,9 @@ public static void init() { .completer(ForgeRegistries.VILLAGER_PROFESSIONS) .docOfType("villager profession") .register(); - - final List careerList = new ArrayList<>(); - for (var profession : ForgeRegistries.VILLAGER_PROFESSIONS) { - if (profession != null) { - for (var career : ((VillagerProfessionAccessor) profession).getCareers()) { - if (career != null) { - careerList.add(career.getName()); - } - } - } - } ObjectMapper.builder("career", VillagerRegistry.VillagerCareer.class) - .parser(ObjectMappers::parseVillagerCareer) - .completerOfNames(() -> careerList) + .parser(IObjectParser.wrapStringGetter(ObjectParserHelper.VILLAGER_CAREERS::get)) + .completerOfNames(ObjectParserHelper.VILLAGER_CAREERS::keySet) .docOfType("villager career") .register(); ObjectMapper.builder("creativeTab", CreativeTabs.class) diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java index 421c959be..76762a480 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMappers.java @@ -3,7 +3,6 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.Result; import com.cleanroommc.groovyscript.core.mixin.CreativeTabsAccessor; -import com.cleanroommc.groovyscript.core.mixin.VillagerProfessionAccessor; import com.google.common.base.Optional; import com.google.common.collect.Iterators; import net.minecraft.block.Block; @@ -21,7 +20,6 @@ import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.registry.ForgeRegistries; -import net.minecraftforge.fml.common.registry.VillagerRegistry; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -163,19 +161,6 @@ private static Result parseBlockStates(IBlockState defaultState, It return Result.some(defaultState); } - public static Result parseVillagerCareer(String mainArg, Object... args) { - for (var profession : ForgeRegistries.VILLAGER_PROFESSIONS) { - if (profession != null) { - for (var career : ((VillagerProfessionAccessor) (profession)).getCareers()) { - if (career != null && mainArg.equals(career.getName())) { - return Result.some(career); - } - } - } - } - return Result.error(); - } - public static Result parseCreativeTab(String mainArg, Object... args) { for (CreativeTabs tab : CreativeTabs.CREATIVE_TAB_ARRAY) { if (tab != null && mainArg.equals(((CreativeTabsAccessor) tab).getTabLabel2())) { diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java index 01e893587..f3ba95cc7 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java @@ -1,8 +1,10 @@ package com.cleanroommc.groovyscript.mapper; +import com.cleanroommc.groovyscript.core.mixin.VillagerProfessionAccessor; import com.google.common.collect.ImmutableMap; import net.minecraft.block.material.Material; import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.fml.common.registry.VillagerRegistry; import java.util.Map; @@ -10,6 +12,8 @@ public class ObjectParserHelper { public static final Map MATERIALS; + public static final Map VILLAGER_CAREERS; + static { MATERIALS = new ImmutableMap.Builder() .put("AIR", Material.AIR) @@ -49,5 +53,15 @@ public class ObjectParserHelper { .put("BARRIER", Material.BARRIER) .put("STRUCTURE_VOID", Material.STRUCTURE_VOID) .build(); + + var careers = new ImmutableMap.Builder(); + for (var profession : ForgeRegistries.VILLAGER_PROFESSIONS) { + if (profession == null) continue; + for (var career : ((VillagerProfessionAccessor) profession).getCareers()) { + if (career == null) continue; + careers.put(career.getName(), career); + } + } + VILLAGER_CAREERS = careers.build(); } } From 22c0c9177b0142349d2c2c1f96cc5f9366ab5af2 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:22:00 -0700 Subject: [PATCH 09/12] rename material to blockmaterial --- .../cleanroommc/groovyscript/mapper/ObjectMapperManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java index b23bdb9cc..e89110df8 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java @@ -119,7 +119,7 @@ public static void init() { .docOfType("block") .textureBinder(TextureBinder.of(ItemStack::new, TextureBinder.ofItem())) .register(); - ObjectMapper.builder("material", Material.class) + ObjectMapper.builder("blockmaterial", Material.class) .parser(IObjectParser.wrapStringGetter(ObjectParserHelper.MATERIALS::get)) .completerOfNames(ObjectParserHelper.MATERIALS::keySet) .docOfType("block material") From 3aa5b4cc466165f1214c1cbb22318ec720ce95cc Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sat, 4 Oct 2025 14:15:04 -0700 Subject: [PATCH 10/12] reconfigure materials and remove villager career storing --- .../mapper/ObjectMapperManager.java | 27 +++++-- .../mapper/ObjectParserHelper.java | 70 +++++-------------- 2 files changed, 40 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java index 6920c122f..3a7393a09 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java @@ -6,6 +6,7 @@ import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; import com.cleanroommc.groovyscript.core.mixin.CreativeTabsAccessor; import com.cleanroommc.groovyscript.core.mixin.OreDictionaryAccessor; +import com.cleanroommc.groovyscript.core.mixin.VillagerProfessionAccessor; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; import com.cleanroommc.groovyscript.server.CompletionParams; import com.cleanroommc.groovyscript.server.Completions; @@ -73,6 +74,7 @@ public static void registerObjectMapper(AbstractObjectMapper mapper) { } public static void init() { + ObjectParserHelper.init(); registerObjectMapper(ItemStackMapper.INSTANCE); registerObjectMapper(BlockStateMapper.INSTANCE); ObjectMapper.builder("resource", ResourceLocation.class) @@ -117,8 +119,8 @@ public static void init() { .textureBinder(TextureBinder.of(ItemStack::new, TextureBinder.ofItem())) .register(); ObjectMapper.builder("blockmaterial", Material.class) - .parser(IObjectParser.wrapStringGetter(ObjectParserHelper.MATERIALS::get)) - .completerOfNames(ObjectParserHelper.MATERIALS::keySet) + .parser(IObjectParser.wrapStringGetter(ObjectParserHelper.materials::get)) + .completerOfNames(ObjectParserHelper.materials::keySet) .docOfType("block material") .register(); /*ObjectMapper.builder("blockstate", IBlockState.class) @@ -172,8 +174,23 @@ public static void init() { .docOfType("villager profession") .register(); ObjectMapper.builder("career", VillagerRegistry.VillagerCareer.class) - .parser(IObjectParser.wrapStringGetter(ObjectParserHelper.VILLAGER_CAREERS::get)) - .completerOfNames(ObjectParserHelper.VILLAGER_CAREERS::keySet) + .parser(IObjectParser.wrapStringGetter(x -> { + for (var profession : ForgeRegistries.VILLAGER_PROFESSIONS) { + for (var career : ((VillagerProfessionAccessor) profession).getCareers()) { + if (x.equals(career.getName())) return career; + } + } + return null; + })) + .completerOfNames(() -> { + List careers = new ArrayList<>(); + for (var profession : ForgeRegistries.VILLAGER_PROFESSIONS) { + for (var career : ((VillagerProfessionAccessor) profession).getCareers()) { + careers.add(career.getName()); + } + } + return careers; + }) .docOfType("villager career") .register(); ObjectMapper.builder("creativeTab", CreativeTabs.class) @@ -213,7 +230,7 @@ public static void init() { * @param name game object handler name (method name) * @param mainArg main argument * @param args extra arguments - * @param silent if error messages should be logged + * @param silent if error messages should be logged * @return game object or null */ diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java index f3ba95cc7..6bfeb4fde 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java @@ -1,67 +1,33 @@ package com.cleanroommc.groovyscript.mapper; -import com.cleanroommc.groovyscript.core.mixin.VillagerProfessionAccessor; import com.google.common.collect.ImmutableMap; import net.minecraft.block.material.Material; -import net.minecraftforge.fml.common.registry.ForgeRegistries; -import net.minecraftforge.fml.common.registry.VillagerRegistry; +import java.lang.reflect.Modifier; +import java.util.Locale; import java.util.Map; public class ObjectParserHelper { - public static final Map MATERIALS; + public static Map materials; - public static final Map VILLAGER_CAREERS; - - static { - MATERIALS = new ImmutableMap.Builder() - .put("AIR", Material.AIR) - .put("GRASS", Material.GRASS) - .put("GROUND", Material.GROUND) - .put("WOOD", Material.WOOD) - .put("ROCK", Material.ROCK) - .put("IRON", Material.IRON) - .put("ANVIL", Material.ANVIL) - .put("WATER", Material.WATER) - .put("LAVA", Material.LAVA) - .put("LEAVES", Material.LEAVES) - .put("PLANTS", Material.PLANTS) - .put("VINE", Material.VINE) - .put("SPONGE", Material.SPONGE) - .put("CLOTH", Material.CLOTH) - .put("FIRE", Material.FIRE) - .put("SAND", Material.SAND) - .put("CIRCUITS", Material.CIRCUITS) - .put("CARPET", Material.CARPET) - .put("GLASS", Material.GLASS) - .put("REDSTONE_LIGHT", Material.REDSTONE_LIGHT) - .put("TNT", Material.TNT) - .put("CORAL", Material.CORAL) - .put("ICE", Material.ICE) - .put("PACKED_ICE", Material.PACKED_ICE) - .put("SNOW", Material.SNOW) - .put("CRAFTED_SNOW", Material.CRAFTED_SNOW) - .put("CACTUS", Material.CACTUS) - .put("CLAY", Material.CLAY) - .put("GOURD", Material.GOURD) - .put("DRAGON_EGG", Material.DRAGON_EGG) - .put("PORTAL", Material.PORTAL) - .put("CAKE", Material.CAKE) - .put("WEB", Material.WEB) - .put("PISTON", Material.PISTON) - .put("BARRIER", Material.BARRIER) - .put("STRUCTURE_VOID", Material.STRUCTURE_VOID) - .build(); + public static void init() { + materials = getMaterials(); + } - var careers = new ImmutableMap.Builder(); - for (var profession : ForgeRegistries.VILLAGER_PROFESSIONS) { - if (profession == null) continue; - for (var career : ((VillagerProfessionAccessor) profession).getCareers()) { - if (career == null) continue; - careers.put(career.getName(), career); + private static ImmutableMap getMaterials() { + ImmutableMap.Builder materialBuilder = new ImmutableMap.Builder<>(); + for (var field : Material.class.getFields()) { + if ((field.getModifiers() & Modifier.STATIC) != 0 && field.getType() == Material.class) { + try { + var material = (Material) field.get(null); + materialBuilder.put(field.getName(), material); + materialBuilder.put(field.getName().toLowerCase(Locale.ROOT), material); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } } } - VILLAGER_CAREERS = careers.build(); + return materialBuilder.build(); } } From 5739f736672a9b8c0706106d671352e4e4d143d5 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sat, 4 Oct 2025 14:15:23 -0700 Subject: [PATCH 11/12] the humble spotless apply --- .../groovyscript/compat/mods/erebus/Composter.java | 1 - .../groovyscript/compat/mods/erebus/Erebus.java | 1 - .../groovyscript/compat/mods/erebus/Smoothie.java | 4 +++- .../groovyscript/mapper/ObjectMapperManager.java | 7 ++++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Composter.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Composter.java index 5b62b66c0..491653670 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Composter.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Composter.java @@ -104,5 +104,4 @@ public void removeAllFromBlacklist() { entries.forEach(blacklistStorage::addBackup); entries.clear(); } - } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Erebus.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Erebus.java index f8c9bc7a8..916bbb3b4 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Erebus.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Erebus.java @@ -7,5 +7,4 @@ public class Erebus extends GroovyPropertyContainer { public final Composter composter = new Composter(); public final Smoothie smoothie = new Smoothie(); public final OfferingAltar offeringAltar = new OfferingAltar(); - } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Smoothie.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Smoothie.java index 11cdecac1..8ddaf3990 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Smoothie.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/erebus/Smoothie.java @@ -39,7 +39,9 @@ public Collection getRecipes() { return SmoothieMakerRecipeAccessor.getRecipes(); } - @MethodDescription(example = {@Example("item('erebus:materials', 18)"), @Example("fluid('honey')")}) + @MethodDescription(example = { + @Example("item('erebus:materials', 18)"), @Example("fluid('honey')") + }) public boolean removeByInput(IIngredient input) { return getRecipes().removeIf(r -> { for (FluidStack fluid : r.getFluids()) { diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java index 3a7393a09..9d013915c 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectMapperManager.java @@ -39,13 +39,14 @@ public class ObjectMapperManager { - private static final Map> handlers = new Object2ObjectOpenHashMap<>(); - private static final Map>> handlerConflicts = new Object2ObjectOpenHashMap<>(); - private static final Map, Map>> modHandlers = new Object2ObjectOpenHashMap<>(); public static final String EMPTY = "empty"; public static final String WILDCARD = "*"; public static final String SPLITTER = ":"; + private static final Map> handlers = new Object2ObjectOpenHashMap<>(); + private static final Map>> handlerConflicts = new Object2ObjectOpenHashMap<>(); + private static final Map, Map>> modHandlers = new Object2ObjectOpenHashMap<>(); + public static void registerObjectMapper(AbstractObjectMapper mapper) { String key = mapper.getName(); if (mapper.getMod() != null) { From d89c5df815e70af49fda8769988cc4a6b0883ea8 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sat, 4 Oct 2025 14:55:50 -0700 Subject: [PATCH 12/12] call isStatic --- .../com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java index 6bfeb4fde..28c8dc58f 100644 --- a/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java +++ b/src/main/java/com/cleanroommc/groovyscript/mapper/ObjectParserHelper.java @@ -18,7 +18,7 @@ public static void init() { private static ImmutableMap getMaterials() { ImmutableMap.Builder materialBuilder = new ImmutableMap.Builder<>(); for (var field : Material.class.getFields()) { - if ((field.getModifiers() & Modifier.STATIC) != 0 && field.getType() == Material.class) { + if (Modifier.isStatic(field.getModifiers()) && field.getType() == Material.class) { try { var material = (Material) field.get(null); materialBuilder.put(field.getName(), material);