From b88969cf131f8cae58b66e0c755559805f54e6ff Mon Sep 17 00:00:00 2001 From: Juuxel Date: Fri, 25 Jan 2019 23:53:11 +0100 Subject: [PATCH] (#59) Loot entry extensions --- .../fabric/api/loot/LootEntryRegistry.java | 37 ++++++++++++ .../impl/loot/LootEntryRegistryImpl.java | 47 +++++++++++++++ .../fabric/mixin/loot/MixinLootEntries.java | 37 ++++++++++++ .../net.fabricmc.fabric.mixins.common.json | 1 + .../fabricmc/fabric/loot/LootEntryMod.java | 60 +++++++++++++++++++ .../minecraft/loot_tables/blocks/stone.json | 44 ++++++++++++++ src/test/resources/mod.json | 3 +- 7 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/fabricmc/fabric/api/loot/LootEntryRegistry.java create mode 100644 src/main/java/net/fabricmc/fabric/impl/loot/LootEntryRegistryImpl.java create mode 100644 src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootEntries.java create mode 100644 src/test/java/net/fabricmc/fabric/loot/LootEntryMod.java create mode 100644 src/test/resources/data/minecraft/loot_tables/blocks/stone.json diff --git a/src/main/java/net/fabricmc/fabric/api/loot/LootEntryRegistry.java b/src/main/java/net/fabricmc/fabric/api/loot/LootEntryRegistry.java new file mode 100644 index 000000000..3567061fb --- /dev/null +++ b/src/main/java/net/fabricmc/fabric/api/loot/LootEntryRegistry.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.loot; + +import net.fabricmc.fabric.impl.loot.LootEntryRegistryImpl; +import net.minecraft.world.loot.entry.LootEntry; + +/** + * Fabric's extensions to {@code net.minecraft.world.loot.entry.LootEntries} for registering + * custom loot entry types. + * + * @see #registerType + */ +public interface LootEntryRegistry { + LootEntryRegistry INSTANCE = LootEntryRegistryImpl.INSTANCE; + + /** + * Registers a loot entry type by its serializer. + * + * @param serializer the loot entry serializer + */ + void registerType(LootEntry.Serializer serializer); +} diff --git a/src/main/java/net/fabricmc/fabric/impl/loot/LootEntryRegistryImpl.java b/src/main/java/net/fabricmc/fabric/impl/loot/LootEntryRegistryImpl.java new file mode 100644 index 000000000..86737f411 --- /dev/null +++ b/src/main/java/net/fabricmc/fabric/impl/loot/LootEntryRegistryImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.impl.loot; + +import net.fabricmc.fabric.api.loot.LootEntryRegistry; +import net.minecraft.world.loot.entry.LootEntries; +import net.minecraft.world.loot.entry.LootEntry; + +import java.util.function.Consumer; + +public final class LootEntryRegistryImpl implements LootEntryRegistry { + private static Consumer> registerFunction; + public static final LootEntryRegistryImpl INSTANCE = new LootEntryRegistryImpl(); + + static { + loadLootEntries(); + } + + private LootEntryRegistryImpl() {} + + @Override + public void registerType(LootEntry.Serializer serializer) { + registerFunction.accept(serializer); + } + + public static void setRegisterFunction(Consumer> registerFunction) { + LootEntryRegistryImpl.registerFunction = registerFunction; + } + + private static void loadLootEntries() { + try { Class.forName(LootEntries.class.getCanonicalName()); } catch (ClassNotFoundException e) {} + } +} diff --git a/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootEntries.java b/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootEntries.java new file mode 100644 index 000000000..1859c8f0a --- /dev/null +++ b/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootEntries.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.loot; + +import net.fabricmc.fabric.impl.loot.LootEntryRegistryImpl; +import net.minecraft.world.loot.entry.LootEntries; +import net.minecraft.world.loot.entry.LootEntry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LootEntries.class) +public class MixinLootEntries { + @Shadow + private static void register(LootEntry.Serializer lootEntry$Serializer_1) {} + + @Inject(method = "", at = @At("RETURN")) + private static void onClinit(CallbackInfo info) { + LootEntryRegistryImpl.setRegisterFunction(MixinLootEntries::register); + } +} diff --git a/src/main/resources/net.fabricmc.fabric.mixins.common.json b/src/main/resources/net.fabricmc.fabric.mixins.common.json index 137fd6dfa..283f7cc0a 100644 --- a/src/main/resources/net.fabricmc.fabric.mixins.common.json +++ b/src/main/resources/net.fabricmc.fabric.mixins.common.json @@ -19,6 +19,7 @@ "events.tick.MixinWorld", "item.MixinAbstractFurnaceBlockEntity", "itemgroup.MixinItemGroup", + "loot.MixinLootEntries", "misc.MixinCrashReport", "networking.MixinServerPlayNetworkHandler", "networking.MixinSPacketCustomPayload", diff --git a/src/test/java/net/fabricmc/fabric/loot/LootEntryMod.java b/src/test/java/net/fabricmc/fabric/loot/LootEntryMod.java new file mode 100644 index 000000000..3df13bae5 --- /dev/null +++ b/src/test/java/net/fabricmc/fabric/loot/LootEntryMod.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016, 2017, 2018 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.loot; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.loot.LootEntryRegistry; +import net.minecraft.util.Identifier; +import net.minecraft.util.JsonHelper; +import net.minecraft.world.loot.condition.LootCondition; +import net.minecraft.world.loot.entry.LootEntry; +import net.minecraft.world.loot.entry.TagEntry; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class LootEntryMod implements ModInitializer { + private static final Logger LOGGER = LogManager.getLogger(); + + @Override + public void onInitialize() { + LootEntryRegistry.INSTANCE.registerType(new TestSerializer()); + } + + private static class TestSerializer extends LootEntry.Serializer { + private static final TagEntry.Serializer SERIALIZER = new TagEntry.Serializer(); + + public TestSerializer() { + super(new Identifier("fabric", "extended_tag"), TagEntry.class); + } + + @Override + public void toJson(JsonObject obj, TagEntry entry, JsonSerializationContext context) { + SERIALIZER.method_451(obj, entry, context); + obj.addProperty("fabric", true); + } + + @Override + public TagEntry fromJson(JsonObject var1, JsonDeserializationContext var2, LootCondition[] var3) { + LOGGER.info("Is this a Fabric loot entry? " + JsonHelper.getBoolean(var1, "fabric", true)); + return SERIALIZER.fromJson(var1, var2, var3); + } + } +} + diff --git a/src/test/resources/data/minecraft/loot_tables/blocks/stone.json b/src/test/resources/data/minecraft/loot_tables/blocks/stone.json new file mode 100644 index 000000000..6b0ef6c00 --- /dev/null +++ b/src/test/resources/data/minecraft/loot_tables/blocks/stone.json @@ -0,0 +1,44 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "enchantments": [ + { + "enchantment": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + ], + "name": "minecraft:stone" + }, + { + "type": "fabric:extended_tag", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "name": "minecraft:wool", + "expand": false + } + ] + } + ] + } + ] +} diff --git a/src/test/resources/mod.json b/src/test/resources/mod.json index e24ed7115..44b50c290 100644 --- a/src/test/resources/mod.json +++ b/src/test/resources/mod.json @@ -9,6 +9,7 @@ "net.fabricmc.fabric.colormapper.ColorProviderMod", "net.fabricmc.fabric.events.ServerEventMod", "net.fabricmc.fabric.containers.ContainerMod", - "net.fabricmc.fabric.containers.ContainerModClient" + "net.fabricmc.fabric.containers.ContainerModClient", + "net.fabricmc.fabric.loot.LootEntryMod" ] }