diff --git a/build.gradle b/build.gradle index c2c656746..c6f71e732 100644 --- a/build.gradle +++ b/build.gradle @@ -132,6 +132,11 @@ dependencies { runtimeOnly rfg.deobf('curse.maven:blood-magic-224791:2822288') } + compileOnly rfg.deobf('curse.maven:actually-additions-228404:3117927') + if (project.debug_actually_additions.toBoolean()) { + runtimeOnly rfg.deobf('curse.maven:actually-additions-228404:3117927') + } + compileOnly rfg.deobf('curse.maven:cucumber-272335:2645867') compileOnly rfg.deobf('curse.maven:extended-crafting-nomifactory-edition-398267:3613140') if (project.debug_extended_crafting.toBoolean()) { diff --git a/examples/actuallyadditions.groovy b/examples/actuallyadditions.groovy new file mode 100644 index 000000000..aad6e1847 --- /dev/null +++ b/examples/actuallyadditions.groovy @@ -0,0 +1,164 @@ + +// Atomic Reconstructor +// The Atomic Reconstructor is a block which uses energy to convert a block or item in front of it into other items. +mods.actuallyadditions.atomicreconstructor.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond')) + .energyUse(1000) // Optional, int + .register() + +mods.actuallyadditions.atomicreconstructor.recipeBuilder() + .input(item('minecraft:gold_ingot')) + .output(item('minecraft:clay') * 2) + .register() + +mods.actuallyadditions.atomicreconstructor.removeByInput(item('minecraft:diamond')) +mods.actuallyadditions.atomicreconstructor.removeByOutput(item('actuallyadditions:block_crystal')) +//mods.actuallyadditions.atomicreconstructor.removeAll() + +// Ball of Fur +// A weighted itemstack output for using a Ball of Fur, dropped by a cat. +mods.actuallyadditions.balloffur.recipeBuilder() + .output(item('minecraft:clay') * 32) + .weight(15) + .register() + +mods.actuallyadditions.balloffur.removeByOutput(item('minecraft:feather')) +//mods.actuallyadditions.balloffur.removeAll() + +// Compost +// Converts an input item into an output item after 150 seconds. Requires an input and output display blockstate. +mods.actuallyadditions.compost.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond')) + .inputDisplay(blockstate('minecraft:clay')) + .outputDisplay(blockstate('minecraft:diamond_block')) + .register() + +mods.actuallyadditions.compost.removeByInput(item('actuallyadditions:item_canola_seed')) +mods.actuallyadditions.compost.removeByOutput(item('actuallyadditions:item_fertilizer')) +//mods.actuallyadditions.compost.removeAll() + +// Crusher +// Converts an input itemstack into an output itemstack with a chance of a second itemstack +mods.actuallyadditions.crusher.recipeBuilder() + .input(item('minecraft:clay')) + .output(item('minecraft:diamond'), item('minecraft:diamond')) // Second output is optional, and modified by chance + .chance(100) // Optional, int + .register() + +mods.actuallyadditions.crusher.recipeBuilder() + .input(item('minecraft:diamond_block')) + .output(item('minecraft:diamond') * 12) + .register() + +mods.actuallyadditions.crusher.removeByInput(item('minecraft:bone')) +mods.actuallyadditions.crusher.removeByOutput(item('minecraft:sugar')) +//mods.actuallyadditions.crusher.removeAll() + +// Empowerer +// Turns 5 input items into an output item at the cost of power and time. Has a configurable color +mods.actuallyadditions.empowerer.recipeBuilder() + .mainInput(item('minecraft:clay')) // Optional, itemstack. if undefined and input has 5 items, mainInput uses the first itemstack input. Otherwise, errors. + .input(item('minecraft:clay'),item('minecraft:clay'),item('minecraft:clay'),item('minecraft:clay')) + .output(item('minecraft:diamond')) + .time(50) + .energy(1000) // Optional, int + .red(0.5) // Optional, float (default 0) + .green(0.3) // Optional, float (default 0) + .blue(0.2) // Optional, float (default 0) + .register() + +mods.actuallyadditions.empowerer.recipeBuilder() + .mainInput(item('minecraft:clay')) + .input(item('minecraft:diamond'),item('minecraft:clay'),item('minecraft:clay'),item('minecraft:clay')) + .output(item('minecraft:diamond') * 2) + .time(50) + .color(0.5, 0.3, 0.2) // Optional, float... shorthand for (red, green, blue). Must contain exactly 3 entries. "particleColor" and "color" are aliases + .register() + +mods.actuallyadditions.empowerer.recipeBuilder() + .mainInput(item('minecraft:diamond')) + .input(item('minecraft:diamond'),item('minecraft:gold_ingot'),item('minecraft:diamond'),item('minecraft:gold_ingot')) + .output(item('minecraft:dirt') * 8) + .time(50) + .particleColor(0x00FF88) // Optional, int. Hexadecimal color. "particleColor" and "color" are aliases + .register() + +mods.actuallyadditions.empowerer.recipeBuilder() + .input(item('minecraft:gold_ingot'),item('minecraft:clay'),item('minecraft:clay'),item('minecraft:clay'),item('minecraft:clay')) + .output(item('minecraft:diamond')) + .time(50) + .register() + +mods.actuallyadditions.empowerer.removeByInput(item('actuallyadditions:item_crystal')) +mods.actuallyadditions.empowerer.removeByOutput(item('actuallyadditions:item_misc:24')) +//mods.actuallyadditions.empowerer.removeAll() + +// Nether Mining Lens +// A weighted oredict for the block obtained via firing a Mining Lens at a block of Netherrack. The oredict must have a block, or the world will hang. +mods.actuallyadditions.nethermininglens.recipeBuilder() + .ore(ore('blockDiamond')) + .weight(100) + .register() + +mods.actuallyadditions.nethermininglens.recipeBuilder() + .ore('blockGold') + .weight(100) + .register() + +mods.actuallyadditions.nethermininglens.removeByOre(ore('oreQuartz')) +mods.actuallyadditions.nethermininglens.removeByOre('oreQuartz') +//mods.actuallyadditions.nethermininglens.removeAll() + +// Oil Gen +// Turns a fluid into power at a rate +mods.actuallyadditions.oilgen.recipeBuilder() + .fluidInput(fluid('water')) + .amount(1000) // Optional, uses the FluidStack amount if not defined. + .time(50) + .register() + +mods.actuallyadditions.oilgen.recipeBuilder() + .fluidInput(fluid('lava') * 50) + .time(100) + .register() + +mods.actuallyadditions.oilgen.removeByInput(fluid('canolaoil').getFluid()) +mods.actuallyadditions.oilgen.removeByInput('refinedcanolaoil') +//mods.actuallyadditions.oilgen.removeAll() + + +// Stone Mining Lens +// A weighted oredict for the block obtained via firing a Mining Lens at a block of Stone. The oredict must have a block, or the world will hang. +mods.actuallyadditions.stonemininglens.recipeBuilder() + .ore(ore('blockDiamond')) + .weight(100) + .register() + +mods.actuallyadditions.stonemininglens.recipeBuilder() + .ore('blockGold') + .weight(100) + .register() + +mods.actuallyadditions.stonemininglens.removeByOre(ore('oreCoal')) +mods.actuallyadditions.stonemininglens.removeByOre('oreLapis') +//mods.actuallyadditions.stonemininglens.removeAll() + +// Treasure Chest +// A weighted item, with a weight to obtain and a minimum and maximum amount. Obtained via right clicking a Treasure Chest spawning randomly on the sea floor. +mods.actuallyadditions.treasurechest.recipeBuilder() + .output(item('minecraft:clay')) + .weight(50) + .min(16) + .max(32) + .register() + +mods.actuallyadditions.treasurechest.removeByOutput(item('minecraft:iron_ingot')) +//mods.actuallyadditions.treasurechest.removeAll() + + + + + + diff --git a/gradle.properties b/gradle.properties index 3070d057b..9a0498abb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,6 +16,7 @@ debug_load_all_mods = true coremod_plugin_class_name = com.cleanroommc.groovyscript.core.GroovyScriptCore # Debug mod compat +debug_actually_additions = false debug_chisel = false debug_mekanism = false debug_thermal = 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 1724f12ca..e70675094 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -2,6 +2,7 @@ import com.cleanroommc.groovyscript.api.GroovyBlacklist; import com.cleanroommc.groovyscript.api.IDynamicGroovyProperty; +import com.cleanroommc.groovyscript.compat.mods.actuallyadditions.ActuallyAdditions; import com.cleanroommc.groovyscript.compat.mods.astralsorcery.AstralSorcery; import com.cleanroommc.groovyscript.compat.mods.bloodmagic.BloodMagic; import com.cleanroommc.groovyscript.compat.mods.botania.Botania; @@ -38,8 +39,9 @@ public class ModSupport implements IDynamicGroovyProperty { public static final ModSupport INSTANCE = new ModSupport(); // Just for Binding purposes - public static final Container CHISEL = new Container<>("chisel", "Chisel", Chisel::new); + public static final Container ACTUALLY_ADDITIONS = new Container<>("actuallyadditions", "Actually Additions", ActuallyAdditions::new, "aa"); public static final Container ASTRAL_SORCERY = new Container<>("astralsorcery", "Astral Sorcery", AstralSorcery::new, "astral", "astral_sorcery", "as"); + public static final Container CHISEL = new Container<>("chisel", "Chisel", Chisel::new); public static final Container ENDER_IO = new Container<>("enderio", "Ender IO", EnderIO::new, "eio"); public static final Container JEI = new Container<>("jei", "Just Enough Items", JustEnoughItems::new, "hei"); public static final Container THAUMCRAFT = new Container<>("thaumcraft", "Thaumcraft", Thaumcraft::new, "tc", "thaum"); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/ActuallyAdditions.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/ActuallyAdditions.java new file mode 100644 index 000000000..a34c0112c --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/ActuallyAdditions.java @@ -0,0 +1,29 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; + +public class ActuallyAdditions extends ModPropertyContainer { + + public final Crusher crusher = new Crusher(); + public final OilGen oilGen = new OilGen(); + public final Compost compost = new Compost(); + public final BallOfFur ballOfFur = new BallOfFur(); + public final TreasureChest treasureChest = new TreasureChest(); + public final Empowerer empowerer = new Empowerer(); + public final AtomicReconstructor atomicReconstructor = new AtomicReconstructor(); + public final NetherMiningLens netherMiningLens = new NetherMiningLens(); + public final StoneMiningLens stoneMiningLens = new StoneMiningLens(); + + public ActuallyAdditions() { + addRegistry(crusher); + addRegistry(oilGen); + addRegistry(compost); + addRegistry(ballOfFur); + addRegistry(treasureChest); + addRegistry(empowerer); + addRegistry(atomicReconstructor); + addRegistry(netherMiningLens); + addRegistry(stoneMiningLens); + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/AtomicReconstructor.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/AtomicReconstructor.java new file mode 100644 index 000000000..68807d4f4 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/AtomicReconstructor.java @@ -0,0 +1,118 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.lens.Lens; +import de.ellpeck.actuallyadditions.api.recipe.LensConversionRecipe; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +public class AtomicReconstructor extends VirtualizedRegistry { + + public AtomicReconstructor() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES::remove); + ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES.addAll(restoreFromBackup()); + } + + public LensConversionRecipe add(Ingredient input, ItemStack output, int energy, Lens type) { + LensConversionRecipe recipe = new LensConversionRecipe(input, output, energy, type); + add(recipe); + return recipe; + } + + public void add(LensConversionRecipe recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES.add(recipe); + } + + public boolean remove(LensConversionRecipe recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES.remove(recipe); + return true; + } + + public boolean removeByInput(IIngredient input) { + return ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES.removeIf(recipe -> { + boolean found = recipe.getInput().test(IngredientHelper.toItemStack(input)); + if (found) { + addBackup(recipe); + } + return found; + }); + } + + public boolean removeByOutput(ItemStack output) { + return ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES.removeIf(recipe -> { + boolean matches = ItemStack.areItemStacksEqual(recipe.getOutput(), output); + if (matches) { + addBackup(recipe); + } + return matches; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES.forEach(this::addBackup); + ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.RECONSTRUCTOR_LENS_CONVERSION_RECIPES) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private int energyUse = 1; + + public RecipeBuilder energyUse(int energyUse) { + this.energyUse = energyUse; + return this; + } + + public RecipeBuilder energy(int energy) { + this.energyUse = energy; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Atomic Reconstructor recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + msg.add(energyUse <= 0, "energyUse must be an integer greater than 0, yet it was {}", energyUse); + } + + @Override + public @Nullable LensConversionRecipe register() { + if (!validate()) return null; + LensConversionRecipe recipe = new LensConversionRecipe(input.get(0).toMcIngredient(), output.get(0), energyUse, ActuallyAdditionsAPI.lensDefaultConversion); + ModSupport.ACTUALLY_ADDITIONS.get().atomicReconstructor.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/BallOfFur.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/BallOfFur.java new file mode 100644 index 000000000..973ef4d69 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/BallOfFur.java @@ -0,0 +1,99 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +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 de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.recipe.BallOfFurReturn; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +public class BallOfFur extends VirtualizedRegistry { + + public BallOfFur() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.BALL_OF_FUR_RETURN_ITEMS::remove); + ActuallyAdditionsAPI.BALL_OF_FUR_RETURN_ITEMS.addAll(restoreFromBackup()); + } + + public BallOfFurReturn add(ItemStack drop, int chance) { + BallOfFurReturn recipe = new BallOfFurReturn(drop, chance); + add(recipe); + return recipe; + } + + public void add(BallOfFurReturn recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.BALL_OF_FUR_RETURN_ITEMS.add(recipe); + } + + public boolean remove(BallOfFurReturn recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.BALL_OF_FUR_RETURN_ITEMS.remove(recipe); + return true; + } + + public boolean removeByOutput(ItemStack output) { + return ActuallyAdditionsAPI.BALL_OF_FUR_RETURN_ITEMS.removeIf(recipe -> { + boolean found = ItemStack.areItemStacksEqual(recipe.returnItem, output); + if (found) { + addBackup(recipe); + } + return found; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.BALL_OF_FUR_RETURN_ITEMS.forEach(this::addBackup); + ActuallyAdditionsAPI.BALL_OF_FUR_RETURN_ITEMS.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.BALL_OF_FUR_RETURN_ITEMS) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private int weight; + + public RecipeBuilder weight(int weight) { + this.weight = weight; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Ball Of Fur recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 0, 0, 1, 1); + validateFluids(msg); + msg.add(weight < 0, "weight must be a non negative integer, yet it was {}", weight); + } + + @Override + public @Nullable BallOfFurReturn register() { + if (!validate()) return null; + BallOfFurReturn recipe = new BallOfFurReturn(output.get(0), weight); + ModSupport.ACTUALLY_ADDITIONS.get().ballOfFur.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Compost.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Compost.java new file mode 100644 index 000000000..4a9877bbc --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Compost.java @@ -0,0 +1,125 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.recipe.CompostRecipe; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +public class Compost extends VirtualizedRegistry { + + public Compost() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.COMPOST_RECIPES::remove); + ActuallyAdditionsAPI.COMPOST_RECIPES.addAll(restoreFromBackup()); + } + + public CompostRecipe add(Ingredient input, Block inputDisplay, ItemStack output, Block outputDisplay) { + return add(input, inputDisplay.getDefaultState(), output, outputDisplay.getDefaultState()); + } + + public CompostRecipe add(Ingredient input, IBlockState inputDisplay, ItemStack output, IBlockState outputDisplay) { + CompostRecipe recipe = new CompostRecipe(input, inputDisplay, output, outputDisplay); + add(recipe); + return recipe; + } + + public void add(CompostRecipe recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.COMPOST_RECIPES.add(recipe); + } + + public boolean remove(CompostRecipe recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.COMPOST_RECIPES.remove(recipe); + return true; + } + + public boolean removeByInput(IIngredient input) { + return ActuallyAdditionsAPI.COMPOST_RECIPES.removeIf(recipe -> { + boolean found = recipe.getInput().test(IngredientHelper.toItemStack(input)); + if (found) { + addBackup(recipe); + } + return found; + }); + } + + public boolean removeByOutput(ItemStack output) { + return ActuallyAdditionsAPI.COMPOST_RECIPES.removeIf(recipe -> { + boolean matches = ItemStack.areItemStacksEqual(recipe.getOutput(), output); + if (matches) { + addBackup(recipe); + } + return matches; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.COMPOST_RECIPES.forEach(this::addBackup); + ActuallyAdditionsAPI.COMPOST_RECIPES.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.COMPOST_RECIPES) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private IBlockState inputDisplay; + private IBlockState outputDisplay; + + public RecipeBuilder inputDisplay(IBlockState inputDisplay) { + this.inputDisplay = inputDisplay; + return this; + } + + public RecipeBuilder outputDisplay(IBlockState outputDisplay) { + this.outputDisplay = outputDisplay; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Compost recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 1); + validateFluids(msg); + msg.add(inputDisplay == null, "inputDisplay must be defined"); + msg.add(outputDisplay == null, "inputDisplay must be defined"); + } + + @Override + public @Nullable CompostRecipe register() { + if (!validate()) return null; + CompostRecipe recipe = new CompostRecipe(input.get(0).toMcIngredient(), inputDisplay, output.get(0), outputDisplay); + ModSupport.ACTUALLY_ADDITIONS.get().compost.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Crusher.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Crusher.java new file mode 100644 index 000000000..d64dc3f1a --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Crusher.java @@ -0,0 +1,116 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.recipe.CrusherRecipe; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +public class Crusher extends VirtualizedRegistry { + + public Crusher() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.CRUSHER_RECIPES::remove); + ActuallyAdditionsAPI.CRUSHER_RECIPES.addAll(restoreFromBackup()); + } + + public CrusherRecipe add(Ingredient input, ItemStack output) { + return add(input, output, ItemStack.EMPTY, 100); + } + + public CrusherRecipe add(Ingredient input, ItemStack output, ItemStack secondaryOutput, int chance) { + CrusherRecipe recipe = new CrusherRecipe(input, output, secondaryOutput, chance); + add(recipe); + return recipe; + } + + public void add(CrusherRecipe recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.CRUSHER_RECIPES.add(recipe); + } + + public boolean remove(CrusherRecipe recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.CRUSHER_RECIPES.remove(recipe); + return true; + } + + public boolean removeByInput(IIngredient input) { + return ActuallyAdditionsAPI.CRUSHER_RECIPES.removeIf(recipe -> { + boolean found = recipe.getInput().test(IngredientHelper.toItemStack(input)); + if (found) { + addBackup(recipe); + } + return found; + }); + } + + public boolean removeByOutput(ItemStack output) { + return ActuallyAdditionsAPI.CRUSHER_RECIPES.removeIf(recipe -> { + boolean matches = ItemStack.areItemStacksEqual(recipe.getOutputOne(), output); + if (matches) { + addBackup(recipe); + } + return matches; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.CRUSHER_RECIPES.forEach(this::addBackup); + ActuallyAdditionsAPI.CRUSHER_RECIPES.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.CRUSHER_RECIPES) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private int chance; + + public RecipeBuilder chance(int chance) { + this.chance = chance; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Crusher recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 1, 1, 2); + validateFluids(msg); + msg.add(chance < 0 || chance > 100, "chance must be a non negative integer less than 100, yet it was {}", chance); + } + + @Override + public @Nullable CrusherRecipe register() { + if (!validate()) return null; + CrusherRecipe recipe = new CrusherRecipe(input.get(0).toMcIngredient(), output.get(0), output.size() < 2 ? ItemStack.EMPTY : output.get(1), chance); + ModSupport.ACTUALLY_ADDITIONS.get().crusher.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Empowerer.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Empowerer.java new file mode 100644 index 000000000..95d08a053 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/Empowerer.java @@ -0,0 +1,194 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.recipe.EmpowererRecipe; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; + +public class Empowerer extends VirtualizedRegistry { + + public Empowerer() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.EMPOWERER_RECIPES::remove); + ActuallyAdditionsAPI.EMPOWERER_RECIPES.addAll(restoreFromBackup()); + } + + public EmpowererRecipe add(Ingredient input, ItemStack output, Ingredient modifier1, Ingredient modifier2, Ingredient modifier3, Ingredient modifier4, int energyPerStand, int time, float[] particleColor) { + EmpowererRecipe recipe = new EmpowererRecipe(input, output, modifier1, modifier2, modifier3, modifier4, energyPerStand, time, particleColor); + add(recipe); + return recipe; + } + + public void add(EmpowererRecipe recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.EMPOWERER_RECIPES.add(recipe); + } + + public boolean remove(EmpowererRecipe recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.EMPOWERER_RECIPES.remove(recipe); + return true; + } + + public boolean removeByInput(IIngredient input) { + return ActuallyAdditionsAPI.EMPOWERER_RECIPES.removeIf(recipe -> { + boolean found = recipe.getInput().test(IngredientHelper.toItemStack(input)); + if (found) { + addBackup(recipe); + } + return found; + }); + } + + public boolean removeByOutput(ItemStack output) { + return ActuallyAdditionsAPI.EMPOWERER_RECIPES.removeIf(recipe -> { + boolean matches = ItemStack.areItemStacksEqual(recipe.getOutput(), output); + if (matches) { + addBackup(recipe); + } + return matches; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.EMPOWERER_RECIPES.forEach(this::addBackup); + ActuallyAdditionsAPI.EMPOWERER_RECIPES.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.EMPOWERER_RECIPES) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private IIngredient mainInput; + private int energyPerStand; + private int time; + private float red = 0; + private float green = 0; + private float blue = 0; + + public RecipeBuilder mainInput(IIngredient mainInput) { + this.mainInput = mainInput; + return this; + } + + public RecipeBuilder energyPerStand(int energyPerStand) { + this.energyPerStand = energyPerStand; + return this; + } + + public RecipeBuilder energy(int energy) { + this.energyPerStand = energy; + return this; + } + + public RecipeBuilder time(int time) { + this.time = time; + return this; + } + + public RecipeBuilder particleColor(float... color) { + if (color.length != 3) { + GroovyLog.get().warn("Error setting color in Actually Additions Empowerer recipe. color must contain 3 floats, yet it contained {}", color.length); + return this; + } + this.red = color[0]; + this.green = color[1]; + this.blue = color[2]; + return this; + } + + public RecipeBuilder color(float... color) { + return this.particleColor(color); + } + + public RecipeBuilder particleColor(int hex) { + Color color = new Color(hex); + this.red = color.getRed() / 255f; + this.green = color.getGreen() / 255f; + this.blue = color.getBlue() / 255f; + return this; + } + + public RecipeBuilder color(int hex) { + return this.particleColor(hex); + } + + public RecipeBuilder red(float red) { + this.red = red; + return this; + } + + public RecipeBuilder green(float green) { + this.green = green; + return this; + } + + public RecipeBuilder blue(float blue) { + this.blue = blue; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Empowerer recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + if (input.size() == 5 && mainInput == null) { + mainInput = input.remove(0); + } + validateItems(msg, 4, 4, 1, 1); + validateFluids(msg); + msg.add(mainInput == null, "mainInput must be defined"); + msg.add(energyPerStand < 0, "energyPerStand must be a non negative integer, yet it was {}", energyPerStand); + msg.add(time <= 0, "time must be an integer greater than 0, yet it was {}", time); + msg.add(red < 0 || red > 1, "red must be a float between 0 and 1, yet it was {}", red); + msg.add(green < 0 || green > 1, "green must be a float between 0 and 1, yet it was {}", green); + msg.add(blue < 0 || blue > 1, "blue must be a float between 0 and 1, yet it was {}", blue); + } + + @Override + public @Nullable EmpowererRecipe register() { + if (!validate()) return null; + EmpowererRecipe recipe = new EmpowererRecipe( + mainInput.toMcIngredient(), + output.get(0), + input.get(0).toMcIngredient(), + input.get(1).toMcIngredient(), + input.get(2).toMcIngredient(), + input.get(3).toMcIngredient(), + energyPerStand, + time, + new float[]{red, green, blue} + ); + ModSupport.ACTUALLY_ADDITIONS.get().empowerer.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/NetherMiningLens.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/NetherMiningLens.java new file mode 100644 index 000000000..94618757f --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/NetherMiningLens.java @@ -0,0 +1,115 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +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 de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.recipe.WeightedOre; +import org.jetbrains.annotations.Nullable; + +public class NetherMiningLens extends VirtualizedRegistry { + + public NetherMiningLens() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.NETHERRACK_ORES::remove); + ActuallyAdditionsAPI.NETHERRACK_ORES.addAll(restoreFromBackup()); + } + + public WeightedOre add(String oreName, int weight) { + WeightedOre recipe = new WeightedOre(oreName, weight); + add(recipe); + return recipe; + } + + public void add(WeightedOre recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.NETHERRACK_ORES.add(recipe); + } + + public boolean remove(WeightedOre recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.NETHERRACK_ORES.remove(recipe); + return true; + } + + public boolean removeByOre(OreDictIngredient ore) { + return this.removeByOre(ore.getOreDict()); + } + + public boolean removeByOre(String oreName) { + return ActuallyAdditionsAPI.NETHERRACK_ORES.removeIf(recipe -> { + boolean found = oreName.equals(recipe.name); + if (found) { + addBackup(recipe); + } + return found; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.NETHERRACK_ORES.forEach(this::addBackup); + ActuallyAdditionsAPI.NETHERRACK_ORES.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.NETHERRACK_ORES) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private String ore; + private int weight; + + public RecipeBuilder ore(String ore) { + this.ore = ore; + return this; + } + + public RecipeBuilder ore(OreDictIngredient ore) { + this.ore = ore.getOreDict(); + return this; + } + + public RecipeBuilder weight(int weight) { + this.weight = weight; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Nether Mining Lens recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg); + validateFluids(msg); + msg.add(ore == null, "ore must be defined"); + msg.add(weight < 0, "weight must be a non negative integer, yet it was {}", weight); + } + + @Override + public @Nullable WeightedOre register() { + if (!validate()) return null; + WeightedOre recipe = new WeightedOre(ore, weight); + ModSupport.ACTUALLY_ADDITIONS.get().netherMiningLens.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/OilGen.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/OilGen.java new file mode 100644 index 000000000..64ae578dd --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/OilGen.java @@ -0,0 +1,125 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +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 de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.recipe.OilGenRecipe; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import org.jetbrains.annotations.Nullable; + +public class OilGen extends VirtualizedRegistry { + + public OilGen() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.OIL_GENERATOR_RECIPES::remove); + ActuallyAdditionsAPI.OIL_GENERATOR_RECIPES.addAll(restoreFromBackup()); + } + + public OilGenRecipe add(Fluid input, int amount, int time) { + return add(input.getName(), amount, time); + } + + public OilGenRecipe add(String input, int amount, int time) { + OilGenRecipe recipe = new OilGenRecipe(input, amount, time); + add(recipe); + return recipe; + } + + public void add(OilGenRecipe recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.OIL_GENERATOR_RECIPES.add(recipe); + } + + public boolean remove(OilGenRecipe recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.OIL_GENERATOR_RECIPES.remove(recipe); + return true; + } + + public boolean removeByInput(FluidStack fluid) { + return this.removeByInput(fluid.getFluid()); + } + + public boolean removeByInput(Fluid fluid) { + return this.removeByInput(fluid.getName()); + } + + public boolean removeByInput(String fluid) { + return ActuallyAdditionsAPI.OIL_GENERATOR_RECIPES.removeIf(recipe -> { + boolean found = fluid.equals(recipe.fluidName); + if (found) { + addBackup(recipe); + } + return found; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.OIL_GENERATOR_RECIPES.forEach(this::addBackup); + ActuallyAdditionsAPI.OIL_GENERATOR_RECIPES.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.OIL_GENERATOR_RECIPES) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private int amount; + private int time; + + public RecipeBuilder fluidInput(FluidStack fluid) { + this.fluidInput.add(fluid); + if (this.amount == 0) this.amount = fluid.amount; + return this; + } + + public RecipeBuilder amount(int amount) { + this.amount = amount; + return this; + } + + public RecipeBuilder time(int time) { + this.time = time; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Oil Gen recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg); + validateFluids(msg, 1, 1, 0, 0); + msg.add(amount < 0, "amount must be a non negative integer, yet it was {}", amount); + msg.add(time < 0, "time must be a non negative integer, yet it was {}", time); + } + + @Override + public @Nullable OilGenRecipe register() { + if (!validate()) return null; + OilGenRecipe recipe = new OilGenRecipe(fluidInput.get(0).getFluid().getName(), amount, time); + ModSupport.ACTUALLY_ADDITIONS.get().oilGen.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/StoneMiningLens.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/StoneMiningLens.java new file mode 100644 index 000000000..526fe3c70 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/StoneMiningLens.java @@ -0,0 +1,115 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +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 de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.recipe.WeightedOre; +import org.jetbrains.annotations.Nullable; + +public class StoneMiningLens extends VirtualizedRegistry { + + public StoneMiningLens() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.STONE_ORES::remove); + ActuallyAdditionsAPI.STONE_ORES.addAll(restoreFromBackup()); + } + + public WeightedOre add(String oreName, int weight) { + WeightedOre recipe = new WeightedOre(oreName, weight); + add(recipe); + return recipe; + } + + public void add(WeightedOre recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.STONE_ORES.add(recipe); + } + + public boolean remove(WeightedOre recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.STONE_ORES.remove(recipe); + return true; + } + + public boolean removeByOre(OreDictIngredient ore) { + return this.removeByOre(ore.getOreDict()); + } + + public boolean removeByOre(String oreName) { + return ActuallyAdditionsAPI.STONE_ORES.removeIf(recipe -> { + boolean found = oreName.equals(recipe.name); + if (found) { + addBackup(recipe); + } + return found; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.STONE_ORES.forEach(this::addBackup); + ActuallyAdditionsAPI.STONE_ORES.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.STONE_ORES) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private String ore; + private int weight; + + public RecipeBuilder ore(String ore) { + this.ore = ore; + return this; + } + + public RecipeBuilder ore(OreDictIngredient ore) { + this.ore = ore.getOreDict(); + return this; + } + + public RecipeBuilder weight(int weight) { + this.weight = weight; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Stone Mining Lens recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg); + validateFluids(msg); + msg.add(ore == null, "ore must be defined"); + msg.add(weight < 0, "weight must be a non negative integer, yet it was {}", weight); + } + + @Override + public @Nullable WeightedOre register() { + if (!validate()) return null; + WeightedOre recipe = new WeightedOre(ore, weight); + ModSupport.ACTUALLY_ADDITIONS.get().stoneMiningLens.add(recipe); + return recipe; + } + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/TreasureChest.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/TreasureChest.java new file mode 100644 index 000000000..fb628381f --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/actuallyadditions/TreasureChest.java @@ -0,0 +1,114 @@ +package com.cleanroommc.groovyscript.compat.mods.actuallyadditions; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +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 de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; +import de.ellpeck.actuallyadditions.api.recipe.TreasureChestLoot; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +public class TreasureChest extends VirtualizedRegistry { + + public TreasureChest() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(ActuallyAdditionsAPI.TREASURE_CHEST_LOOT::remove); + ActuallyAdditionsAPI.TREASURE_CHEST_LOOT.addAll(restoreFromBackup()); + } + + public TreasureChestLoot add(ItemStack returnItem, int chance, int minAmount, int maxAmount) { + TreasureChestLoot recipe = new TreasureChestLoot(returnItem, chance, minAmount, maxAmount); + add(recipe); + return recipe; + } + + public void add(TreasureChestLoot recipe) { + if (recipe == null) return; + addScripted(recipe); + ActuallyAdditionsAPI.TREASURE_CHEST_LOOT.add(recipe); + } + + public boolean remove(TreasureChestLoot recipe) { + if (recipe == null) return false; + addBackup(recipe); + ActuallyAdditionsAPI.TREASURE_CHEST_LOOT.remove(recipe); + return true; + } + + public boolean removeByOutput(ItemStack output) { + return ActuallyAdditionsAPI.TREASURE_CHEST_LOOT.removeIf(recipe -> { + boolean matches = ItemStack.areItemStacksEqual(recipe.returnItem, output); + if (matches) { + addBackup(recipe); + } + return matches; + }); + } + + public void removeAll() { + ActuallyAdditionsAPI.TREASURE_CHEST_LOOT.forEach(this::addBackup); + ActuallyAdditionsAPI.TREASURE_CHEST_LOOT.clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(ActuallyAdditionsAPI.TREASURE_CHEST_LOOT) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private int weight; + private int min; + private int max; + + public RecipeBuilder weight(int weight) { + this.weight = weight; + return this; + } + + public RecipeBuilder min(int min) { + this.min = min; + return this; + } + + public RecipeBuilder max(int max) { + this.max = max; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Actually Additions Treasure Chest Loot recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 0, 0, 1, 1); + validateFluids(msg); + msg.add(weight < 0, "weight must be a non negative integer, yet it was {}", weight); + msg.add(min < 0, "min must be a non negative integer, yet it was {}", min); + msg.add(max < 0, "max must be a non negative integer, yet it was {}", max); + msg.add(max < min, "max must be greater than min, yet max was {} while min was {}", max, min); + } + + @Override + public @Nullable TreasureChestLoot register() { + if (!validate()) return null; + TreasureChestLoot recipe = new TreasureChestLoot(output.get(0), weight, min, max); + ModSupport.ACTUALLY_ADDITIONS.get().treasureChest.add(recipe); + return recipe; + } + } +}