From edf41bda191337c5986499370371806d8ca86a50 Mon Sep 17 00:00:00 2001 From: Cyborgmas Date: Tue, 8 Sep 2020 15:11:08 -0400 Subject: [PATCH] Add dataprovider for Global Loot Modifiers (#6960) --- build.gradle | 3 +- .../loot_modifiers/global_loot_modifiers.json | 7 ++ .../loot_modifiers/smelting.json | 18 +++ .../loot_modifiers/wheat_harvest.json | 18 +++ .../data/GlobalLootModifierProvider.java | 119 ++++++++++++++++++ .../loot/GlobalLootModifierSerializer.java | 19 +++ .../loot/GlobalLootModifiersTest.java | 110 ++++++++++++---- 7 files changed, 268 insertions(+), 26 deletions(-) create mode 100644 src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json create mode 100644 src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json create mode 100644 src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json create mode 100644 src/main/java/net/minecraftforge/common/data/GlobalLootModifierProvider.java diff --git a/build.gradle b/build.gradle index 511883ec6..d59597aff 100644 --- a/build.gradle +++ b/build.gradle @@ -349,7 +349,8 @@ project(':forge') { args '--flat', '--all', '--validate', '--mod', 'data_gen_test', - '--mod', 'piston_event_test', + '--mod', 'piston_event_test', + '--mod', 'global_loot_test', '--output', rootProject.file('src/generated_test/resources/'), '--existing', sourceSets.main.resources.srcDirs[0] } diff --git a/src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json b/src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json new file mode 100644 index 000000000..357a58d7a --- /dev/null +++ b/src/generated_test/resources/data/forge/loot_modifiers/global_loot_modifiers.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "entries": [ + "global_loot_test:wheat_harvest", + "global_loot_test:smelting" + ] +} \ No newline at end of file diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json b/src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json new file mode 100644 index 000000000..60c612111 --- /dev/null +++ b/src/generated_test/resources/data/global_loot_test/loot_modifiers/smelting.json @@ -0,0 +1,18 @@ +{ + "conditions": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "enchantments": [ + { + "enchantment": "global_loot_test:smelt", + "levels": { + "min": 1 + } + } + ] + } + } + ], + "type": "global_loot_test:smelting" +} \ No newline at end of file diff --git a/src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json b/src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json new file mode 100644 index 000000000..fd7ea7894 --- /dev/null +++ b/src/generated_test/resources/data/global_loot_test/loot_modifiers/wheat_harvest.json @@ -0,0 +1,18 @@ +{ + "conditions": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "item": "minecraft:shears" + } + }, + { + "condition": "minecraft:block_state_property", + "block": "minecraft:wheat" + } + ], + "numSeeds": 3, + "seedItem": "minecraft:wheat_seeds", + "replacement": "minecraft:wheat", + "type": "global_loot_test:wheat_harvest" +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/common/data/GlobalLootModifierProvider.java b/src/main/java/net/minecraftforge/common/data/GlobalLootModifierProvider.java new file mode 100644 index 000000000..f7dc9f098 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/data/GlobalLootModifierProvider.java @@ -0,0 +1,119 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2020. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.common.data; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import cpw.mods.modlauncher.api.LamdbaExceptionUtils; +import net.minecraft.data.DataGenerator; +import net.minecraft.data.DirectoryCache; +import net.minecraft.data.IDataProvider; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Tuple; +import net.minecraftforge.common.loot.GlobalLootModifierSerializer; +import net.minecraftforge.common.loot.IGlobalLootModifier; +import net.minecraftforge.common.loot.LootModifier; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Provider for forge's GlobalLootModifier system. See {@link LootModifier} and {@link GlobalLootModifierSerializer}. + * + * This provider only requires implementing {@link #start()} and calling {@link #add} from it. + */ +public abstract class GlobalLootModifierProvider implements IDataProvider +{ + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + private final DataGenerator gen; + private final String modid; + private final Map, JsonObject>> toSerialize = new HashMap<>(); + private boolean replace = false; + + public GlobalLootModifierProvider(DataGenerator gen, String modid) + { + this.gen = gen; + this.modid = modid; + } + + /** + * Sets the "replace" key in global_loot_modifiers to true. + */ + protected void replacing() + { + this.replace = true; + } + + /** + * Call {@link #add} here, which will pass in the necessary information to write the jsons. + */ + protected abstract void start(); + + @Override + public void act(DirectoryCache cache) throws IOException + { + start(); + + Path forgePath = gen.getOutputFolder().resolve("data/forge/loot_modifiers/global_loot_modifiers.json"); + String modPath = "data/" + modid + "/loot_modifiers/"; + List entries = new ArrayList<>(); + + toSerialize.forEach(LamdbaExceptionUtils.rethrowBiConsumer((name, pair) -> + { + entries.add(new ResourceLocation(modid, name)); + Path modifierPath = gen.getOutputFolder().resolve(modPath + name + ".json"); + + JsonObject json = pair.getB(); + json.addProperty("type", pair.getA().getRegistryName().toString()); + + IDataProvider.save(GSON, cache, json, modifierPath); + })); + + JsonObject forgeJson = new JsonObject(); + forgeJson.addProperty("replace", this.replace); + forgeJson.add("entries", GSON.toJsonTree(entries.stream().map(ResourceLocation::toString).collect(Collectors.toList()))); + + IDataProvider.save(GSON, cache, forgeJson, forgePath); + } + + /** + * Passes in the data needed to create the file without any extra objects. + * + * @param modifier The name of the modifier, which will be the file name. + * @param serializer The serializer of this modifier. + * @param conditions The loot conditions before {@link LootModifier#doApply} is called. + */ + public void add(String modifier, GlobalLootModifierSerializer serializer, T instance) + { + this.toSerialize.put(modifier, new Tuple<>(serializer, serializer.write(instance))); + } + + @Override + public String getName() + { + return "Global Loot Modifiers : " + modid; + } +} diff --git a/src/main/java/net/minecraftforge/common/loot/GlobalLootModifierSerializer.java b/src/main/java/net/minecraftforge/common/loot/GlobalLootModifierSerializer.java index b62532605..d75493911 100644 --- a/src/main/java/net/minecraftforge/common/loot/GlobalLootModifierSerializer.java +++ b/src/main/java/net/minecraftforge/common/loot/GlobalLootModifierSerializer.java @@ -21,6 +21,7 @@ package net.minecraftforge.common.loot; import com.google.gson.JsonObject; +import net.minecraft.loot.ConditionArraySerializer; import net.minecraft.loot.conditions.ILootCondition; import net.minecraft.util.ResourceLocation; import net.minecraftforge.registries.GameData; @@ -64,6 +65,24 @@ public abstract class GlobalLootModifierSerializer> GLM = DeferredRegister.create(ForgeRegistries.LOOT_MODIFIER_SERIALIZERS, MODID); + private static final DeferredRegister ENCHANTS = DeferredRegister.create(ForgeRegistries.ENCHANTMENTS, MODID); + + private static final RegistryObject SMELTING = GLM.register("smelting", SmeltingEnchantmentModifier.Serializer::new); + private static final RegistryObject WHEATSEEDS = GLM.register("wheat_harvest", WheatSeedsConverterModifier.Serializer::new); + private static final RegistryObject SILKTOUCH = GLM.register("silk_touch_bamboo", SilkTouchTestModifier.Serializer::new); + private static final RegistryObject SMELT = ENCHANTS.register("smelt", () -> new SmelterEnchantment(Rarity.UNCOMMON, EnchantmentType.DIGGER, EquipmentSlotType.MAINHAND)); @EventBusSubscriber(modid = MODID, bus = EventBusSubscriber.Bus.MOD) public static class EventHandlers { @SubscribeEvent - public static void registerEnchantments(@Nonnull final RegistryEvent.Register event) { - if (ENABLE) { - event.getRegistry().register(new SmelterEnchantment(Rarity.UNCOMMON, EnchantmentType.DIGGER, new EquipmentSlotType[] {EquipmentSlotType.MAINHAND}).setRegistryName(new ResourceLocation(MODID,"smelt"))); - } + public static void runData(GatherDataEvent event) + { + if(ENABLE) + event.getGenerator().addProvider(new DataProvider(event.getGenerator(), MODID)); + } + } + + private static class DataProvider extends GlobalLootModifierProvider + { + public DataProvider(DataGenerator gen, String modid) + { + super(gen, modid); } - @SubscribeEvent - public static void registerModifierSerializers(@Nonnull final RegistryEvent.Register> event) { - if (ENABLE) { - event.getRegistry().register( - new WheatSeedsConverterModifier.Serializer().setRegistryName(new ResourceLocation(MODID,"wheat_harvest")) - ); - event.getRegistry().register(new SmeltingEnchantmentModifier.Serializer().setRegistryName(new ResourceLocation(MODID,"smelting"))); - event.getRegistry().register(new SilkTouchTestModifier.Serializer().setRegistryName(new ResourceLocation(MODID,"silk_touch_bamboo"))); - } + @Override + protected void start() + { + add("smelting", SMELTING.get(), new SmeltingEnchantmentModifier( + new ILootCondition[]{ + MatchTool.builder( + ItemPredicate.Builder.create().enchantment( + new EnchantmentPredicate(SMELT.get(), MinMaxBounds.IntBound.atLeast(1)))) + .build() + }) + ); + + add("wheat_harvest", WHEATSEEDS.get(), new WheatSeedsConverterModifier( + new ILootCondition[] { + MatchTool.builder(ItemPredicate.Builder.create().item(Items.SHEARS)).build(), + BlockStateProperty.builder(Blocks.WHEAT).build() + }, + 3, Items.WHEAT_SEEDS, Items.WHEAT) + ); } } @@ -119,6 +160,11 @@ public class GlobalLootModifiersTest { public SmeltingEnchantmentModifier read(ResourceLocation name, JsonObject json, ILootCondition[] conditionsIn) { return new SmeltingEnchantmentModifier(conditionsIn); } + + @Override + public JsonObject write(SmeltingEnchantmentModifier instance) { + return makeConditions(instance.conditions); + } } } @@ -151,6 +197,11 @@ public class GlobalLootModifiersTest { public SilkTouchTestModifier read(ResourceLocation name, JsonObject json, ILootCondition[] conditionsIn) { return new SilkTouchTestModifier(conditionsIn); } + + @Override + public JsonObject write(SilkTouchTestModifier instance) { + return makeConditions(instance.conditions); + } } } @@ -201,6 +252,15 @@ public class GlobalLootModifiersTest { Item wheat = ForgeRegistries.ITEMS.getValue(new ResourceLocation(JSONUtils.getString(object, "replacement"))); return new WheatSeedsConverterModifier(conditionsIn, numSeeds, seed, wheat); } + + @Override + public JsonObject write(WheatSeedsConverterModifier instance) { + JsonObject json = makeConditions(instance.conditions); + json.addProperty("numSeeds", instance.numSeedsToConvert); + json.addProperty("seedItem", ForgeRegistries.ITEMS.getKey(instance.itemToCheck).toString()); + json.addProperty("replacement", ForgeRegistries.ITEMS.getKey(instance.itemReward).toString()); + return json; + } } } }