--- a/net/minecraft/world/level/storage/loot/LootTables.java
+++ b/net/minecraft/world/level/storage/loot/LootTables.java
@@ -1,60 +1,80 @@
 package net.minecraft.world.level.storage.loot;
 
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
 import com.google.gson.Gson;
 import com.google.gson.JsonElement;
 import com.mojang.logging.LogUtils;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
+import java.util.function.Function;
 import net.minecraft.resources.ResourceLocation;
 import net.minecraft.server.packs.resources.ResourceManager;
 import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
 import net.minecraft.util.profiling.ProfilerFiller;
+import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet;
 import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
 import org.slf4j.Logger;
 
 public class LootTables extends SimpleJsonResourceReloadListener {
+
     private static final Logger LOGGER = LogUtils.getLogger();
     private static final Gson GSON = Deserializers.createLootTableSerializer().create();
     private Map<ResourceLocation, LootTable> tables = ImmutableMap.of();
+    public Map<LootTable, ResourceLocation> lootTableToKey = ImmutableMap.of(); // CraftBukkit
     private final PredicateManager predicateManager;
 
     public LootTables(PredicateManager conditionManager) {
-        super(GSON, "loot_tables");
+        super(LootTables.GSON, "loot_tables");
         this.predicateManager = conditionManager;
     }
 
     public LootTable get(ResourceLocation id) {
-        return this.tables.getOrDefault(id, LootTable.EMPTY);
+        return (LootTable) this.tables.getOrDefault(id, LootTable.EMPTY);
     }
 
-    @Override
     protected void apply(Map<ResourceLocation, JsonElement> prepared, ResourceManager manager, ProfilerFiller profiler) {
-        ImmutableMap.Builder<ResourceLocation, LootTable> builder = ImmutableMap.builder();
-        JsonElement jsonElement = prepared.remove(BuiltInLootTables.EMPTY);
-        if (jsonElement != null) {
-            LOGGER.warn("Datapack tried to redefine {} loot table, ignoring", (Object)BuiltInLootTables.EMPTY);
+        Builder<ResourceLocation, LootTable> builder = ImmutableMap.builder();
+        JsonElement jsonelement = (JsonElement) prepared.remove(BuiltInLootTables.EMPTY);
+
+        if (jsonelement != null) {
+            LootTables.LOGGER.warn("Datapack tried to redefine {} loot table, ignoring", BuiltInLootTables.EMPTY);
         }
 
-        prepared.forEach((id, json) -> {
+        prepared.forEach((minecraftkey, jsonelement1) -> {
             try {
-                LootTable lootTable = GSON.fromJson(json, LootTable.class);
-                builder.put(id, lootTable);
-            } catch (Exception var4) {
-                LOGGER.error("Couldn't parse loot table {}", id, var4);
+                LootTable loottable = (LootTable) LootTables.GSON.fromJson(jsonelement1, LootTable.class);
+
+                builder.put(minecraftkey, loottable);
+            } catch (Exception exception) {
+                LootTables.LOGGER.error("Couldn't parse loot table {}", minecraftkey, exception);
             }
 
         });
         builder.put(BuiltInLootTables.EMPTY, LootTable.EMPTY);
-        ImmutableMap<ResourceLocation, LootTable> immutableMap = builder.build();
-        ValidationContext validationContext = new ValidationContext(LootContextParamSets.ALL_PARAMS, this.predicateManager::get, immutableMap::get);
-        immutableMap.forEach((id, lootTable) -> {
-            validate(validationContext, id, lootTable);
+        ImmutableMap<ResourceLocation, LootTable> immutablemap = builder.build();
+        LootContextParamSet lootcontextparameterset = LootContextParamSets.ALL_PARAMS;
+        PredicateManager lootpredicatemanager = this.predicateManager;
+
+        Objects.requireNonNull(this.predicateManager);
+        Function<ResourceLocation, net.minecraft.world.level.storage.loot.predicates.LootItemCondition> function = lootpredicatemanager::get; // CraftBukkit - decompile error
+
+        Objects.requireNonNull(immutablemap);
+        ValidationContext lootcollector = new ValidationContext(lootcontextparameterset, function, immutablemap::get);
+
+        immutablemap.forEach((minecraftkey, loottable) -> {
+            LootTables.validate(lootcollector, minecraftkey, loottable);
         });
-        validationContext.getProblems().forEach((key, value) -> {
-            LOGGER.warn("Found validation problem in {}: {}", key, value);
+        lootcollector.getProblems().forEach((s, s1) -> {
+            LootTables.LOGGER.warn("Found validation problem in {}: {}", s, s1);
         });
-        this.tables = immutableMap;
+        this.tables = immutablemap;
+        // CraftBukkit start - build a reversed registry map
+        ImmutableMap.Builder<LootTable, ResourceLocation> lootTableToKeyBuilder = ImmutableMap.builder();
+        this.tables.forEach((lootTable, key) -> lootTableToKeyBuilder.put(key, lootTable));
+        this.lootTableToKey = lootTableToKeyBuilder.build();
+        // CraftBukkit end
     }
 
     public static void validate(ValidationContext reporter, ResourceLocation id, LootTable table) {
@@ -62,7 +82,7 @@
     }
 
     public static JsonElement serialize(LootTable table) {
-        return GSON.toJsonTree(table);
+        return LootTables.GSON.toJsonTree(table);
     }
 
     public Set<ResourceLocation> getIds() {
