From 9005864c49263d0e85fa8311638faf6796de539a Mon Sep 17 00:00:00 2001 From: Wizzerinus | Alex K Date: Sat, 6 Jul 2024 08:36:05 +0300 Subject: [PATCH] Add EssentialCraft 4 compatibility (#176) * added essentialcraft compatibility * ec4: addressed the PR questions * ec4: addressed more PR questions * ec4: extensively mixin Magmatic to fix crashes * ec4: pr fixes * ec4: pr fixes --- dependencies.gradle | 4 +- examples/postInit/essentialcraft.groovy | 91 ++++++++++++ gradle.properties | 1 + .../groovyscript/compat/mods/ModSupport.java | 2 + .../essentialcraft/DemonTradeManager.java | 91 ++++++++++++ .../mods/essentialcraft/EssentialCraft.java | 21 +++ .../mods/essentialcraft/MagicianTable.java | 89 ++++++++++++ .../mods/essentialcraft/MagmaticSmeltery.java | 131 ++++++++++++++++++ .../essentialcraft/MithrilineFurnace.java | 104 ++++++++++++++ .../mods/essentialcraft/RadiatingChamber.java | 121 ++++++++++++++++ .../compat/mods/essentialcraft/WindRune.java | 101 ++++++++++++++ .../groovyscript/core/LateMixin.java | 1 + .../OreSmeltingRecipeMixin.java | 29 ++++ .../essentialcraft/TileFurnaceMagicMixin.java | 33 +++++ .../TileMagmaticSmelterMixin.java | 35 +++++ .../assets/groovyscript/lang/en_us.lang | 36 +++++ .../mixin.groovyscript.essentialcraft.json | 12 ++ 17 files changed, 901 insertions(+), 1 deletion(-) create mode 100644 examples/postInit/essentialcraft.groovy create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/DemonTradeManager.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/EssentialCraft.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MagicianTable.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MagmaticSmeltery.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MithrilineFurnace.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/RadiatingChamber.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/WindRune.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/OreSmeltingRecipeMixin.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/TileFurnaceMagicMixin.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/TileMagmaticSmelterMixin.java create mode 100644 src/main/resources/mixin.groovyscript.essentialcraft.json diff --git a/dependencies.gradle b/dependencies.gradle index ae1e1495b..f81f40aeb 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -38,7 +38,7 @@ final def mod_dependencies = [ 'guidebook-253874:2989594' : [project.debug_arcane_archives], 'mystical_lib-277064:3483816' : [project.debug_arcane_archives, project.debug_roots], 'astralsorcery-sorcery-241721:3044416' : [project.debug_astral], - 'baubles-227083:2518667' : [project.debug_astral, project.debug_botania, project.debug_thaum], + 'baubles-227083:2518667' : [project.debug_astral, project.debug_botania, project.debug_thaum, project.debug_essentialcraft_4], 'avaritia_1_10-261348:3143349' : [project.debug_avaritia], 'bwm-core-294335:2624990' : [project.debug_better_with_mods], 'bwm-suite-246760:3289033' : [project.debug_better_with_mods], @@ -53,6 +53,8 @@ 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], + '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], 'evilcraft-74610:2811267' : [project.debug_evilcraft], 'cucumber-272335:2645867' : [project.debug_extended_crafting], diff --git a/examples/postInit/essentialcraft.groovy b/examples/postInit/essentialcraft.groovy new file mode 100644 index 000000000..2195fbd3c --- /dev/null +++ b/examples/postInit/essentialcraft.groovy @@ -0,0 +1,91 @@ + +// Auto generated groovyscript example file +// MODS_LOADED: essentialcraft + +println 'mod \'essentialcraft\' detected, running script' + +// Demon Trade: +// 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. + +mods.essentialcraft.demon_trade.remove(entity('minecraft:enderman')) +mods.essentialcraft.demon_trade.remove(item('minecraft:nether_star')) +// mods.essentialcraft.demon_trade.removeAll() + +mods.essentialcraft.demon_trade.add(entity('minecraft:chicken')) +mods.essentialcraft.demon_trade.add(item('minecraft:diamond')) + +// Magician Table: +// A 5-slot processing machine using MRU. Can be upgraded with various plates to increase its speed. + +mods.essentialcraft.magician_table.removeByOutput(item('essentialcraft:genitem')) +// mods.essentialcraft.magician_table.removeAll() + +mods.essentialcraft.magician_table.recipeBuilder() + .input(item('minecraft:diamond'), ore('ingotGold'), ore('ingotGold'), ore('stickWood'), ore('stickWood')) + .output(item('minecraft:iron_ingot')) + .mru(500) + .register() + + +// Magmatic Smeltery: +// A machine used to quadruple ores using MRU and lava. Also adds the same recipes for Magmatic Furnace, which is used to +// double ores using MRU. + +mods.essentialcraft.magmatic_smeltery.removeByInput(ore('oreIron')) +mods.essentialcraft.magmatic_smeltery.removeByInput('oreDiamond') +// mods.essentialcraft.magmatic_smeltery.removeAll() + +mods.essentialcraft.magmatic_smeltery.recipeBuilder() + .input('blockIron') + .output('ingotGold') + .factor(3) + .color(0x0000ff) + .register() + + +// Mithriline Furnace: +// Converts various items into other items using ESPE. + +mods.essentialcraft.mithriline_furnace.removeByInput(ore('dustGlowstone')) +mods.essentialcraft.mithriline_furnace.removeByOutput(item('minecraft:emerald')) +// mods.essentialcraft.mithriline_furnace.removeAll() + +mods.essentialcraft.mithriline_furnace.recipeBuilder() + .input(item('minecraft:coal_block') * 3) + .output(item('minecraft:diamond_block')) + .espe(500) + .register() + + +// Radiating Chamber: +// Combines two items together using MRU to obtain a third item. Can optionally require a specific range of MRU balance to +// execute the recipe. + +mods.essentialcraft.radiating_chamber.removeByOutput(item('essentialcraft:genitem', 42)) +// mods.essentialcraft.radiating_chamber.removeAll() + +mods.essentialcraft.radiating_chamber.recipeBuilder() + .input(item('minecraft:nether_star'), item('minecraft:stone')) + .output(item('minecraft:beacon')) + .time(100) + .mruPerTick(10.0f) + .upperBalance(1.5f) + .lowerBalance(0.25f) + .register() + + +// Wind Rune: +// Transforms various items using ESPE. + +mods.essentialcraft.wind_rune.removeByInput(item('minecraft:diamond')) +mods.essentialcraft.wind_rune.removeByOutput(item('essentialcraft:air_potion')) +// mods.essentialcraft.wind_rune.removeAll() + +mods.essentialcraft.wind_rune.recipeBuilder() + .input(item('minecraft:gold_block')) + .output(item('minecraft:diamond_block')) + .espe(500) + .register() + + diff --git a/gradle.properties b/gradle.properties index 9b833e877..4a2984bf6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -28,6 +28,7 @@ debug_chisel = false debug_compact_machines = false debug_draconic_evolution = false debug_enderio = false +debug_essentialcraft_4 = false debug_evilcraft = false debug_extended_crafting = false debug_extra_utilities_2 = false diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java index e589a4f99..1c010bdf9 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -19,6 +19,7 @@ import com.cleanroommc.groovyscript.compat.mods.compactmachines.CompactMachines; import com.cleanroommc.groovyscript.compat.mods.draconicevolution.DraconicEvolution; import com.cleanroommc.groovyscript.compat.mods.enderio.EnderIO; +import com.cleanroommc.groovyscript.compat.mods.essentialcraft.EssentialCraft; import com.cleanroommc.groovyscript.compat.mods.evilcraft.EvilCraft; import com.cleanroommc.groovyscript.compat.mods.extendedcrafting.ExtendedCrafting; import com.cleanroommc.groovyscript.compat.mods.extrautils2.ExtraUtils2; @@ -80,6 +81,7 @@ public class ModSupport { public static final GroovyContainer COMPACT_MACHINES = new InternalModContainer<>("compactmachines3", "Compact Machines 3", CompactMachines::new, "compactmachines"); 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 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); public static final GroovyContainer EXTRA_UTILITIES_2 = new InternalModContainer<>("extrautils2", "Extra Utilities 2", ExtraUtils2::new, "extrautilities2"); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/DemonTradeManager.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/DemonTradeManager.java new file mode 100644 index 000000000..5b74b94da --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/DemonTradeManager.java @@ -0,0 +1,91 @@ +package com.cleanroommc.groovyscript.compat.mods.essentialcraft; + +import com.cleanroommc.groovyscript.api.IIngredient; +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.helper.Alias; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import net.minecraft.item.ItemStack; +import essentialcraft.api.DemonTrade; +import net.minecraftforge.fml.common.registry.EntityEntry; + +@RegistryDescription( + category = RegistryDescription.Category.ENTRIES, + admonition = @Admonition(value = "groovyscript.wiki.essentialcraft.demon_trade.note0", type = Admonition.Type.DANGER)) +public class DemonTradeManager extends VirtualizedRegistry { + public DemonTradeManager() { + super(Alias.generateOf("DemonTrade")); + } + + @Override + public void onReload() { + removeScripted().forEach(DemonTrade::removeTrade); + restoreFromBackup().forEach(r -> { + DemonTrade.TRADES.add(r); + if (r.desiredItem.isEmpty()) { + DemonTrade.ALL_MOBS.add(r.entityType); + } + }); + } + + @MethodDescription(example = @Example("item('minecraft:diamond')"), type = MethodDescription.Type.ADDITION) + public void add(IIngredient x) { + for (ItemStack it : x.getMatchingStacks()) { + DemonTrade t = new DemonTrade(it); // this automatically registers the trade + addScripted(t); + } + } + + @MethodDescription(example = @Example("entity('minecraft:chicken')"), type = MethodDescription.Type.ADDITION) + public void add(EntityEntry x) { + DemonTrade t = new DemonTrade(x); // this automatically registers the trade + addScripted(t); + } + + @MethodDescription(example = @Example("item('minecraft:nether_star')")) + public boolean remove(IIngredient x) { + return DemonTrade.TRADES.removeIf(r -> { + if (!r.desiredItem.isEmpty() && x.test(r.desiredItem)) { + addBackup(r); + return true; + } + return false; + }); + } + + @MethodDescription(description = "groovyscript.wiki.essentialcraft.demon_trade.removeEntity", example = @Example("entity('minecraft:enderman')")) + public boolean remove(EntityEntry x) { + return DemonTrade.TRADES.removeIf(r -> { + if (r.desiredItem.isEmpty() && x.equals(r.entityType)) { + addBackup(r); + DemonTrade.ALL_MOBS.remove(r.entityType); + return true; + } + return false; + }); + } + + private boolean remove(DemonTrade t) { + if (DemonTrade.TRADES.stream().anyMatch(r -> r.equals(t))) { + addBackup(t); + DemonTrade.removeTrade(t); + return true; + } + return false; + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + DemonTrade.TRADES.forEach(this::addBackup); + DemonTrade.TRADES.clear(); + DemonTrade.ALL_MOBS.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(DemonTrade.TRADES).setRemover(this::remove); + } +} \ No newline at end of file diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/EssentialCraft.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/EssentialCraft.java new file mode 100644 index 000000000..049bdcf9a --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/EssentialCraft.java @@ -0,0 +1,21 @@ +package com.cleanroommc.groovyscript.compat.mods.essentialcraft; + +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; + +public class EssentialCraft extends ModPropertyContainer { + public final DemonTradeManager demonTrade = new DemonTradeManager(); + public final MagicianTable magicianTable = new MagicianTable(); + public final MagmaticSmeltery magmaticSmeltery = new MagmaticSmeltery(); + public final MithrilineFurnace mithrilineFurnace = new MithrilineFurnace(); + public final RadiatingChamber radiatingChamber = new RadiatingChamber(); + public final WindRune windRune = new WindRune(); + + public EssentialCraft() { + addRegistry(demonTrade); + addRegistry(magicianTable); + addRegistry(magmaticSmeltery); + addRegistry(mithrilineFurnace); + addRegistry(radiatingChamber); + addRegistry(windRune); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MagicianTable.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MagicianTable.java new file mode 100644 index 000000000..755318a1b --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MagicianTable.java @@ -0,0 +1,89 @@ +package com.cleanroommc.groovyscript.compat.mods.essentialcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import essentialcraft.api.MagicianTableRecipe; +import essentialcraft.api.MagicianTableRecipes; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription(admonition = @Admonition(value = "groovyscript.wiki.essentialcraft.magician_table.note0", type = Admonition.Type.WARNING)) +public class MagicianTable extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond'), ore('ingotGold'), ore('ingotGold'), ore('stickWood'), ore('stickWood')).output(item('minecraft:iron_ingot')).mru(500)")) + public MagicianTable.RecipeBuilder recipeBuilder() { + return new MagicianTable.RecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(MagicianTableRecipes::removeRecipe); + restoreFromBackup().forEach(MagicianTableRecipes::addRecipe); + } + + @MethodDescription(example = @Example("item('essentialcraft:genitem')")) + public boolean removeByOutput(IIngredient x) { + return MagicianTableRecipes.RECIPES.removeIf(r -> { + if (x.test(r.getRecipeOutput())) { + addBackup(r); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + MagicianTableRecipes.RECIPES.forEach(this::addBackup); + MagicianTableRecipes.RECIPES.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(MagicianTableRecipes.RECIPES).setRemover(r -> { + addBackup(r); + return MagicianTableRecipes.RECIPES.remove(r); + }); + } + + @Property(property = "input", valid = {@Comp(value = "1", type = Comp.Type.GTE), @Comp(value = "5", type = Comp.Type.LTE)}) + @Property(property = "output", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + @Property(valid = @Comp(type = Comp.Type.GTE, value = "1")) + private int mru; + + @RecipeBuilderMethodDescription + public RecipeBuilder mru(int cost) { + mru = cost; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Magician Table Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 5, 1, 1); + validateFluids(msg); + msg.add(mru < 1, "mru cost must be 1 or greater, got {}", mru); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable MagicianTableRecipe register() { + if (!validate()) return null; + Ingredient[] inputIngredient = input.stream().map(IIngredient::toMcIngredient).toArray(Ingredient[]::new); + MagicianTableRecipe recipe = new MagicianTableRecipe(inputIngredient, output.get(0), mru); + ModSupport.ESSENTIALCRAFT.get().magicianTable.addScripted(recipe); + MagicianTableRecipes.addRecipe(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MagmaticSmeltery.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MagmaticSmeltery.java new file mode 100644 index 000000000..8908fa0a6 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MagmaticSmeltery.java @@ -0,0 +1,131 @@ +package com.cleanroommc.groovyscript.compat.mods.essentialcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; +import com.cleanroommc.groovyscript.helper.recipe.IRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import essentialcraft.api.OreSmeltingRecipe; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription(reloadability = RegistryDescription.Reloadability.DISABLED, admonition={ + @Admonition(value = "groovyscript.wiki.essentialcraft.magmatic_smeltery.note0", type = Admonition.Type.WARNING), +}) +public class MagmaticSmeltery extends VirtualizedRegistry { + @RecipeBuilderDescription(example = @Example(".input('blockIron').output('ingotGold').factor(3).color(0x0000ff)")) + public MagmaticSmeltery.RecipeBuilder recipeBuilder() { + return new MagmaticSmeltery.RecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(OreSmeltingRecipe::removeRecipe); + restoreFromBackup().forEach(OreSmeltingRecipe::register); + } + + @MethodDescription(example = @Example("ore('oreIron')")) + public boolean removeByInput(OreDictIngredient x) { + return removeByInput(x.getOreDict()); + } + + @MethodDescription(example = @Example("'oreDiamond'")) + public boolean removeByInput(String x) { + if (OreSmeltingRecipe.RECIPE_MAP.containsKey(x)) { + OreSmeltingRecipe recipe = OreSmeltingRecipe.RECIPE_MAP.get(x); + addBackup(recipe); + OreSmeltingRecipe.removeRecipe(recipe); + return true; + } + return false; + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + OreSmeltingRecipe.RECIPES.forEach(this::addBackup); + OreSmeltingRecipe.RECIPES.clear(); + OreSmeltingRecipe.RECIPE_MAP.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(OreSmeltingRecipe.RECIPES).setRemover(r -> removeByInput(r.oreName)); + } + + public static class RecipeBuilder implements IRecipeBuilder { + @Property(valid = @Comp("1")) + private String input; + + @Property(valid = @Comp("1")) + private String output; + + @Property(valid = {@Comp(type = Comp.Type.GTE, value = "0"), @Comp(type = Comp.Type.LTE, value = "0xffffff")}) + private int color; + + @Property(valid = @Comp(type = Comp.Type.GTE, value = "1"), defaultValue = "1") + private int factor = 1; + + @RecipeBuilderMethodDescription + public MagmaticSmeltery.RecipeBuilder input(String input) { + this.input = input; + return this; + } + + @RecipeBuilderMethodDescription + public MagmaticSmeltery.RecipeBuilder input(OreDictIngredient input) { + this.input = input.getOreDict(); + return this; + } + + @RecipeBuilderMethodDescription + public MagmaticSmeltery.RecipeBuilder output(String output) { + this.output = output; + return this; + } + + @RecipeBuilderMethodDescription + public MagmaticSmeltery.RecipeBuilder output(OreDictIngredient output) { + this.output = output.getOreDict(); + return this; + } + + @RecipeBuilderMethodDescription + public MagmaticSmeltery.RecipeBuilder color(int color) { + this.color = color; + return this; + } + + @RecipeBuilderMethodDescription + public MagmaticSmeltery.RecipeBuilder factor(int factor) { + this.factor = factor; + return this; + } + + public String getErrorMsg() { + return "Error adding Magmatic Smeltery Recipe"; + } + + public void validate(GroovyLog.Msg msg) { + msg.add(OreSmeltingRecipe.RECIPE_MAP.containsKey(input), "This OreDict can already be processed in Magmatic Smeltery: {}", input); + msg.add(color < 0 || color >= (1 << 24), "color must be between 0 and 0xffffff, got {}", Integer.toHexString(color)); + } + + @Override + public boolean validate() { + GroovyLog.Msg msg = GroovyLog.msg(getErrorMsg()).error(); + validate(msg); + return !msg.postIfNotEmpty(); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable OreSmeltingRecipe register() { + if (!validate()) return null; + OreSmeltingRecipe recipe = new OreSmeltingRecipe(input, output, color, factor); + recipe.register(); + ModSupport.ESSENTIALCRAFT.get().magmaticSmeltery.addScripted(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MithrilineFurnace.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MithrilineFurnace.java new file mode 100644 index 000000000..3b183ad8a --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/MithrilineFurnace.java @@ -0,0 +1,104 @@ +package com.cleanroommc.groovyscript.compat.mods.essentialcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import essentialcraft.api.MithrilineFurnaceRecipe; +import essentialcraft.api.MithrilineFurnaceRecipes; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +@RegistryDescription +public class MithrilineFurnace extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:coal_block') * 3).output(item('minecraft:diamond_block')).espe(500)")) + public MithrilineFurnace.RecipeBuilder recipeBuilder() { + return new MithrilineFurnace.RecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(MithrilineFurnaceRecipes::removeRecipe); + restoreFromBackup().forEach(MithrilineFurnaceRecipes::addRecipe); + } + + @MethodDescription(example = @Example("ore('dustGlowstone')")) + public boolean removeByInput(IIngredient x) { + return MithrilineFurnaceRecipes.RECIPES.removeIf(r -> { + if (Arrays.stream(x.getMatchingStacks()).anyMatch(r.input)) { + addBackup(r); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example("item('minecraft:emerald')")) + public boolean removeByOutput(IIngredient x) { + return MithrilineFurnaceRecipes.RECIPES.removeIf(r -> { + if (x.test(r.result)) { + addBackup(r); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + MithrilineFurnaceRecipes.RECIPES.forEach(this::addBackup); + MithrilineFurnaceRecipes.RECIPES.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(MithrilineFurnaceRecipes.RECIPES).setRemover(r -> { + addBackup(r); + return MithrilineFurnaceRecipes.RECIPES.remove(r); + }); + } + + @Property(property = "input", valid = @Comp("1")) + @Property(property = "output", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + @Property(valid = @Comp(type = Comp.Type.GTE, value = "1")) + private int espe; + + @RecipeBuilderMethodDescription + public RecipeBuilder espe(int cost) { + espe = cost; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Mithriline Furnace Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + msg.add(espe < 1, "espe cost must be 1 or greater, got {}", espe); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable MithrilineFurnaceRecipe register() { + if (!validate()) return null; + int stackSize = input.get(0).getAmount(); + Ingredient inputItem = input.get(0).withAmount(1).toMcIngredient(); + MithrilineFurnaceRecipe recipe = new MithrilineFurnaceRecipe(inputItem, output.get(0), (float) espe, stackSize); + ModSupport.ESSENTIALCRAFT.get().mithrilineFurnace.addScripted(recipe); + MithrilineFurnaceRecipes.addRecipe(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/RadiatingChamber.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/RadiatingChamber.java new file mode 100644 index 000000000..b8d81289f --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/RadiatingChamber.java @@ -0,0 +1,121 @@ +package com.cleanroommc.groovyscript.compat.mods.essentialcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import essentialcraft.api.RadiatingChamberRecipe; +import essentialcraft.api.RadiatingChamberRecipes; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription +public class RadiatingChamber extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:nether_star'), item('minecraft:stone')).output(item('minecraft:beacon')).time(100).mruPerTick(10.0f).upperBalance(1.5f).lowerBalance(0.25f)")) + public RadiatingChamber.RecipeBuilder recipeBuilder() { + return new RadiatingChamber.RecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(RadiatingChamberRecipes::removeRecipe); + restoreFromBackup().forEach(RadiatingChamberRecipes::addRecipe); + } + + @MethodDescription(example = @Example("item('essentialcraft:genitem', 42)")) + public boolean removeByOutput(IIngredient x) { + return RadiatingChamberRecipes.RECIPES.removeIf(r -> { + if (x.test(r.getRecipeOutput())) { + addBackup(r); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + RadiatingChamberRecipes.RECIPES.forEach(this::addBackup); + RadiatingChamberRecipes.RECIPES.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(RadiatingChamberRecipes.RECIPES).setRemover(r -> { + addBackup(r); + return RadiatingChamberRecipes.RECIPES.remove(r); + }); + } + + @Property(property = "input", valid = {@Comp(value = "1", type = Comp.Type.GTE), @Comp(value = "2", type = Comp.Type.LTE)}) + @Property(property = "output", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + @Property(valid = @Comp(type = Comp.Type.GTE, value = "1")) + private int time; + + @Property(valid = @Comp(type = Comp.Type.GTE, value = "1"), defaultValue = "1.0f") + private float mruPerTick = 1.0f; + + @Property(valid = {@Comp(type = Comp.Type.GTE, value = "0.0f"), @Comp(type = Comp.Type.LTE, value = "2.0f")}) + private float lowerBalance; + + @Property(valid = {@Comp(type = Comp.Type.GTE, value = "0.0f"), @Comp(type = Comp.Type.LTE, value = "2.0f")}, defaultValue = "2.0f") + private float upperBalance = 2.0f; + + @RecipeBuilderMethodDescription + public RadiatingChamber.RecipeBuilder time(int time) { + this.time = time; + return this; + } + + @RecipeBuilderMethodDescription + public RadiatingChamber.RecipeBuilder mruPerTick(float mruPerTick) { + this.mruPerTick = mruPerTick; + return this; + } + + @RecipeBuilderMethodDescription + public RadiatingChamber.RecipeBuilder lowerBalance(float lowerBalance) { + this.lowerBalance = lowerBalance; + return this; + } + + @RecipeBuilderMethodDescription + public RadiatingChamber.RecipeBuilder upperBalance(float upperBalance) { + this.upperBalance = upperBalance; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Magician Table Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 2, 1, 1); + validateFluids(msg); + msg.add(time < 1, "time must be 1 or greater, got {}", time); + msg.add(mruPerTick < 1.0f, "mru per tick must be at least 1.0f, got {}", mruPerTick); + msg.add(lowerBalance < 0.0f || lowerBalance > 2.0f, "lower balance must be between 0.0f and 2.0f, got {}", lowerBalance); + msg.add(upperBalance < 0.0f || upperBalance > 2.0f, "upper balance must be between 0.0f and 2.0f, got {}", upperBalance); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable RadiatingChamberRecipe register() { + if (!validate()) return null; + Ingredient[] inputIngredient = input.stream().map(IIngredient::toMcIngredient).toArray(Ingredient[]::new); + // the attribute names lie to the devs, they're called 'int mruRequired' and 'float costModifier' + // but actually they're 'int timeInTicks' and 'float mruPerTick' + RadiatingChamberRecipe recipe = new RadiatingChamberRecipe(inputIngredient, output.get(0), time, upperBalance, lowerBalance, mruPerTick); + ModSupport.ESSENTIALCRAFT.get().radiatingChamber.addScripted(recipe); + RadiatingChamberRecipes.addRecipe(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/WindRune.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/WindRune.java new file mode 100644 index 000000000..3f394431e --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/essentialcraft/WindRune.java @@ -0,0 +1,101 @@ +package com.cleanroommc.groovyscript.compat.mods.essentialcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import essentialcraft.api.WindImbueRecipe; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription +public class WindRune extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:gold_block')).output(item('minecraft:diamond_block')).espe(500)")) + public WindRune.RecipeBuilder recipeBuilder() { + return new WindRune.RecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(WindImbueRecipe::removeRecipe); + WindImbueRecipe.RECIPES.addAll(restoreFromBackup()); + } + + @MethodDescription(example = @Example("item('minecraft:diamond')")) + public boolean removeByInput(IIngredient x) { + ItemStack[] stacks = x.getMatchingStacks(); + if (stacks.length == 0) return false; + return WindImbueRecipe.RECIPES.removeIf(r -> { + if (r.input.test(stacks[0])) { + addBackup(r); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example("item('essentialcraft:air_potion')")) + public boolean removeByOutput(IIngredient x) { + return WindImbueRecipe.RECIPES.removeIf(r -> { + if (x.test(r.result)) { + addBackup(r); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + WindImbueRecipe.RECIPES.forEach(this::addBackup); + WindImbueRecipe.RECIPES.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(WindImbueRecipe.RECIPES).setRemover(r -> { + addBackup(r); + return WindImbueRecipe.RECIPES.remove(r); + }); + } + + @Property(property = "input", valid = @Comp("1")) + @Property(property = "output", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + @Property(valid = @Comp(type = Comp.Type.GTE, value = "1")) + private int espe; + + @RecipeBuilderMethodDescription + public RecipeBuilder espe(int cost) { + espe = cost; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Wind Rune Recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + msg.add(espe < 1, "espe cost must be 1 or greater, got {}", espe); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable WindImbueRecipe register() { + if (!validate()) return null; + Ingredient inputItem = input.get(0).toMcIngredient(); + WindImbueRecipe recipe = new WindImbueRecipe(inputItem, output.get(0), espe); // also adds the recipe + ModSupport.ESSENTIALCRAFT.get().windRune.addScripted(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java index 4b1bd1c80..c2b1fef6d 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java @@ -20,6 +20,7 @@ public class LateMixin implements ILateMixinLoader { "calculator", "draconicevolution", "enderio", + "essentialcraft", "extendedcrafting", "extrautils2", "forestry", diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/OreSmeltingRecipeMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/OreSmeltingRecipeMixin.java new file mode 100644 index 000000000..fa96ef1f0 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/OreSmeltingRecipeMixin.java @@ -0,0 +1,29 @@ +package com.cleanroommc.groovyscript.core.mixin.essentialcraft; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import essentialcraft.api.OreSmeltingRecipe; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(value = OreSmeltingRecipe.class, remap = false) +public abstract class OreSmeltingRecipeMixin { + + /** + * @reason This mixin fixes a client crash when reloading recipes for Magmatic Smeltery, + * which happens when a deleted Magmatic Ore item is being rendered and the mod cannot determine the Alloy's overlay color. + */ + + @WrapOperation(method = "getColorFromItemStack", at = @At(value = "FIELD", target = "Lessentialcraft/api/OreSmeltingRecipe;color:I")) + private static int getColorFromItemStack(OreSmeltingRecipe recipe, Operation original) { + if (recipe == null) return 16777215; + return original.call(recipe); + } + + @WrapOperation(method = "getLocalizedOreName", at = @At(value = "FIELD", target = "Lessentialcraft/api/OreSmeltingRecipe;oreName:Ljava/lang/String;")) + private static String getLocalizedOreName(OreSmeltingRecipe recipe, Operation original) { + if (recipe == null) return ""; + return original.call(recipe); + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/TileFurnaceMagicMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/TileFurnaceMagicMixin.java new file mode 100644 index 000000000..0d5f2986f --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/TileFurnaceMagicMixin.java @@ -0,0 +1,33 @@ +package com.cleanroommc.groovyscript.core.mixin.essentialcraft; + +import essentialcraft.api.OreSmeltingRecipe; +import essentialcraft.common.item.ItemsCore; +import essentialcraft.common.tile.TileFurnaceMagic; +import essentialcraft.common.tile.TileMRUGeneric; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = TileFurnaceMagic.class, remap = false) +public abstract class TileFurnaceMagicMixin extends TileMRUGeneric { + + @Shadow + public int smeltingLevel; + + /** + * @reason This mixin fixes a server crash when an invalid Magmatic Ore is put into the Magmatic Furnace's input slot. + * Normally this causes an ArrayOutOfBoundsException when the recipe with index -1 (invalid input) is being read from the registry. + * The indices of its slots are as follows: Bound Gem (0), Ore/Magmatic Alloy input (1), Magmatic Alloy/Resource output (2). + */ + @Inject(method = "update", at = @At("HEAD"), cancellable = true) + public void onUpdate(CallbackInfo ci) { + ItemStack alloy = this.getStackInSlot(1); + if (alloy.getItem() == ItemsCore.magicalAlloy && OreSmeltingRecipe.getIndex(alloy) == -1) { + this.smeltingLevel = 0; + ci.cancel(); + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/TileMagmaticSmelterMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/TileMagmaticSmelterMixin.java new file mode 100644 index 000000000..05cc519b2 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/essentialcraft/TileMagmaticSmelterMixin.java @@ -0,0 +1,35 @@ +package com.cleanroommc.groovyscript.core.mixin.essentialcraft; + +import essentialcraft.api.OreSmeltingRecipe; +import essentialcraft.common.item.ItemsCore; +import essentialcraft.common.tile.TileMRUGeneric; +import essentialcraft.common.tile.TileMagmaticSmelter; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = TileMagmaticSmelter.class, remap = false) +public abstract class TileMagmaticSmelterMixin extends TileMRUGeneric { + + @Shadow + public int smeltingLevel; + + /** + * @reason This mixin fixes a server crash when an invalid Magmatic Ore is put into the Magmatic Smeltery's input slot. + * Normally this causes an ArrayOutOfBoundsException when the recipe with index -1 (invalid input) is being read from the registry. + * The indices of its slots are as follows: Bound Gem (0), Lava Bucket (1), Empty Bucket output (2), + * Ore input (3), Magmatic Alloy output (4), Magmatic Alloy input (5), Resource output (6), Magical Slag (7). + */ + @Inject(method = "update", at = @At("HEAD"), cancellable = true) + public void onUpdate(CallbackInfo ci) { + ItemStack ore = this.getStackInSlot(3); + ItemStack alloy = this.getStackInSlot(5); + if (ore.isEmpty() && alloy.getItem() == ItemsCore.magicalAlloy && OreSmeltingRecipe.getIndex(alloy) == -1) { + this.smeltingLevel = 0; + ci.cancel(); + } + } +} diff --git a/src/main/resources/assets/groovyscript/lang/en_us.lang b/src/main/resources/assets/groovyscript/lang/en_us.lang index d3a5ab9ec..b60610108 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -796,6 +796,42 @@ 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 +# 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. +groovyscript.wiki.essentialcraft.demon_trade.add=Adds an item or an entity that can be sold to demons +groovyscript.wiki.essentialcraft.demon_trade.remove=Removes an item from the pool of sold items +groovyscript.wiki.essentialcraft.demon_trade.removeEntity=Removes an entity from the pool of sold items +groovyscript.wiki.essentialcraft.demon_trade.note0=Demon Trade recipes must set the correct NBT on all input items. This is a bug that was fixed in the version 1.12.2-4.9.112.6 of the mod. + +groovyscript.wiki.essentialcraft.magician_table.title=Magician Table +groovyscript.wiki.essentialcraft.magician_table.description=A 5-slot processing machine using MRU. Can be upgraded with various plates to increase its speed. +groovyscript.wiki.essentialcraft.magician_table.note0=Certain OreDict entries might give unexpected results when used in the Magician Table as inputs. Known entries include: ingotGold, gemEnderPearl +groovyscript.wiki.essentialcraft.magician_table.mru.value=Sets the base MRU cost for this recipe. This cost also equals the time needed to execute the recipe in ticks + +groovyscript.wiki.essentialcraft.magmatic_smeltery.title=Magmatic Smeltery +groovyscript.wiki.essentialcraft.magmatic_smeltery.description=A machine used to quadruple ores using MRU and lava. Also adds the same recipes for Magmatic Furnace, which is used to double ores using MRU. +groovyscript.wiki.essentialcraft.magmatic_smeltery.note0=Magmatic Smeltery does not have a JEI handler. This means its recipes will not be displayed in JEI and have to be tested manually. +groovyscript.wiki.essentialcraft.magmatic_smeltery.color.value=Sets the overlay color for the Magmatic Alloy item of this ore +groovyscript.wiki.essentialcraft.magmatic_smeltery.input.value=Sets the OreDict name of the input item +groovyscript.wiki.essentialcraft.magmatic_smeltery.factor.value=Sets the output factor of the recipe. Magmatic Furnace will smelt the input item into this many Magmatic Alloys, Magmatic Smeltery will give double this many Magmatic Alloys, and Alloys will always be smelted into 2x of the output item +groovyscript.wiki.essentialcraft.magmatic_smeltery.output.value=Sets the OreDict name of the output item + +groovyscript.wiki.essentialcraft.mithriline_furnace.title=Mithriline Furnace +groovyscript.wiki.essentialcraft.mithriline_furnace.description=Converts various items into other items using ESPE. +groovyscript.wiki.essentialcraft.mithriline_furnace.espe.value=Sets the ESPE cost for this recipe + +groovyscript.wiki.essentialcraft.radiating_chamber.title=Radiating Chamber +groovyscript.wiki.essentialcraft.radiating_chamber.description=Combines two items together using MRU to obtain a third item. Can optionally require a specific range of MRU balance to execute the recipe. +groovyscript.wiki.essentialcraft.radiating_chamber.time.value=Sets the time needed to execute this recipe, in ticks +groovyscript.wiki.essentialcraft.radiating_chamber.mruPerTick.value=Sets the amount of MRU spent by the Chamber each tick. The total MRU can be calculated as `time * mruPerTick` +groovyscript.wiki.essentialcraft.radiating_chamber.lowerBalance.value=Sets the minimum balance required for this recipe +groovyscript.wiki.essentialcraft.radiating_chamber.upperBalance.value=Sets the maximum balance required for this recipe + +groovyscript.wiki.essentialcraft.wind_rune.title=Wind Rune +groovyscript.wiki.essentialcraft.wind_rune.description=Transforms various items using ESPE. +groovyscript.wiki.essentialcraft.wind_rune.espe.value=Sets the ESPE cost for this recipe + # EvilCraft groovyscript.wiki.evilcraft.blood_infuser.title=Blood Infuser groovyscript.wiki.evilcraft.blood_infuser.description=Consumes an item, some fluid, and requires a given tier of Promise of Tenacity to produce the output and some experience after a duration. diff --git a/src/main/resources/mixin.groovyscript.essentialcraft.json b/src/main/resources/mixin.groovyscript.essentialcraft.json new file mode 100644 index 000000000..2f31e9159 --- /dev/null +++ b/src/main/resources/mixin.groovyscript.essentialcraft.json @@ -0,0 +1,12 @@ +{ + "package": "com.cleanroommc.groovyscript.core.mixin.essentialcraft", + "refmap": "mixins.groovyscript.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "OreSmeltingRecipeMixin", + "TileFurnaceMagicMixin", + "TileMagmaticSmelterMixin" + ] +} \ No newline at end of file