diff --git a/dependencies.gradle b/dependencies.gradle index f81f40aeb..848a12f2f 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -76,6 +76,7 @@ final def mod_dependencies = [ 'mekanism-268560:2835175' : [project.debug_mekanism], 'natures-aura-306626:2882138' : [project.debug_natures_aura], 'packmode-278398:2567799' : [project.debug_packmode], + 'pneumaticcraft-repressurized-281849:2978408' : [project.debug_pneumaticcraft], 'projecte-226410:2702991' : [project.debug_projecte], 'athenaeum-284350:4633750' : [project.debug_pyrotech], 'pyrotech-306676:4956838' : [project.debug_pyrotech], diff --git a/examples/postInit/loottables.groovy b/examples/postInit/loottables.groovy index 621cae3ed..51c47b97c 100644 --- a/examples/postInit/loottables.groovy +++ b/examples/postInit/loottables.groovy @@ -1,5 +1,6 @@ import com.cleanroommc.groovyscript.event.LootTablesLoadedEvent +import net.minecraft.world.storage.loot.LootContext event_manager.listen { LootTablesLoadedEvent event -> patchStrongholdLibraryLT(event) @@ -19,7 +20,7 @@ def patchStrongholdLibraryLT(event) { .quality(1) .build() ) - event.loot.printEntries('minecraft:chests/stronghold_library', 'main') +// event.loot.printEntries('minecraft:chests/stronghold_library', 'main') } def patchChickenLT(event) { @@ -30,7 +31,7 @@ def patchChickenLT(event) { .entry( event.loot.entryBuilder() .item(item('minecraft:diamond')) - .function{ stack, random, context -> + .function{ ItemStack stack, Random random, LootContext context -> stack.setCount(10) return stack } @@ -38,7 +39,7 @@ def patchChickenLT(event) { .quality(1) .build() ) - .condition{ random, context -> random.nextFloat() < 0.05f } + .condition{ Random random, LootContext context -> random.nextFloat() < 0.05f } .rollsRange(1.0f, 3.0f) .bonusRollsRange(0.0f, 0.0f) .build() diff --git a/examples/postInit/pneumaticcraft.groovy b/examples/postInit/pneumaticcraft.groovy new file mode 100644 index 000000000..cd325f03e --- /dev/null +++ b/examples/postInit/pneumaticcraft.groovy @@ -0,0 +1,215 @@ + +// Auto generated groovyscript example file +// MODS_LOADED: pneumaticcraft + +println 'mod \'pneumaticcraft\' detected, running script' + +// Amadron: +// Uses an Amadron Tablet and linked inventories in world to trade via drones. + +mods.pneumaticcraft.amadron.removeByInput(item('minecraft:rotten_flesh')) +mods.pneumaticcraft.amadron.removeByOutput(item('minecraft:emerald')) +// mods.pneumaticcraft.amadron.removeAll() +// mods.pneumaticcraft.amadron.removeAllPeriodic() +// mods.pneumaticcraft.amadron.removeAllStatic() + +mods.pneumaticcraft.amadron.recipeBuilder() + .input(item('minecraft:clay') * 3) + .output(item('minecraft:gold_ingot')) + .register() + +mods.pneumaticcraft.amadron.recipeBuilder() + .fluidInput(fluid('water') * 50) + .output(item('minecraft:clay') * 3) + .register() + +mods.pneumaticcraft.amadron.recipeBuilder() + .fluidInput(fluid('water') * 50) + .fluidOutput(fluid('lava') * 10) + .periodic() + .register() + + +// Assembly Controller: +// Uses a given Program to convert an input itemstack into an output itemstack. Drill recipes that output an itemstack used +// for the input itemstack of a Laser recipe can be chained via the Drill & Laser Program. + +mods.pneumaticcraft.assembly_controller.removeByInput(item('minecraft:redstone')) +mods.pneumaticcraft.assembly_controller.removeByOutput(item('pneumaticcraft:pressure_chamber_valve')) +// mods.pneumaticcraft.assembly_controller.removeAll() +// mods.pneumaticcraft.assembly_controller.removeAllDrill() +// mods.pneumaticcraft.assembly_controller.removeAllLaser() + +mods.pneumaticcraft.assembly_controller.recipeBuilder() + .input(item('minecraft:clay') * 3) + .output(item('minecraft:gold_ingot') * 6) + .drill() + .register() + +mods.pneumaticcraft.assembly_controller.recipeBuilder() + .input(item('minecraft:gold_ingot') * 6) + .output(item('minecraft:diamond')) + .laser() + .register() + +mods.pneumaticcraft.assembly_controller.recipeBuilder() + .input(item('minecraft:stone')) + .output(item('minecraft:clay') * 5) + .laser() + .register() + + +// Explosion: +// Converts an input item into an output item, with a chance to fail and destroy the item. + +// mods.pneumaticcraft.explosion.removeByInput(item('minecraft:iron_block')) +mods.pneumaticcraft.explosion.removeByOutput(item('pneumaticcraft:compressed_iron_block')) +// mods.pneumaticcraft.explosion.removeAll() + +mods.pneumaticcraft.explosion.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:gold_ingot')) + .lossRate(40) + .register() + +mods.pneumaticcraft.explosion.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:obsidian')) + .register() + + +// Heat Frame Cooling: +// Converts an input itemstack into an output itemstack when inside an inventory placed within a Heat Frame which is +// cooled. + +mods.pneumaticcraft.heat_frame_cooling.removeByInput(item('minecraft:water_bucket')) +mods.pneumaticcraft.heat_frame_cooling.removeByOutput(item('minecraft:obsidian')) +// mods.pneumaticcraft.heat_frame_cooling.removeAll() + +mods.pneumaticcraft.heat_frame_cooling.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:gold_ingot')) + .register() + +mods.pneumaticcraft.heat_frame_cooling.recipeBuilder() + .input(item('minecraft:diamond')) + .output(item('minecraft:obsidian')) + .register() + + +// Liquid Fuel: +// Converts fluid into Pressure in a Liquid Compressor. + +mods.pneumaticcraft.liquid_fuel.remove(fluid('lava')) +// mods.pneumaticcraft.liquid_fuel.removeAll() + +mods.pneumaticcraft.liquid_fuel.recipeBuilder() + .fluidInput(fluid('water')) + .pressure(100_000_000) + .register() + + + +// Plastic Mixer: +// Converts a fluidstack and an item with a variable damage value into each other, requiring temperature to operate the +// process, optionally consuming dye, and allowing either only melting or only solidifying. + +// mods.pneumaticcraft.plastic_mixer.removeByFluid(fluid('plastic')) +// mods.pneumaticcraft.plastic_mixer.removeByItem(item('pneumaticcraft:plastic')) +// mods.pneumaticcraft.plastic_mixer.removeAll() + +mods.pneumaticcraft.plastic_mixer.recipeBuilder() + .fluidInput(fluid('lava') * 100) + .output(item('minecraft:clay')) + .allowMelting() + .allowSolidifying() + .requiredTemperature(323) + .register() + +mods.pneumaticcraft.plastic_mixer.recipeBuilder() + .fluidInput(fluid('water') * 50) + .output(item('minecraft:sapling')) + .allowSolidifying() + .requiredTemperature(298) + .meta(-1) + .register() + + +// Pressure Chamber: +// Converts any number of input itemstacks into any number of output itemstacks, either generating Pressure or consuming +// Pressure from the Pressure Chamber. + +mods.pneumaticcraft.pressure_chamber.removeByInput(item('minecraft:iron_block')) +mods.pneumaticcraft.pressure_chamber.removeByOutput(item('minecraft:diamond')) +// mods.pneumaticcraft.pressure_chamber.removeAll() + +mods.pneumaticcraft.pressure_chamber.recipeBuilder() + .input(item('minecraft:clay') * 3) + .output(item('minecraft:gold_ingot')) + .pressure(4) + .register() + +mods.pneumaticcraft.pressure_chamber.recipeBuilder() + .input(item('minecraft:clay'), item('minecraft:gold_ingot'), item('minecraft:gold_block'), item('minecraft:gold_nugget'), item('minecraft:diamond'), item('minecraft:diamond_block'), item('minecraft:obsidian'), item('minecraft:stone'), item('minecraft:stone:1'), item('minecraft:stone:2'), item('minecraft:stone:3'), item('minecraft:stone:4'), item('minecraft:stone:5'), item('minecraft:stone:6')) + .output(item('minecraft:cobblestone')) + .pressure(4) + .register() + + +// Refinery: +// Converts an input fluidstack into between 2 and 4 fluidstacks, consuming Temperature, with the number of fluidstacks +// output depending on the recipe and the number of Refineries vertically stacked. + +// mods.pneumaticcraft.refinery.removeByInput(fluid('oil')) +mods.pneumaticcraft.refinery.removeByOutput(fluid('kerosene')) +// mods.pneumaticcraft.refinery.removeAll() + +mods.pneumaticcraft.refinery.recipeBuilder() + .fluidInput(fluid('water') * 1000) + .fluidOutput(fluid('lava') * 750, fluid('lava') * 250, fluid('lava') * 100, fluid('lava') * 50) + .register() + +mods.pneumaticcraft.refinery.recipeBuilder() + .fluidInput(fluid('lava') * 100) + .fluidOutput(fluid('water') * 50, fluid('kerosene') * 25) + .register() + + +// Thermopneumatic Processing Plant: +// Converts an input fluidstack into an output fluidstack, consuming Pressure and Temperature, with an optional itemstack +// being consumed. + +mods.pneumaticcraft.thermopneumatic_processing_plant.removeByInput(fluid('diesel')) +mods.pneumaticcraft.thermopneumatic_processing_plant.removeByInput(item('minecraft:coal')) +mods.pneumaticcraft.thermopneumatic_processing_plant.removeByOutput(fluid('lpg')) +// mods.pneumaticcraft.thermopneumatic_processing_plant.removeAll() + +mods.pneumaticcraft.thermopneumatic_processing_plant.recipeBuilder() + .input(item('minecraft:clay') * 3) + .fluidInput(fluid('water') * 100) + .fluidOutput(fluid('kerosene') * 100) + .pressure(4) + .requiredTemperature(323) + .register() + +mods.pneumaticcraft.thermopneumatic_processing_plant.recipeBuilder() + .fluidInput(fluid('water') * 100) + .fluidOutput(fluid('lava') * 100) + .pressure(4) + .requiredTemperature(323) + .register() + + +// XP Fluid: +// Controls what fluids are considered XP Fluids and how much experience they provide. + +// mods.pneumaticcraft.xp_fluid.remove(fluid('xpjuice')) +// mods.pneumaticcraft.xp_fluid.removeAll() + +mods.pneumaticcraft.xp_fluid.recipeBuilder() + .fluidInput(fluid('lava')) + .ratio(5) + .register() + + + diff --git a/examples/postInit/vanilla.groovy b/examples/postInit/vanilla.groovy index 0132f644b..d0444e27e 100644 --- a/examples/postInit/vanilla.groovy +++ b/examples/postInit/vanilla.groovy @@ -5,6 +5,7 @@ import net.minecraftforge.event.entity.living.EnderTeleportEvent import net.minecraftforge.event.world.BlockEvent import net.minecraft.util.text.TextComponentString +/* def ore_iron = ore('ingotIron') def item_iron = item('minecraft:iron_ingot') log.info(item_iron in ore_iron) // true @@ -14,6 +15,7 @@ log.info(item_iron << ore_iron) // true log.info((item_iron * 3) << ore_iron) // false log.info(ore_iron >> item_iron) // true log.info(ore_iron >> (item_iron * 3)) // false +*/ /*file('config/').eachFile { file -> println file.path diff --git a/gradle.properties b/gradle.properties index 4a2984bf6..89cf12b65 100644 --- a/gradle.properties +++ b/gradle.properties @@ -43,6 +43,7 @@ debug_lazy_ae2 = false debug_mekanism = false debug_natures_aura = false debug_packmode = false +debug_pneumaticcraft = false debug_prodigytech = false debug_projecte = false debug_pyrotech = 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 1c010bdf9..2598d864b 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -33,6 +33,7 @@ import com.cleanroommc.groovyscript.compat.mods.lazyae2.LazyAE2; import com.cleanroommc.groovyscript.compat.mods.mekanism.Mekanism; import com.cleanroommc.groovyscript.compat.mods.naturesaura.NaturesAura; +import com.cleanroommc.groovyscript.compat.mods.pneumaticcraft.PneumaticCraft; import com.cleanroommc.groovyscript.compat.mods.prodigytech.ProdigyTech; import com.cleanroommc.groovyscript.compat.mods.projecte.ProjectE; import com.cleanroommc.groovyscript.compat.mods.pyrotech.PyroTech; @@ -95,6 +96,7 @@ public class ModSupport { public static final GroovyContainer MEKANISM = new InternalModContainer<>("mekanism", "Mekanism", Mekanism::new); public static final GroovyContainer LAZYAE2 = new InternalModContainer<>("threng", "LazyAE2", LazyAE2::new, "lazyae2"); public static final GroovyContainer NATURES_AURA = new InternalModContainer<>("naturesaura", "Nature's Aura", NaturesAura::new); + public static final GroovyContainer PNEUMATIC_CRAFT = new InternalModContainer<>("pneumaticcraft", "PneumaticCraft: Repressurized", PneumaticCraft::new); 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); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Amadron.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Amadron.java new file mode 100644 index 000000000..d687b464a --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Amadron.java @@ -0,0 +1,197 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.AbstractReloadableStorage; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.common.recipes.AmadronOffer; +import me.desht.pneumaticcraft.common.recipes.AmadronOfferManager; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +@RegistryDescription( + admonition = @Admonition(value = "groovyscript.wiki.pneumaticcraft.amadron.note0", type = Admonition.Type.WARNING) +) +public class Amadron extends VirtualizedRegistry { + + private final AbstractReloadableStorage periodicStorage = new AbstractReloadableStorage<>(); + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay') * 3).output(item('minecraft:gold_ingot'))"), + @Example(".fluidInput(fluid('water') * 50).output(item('minecraft:clay') * 3)"), + @Example(".fluidInput(fluid('water') * 50).fluidOutput(fluid('lava') * 10).periodic()") + }) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + AmadronOfferManager.getInstance().getStaticOffers().removeAll(removeScripted()); + AmadronOfferManager.getInstance().getStaticOffers().addAll(restoreFromBackup()); + AmadronOfferManager.getInstance().getPeriodicOffers().removeAll(periodicStorage.removeScripted()); + AmadronOfferManager.getInstance().getPeriodicOffers().addAll(periodicStorage.restoreFromBackup()); + } + + @Override + public void afterScriptLoad() { + AmadronOfferManager.getInstance().shufflePeriodicOffers(); + AmadronOfferManager.getInstance().recompileOffers(); + } + + public void addStatic(AmadronOffer recipe) { + AmadronOfferManager.getInstance().getStaticOffers().add(recipe); + addScripted(recipe); + } + + public void addPeriodic(AmadronOffer recipe) { + // PeriodicOffers is a List, but it really ought to be a HashSet to properly work with AmadronOfferManager#shufflePeriodicOffers(), + // especially since AmadronOffer overrides the hashCode. + if (AmadronOfferManager.getInstance().getPeriodicOffers().contains(recipe)) return; + AmadronOfferManager.getInstance().getPeriodicOffers().add(recipe); + periodicStorage.addScripted(recipe); + } + + public boolean removeStatic(AmadronOffer recipe) { + addBackup(recipe); + return AmadronOfferManager.getInstance().getStaticOffers().remove(recipe); + } + + public boolean removePeriodic(AmadronOffer recipe) { + periodicStorage.addBackup(recipe); + return AmadronOfferManager.getInstance().getPeriodicOffers().remove(recipe); + } + + public boolean remove(AmadronOffer recipe) { + if (AmadronOfferManager.getInstance().getStaticOffers().contains(recipe)) return removeStatic(recipe); + if (AmadronOfferManager.getInstance().getPeriodicOffers().contains(recipe)) return removePeriodic(recipe); + return false; + } + + @MethodDescription(example = @Example("item('minecraft:emerald')")) + public boolean removeByOutput(IIngredient output) { + return AmadronOfferManager.getInstance().getStaticOffers().removeIf(entry -> { + if (entry.getOutput() instanceof FluidStack fluid && output.test(fluid) || entry.getOutput() instanceof ItemStack item && output.test(item)) { + addBackup(entry); + return true; + } + return false; + }) | AmadronOfferManager.getInstance().getPeriodicOffers().removeIf(entry -> { + if (entry.getOutput() instanceof FluidStack fluid && output.test(fluid) || entry.getOutput() instanceof ItemStack item && output.test(item)) { + periodicStorage.addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example("item('minecraft:rotten_flesh')")) + public boolean removeByInput(IIngredient input) { + return AmadronOfferManager.getInstance().getStaticOffers().removeIf(entry -> { + if (entry.getInput() instanceof FluidStack fluid && input.test(fluid) || entry.getInput() instanceof ItemStack item && input.test(item)) { + addBackup(entry); + return true; + } + return false; + }) | AmadronOfferManager.getInstance().getPeriodicOffers().removeIf(entry -> { + if (entry.getInput() instanceof FluidStack fluid && input.test(fluid) || entry.getInput() instanceof ItemStack item && input.test(item)) { + periodicStorage.addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAllStatic() { + AmadronOfferManager.getInstance().getStaticOffers().forEach(this::addBackup); + AmadronOfferManager.getInstance().getStaticOffers().clear(); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAllPeriodic() { + AmadronOfferManager.getInstance().getPeriodicOffers().forEach(periodicStorage::addBackup); + AmadronOfferManager.getInstance().getPeriodicOffers().clear(); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + removeAllStatic(); + removeAllPeriodic(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + List list = new ArrayList<>(); + list.addAll(AmadronOfferManager.getInstance().getStaticOffers()); + list.addAll(AmadronOfferManager.getInstance().getPeriodicOffers()); + return new SimpleObjectStream<>(list).setRemover(this::removeStatic); + } + + @Property(property = "input", valid = {@Comp(type = Comp.Type.GTE, value = "0"), @Comp(type = Comp.Type.LTE, value = "1")}) + @Property(property = "output", valid = {@Comp(type = Comp.Type.GTE, value = "0"), @Comp(type = Comp.Type.LTE, value = "1")}) + @Property(property = "fluidInput", valid = {@Comp(type = Comp.Type.GTE, value = "0"), @Comp(type = Comp.Type.LTE, value = "1")}) + @Property(property = "fluidOutput", valid = {@Comp(type = Comp.Type.GTE, value = "0"), @Comp(type = Comp.Type.LTE, value = "1")}) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property + private boolean periodic; + + @RecipeBuilderMethodDescription + public RecipeBuilder periodic() { + this.periodic = !periodic; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder periodic(boolean periodic) { + this.periodic = periodic; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Amadron recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 0, 1, 0, 1); + validateFluids(msg, 0, 1, 0, 1); + msg.add(input.isEmpty() && fluidInput.isEmpty(), "either input or fluidInput must contain an entry, but both were empty"); + msg.add(output.isEmpty() && fluidOutput.isEmpty(), "either output or fluidOutput must contain an entry, but both were empty"); + } + + private static void register(boolean periodic, AmadronOffer recipe) { + if (periodic) ModSupport.PNEUMATIC_CRAFT.get().amadron.addPeriodic(recipe); + else ModSupport.PNEUMATIC_CRAFT.get().amadron.addStatic(recipe); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable AmadronOffer register() { + if (!validate()) return null; + AmadronOffer recipe = null; + Object o = fluidOutput.isEmpty() ? output.getOrEmpty(0) : fluidOutput.get(0); + if (input.isEmpty()) { + recipe = new AmadronOffer(fluidInput.getOrEmpty(0), o); + register(periodic, recipe); + } else { + for (var stack : input.get(0).getMatchingStacks()) { + recipe = new AmadronOffer(stack, o); + register(periodic, recipe); + } + } + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/AssemblyController.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/AssemblyController.java new file mode 100644 index 000000000..c9c092926 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/AssemblyController.java @@ -0,0 +1,182 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.common.item.ItemAssemblyProgram; +import me.desht.pneumaticcraft.common.recipes.AssemblyRecipe; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@RegistryDescription +public class AssemblyController extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay') * 3).output(item('minecraft:gold_ingot') * 6).drill()"), + @Example(".input(item('minecraft:gold_ingot') * 6).output(item('minecraft:diamond')).laser()"), + @Example(".input(item('minecraft:stone')).output(item('minecraft:clay') * 5).laser()") + }) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + private List map(AssemblyRecipe recipe) { + int type = recipe.getProgramStack().getMetadata(); + if (type < 0 || type > AssemblyType.values().length) { + GroovyLog.msg("Error getting the recipe map for PneumaticCraft Assembly Controller") + .add("type was {}, which is not one of the expected values of 0, 1, or 2", type) + .error() + .post(); + return new ArrayList<>(); + } + return map(AssemblyType.values()[type]); + } + + private List map(AssemblyType type) { + return switch (type) { + case DRILL -> AssemblyRecipe.drillRecipes; + case LASER -> AssemblyRecipe.laserRecipes; + }; + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(recipe -> map(recipe).remove(recipe)); + restoreFromBackup().forEach(recipe -> map(recipe).add(recipe)); + } + + @Override + @GroovyBlacklist + public void afterScriptLoad() { + AssemblyRecipe.drillLaserRecipes.clear(); + AssemblyRecipe.calculateAssemblyChain(); + } + + public void add(AssemblyRecipe recipe) { + map(recipe).add(recipe); + addScripted(recipe); + } + + public boolean remove(AssemblyRecipe recipe) { + addBackup(recipe); + return map(recipe).remove(recipe); + } + + @MethodDescription + public boolean removeByOutput(AssemblyType type, IIngredient output) { + return map(type).removeIf(entry -> { + if (output.test(entry.getOutput())) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example("item('pneumaticcraft:pressure_chamber_valve')")) + public boolean removeByOutput(IIngredient output) { + return removeByOutput(AssemblyType.DRILL, output) | removeByOutput(AssemblyType.LASER, output); + } + + @MethodDescription + public boolean removeByInput(AssemblyType type, IIngredient input) { + return map(type).removeIf(entry -> { + if (input.test(entry.getInput())) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example("item('minecraft:redstone')")) + public boolean removeByInput(IIngredient input) { + return removeByOutput(AssemblyType.DRILL, input) | removeByOutput(AssemblyType.LASER, input); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAllDrill() { + map(AssemblyType.DRILL).forEach(this::addBackup); + map(AssemblyType.DRILL).clear(); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAllLaser() { + map(AssemblyType.LASER).forEach(this::addBackup); + map(AssemblyType.LASER).clear(); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + removeAllDrill(); + removeAllLaser(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(Arrays.stream(AssemblyType.values()).map(this::map).flatMap(Collection::stream).collect(Collectors.toList())) + .setRemover(this::remove); + } + + public enum AssemblyType { + DRILL, + LASER + } + + @Property(property = "input", valid = @Comp("1")) + @Property(property = "output", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(valid = @Comp(value = "null", type = Comp.Type.NOT)) + private ItemStack programStack; + + @RecipeBuilderMethodDescription(field = "programStack") + public RecipeBuilder drill() { + this.programStack = ItemAssemblyProgram.getStackForProgramType(0, 1); + return this; + } + + @RecipeBuilderMethodDescription(field = "programStack") + public RecipeBuilder laser() { + this.programStack = ItemAssemblyProgram.getStackForProgramType(1, 1); + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Assembly Controller recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + msg.add(programStack == null, "programStack cannot be null"); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable AssemblyRecipe register() { + if (!validate()) return null; + AssemblyRecipe recipe = null; + for (ItemStack stack : input.get(0).getMatchingStacks()) { + AssemblyRecipe recipe1 = new AssemblyRecipe(stack, output.get(0), programStack); + ModSupport.PNEUMATIC_CRAFT.get().assemblyController.add(recipe1); + if (recipe == null) recipe = recipe1; + } + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Explosion.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Explosion.java new file mode 100644 index 000000000..4d8d96779 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Explosion.java @@ -0,0 +1,116 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +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.OreDictIngredient; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.common.recipes.ExplosionCraftingRecipe; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription( + admonition = @Admonition(value = "groovyscript.wiki.pneumaticcraft.explosion.note0", type = Admonition.Type.TIP) +) +public class Explosion extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).output(item('minecraft:gold_ingot')).lossRate(40)"), + @Example(".input(item('minecraft:diamond')).output(item('minecraft:obsidian'))") + }) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + ExplosionCraftingRecipe.recipes.removeAll(removeScripted()); + ExplosionCraftingRecipe.recipes.addAll(restoreFromBackup()); + } + + public void add(ExplosionCraftingRecipe recipe) { + ExplosionCraftingRecipe.recipes.add(recipe); + addScripted(recipe); + } + + public boolean remove(ExplosionCraftingRecipe recipe) { + addBackup(recipe); + return ExplosionCraftingRecipe.recipes.remove(recipe); + } + + @MethodDescription(example = @Example("item('pneumaticcraft:compressed_iron_block')")) + public boolean removeByOutput(IIngredient output) { + return ExplosionCraftingRecipe.recipes.removeIf(entry -> { + if (output.test(entry.getOutput())) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example(value = "item('minecraft:iron_block')", commented = true)) + public boolean removeByInput(IIngredient input) { + return ExplosionCraftingRecipe.recipes.removeIf(entry -> { + if (input.test(entry.getInput()) || input instanceof OreDictIngredient oreDictIngredient && oreDictIngredient.getOreDict().equals(entry.getOreDictKey())) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + ExplosionCraftingRecipe.recipes.forEach(this::addBackup); + ExplosionCraftingRecipe.recipes.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ExplosionCraftingRecipe.recipes).setRemover(this::remove); + } + + @Property(property = "input", valid = @Comp("1")) + @Property(property = "output", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(valid = @Comp(type = Comp.Type.GTE, value = "0")) + private int lossRate; + + @RecipeBuilderMethodDescription + public RecipeBuilder lossRate(int lossRate) { + this.lossRate = lossRate; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Explosion recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + msg.add(lossRate < 0, "lossRate must be a non negative integer, yet it was {}", lossRate); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable ExplosionCraftingRecipe register() { + if (!validate()) return null; + ExplosionCraftingRecipe recipe = null; + for (ItemStack stack : input.get(0).getMatchingStacks()) { + ExplosionCraftingRecipe recipe1 = new ExplosionCraftingRecipe(stack, output.get(0), lossRate); + ModSupport.PNEUMATIC_CRAFT.get().explosion.add(recipe1); + if (recipe == null) recipe = recipe1; + } + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/HeatFrameCooling.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/HeatFrameCooling.java new file mode 100644 index 000000000..3a76f5bfa --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/HeatFrameCooling.java @@ -0,0 +1,98 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.common.recipes.HeatFrameCoolingRecipe; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription +public class HeatFrameCooling extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay')).output(item('minecraft:gold_ingot'))"), + @Example(".input(item('minecraft:diamond')).output(item('minecraft:obsidian'))") + }) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + HeatFrameCoolingRecipe.recipes.removeAll(removeScripted()); + HeatFrameCoolingRecipe.recipes.addAll(restoreFromBackup()); + } + + public void add(HeatFrameCoolingRecipe recipe) { + HeatFrameCoolingRecipe.recipes.add(recipe); + addScripted(recipe); + } + + public boolean remove(HeatFrameCoolingRecipe recipe) { + addBackup(recipe); + return HeatFrameCoolingRecipe.recipes.remove(recipe); + } + + @MethodDescription(example = @Example("item('minecraft:obsidian')")) + public boolean removeByOutput(IIngredient output) { + return HeatFrameCoolingRecipe.recipes.removeIf(entry -> { + if (output.test(entry.output)) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example("item('minecraft:water_bucket')")) + public boolean removeByInput(IIngredient input) { + return HeatFrameCoolingRecipe.recipes.removeIf(entry -> { + if (entry.input.getStacks().stream().anyMatch(input)) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + HeatFrameCoolingRecipe.recipes.forEach(this::addBackup); + HeatFrameCoolingRecipe.recipes.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(HeatFrameCoolingRecipe.recipes).setRemover(this::remove); + } + + @Property(property = "input", valid = @Comp("1")) + @Property(property = "output", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Heat Frame Cooling recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable HeatFrameCoolingRecipe register() { + if (!validate()) return null; + HeatFrameCoolingRecipe recipe = new HeatFrameCoolingRecipe(PneumaticCraft.toItemIngredient(input.get(0)), output.get(0)); + ModSupport.PNEUMATIC_CRAFT.get().heatFrameCooling.add(recipe); + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/LiquidFuel.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/LiquidFuel.java new file mode 100644 index 000000000..4b81c3917 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/LiquidFuel.java @@ -0,0 +1,99 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.common.PneumaticCraftAPIHandler; +import net.minecraftforge.fluids.FluidStack; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +@RegistryDescription(category = RegistryDescription.Category.ENTRIES) +public class LiquidFuel extends VirtualizedRegistry> { + + @RecipeBuilderDescription(example = @Example(".fluidInput(fluid('water')).pressure(100_000_000)")) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(recipe -> PneumaticCraftAPIHandler.getInstance().liquidFuels.remove(recipe.getKey())); + restoreFromBackup().forEach(recipe -> PneumaticCraftAPIHandler.getInstance().liquidFuels.put(recipe.getKey(), recipe.getValue())); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public void add(String fluid, int pressure) { + PneumaticCraftAPIHandler.getInstance().liquidFuels.put(fluid, pressure); + addScripted(Pair.of(fluid, pressure)); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public void add(FluidStack fluid, int pressure) { + add(fluid.getFluid().getName(), pressure); + } + + @MethodDescription + public boolean remove(String fluid) { + Integer pressure = PneumaticCraftAPIHandler.getInstance().liquidFuels.get(fluid); + if (pressure == null) return false; + addBackup(Pair.of(fluid, pressure)); + return PneumaticCraftAPIHandler.getInstance().liquidFuels.remove(fluid, pressure); + } + + @MethodDescription(example = @Example("fluid('lava')")) + public boolean remove(FluidStack fluid) { + return remove(fluid.getFluid().getName()); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + PneumaticCraftAPIHandler.getInstance().liquidFuels.forEach((key, value) -> addBackup(Pair.of(key, value))); + PneumaticCraftAPIHandler.getInstance().liquidFuels.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream> streamRecipes() { + return new SimpleObjectStream<>(PneumaticCraftAPIHandler.getInstance().liquidFuels.entrySet()) + .setRemover(x -> remove(x.getKey())); + } + + @Property(property = "fluidInput", valid = {@Comp(type = Comp.Type.GTE, value = "0"), @Comp(type = Comp.Type.LTE, value = "1")}) + public static class RecipeBuilder extends AbstractRecipeBuilder> { + + @Property + private int pressure; + + @RecipeBuilderMethodDescription + public RecipeBuilder pressure(int pressure) { + this.pressure = pressure; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Liquid Fuel entry"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg); + validateFluids(msg, 1, 1, 0, 0); + msg.add(pressure <= 0, "pressure must be greater than 0, yet it was {}", pressure); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable Pair register() { + if (!validate()) return null; + ModSupport.PNEUMATIC_CRAFT.get().liquidFuel.add(fluidInput.get(0), pressure); + return Pair.of(fluidInput.get(0), pressure); + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PlasticMixer.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PlasticMixer.java new file mode 100644 index 000000000..f7f170fa0 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PlasticMixer.java @@ -0,0 +1,179 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +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.core.mixin.pneumaticcraft.PlasticMixerRecipeAccessor; +import com.cleanroommc.groovyscript.core.mixin.pneumaticcraft.PlasticMixerRegistryAccessor; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.common.recipes.PlasticMixerRegistry; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription( + admonition = { + @Admonition(value = "groovyscript.wiki.pneumaticcraft.plastic_mixer.note0", type = Admonition.Type.WARNING), + @Admonition(value = "groovyscript.wiki.pneumaticcraft.plastic_mixer.note1", type = Admonition.Type.DANGER) + } +) +public class PlasticMixer extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = { + @Example(".fluidInput(fluid('lava') * 100).output(item('minecraft:clay')).allowMelting().allowSolidifying().requiredTemperature(323)"), + @Example(".fluidInput(fluid('water') * 50).output(item('minecraft:sapling')).allowSolidifying().requiredTemperature(298).meta(-1)") + }) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + private static PlasticMixerRegistryAccessor getInstance() { + return (PlasticMixerRegistryAccessor) (Object) PlasticMixerRegistry.INSTANCE; + } + + @Override + public void onReload() { + getInstance().getRecipes().removeAll(removeScripted()); + getInstance().getRecipes().addAll(restoreFromBackup()); + } + + @Override + public void afterScriptLoad() { + getInstance().getValidFluids().clear(); + getInstance().getValidItems().clear(); + for (PlasticMixerRegistry.PlasticMixerRecipe recipe : getInstance().getRecipes()) { + getInstance().getValidFluids().add(recipe.getFluidStack().getFluid().getName()); + getInstance().getValidItems().put(recipe.getItemStack().getItem(), recipe.allowMelting()); + } + } + + public void add(PlasticMixerRegistry.PlasticMixerRecipe recipe) { + getInstance().getRecipes().add(recipe); + addScripted(recipe); + } + + public boolean remove(PlasticMixerRegistry.PlasticMixerRecipe recipe) { + addBackup(recipe); + return getInstance().getRecipes().remove(recipe); + } + + @MethodDescription(example = @Example(value = "fluid('plastic')", commented = true)) + public boolean removeByFluid(IIngredient fluid) { + return getInstance().getRecipes().removeIf(entry -> { + if (fluid.test(entry.getFluidStack())) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example(value = "item('pneumaticcraft:plastic')", commented = true)) + public boolean removeByItem(IIngredient item) { + return getInstance().getRecipes().removeIf(entry -> { + if (item.test(entry.getItemStack())) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + getInstance().getRecipes().forEach(this::addBackup); + getInstance().getRecipes().clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(getInstance().getRecipes()).setRemover(this::remove); + } + + @Property(property = "output", valid = @Comp("1")) + @Property(property = "fluidInput", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property + private int meta; + @Property + private int requiredTemperature; + @Property + private boolean allowMelting; + @Property + private boolean allowSolidifying; + @Property + private boolean useDye; + + @RecipeBuilderMethodDescription + public RecipeBuilder meta(int meta) { + this.meta = meta; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder requiredTemperature(int requiredTemperature) { + this.requiredTemperature = requiredTemperature; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder allowMelting() { + this.allowMelting = !allowMelting; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder allowMelting(boolean allowMelting) { + this.allowMelting = allowMelting; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder allowSolidifying() { + this.allowSolidifying = !allowSolidifying; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder allowSolidifying(boolean allowSolidifying) { + this.allowSolidifying = allowSolidifying; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder useDye() { + this.useDye = !useDye; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder useDye(boolean useDye) { + this.useDye = useDye; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Plastic Mixer recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 0, 0, 1, 1); + validateFluids(msg, 1, 1, 0, 0); + msg.add(!allowMelting && !allowSolidifying, "neither allowMelting or allowSolidifying are enabled, one of the two must be enabled"); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable PlasticMixerRegistry.PlasticMixerRecipe register() { + if (!validate()) return null; + PlasticMixerRegistry.PlasticMixerRecipe recipe = PlasticMixerRecipeAccessor.createPlasticMixerRecipe(fluidInput.get(0), output.get(0), requiredTemperature, allowMelting, allowSolidifying, useDye, meta); + ModSupport.PNEUMATIC_CRAFT.get().plasticMixer.add(recipe); + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PneumaticCraft.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PneumaticCraft.java new file mode 100644 index 000000000..a59622170 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PneumaticCraft.java @@ -0,0 +1,30 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.mods.GroovyPropertyContainer; +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient; +import me.desht.pneumaticcraft.api.recipe.ItemIngredient; +import net.minecraft.item.ItemStack; + +public class PneumaticCraft extends GroovyPropertyContainer { + + public final Amadron amadron = new Amadron(); + public final AssemblyController assemblyController = new AssemblyController(); + public final Explosion explosion = new Explosion(); + public final HeatFrameCooling heatFrameCooling = new HeatFrameCooling(); + public final LiquidFuel liquidFuel = new LiquidFuel(); + public final PlasticMixer plasticMixer = new PlasticMixer(); + public final PressureChamber pressureChamber = new PressureChamber(); + public final Refinery refinery = new Refinery(); + public final ThermopneumaticProcessingPlant thermopneumaticProcessingPlant = new ThermopneumaticProcessingPlant(); + public final XpFluid xpFluid = new XpFluid(); + + public static ItemIngredient toItemIngredient(IIngredient ingredient) { + if (ingredient instanceof OreDictIngredient oreDictIngredient) return new ItemIngredient(oreDictIngredient.getOreDict(), ingredient.getAmount()); + if (IngredientHelper.isItem(ingredient)) return new ItemIngredient(IngredientHelper.toItemStack(ingredient).copy()); + return new ItemIngredient(ItemStack.EMPTY); + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PressureChamber.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PressureChamber.java new file mode 100644 index 000000000..08d177e10 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/PressureChamber.java @@ -0,0 +1,112 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.api.recipe.IPressureChamberRecipe; +import me.desht.pneumaticcraft.api.recipe.ItemIngredient; +import me.desht.pneumaticcraft.common.recipes.PressureChamberRecipe; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +@RegistryDescription +public class PressureChamber extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay') * 3).output(item('minecraft:gold_ingot')).pressure(4)"), + @Example(".input(item('minecraft:clay'), item('minecraft:gold_ingot'), item('minecraft:gold_block'), item('minecraft:gold_nugget'), item('minecraft:diamond'), item('minecraft:diamond_block'), item('minecraft:obsidian'), item('minecraft:stone'), item('minecraft:stone:1'), item('minecraft:stone:2'), item('minecraft:stone:3'), item('minecraft:stone:4'), item('minecraft:stone:5'), item('minecraft:stone:6')).output(item('minecraft:cobblestone')).pressure(4)") + }) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + PressureChamberRecipe.recipes.removeAll(removeScripted()); + PressureChamberRecipe.recipes.addAll(restoreFromBackup()); + } + + public void add(IPressureChamberRecipe recipe) { + PressureChamberRecipe.recipes.add(recipe); + addScripted(recipe); + } + + public boolean remove(IPressureChamberRecipe recipe) { + addBackup(recipe); + return PressureChamberRecipe.recipes.remove(recipe); + } + + @MethodDescription(example = @Example("item('minecraft:diamond')")) + public boolean removeByOutput(IIngredient output) { + return PressureChamberRecipe.recipes.removeIf(entry -> { + if (entry.getResult().stream().anyMatch(output)) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example("item('minecraft:iron_block')")) + public boolean removeByInput(IIngredient input) { + return PressureChamberRecipe.recipes.removeIf(entry -> { + if (entry.getInput().stream().map(ItemIngredient::getStacks).flatMap(Collection::stream).anyMatch(input)) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + PressureChamberRecipe.recipes.forEach(this::addBackup); + PressureChamberRecipe.recipes.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(PressureChamberRecipe.recipes).setRemover(this::remove); + } + + @Property(property = "input", valid = {@Comp(type = Comp.Type.GTE, value = "1"), @Comp(type = Comp.Type.LTE, value = "Integer.MAX_VALUE")}) + @Property(property = "output", valid = {@Comp(type = Comp.Type.GTE, value = "1"), @Comp(type = Comp.Type.LTE, value = "Integer.MAX_VALUE")}) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property + private float pressure; + + @RecipeBuilderMethodDescription + public RecipeBuilder pressure(float pressure) { + this.pressure = pressure; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Pressure Chamber recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, Integer.MAX_VALUE, 1, Integer.MAX_VALUE); + validateFluids(msg); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable IPressureChamberRecipe register() { + if (!validate()) return null; + IPressureChamberRecipe recipe = new PressureChamberRecipe.SimpleRecipe(input.stream().map(PneumaticCraft::toItemIngredient).toArray(ItemIngredient[]::new), pressure, output.toArray(new ItemStack[0])); + ModSupport.PNEUMATIC_CRAFT.get().pressureChamber.add(recipe); + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Refinery.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Refinery.java new file mode 100644 index 000000000..5f304f8a6 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/Refinery.java @@ -0,0 +1,110 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.common.recipes.RefineryRecipe; +import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +@RegistryDescription +public class Refinery extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = { + @Example(".fluidInput(fluid('water') * 1000).fluidOutput(fluid('lava') * 750, fluid('lava') * 250, fluid('lava') * 100, fluid('lava') * 50)"), + @Example(".fluidInput(fluid('lava') * 100).fluidOutput(fluid('water') * 50, fluid('kerosene') * 25)") + }) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + RefineryRecipe.recipes.removeAll(removeScripted()); + RefineryRecipe.recipes.addAll(restoreFromBackup()); + } + + public void add(RefineryRecipe recipe) { + RefineryRecipe.recipes.add(recipe); + addScripted(recipe); + } + + public boolean remove(RefineryRecipe recipe) { + addBackup(recipe); + return RefineryRecipe.recipes.remove(recipe); + } + + @MethodDescription(example = @Example("fluid('kerosene')")) + public boolean removeByOutput(IIngredient output) { + return RefineryRecipe.recipes.removeIf(entry -> { + if (Arrays.stream(entry.outputs).anyMatch(output::test)) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = @Example(value = "fluid('oil')", commented = true)) + public boolean removeByInput(IIngredient input) { + return RefineryRecipe.recipes.removeIf(entry -> { + if (input.test(entry.input)) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + RefineryRecipe.recipes.forEach(this::addBackup); + RefineryRecipe.recipes.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(RefineryRecipe.recipes).setRemover(this::remove); + } + + @Property(property = "fluidInput", valid = @Comp("1")) + @Property(property = "fluidOutput", valid = {@Comp(type = Comp.Type.GTE, value = "2"), @Comp(type = Comp.Type.LTE, value = "4")}) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property(defaultValue = "373") + private int requiredTemperature = 373; + + @RecipeBuilderMethodDescription + public RecipeBuilder requiredTemperature(int requiredTemperature) { + this.requiredTemperature = requiredTemperature; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Refinery recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg); + validateFluids(msg, 1, 1, 2, 4); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable RefineryRecipe register() { + if (!validate()) return null; + RefineryRecipe recipe = new RefineryRecipe(requiredTemperature, fluidInput.get(0), fluidOutput.toArray(new FluidStack[0])); + ModSupport.PNEUMATIC_CRAFT.get().refinery.add(recipe); + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/ThermopneumaticProcessingPlant.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/ThermopneumaticProcessingPlant.java new file mode 100644 index 000000000..e9b3299d3 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/ThermopneumaticProcessingPlant.java @@ -0,0 +1,127 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.api.recipe.IThermopneumaticProcessingPlantRecipe; +import me.desht.pneumaticcraft.common.recipes.BasicThermopneumaticProcessingPlantRecipe; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +@RegistryDescription +public class ThermopneumaticProcessingPlant extends VirtualizedRegistry { + + @RecipeBuilderDescription(example = { + @Example(".input(item('minecraft:clay') * 3).fluidInput(fluid('water') * 100).fluidOutput(fluid('kerosene') * 100).pressure(4).requiredTemperature(323)"), + @Example(".fluidInput(fluid('water') * 100).fluidOutput(fluid('lava') * 100).pressure(4).requiredTemperature(323)") + }) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + BasicThermopneumaticProcessingPlantRecipe.recipes.removeAll(removeScripted()); + BasicThermopneumaticProcessingPlantRecipe.recipes.addAll(restoreFromBackup()); + } + + public void add(IThermopneumaticProcessingPlantRecipe recipe) { + BasicThermopneumaticProcessingPlantRecipe.recipes.add(recipe); + addScripted(recipe); + } + + public boolean remove(IThermopneumaticProcessingPlantRecipe recipe) { + addBackup(recipe); + return BasicThermopneumaticProcessingPlantRecipe.recipes.remove(recipe); + } + + @MethodDescription(example = @Example("fluid('lpg')")) + public boolean removeByOutput(IIngredient output) { + return BasicThermopneumaticProcessingPlantRecipe.recipes.removeIf(entry -> { + if (entry instanceof BasicThermopneumaticProcessingPlantRecipe recipe && output.test(recipe.getOutputLiquid())) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(example = {@Example("item('minecraft:coal')"), @Example("fluid('diesel')")}) + public boolean removeByInput(IIngredient input) { + return BasicThermopneumaticProcessingPlantRecipe.recipes.removeIf(entry -> { + if (entry instanceof BasicThermopneumaticProcessingPlantRecipe recipe && (input.test(recipe.getInputLiquid()) || input.test(recipe.getInputItem()))) { + addBackup(entry); + return true; + } + return false; + }); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + BasicThermopneumaticProcessingPlantRecipe.recipes.forEach(this::addBackup); + BasicThermopneumaticProcessingPlantRecipe.recipes.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(BasicThermopneumaticProcessingPlantRecipe.recipes).setRemover(this::remove); + } + + @Property(property = "input", valid = {@Comp(type = Comp.Type.GTE, value = "0"), @Comp(type = Comp.Type.LTE, value = "1")}) + @Property(property = "fluidInput", valid = @Comp("1")) + @Property(property = "fluidOutput", valid = @Comp("1")) + public static class RecipeBuilder extends AbstractRecipeBuilder { + + @Property + private float pressure; + @Property + private double requiredTemperature; + + @RecipeBuilderMethodDescription + public RecipeBuilder pressure(float pressure) { + this.pressure = pressure; + return this; + } + + @RecipeBuilderMethodDescription + public RecipeBuilder requiredTemperature(double requiredTemperature) { + this.requiredTemperature = requiredTemperature; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Thermopneumatic Processing Plant recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 0, 1, 0, 0); + validateFluids(msg, 1, 1, 1, 1); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable IThermopneumaticProcessingPlantRecipe register() { + if (!validate()) return null; + IThermopneumaticProcessingPlantRecipe recipe = null; + if (input.isEmpty()) { + recipe = new BasicThermopneumaticProcessingPlantRecipe(fluidInput.get(0), ItemStack.EMPTY, fluidOutput.get(0), requiredTemperature, pressure); + ModSupport.PNEUMATIC_CRAFT.get().thermopneumaticProcessingPlant.add(recipe); + } else { + for (ItemStack stack : input.get(0).getMatchingStacks()) { + IThermopneumaticProcessingPlantRecipe recipe1 = new BasicThermopneumaticProcessingPlantRecipe(fluidInput.get(0), stack, fluidOutput.get(0), requiredTemperature, pressure); + ModSupport.PNEUMATIC_CRAFT.get().thermopneumaticProcessingPlant.add(recipe1); + if (recipe == null) recipe = recipe1; + } + } + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/XpFluid.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/XpFluid.java new file mode 100644 index 000000000..cb7a310f6 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/pneumaticcraft/XpFluid.java @@ -0,0 +1,109 @@ +package com.cleanroommc.groovyscript.compat.mods.pneumaticcraft; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.documentation.annotations.*; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import me.desht.pneumaticcraft.common.PneumaticCraftAPIHandler; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +@RegistryDescription(category = RegistryDescription.Category.ENTRIES) +public class XpFluid extends VirtualizedRegistry> { + + @RecipeBuilderDescription(example = @Example(".fluidInput(fluid('lava')).ratio(5)")) + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(recipe -> PneumaticCraftAPIHandler.getInstance().liquidXPs.remove(recipe.getKey())); + restoreFromBackup().forEach(recipe -> PneumaticCraftAPIHandler.getInstance().liquidXPs.put(recipe.getKey(), recipe.getValue())); + } + + @Override + @GroovyBlacklist + public void afterScriptLoad() { + PneumaticCraftAPIHandler.getInstance().availableLiquidXPs.clear(); + PneumaticCraftAPIHandler.getInstance().availableLiquidXPs.addAll(PneumaticCraftAPIHandler.getInstance().liquidXPs.keySet()); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public void add(Fluid fluid, int ratio) { + PneumaticCraftAPIHandler.getInstance().liquidXPs.put(fluid, ratio); + addScripted(Pair.of(fluid, ratio)); + } + + @MethodDescription(type = MethodDescription.Type.ADDITION) + public void add(FluidStack fluid, int ratio) { + add(fluid.getFluid(), ratio); + } + + @MethodDescription + public boolean remove(Fluid fluid) { + Integer ratio = PneumaticCraftAPIHandler.getInstance().liquidXPs.get(fluid); + if (ratio == null) return false; + addBackup(Pair.of(fluid, ratio)); + return PneumaticCraftAPIHandler.getInstance().liquidXPs.remove(fluid, ratio); + } + + @MethodDescription(example = @Example(value = "fluid('xpjuice')", commented = true)) + public boolean remove(FluidStack fluid) { + return remove(fluid.getFluid()); + } + + @MethodDescription(priority = 2000, example = @Example(commented = true)) + public void removeAll() { + PneumaticCraftAPIHandler.getInstance().liquidXPs.forEach((key, value) -> addBackup(Pair.of(key, value))); + PneumaticCraftAPIHandler.getInstance().liquidXPs.clear(); + } + + @MethodDescription(type = MethodDescription.Type.QUERY) + public SimpleObjectStream> streamRecipes() { + return new SimpleObjectStream<>(PneumaticCraftAPIHandler.getInstance().liquidXPs.entrySet()) + .setRemover(x -> remove(x.getKey())); + } + + @Property(property = "fluidInput", valid = {@Comp(type = Comp.Type.GTE, value = "0"), @Comp(type = Comp.Type.LTE, value = "1")}) + public static class RecipeBuilder extends AbstractRecipeBuilder> { + + @Property + private int ratio; + + @RecipeBuilderMethodDescription + public RecipeBuilder ratio(int ratio) { + this.ratio = ratio; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding PneumaticCraft Liquid Fuel entry"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg); + validateFluids(msg, 1, 1, 0, 0); + msg.add(ratio <= 0, "ratio must be greater than 0, yet it was {}", ratio); + } + + @Override + @RecipeBuilderRegistrationMethod + public @Nullable Pair register() { + if (!validate()) return null; + ModSupport.PNEUMATIC_CRAFT.get().xpFluid.add(fluidInput.get(0), ratio); + return Pair.of(fluidInput.get(0), ratio); + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java index c2b1fef6d..c05223cb9 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java @@ -30,6 +30,7 @@ public class LateMixin implements ILateMixinLoader { "inspirations", "jei", "mekanism", + "pneumaticcraft", "projecte", "pyrotech", "roots", diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/pneumaticcraft/PlasticMixerRecipeAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pneumaticcraft/PlasticMixerRecipeAccessor.java new file mode 100644 index 000000000..f109549c7 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pneumaticcraft/PlasticMixerRecipeAccessor.java @@ -0,0 +1,17 @@ +package com.cleanroommc.groovyscript.core.mixin.pneumaticcraft; + +import me.desht.pneumaticcraft.common.recipes.PlasticMixerRegistry; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(value = PlasticMixerRegistry.PlasticMixerRecipe.class, remap = false) +public interface PlasticMixerRecipeAccessor { + + @Invoker("") + static PlasticMixerRegistry.PlasticMixerRecipe createPlasticMixerRecipe(FluidStack fluidStack, ItemStack itemStack, int temperature, boolean allowMelting, boolean allowSolidifying, boolean useDye, int meta) { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/pneumaticcraft/PlasticMixerRegistryAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pneumaticcraft/PlasticMixerRegistryAccessor.java new file mode 100644 index 000000000..c7f8fec14 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/pneumaticcraft/PlasticMixerRegistryAccessor.java @@ -0,0 +1,24 @@ +package com.cleanroommc.groovyscript.core.mixin.pneumaticcraft; + +import me.desht.pneumaticcraft.common.recipes.PlasticMixerRegistry; +import net.minecraft.item.Item; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Mixin(value = PlasticMixerRegistry.class, remap = false) +public interface PlasticMixerRegistryAccessor { + + @Accessor + Set getValidFluids(); + + @Accessor + Map getValidItems(); + + @Accessor + List getRecipes(); + +} diff --git a/src/main/resources/assets/groovyscript/lang/en_us.lang b/src/main/resources/assets/groovyscript/lang/en_us.lang index b60610108..1c8e25a16 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -1422,6 +1422,66 @@ groovyscript.wiki.pyrotech.tanning_rack.failureItem.value=Sets the output when t groovyscript.wiki.pyrotech.tanning_rack.add=Adds recipes in the format `name`, `input`, `output`, `dryTime`, `failureItem` +# PneumaticCraft +groovyscript.wiki.pneumaticcraft.amadron.title=Amadron +groovyscript.wiki.pneumaticcraft.amadron.description=Uses an Amadron Tablet and linked inventories in world to trade via drones. +groovyscript.wiki.pneumaticcraft.amadron.note0=Amadron recipes added or removed via GroovyScript will be saved to a config file in `config/pneumaticcraft/`, meaning changes made may persist unexpectedly through restarts. +groovyscript.wiki.pneumaticcraft.amadron.periodic.value=Sets if the Amadron recipe is periodic +groovyscript.wiki.pneumaticcraft.amadron.removeAllPeriodic=Removes all periodic recipes +groovyscript.wiki.pneumaticcraft.amadron.removeAllStatic=Removes all static recipes + +groovyscript.wiki.pneumaticcraft.assembly_controller.title=Assembly Controller +groovyscript.wiki.pneumaticcraft.assembly_controller.description=Uses a given Program to convert an input itemstack into an output itemstack. Drill recipes that output an itemstack used for the input itemstack of a Laser recipe can be chained via the Drill & Laser Program. +groovyscript.wiki.pneumaticcraft.assembly_controller.programStack.value=Sets the program type used, between Drill and Laser +groovyscript.wiki.pneumaticcraft.assembly_controller.removeAllDrill=Removes all Drill program recipes +groovyscript.wiki.pneumaticcraft.assembly_controller.removeAllLaser=Removes all Laser program recipes + +groovyscript.wiki.pneumaticcraft.explosion.title=Explosion +groovyscript.wiki.pneumaticcraft.explosion.description=Converts an input item into an output item, with a chance to fail and destroy the item. +groovyscript.wiki.pneumaticcraft.explosion.note0=Consider using the inWorldCrafting Explosion compat instead! +groovyscript.wiki.pneumaticcraft.explosion.lossRate.value=Sets the failure rate of the recipe, where the item is simply destroyed instead of being converted + +groovyscript.wiki.pneumaticcraft.heat_frame_cooling.title=Heat Frame Cooling +groovyscript.wiki.pneumaticcraft.heat_frame_cooling.description=Converts an input itemstack into an output itemstack when inside an inventory placed within a Heat Frame which is cooled. + +groovyscript.wiki.pneumaticcraft.liquid_fuel.title=Liquid Fuel +groovyscript.wiki.pneumaticcraft.liquid_fuel.description=Converts fluid into Pressure in a Liquid Compressor. +groovyscript.wiki.pneumaticcraft.liquid_fuel.add=Adds entries in the format `fluid`, `pressure` +groovyscript.wiki.pneumaticcraft.liquid_fuel.pressure.value=Sets the Pressure created by the fluid +groovyscript.wiki.pneumaticcraft.liquid_fuel.remove=Removes entries with the given `fluid` + +groovyscript.wiki.pneumaticcraft.plastic_mixer.title=Plastic Mixer +groovyscript.wiki.pneumaticcraft.plastic_mixer.description=Converts a fluidstack and an item with a variable damage value into each other, requiring temperature to operate the process, optionally consuming dye, and allowing either only melting or only solidifying. +groovyscript.wiki.pneumaticcraft.plastic_mixer.note0=Items with metadata 15 will never consume dye, even if the option is enabled. +groovyscript.wiki.pneumaticcraft.plastic_mixer.note1=Only one meta value can be used for a recipe per fluid, and the meta value will be applied to the item. +groovyscript.wiki.pneumaticcraft.plastic_mixer.meta.value=Sets the meta value for selecting the recipe, only one meta value can be used for a fluid +groovyscript.wiki.pneumaticcraft.plastic_mixer.useDye.value=Sets if the recipe consumes a random dye +groovyscript.wiki.pneumaticcraft.plastic_mixer.allowMelting.value=Sets if the recipe allows melting the output item back into the input fluid +groovyscript.wiki.pneumaticcraft.plastic_mixer.allowSolidifying.value=Sets if the recipe allows solidifying the input fluid into the output item +groovyscript.wiki.pneumaticcraft.plastic_mixer.requiredTemperature.value=Sets the required temperature in Kelvin to melt or solidify the recipe +groovyscript.wiki.pneumaticcraft.plastic_mixer.removeByFluid=Removes all recipes with the given fluid input +groovyscript.wiki.pneumaticcraft.plastic_mixer.removeByItem=Removes all recipes with the given item output + +groovyscript.wiki.pneumaticcraft.pressure_chamber.title=Pressure Chamber +groovyscript.wiki.pneumaticcraft.pressure_chamber.description=Converts any number of input itemstacks into any number of output itemstacks, either generating Pressure or consuming Pressure from the Pressure Chamber. +groovyscript.wiki.pneumaticcraft.pressure_chamber.pressure.value=Sets the Pressure consumed to perform the craft, if negative will generate Pressure instead + +groovyscript.wiki.pneumaticcraft.refinery.title=Refinery +groovyscript.wiki.pneumaticcraft.refinery.description=Converts an input fluidstack into between 2 and 4 fluidstacks, consuming Temperature, with the number of fluidstacks output depending on the recipe and the number of Refineries vertically stacked. +groovyscript.wiki.pneumaticcraft.refinery.requiredTemperature.value=Sets the required temperate in Kelvin required to process the recipe + +groovyscript.wiki.pneumaticcraft.thermopneumatic_processing_plant.title=Thermopneumatic Processing Plant +groovyscript.wiki.pneumaticcraft.thermopneumatic_processing_plant.description=Converts an input fluidstack into an output fluidstack, consuming Pressure and Temperature, with an optional itemstack being consumed. +groovyscript.wiki.pneumaticcraft.thermopneumatic_processing_plant.pressure.value=Sets the Pressure consumed to perform the craft +groovyscript.wiki.pneumaticcraft.thermopneumatic_processing_plant.requiredTemperature.value=Sets the required temperate in Kelvin required to process the recipe + +groovyscript.wiki.pneumaticcraft.xp_fluid.title=XP Fluid +groovyscript.wiki.pneumaticcraft.xp_fluid.description=Controls what fluids are considered XP Fluids and how much experience they provide. +groovyscript.wiki.pneumaticcraft.xp_fluid.add=Adds entries in the format `fluid`, `ratio` +groovyscript.wiki.pneumaticcraft.xp_fluid.ratio.value=Sets the amount of experience provided by the fluid for the purpose of determining the ratio between xp fluids +groovyscript.wiki.pneumaticcraft.xp_fluid.remove=Removes entries for the given `fluid` + + # Project E groovyscript.wiki.projecte.entity_randomizer.title=Entity Randomizer groovyscript.wiki.projecte.entity_randomizer.description=Converts an entity on the list into a random other entity on the list when a projectile fired from the Philosopher's Stone hits it. There are two lists, one for 'mobs' and the other for 'peacefuls', but any entity can go on either list. diff --git a/src/main/resources/mixin.groovyscript.pneumaticcraft.json b/src/main/resources/mixin.groovyscript.pneumaticcraft.json new file mode 100644 index 000000000..6aca15c84 --- /dev/null +++ b/src/main/resources/mixin.groovyscript.pneumaticcraft.json @@ -0,0 +1,11 @@ +{ + "package": "com.cleanroommc.groovyscript.core.mixin.pneumaticcraft", + "refmap": "mixins.groovyscript.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "PlasticMixerRecipeAccessor", + "PlasticMixerRegistryAccessor" + ] +} \ No newline at end of file