diff --git a/build.gradle b/build.gradle index f6e4a78dc..526ceda5c 100644 --- a/build.gradle +++ b/build.gradle @@ -302,6 +302,12 @@ dependencies { runtimeOnly rfg.deobf('net.sengir.forestry:forestry_1.12.2:5.8.2.422') runtimeOnly rfg.deobf('curse.maven:jei-bees-248370:2490058') } + + compileOnly rfg.deobf('curse.maven:advancedmortars-283777:2780626') + if (project.debug_adv_mortars.toBoolean()) { + runtimeOnly rfg.deobf('curse.maven:advancedmortars-283777:2780626') + } + } processResources { diff --git a/examples/advancedmortars.groovy b/examples/advancedmortars.groovy new file mode 100644 index 000000000..446f90a11 --- /dev/null +++ b/examples/advancedmortars.groovy @@ -0,0 +1,49 @@ + +// add(List types, ItemStack output, int duration, List inputs) +mods.advancedmortars.Mortar.add( + ['stone'], + item('minecraft:diamond') * 4, + 4, + [ore('ingotGold')] +) + +mods.advancedmortars.Mortar.add( + ['stone'], + item('minecraft:tnt'), + 4, + [ore('ingotGold')] +) + +// add(List types, ItemStack output, int duration, ItemStack secondaryOutput, float secondaryOutputChance, List inputs) +mods.advancedmortars.Mortar.add( + ['iron', 'wood'], + item('minecraft:tnt') * 5, + 4, + item('minecraft:tnt'), + 0.7, + [ore('ingotIron'), ore('ingotIron'), ore('ingotIron'), ore('ingotIron'), // max 8 + ore('ingotIron'), ore('ingotIron'), ore('ingotIron'), ore('ingotIron')] +) + +mods.advancedmortars.Mortar.recipeBuilder() + .type('stone') // EnumMortarType ('wood', 'stone', 'iron', 'diamond', 'gold', 'obsidian', 'emerald') + .duration(2) // int + .output(item('minecraft:grass')) // ItemStack + .input(item('minecraft:dirt')) // IIngredient + .register() + +mods.advancedmortars.Mortar.recipeBuilder() + .type('emerald') + .duration(4) + .output(item('minecraft:wheat_seeds') * 16) + .secondaryOutput(item('minecraft:melon_seeds')) // ItemStack + .input(ore('cropWheat')) + .register() + +mods.advancedmortars.Mortar.recipeBuilder() + .type('obsidian') + .duration(8) + .output(item('minecraft:wheat_seeds') * 16) + .secondaryOutput(item('minecraft:melon_seeds'), 0.5) // ItemStack, float + .input(ore('cropWheat')) + .register() \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index a7fe471af..2f995f652 100644 --- a/gradle.properties +++ b/gradle.properties @@ -35,6 +35,7 @@ debug_roots = false debug_blood_magic = false debug_tinkers = false debug_extended_crafting = false +debug_adv_mortars = false debug_botania = false debug_forestry = false debug_inspirations = 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 575e8f49c..6263e14af 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -3,6 +3,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.advancedmortars.AdvancedMortars; import com.cleanroommc.groovyscript.compat.mods.appliedenergistics2.AppliedEnergistics2; import com.cleanroommc.groovyscript.compat.mods.astralsorcery.AstralSorcery; import com.cleanroommc.groovyscript.compat.mods.bloodmagic.BloodMagic; @@ -66,6 +67,7 @@ public class ModSupport implements IDynamicGroovyProperty { public static final Container INDUSTRIALCRAFT = new Container<>("ic2", "Industrial Craft 2", IC2::new, "industrialcraft"); public static final Container EXTENDED_CRAFTING = new Container<>("extendedcrafting", "Extended Crafting", ExtendedCrafting::new); public static final Container FORESTRY = new Container<>("forestry", "Forestry", Forestry::new); + public static final Container ADVANCED_MORTARS = new Container<>("advancedmortars", "Advanced Mortars", AdvancedMortars::new); public static final Container WOOT = new Container<>("woot", "Woot", Woot::new); public static final Container INSPIRATIONS = new Container<>("inspirations", "Inspirations", Inspirations::new); public static final Container COMPACT_MACHINES = new Container<>("compactmachines3", "Compact Machines 3", CompactMachines::new, "compactmachines"); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/advancedmortars/AdvancedMortars.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/advancedmortars/AdvancedMortars.java new file mode 100644 index 000000000..759d0b2c0 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/advancedmortars/AdvancedMortars.java @@ -0,0 +1,13 @@ +package com.cleanroommc.groovyscript.compat.mods.advancedmortars; + +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; + +public class AdvancedMortars extends ModPropertyContainer { + + public final Mortar mortar = new Mortar(); + + public AdvancedMortars() { + addRegistry(mortar); + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/advancedmortars/Mortar.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/advancedmortars/Mortar.java new file mode 100644 index 000000000..093590850 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/advancedmortars/Mortar.java @@ -0,0 +1,183 @@ +package com.cleanroommc.groovyscript.compat.mods.advancedmortars; + +import com.cleanroommc.groovyscript.api.GroovyBlacklist; +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.core.mixin.advancedmortars.RegistryRecipeMortarAccessor; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import com.codetaylor.mc.advancedmortars.modules.mortar.api.MortarAPI; +import com.codetaylor.mc.advancedmortars.modules.mortar.recipe.RecipeMortar; +import com.codetaylor.mc.advancedmortars.modules.mortar.reference.EnumMortarType; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class Mortar extends VirtualizedRegistry { + + public Mortar() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + @GroovyBlacklist + public void onReload() { + removeScripted().forEach(recipe -> ((RegistryRecipeMortarAccessor) MortarAPI.RECIPE_REGISTRY).getRecipeMap().values().forEach(list -> list.removeIf(r -> r == recipe))); + restoreFromBackup().forEach(recipe -> getTypes(recipe).forEach(type -> add(type, recipe))); + } + + public void add(List types, ItemStack output, int duration, List inputs) { + add(types, output, duration, ItemStack.EMPTY, 0.0f, inputs); + } + + public void add(List types, ItemStack output, int duration, ItemStack secondaryOutput, float secondaryOutputChance, List inputs) { + if (inputs == null || inputs.size() == 0) return; + if (inputs.size() > 8) { + GroovyLog.msg("Error adding Advanced Mortars recipe") + .add("maximum number of 8 input ingredients exceeded: " + inputs.size()) + .error() + .post(); + return; + } + for (String type : types) { + EnumMortarType enumMortarType = EnumMortarType.fromName(type); + if (enumMortarType == null) { + GroovyLog.msg("Error adding Advanced Mortars recipe") + .add("invalid mortar type: " + type) + .add("valid types are: " + Arrays.toString(EnumMortarType.NAMES)) + .error() + .post(); + return; + } + add(enumMortarType, new RecipeMortar(output, duration, secondaryOutput, secondaryOutputChance, IngredientHelper.toIngredientNonNullList(inputs))); + } + } + + public void add(EnumMortarType type, RecipeMortar recipe) { + List list = ((RegistryRecipeMortarAccessor) MortarAPI.RECIPE_REGISTRY).getRecipeMap().computeIfAbsent(type, (k) -> new ArrayList<>()); + list.add(recipe); + addScripted(recipe); + } + + public static List getTypes(RecipeMortar recipe) { + return ((RegistryRecipeMortarAccessor) MortarAPI.RECIPE_REGISTRY) + .getRecipeMap() + .entrySet() + .stream() + .filter(x -> x.getValue().contains(recipe)) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + } + + public class RecipeBuilder extends AbstractRecipeBuilder { + + private final List types = new ArrayList<>(); + private int duration; + private ItemStack secondaryOutput = ItemStack.EMPTY; + private float secondaryOutputChance = 1.0f; + + public RecipeBuilder type(String... type) { + this.types.addAll(Arrays.asList(type)); + return this; + } + + public RecipeBuilder type(List type) { + this.types.addAll(type); + return this; + } + + public RecipeBuilder wood() { + this.types.add("wood"); + return this; + } + + public RecipeBuilder stone() { + this.types.add("stone"); + return this; + } + + public RecipeBuilder iron() { + this.types.add("iron"); + return this; + } + + public RecipeBuilder diamond() { + this.types.add("diamond"); + return this; + } + + public RecipeBuilder gold() { + this.types.add("gold"); + return this; + } + + public RecipeBuilder obsidian() { + this.types.add("obsidian"); + return this; + } + + public RecipeBuilder emerald() { + this.types.add("emerald"); + return this; + } + + public RecipeBuilder duration(int duration) { + this.duration = duration; + return this; + } + + public RecipeBuilder secondaryOutput(ItemStack itemStack) { + this.secondaryOutput = itemStack; + return this; + } + + public RecipeBuilder secondaryOutput(ItemStack itemStack, float chance) { + this.secondaryOutput = itemStack; + this.secondaryOutputChance = chance; + return this; + } + + public RecipeBuilder secondaryOutputChance(float chance) { + this.secondaryOutputChance = chance; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Advanced Mortars recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 1, 8, 1, 1); + for (String type : types) { + EnumMortarType enumMortarType = EnumMortarType.fromName(type); + if (enumMortarType == null) { + msg.add("invalid mortar type: " + type).add("valid types are: " + Arrays.toString(EnumMortarType.NAMES)); + } + } + if (secondaryOutputChance > 1.0f) { + secondaryOutputChance = 1.0f; + } + } + + @Override + public @Nullable RecipeMortar register() { + if (!validate()) return null; + RecipeMortar recipe = new RecipeMortar(output.get(0), duration, secondaryOutput, secondaryOutputChance, IngredientHelper.toIngredientNonNullList(input)); + types.stream().map(EnumMortarType::fromName).forEach(enumMortarType -> add(enumMortarType, recipe)); + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java index 8b9cdc911..7cabea85e 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java @@ -11,6 +11,7 @@ public class LateMixin implements ILateMixinLoader { public static final List modMixins = ImmutableList.of( + "advancedmortars", "appliedenergistics2", "astralsorcery", "bloodmagic", diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/advancedmortars/RegistryRecipeMortarAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/advancedmortars/RegistryRecipeMortarAccessor.java new file mode 100644 index 000000000..5d0718e4e --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/advancedmortars/RegistryRecipeMortarAccessor.java @@ -0,0 +1,18 @@ +package com.cleanroommc.groovyscript.core.mixin.advancedmortars; + +import com.codetaylor.mc.advancedmortars.modules.mortar.recipe.RecipeMortar; +import com.codetaylor.mc.advancedmortars.modules.mortar.recipe.RegistryRecipeMortar; +import com.codetaylor.mc.advancedmortars.modules.mortar.reference.EnumMortarType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.EnumMap; +import java.util.List; + +@Mixin(value = RegistryRecipeMortar.class, remap = false) +public interface RegistryRecipeMortarAccessor { + + @Accessor + EnumMap> getRecipeMap(); + +} diff --git a/src/main/resources/mixin.groovyscript.advancedmortars.json b/src/main/resources/mixin.groovyscript.advancedmortars.json new file mode 100644 index 000000000..409a3ffc7 --- /dev/null +++ b/src/main/resources/mixin.groovyscript.advancedmortars.json @@ -0,0 +1,10 @@ +{ + "package": "com.cleanroommc.groovyscript.core.mixin.advancedmortars", + "refmap": "mixins.groovyscript.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "RegistryRecipeMortarAccessor" + ] +} \ No newline at end of file