From 8b4c87c6a8982ff3863333a26a5153e6de27340e Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sun, 2 Jul 2023 02:28:43 -0700 Subject: [PATCH 1/3] implement Woot compat --- build.gradle | 10 +- examples/woot.groovy | 196 +++++++++++++++++ gradle.properties | 3 +- .../groovyscript/compat/mods/ModSupport.java | 2 + .../groovyscript/compat/mods/woot/Drops.java | 202 ++++++++++++++++++ .../compat/mods/woot/MobConfig.java | 93 ++++++++ .../groovyscript/compat/mods/woot/Policy.java | 198 +++++++++++++++++ .../compat/mods/woot/Spawning.java | 159 ++++++++++++++ .../compat/mods/woot/StygianIronAnvil.java | 132 ++++++++++++ .../groovyscript/compat/mods/woot/Woot.java | 20 ++ .../groovyscript/core/LateMixin.java | 21 +- .../core/mixin/woot/AnvilManagerAccessor.java | 15 ++ .../core/mixin/woot/CustomDropAccessor.java | 26 +++ .../woot/CustomDropsRepositoryAccessor.java | 16 ++ .../mixin/woot/PolicyRepositoryAccessor.java | 44 ++++ .../woot/SpawnRecipeRepositoryAccessor.java | 19 ++ .../WootConfigurationManagerAccessor.java | 30 +++ .../resources/mixin.groovyscript.woot.json | 15 ++ 18 files changed, 1196 insertions(+), 5 deletions(-) create mode 100644 examples/woot.groovy create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Drops.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/MobConfig.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Policy.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Spawning.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/StygianIronAnvil.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Woot.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/AnvilManagerAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropsRepositoryAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/PolicyRepositoryAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/SpawnRecipeRepositoryAccessor.java create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/WootConfigurationManagerAccessor.java create mode 100644 src/main/resources/mixin.groovyscript.woot.json diff --git a/build.gradle b/build.gradle index 0fc29a6ee..a9c620cb3 100644 --- a/build.gradle +++ b/build.gradle @@ -126,9 +126,12 @@ dependencies { } compileOnly rfg.deobf('curse.maven:guide-api-228832:2645992') + if (project.debug_blood_magic.toBoolean() || project.debug_woot.toBoolean()) { + runtimeOnly rfg.deobf('curse.maven:guide-api-228832:2645992') + } + compileOnly rfg.deobf('curse.maven:blood-magic-224791:2822288') if (project.debug_blood_magic.toBoolean()) { - runtimeOnly rfg.deobf('curse.maven:guide-api-228832:2645992') runtimeOnly rfg.deobf('curse.maven:blood-magic-224791:2822288') } @@ -235,6 +238,11 @@ dependencies { runtimeOnly rfg.deobf('curse.maven:immersive_engineering-231951:2974106') } + compileOnly rfg.deobf("curse.maven:woot-244049:2712670") + if (project.debug_woot.toBoolean()) { + runtimeOnly rfg.deobf('curse.maven:woot-244049:2712670') + } + compileOnly 'slimeknights.mantle:Mantle:1.12-1.3.3.55' compileOnly 'slimeknights:TConstruct:1.12.2-2.13.0.190' compileOnly rfg.deobf('curse.maven:constructs-armory-287683:3174535') diff --git a/examples/woot.groovy b/examples/woot.groovy new file mode 100644 index 000000000..81065574d --- /dev/null +++ b/examples/woot.groovy @@ -0,0 +1,196 @@ +//import ipsis.woot.configuration.EnumConfigKey +//import ipsis.woot.util.WootMobName + +import ipsis.woot.util.WootMobName + + +// Note: +// Drops, Spawning, Policy, and Mob Config can also be controlled via .json config file +// Drops can also be modified via `custom_drops.json`, +// Spawning can also be modified via `factory_config.json`, +// Policy and Mob Config can also be modified via `factory_config.json`. + + +// Stygian Iron Anvil: +// Has a catalyst (which may or may not be consumed) placed on the anvil, with the input items thrown atop the base. +// The anvil must be above a Magma Block and then right clicked with a Hammer, converting the input items into the output item. +mods.woot.stygianironanvil.recipeBuilder() + .input(item('minecraft:diamond'),item('minecraft:diamond'),item('minecraft:diamond')) + .base(item('minecraft:gold_ingot')) + .output(item('minecraft:clay')) + .preserveBase(true) // Optional, boolean. Defaults to false + .register() + +mods.woot.anvil.recipeBuilder() + .input(item('minecraft:diamond'), + item('minecraft:gold_ingot'), + item('minecraft:iron_ingot'), + item('minecraft:diamond_block'), + item('minecraft:gold_block'), + item('minecraft:iron_bars'), + item('minecraft:magma')) // Accepts more than 6 items, but JEI only displays the first 6. + .base(item('minecraft:clay')) + .output(item('minecraft:clay')) + .preserveBase() // Toggle preserveBase + .register() + +mods.woot.anvil.removeByBase(item('minecraft:iron_bars')) +mods.woot.anvil.removeByOutput(item('woot:stygianironplate')) +//mods.woot.anvil.removeAll() + + +// Drops: +// Controls extra drops given by mobs. Chance and Size are both arrays 4 long, containing the values for levels 0/1/2/3 levels of Looting. +mods.woot.drops.recipeBuilder() + .name('minecraft:zombie') + .output(item('minecraft:clay')) + .chance(10, 30, 60, 100) + .size(5, 10, 20, 50) + .register() + +mods.woot.drops.removeByEntity(new WootMobName('minecraft:ender_dragon')) +mods.woot.drops.removeByEntity(entity('minecraft:ender_dragon')) +mods.woot.drops.removeByEntity('minecraft:ender_dragon') +mods.woot.drops.removeByEntity('minecraft:ender_dragon', '') // NBT tag +mods.woot.drops.removeByOutput(item('minecraft:dragon_breath')) +//mods.woot.drops.removeAll() + + +// Spawning: +// Controls item/fluid costs of a given mob or the default cost. +mods.woot.spawning.recipeBuilder() + .name('minecraft:zombie') // Optional, either a name must be defined or the recipe must be the "defaultSpawnRecipe" + .input(item('minecraft:clay')) // up to 6 input items + .fluidInput(fluid('water')) // up to 6 input fluids + .register() + +mods.woot.spawning.recipeBuilder() + .defaultSpawnRecipe(true) // Optional, either a name must be defined or the recipe must be the "defaultSpawnRecipe" + .input(item('minecraft:gold_ingot'), item('minecraft:diamond')) + .register() + + +mods.woot.spawning.remove(new WootMobName('minecraft:ender_dragon')) +mods.woot.spawning.removeByEntity(new WootMobName('minecraft:ender_dragon')) +mods.woot.spawning.removeByEntity(entity('minecraft:ender_dragon')) +mods.woot.spawning.removeByEntity('minecraft:ender_dragon') +mods.woot.spawning.removeByEntity('minecraft:ender_dragon', '') // NBT tag +//mods.woot.spawning.removeAll() + + +// Policy: +// Controls what entities can be farmed for what items via an entity blacklist, mod blacklist, item output blacklist, item output mod blacklist, and a mob whitelist. +// Note: if the whitelist contains any entities, any entities not in the whitelist are banned (rendering EntityModBlacklist and EntityBlacklist superflous). +// GenerateOnlyList contains all entities which cannot be captured via shard, meaning the controller would need to be obtained a different way. +//mods.woot.policy.addToEntityModBlacklist('minecraft') +mods.woot.policy.addToEntityBlacklist('minecraft:witch') // Also takes a WootMobName +mods.woot.policy.addToItemModBlacklist('woot') +mods.woot.policy.addToItemBlacklist(item('minecraft:gunpowder')) +//mods.woot.policy.addToEntityWhitelist('minecraft:zombie') // Also takes a WootMobName +mods.woot.policy.addToGenerateOnlyList('minecraft:skeleton') // Also takes a WootMobName + +mods.woot.policy.removeFromEntityModBlacklist('botania') +mods.woot.policy.removeFromEntityBlacklist('twilightforest:naga') // Also takes a WootMobName +//mods.woot.policy.removeFromItemModBlacklist('minecraft') // Note: has no default entries +//mods.woot.policy.removeFromItemBlacklist(item('minecraft:sugar')) // Note: has no default entries +//mods.woot.policy.removeFromEntityWhitelist('minecraft:wither_skeleton') // Note: has no default entries. Also takes a WootMobName +//mods.woot.policy.removeFromGenerateOnlyList('minecraft:wither_skeleton') // Note: has no default entries. Also takes a WootMobName + +//mods.woot.policy.removeAllFromEntityModBlacklist() +//mods.woot.policy.removeAllFromEntityBlacklist() +//mods.woot.policy.removeAllFromItemModBlacklist() // Note: has no default entries +//mods.woot.policy.removeAllFromItemBlacklist() // Note: has no default entries +//mods.woot.policy.removeAllFromEntityWhitelist() // Note: has no default entries +//mods.woot.policy.removeAllFromGenerateOnlyList() // Note: has no default entries + +//mods.woot.policy.removeAll() + + +// Mob Config: +// Control the default values or mob-specific values for a large number of effects, a full list can be found at +// ipsis.woot.configuration.EnumConfigKey. View on Github via the link: +// https://github.com/Ipsis/Woot/blob/55e88f5a15d66cc987e676d665d20f4afbe008b8/src/main/java/ipsis/woot/configuration/EnumConfigKey.java#L14 + +// Change the default Spawn Ticks interval to 100 (default 320) +mods.woot.mobconfig.add('spawn_ticks', 100) +// Change the Spawn Ticks interval for Zombies to 1 (default the global Spawn Ticks) +mods.woot.mobconfig.add('minecraft:zombie', 'spawn_ticks', 1) + +// Remove the unique cost for Wither Skeletons, making it fallback to the default (default 1) +mods.woot.mobconfig.remove('minecraft:wither_skeleton', 'spawn_units') + +// Remove all config values set for the Wither +mods.woot.mobconfig.remove('minecraft:wither') + +//mods.woot.mobconfig.removeAll() + + +/* Mob-specific overrides for EnumConfigKey: + * SPAWN_TICKS + * KILL_COUNT + * SPAWN_UNITS + * DEATH_XP + * MASS_FX + * FACTORY_TIER + * POWER_PER_UNIT + * T1_POWER_TICK, T2_POWER_TICK, T3_POWER_TICK, T4_POWER_TICK + * RATE_1_POWER_TICK, RATE_2_POWER_TICK, RATE_3_POWER_TICK + * MASS_1_POWER_TICK, MASS_2_POWER_TICK, MASS_3_POWER_TICK + * LOOTING_1_POWER_TICK, LOOTING_2_POWER_TICK, LOOTING_3_POWER_TICK + * DECAP_1_POWER_TICK, DECAP_2_POWER_TICK, DECAP_3_POWER_TICK + * XP_1_POWER_TICK, XP_2_POWER_TICK, XP_3_POWER_TICK + * EFF_1_POWER_TICK, EFF_2_POWER_TICK, EFF_3_POWER_TICK + * BM_LE_TANK_1_POWER_TICK, BM_LE_TANK_2_POWER_TICK, BM_LE_TANK_3_POWER_TICK + * BM_LE_ALTAR_1_POWER_TICK, BM_LE_ALTAR_2_POWER_TICK, BM_LE_ALTAR_3_POWER_TICK + * BM_CRYSTAL_1_POWER_TICK, BM_CRYSTAL_2_POWER_TICK, BM_CRYSTAL_3_POWER_TICK + * EC_BLOOD_1_POWER_TICK, EC_BLOOD_2_POWER_TICK, EC_BLOOD_3_POWER_TICK + * RATE_1_PARAM, RATE_2_PARAM, RATE_3_PARAM + * MASS_1_PARAM, MASS_2_PARAM, MASS_3_PARAM + * DECAP_1_PARAM, DECAP_2_PARAM, DECAP_3_PARAM + * XP_1_PARAM, XP_2_PARAM, XP_3_PARAM + * EFF_1_PARAM, EFF_2_PARAM, EFF_3_PARAM + * BM_LE_TANK_1_PARAM, BM_LE_TANK_2_PARAM, BM_LE_TANK_3_PARAM + * BM_LE_ALTAR_1_PARAM, BM_LE_ALTAR_2_PARAM, BM_LE_ALTAR_3_PARAM + * EC_BLOOD_1_PARAM, EC_BLOOD_2_PARAM, EC_BLOOD_3_PARAM + * BM_CRYSTAL_1_PARAM, BM_CRYSTAL_2_PARAM, BM_CRYSTAL_3_PARAM + */ + +/* Default options for EnumConfigKey (global): + * TARTARUS_ID + * SAMPLE_SIZE + * LEARN_TICKS + * SPAWN_TICKS + * HEADHUNTER_1_CHANCE, HEADHUNTER_2_CHANCE, HEADHUNTER_3_CHANCE + * NUM_MOBS + * KILL_COUNT + * SPAWN_UNITS + * DEATH_XP + * MASS_FX + * FACTORY_TIER + * T1_UNITS_MAX, T2_UNITS_MAX, T3_UNITS_MAX, T4_UNITS_MAX + * POWER_PER_UNIT + * T1_POWER_MAX, T2_POWER_MAX, T3_POWER_MAX + * T1_POWER_RX_TICK, T2_POWER_RX_TICK, T3_POWER_RX_TICK + * T1_POWER_TICK, T2_POWER_TICK, T3_POWER_TICK, T4_POWER_TICK + * T2_SHARD_GEN, T3_SHARD_GEN, T4_SHARD_GEN + * RATE_1_POWER_TICK, RATE_2_POWER_TICK, RATE_3_POWER_TICK + * MASS_1_POWER_TICK, MASS_2_POWER_TICK, MASS_3_POWER_TICK + * LOOTING_1_POWER_TICK, LOOTING_2_POWER_TICK, LOOTING_3_POWER_TICK + * DECAP_1_POWER_TICK, DECAP_2_POWER_TICK, DECAP_3_POWER_TICK + * XP_1_POWER_TICK, XP_2_POWER_TICK, XP_3_POWER_TICK + * EFF_1_POWER_TICK, EFF_2_POWER_TICK, EFF_3_POWER_TICK + * BM_LE_TANK_1_POWER_TICK, BM_LE_TANK_2_POWER_TICK, BM_LE_TANK_3_POWER_TICK + * BM_LE_ALTAR_1_POWER_TICK, BM_LE_ALTAR_2_POWER_TICK, BM_LE_ALTAR_3_POWER_TICK + * BM_CRYSTAL_1_POWER_TICK, BM_CRYSTAL_2_POWER_TICK, BM_CRYSTAL_3_POWER_TICK + * EC_BLOOD_1_POWER_TICK, EC_BLOOD_2_POWER_TICK, EC_BLOOD_3_POWER_TICK + * RATE_1_PARAM, RATE_2_PARAM, RATE_3_PARAM + * MASS_1_PARAM, MASS_2_PARAM, MASS_3_PARAM + * LOOTING_1_PARAM, LOOTING_2_PARAM, LOOTING_3_PARAM + * DECAP_1_PARAM, DECAP_2_PARAM, DECAP_3_PARAM + * XP_1_PARAM, XP_2_PARAM, XP_3_PARAM + * EFF_1_PARAM, EFF_2_PARAM, EFF_3_PARAM + * BM_LE_TANK_1_PARAM, BM_LE_TANK_2_PARAM, BM_LE_TANK_3_PARAM + * BM_LE_ALTAR_1_PARAM, BM_LE_ALTAR_2_PARAM, BM_LE_ALTAR_3_PARAM + * EC_BLOOD_1_PARAM, EC_BLOOD_2_PARAM, EC_BLOOD_3_PARAM + * BM_CRYSTAL_1_PARAM, BM_CRYSTAL_2_PARAM, BM_CRYSTAL_3_PARAM + */ \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 2b33b8d78..a6407814a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -32,4 +32,5 @@ debug_blood_magic = false debug_tinkers = false debug_extended_crafting = false debug_botania = false -debug_forestry = false \ No newline at end of file +debug_forestry = false +debug_woot = 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 c22b71d2c..834c3a0ea 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/ModSupport.java @@ -21,6 +21,7 @@ import com.cleanroommc.groovyscript.compat.mods.thaumcraft.Thaumcraft; import com.cleanroommc.groovyscript.compat.mods.thermalexpansion.ThermalExpansion; import com.cleanroommc.groovyscript.compat.mods.tinkersconstruct.TinkersConstruct; +import com.cleanroommc.groovyscript.compat.mods.woot.Woot; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; @@ -59,6 +60,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 WOOT = new Container<>("woot", "Woot", Woot::new); public static Collection> getAllContainers() { return new ObjectOpenHashSet<>(containers.values()); diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Drops.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Drops.java new file mode 100644 index 000000000..d26e2ca58 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Drops.java @@ -0,0 +1,202 @@ +package com.cleanroommc.groovyscript.compat.mods.woot; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.core.mixin.woot.CustomDropAccessor; +import com.cleanroommc.groovyscript.core.mixin.woot.CustomDropsRepositoryAccessor; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import ipsis.Woot; +import ipsis.woot.util.WootMobName; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.common.registry.EntityEntry; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public class Drops extends VirtualizedRegistry { + + public Drops() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + restoreFromBackup().forEach(drop -> ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops().add(drop)); + removeScripted().forEach(drop -> ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops() + .removeIf(d -> areCustomDropsEqual((CustomDropAccessor) d, (CustomDropAccessor) drop)) + ); + } + + public void add(WootMobName wootMobName, ItemStack itemStack, List chances, List sizes) { + Woot.customDropsRepository.addDrop(wootMobName, itemStack, chances, sizes); + // get the drop we just added, but painfully + addScripted( + ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops() + .stream() + .filter(drop -> areCustomDropsEqual((CustomDropAccessor) drop, wootMobName, itemStack, chances, sizes)) + .collect(Collectors.toList()).get(0) + ); + } + + public boolean remove(Object drop) { + return ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops().removeIf(d -> { + if (areCustomDropsEqual((CustomDropAccessor) d, (CustomDropAccessor) drop)) { + addBackup(d); + return true; + } + return false; + }); + } + + public boolean removeByEntity(WootMobName name) { + return ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops().removeIf(d -> { + if (((CustomDropAccessor) d).getWootMobName().equals(name)) { + addBackup(d); + return true; + } + return false; + }); + } + + public boolean removeByEntity(EntityEntry entity) { + return removeByEntity(new WootMobName(entity.getName())); + } + + public boolean removeByEntity(String name) { + return removeByEntity(new WootMobName(name)); + } + + public boolean removeByEntity(String name, String tag) { + return removeByEntity(new WootMobName(name, tag)); + } + + public boolean removeByOutput(ItemStack output) { + return ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops().removeIf(d -> { + if (ItemStack.areItemStacksEqual(((CustomDropAccessor) d).getItemStack(), output)) { + addBackup(d); + return true; + } + return false; + }); + } + + public void removeAll() { + ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops().forEach(this::addBackup); + ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops().clear(); + } + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops()) + .setRemover(this::remove); + } + + private boolean areCustomDropsEqual(CustomDropAccessor target, CustomDropAccessor other) { + return target.getWootMobName().equals(other.getWootMobName()) && + ItemStack.areItemStacksEqual(target.getItemStack(), other.getItemStack()) && + target.getChanceMap().equals(other.getChanceMap()) && + target.getSizeMap().equals(other.getSizeMap()); + } + + private boolean areCustomDropsEqual(CustomDropAccessor target, WootMobName wootMobName, ItemStack itemStack, List chances, List sizes) { + return target.getWootMobName().equals(wootMobName) && + ItemStack.areItemStacksEqual(target.getItemStack(), itemStack) && + target.getChanceMap().values().containsAll(chances) && + target.getSizeMap().values().containsAll(sizes); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private WootMobName name; + private final List chance = new ArrayList<>(); + private final List size = new ArrayList<>(); + + public RecipeBuilder name(WootMobName name) { + this.name = name; + return this; + } + + public RecipeBuilder name(EntityEntry entity) { + this.name = new WootMobName(entity.getName()); + return this; + } + + public RecipeBuilder name(String name) { + this.name = new WootMobName(name); + return this; + } + + public RecipeBuilder name(String name, String tag) { + this.name = new WootMobName(name, tag); + return this; + } + + public RecipeBuilder chance(int chance) { + this.chance.add(chance); + return this; + } + + public RecipeBuilder chance(int... chances) { + for (int chance : chances) { + chance(chance); + } + return this; + } + + public RecipeBuilder chance(Collection chances) { + for (int chance : chances) { + chance(chance); + } + return this; + } + + public RecipeBuilder size(int size) { + this.size.add(size); + return this; + } + + public RecipeBuilder size(int... sizes) { + for (int size : sizes) { + size(size); + } + return this; + } + + public RecipeBuilder size(Collection sizes) { + for (int size : sizes) { + size(size); + } + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Woot custom drops"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 0, 0, 1, 1); + validateFluids(msg); + msg.add(name == null || !name.isValid(), "name must be defined and a valid name, yet it was {}", name); + msg.add(chance.size() != 4, "chance must have exactly 4 entries, but found {}", chance.size()); + msg.add(size.size() != 4, "size must have exactly 4 entries, but found {}", size.size()); + } + + @Override + public @Nullable ItemStack register() { + if (!validate()) return null; + ModSupport.WOOT.get().drops.add(name, output.get(0), chance, size); + return null; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/MobConfig.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/MobConfig.java new file mode 100644 index 000000000..1358f0b94 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/MobConfig.java @@ -0,0 +1,93 @@ +package com.cleanroommc.groovyscript.compat.mods.woot; + +import com.cleanroommc.groovyscript.core.mixin.woot.WootConfigurationManagerAccessor; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import ipsis.Woot; +import ipsis.woot.configuration.EnumConfigKey; +import ipsis.woot.util.WootMobName; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +public class MobConfig extends VirtualizedRegistry> { + + public MobConfig() { + super(); + } + + @Override + public void onReload() { + restoreFromBackup().forEach(pair -> ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().put(pair.getKey(), pair.getValue())); + removeScripted().forEach(pair -> { + if (pair.getKey().contains(":")) ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().remove(pair.getKey()); + else ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMap().put(EnumConfigKey.get(pair.getKey()), pair.getValue()); + }); + } + + public void add(WootMobName name, EnumConfigKey key, int value) { + String target = ((WootConfigurationManagerAccessor) Woot.wootConfiguration).callMakeKey(name, key); + addScripted(Pair.of(target, ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().get(target))); + ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().put(target, value); + } + + public void add(String name, EnumConfigKey key, int value) { + add(new WootMobName(name), key, value); + } + + public void add(WootMobName name, String key, int value) { + add(name, EnumConfigKey.get(key.toUpperCase(Locale.ROOT)), value); + } + + public void add(String name, String key, int value) { + add(new WootMobName(name), EnumConfigKey.get(key.toUpperCase(Locale.ROOT)), value); + } + + // Note: there is no remove method for the IntegerMap since all values must be defined + public void add(EnumConfigKey key, int value) { + addScripted(Pair.of(key.name(), ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMap().get(key))); + ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMap().put(key, value); + } + + public void add(String key, int value) { + add(EnumConfigKey.get(key.toUpperCase(Locale.ROOT)), value); + } + + public void remove(WootMobName name, EnumConfigKey key) { + String target = ((WootConfigurationManagerAccessor) Woot.wootConfiguration).callMakeKey(name, key); + addBackup(Pair.of(target, ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().get(target))); + ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().remove(target); + } + + public void remove(String name, EnumConfigKey key) { + remove(new WootMobName(name), key); + } + + public void remove(WootMobName name, String key) { + remove(name, EnumConfigKey.get(key.toUpperCase(Locale.ROOT))); + } + + public void remove(String name, String key) { + remove(new WootMobName(name), EnumConfigKey.get(key.toUpperCase(Locale.ROOT))); + } + + public void remove(WootMobName name) { + for (Map.Entry entry : ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().entrySet().stream() + .filter(x -> x.getKey().startsWith(name.toString())) + .collect(Collectors.toList())) { + addBackup(Pair.of(entry.getKey(), entry.getValue())); + ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().remove(entry.getKey()); + } + } + + + public void remove(String name) { + remove(new WootMobName(name)); + } + + public void removeAll() { + ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().forEach((key, value) -> addBackup(Pair.of(key, value))); + ((WootConfigurationManagerAccessor) Woot.wootConfiguration).getIntegerMobMap().clear(); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Policy.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Policy.java new file mode 100644 index 000000000..5d3535d45 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Policy.java @@ -0,0 +1,198 @@ +package com.cleanroommc.groovyscript.compat.mods.woot; + +import com.cleanroommc.groovyscript.core.mixin.woot.PolicyRepositoryAccessor; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import ipsis.Woot; +import ipsis.woot.util.WootMobName; +import net.minecraft.item.ItemStack; +import org.apache.commons.lang3.tuple.Pair; + +public class Policy extends VirtualizedRegistry> { + + public Policy() { + super(); + } + + @Override + public void onReload() { + restoreFromBackup().forEach(pair -> { + switch (pair.getKey()) { + case ENTITY_MOD_BLACKLIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalModBlacklist().add((String) pair.getValue()); + break; + case ENTITY_BLACKLIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityBlacklist().add((WootMobName) pair.getValue()); + break; + case ITEM_MOD_BLACKLIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemModBlacklist().add((String) pair.getValue()); + break; + case ITEM_BLACKLIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemBlacklist().add((ItemStack) pair.getValue()); + break; + case ENTITY_WHITELIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityWhitelist().add((WootMobName) pair.getValue()); + break; + case GENERATE_ONLY_LIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalGenerateOnlyList().add((WootMobName) pair.getValue()); + break; + } + }); + removeScripted().forEach(pair -> { + switch (pair.getKey()) { + case ENTITY_MOD_BLACKLIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalModBlacklist().remove((String) pair.getValue()); + break; + case ENTITY_BLACKLIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityBlacklist().remove((WootMobName) pair.getValue()); + break; + case ITEM_MOD_BLACKLIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemModBlacklist().remove((String) pair.getValue()); + break; + case ITEM_BLACKLIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemBlacklist().remove((ItemStack) pair.getValue()); + break; + case ENTITY_WHITELIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityWhitelist().remove((WootMobName) pair.getValue()); + break; + case GENERATE_ONLY_LIST: + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalGenerateOnlyList().remove((WootMobName) pair.getValue()); + break; + } + }); + } + + public void addToEntityModBlacklist(String name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalModBlacklist().add(name); + addScripted(Pair.of(PolicyType.ENTITY_MOD_BLACKLIST, name)); + } + + public void addToEntityBlacklist(WootMobName name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityBlacklist().add(name); + addScripted(Pair.of(PolicyType.ENTITY_BLACKLIST, name)); + } + + public void addToEntityBlacklist(String name) { + addToEntityBlacklist(new WootMobName(name)); + } + + public void addToItemModBlacklist(String name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemModBlacklist().add(name); + addScripted(Pair.of(PolicyType.ITEM_MOD_BLACKLIST, name)); + } + + public void addToItemBlacklist(ItemStack item) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemBlacklist().add(item); + addScripted(Pair.of(PolicyType.ITEM_BLACKLIST, item)); + } + + public void addToEntityWhitelist(WootMobName name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityWhitelist().add(name); + addScripted(Pair.of(PolicyType.ENTITY_WHITELIST, name)); + } + + public void addToEntityWhitelist(String name) { + addToEntityWhitelist(new WootMobName(name)); + } + + public void addToGenerateOnlyList(WootMobName name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalGenerateOnlyList().add(name); + addScripted(Pair.of(PolicyType.GENERATE_ONLY_LIST, name)); + } + + public void addToGenerateOnlyList(String name) { + addToGenerateOnlyList(new WootMobName(name)); + } + + public void removeFromEntityModBlacklist(String name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalModBlacklist().remove(name); + addBackup(Pair.of(PolicyType.ENTITY_MOD_BLACKLIST, name)); + } + + public void removeFromEntityBlacklist(WootMobName name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityBlacklist().remove(name); + addBackup(Pair.of(PolicyType.ENTITY_BLACKLIST, name)); + } + + public void removeFromEntityBlacklist(String name) { + removeFromEntityBlacklist(new WootMobName(name)); + } + + public void removeFromItemModBlacklist(String name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemModBlacklist().remove(name); + addBackup(Pair.of(PolicyType.ITEM_MOD_BLACKLIST, name)); + } + + public void removeFromItemBlacklist(ItemStack item) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemBlacklist().remove(item); + addBackup(Pair.of(PolicyType.ITEM_BLACKLIST, item)); + } + + public void removeFromEntityWhitelist(WootMobName name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityWhitelist().remove(name); + addBackup(Pair.of(PolicyType.ENTITY_WHITELIST, name)); + } + + public void removeFromEntityWhitelist(String name) { + removeFromEntityWhitelist(new WootMobName(name)); + } + + public void removeFromGenerateOnlyList(WootMobName name) { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalGenerateOnlyList().remove(name); + addBackup(Pair.of(PolicyType.GENERATE_ONLY_LIST, name)); + } + + public void removeFromGenerateOnlyList(String name) { + removeFromGenerateOnlyList(new WootMobName(name)); + } + + public void removeAllFromEntityModBlacklist() { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalModBlacklist().forEach(x -> addBackup(Pair.of(PolicyType.ENTITY_MOD_BLACKLIST, x))); + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalModBlacklist().clear(); + } + + public void removeAllFromEntityBlacklist() { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityBlacklist().forEach(x -> addBackup(Pair.of(PolicyType.ENTITY_BLACKLIST, x))); + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityBlacklist().clear(); + } + + public void removeAllFromItemModBlacklist() { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemModBlacklist().forEach(x -> addBackup(Pair.of(PolicyType.ITEM_MOD_BLACKLIST, x))); + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemModBlacklist().clear(); + } + + public void removeAllFromItemBlacklist() { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemBlacklist().forEach(x -> addBackup(Pair.of(PolicyType.ITEM_BLACKLIST, x))); + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalItemBlacklist().clear(); + } + + public void removeAllFromEntityWhitelist() { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityWhitelist().forEach(x -> addBackup(Pair.of(PolicyType.ENTITY_WHITELIST, x))); + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalEntityWhitelist().clear(); + } + + public void removeAllFromGenerateOnlyList() { + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalGenerateOnlyList().forEach(x -> addBackup(Pair.of(PolicyType.GENERATE_ONLY_LIST, x))); + ((PolicyRepositoryAccessor) Woot.policyRepository).getExternalGenerateOnlyList().clear(); + } + + public void removeAll() { + removeAllFromEntityModBlacklist(); + removeAllFromEntityBlacklist(); + removeAllFromItemModBlacklist(); + removeAllFromItemBlacklist(); + removeAllFromEntityWhitelist(); + removeAllFromGenerateOnlyList(); + } + + public enum PolicyType { + ENTITY_MOD_BLACKLIST,//getExternalModBlacklist + ENTITY_BLACKLIST,//getExternalEntityBlacklist + ITEM_MOD_BLACKLIST,//getExternalItemModBlacklist + ITEM_BLACKLIST,//getExternalItemBlacklist + ENTITY_WHITELIST,//getExternalEntityWhitelist + GENERATE_ONLY_LIST//getExternalGenerateOnlyList + } + + + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Spawning.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Spawning.java new file mode 100644 index 000000000..021f0b288 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Spawning.java @@ -0,0 +1,159 @@ +package com.cleanroommc.groovyscript.compat.mods.woot; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.core.mixin.woot.SpawnRecipeRepositoryAccessor; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import ipsis.Woot; +import ipsis.woot.farming.ISpawnRecipe; +import ipsis.woot.farming.SpawnRecipe; +import ipsis.woot.util.WootMobName; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fml.common.registry.EntityEntry; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +public class Spawning extends VirtualizedRegistry> { + + public Spawning() { + super(); + } + + public RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + restoreFromBackup().forEach(pair -> ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getRecipes().put(pair.getKey(), pair.getValue())); + removeScripted().forEach(pair -> ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getRecipes().remove(pair.getKey())); + //((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getDefaultSpawnRecipe().setEfficiency(true); + ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getDefaultSpawnRecipe().getItems().clear(); + ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getDefaultSpawnRecipe().getFluids().clear(); + } + + public void addDefaultItem(ItemStack item) { + ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getDefaultSpawnRecipe().addIngredient(item); + } + + public void addDefaultFluid(FluidStack fluid) { + ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getDefaultSpawnRecipe().addIngredient(fluid); + } + + //public void setDefaultEfficiency(boolean efficiency) { + // ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getDefaultSpawnRecipe().setEfficiency(efficiency); + //} + + public void add(WootMobName name, SpawnRecipe recipe) { + ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getRecipes().put(name, recipe); + addScripted(Pair.of(name, recipe)); + } + + public boolean remove(WootMobName name) { + SpawnRecipe recipe = ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getRecipes().get(name); + ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getRecipes().remove(name); + addBackup(Pair.of(name, recipe)); + return true; + } + + public boolean removeByEntity(WootMobName name) { + return remove(name); + } + + public boolean removeByEntity(EntityEntry entity) { + return remove(new WootMobName(entity.getName())); + } + + public boolean removeByEntity(String name) { + return remove(new WootMobName(name)); + } + + public boolean removeByEntity(String name, String tag) { + return remove(new WootMobName(name, tag)); + } + + public void removeAll() { + ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getRecipes().forEach((l, r) -> addBackup(Pair.of(l, r))); + ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getRecipes().clear(); + } + + public SimpleObjectStream> streamRecipes() { + return new SimpleObjectStream<>(((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getRecipes().entrySet()) + .setRemover(x -> remove(x.getKey())); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private boolean defaultSpawnRecipe = false; + private WootMobName name; + //private boolean efficiency; + + public RecipeBuilder defaultSpawnRecipe(boolean defaultSpawnRecipe) { + this.defaultSpawnRecipe = defaultSpawnRecipe; + return this; + } + + public RecipeBuilder defaultSpawnRecipe() { + this.defaultSpawnRecipe = !defaultSpawnRecipe; + return this; + } + + public RecipeBuilder name(WootMobName name) { + this.name = name; + return this; + } + + public RecipeBuilder name(EntityEntry entity) { + this.name = new WootMobName(entity.getName()); + return this; + } + + public RecipeBuilder name(String name) { + this.name = new WootMobName(name); + return this; + } + + //public RecipeBuilder efficiency(boolean efficiency) { + // this.efficiency = efficiency; + // return this; + //} + + @Override + public String getErrorMsg() { + return "Error adding Woot custom spawning costs"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + validateItems(msg, 0, 6, 0, 0); + validateFluids(msg, 0, 6, 0, 0); + msg.add(!defaultSpawnRecipe && (name == null || !name.isValid()), "if the recipe is not the defaultSpawnRecipe, the name must be defined and a valid name, yet it was {}", name); + } + + @Override + public @Nullable ISpawnRecipe register() { + if (!validate()) return null; + + SpawnRecipe recipe = defaultSpawnRecipe + ? ((SpawnRecipeRepositoryAccessor) Woot.spawnRecipeRepository).getDefaultSpawnRecipe() + : new SpawnRecipe(); + for (IIngredient item : input) { + recipe.addIngredient(item.getMatchingStacks()[0]); + } + for (FluidStack fluid : fluidInput) { + recipe.addIngredient(fluid); + } + //recipe.setEfficiency(efficiency); + + if (!defaultSpawnRecipe) ModSupport.WOOT.get().spawning.add(name, recipe); + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/StygianIronAnvil.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/StygianIronAnvil.java new file mode 100644 index 000000000..0be1e14e1 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/StygianIronAnvil.java @@ -0,0 +1,132 @@ +package com.cleanroommc.groovyscript.compat.mods.woot; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.compat.mods.ModSupport; +import com.cleanroommc.groovyscript.core.mixin.woot.AnvilManagerAccessor; +import com.cleanroommc.groovyscript.helper.SimpleObjectStream; +import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder; +import com.cleanroommc.groovyscript.registry.VirtualizedRegistry; +import ipsis.Woot; +import ipsis.woot.crafting.AnvilRecipe; +import ipsis.woot.crafting.IAnvilRecipe; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.stream.Collectors; + +public class StygianIronAnvil extends VirtualizedRegistry { + + public StygianIronAnvil() { + super(VirtualizedRegistry.generateAliases("Anvil")); + } + + public static RecipeBuilder recipeBuilder() { + return new RecipeBuilder(); + } + + @Override + public void onReload() { + removeScripted().forEach(Woot.anvilManager.getRecipes()::remove); + Woot.anvilManager.getRecipes().addAll(restoreFromBackup()); + } + + @Override + public void afterScriptLoad() { + // Recalculate valid base items + ((AnvilManagerAccessor) Woot.anvilManager).getValidBaseItems().clear(); + Woot.anvilManager.getRecipes().forEach(x -> { + if (((AnvilManagerAccessor) Woot.anvilManager).getValidBaseItems().contains(x.getBaseItem())) return; + ((AnvilManagerAccessor) Woot.anvilManager).getValidBaseItems().add(x.getBaseItem()); + }); + } + + public void add(IAnvilRecipe recipe) { + Woot.anvilManager.getRecipes().add(recipe); + addScripted(recipe); + } + + public boolean remove(IAnvilRecipe recipe) { + Woot.anvilManager.getRecipes().remove(recipe); + addBackup(recipe); + return true; + } + + public boolean removeByBase(ItemStack base) { + return Woot.anvilManager.getRecipes().removeIf(x -> { + if (ItemStack.areItemsEqual(x.getBaseItem(), base)) { + addBackup(x); + return true; + } + return false; + }); + } + + public boolean removeByOutput(ItemStack output) { + return Woot.anvilManager.getRecipes().removeIf(x -> { + if (ItemStack.areItemsEqual(x.getCopyOutput(), output)) { + addBackup(x); + return true; + } + return false; + }); + } + + public void removeAll() { + Woot.anvilManager.getRecipes().forEach(this::addBackup); + Woot.anvilManager.getRecipes().clear(); + } + + + public SimpleObjectStream streamRecipes() { + return new SimpleObjectStream<>(Woot.anvilManager.getRecipes()) + .setRemover(this::remove); + } + + public static class RecipeBuilder extends AbstractRecipeBuilder { + + private ItemStack base = ItemStack.EMPTY; + private boolean preserveBase = false; + + public RecipeBuilder base(ItemStack base) { + this.base = base; + return this; + } + + public RecipeBuilder preserveBase(boolean preserveBase) { + this.preserveBase = preserveBase; + return this; + } + + public RecipeBuilder preserveBase() { + this.preserveBase = !this.preserveBase; + return this; + } + + @Override + public String getErrorMsg() { + return "Error adding Woot Stygian Iron Anvil recipe"; + } + + @Override + public void validate(GroovyLog.Msg msg) { + // Note: JEI can only display 6 inputs, but there doesnt appear to be a limit for the actual recipe + // validateItems(msg, 1, 6, 1, 1); + validateItems(msg, 1, Integer.MAX_VALUE, 1, 1); + validateFluids(msg); + msg.add(base.isEmpty(), "base must be defined"); + } + + @Override + public @Nullable IAnvilRecipe register() { + if (!validate()) return null; + + if (((AnvilManagerAccessor) Woot.anvilManager).getValidBaseItems().stream().noneMatch(x -> x.isItemEqual(base))) ((AnvilManagerAccessor) Woot.anvilManager).getValidBaseItems().add(base); + + IAnvilRecipe recipe = new AnvilRecipe(output.get(0), base, preserveBase); + recipe.getInputs().addAll(input.stream().map(x -> x.toMcIngredient().getMatchingStacks()[0]).collect(Collectors.toList())); + ModSupport.WOOT.get().stygianIronAnvil.add(recipe); + return recipe; + } + } + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Woot.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Woot.java new file mode 100644 index 000000000..93ef29f12 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Woot.java @@ -0,0 +1,20 @@ +package com.cleanroommc.groovyscript.compat.mods.woot; + +import com.cleanroommc.groovyscript.compat.mods.ModPropertyContainer; + +public class Woot extends ModPropertyContainer { + + StygianIronAnvil stygianIronAnvil = new StygianIronAnvil(); + Drops drops = new Drops(); + Spawning spawning = new Spawning(); + Policy policy = new Policy(); + MobConfig mobConfig = new MobConfig(); + + public Woot() { + addRegistry(stygianIronAnvil); + addRegistry(drops); + addRegistry(spawning); + addRegistry(policy); + addRegistry(mobConfig); + } +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java index 4a1c55ac4..11c912c78 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/LateMixin.java @@ -10,9 +10,24 @@ public class LateMixin implements ILateMixinLoader { - public static final List modMixins = ImmutableList.of("jei", "mekanism", "enderio", "thermalexpansion", "draconicevolution", - "ic2_classic", "ic2_exp", "bloodmagic", "astralsorcery", "tconstruct", - "tcomplement", "extendedcrafting", "botania", "roots", "forestry"); + public static final List modMixins = ImmutableList.of( + "jei", + "mekanism", + "enderio", + "thermalexpansion", + "draconicevolution", + "ic2_classic", + "ic2_exp", + "bloodmagic", + "astralsorcery", + "tconstruct", + "tcomplement", + "extendedcrafting", + "botania", + "roots", + "forestry", + "woot" + ); @Override public List getMixinConfigs() { diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/AnvilManagerAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/AnvilManagerAccessor.java new file mode 100644 index 000000000..afb118cff --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/AnvilManagerAccessor.java @@ -0,0 +1,15 @@ +package com.cleanroommc.groovyscript.core.mixin.woot; + +import ipsis.woot.crafting.AnvilManager; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(value = AnvilManager.class, remap = false) +public interface AnvilManagerAccessor { + + @Accessor + List getValidBaseItems(); +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropAccessor.java new file mode 100644 index 000000000..2327914be --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropAccessor.java @@ -0,0 +1,26 @@ +package com.cleanroommc.groovyscript.core.mixin.woot; + +import ipsis.woot.util.EnumEnchantKey; +import ipsis.woot.util.WootMobName; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.HashMap; + +@Mixin(targets = "ipsis.woot.loot.customdrops.CustomDropsRepository$CustomDrop", remap = false) +public interface CustomDropAccessor { + + @Accessor + WootMobName getWootMobName(); + + @Accessor + ItemStack getItemStack(); + + @Accessor + HashMap getChanceMap(); + + @Accessor + HashMap getSizeMap(); + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropsRepositoryAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropsRepositoryAccessor.java new file mode 100644 index 000000000..d0b330f76 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropsRepositoryAccessor.java @@ -0,0 +1,16 @@ +package com.cleanroommc.groovyscript.core.mixin.woot; + +import ipsis.woot.loot.customdrops.CustomDropsRepository; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(value = CustomDropsRepository.class, remap = false) +public interface CustomDropsRepositoryAccessor { + + @Accessor + List getDrops(); + //List getDrops(); + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/PolicyRepositoryAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/PolicyRepositoryAccessor.java new file mode 100644 index 000000000..612074309 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/PolicyRepositoryAccessor.java @@ -0,0 +1,44 @@ +package com.cleanroommc.groovyscript.core.mixin.woot; + +import ipsis.woot.policy.PolicyRepository; +import ipsis.woot.util.WootMobName; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(value = PolicyRepository.class, remap = false) +public interface PolicyRepositoryAccessor { + + @Accessor + List getInternalModBlacklist(); + + @Accessor + List getInternalEntityBlacklist(); + + @Accessor + List getInternalItemModBlacklist(); + + @Accessor + List getInternalItemBlacklist(); + + @Accessor + List getExternalModBlacklist(); + + @Accessor + List getExternalEntityBlacklist(); + + @Accessor + List getExternalItemModBlacklist(); + + @Accessor + List getExternalItemBlacklist(); + + @Accessor + List getExternalEntityWhitelist(); + + @Accessor + List getExternalGenerateOnlyList(); + +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/SpawnRecipeRepositoryAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/SpawnRecipeRepositoryAccessor.java new file mode 100644 index 000000000..aabf430a4 --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/SpawnRecipeRepositoryAccessor.java @@ -0,0 +1,19 @@ +package com.cleanroommc.groovyscript.core.mixin.woot; + +import ipsis.woot.farming.SpawnRecipe; +import ipsis.woot.farming.SpawnRecipeRepository; +import ipsis.woot.util.WootMobName; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.HashMap; + +@Mixin(value = SpawnRecipeRepository.class, remap = false) +public interface SpawnRecipeRepositoryAccessor { + + @Accessor + HashMap getRecipes(); + + @Accessor + SpawnRecipe getDefaultSpawnRecipe(); +} diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/WootConfigurationManagerAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/WootConfigurationManagerAccessor.java new file mode 100644 index 000000000..4670ac45e --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/WootConfigurationManagerAccessor.java @@ -0,0 +1,30 @@ +package com.cleanroommc.groovyscript.core.mixin.woot; + +import ipsis.woot.configuration.EnumConfigKey; +import ipsis.woot.configuration.WootConfigurationManager; +import ipsis.woot.util.WootMobName; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.Map; + +@Mixin(value = WootConfigurationManager.class, remap = false) +public interface WootConfigurationManagerAccessor { + + @Accessor + Map getIntegerMap(); + + @Accessor + Map getBooleanMap(); + + @Accessor + Map getIntegerMobMap(); + + @Accessor + Map getBooleanMobMap(); + + @Invoker + String callMakeKey(WootMobName wootMobName, EnumConfigKey configKey); + +} diff --git a/src/main/resources/mixin.groovyscript.woot.json b/src/main/resources/mixin.groovyscript.woot.json new file mode 100644 index 000000000..6888ec41c --- /dev/null +++ b/src/main/resources/mixin.groovyscript.woot.json @@ -0,0 +1,15 @@ +{ + "package": "com.cleanroommc.groovyscript.core.mixin.woot", + "refmap": "mixins.groovyscript.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "AnvilManagerAccessor", + "CustomDropAccessor", + "CustomDropsRepositoryAccessor", + "PolicyRepositoryAccessor", + "SpawnRecipeRepositoryAccessor", + "WootConfigurationManagerAccessor" + ] +} \ No newline at end of file From feef5ff9c010ab5be73c62fc1cd7ebd3926d311e Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Wed, 2 Aug 2023 12:23:01 -0700 Subject: [PATCH 2/3] address review --- .../groovyscript/compat/mods/woot/Drops.java | 16 ++++++++++------ .../groovyscript/compat/mods/woot/Policy.java | 2 -- .../compat/mods/woot/StygianIronAnvil.java | 3 ++- .../groovyscript/compat/mods/woot/Woot.java | 10 +++++----- .../woot/CustomDropsRepositoryAccessor.java | 1 - 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Drops.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Drops.java index d26e2ca58..f475160dd 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Drops.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Drops.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; public class Drops extends VirtualizedRegistry { @@ -39,12 +40,15 @@ public void onReload() { public void add(WootMobName wootMobName, ItemStack itemStack, List chances, List sizes) { Woot.customDropsRepository.addDrop(wootMobName, itemStack, chances, sizes); // get the drop we just added, but painfully - addScripted( - ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops() - .stream() - .filter(drop -> areCustomDropsEqual((CustomDropAccessor) drop, wootMobName, itemStack, chances, sizes)) - .collect(Collectors.toList()).get(0) - ); + Optional recipe = ((CustomDropsRepositoryAccessor) Woot.customDropsRepository).getDrops() + .stream() + .filter(drop -> areCustomDropsEqual((CustomDropAccessor) drop, wootMobName, itemStack, chances, sizes)) + .findFirst(); + if (!recipe.isPresent()) { + GroovyLog.msg("Error adding entry to Woot Custom Drops Repository with name {}", wootMobName).error().post(); + return; + } + addScripted(recipe.get()); } public boolean remove(Object drop) { diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Policy.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Policy.java index 5d3535d45..f1a500e25 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Policy.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Policy.java @@ -193,6 +193,4 @@ public enum PolicyType { GENERATE_ONLY_LIST//getExternalGenerateOnlyList } - - } diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/StygianIronAnvil.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/StygianIronAnvil.java index 0be1e14e1..be0684a3e 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/StygianIronAnvil.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/StygianIronAnvil.java @@ -4,6 +4,7 @@ import com.cleanroommc.groovyscript.compat.mods.ModSupport; import com.cleanroommc.groovyscript.core.mixin.woot.AnvilManagerAccessor; 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 ipsis.Woot; @@ -113,7 +114,7 @@ public void validate(GroovyLog.Msg msg) { // validateItems(msg, 1, 6, 1, 1); validateItems(msg, 1, Integer.MAX_VALUE, 1, 1); validateFluids(msg); - msg.add(base.isEmpty(), "base must be defined"); + msg.add(IngredientHelper.isEmpty(base), "base must be defined"); } @Override diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Woot.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Woot.java index 93ef29f12..f0aec1566 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Woot.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/woot/Woot.java @@ -4,11 +4,11 @@ public class Woot extends ModPropertyContainer { - StygianIronAnvil stygianIronAnvil = new StygianIronAnvil(); - Drops drops = new Drops(); - Spawning spawning = new Spawning(); - Policy policy = new Policy(); - MobConfig mobConfig = new MobConfig(); + public final StygianIronAnvil stygianIronAnvil = new StygianIronAnvil(); + public final Drops drops = new Drops(); + public final Spawning spawning = new Spawning(); + public final Policy policy = new Policy(); + public final MobConfig mobConfig = new MobConfig(); public Woot() { addRegistry(stygianIronAnvil); diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropsRepositoryAccessor.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropsRepositoryAccessor.java index d0b330f76..13ab7fb7d 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropsRepositoryAccessor.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/woot/CustomDropsRepositoryAccessor.java @@ -11,6 +11,5 @@ public interface CustomDropsRepositoryAccessor { @Accessor List getDrops(); - //List getDrops(); } From 48724f9cf90ce1103db128e97b92c293cf65265f Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Sat, 5 Aug 2023 07:49:58 -0700 Subject: [PATCH 3/3] move examples file --- examples/{ => postInit}/woot.groovy | 2 ++ 1 file changed, 2 insertions(+) rename examples/{ => postInit}/woot.groovy (99%) diff --git a/examples/woot.groovy b/examples/postInit/woot.groovy similarity index 99% rename from examples/woot.groovy rename to examples/postInit/woot.groovy index 81065574d..26ebcd6a0 100644 --- a/examples/woot.groovy +++ b/examples/postInit/woot.groovy @@ -3,6 +3,8 @@ import ipsis.woot.util.WootMobName +if (!isLoaded('woot')) return +println 'mod \'woot\' detected, running script' // Note: // Drops, Spawning, Policy, and Mob Config can also be controlled via .json config file