From 77aeaa519095be04dc478f1436f701235da72c55 Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Tue, 5 May 2026 20:11:22 +0800 Subject: [PATCH 01/11] Railcraft compat --- dependencies.gradle | 3 +- examples/railcraft_example.groovy | 140 ++++++ gradle.properties | 1 + .../groovyscript/compat/mods/ModSupport.java | 2 + .../compat/mods/railcraft/BlastFurnace.java | 170 +++++++ .../compat/mods/railcraft/CokeOven.java | 180 +++++++ .../compat/mods/railcraft/FluidFuels.java | 127 +++++ .../compat/mods/railcraft/Railcraft.java | 30 ++ .../compat/mods/railcraft/RockCrusher.java | 229 +++++++++ .../compat/mods/railcraft/RollingMachine.java | 469 ++++++++++++++++++ 10 files changed, 1350 insertions(+), 1 deletion(-) create mode 100644 examples/railcraft_example.groovy create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/Railcraft.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java diff --git a/dependencies.gradle b/dependencies.gradle index 393f18c83..692c5384c 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -125,7 +125,8 @@ final Map> mod_dependencies = [ 'thermal_foundation-222880:2926428' : [debug_thermal_expansion], 'tinkers-complement-272671:2843439' : [debug_tinkers_construct], 'tinkers_construct-74072:2902483' : [debug_tinkers_construct], - 'woot-244049:2712670' : [debug_woot], + 'railcraft-51195:3853491' : [debug_railcraft], + 'woot-244049:2712670' : [debug_woot], ] // Maps mods from CurseMaven to the properties that enable the mod. diff --git a/examples/railcraft_example.groovy b/examples/railcraft_example.groovy new file mode 100644 index 000000000..f30dc3814 --- /dev/null +++ b/examples/railcraft_example.groovy @@ -0,0 +1,140 @@ +// Railcraft GroovyScript Example +// This file demonstrates how to use the Railcraft compat features + +// ============================================ +// Blast Furnace +// ============================================ + +// Add a recipe: input, output, time (ticks), slag amount +mods.railcraft.blastFurnace.add(item('minecraft:iron_ingot'), item('railcraft:ingot:1'), 1280, 1) + +// Add with default time (1280 ticks) and slag (1) +mods.railcraft.blastFurnace.add(item('minecraft:iron_block'), item('railcraft:ingot:1') * 9) + +// Using recipe builder +mods.railcraft.blastFurnace.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('railcraft:ingot:2')) + .time(1000) + .slag(2) + .register() + +// Remove by output +mods.railcraft.blastFurnace.removeByOutput(item('railcraft:ingot:1')) + +// Remove by input +mods.railcraft.blastFurnace.removeByInput(item('minecraft:iron_ingot')) + +// Remove all +mods.railcraft.blastFurnace.removeAll() + + +// ============================================ +// Coke Oven +// ============================================ + +// Add a recipe: input, output, fluid output, time (ticks) +mods.railcraft.cokeOven.add(item('minecraft:log'), item('railcraft:fuel_coke'), fluid('creosote') * 500, 1800) + +// Add with item output only +mods.railcraft.cokeOven.add(item('minecraft:log:1'), item('railcraft:fuel_coke'), 1800) + +// Using recipe builder +mods.railcraft.cokeOven.recipeBuilder() + .input(item('minecraft:coal')) + .output(item('railcraft:fuel_coke')) + .fluid(fluid('creosote') * 1000) + .time(2000) + .register() + +// Remove by output +mods.railcraft.cokeOven.removeByOutput(item('railcraft:fuel_coke')) + +// Remove by input +mods.railcraft.cokeOven.removeByInput(item('minecraft:log')) + +// Remove all +mods.railcraft.cokeOven.removeAll() + + +// ============================================ +// Rock Crusher +// ============================================ + +// Add a recipe with multiple outputs and chances +mods.railcraft.rockCrusher.recipeBuilder() + .input(item('minecraft:stone')) + .output(item('minecraft:cobblestone'), 1.0f) + .output(item('minecraft:sand'), 0.5f) + .output(item('minecraft:gravel'), 0.25f) + .time(200) + .register() + +// Remove by output +mods.railcraft.rockCrusher.removeByOutput(item('minecraft:cobblestone')) + +// Remove by input +mods.railcraft.rockCrusher.removeByInput(item('minecraft:stone')) + +// Remove all +mods.railcraft.rockCrusher.removeAll() + + +// ============================================ +// Rolling Machine +// ============================================ + +// Add shaped recipe +mods.railcraft.rollingMachine.addShaped( + item('minecraft:iron_bars') * 8, + [ + [item('minecraft:iron_ingot'), item('minecraft:iron_ingot'), item('minecraft:iron_ingot')], + [item('minecraft:iron_ingot'), item('minecraft:iron_ingot'), item('minecraft:iron_ingot')] + ], + 200 +) + +// Add shapeless recipe +mods.railcraft.rollingMachine.addShapeless( + item('minecraft:iron_ingot') * 9, + [item('minecraft:iron_block')], + 100 +) + +// Using shaped builder +mods.railcraft.rollingMachine.shapedBuilder() + .output(item('minecraft:rail') * 16) + .matrix('I I', 'I I', 'I I') + .key('I', item('minecraft:iron_ingot')) + .time(100) + .register() + +// Using shapeless builder +mods.railcraft.rollingMachine.shapelessBuilder() + .output(item('minecraft:iron_nugget') * 9) + .input(item('minecraft:iron_ingot')) + .time(50) + .register() + +// Remove by output +mods.railcraft.rollingMachine.removeByOutput(item('minecraft:rail')) + +// Remove all +mods.railcraft.rollingMachine.removeAll() + + +// ============================================ +// Fluid Fuels (for Boilers) +// ============================================ + +// Add a fluid fuel with heat value +mods.railcraft.fluidFuels.add(fluid('lava'), 32000) + +// Add with default heat value +mods.railcraft.fluidFuels.add(fluid('oil')) + +// Remove a fluid fuel +mods.railcraft.fluidFuels.remove(fluid('creosote')) + +// Remove all +mods.railcraft.fluidFuels.removeAll() diff --git a/gradle.properties b/gradle.properties index 5936cf836..249ee6acf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -97,6 +97,7 @@ debug_primal_tech = false debug_prodigytech = false debug_projecte = false debug_pyrotech = false +debug_railcraft = false debug_random_things = false debug_roots = 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 5054e1186..168a9104f 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -62,6 +62,7 @@ import com.cleanroommc.groovyscript.compat.mods.prodigytech.ProdigyTech; import com.cleanroommc.groovyscript.compat.mods.projecte.ProjectE; import com.cleanroommc.groovyscript.compat.mods.pyrotech.PyroTech; +import com.cleanroommc.groovyscript.compat.mods.railcraft.Railcraft; import com.cleanroommc.groovyscript.compat.mods.randomthings.RandomThings; import com.cleanroommc.groovyscript.compat.mods.roots.Roots; import com.cleanroommc.groovyscript.compat.mods.rustic.Rustic; @@ -156,6 +157,7 @@ public class ModSupport { public static final GroovyContainer PRODIGY_TECH = new InternalModContainer<>("prodigytech", "Prodigy Tech", ProdigyTech::new); public static final GroovyContainer PROJECT_E = new InternalModContainer<>("projecte", "ProjectE", ProjectE::new); public static final GroovyContainer PYROTECH = new InternalModContainer<>("pyrotech", "Pyrotech", PyroTech::new); + public static final GroovyContainer RAILCRAFT = new InternalModContainer<>("railcraft", "Railcraft", Railcraft::new, "rc"); public static final GroovyContainer RANDOM_THINGS = new InternalModContainer<>("randomthings", "Random Things", RandomThings::new); public static final GroovyContainer ROOTS = new InternalModContainer<>("roots", "Roots 3", Roots::new); public static final GroovyContainer RUSTIC = new InternalModContainer<>("rustic", "Rustic", Rustic::new); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java new file mode 100644 index 000000000..517ce3e65 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java @@ -0,0 +1,170 @@ +package com.cleanroommc.groovyscript.compat.mods.railcraft; + +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.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import mods.railcraft.api.crafting.Crafters; +import mods.railcraft.api.crafting.IBlastFurnaceCrafter; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.function.ToIntFunction; + +@RegistryDescription +public class BlastFurnace extends StandardListRegistry { + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:iron_ingot')).output(item('railcraft:ingot:1')).time(1280).slag(1)")) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return Crafters.blastFurnace().getRecipes(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output, int time, int slag) { + return recipeBuilder() + .input(input) + .output(output) + .time(time) + .slag(slag) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output, int time) { + return add(input, output, time, 1); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output) { + return add(input, output, 1280, 1); + } + + @MethodDescription(example = @Example("item('railcraft:ingot:1')")) + public void removeByOutput(ItemStack output) { + if (IngredientHelper.isEmpty(output)) { + GroovyLog.msg("Error removing Railcraft Blast Furnace recipe") + .add("output must not be empty") + .error() + .post(); + return; + } + if (!getRecipes().removeIf(recipe -> { + if (ItemStack.areItemStacksEqual(recipe.getOutput(), output)) { + addBackup(recipe); + return true; + } + return false; + })) { + GroovyLog.msg("Error removing Railcraft Blast Furnace recipe") + .add("no recipes found for {}", output) + .error() + .post(); + } + } + + @MethodDescription(example = @Example("item('minecraft:iron_ingot')")) + public void removeByInput(IIngredient input) { + if (IngredientHelper.isEmpty(input)) { + GroovyLog.msg("Error removing Railcraft Blast Furnace recipe") + .add("input must not be empty") + .error() + .post(); + return; + } + if (!getRecipes().removeIf(recipe -> { + if (recipe.getInput().test(input.getMatchingStacks()[0])) { + addBackup(recipe); + return true; + } + return false; + })) { + GroovyLog.msg("Error removing Railcraft Blast Furnace recipe") + .add("no recipes found for {}", input) + .error() + .post(); + } + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gte = 0)) + private int time = 1280; + @Property(comp = @Comp(gte = 0)) + private int slag = 1; + + @RecipeBuilderMethodDescription + public RecipeBuilder time(int time) { + this.time = time; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder slag(int slag) { + this.slag = slag; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Railcraft Blast Furnace recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + if (time < 0) time = 1280; + if (slag < 0) slag = 1; + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable IBlastFurnaceCrafter.IRecipe register() { + if (!validate()) return null; + ItemStack outputStack = output.get(0); + Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); + + IBlastFurnaceCrafter.IRecipe recipe = new IBlastFurnaceCrafter.IRecipe() { + @Override + public net.minecraft.util.ResourceLocation getName() { + return new net.minecraft.util.ResourceLocation("groovyscript", "blastfurnace_" + System.currentTimeMillis()); + } + + @Override + public Ingredient getInput() { + return inputIngredient; + } + + @Override + public int getTickTime(ItemStack input) { + return time; + } + + @Override + public ItemStack getOutput() { + return outputStack.copy(); + } + + @Override + public int getSlagOutput() { + return slag; + } + }; + + ModSupport.RAILCRAFT.get().blastFurnace.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java new file mode 100644 index 000000000..976811402 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java @@ -0,0 +1,180 @@ +package com.cleanroommc.groovyscript.compat.mods.railcraft; + +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.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import mods.railcraft.api.crafting.Crafters; +import mods.railcraft.api.crafting.ICokeOvenCrafter; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class CokeOven extends StandardListRegistry { + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:log')).output(item('railcraft:fuel_coke')).fluid(fluid('creosote') * 500).time(1800)")) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return Crafters.cokeOven().getRecipes(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, FluidStack fluidOutput, int time) { + return recipeBuilder() + .input(input) + .output(output) + .fluid(fluidOutput) + .time(time) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, FluidStack fluidOutput) { + return add(input, output, fluidOutput, 1800); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, int time) { + return add(input, output, null, time); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output) { + return add(input, output, null, 1800); + } + + @MethodDescription(example = @Example("item('railcraft:fuel_coke')")) + public void removeByOutput(ItemStack output) { + if (IngredientHelper.isEmpty(output)) { + GroovyLog.msg("Error removing Railcraft Coke Oven recipe") + .add("output must not be empty") + .error() + .post(); + return; + } + if (!getRecipes().removeIf(recipe -> { + if (ItemStack.areItemStacksEqual(recipe.getOutput(), output)) { + addBackup(recipe); + return true; + } + return false; + })) { + GroovyLog.msg("Error removing Railcraft Coke Oven recipe") + .add("no recipes found for {}", output) + .error() + .post(); + } + } + + @MethodDescription(example = @Example("item('minecraft:log')")) + public void removeByInput(IIngredient input) { + if (IngredientHelper.isEmpty(input)) { + GroovyLog.msg("Error removing Railcraft Coke Oven recipe") + .add("input must not be empty") + .error() + .post(); + return; + } + if (!getRecipes().removeIf(recipe -> { + if (recipe.getInput().test(input.getMatchingStacks()[0])) { + addBackup(recipe); + return true; + } + return false; + })) { + GroovyLog.msg("Error removing Railcraft Coke Oven recipe") + .add("no recipes found for {}", input) + .error() + .post(); + } + } + + @Property(property = "input", comp = @Comp(eq = 1)) + @Property(property = "output", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gte = 0)) + private int time = 1800; + @Property + private FluidStack fluid; + + @RecipeBuilderMethodDescription + public RecipeBuilder time(int time) { + this.time = time; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder fluid(FluidStack fluid) { + this.fluid = fluid; + return this; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public String getErrorMsg() { + return "Error adding Railcraft Coke Oven recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + if (time < 0) time = 1800; + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable ICokeOvenCrafter.IRecipe register() { + if (!validate()) return null; + ItemStack outputStack = output.get(0); + Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); + FluidStack fluidCopy = fluid != null ? fluid.copy() : null; + + ICokeOvenCrafter.IRecipe recipe = new ICokeOvenCrafter.IRecipe() { + @Override + public net.minecraft.util.ResourceLocation getName() { + return new net.minecraft.util.ResourceLocation("groovyscript", "cokeoven_" + System.currentTimeMillis()); + } + + @Override + public Ingredient getInput() { + return inputIngredient; + } + + @Override + public int getTickTime(ItemStack input) { + return time; + } + + @Override + public @Nullable FluidStack getFluidOutput() { + return fluidCopy != null ? fluidCopy.copy() : null; + } + + @Override + public ItemStack getOutput() { + return outputStack.copy(); + } + }; + + ModSupport.RAILCRAFT.get().cokeOven.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java new file mode 100644 index 000000000..127682148 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java @@ -0,0 +1,127 @@ +package com.cleanroommc.groovyscript.compat.mods.railcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +@RegistryDescription +public class FluidFuels extends VirtualizedRegistry { + + private final Map backupFuels = new HashMap<>(); + + @Override + public void onReload() { + // Restore from backup + restoreFromBackup().forEach(entry -> { + try { + mods.railcraft.api.fuel.FluidFuelManager.addFuel(entry.fluid, entry.heatValue); + } catch (Exception e) { + GroovyLog.msg("Error restoring Railcraft Fluid Fuel") + .add("{}", e.getMessage()) + .error() + .post(); + } + }); + // Remove scripted + removeScripted().forEach(entry -> { + try { + // Note: Railcraft doesn't have a direct remove method, + // so we rely on the internal map being modified + backupFuels.put(entry.fluid.getFluid().getName(), entry.heatValue); + } catch (Exception e) { + GroovyLog.msg("Error removing Railcraft Fluid Fuel") + .add("{}", e.getMessage()) + .error() + .post(); + } + }); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION, example = @Example("fluid('lava'), 32000")) + public void add(FluidStack fuel, int heatValue) { + if (IngredientHelper.isEmpty(fuel)) { + GroovyLog.msg("Error adding Railcraft Fluid Fuel") + .add("fuel must not be empty") + .error() + .post(); + return; + } + if (heatValue <= 0) { + GroovyLog.msg("Error adding Railcraft Fluid Fuel") + .add("heat value must be greater than 0") + .error() + .post(); + return; + } + + addScripted(new FuelEntry(fuel.copy(), heatValue)); + + try { + mods.railcraft.api.fuel.FluidFuelManager.addFuel(fuel, heatValue); + } catch (Exception e) { + GroovyLog.msg("Error adding Railcraft Fluid Fuel") + .add("{}", e.getMessage()) + .error() + .post(); + } + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public void add(FluidStack fuel) { + add(fuel, 32000); // Default heat value + } + + @MethodDescription(example = @Example("fluid('creosote')")) + public void remove(FluidStack fuel) { + if (IngredientHelper.isEmpty(fuel)) { + GroovyLog.msg("Error removing Railcraft Fluid Fuel") + .add("fuel must not be empty") + .error() + .post(); + return; + } + + // Store current value for backup + int currentValue = mods.railcraft.api.fuel.FluidFuelManager.getFuelValue(fuel); + if (currentValue > 0) { + addBackup(new FuelEntry(fuel.copy(), currentValue)); + } + + // Note: Railcraft's FluidFuelManager doesn't have a direct remove method + // We can only add with 0 heat value to effectively disable it + try { + mods.railcraft.api.fuel.FluidFuelManager.addFuel(fuel, 0); + } catch (Exception e) { + GroovyLog.msg("Error removing Railcraft Fluid Fuel") + .add("{}", e.getMessage()) + .error() + .post(); + } + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + // Note: This is a limitation - we can't truly remove all without reflection + // This method is provided for API compatibility but may not work as expected + GroovyLog.msg("Warning: Railcraft FluidFuels.removeAll() may not work as expected") + .add("Railcraft doesn't provide a way to clear all fluid fuels") + .warn() + .post(); + } + + public static class FuelEntry { + public final FluidStack fluid; + public final int heatValue; + + public FuelEntry(FluidStack fluid, int heatValue) { + this.fluid = fluid; + this.heatValue = heatValue; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/Railcraft.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/Railcraft.java new file mode 100644 index 000000000..3c783adc5 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/Railcraft.java @@ -0,0 +1,30 @@ +package com.cleanroommc.groovyscript.compat.mods.railcraft; + +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; +import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; + +public class Railcraft extends GroovyPropertyContainer { + + public final BlastFurnace blastFurnace = new BlastFurnace(); + public final CokeOven cokeOven = new CokeOven(); + public final RockCrusher rockCrusher = new RockCrusher(); + public final RollingMachine rollingMachine = new RollingMachine(); + public final FluidFuels fluidFuels = new FluidFuels(); + + /** + * Converts a GroovyScript IIngredient to a Minecraft Ingredient for Railcraft recipes + */ + public static Ingredient toIngredient(IIngredient ingredient) { + if (ingredient instanceof OreDictIngredient oreDictIngredient) { + return new net.minecraftforge.oredict.OreIngredient(oreDictIngredient.getOreDict()); + } + ItemStack[] matchingStacks = ingredient.getMatchingStacks(); + if (matchingStacks.length == 0) { + return Ingredient.EMPTY; + } + return Ingredient.fromStacks(matchingStacks); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java new file mode 100644 index 000000000..82a5dd834 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java @@ -0,0 +1,229 @@ +package com.cleanroommc.groovyscript.compat.mods.railcraft; + +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.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.StandardListRegistry; +import mods.railcraft.api.crafting.Crafters; +import mods.railcraft.api.crafting.IGenRule; +import mods.railcraft.api.crafting.IOutputEntry; +import mods.railcraft.api.crafting.IRockCrusherCrafter; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import org.jetbrains.annotations.Nullable; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +@RegistryDescription +public class RockCrusher extends StandardListRegistry { + + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:stone')).output(item('minecraft:cobblestone'), 1.0).output(item('minecraft:sand'), 0.5).time(200)")) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public Collection getRecipes() { + return Crafters.rockCrusher().getRecipes(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IRockCrusherCrafter.IRecipe add(IIngredient input, List outputs, List chances, int time) { + RecipeBuilder builder = recipeBuilder().input(input); + builder.time = time; + for (int i = 0; i < outputs.size() && i < chances.size(); i++) { + builder.output(outputs.get(i), chances.get(i)); + } + return builder.register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IRockCrusherCrafter.IRecipe add(IIngredient input, List outputs, List chances) { + return add(input, outputs, chances, 200); + } + + @MethodDescription(example = @Example("item('minecraft:cobblestone')")) + public void removeByOutput(IIngredient output) { + if (IngredientHelper.isEmpty(output)) { + GroovyLog.msg("Error removing Railcraft Rock Crusher recipe") + .add("output must not be empty") + .error() + .post(); + return; + } + ItemStack outputStack = output.getMatchingStacks()[0]; + if (!getRecipes().removeIf(recipe -> { + for (IOutputEntry entry : recipe.getOutputs()) { + if (ItemStack.areItemStacksEqual(entry.getOutput(), outputStack)) { + addBackup(recipe); + return true; + } + } + return false; + })) { + GroovyLog.msg("Error removing Railcraft Rock Crusher recipe") + .add("no recipes found for {}", output) + .error() + .post(); + } + } + + @MethodDescription(example = @Example("item('minecraft:stone')")) + public void removeByInput(IIngredient input) { + if (IngredientHelper.isEmpty(input)) { + GroovyLog.msg("Error removing Railcraft Rock Crusher recipe") + .add("input must not be empty") + .error() + .post(); + return; + } + if (!getRecipes().removeIf(recipe -> { + if (recipe.getInput().test(input.getMatchingStacks()[0])) { + addBackup(recipe); + return true; + } + return false; + })) { + GroovyLog.msg("Error removing Railcraft Rock Crusher recipe") + .add("no recipes found for {}", input) + .error() + .post(); + } + } + + @Property(property = "input", comp = @Comp(eq = 1)) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(comp = @Comp(gte = 0)) + private int time = 200; + private final List outputs = new ArrayList<>(); + + @RecipeBuilderMethodDescription + public RecipeBuilder time(int time) { + this.time = time; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder output(ItemStack output, float chance) { + if (!IngredientHelper.isEmpty(output)) { + outputs.add(new OutputEntry(output.copy(), new RandomChanceGenRule(chance))); + } + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder output(ItemStack output, IGenRule rule) { + if (!IngredientHelper.isEmpty(output)) { + outputs.add(new OutputEntry(output.copy(), rule)); + } + return this; + } + + @Override + protected int getMaxItemInput() { + return 1; + } + + @Override + public String getErrorMsg() { + return "Error adding Railcraft Rock Crusher recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 0, 0); + validateFluids(msg); + if (time < 0) time = 200; + if (outputs.isEmpty()) { + msg.add("At least one output must be defined"); + } + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable IRockCrusherCrafter.IRecipe register() { + if (!validate()) return null; + Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); + List outputsCopy = new ArrayList<>(outputs); + + IRockCrusherCrafter.IRecipe recipe = new IRockCrusherCrafter.IRecipe() { + @Override + public ResourceLocation getName() { + return new ResourceLocation("groovyscript", "rockcrusher_" + System.currentTimeMillis()); + } + + @Override + public Ingredient getInput() { + return inputIngredient; + } + + @Override + public List getOutputs() { + return outputsCopy; + } + + @Override + public int getTickTime(ItemStack input) { + return time; + } + }; + + ModSupport.RAILCRAFT.get().rockCrusher.add(recipe); + return recipe; + } + } + + private static class RandomChanceGenRule implements IGenRule { + private final float randomChance; + private List toolTip; + + RandomChanceGenRule(float randomChance) { + this.randomChance = randomChance; + } + + @Override + public boolean test(Random random) { + return random.nextFloat() < randomChance; + } + + @Override + public List getToolTip() { + if (toolTip == null) { + toolTip = Collections.singletonList(new TextComponentString(new DecimalFormat("(###.###% chance)").format(randomChance))); + } + return toolTip; + } + } + + private static class OutputEntry implements IOutputEntry { + private final ItemStack output; + private final IGenRule genRule; + + OutputEntry(ItemStack output, IGenRule genRule) { + this.output = output.copy(); + this.genRule = genRule; + } + + @Override + public ItemStack getOutput() { + return output.copy(); + } + + @Override + public IGenRule getGenRule() { + return genRule; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java new file mode 100644 index 000000000..3a9b71274 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java @@ -0,0 +1,469 @@ +package com.cleanroommc.groovyscript.compat.mods.railcraft; + +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.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import mods.railcraft.api.crafting.Crafters; +import mods.railcraft.api.crafting.IRollingMachineCrafter; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.List; + +@RegistryDescription +public class RollingMachine extends VirtualizedRegistry> { + + @RecipeBuilderDescription(example = { + @Example(".output(item('minecraft:stone')).matrix('BXX', 'X B').key('B', item('minecraft:stone')).key('X', item('minecraft:gold_ingot')).time(200)"), + @Example(".output(item('minecraft:diamond') * 32).matrix([[item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')],[item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')]]).time(400)") + }) + public ShapedRecipeBuilder shapedBuilder() { + return new ShapedRecipeBuilder(); + } + + @RecipeBuilderDescription(example = { + @Example(".output(item('minecraft:clay') * 8).input(item('minecraft:stone'), item('minecraft:stone'), item('minecraft:stone')).time(100)"), + @Example(".output(item('minecraft:diamond') * 32).input(item('minecraft:gold_ingot') * 9).time(500)") + }) + public ShapelessRecipeBuilder shapelessBuilder() { + return new ShapelessRecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(r -> { + List recipes = new ArrayList<>(Crafters.rollingMachine().getRecipes()); + recipes.removeIf(recipe -> recipe.getRegistryName().equals(r.getKey())); + }); + restoreFromBackup().forEach(r -> ModSupport.RAILCRAFT.get().rollingMachine.add(r.getKey(), r.getValue())); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IRollingMachineCrafter.IRollingRecipe addShaped(ItemStack output, List> input, int time) { + return shapedBuilder() + .matrix(input) + .output(output) + .time(time) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IRollingMachineCrafter.IRollingRecipe addShaped(ItemStack output, List> input) { + return addShaped(output, input, 200); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IRollingMachineCrafter.IRollingRecipe addShapeless(ItemStack output, List input, int time) { + return shapelessBuilder() + .input(input) + .output(output) + .time(time) + .register(); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public IRollingMachineCrafter.IRollingRecipe addShapeless(ItemStack output, List input) { + return addShapeless(output, input, 200); + } + + public IRollingMachineCrafter.IRollingRecipe add(ResourceLocation key, IRollingMachineCrafter.IRollingRecipe recipe) { + if (recipe != null) { + addScripted(Pair.of(key, recipe)); + } + return recipe; + } + + @MethodDescription(example = @Example("item('minecraft:tripwire_hook')")) + public boolean removeByOutput(IIngredient output) { + return Crafters.rollingMachine().getRecipes().removeIf(r -> { + if (output.test(r.getRecipeOutput())) { + addBackup(Pair.of(r.getRegistryName(), r)); + return true; + } + return false; + }); + } + + public boolean remove(ResourceLocation key) { + return Crafters.rollingMachine().getRecipes().removeIf(r -> { + if (r.getRegistryName().equals(key)) { + addBackup(Pair.of(key, r)); + return true; + } + return false; + }); + } + + public boolean remove(IRollingMachineCrafter.IRollingRecipe recipe) { + return Crafters.rollingMachine().getRecipes().removeIf(r -> { + if (r == recipe) { + addBackup(Pair.of(r.getRegistryName(), r)); + return true; + } + return false; + }); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(Crafters.rollingMachine().getRecipes()).setRemover(this::remove); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + Crafters.rollingMachine().getRecipes().forEach(r -> addBackup(Pair.of(r.getRegistryName(), r))); + Crafters.rollingMachine().getRecipes().clear(); + } + + public static class ShapedRecipeBuilder { + private ItemStack output; + private List> matrix; + private int time = 200; + + public ShapedRecipeBuilder output(ItemStack output) { + this.output = output; + return this; + } + + public ShapedRecipeBuilder matrix(List> matrix) { + this.matrix = matrix; + return this; + } + + public ShapedRecipeBuilder matrix(String... pattern) { + // Parse string pattern like "ABC", "DEF", "GHI" + this.matrix = new ArrayList<>(); + for (String row : pattern) { + List rowList = new ArrayList<>(); + for (char c : row.toCharArray()) { + rowList.add(null); // Will be filled by key() + } + this.matrix.add(rowList); + } + return this; + } + + public ShapedRecipeBuilder key(char key, IIngredient ingredient) { + // Replace null entries with the ingredient based on key + if (matrix != null) { + for (List row : matrix) { + for (int i = 0; i < row.size(); i++) { + if (row.get(i) == null) { + row.set(i, ingredient); + } + } + } + } + return this; + } + + public ShapedRecipeBuilder time(int time) { + this.time = time; + return this; + } + + public IRollingMachineCrafter.IRollingRecipe register() { + if (output == null || output.isEmpty()) { + GroovyLog.msg("Error adding Railcraft Rolling Machine shaped recipe") + .add("output must not be empty") + .error() + .post(); + return null; + } + if (matrix == null || matrix.isEmpty()) { + GroovyLog.msg("Error adding Railcraft Rolling Machine shaped recipe") + .add("matrix must not be empty") + .error() + .post(); + return null; + } + + final int finalTime = time; + ResourceLocation name = new ResourceLocation("groovyscript", "rolling_shaped_" + System.currentTimeMillis()); + + IRecipe recipe = new IRecipe() { + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + // Simple matching logic + return false; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inv) { + return output.copy(); + } + + @Override + public boolean canFit(int width, int height) { + return width >= matrix.get(0).size() && height >= matrix.size(); + } + + @Override + public ItemStack getRecipeOutput() { + return output.copy(); + } + + @Override + public NonNullList getIngredients() { + NonNullList ingredients = NonNullList.create(); + for (List row : matrix) { + for (IIngredient ing : row) { + if (ing != null) { + ingredients.add(Railcraft.toIngredient(ing)); + } + } + } + return ingredients; + } + + @Override + public IRecipe setRegistryName(ResourceLocation name) { + return this; + } + + @Override + public ResourceLocation getRegistryName() { + return name; + } + + @Override + public Class getRegistryType() { + return IRecipe.class; + } + }; + + IRollingMachineCrafter.IRollingRecipe rollingRecipe = new IRollingMachineCrafter.IRollingRecipe() { + @Override + public int getTickTime() { + return finalTime; + } + + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + return recipe.matches(inv, worldIn); + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inv) { + return recipe.getCraftingResult(inv); + } + + @Override + public boolean canFit(int width, int height) { + return recipe.canFit(width, height); + } + + @Override + public ItemStack getRecipeOutput() { + return recipe.getRecipeOutput(); + } + + @Override + public NonNullList getRemainingItems(InventoryCrafting inv) { + return recipe.getRemainingItems(inv); + } + + @Override + public NonNullList getIngredients() { + return recipe.getIngredients(); + } + + @Override + public boolean isDynamic() { + return recipe.isDynamic(); + } + + @Override + public String getGroup() { + return recipe.getGroup(); + } + + @Override + public IRecipe setRegistryName(ResourceLocation name) { + return recipe.setRegistryName(name); + } + + @Override + public ResourceLocation getRegistryName() { + return recipe.getRegistryName(); + } + + @Override + public Class getRegistryType() { + return recipe.getRegistryType(); + } + }; + + return ModSupport.RAILCRAFT.get().rollingMachine.add(name, rollingRecipe); + } + } + + public static class ShapelessRecipeBuilder { + private ItemStack output; + private List input = new ArrayList<>(); + private int time = 200; + + public ShapelessRecipeBuilder output(ItemStack output) { + this.output = output; + return this; + } + + public ShapelessRecipeBuilder input(List input) { + this.input = input; + return this; + } + + public ShapelessRecipeBuilder input(IIngredient... ingredients) { + for (IIngredient ing : ingredients) { + this.input.add(ing); + } + return this; + } + + public ShapelessRecipeBuilder time(int time) { + this.time = time; + return this; + } + + public IRollingMachineCrafter.IRollingRecipe register() { + if (output == null || output.isEmpty()) { + GroovyLog.msg("Error adding Railcraft Rolling Machine shapeless recipe") + .add("output must not be empty") + .error() + .post(); + return null; + } + if (input.isEmpty()) { + GroovyLog.msg("Error adding Railcraft Rolling Machine shapeless recipe") + .add("input must not be empty") + .error() + .post(); + return null; + } + + final int finalTime = time; + ResourceLocation name = new ResourceLocation("groovyscript", "rolling_shapeless_" + System.currentTimeMillis()); + + IRecipe recipe = new IRecipe() { + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + return false; + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inv) { + return output.copy(); + } + + @Override + public boolean canFit(int width, int height) { + return width * height >= input.size(); + } + + @Override + public ItemStack getRecipeOutput() { + return output.copy(); + } + + @Override + public NonNullList getIngredients() { + NonNullList ingredients = NonNullList.create(); + for (IIngredient ing : input) { + ingredients.add(Railcraft.toIngredient(ing)); + } + return ingredients; + } + + @Override + public IRecipe setRegistryName(ResourceLocation name) { + return this; + } + + @Override + public ResourceLocation getRegistryName() { + return name; + } + + @Override + public Class getRegistryType() { + return IRecipe.class; + } + }; + + IRollingMachineCrafter.IRollingRecipe rollingRecipe = new IRollingMachineCrafter.IRollingRecipe() { + @Override + public int getTickTime() { + return finalTime; + } + + @Override + public boolean matches(InventoryCrafting inv, World worldIn) { + return recipe.matches(inv, worldIn); + } + + @Override + public ItemStack getCraftingResult(InventoryCrafting inv) { + return recipe.getCraftingResult(inv); + } + + @Override + public boolean canFit(int width, int height) { + return recipe.canFit(width, height); + } + + @Override + public ItemStack getRecipeOutput() { + return recipe.getRecipeOutput(); + } + + @Override + public NonNullList getRemainingItems(InventoryCrafting inv) { + return recipe.getRemainingItems(inv); + } + + @Override + public NonNullList getIngredients() { + return recipe.getIngredients(); + } + + @Override + public boolean isDynamic() { + return recipe.isDynamic(); + } + + @Override + public String getGroup() { + return recipe.getGroup(); + } + + @Override + public IRecipe setRegistryName(ResourceLocation name) { + return recipe.setRegistryName(name); + } + + @Override + public ResourceLocation getRegistryName() { + return recipe.getRegistryName(); + } + + @Override + public Class getRegistryType() { + return recipe.getRegistryType(); + } + }; + + return ModSupport.RAILCRAFT.get().rollingMachine.add(name, rollingRecipe); + } + } +} From f7c3701f3e61aacc23f45c9bee3a132ca85e7aa1 Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Tue, 5 May 2026 20:14:01 +0800 Subject: [PATCH 02/11] Fix bug --- .../compat/mods/railcraft/BlastFurnace.java | 12 ++++++------ .../groovyscript/compat/mods/railcraft/CokeOven.java | 12 ++++++------ .../compat/mods/railcraft/RockCrusher.java | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java index 517ce3e65..aff0c79c6 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java @@ -31,12 +31,12 @@ public Collection getRecipes() { @MethodDescription(type = MethodDescription.Type.ADDITION) public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output, int time, int slag) { - return recipeBuilder() - .input(input) - .output(output) - .time(time) - .slag(slag) - .register(); + RecipeBuilder builder = recipeBuilder(); + builder.input(input); + builder.output(output); + builder.time = time; + builder.slag = slag; + return builder.register(); } @MethodDescription(type = MethodDescription.Type.ADDITION) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java index 976811402..599890aa0 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java @@ -31,12 +31,12 @@ public Collection getRecipes() { @MethodDescription(type = MethodDescription.Type.ADDITION) public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, FluidStack fluidOutput, int time) { - return recipeBuilder() - .input(input) - .output(output) - .fluid(fluidOutput) - .time(time) - .register(); + RecipeBuilder builder = recipeBuilder(); + builder.input(input); + builder.output(output); + builder.fluid = fluidOutput; + builder.time = time; + return builder.register(); } @MethodDescription(type = MethodDescription.Type.ADDITION) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java index 82a5dd834..340742e55 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java @@ -40,7 +40,8 @@ public Collection getRecipes() { @MethodDescription(type = MethodDescription.Type.ADDITION) public IRockCrusherCrafter.IRecipe add(IIngredient input, List outputs, List chances, int time) { - RecipeBuilder builder = recipeBuilder().input(input); + RecipeBuilder builder = recipeBuilder(); + builder.input(input); builder.time = time; for (int i = 0; i < outputs.size() && i < chances.size(); i++) { builder.output(outputs.get(i), chances.get(i)); From 17e5d27541b453be6872e32a949ef4dad3082abc Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Tue, 5 May 2026 20:33:20 +0800 Subject: [PATCH 03/11] Update railcraft_example.groovy --- examples/{ => postInit/generated}/railcraft_example.groovy | 1 + 1 file changed, 1 insertion(+) rename examples/{ => postInit/generated}/railcraft_example.groovy (99%) diff --git a/examples/railcraft_example.groovy b/examples/postInit/generated/railcraft_example.groovy similarity index 99% rename from examples/railcraft_example.groovy rename to examples/postInit/generated/railcraft_example.groovy index f30dc3814..91e70fc7c 100644 --- a/examples/railcraft_example.groovy +++ b/examples/postInit/generated/railcraft_example.groovy @@ -1,5 +1,6 @@ // Railcraft GroovyScript Example // This file demonstrates how to use the Railcraft compat features +// pls Railcraft 1.2.1.0 beta8 // ============================================ // Blast Furnace From 09cdcb966bd02fd221ae3f76bfb641e18d84ba41 Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Wed, 6 May 2026 00:06:37 +0800 Subject: [PATCH 04/11] optimize code --- .../compat/mods/railcraft/BlastFurnace.java | 15 +++++++-------- .../compat/mods/railcraft/CokeOven.java | 14 +++++++------- .../compat/mods/railcraft/RockCrusher.java | 12 ++++++------ 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java index aff0c79c6..7eb7ef94c 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java @@ -14,7 +14,6 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; -import java.util.function.ToIntFunction; @RegistryDescription public class BlastFurnace extends StandardListRegistry { @@ -46,7 +45,7 @@ public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output, int @MethodDescription(type = MethodDescription.Type.ADDITION) public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output) { - return add(input, output, 1280, 1); + return add(input, output, IBlastFurnaceCrafter.SMELT_TIME, 1); } @MethodDescription(example = @Example("item('railcraft:ingot:1')")) @@ -99,9 +98,9 @@ public void removeByInput(IIngredient input) { @Property(property = "output", comp = @Comp(eq = 1)) public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 0)) - private int time = 1280; - @Property(comp = @Comp(gte = 0)) + @Property(comp = @Comp(gte = 0), defaultValue = "IBlastFurnaceCrafter.SMELT_TIME") + private int time = IBlastFurnaceCrafter.SMELT_TIME; + @Property(comp = @Comp(gte = 0), defaultValue = "1") private int slag = 1; @RecipeBuilderMethodDescription @@ -125,7 +124,7 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 1, 1); validateFluids(msg); - if (time < 0) time = 1280; + if (time < 0) time = IBlastFurnaceCrafter.SMELT_TIME; if (slag < 0) slag = 1; } @@ -135,7 +134,7 @@ public void validate(GroovyLog.Msg msg) { if (!validate()) return null; ItemStack outputStack = output.get(0); Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); - + IBlastFurnaceCrafter.IRecipe recipe = new IBlastFurnaceCrafter.IRecipe() { @Override public net.minecraft.util.ResourceLocation getName() { @@ -162,7 +161,7 @@ public int getSlagOutput() { return slag; } }; - + ModSupport.RAILCRAFT.get().blastFurnace.add(recipe); return recipe; } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java index 599890aa0..4d86fc71f 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java @@ -41,7 +41,7 @@ public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, FluidSt @MethodDescription(type = MethodDescription.Type.ADDITION) public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, FluidStack fluidOutput) { - return add(input, output, fluidOutput, 1800); + return add(input, output, fluidOutput, ICokeOvenCrafter.DEFAULT_COOK_TIME); } @MethodDescription(type = MethodDescription.Type.ADDITION) @@ -51,7 +51,7 @@ public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, int tim @MethodDescription(type = MethodDescription.Type.ADDITION) public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output) { - return add(input, output, null, 1800); + return add(input, output, null, ICokeOvenCrafter.DEFAULT_COOK_TIME); } @MethodDescription(example = @Example("item('railcraft:fuel_coke')")) @@ -104,8 +104,8 @@ public void removeByInput(IIngredient input) { @Property(property = "output", comp = @Comp(eq = 1)) public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 0)) - private int time = 1800; + @Property(comp = @Comp(gte = 0), defaultValue = "ICokeOvenCrafter.DEFAULT_COOK_TIME") + private int time = ICokeOvenCrafter.DEFAULT_COOK_TIME; @Property private FluidStack fluid; @@ -135,7 +135,7 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 1, 1); validateFluids(msg); - if (time < 0) time = 1800; + if (time < 0) time = ICokeOvenCrafter.DEFAULT_COOK_TIME; } @Override @@ -145,7 +145,7 @@ public void validate(GroovyLog.Msg msg) { ItemStack outputStack = output.get(0); Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); FluidStack fluidCopy = fluid != null ? fluid.copy() : null; - + ICokeOvenCrafter.IRecipe recipe = new ICokeOvenCrafter.IRecipe() { @Override public net.minecraft.util.ResourceLocation getName() { @@ -172,7 +172,7 @@ public ItemStack getOutput() { return outputStack.copy(); } }; - + ModSupport.RAILCRAFT.get().cokeOven.add(recipe); return recipe; } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java index 340742e55..bf9edb278 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java @@ -51,7 +51,7 @@ public IRockCrusherCrafter.IRecipe add(IIngredient input, List output @MethodDescription(type = MethodDescription.Type.ADDITION) public IRockCrusherCrafter.IRecipe add(IIngredient input, List outputs, List chances) { - return add(input, outputs, chances, 200); + return add(input, outputs, chances, IRockCrusherCrafter.PROCESS_TIME); } @MethodDescription(example = @Example("item('minecraft:cobblestone')")) @@ -106,8 +106,8 @@ public void removeByInput(IIngredient input) { @Property(property = "input", comp = @Comp(eq = 1)) public static class RecipeBuilder extends AbstractRecipeBuilder { - @Property(comp = @Comp(gte = 0)) - private int time = 200; + @Property(comp = @Comp(gte = 0), defaultValue = "IRockCrusherCrafter.PROCESS_TIME") + private int time = IRockCrusherCrafter.PROCESS_TIME; private final List outputs = new ArrayList<>(); @RecipeBuilderMethodDescription @@ -146,7 +146,7 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 0, 0); validateFluids(msg); - if (time < 0) time = 200; + if (time < 0) time = IRockCrusherCrafter.PROCESS_TIME; if (outputs.isEmpty()) { msg.add("At least one output must be defined"); } @@ -158,7 +158,7 @@ public void validate(GroovyLog.Msg msg) { if (!validate()) return null; Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); List outputsCopy = new ArrayList<>(outputs); - + IRockCrusherCrafter.IRecipe recipe = new IRockCrusherCrafter.IRecipe() { @Override public ResourceLocation getName() { @@ -180,7 +180,7 @@ public int getTickTime(ItemStack input) { return time; } }; - + ModSupport.RAILCRAFT.get().rockCrusher.add(recipe); return recipe; } From dd77b78b436fa3e7cf6f36315d1b024caf2f2aba Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Wed, 6 May 2026 00:19:35 +0800 Subject: [PATCH 05/11] Functional and logical bug fixes --- .../compat/mods/railcraft/BlastFurnace.java | 34 ++++++++++++++---- .../compat/mods/railcraft/CokeOven.java | 22 ++++++++---- .../compat/mods/railcraft/FluidFuels.java | 33 ++++++++++------- .../compat/mods/railcraft/Railcraft.java | 18 ---------- .../compat/mods/railcraft/RockCrusher.java | 36 +++++++++++++++---- .../compat/mods/railcraft/RollingMachine.java | 4 +-- 6 files changed, 95 insertions(+), 52 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java index 7eb7ef94c..544085583 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java @@ -30,6 +30,20 @@ public Collection getRecipes() { @MethodDescription(type = MethodDescription.Type.ADDITION) public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output, int time, int slag) { + if (time <= 0) { + GroovyLog.msg("Error adding Railcraft Blast Furnace recipe") + .error() + .add("time must be greater than 0, got: {}", time) + .post(); + return null; + } + if (slag < 0) { + GroovyLog.msg("Error adding Railcraft Blast Furnace recipe") + .error() + .add("slag must be non-negative, got: {}", slag) + .post(); + return null; + } RecipeBuilder builder = recipeBuilder(); builder.input(input); builder.output(output); @@ -52,8 +66,8 @@ public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output) { public void removeByOutput(ItemStack output) { if (IngredientHelper.isEmpty(output)) { GroovyLog.msg("Error removing Railcraft Blast Furnace recipe") - .add("output must not be empty") .error() + .add("output must not be empty") .post(); return; } @@ -65,8 +79,8 @@ public void removeByOutput(ItemStack output) { return false; })) { GroovyLog.msg("Error removing Railcraft Blast Furnace recipe") - .add("no recipes found for {}", output) .error() + .add("no recipes found for {}", output) .post(); } } @@ -75,8 +89,8 @@ public void removeByOutput(ItemStack output) { public void removeByInput(IIngredient input) { if (IngredientHelper.isEmpty(input)) { GroovyLog.msg("Error removing Railcraft Blast Furnace recipe") - .add("input must not be empty") .error() + .add("input must not be empty") .post(); return; } @@ -88,8 +102,8 @@ public void removeByInput(IIngredient input) { return false; })) { GroovyLog.msg("Error removing Railcraft Blast Furnace recipe") - .add("no recipes found for {}", input) .error() + .add("no recipes found for {}", input) .post(); } } @@ -124,8 +138,14 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 1, 1); validateFluids(msg); - if (time < 0) time = IBlastFurnaceCrafter.SMELT_TIME; - if (slag < 0) slag = 1; + if (time <= 0) { + msg.add("time must be greater than 0, got: {}", time); + time = IBlastFurnaceCrafter.SMELT_TIME; + } + if (slag < 0) { + msg.add("slag must be non-negative, got: {}", slag); + slag = 1; + } } @Override @@ -133,7 +153,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable IBlastFurnaceCrafter.IRecipe register() { if (!validate()) return null; ItemStack outputStack = output.get(0); - Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); + Ingredient inputIngredient = input.get(0).toMcIngredient(); IBlastFurnaceCrafter.IRecipe recipe = new IBlastFurnaceCrafter.IRecipe() { @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java index 4d86fc71f..a320b7261 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java @@ -31,6 +31,13 @@ public Collection getRecipes() { @MethodDescription(type = MethodDescription.Type.ADDITION) public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, FluidStack fluidOutput, int time) { + if (time <= 0) { + GroovyLog.msg("Error adding Railcraft Coke Oven recipe") + .error() + .add("time must be greater than 0, got: {}", time) + .post(); + return null; + } RecipeBuilder builder = recipeBuilder(); builder.input(input); builder.output(output); @@ -58,8 +65,8 @@ public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output) { public void removeByOutput(ItemStack output) { if (IngredientHelper.isEmpty(output)) { GroovyLog.msg("Error removing Railcraft Coke Oven recipe") - .add("output must not be empty") .error() + .add("output must not be empty") .post(); return; } @@ -71,8 +78,8 @@ public void removeByOutput(ItemStack output) { return false; })) { GroovyLog.msg("Error removing Railcraft Coke Oven recipe") - .add("no recipes found for {}", output) .error() + .add("no recipes found for {}", output) .post(); } } @@ -81,8 +88,8 @@ public void removeByOutput(ItemStack output) { public void removeByInput(IIngredient input) { if (IngredientHelper.isEmpty(input)) { GroovyLog.msg("Error removing Railcraft Coke Oven recipe") - .add("input must not be empty") .error() + .add("input must not be empty") .post(); return; } @@ -94,8 +101,8 @@ public void removeByInput(IIngredient input) { return false; })) { GroovyLog.msg("Error removing Railcraft Coke Oven recipe") - .add("no recipes found for {}", input) .error() + .add("no recipes found for {}", input) .post(); } } @@ -135,7 +142,10 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 1, 1); validateFluids(msg); - if (time < 0) time = ICokeOvenCrafter.DEFAULT_COOK_TIME; + if (time <= 0) { + msg.add("time must be greater than 0, got: {}", time); + time = ICokeOvenCrafter.DEFAULT_COOK_TIME; + } } @Override @@ -143,7 +153,7 @@ public void validate(GroovyLog.Msg msg) { public @Nullable ICokeOvenCrafter.IRecipe register() { if (!validate()) return null; ItemStack outputStack = output.get(0); - Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); + Ingredient inputIngredient = input.get(0).toMcIngredient(); FluidStack fluidCopy = fluid != null ? fluid.copy() : null; ICokeOvenCrafter.IRecipe recipe = new ICokeOvenCrafter.IRecipe() { diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java index 127682148..de11664f8 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java @@ -23,21 +23,24 @@ public void onReload() { mods.railcraft.api.fuel.FluidFuelManager.addFuel(entry.fluid, entry.heatValue); } catch (Exception e) { GroovyLog.msg("Error restoring Railcraft Fluid Fuel") - .add("{}", e.getMessage()) .error() + .add("fluid: {}", entry.fluid.getFluid().getName()) + .add("heat value: {}", entry.heatValue) + .add("exception: {}", e.getMessage()) .post(); } }); // Remove scripted removeScripted().forEach(entry -> { try { - // Note: Railcraft doesn't have a direct remove method, + // Note: Railcraft doesn't have a direct remove method, // so we rely on the internal map being modified backupFuels.put(entry.fluid.getFluid().getName(), entry.heatValue); } catch (Exception e) { GroovyLog.msg("Error removing Railcraft Fluid Fuel") - .add("{}", e.getMessage()) .error() + .add("fluid: {}", entry.fluid.getFluid().getName()) + .add("exception: {}", e.getMessage()) .post(); } }); @@ -47,27 +50,30 @@ public void onReload() { public void add(FluidStack fuel, int heatValue) { if (IngredientHelper.isEmpty(fuel)) { GroovyLog.msg("Error adding Railcraft Fluid Fuel") - .add("fuel must not be empty") .error() + .add("fuel must not be empty") .post(); return; } if (heatValue <= 0) { GroovyLog.msg("Error adding Railcraft Fluid Fuel") - .add("heat value must be greater than 0") .error() + .add("fluid: {}", fuel.getFluid().getName()) + .add("heat value: {} (must be > 0)", heatValue) .post(); return; } - + addScripted(new FuelEntry(fuel.copy(), heatValue)); - + try { mods.railcraft.api.fuel.FluidFuelManager.addFuel(fuel, heatValue); } catch (Exception e) { GroovyLog.msg("Error adding Railcraft Fluid Fuel") - .add("{}", e.getMessage()) .error() + .add("fluid: {}", fuel.getFluid().getName()) + .add("heat value: {}", heatValue) + .add("exception: {}", e.getMessage()) .post(); } } @@ -81,26 +87,27 @@ public void add(FluidStack fuel) { public void remove(FluidStack fuel) { if (IngredientHelper.isEmpty(fuel)) { GroovyLog.msg("Error removing Railcraft Fluid Fuel") - .add("fuel must not be empty") .error() + .add("fuel must not be empty") .post(); return; } - + // Store current value for backup int currentValue = mods.railcraft.api.fuel.FluidFuelManager.getFuelValue(fuel); if (currentValue > 0) { addBackup(new FuelEntry(fuel.copy(), currentValue)); } - + // Note: Railcraft's FluidFuelManager doesn't have a direct remove method // We can only add with 0 heat value to effectively disable it try { mods.railcraft.api.fuel.FluidFuelManager.addFuel(fuel, 0); } catch (Exception e) { GroovyLog.msg("Error removing Railcraft Fluid Fuel") - .add("{}", e.getMessage()) .error() + .add("fluid: {}", fuel.getFluid().getName()) + .add("exception: {}", e.getMessage()) .post(); } } @@ -110,8 +117,8 @@ public void removeAll() { // Note: This is a limitation - we can't truly remove all without reflection // This method is provided for API compatibility but may not work as expected GroovyLog.msg("Warning: Railcraft FluidFuels.removeAll() may not work as expected") - .add("Railcraft doesn't provide a way to clear all fluid fuels") .warn() + .add("Railcraft doesn't provide a way to clear all fluid fuels") .post(); } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/Railcraft.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/Railcraft.java index 3c783adc5..0aa729ad8 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/Railcraft.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/Railcraft.java @@ -1,10 +1,6 @@ package com.cleanroommc.groovyscript.compat.mods.railcraft; -import com.cleanroommc.groovyscript.api.IIngredient; import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; -import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.Ingredient; public class Railcraft extends GroovyPropertyContainer { @@ -13,18 +9,4 @@ public class Railcraft extends GroovyPropertyContainer { public final RockCrusher rockCrusher = new RockCrusher(); public final RollingMachine rollingMachine = new RollingMachine(); public final FluidFuels fluidFuels = new FluidFuels(); - - /** - * Converts a GroovyScript IIngredient to a Minecraft Ingredient for Railcraft recipes - */ - public static Ingredient toIngredient(IIngredient ingredient) { - if (ingredient instanceof OreDictIngredient oreDictIngredient) { - return new net.minecraftforge.oredict.OreIngredient(oreDictIngredient.getOreDict()); - } - ItemStack[] matchingStacks = ingredient.getMatchingStacks(); - if (matchingStacks.length == 0) { - return Ingredient.EMPTY; - } - return Ingredient.fromStacks(matchingStacks); - } } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java index bf9edb278..929a10607 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java @@ -40,6 +40,27 @@ public Collection getRecipes() { @MethodDescription(type = MethodDescription.Type.ADDITION) public IRockCrusherCrafter.IRecipe add(IIngredient input, List outputs, List chances, int time) { + if (time <= 0) { + GroovyLog.msg("Error adding Railcraft Rock Crusher recipe") + .error() + .add("time must be greater than 0, got: {}", time) + .post(); + return null; + } + if (outputs == null || outputs.isEmpty()) { + GroovyLog.msg("Error adding Railcraft Rock Crusher recipe") + .error() + .add("outputs must not be empty") + .post(); + return null; + } + if (chances == null || chances.isEmpty()) { + GroovyLog.msg("Error adding Railcraft Rock Crusher recipe") + .error() + .add("chances must not be empty") + .post(); + return null; + } RecipeBuilder builder = recipeBuilder(); builder.input(input); builder.time = time; @@ -58,8 +79,8 @@ public IRockCrusherCrafter.IRecipe add(IIngredient input, List output public void removeByOutput(IIngredient output) { if (IngredientHelper.isEmpty(output)) { GroovyLog.msg("Error removing Railcraft Rock Crusher recipe") - .add("output must not be empty") .error() + .add("output must not be empty") .post(); return; } @@ -74,8 +95,8 @@ public void removeByOutput(IIngredient output) { return false; })) { GroovyLog.msg("Error removing Railcraft Rock Crusher recipe") - .add("no recipes found for {}", output) .error() + .add("no recipes found for {}", output) .post(); } } @@ -84,8 +105,8 @@ public void removeByOutput(IIngredient output) { public void removeByInput(IIngredient input) { if (IngredientHelper.isEmpty(input)) { GroovyLog.msg("Error removing Railcraft Rock Crusher recipe") - .add("input must not be empty") .error() + .add("input must not be empty") .post(); return; } @@ -97,8 +118,8 @@ public void removeByInput(IIngredient input) { return false; })) { GroovyLog.msg("Error removing Railcraft Rock Crusher recipe") - .add("no recipes found for {}", input) .error() + .add("no recipes found for {}", input) .post(); } } @@ -146,7 +167,10 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 0, 0); validateFluids(msg); - if (time < 0) time = IRockCrusherCrafter.PROCESS_TIME; + if (time <= 0) { + msg.add("time must be greater than 0, got: {}", time); + time = IRockCrusherCrafter.PROCESS_TIME; + } if (outputs.isEmpty()) { msg.add("At least one output must be defined"); } @@ -156,7 +180,7 @@ public void validate(GroovyLog.Msg msg) { @RecipeBuilderRegistrationMethod public @Nullable IRockCrusherCrafter.IRecipe register() { if (!validate()) return null; - Ingredient inputIngredient = Railcraft.toIngredient(input.get(0)); + Ingredient inputIngredient = input.get(0).toMcIngredient(); List outputsCopy = new ArrayList<>(outputs); IRockCrusherCrafter.IRecipe recipe = new IRockCrusherCrafter.IRecipe() { diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java index 3a9b71274..66d4501dc 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java @@ -220,7 +220,7 @@ public NonNullList getIngredients() { for (List row : matrix) { for (IIngredient ing : row) { if (ing != null) { - ingredients.add(Railcraft.toIngredient(ing)); + ingredients.add(ing.toMcIngredient()); } } } @@ -380,7 +380,7 @@ public ItemStack getRecipeOutput() { public NonNullList getIngredients() { NonNullList ingredients = NonNullList.create(); for (IIngredient ing : input) { - ingredients.add(Railcraft.toIngredient(ing)); + ingredients.add(ing.toMcIngredient()); } return ingredients; } From 4ab6ae25b51699576b2d9f2028035eb68f8c3dbf Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Wed, 6 May 2026 00:22:36 +0800 Subject: [PATCH 06/11] Update FluidFuels.java --- .../groovyscript/compat/mods/railcraft/FluidFuels.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java index de11664f8..002d5a8be 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java @@ -4,12 +4,15 @@ import com.cleanroommc.groovyscript.api.documentation.annotations.*; import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import mods.railcraft.api.fuel.FluidFuelManager; import net.minecraftforge.fluids.FluidStack; import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; + + @RegistryDescription public class FluidFuels extends VirtualizedRegistry { @@ -20,7 +23,7 @@ public void onReload() { // Restore from backup restoreFromBackup().forEach(entry -> { try { - mods.railcraft.api.fuel.FluidFuelManager.addFuel(entry.fluid, entry.heatValue); + FluidFuelManager.addFuel(entry.fluid, entry.heatValue); } catch (Exception e) { GroovyLog.msg("Error restoring Railcraft Fluid Fuel") .error() @@ -67,7 +70,7 @@ public void add(FluidStack fuel, int heatValue) { addScripted(new FuelEntry(fuel.copy(), heatValue)); try { - mods.railcraft.api.fuel.FluidFuelManager.addFuel(fuel, heatValue); + FluidFuelManager.addFuel(fuel, heatValue); } catch (Exception e) { GroovyLog.msg("Error adding Railcraft Fluid Fuel") .error() @@ -102,7 +105,7 @@ public void remove(FluidStack fuel) { // Note: Railcraft's FluidFuelManager doesn't have a direct remove method // We can only add with 0 heat value to effectively disable it try { - mods.railcraft.api.fuel.FluidFuelManager.addFuel(fuel, 0); + FluidFuelManager.addFuel(fuel, 0); } catch (Exception e) { GroovyLog.msg("Error removing Railcraft Fluid Fuel") .error() From 99933e7969f7176f013df67a80f68506467d93b5 Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Wed, 6 May 2026 00:26:12 +0800 Subject: [PATCH 07/11] Update FluidFuels.java --- .../compat/mods/railcraft/FluidFuels.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java index 002d5a8be..c531eecc3 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java @@ -20,29 +20,29 @@ public class FluidFuels extends VirtualizedRegistry { @Override public void onReload() { - // Restore from backup - restoreFromBackup().forEach(entry -> { + // Remove scripted (disable them by setting heat to 0) + removeScripted().forEach(entry -> { try { - FluidFuelManager.addFuel(entry.fluid, entry.heatValue); + // Disable the fuel by setting heat value to 0 + FluidFuelManager.addFuel(entry.fluid, 0); } catch (Exception e) { - GroovyLog.msg("Error restoring Railcraft Fluid Fuel") + GroovyLog.msg("Error removing Railcraft Fluid Fuel") .error() .add("fluid: {}", entry.fluid.getFluid().getName()) - .add("heat value: {}", entry.heatValue) .add("exception: {}", e.getMessage()) .post(); } }); - // Remove scripted - removeScripted().forEach(entry -> { + + // Restore from backup + restoreFromBackup().forEach(entry -> { try { - // Note: Railcraft doesn't have a direct remove method, - // so we rely on the internal map being modified - backupFuels.put(entry.fluid.getFluid().getName(), entry.heatValue); + FluidFuelManager.addFuel(entry.fluid, entry.heatValue); } catch (Exception e) { - GroovyLog.msg("Error removing Railcraft Fluid Fuel") + GroovyLog.msg("Error restoring Railcraft Fluid Fuel") .error() .add("fluid: {}", entry.fluid.getFluid().getName()) + .add("heat value: {}", entry.heatValue) .add("exception: {}", e.getMessage()) .post(); } @@ -67,6 +67,12 @@ public void add(FluidStack fuel, int heatValue) { return; } + // Store the original value for backup before adding + int originalValue = FluidFuelManager.getFuelValue(fuel); + if (originalValue > 0) { + addBackup(new FuelEntry(fuel.copy(), originalValue)); + } + addScripted(new FuelEntry(fuel.copy(), heatValue)); try { @@ -97,7 +103,7 @@ public void remove(FluidStack fuel) { } // Store current value for backup - int currentValue = mods.railcraft.api.fuel.FluidFuelManager.getFuelValue(fuel); + int currentValue = FluidFuelManager.getFuelValue(fuel); if (currentValue > 0) { addBackup(new FuelEntry(fuel.copy(), currentValue)); } From 84d43bb9dc5b9c69a745ffa1b720ff20d02f859b Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Wed, 6 May 2026 00:38:20 +0800 Subject: [PATCH 08/11] Update buildscript.properties --- buildscript.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildscript.properties b/buildscript.properties index af2098305..adb552127 100644 --- a/buildscript.properties +++ b/buildscript.properties @@ -16,7 +16,7 @@ modGroup = com.cleanroommc.groovyscript # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 1.4.3 +modVersion = 1.4.4 # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = false From e6ff65d5d6b69d797745ad2d158652f3890f2a11 Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Wed, 6 May 2026 08:49:41 +0800 Subject: [PATCH 09/11] optimize code --- buildscript.properties | 2 +- .../compat/mods/railcraft/BlastFurnace.java | 24 ++------------- .../compat/mods/railcraft/CokeOven.java | 30 +++++-------------- .../compat/mods/railcraft/FluidFuels.java | 7 ----- .../compat/mods/railcraft/RollingMachine.java | 9 ++---- 5 files changed, 12 insertions(+), 60 deletions(-) diff --git a/buildscript.properties b/buildscript.properties index adb552127..af2098305 100644 --- a/buildscript.properties +++ b/buildscript.properties @@ -16,7 +16,7 @@ modGroup = com.cleanroommc.groovyscript # Version of your mod. # This field can be left empty if you want your mod's version to be determined by the latest git tag instead. -modVersion = 1.4.4 +modVersion = 1.4.3 # Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version) includeMCVersionJar = false diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java index 544085583..f10f4de2a 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java @@ -30,20 +30,6 @@ public Collection getRecipes() { @MethodDescription(type = MethodDescription.Type.ADDITION) public IBlastFurnaceCrafter.IRecipe add(IIngredient input, ItemStack output, int time, int slag) { - if (time <= 0) { - GroovyLog.msg("Error adding Railcraft Blast Furnace recipe") - .error() - .add("time must be greater than 0, got: {}", time) - .post(); - return null; - } - if (slag < 0) { - GroovyLog.msg("Error adding Railcraft Blast Furnace recipe") - .error() - .add("slag must be non-negative, got: {}", slag) - .post(); - return null; - } RecipeBuilder builder = recipeBuilder(); builder.input(input); builder.output(output); @@ -138,14 +124,8 @@ public String getErrorMsg() { public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 1, 1); validateFluids(msg); - if (time <= 0) { - msg.add("time must be greater than 0, got: {}", time); - time = IBlastFurnaceCrafter.SMELT_TIME; - } - if (slag < 0) { - msg.add("slag must be non-negative, got: {}", slag); - slag = 1; - } + msg.add(time <= 0, "time must be greater than 0, got: {}", time); + msg.add(slag < 0, "slag must be non-negative, got: {}", slag); } @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java index a320b7261..85cd61c42 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java @@ -19,7 +19,7 @@ @RegistryDescription public class CokeOven extends StandardListRegistry { - @RecipeBuilderDescription(example = @Example(".input(item('minecraft:log')).output(item('railcraft:fuel_coke')).fluid(fluid('creosote') * 500).time(1800)")) + @RecipeBuilderDescription(example = @Example(".input(item('minecraft:log')).output(item('railcraft:fuel_coke')).fluidOutput(fluid('creosote') * 500).time(1800)")) public static RecipeBuilder recipeBuilder() { return new RecipeBuilder(); } @@ -31,17 +31,12 @@ public Collection getRecipes() { @MethodDescription(type = MethodDescription.Type.ADDITION) public ICokeOvenCrafter.IRecipe add(IIngredient input, ItemStack output, FluidStack fluidOutput, int time) { - if (time <= 0) { - GroovyLog.msg("Error adding Railcraft Coke Oven recipe") - .error() - .add("time must be greater than 0, got: {}", time) - .post(); - return null; - } RecipeBuilder builder = recipeBuilder(); builder.input(input); builder.output(output); - builder.fluid = fluidOutput; + if (fluidOutput != null) { + builder.fluidOutput(fluidOutput); + } builder.time = time; return builder.register(); } @@ -113,8 +108,6 @@ public static class RecipeBuilder extends AbstractRecipeBuilder { - private final Map backupFuels = new HashMap<>(); - @Override public void onReload() { // Remove scripted (disable them by setting heat to 0) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java index 66d4501dc..06a0722fe 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java @@ -106,13 +106,8 @@ public boolean remove(ResourceLocation key) { } public boolean remove(IRollingMachineCrafter.IRollingRecipe recipe) { - return Crafters.rollingMachine().getRecipes().removeIf(r -> { - if (r == recipe) { - addBackup(Pair.of(r.getRegistryName(), r)); - return true; - } - return false; - }); + addBackup(Pair.of(recipe.getRegistryName(), recipe)); + return Crafters.rollingMachine().getRecipes().remove(recipe); } @MethodDescription(type = MethodDescription.Type.QUERY) From 4e9ccdd3a56d84176a1b16cb073f9fc00ecb4984 Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Wed, 6 May 2026 09:47:41 +0800 Subject: [PATCH 10/11] code --- .../groovyscript/compat/mods/railcraft/BlastFurnace.java | 1 + .../groovyscript/compat/mods/railcraft/CokeOven.java | 3 ++- .../groovyscript/compat/mods/railcraft/FluidFuels.java | 6 +++--- .../groovyscript/compat/mods/railcraft/RockCrusher.java | 3 +++ .../groovyscript/compat/mods/railcraft/RollingMachine.java | 7 ++++++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java index f10f4de2a..a2f698356 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/BlastFurnace.java @@ -136,6 +136,7 @@ public void validate(GroovyLog.Msg msg) { Ingredient inputIngredient = input.get(0).toMcIngredient(); IBlastFurnaceCrafter.IRecipe recipe = new IBlastFurnaceCrafter.IRecipe() { + @Override public net.minecraft.util.ResourceLocation getName() { return new net.minecraft.util.ResourceLocation("groovyscript", "blastfurnace_" + System.currentTimeMillis()); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java index 85cd61c42..bd1156a12 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/CokeOven.java @@ -128,7 +128,7 @@ public String getErrorMsg() { @Override public void validate(GroovyLog.Msg msg) { validateItems(msg, 1, 1, 1, 1); - validateFluids(msg, 0, 1, 0, 1); + validateFluids(msg, 0, 0, 0, 1); msg.add(time <= 0, "time must be greater than 0, got: {}", time); } @@ -141,6 +141,7 @@ public void validate(GroovyLog.Msg msg) { FluidStack fluidCopy = fluidOutput.isEmpty() ? null : fluidOutput.get(0).copy(); ICokeOvenCrafter.IRecipe recipe = new ICokeOvenCrafter.IRecipe() { + @Override public net.minecraft.util.ResourceLocation getName() { return new net.minecraft.util.ResourceLocation("groovyscript", "cokeoven_" + System.currentTimeMillis()); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java index 49b3d7981..74adf46b3 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/FluidFuels.java @@ -6,7 +6,6 @@ import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; import mods.railcraft.api.fuel.FluidFuelManager; import net.minecraftforge.fluids.FluidStack; -import org.jetbrains.annotations.Nullable; @RegistryDescription public class FluidFuels extends VirtualizedRegistry { @@ -26,7 +25,7 @@ public void onReload() { .post(); } }); - + // Restore from backup restoreFromBackup().forEach(entry -> { try { @@ -65,7 +64,7 @@ public void add(FluidStack fuel, int heatValue) { if (originalValue > 0) { addBackup(new FuelEntry(fuel.copy(), originalValue)); } - + addScripted(new FuelEntry(fuel.copy(), heatValue)); try { @@ -125,6 +124,7 @@ public void removeAll() { } public static class FuelEntry { + public final FluidStack fluid; public final int heatValue; diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java index 929a10607..01818c64a 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RockCrusher.java @@ -184,6 +184,7 @@ public void validate(GroovyLog.Msg msg) { List outputsCopy = new ArrayList<>(outputs); IRockCrusherCrafter.IRecipe recipe = new IRockCrusherCrafter.IRecipe() { + @Override public ResourceLocation getName() { return new ResourceLocation("groovyscript", "rockcrusher_" + System.currentTimeMillis()); @@ -211,6 +212,7 @@ public int getTickTime(ItemStack input) { } private static class RandomChanceGenRule implements IGenRule { + private final float randomChance; private List toolTip; @@ -233,6 +235,7 @@ public List getToolTip() { } private static class OutputEntry implements IOutputEntry { + private final ItemStack output; private final IGenRule genRule; diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java index 06a0722fe..64751d2c3 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/railcraft/RollingMachine.java @@ -5,7 +5,6 @@ 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.IngredientHelper; import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; import mods.railcraft.api.crafting.Crafters; import mods.railcraft.api.crafting.IRollingMachineCrafter; @@ -122,6 +121,7 @@ public void removeAll() { } public static class ShapedRecipeBuilder { + private ItemStack output; private List> matrix; private int time = 200; @@ -188,6 +188,7 @@ public IRollingMachineCrafter.IRollingRecipe register() { ResourceLocation name = new ResourceLocation("groovyscript", "rolling_shaped_" + System.currentTimeMillis()); IRecipe recipe = new IRecipe() { + @Override public boolean matches(InventoryCrafting inv, World worldIn) { // Simple matching logic @@ -239,6 +240,7 @@ public Class getRegistryType() { }; IRollingMachineCrafter.IRollingRecipe rollingRecipe = new IRollingMachineCrafter.IRollingRecipe() { + @Override public int getTickTime() { return finalTime; @@ -305,6 +307,7 @@ public Class getRegistryType() { } public static class ShapelessRecipeBuilder { + private ItemStack output; private List input = new ArrayList<>(); private int time = 200; @@ -351,6 +354,7 @@ public IRollingMachineCrafter.IRollingRecipe register() { ResourceLocation name = new ResourceLocation("groovyscript", "rolling_shapeless_" + System.currentTimeMillis()); IRecipe recipe = new IRecipe() { + @Override public boolean matches(InventoryCrafting inv, World worldIn) { return false; @@ -397,6 +401,7 @@ public Class getRegistryType() { }; IRollingMachineCrafter.IRollingRecipe rollingRecipe = new IRollingMachineCrafter.IRollingRecipe() { + @Override public int getTickTime() { return finalTime; From f87af5659f9805c66852a1d0163d9504d136b49d Mon Sep 17 00:00:00 2001 From: Lonelyxiya <3438505487@qq.com> Date: Wed, 6 May 2026 10:15:38 +0800 Subject: [PATCH 11/11] huh --- .../generated/railcraft_example.groovy | 141 ------------------ .../generated/railcraft_generated.groovy | 92 ++++++++++++ 2 files changed, 92 insertions(+), 141 deletions(-) delete mode 100644 examples/postInit/generated/railcraft_example.groovy create mode 100644 examples/postInit/generated/railcraft_generated.groovy diff --git a/examples/postInit/generated/railcraft_example.groovy b/examples/postInit/generated/railcraft_example.groovy deleted file mode 100644 index 91e70fc7c..000000000 --- a/examples/postInit/generated/railcraft_example.groovy +++ /dev/null @@ -1,141 +0,0 @@ -// Railcraft GroovyScript Example -// This file demonstrates how to use the Railcraft compat features -// pls Railcraft 1.2.1.0 beta8 - -// ============================================ -// Blast Furnace -// ============================================ - -// Add a recipe: input, output, time (ticks), slag amount -mods.railcraft.blastFurnace.add(item('minecraft:iron_ingot'), item('railcraft:ingot:1'), 1280, 1) - -// Add with default time (1280 ticks) and slag (1) -mods.railcraft.blastFurnace.add(item('minecraft:iron_block'), item('railcraft:ingot:1') * 9) - -// Using recipe builder -mods.railcraft.blastFurnace.recipeBuilder() - .input(item('minecraft:gold_ingot')) - .output(item('railcraft:ingot:2')) - .time(1000) - .slag(2) - .register() - -// Remove by output -mods.railcraft.blastFurnace.removeByOutput(item('railcraft:ingot:1')) - -// Remove by input -mods.railcraft.blastFurnace.removeByInput(item('minecraft:iron_ingot')) - -// Remove all -mods.railcraft.blastFurnace.removeAll() - - -// ============================================ -// Coke Oven -// ============================================ - -// Add a recipe: input, output, fluid output, time (ticks) -mods.railcraft.cokeOven.add(item('minecraft:log'), item('railcraft:fuel_coke'), fluid('creosote') * 500, 1800) - -// Add with item output only -mods.railcraft.cokeOven.add(item('minecraft:log:1'), item('railcraft:fuel_coke'), 1800) - -// Using recipe builder -mods.railcraft.cokeOven.recipeBuilder() - .input(item('minecraft:coal')) - .output(item('railcraft:fuel_coke')) - .fluid(fluid('creosote') * 1000) - .time(2000) - .register() - -// Remove by output -mods.railcraft.cokeOven.removeByOutput(item('railcraft:fuel_coke')) - -// Remove by input -mods.railcraft.cokeOven.removeByInput(item('minecraft:log')) - -// Remove all -mods.railcraft.cokeOven.removeAll() - - -// ============================================ -// Rock Crusher -// ============================================ - -// Add a recipe with multiple outputs and chances -mods.railcraft.rockCrusher.recipeBuilder() - .input(item('minecraft:stone')) - .output(item('minecraft:cobblestone'), 1.0f) - .output(item('minecraft:sand'), 0.5f) - .output(item('minecraft:gravel'), 0.25f) - .time(200) - .register() - -// Remove by output -mods.railcraft.rockCrusher.removeByOutput(item('minecraft:cobblestone')) - -// Remove by input -mods.railcraft.rockCrusher.removeByInput(item('minecraft:stone')) - -// Remove all -mods.railcraft.rockCrusher.removeAll() - - -// ============================================ -// Rolling Machine -// ============================================ - -// Add shaped recipe -mods.railcraft.rollingMachine.addShaped( - item('minecraft:iron_bars') * 8, - [ - [item('minecraft:iron_ingot'), item('minecraft:iron_ingot'), item('minecraft:iron_ingot')], - [item('minecraft:iron_ingot'), item('minecraft:iron_ingot'), item('minecraft:iron_ingot')] - ], - 200 -) - -// Add shapeless recipe -mods.railcraft.rollingMachine.addShapeless( - item('minecraft:iron_ingot') * 9, - [item('minecraft:iron_block')], - 100 -) - -// Using shaped builder -mods.railcraft.rollingMachine.shapedBuilder() - .output(item('minecraft:rail') * 16) - .matrix('I I', 'I I', 'I I') - .key('I', item('minecraft:iron_ingot')) - .time(100) - .register() - -// Using shapeless builder -mods.railcraft.rollingMachine.shapelessBuilder() - .output(item('minecraft:iron_nugget') * 9) - .input(item('minecraft:iron_ingot')) - .time(50) - .register() - -// Remove by output -mods.railcraft.rollingMachine.removeByOutput(item('minecraft:rail')) - -// Remove all -mods.railcraft.rollingMachine.removeAll() - - -// ============================================ -// Fluid Fuels (for Boilers) -// ============================================ - -// Add a fluid fuel with heat value -mods.railcraft.fluidFuels.add(fluid('lava'), 32000) - -// Add with default heat value -mods.railcraft.fluidFuels.add(fluid('oil')) - -// Remove a fluid fuel -mods.railcraft.fluidFuels.remove(fluid('creosote')) - -// Remove all -mods.railcraft.fluidFuels.removeAll() diff --git a/examples/postInit/generated/railcraft_generated.groovy b/examples/postInit/generated/railcraft_generated.groovy new file mode 100644 index 000000000..35bea5f93 --- /dev/null +++ b/examples/postInit/generated/railcraft_generated.groovy @@ -0,0 +1,92 @@ + +// Auto generated groovyscript example file +// MODS_LOADED: railcraft + +log 'mod \'railcraft\' detected, running script' + +// groovyscript.wiki.railcraft.blast_furnace.title: +// groovyscript.wiki.railcraft.blast_furnace.description. + +mods.railcraft.blast_furnace.removeByInput(item('minecraft:iron_ingot')) +mods.railcraft.blast_furnace.removeByOutput(item('railcraft:ingot:1')) +// mods.railcraft.blast_furnace.removeAll() + +mods.railcraft.blast_furnace.recipeBuilder() + .input(item('minecraft:iron_ingot')) + .output(item('railcraft:ingot:1')) + .time(1280) + .slag(1) + .register() + + +// groovyscript.wiki.railcraft.coke_oven.title: +// groovyscript.wiki.railcraft.coke_oven.description. + +mods.railcraft.coke_oven.removeByInput(item('minecraft:log')) +mods.railcraft.coke_oven.removeByOutput(item('railcraft:fuel_coke')) +// mods.railcraft.coke_oven.removeAll() + +mods.railcraft.coke_oven.recipeBuilder() + .input(item('minecraft:log')) + .output(item('railcraft:fuel_coke')) + .fluidOutput(fluid('creosote') * 500) + .time(1800) + .register() + + +// groovyscript.wiki.railcraft.fluid_fuels.title: +// groovyscript.wiki.railcraft.fluid_fuels.description. + +mods.railcraft.fluid_fuels.remove(fluid('creosote')) +// mods.railcraft.fluid_fuels.removeAll() + +mods.railcraft.fluid_fuels.add(fluid('lava'), 32000) + +// groovyscript.wiki.railcraft.rock_crusher.title: +// groovyscript.wiki.railcraft.rock_crusher.description. + +mods.railcraft.rock_crusher.removeByInput(item('minecraft:stone')) +mods.railcraft.rock_crusher.removeByOutput(item('minecraft:cobblestone')) +// mods.railcraft.rock_crusher.removeAll() + +mods.railcraft.rock_crusher.recipeBuilder() + .input(item('minecraft:stone')) + .output(item('minecraft:cobblestone'), 1.0) + .output(item('minecraft:sand'), 0.5) + .time(200) + .register() + + +// groovyscript.wiki.railcraft.rolling_machine.title: +// groovyscript.wiki.railcraft.rolling_machine.description. + +mods.railcraft.rolling_machine.removeByOutput(item('minecraft:tripwire_hook')) +// mods.railcraft.rolling_machine.removeAll() + +mods.railcraft.rolling_machine.shapedBuilder() + .output(item('minecraft:stone')) + .matrix('BXX', + 'X B') + .key('B', item('minecraft:stone')) + .key('X', item('minecraft:gold_ingot')) + .time(200) + + +mods.railcraft.rolling_machine.shapedBuilder() + .output(item('minecraft:diamond') * 32) + .matrix([[item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')], + [item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')], + [item('minecraft:gold_ingot'), item('minecraft:gold_ingot'), item('minecraft:gold_ingot')]]) + .time(400) + + +mods.railcraft.rolling_machine.shapelessBuilder() + .output(item('minecraft:clay') * 8) + .input(item('minecraft:stone'), item('minecraft:stone'), item('minecraft:stone')) + .time(100) + + +mods.railcraft.rolling_machine.shapelessBuilder() + .output(item('minecraft:diamond') * 32) + .input(item('minecraft:gold_ingot') * 9) + .time(500)