From 16ed04a0d17f0341d85227e9e9f214ba9e02088f Mon Sep 17 00:00:00 2001 From: brachy84 <45517902+brachy84@users.noreply.github.com> Date: Fri, 5 Apr 2024 01:38:10 +0200 Subject: [PATCH] GroovyScript 1.0.0 (#2425) Co-authored-by: TechLord22 <37029404+TechLord22@users.noreply.github.com> --- dependencies.gradle | 2 +- src/main/java/gregtech/GregTechMod.java | 2 +- .../integration/groovy/GroovyExpansions.java | 27 ++ .../GroovyMaterialBuilderExpansion.java | 10 + .../groovy/GroovyScriptModule.java | 143 ++++--- .../integration/groovy/MaterialExpansion.java | 225 +++++++++++ .../groovy/MaterialPropertyExpansion.java | 355 ++++++++++++++++++ .../integration/groovy/PropertyContainer.java | 47 +++ .../groovy/VirtualizedRecipeMap.java | 2 +- 9 files changed, 760 insertions(+), 53 deletions(-) create mode 100644 src/main/java/gregtech/integration/groovy/MaterialExpansion.java create mode 100644 src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java create mode 100644 src/main/java/gregtech/integration/groovy/PropertyContainer.java diff --git a/dependencies.gradle b/dependencies.gradle index 49d93cc7bd5..4ab81db91bd 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -41,7 +41,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") api("com.cleanroommc:modularui:2.4.3") { transitive = false } - api("com.cleanroommc:groovyscript:0.8.0") { transitive = false } + api("com.cleanroommc:groovyscript:1.0.1") { transitive = false } api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.684") api rfg.deobf("curse.maven:ae2-extended-life-570458:4402048") // AE2UEL 0.55.6 api rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31 diff --git a/src/main/java/gregtech/GregTechMod.java b/src/main/java/gregtech/GregTechMod.java index 7e55e60b889..883b581292c 100644 --- a/src/main/java/gregtech/GregTechMod.java +++ b/src/main/java/gregtech/GregTechMod.java @@ -33,7 +33,7 @@ dependencies = "required:forge@[14.23.5.2847,);" + "required-after:codechickenlib@[3.2.3,);" + "required-after:modularui@[2.3,);" + "required-after:mixinbooter@[8.0,);" + "after:appliedenergistics2;" + "after:forestry;" + "after:extrabees;" + "after:extratrees;" + "after:genetics;" + "after:magicbees;" + - "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + "after:groovyscript@[0.7.0,);" + + "after:jei@[4.15.0,);" + "after:crafttweaker@[4.1.20,);" + "after:groovyscript@[1.0.1,);" + "after:theoneprobe;" + "after:hwyla;") public class GregTechMod { diff --git a/src/main/java/gregtech/integration/groovy/GroovyExpansions.java b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java index 8c23fdf270f..e24191091e8 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyExpansions.java +++ b/src/main/java/gregtech/integration/groovy/GroovyExpansions.java @@ -1,8 +1,13 @@ package gregtech.integration.groovy; +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.fluids.attribute.FluidAttributes; import gregtech.api.recipes.RecipeBuilder; +import gregtech.api.unification.Element; +import gregtech.api.unification.Elements; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.properties.ToolProperty; import net.minecraft.util.ResourceLocation; @@ -39,4 +44,26 @@ public static Material.Builder materialBuilder(MaterialEvent event, int id, Stri } return materialBuilder(event, id, new ResourceLocation(domain, path)); } + + public static ToolProperty.Builder toolBuilder(MaterialEvent event, float harvestSpeed, float attackDamage, + int durability, int harvestLevel) { + return ToolProperty.Builder.of(harvestSpeed, attackDamage, durability, harvestLevel); + } + + public static ToolProperty.Builder toolBuilder(MaterialEvent event) { + return toolBuilder(event, 1.0F, 1.0F, 100, 2); + } + + public static FluidBuilder fluidBuilder(MaterialEvent event) { + return new FluidBuilder(); + } + + public static Element addElement(MaterialEvent event, long protons, long neutrons, long halfLifeSeconds, + String decayTo, String name, String symbol, boolean isIsotope) { + return Elements.add(protons, neutrons, halfLifeSeconds, decayTo, name, symbol, isIsotope); + } + + public static FluidBuilder acidic(FluidBuilder builder) { + return builder.attributes(FluidAttributes.ACID); + } } diff --git a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java index f4e30273435..2b67fa26844 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java +++ b/src/main/java/gregtech/integration/groovy/GroovyMaterialBuilderExpansion.java @@ -8,6 +8,7 @@ import gregtech.api.unification.material.info.MaterialFlag; import gregtech.api.unification.material.info.MaterialIconSet; import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.ToolProperty; import gregtech.api.unification.stack.MaterialStack; import net.minecraft.util.ResourceLocation; @@ -115,4 +116,13 @@ public static Material.Builder components(Material.Builder builder, Object... ob } return builder.components(materialStacks.toArray(new MaterialStack[0])); } + + public static Material.Builder toolStats(Material.Builder builder, ToolProperty.Builder toolBuilder) { + return builder.toolStats(toolBuilder.build()); + } + + public static Material.Builder toolStats(Material.Builder builder, float harvestSpeed, float attackDamage, + int durability, int harvestLevel) { + return builder.toolStats(ToolProperty.Builder.of(harvestSpeed, attackDamage, durability, harvestLevel).build()); + } } diff --git a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java index 571261241b2..e5082df1461 100644 --- a/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java +++ b/src/main/java/gregtech/integration/groovy/GroovyScriptModule.java @@ -2,11 +2,14 @@ import gregtech.api.GTValues; import gregtech.api.GregTechAPI; +import gregtech.api.fluids.FluidBuilder; import gregtech.api.items.metaitem.MetaItem; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.modules.GregTechModule; import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; +import gregtech.api.unification.Element; +import gregtech.api.unification.Elements; import gregtech.api.unification.material.Material; import gregtech.api.unification.material.event.MaterialEvent; import gregtech.api.unification.material.event.PostMaterialEvent; @@ -20,8 +23,6 @@ import gregtech.common.pipelike.fluidpipe.BlockFluidPipe; import gregtech.common.pipelike.itempipe.BlockItemPipe; import gregtech.integration.IntegrationSubmodule; -import gregtech.integration.crafttweaker.material.MaterialExpansion; -import gregtech.integration.crafttweaker.material.MaterialPropertyExpansion; import gregtech.modules.GregTechModules; import net.minecraft.item.ItemStack; @@ -35,24 +36,25 @@ import com.cleanroommc.groovyscript.GroovyScript; import com.cleanroommc.groovyscript.api.GroovyLog; import com.cleanroommc.groovyscript.api.GroovyPlugin; -import com.cleanroommc.groovyscript.api.IGameObjectHandler; +import com.cleanroommc.groovyscript.api.IGameObjectParser; +import com.cleanroommc.groovyscript.api.Result; import com.cleanroommc.groovyscript.compat.mods.GroovyContainer; import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; -import com.cleanroommc.groovyscript.event.EventBusType; -import com.cleanroommc.groovyscript.event.GroovyEventManager; -import com.cleanroommc.groovyscript.gameobjects.GameObjectHandlerManager; +import com.cleanroommc.groovyscript.gameobjects.GameObjectHandler; import com.cleanroommc.groovyscript.helper.EnumHelper; -import com.cleanroommc.groovyscript.sandbox.LoadStage; import com.cleanroommc.groovyscript.sandbox.expand.ExpansionHelper; import com.google.common.collect.ImmutableList; -import groovy.lang.Closure; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.eclipse.lsp4j.CompletionItem; +import org.eclipse.lsp4j.CompletionItemKind; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Supplier; @@ -68,7 +70,7 @@ public class GroovyScriptModule extends IntegrationSubmodule implements GroovyPlugin { private static GroovyContainer modSupportContainer; - private static final Map> metaItems = new Object2ObjectOpenHashMap<>(); + private static final Object2ObjectOpenHashMap> metaItems = new Object2ObjectOpenHashMap<>(); @NotNull @Override @@ -87,12 +89,20 @@ public static boolean isCurrentlyRunning() { } public static > T parseAndValidateEnumValue(Class clazz, String raw, String type) { + return parseAndValidateEnumValue(clazz, raw, type, false); + } + + @Contract("_,_,_,true -> !null") + public static > T parseAndValidateEnumValue(Class clazz, String raw, String type, + boolean crash) { T t = EnumHelper.valueOfNullable(clazz, raw, false); if (t == null) { - GroovyLog.get().error("Can't find {} for {} in material builder. Valid values are {};", + String msg = GroovyLog.format("Can't find {} for {} in material builder. Valid values are {};", type, raw, Arrays.toString(clazz.getEnumConstants())); + if (crash) throw new NoSuchElementException(msg); + GroovyLog.get().error(msg); return null; } return t; @@ -216,57 +226,90 @@ public static void loadMetaItemBracketHandler() { return "GregTech"; } + @Optional.Method(modid = Mods.Names.GROOVY_SCRIPT) @Override public @Nullable ModPropertyContainer createModPropertyContainer() { - return new ModPropertyContainer() { - - public void materialEvent(EventPriority priority, Closure eventListener) { - if (isCurrentlyRunning() && GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { - GroovyLog.get().error("GregTech's material event can only be used in pre init!"); - return; - } - GroovyEventManager.INSTANCE.listen(priority, EventBusType.FORGE, MaterialEvent.class, - eventListener); - } - - public void materialEvent(Closure eventListener) { - materialEvent(EventPriority.NORMAL, eventListener); - } - - public void lateMaterialEvent(EventPriority priority, Closure eventListener) { - if (isCurrentlyRunning() && GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { - GroovyLog.get().error("GregTech's material event can only be used in pre init!"); - return; - } - GroovyEventManager.INSTANCE.listen(priority, EventBusType.FORGE, PostMaterialEvent.class, - eventListener); - } - - public void lateMaterialEvent(Closure eventListener) { - materialEvent(EventPriority.NORMAL, eventListener); - } - }; + return new PropertyContainer(); } @Override public void onCompatLoaded(GroovyContainer groovyContainer) { - modSupportContainer = groovyContainer; - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "recipemap", - IGameObjectHandler.wrapStringGetter(RecipeMap::getByName)); - - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "material", - IGameObjectHandler.wrapStringGetter(GregTechAPI.materialManager::getMaterial)); - - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "oreprefix", - IGameObjectHandler.wrapStringGetter(OrePrefix::getPrefix)); - - GameObjectHandlerManager.registerGameObjectHandler(GTValues.MODID, "metaitem", - IGameObjectHandler.wrapStringGetter(GroovyScriptModule::getMetaItem), ItemStack.EMPTY); + GroovyScriptModule.modSupportContainer = groovyContainer; + GameObjectHandler.builder("recipemap", RecipeMap.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(RecipeMap::getByName)) + .completerOfNamed(RecipeMap::getRecipeMaps, RecipeMap::getUnlocalizedName) + .register(); + GameObjectHandler.builder("material", Material.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(GregTechAPI.materialManager::getMaterial)) + .completerOfNamed(GregTechAPI.materialManager::getRegisteredMaterials, + mat -> mat.getResourceLocation().toString()) + .register(); + + GameObjectHandler.builder("oreprefix", OrePrefix.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(OrePrefix::getPrefix)) + .completerOfNamed(OrePrefix::values, v -> v.name) + .register(); + + GameObjectHandler.builder("metaitem", ItemStack.class) + .mod(GTValues.MODID) + .parser(IGameObjectParser.wrapStringGetter(GroovyScriptModule::getMetaItem)) + .completer((paramIndex, items) -> { + if (paramIndex != 0) return; + for (var iterator = metaItems.object2ObjectEntrySet().fastIterator(); iterator.hasNext();) { + var entry = iterator.next(); + String mod = entry.getKey(); + for (String key : entry.getValue().keySet()) { + var item = new CompletionItem(mod + ":" + key); + item.setKind(CompletionItemKind.Constant); + items.add(item); + } + } + }) + .register(); + + GameObjectHandler.builder("element", Element.class) + .mod(GTValues.MODID) + .parser((s, args) -> { + Element element = Elements.get(s); + if (element != null) return Result.some(element); + if (s.length() <= 6) { + for (Element element1 : Elements.getAllElements()) { + if (element1.symbol.equals(s)) { + return Result.some(element1); + } + } + } + return Result.error(); + }) + .completerOfNamed(Elements::getAllElements, Element::getName) + .register(); ExpansionHelper.mixinClass(Material.class, MaterialExpansion.class); ExpansionHelper.mixinClass(Material.class, MaterialPropertyExpansion.class); ExpansionHelper.mixinClass(Material.Builder.class, GroovyMaterialBuilderExpansion.class); ExpansionHelper.mixinMethod(RecipeBuilder.class, GroovyExpansions.class, "property"); ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "materialBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "toolBuilder"); + ExpansionHelper.mixinMethod(MaterialEvent.class, GroovyExpansions.class, "fluidBuilder"); + ExpansionHelper.mixinMethod(PostMaterialEvent.class, GroovyExpansions.class, "toolBuilder"); + ExpansionHelper.mixinMethod(PostMaterialEvent.class, GroovyExpansions.class, "fluidBuilder"); + ExpansionHelper.mixinMethod(FluidBuilder.class, GroovyExpansions.class, "acidic"); + } + + protected static boolean checkFrozen(String description) { + if (!GregTechAPI.materialManager.canModifyMaterials()) { + GroovyLog.get().error("Cannot {} now, must be done in preInit loadStage and material event", description); + return true; + } + return false; + } + + protected static void logError(Material m, String cause, String type) { + GroovyLog.get().error( + "Cannot {0} of a Material with no {1}! Try calling \"add{1}\" in your late material event first if this is intentional. Material: {2}", + cause, type, m.getUnlocalizedName()); } } diff --git a/src/main/java/gregtech/integration/groovy/MaterialExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java new file mode 100644 index 00000000000..70b92dd04d9 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/MaterialExpansion.java @@ -0,0 +1,225 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.info.MaterialFlag; +import gregtech.api.unification.material.info.MaterialIconSet; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.ToolProperty; + +import net.minecraft.enchantment.Enchantment; + +import com.cleanroommc.groovyscript.api.GroovyLog; + +import static gregtech.integration.groovy.GroovyScriptModule.checkFrozen; +import static gregtech.integration.groovy.GroovyScriptModule.logError; + +@SuppressWarnings("unused") +public class MaterialExpansion { + + //////////////////////////////////// + // Material Methods // + //////////////////////////////////// + + public static void setFormula(Material m, String formula) { + setFormula(m, formula, false); + } + + public static void setFormula(Material m, String formula, boolean withFormatting) { + if (checkFrozen("set material chemical formula")) return; + m.setFormula(formula, withFormatting); + } + + public static boolean hasFlag(Material m, String flagName) { + return m.hasFlag(MaterialFlag.getByName(flagName)); + } + + public static void setIconSet(Material m, String iconSetName) { + if (checkFrozen("set material icon set")) return; + m.setMaterialIconSet(MaterialIconSet.getByName(iconSetName)); + } + + public static String getIconSet(Material m) { + return m.getMaterialIconSet().getName(); + } + + //////////////////////////////////// + // Fluid Property // + //////////////////////////////////// + + public static boolean isGaseous(Material m) { + FluidProperty prop = m.getProperty(PropertyKey.FLUID); + return prop != null && prop.getStorage().get(FluidStorageKeys.GAS) != null; + } + + /////////////////////////////////// + // Dust Property // + /////////////////////////////////// + + public static int harvestLevel(Material m) { + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + return prop.getHarvestLevel(); + } else logError(m, "get the harvest level", "Dust"); + return 0; + } + + public static int burnTime(Material m) { + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + return prop.getBurnTime(); + } else logError(m, "get the burn time", "Dust"); + return 0; + } + + public static void setHarvestLevel(Material m, int harvestLevel) { + if (checkFrozen("set harvest level")) return; + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + prop.setHarvestLevel(harvestLevel); + } else logError(m, "set the harvest level", "Dust"); + } + + public static void setBurnTime(Material m, int burnTime) { + if (checkFrozen("set burn time")) return; + DustProperty prop = m.getProperty(PropertyKey.DUST); + if (prop != null) { + prop.setBurnTime(burnTime); + } else logError(m, "set the burn time", "Dust"); + } + + /////////////////////////////////// + // Tool Property // + /////////////////////////////////// + public static float toolSpeed(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolSpeed(); + } else logError(m, "get the tool speed", "Tool"); + return 0; + } + + public static float attackDamage(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolAttackDamage(); + } else logError(m, "get the tool attack damage", "Tool"); + return 0; + } + + public static int toolDurability(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolDurability(); + } else logError(m, "get the tool durability", "Tool"); + return 0; + } + + public static int toolHarvestLevel(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolHarvestLevel(); + } else logError(m, "get the tool harvest level", "Tool"); + return 0; + } + + public static int toolEnchantability(Material m) { + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + return prop.getToolEnchantability(); + } else logError(m, "get the tool enchantability", "Tool"); + return 0; + } + + public static void addToolEnchantment(Material m, Enchantment enchantment, int level) { + addScaledToolEnchantment(m, enchantment, level, 0); + } + + public static void addScaledToolEnchantment(Material m, Enchantment enchantment, int level, double levelGrowth) { + if (checkFrozen("add tool enchantment")) return; + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + prop.addEnchantmentForTools(enchantment, level, levelGrowth); + } else logError(m, "change tool enchantments", "Tool"); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + boolean shouldIngoreCraftingTools) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, 0, 0, shouldIngoreCraftingTools); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, boolean shouldIngoreCraftingTools) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, 0, shouldIngoreCraftingTools); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, 0, 0, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, 0, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, int toolHarvestLevel) { + setToolStats(m, toolSpeed, toolAttackDamage, toolDurability, enchantability, toolHarvestLevel, false); + } + + public static void setToolStats(Material m, float toolSpeed, float toolAttackDamage, int toolDurability, + int enchantability, int toolHarvestLevel, + boolean shouldIngoreCraftingTools) { + if (checkFrozen("set tool stats")) return; + ToolProperty prop = m.getProperty(PropertyKey.TOOL); + if (prop != null) { + prop.setToolSpeed(toolSpeed); + prop.setToolAttackDamage(toolAttackDamage); + prop.setToolDurability(toolDurability); + prop.setToolHarvestLevel(toolHarvestLevel == 0 ? 2 : toolHarvestLevel); + prop.setToolEnchantability(enchantability == 0 ? 10 : enchantability); + prop.setShouldIgnoreCraftingTools(shouldIngoreCraftingTools); + } else logError(m, "change tool stats", "Tool"); + } + + // Wire/Item Pipe/Fluid Pipe stuff? + + //////////////////////////////////// + // Blast Property // + //////////////////////////////////// + + public static void setBlastTemp(Material m, int blastTemp) { + if (checkFrozen("set blast temperature")) return; + if (blastTemp <= 0) { + GroovyLog.get().error("Blast Temperature must be greater than zero! Material: " + m.getUnlocalizedName()); + return; + } + BlastProperty prop = m.getProperty(PropertyKey.BLAST); + if (prop != null) prop.setBlastTemperature(blastTemp); + else m.setProperty(PropertyKey.BLAST, new BlastProperty(blastTemp)); + } + + public static int blastTemp(Material m) { + BlastProperty prop = m.getProperty(PropertyKey.BLAST); + if (prop != null) { + return prop.getBlastTemperature(); + } else logError(m, "get blast temperature", "Blast"); + return 0; + } + + //////////////////////////////////// + // Ore Property // + //////////////////////////////////// + + public static int oreMultiplier(Material m) { + OreProperty prop = m.getProperty(PropertyKey.ORE); + if (prop != null) { + return prop.getOreMultiplier(); + } else logError(m, "get ore multiplier", "Ore"); + return 0; + } +} diff --git a/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java new file mode 100644 index 00000000000..83ceb1b27a7 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/MaterialPropertyExpansion.java @@ -0,0 +1,355 @@ +package gregtech.integration.groovy; + +import gregtech.api.fluids.FluidBuilder; +import gregtech.api.fluids.FluidState; +import gregtech.api.fluids.attribute.FluidAttributes; +import gregtech.api.fluids.store.FluidStorageKey; +import gregtech.api.fluids.store.FluidStorageKeys; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.properties.BlastProperty; +import gregtech.api.unification.material.properties.DustProperty; +import gregtech.api.unification.material.properties.FluidPipeProperties; +import gregtech.api.unification.material.properties.FluidProperty; +import gregtech.api.unification.material.properties.GemProperty; +import gregtech.api.unification.material.properties.IngotProperty; +import gregtech.api.unification.material.properties.ItemPipeProperties; +import gregtech.api.unification.material.properties.OreProperty; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.unification.material.properties.ToolProperty; +import gregtech.api.unification.material.properties.WireProperties; +import gregtech.api.unification.material.properties.WoodProperty; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; + +import static gregtech.integration.groovy.GroovyScriptModule.checkFrozen; + +@SuppressWarnings("unused") +public class MaterialPropertyExpansion { + + ///////////////////////////////////// + // Property Checkers // + ///////////////////////////////////// + + public static boolean hasBlastTemp(Material m) { + return m.hasProperty(PropertyKey.BLAST); + } + + public static boolean hasDust(Material m) { + return m.hasProperty(PropertyKey.DUST); + } + + public static boolean hasFluidPipes(Material m) { + return m.hasProperty(PropertyKey.FLUID_PIPE); + } + + public static boolean hasFluid(Material m) { + return m.hasProperty(PropertyKey.FLUID); + } + + public static boolean hasGem(Material m) { + return m.hasProperty(PropertyKey.GEM); + } + + public static boolean hasIngot(Material m) { + return m.hasProperty(PropertyKey.INGOT); + } + + public static boolean hasItemPipes(Material m) { + return m.hasProperty(PropertyKey.ITEM_PIPE); + } + + public static boolean hasOre(Material m) { + return m.hasProperty(PropertyKey.ORE); + } + + public static boolean hasTools(Material m) { + return m.hasProperty(PropertyKey.TOOL); + } + + public static boolean hasWires(Material m) { + return m.hasProperty(PropertyKey.WIRE); + } + + //////////////////////////////////// + // Property Setters // + //////////////////////////////////// + + public static void addBlastTemp(Material m, int blastTemp) { + if (checkFrozen("add blast temperature")) return; + if (m.hasProperty(PropertyKey.BLAST)) m.getProperty(PropertyKey.BLAST).setBlastTemperature(blastTemp); + else m.setProperty(PropertyKey.BLAST, new BlastProperty(blastTemp)); + } + + public static void addBlastProperty(Material m, int blastTemp) { + addBlastProperty(m, blastTemp, null, 0, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier) { + addBlastProperty(m, blastTemp, gasTier, 0, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride) { + addBlastProperty(m, blastTemp, gasTier, durationOverride, 0, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride, int eutOverride) { + addBlastProperty(m, blastTemp, gasTier, durationOverride, eutOverride, 0, 0); + } + + public static void addBlastProperty(Material m, int blastTemp, String gasTier, + int durationOverride, int eutOverride, + int vacuumDurationOverride, int vacuumEUtOverride) { + if (checkFrozen("add blast property")) return; + if (m.hasProperty(PropertyKey.BLAST)) { + BlastProperty property = m.getProperty(PropertyKey.BLAST); + property.setBlastTemperature(blastTemp); + if (gasTier != null) property.setGasTier(BlastProperty.validateGasTier(gasTier)); + if (durationOverride != 0) property.setDurationOverride(durationOverride); + if (eutOverride != 0) property.setEutOverride(eutOverride); + if (vacuumDurationOverride != 0) property.setVacuumDurationOverride(vacuumDurationOverride); + if (vacuumEUtOverride != 0) property.setVacuumEutOverride(vacuumEUtOverride); + } else { + BlastProperty.Builder builder = new BlastProperty.Builder(); + builder.temp(blastTemp, + gasTier == null ? BlastProperty.GasTier.LOW : BlastProperty.validateGasTier(gasTier)); + builder.blastStats(durationOverride == 0 ? -1 : durationOverride, eutOverride == 0 ? -1 : eutOverride); + builder.vacuumStats(vacuumEUtOverride == 0 ? -1 : vacuumEUtOverride, + vacuumDurationOverride == 0 ? -1 : vacuumDurationOverride); + m.setProperty(PropertyKey.BLAST, builder.build()); + } + } + + public static void addDust(Material m) { + addDust(m, 0, 0); + } + + public static void addDust(Material m, int harvestLevel) { + addDust(m, harvestLevel, 0); + } + + public static void addDust(Material m, int harvestLevel, int burnTime) { + if (checkFrozen("add a dust to a material")) return; + if (harvestLevel == 0) harvestLevel = 2; + if (m.hasProperty(PropertyKey.DUST)) { + m.getProperty(PropertyKey.DUST).setHarvestLevel(harvestLevel); + m.getProperty(PropertyKey.DUST).setBurnTime(burnTime); + } else m.setProperty(PropertyKey.DUST, new DustProperty(harvestLevel, burnTime)); + } + + public static void addWood(Material m) { + if (checkFrozen("add a wood to a material")) return; + if (!m.hasProperty(PropertyKey.WOOD)) { + m.setProperty(PropertyKey.WOOD, new WoodProperty()); + } + } + + public static void addFluidPipes(Material m, int maxFluidTemperature, int throughput, boolean gasProof) { + addFluidPipes(m, maxFluidTemperature, throughput, gasProof, false, false, false); + } + + public static void addFluidPipes(Material m, int maxFluidTemperature, int throughput, boolean gasProof, + boolean acidProof, boolean cryoProof, boolean plasmaProof) { + if (checkFrozen("add fluid pipes to a material")) return; + if (m.hasProperty(PropertyKey.FLUID_PIPE)) { + m.getProperty(PropertyKey.FLUID_PIPE).setMaxFluidTemperature(maxFluidTemperature); + m.getProperty(PropertyKey.FLUID_PIPE).setThroughput(throughput); + m.getProperty(PropertyKey.FLUID_PIPE).setGasProof(gasProof); + m.getProperty(PropertyKey.FLUID_PIPE).setCanContain(FluidAttributes.ACID, acidProof); + m.getProperty(PropertyKey.FLUID_PIPE).setCryoProof(cryoProof); + m.getProperty(PropertyKey.FLUID_PIPE).setPlasmaProof(plasmaProof); + } else { + m.setProperty(PropertyKey.FLUID_PIPE, new FluidPipeProperties(maxFluidTemperature, throughput, gasProof, + acidProof, cryoProof, plasmaProof)); + } + } + + @GroovyBlacklist + private static void addFluidInternal(Material m, FluidStorageKey key, FluidBuilder builder) { + if (checkFrozen("add a Fluid to a material")) return; + FluidProperty property = m.getProperty(PropertyKey.FLUID); + if (property == null) { + property = new FluidProperty(); + m.setProperty(PropertyKey.FLUID, property); + } + property.getStorage().enqueueRegistration(key, builder); + } + + public static void addLiquid(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.LIQUID, builder.state(FluidState.LIQUID)); + } + + public static void addLiquid(Material m) { + addLiquid(m, new FluidBuilder()); + } + + public static void addFluid(Material m) { + addLiquid(m); + } + + @Deprecated + public static void addFluid(Material m, String fluidTypeName) { + addFluid(m, fluidTypeName, false); + } + + @Deprecated + public static void addFluid(Material m, String fluidTypeName, boolean hasBlock) { + GroovyLog.get().error("The usage of `material.addFluid(String, boolean)` is strongly discouraged. " + + "Please use `addLiquid()`, `addGas()` or `addPlasma()` with or without `FluidBuilder`."); + if (checkFrozen("add a Fluid to a material")) return; + FluidState type = GroovyScriptModule.parseAndValidateEnumValue(FluidState.class, fluidTypeName, "fluid type", + true); + FluidStorageKey storageKey = switch (type) { + case LIQUID -> FluidStorageKeys.LIQUID; + case GAS -> FluidStorageKeys.GAS; + case PLASMA -> FluidStorageKeys.PLASMA; + }; + FluidBuilder builder = new FluidBuilder(); + builder.state(type); + if (hasBlock) builder.block(); + addFluidInternal(m, storageKey, builder); + } + + public static void addGas(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.GAS, builder.state(FluidState.GAS)); + } + + public static void addGas(Material m) { + addGas(m, new FluidBuilder()); + } + + public static void addPlasma(Material m, FluidBuilder builder) { + addFluidInternal(m, FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); + } + + public static void addPlasma(Material m) { + addPlasma(m, new FluidBuilder()); + } + + public static void addGem(Material m) { + if (checkFrozen("add a Gem to a material")) return; + if (!m.hasProperty(PropertyKey.GEM)) m.setProperty(PropertyKey.GEM, new GemProperty()); + } + + public static void addIngot(Material m) { + if (checkFrozen("add an Ingot to a material")) return; + if (!m.hasProperty(PropertyKey.INGOT)) m.setProperty(PropertyKey.INGOT, new IngotProperty()); + } + + public static void addOre(Material m) { + addOre(m, false); + } + + public static void addOre(Material m, boolean emissive) { + addOre(m, 0, 0, emissive); + } + + public static void addOre(Material m, int oreMultiplier, int byproductMultiplier) { + addOre(m, oreMultiplier, byproductMultiplier, false); + } + + public static void addOre(Material m, int oreMultiplier, int byproductMultiplier, boolean emissive) { + if (checkFrozen("add an Ore to a material")) return; + oreMultiplier = oreMultiplier == 0 ? 1 : oreMultiplier; + byproductMultiplier = byproductMultiplier == 0 ? 1 : byproductMultiplier; + if (m.hasProperty(PropertyKey.ORE)) { + m.getProperty(PropertyKey.ORE).setOreMultiplier(oreMultiplier); + m.getProperty(PropertyKey.ORE).setByProductMultiplier(byproductMultiplier); + m.getProperty(PropertyKey.ORE).setEmissive(emissive); + } else m.setProperty(PropertyKey.ORE, new OreProperty(oreMultiplier, byproductMultiplier, emissive)); + } + + public static void addItemPipes(Material m, int priority, float transferRate) { + if (checkFrozen("add Item Pipes to a material")) return; + if (m.hasProperty(PropertyKey.ITEM_PIPE)) { + m.getProperty(PropertyKey.ITEM_PIPE).setPriority(priority); + m.getProperty(PropertyKey.ITEM_PIPE).setTransferRate(transferRate); + } else m.setProperty(PropertyKey.ITEM_PIPE, new ItemPipeProperties(priority, transferRate)); + } + + public static void addTools(Material m, ToolProperty.Builder builder) { + addTools(m, builder.build()); + } + + public static void addTools(Material m, ToolProperty prop) { + if (checkFrozen("add Tools to a material")) return; + ToolProperty property = m.getProperty(PropertyKey.TOOL); + if (property != null) { + property.setToolSpeed(prop.getToolSpeed()); + property.setToolAttackDamage(prop.getToolAttackDamage()); + property.setToolDurability(prop.getToolDurability()); + property.setToolHarvestLevel(prop.getToolHarvestLevel()); + property.setToolAttackSpeed(prop.getToolAttackSpeed()); + property.setToolEnchantability(prop.getToolEnchantability()); + property.setMagnetic(prop.isMagnetic()); + property.setUnbreakable(prop.getUnbreakable()); + property.setShouldIgnoreCraftingTools(prop.getShouldIgnoreCraftingTools()); + property.setDurabilityMultiplier(prop.getDurabilityMultiplier()); + } else { + m.setProperty(PropertyKey.TOOL, prop); + } + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, 0, 10, 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, toolHarvestLevel, 10, 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel, int toolEnchantability) { + addTools(m, toolSpeed, toolAttackDamage, toolAttackSpeed, toolDurability, toolHarvestLevel, toolEnchantability, + 1); + } + + public static void addTools(Material m, float toolSpeed, float toolAttackDamage, float toolAttackSpeed, + int toolDurability, int toolHarvestLevel, int toolEnchantability, + int durabilityMultiplier) { + if (toolEnchantability == 0) toolEnchantability = 10; + if (durabilityMultiplier <= 0) durabilityMultiplier = 1; + addTools(m, ToolProperty.Builder.of(toolSpeed, toolAttackDamage, toolDurability, toolHarvestLevel) + .attackSpeed(toolAttackSpeed) + .enchantability(toolEnchantability) + .durabilityMultiplier(durabilityMultiplier)); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock) { + addWires(m, voltage, baseAmperage, lossPerBlock, false, 0); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, 0); + } + + public static void addWires(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon, + int criticalTemp) { + if (checkFrozen("add Wires to a material")) return; + if (m.hasProperty(PropertyKey.WIRE)) { + m.getProperty(PropertyKey.WIRE).setVoltage(voltage); + m.getProperty(PropertyKey.WIRE).setAmperage(baseAmperage); + m.getProperty(PropertyKey.WIRE).setLossPerBlock(lossPerBlock); + m.getProperty(PropertyKey.WIRE).setSuperconductor(isSuperCon); + m.getProperty(PropertyKey.WIRE).setSuperconductorCriticalTemperature(criticalTemp); + } else m.setProperty(PropertyKey.WIRE, + new WireProperties(voltage, baseAmperage, lossPerBlock, isSuperCon, criticalTemp)); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock) { + addWires(m, voltage, baseAmperage, lossPerBlock, false, 0); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, 0); + } + + public static void addCables(Material m, int voltage, int baseAmperage, int lossPerBlock, boolean isSuperCon, + int criticalTemp) { + addWires(m, voltage, baseAmperage, lossPerBlock, isSuperCon, criticalTemp); + } +} diff --git a/src/main/java/gregtech/integration/groovy/PropertyContainer.java b/src/main/java/gregtech/integration/groovy/PropertyContainer.java new file mode 100644 index 00000000000..35da8ce4905 --- /dev/null +++ b/src/main/java/gregtech/integration/groovy/PropertyContainer.java @@ -0,0 +1,47 @@ +package gregtech.integration.groovy; + +import gregtech.api.unification.material.event.MaterialEvent; +import gregtech.api.unification.material.event.PostMaterialEvent; + +import net.minecraftforge.fml.common.eventhandler.EventPriority; + +import com.cleanroommc.groovyscript.GroovyScript; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.event.EventBusType; +import com.cleanroommc.groovyscript.event.GroovyEventManager; +import com.cleanroommc.groovyscript.sandbox.ClosureHelper; +import com.cleanroommc.groovyscript.sandbox.LoadStage; +import groovy.lang.Closure; +import groovy.lang.DelegatesTo; + +public class PropertyContainer extends ModPropertyContainer { + + public void materialEvent(EventPriority priority, @DelegatesTo(MaterialEvent.class) Closure eventListener) { + if (GroovyScriptModule.isCurrentlyRunning() && + GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + ClosureHelper.withEnvironment(eventListener, new MaterialEvent(), true); + GroovyEventManager.INSTANCE.listen(priority, EventBusType.MAIN, MaterialEvent.class, eventListener); + } + + public void materialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } + + public void lateMaterialEvent(EventPriority priority, Closure eventListener) { + if (GroovyScriptModule.isCurrentlyRunning() && + GroovyScript.getSandbox().getCurrentLoader() != LoadStage.PRE_INIT) { + GroovyLog.get().error("GregTech's material event can only be used in pre init!"); + return; + } + GroovyEventManager.INSTANCE.listen(priority, EventBusType.MAIN, PostMaterialEvent.class, + eventListener); + } + + public void lateMaterialEvent(Closure eventListener) { + materialEvent(EventPriority.NORMAL, eventListener); + } +} diff --git a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java index a2dbf7a3d55..6bd80f4db05 100644 --- a/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java +++ b/src/main/java/gregtech/integration/groovy/VirtualizedRecipeMap.java @@ -23,7 +23,7 @@ public class VirtualizedRecipeMap extends VirtualizedRegistry { public VirtualizedRecipeMap(RecipeMap recipeMap) { super(Alias.generateOf(recipeMap.unlocalizedName, CaseFormat.LOWER_UNDERSCORE)); this.recipeMap = recipeMap; - GroovyScriptModule.getInstance().getVirtualizedRegistrar().addRegistry(this); + GroovyScriptModule.getInstance().getRegistrar().addRegistry(this); } @Override