diff --git a/fabric-loot-api-v2/README.md b/deprecated/fabric-loot-api-v2/README.md similarity index 100% rename from fabric-loot-api-v2/README.md rename to deprecated/fabric-loot-api-v2/README.md diff --git a/deprecated/fabric-loot-api-v2/build.gradle b/deprecated/fabric-loot-api-v2/build.gradle new file mode 100644 index 000000000..f7fd248b6 --- /dev/null +++ b/deprecated/fabric-loot-api-v2/build.gradle @@ -0,0 +1,7 @@ +version = getSubprojectVersion(project) + +moduleDependencies(project, [ + 'fabric-api-base', + 'fabric-resource-loader-v0', + 'fabric-loot-api-v3' +]) diff --git a/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/FabricLootPoolBuilder.java b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/FabricLootPoolBuilder.java new file mode 100644 index 000000000..209d0fb73 --- /dev/null +++ b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/FabricLootPoolBuilder.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 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.v2; + +import java.util.Collection; + +import org.jetbrains.annotations.ApiStatus; + +import net.minecraft.loot.LootPool; +import net.minecraft.loot.condition.LootCondition; +import net.minecraft.loot.entry.LootPoolEntry; +import net.minecraft.loot.function.LootFunction; + +/** + * Convenience extensions to {@link LootPool.Builder} + * for adding pre-built objects or collections. + * + *
This interface is automatically injected to {@link LootPool.Builder}. + * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder} instead. + */ +@ApiStatus.NonExtendable +@Deprecated +public interface FabricLootPoolBuilder { + /** + * Adds an entry to this builder. + * + * @param entry the added loot entry + * @return this builder + * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder#with(LootPoolEntry)} instead. + */ + @Deprecated + default LootPool.Builder with(LootPoolEntry entry) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Adds entries to this builder. + * + * @param entries the added loot entries + * @return this builder + * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder#with(LootPoolEntry)} instead. + */ + @Deprecated + default LootPool.Builder with(Collection extends LootPoolEntry> entries) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Adds a condition to this builder. + * + * @param condition the added condition + * @return this builder + * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder#conditionally(LootCondition)} instead. + */ + @Deprecated + default LootPool.Builder conditionally(LootCondition condition) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Adds conditions to this builder. + * + * @param conditions the added conditions + * @return this builder + * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder#conditionally(LootCondition)} instead. + */ + @Deprecated + default LootPool.Builder conditionally(Collection extends LootCondition> conditions) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Applies a function to this builder. + * + * @param function the applied loot function + * @return this builder + * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder#apply(LootFunction)} instead. + */ + @Deprecated + default LootPool.Builder apply(LootFunction function) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Applies loot functions to this builder. + * + * @param functions the applied loot functions + * @return this builder + * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder#apply(LootFunction)} instead. + */ + @Deprecated + default LootPool.Builder apply(Collection extends LootFunction> functions) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Creates a builder copy of a loot pool. + * + * @param pool the loot pool + * @return the copied builder + * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder#copyOf(LootPool)} instead. + */ + @Deprecated + static LootPool.Builder copyOf(LootPool pool) { + return net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder.copyOf(pool); + } +} diff --git a/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/FabricLootTableBuilder.java b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/FabricLootTableBuilder.java new file mode 100644 index 000000000..993d9b87e --- /dev/null +++ b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/FabricLootTableBuilder.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 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.v2; + +import java.util.Collection; +import java.util.function.Consumer; + +import org.jetbrains.annotations.ApiStatus; + +import net.minecraft.loot.LootPool; +import net.minecraft.loot.LootTable; +import net.minecraft.loot.function.LootFunction; + +/** + * Convenience extensions to {@link LootTable.Builder} + * for adding pre-built objects or collections and modifying loot pools. + * + *
This interface is automatically injected to {@link LootTable.Builder}. + * + * @deprecated use {@link net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder} instead. + */ +@ApiStatus.NonExtendable +@Deprecated +public interface FabricLootTableBuilder { + /** + * Adds a loot pool to this builder. + * + * @param pool the added pool + * @return this builder + * @deprecated use {@link net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder#pool(LootPool)} instead. + */ + @Deprecated + default LootTable.Builder pool(LootPool pool) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Applies a loot function to this builder. + * + * @param function the applied function + * @return this builder + * @deprecated use {@link net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder#apply(LootFunction)} instead. + */ + @Deprecated + default LootTable.Builder apply(LootFunction function) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Adds loot pools to this builder. + * + * @param pools the added pools + * @return this builder + * @deprecated use {@link net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder#pools(Collection)} instead. + */ + @Deprecated + default LootTable.Builder pools(Collection extends LootPool> pools) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Applies loot functions to this builder. + * + * @param functions the applied functions + * @return this builder + * @deprecated use {@link net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder#apply(Collection)} instead. + */ + @Deprecated + default LootTable.Builder apply(Collection extends LootFunction> functions) { + throw new UnsupportedOperationException("Implemented via mixin"); + } + + /** + * Modifies all loot pools already present in this builder. + * + *
This method can be used instead of simply adding a new pool + * when you want the loot table to only drop items from one of the loot pool entries + * instead of both. + * + *
Calling this method turns all pools into builders and rebuilds them back into loot pools afterwards,
+ * so it is more efficient to do all transformations with one {@code modifyPools} call.
+ *
+ * @param modifier the modifying function
+ * @return this builder
+ * @deprecated use {@link net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder#modifyPools(Consumer)} instead.
+ */
+ @Deprecated
+ default LootTable.Builder modifyPools(Consumer super LootPool.Builder> modifier) {
+ throw new UnsupportedOperationException("Implemented via mixin");
+ }
+
+ /**
+ * Creates a builder copy of a loot table.
+ *
+ * @param table the loot table
+ * @return the copied builder
+ * @deprecated use {@link net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder#copyOf(LootTable)} instead.
+ */
+ @Deprecated
+ static LootTable.Builder copyOf(LootTable table) {
+ return net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder.copyOf(table);
+ }
+}
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java
similarity index 90%
rename from fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java
rename to deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java
index dd7959779..5c1088d8d 100644
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java
+++ b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/LootTableEvents.java
@@ -28,7 +28,10 @@ import net.fabricmc.fabric.api.event.EventFactory;
/**
* Events for manipulating loot tables.
+ *
+ * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.LootTableEvents} instead.
*/
+@Deprecated
public final class LootTableEvents {
private LootTableEvents() {
}
@@ -36,7 +39,10 @@ public final class LootTableEvents {
/**
* This event can be used to replace loot tables.
* If a loot table is replaced, the iteration will stop for that loot table.
+ *
+ * @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.LootTableEvents#REPLACE} instead.
*/
+ @Deprecated
public static final Event This includes the additional builtin data packs registered by mods
+ * with Fabric Resource Loader.
+ */
+ MOD(true),
+
+ /**
+ * A loot table loaded from an external data pack.
+ */
+ DATA_PACK(false),
+
+ /**
+ * A loot table created in {@link LootTableEvents#REPLACE}.
+ */
+ REPLACED(false);
+
+ private final boolean builtin;
+
+ LootTableSource(boolean builtin) {
+ this.builtin = builtin;
+ }
+
+ /**
+ * Returns whether this loot table source is builtin
+ * and bundled in the vanilla or mod resources.
+ *
+ * {@link #VANILLA} and {@link #MOD} are builtin.
+ *
+ * @return {@code true} if builtin, {@code false} otherwise
+ */
+ public boolean isBuiltin() {
+ return builtin;
+ }
+}
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/package-info.java b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/package-info.java
similarity index 100%
rename from fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/package-info.java
rename to deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/api/loot/v2/package-info.java
diff --git a/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/impl/loot/v2/LootInitializer.java b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/impl/loot/v2/LootInitializer.java
new file mode 100644
index 000000000..adcd51932
--- /dev/null
+++ b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/impl/loot/v2/LootInitializer.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 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.v2;
+
+import net.fabricmc.api.ModInitializer;
+import net.fabricmc.fabric.api.loot.v3.LootTableEvents;
+import net.fabricmc.fabric.api.loot.v3.LootTableSource;
+
+public class LootInitializer implements ModInitializer {
+ @Override
+ public void onInitialize() {
+ // Forward the events to the v2 API.
+ LootTableEvents.REPLACE.register(((key, original, source, registries) -> net.fabricmc.fabric.api.loot.v2.LootTableEvents.REPLACE.invoker().replaceLootTable(key, original, toV2Source(source))));
+ LootTableEvents.MODIFY.register((key, tableBuilder, source, registries) -> net.fabricmc.fabric.api.loot.v2.LootTableEvents.MODIFY.invoker().modifyLootTable(key, tableBuilder, toV2Source(source)));
+ LootTableEvents.ALL_LOADED.register((resourceManager, lootRegistry) -> net.fabricmc.fabric.api.loot.v2.LootTableEvents.ALL_LOADED.invoker().onLootTablesLoaded(resourceManager, lootRegistry));
+ }
+
+ private static net.fabricmc.fabric.api.loot.v2.LootTableSource toV2Source(LootTableSource source) {
+ return switch (source) {
+ case VANILLA -> net.fabricmc.fabric.api.loot.v2.LootTableSource.VANILLA;
+ case MOD -> net.fabricmc.fabric.api.loot.v2.LootTableSource.MOD;
+ case DATA_PACK -> net.fabricmc.fabric.api.loot.v2.LootTableSource.DATA_PACK;
+ case REPLACED -> net.fabricmc.fabric.api.loot.v2.LootTableSource.REPLACED;
+ };
+ }
+}
diff --git a/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/v2/LootPoolBuilderMixin.java b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/v2/LootPoolBuilderMixin.java
new file mode 100644
index 000000000..c45d21c8d
--- /dev/null
+++ b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/v2/LootPoolBuilderMixin.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 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.v2;
+
+import org.spongepowered.asm.mixin.Mixin;
+
+import net.minecraft.loot.LootPool;
+
+import net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder;
+
+/**
+ * The v3 module injects all the necessary methods into the target class.
+ */
+@Mixin(LootPool.Builder.class)
+abstract class LootPoolBuilderMixin implements FabricLootPoolBuilder {
+}
diff --git a/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/v2/LootTableBuilderMixin.java b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/v2/LootTableBuilderMixin.java
new file mode 100644
index 000000000..c887fa132
--- /dev/null
+++ b/deprecated/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/v2/LootTableBuilderMixin.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 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.v2;
+
+import org.spongepowered.asm.mixin.Mixin;
+
+import net.minecraft.loot.LootTable;
+
+import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
+
+/**
+ * The v3 module injects all the necessary methods into the target class.
+ */
+@Mixin(LootTable.Builder.class)
+abstract class LootTableBuilderMixin implements FabricLootTableBuilder {
+}
diff --git a/fabric-loot-api-v2/src/main/resources/assets/fabric-loot-api-v2/icon.png b/deprecated/fabric-loot-api-v2/src/main/resources/assets/fabric-loot-api-v2/icon.png
similarity index 100%
rename from fabric-loot-api-v2/src/main/resources/assets/fabric-loot-api-v2/icon.png
rename to deprecated/fabric-loot-api-v2/src/main/resources/assets/fabric-loot-api-v2/icon.png
diff --git a/deprecated/fabric-loot-api-v2/src/main/resources/fabric-loot-api-v2.mixins.json b/deprecated/fabric-loot-api-v2/src/main/resources/fabric-loot-api-v2.mixins.json
new file mode 100644
index 000000000..15d28a491
--- /dev/null
+++ b/deprecated/fabric-loot-api-v2/src/main/resources/fabric-loot-api-v2.mixins.json
@@ -0,0 +1,12 @@
+{
+ "required": true,
+ "package": "net.fabricmc.fabric.mixin.loot.v2",
+ "compatibilityLevel": "JAVA_17",
+ "mixins": [
+ "LootPoolBuilderMixin",
+ "LootTableBuilderMixin"
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/deprecated/fabric-loot-api-v2/src/main/resources/fabric.mod.json b/deprecated/fabric-loot-api-v2/src/main/resources/fabric.mod.json
new file mode 100644
index 000000000..a7cdc9dd9
--- /dev/null
+++ b/deprecated/fabric-loot-api-v2/src/main/resources/fabric.mod.json
@@ -0,0 +1,35 @@
+{
+ "schemaVersion": 1,
+ "id": "fabric-loot-api-v2",
+ "name": "Fabric Loot API (v2)",
+ "version": "${version}",
+ "environment": "*",
+ "license": "Apache-2.0",
+ "icon": "assets/fabric-loot-api-v2/icon.png",
+ "contact": {
+ "homepage": "https://fabricmc.net",
+ "irc": "irc://irc.esper.net:6667/fabric",
+ "issues": "https://github.com/FabricMC/fabric/issues",
+ "sources": "https://github.com/FabricMC/fabric"
+ },
+ "authors": [
+ "FabricMC"
+ ],
+ "depends": {
+ "fabricloader": ">=0.15.11",
+ "fabric-api-base": "*",
+ "fabric-resource-loader-v0": "*"
+ },
+ "description": "Hooks for manipulating loot tables.",
+ "entrypoints": {
+ "main": [
+ "net.fabricmc.fabric.impl.loot.v2.LootInitializer"
+ ]
+ },
+ "mixins": [
+ "fabric-loot-api-v2.mixins.json"
+ ],
+ "custom": {
+ "fabric-api:module-lifecycle": "deprecated"
+ }
+}
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/ReloadableRegistriesMixin.java b/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/ReloadableRegistriesMixin.java
deleted file mode 100644
index aaedc21da..000000000
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/ReloadableRegistriesMixin.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, 2018, 2019 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 com.llamalad7.mixinextras.sugar.Local;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.ModifyArg;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import net.minecraft.loot.LootDataType;
-import net.minecraft.loot.LootTable;
-import net.minecraft.registry.MutableRegistry;
-import net.minecraft.registry.Registry;
-import net.minecraft.registry.RegistryKey;
-import net.minecraft.registry.RegistryKeys;
-import net.minecraft.registry.RegistryOps;
-import net.minecraft.registry.ReloadableRegistries;
-import net.minecraft.resource.ResourceManager;
-import net.minecraft.util.Identifier;
-
-import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
-import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
-import net.fabricmc.fabric.api.loot.v2.LootTableSource;
-import net.fabricmc.fabric.impl.loot.LootUtil;
-
-/**
- * Implements the events from {@link LootTableEvents}.
- */
-@Mixin(ReloadableRegistries.class)
-abstract class ReloadableRegistriesMixin {
- @ModifyArg(method = "method_58286", at = @At(value = "INVOKE", target = "Lnet/minecraft/registry/MutableRegistry;add(Lnet/minecraft/registry/RegistryKey;Ljava/lang/Object;Lnet/minecraft/registry/entry/RegistryEntryInfo;)Lnet/minecraft/registry/entry/RegistryEntry$Reference;"), index = 1)
- private static Object modifyLootTable(Object value, @Local(argsOnly = true) Identifier id) {
- if (!(value instanceof LootTable table)) return value;
-
- if (table == LootTable.EMPTY) {
- // This is a special table and cannot be modified.
- return value;
- }
-
- RegistryKey You can also modify loot tables that are created by {@link #REPLACE}.
+ * They have the loot table source {@link LootTableSource#REPLACED}.
+ *
+ * If you want only one of the items to drop, you can use
+ * {@link FabricLootTableBuilder#modifyPools(java.util.function.Consumer)} to add the new item to
+ * the original loot pool instead.
+ * {@snippet :
+ * LootTableEvents.MODIFY.register((key, tableBuilder, source, registries) -> {
+ * // If the loot table is for the cobblestone block and it is not overridden by a user:
+ * if (Blocks.COBBLESTONE.getLootTableKey() == key && source.isBuiltin()) {
+ * // Create a new loot pool that will hold the diamonds.
+ * LootPool.Builder pool = LootPool.builder()
+ * // Add diamonds...
+ * .with(ItemEntry.builder(Items.DIAMOND))
+ * // ...only if the block would survive a potential explosion.
+ * .conditionally(SurvivesExplosionLootCondition.builder());
+ *
+ * // Add the loot pool to the loot table
+ * tableBuilder.pool(pool);
+ * }
+ * });
+ * }
+ */
+ public static final Event You can also check where loot tables are coming from in those events with
+ * {@link net.fabricmc.fabric.api.loot.v3.LootTableSource}. This is useful when you only want to modify
+ * loot tables from mods or vanilla, but not user-created data packs.
+ *
+ * Example: adding diamonds to the cobblestone loot table
+ * We'll add a new diamond {@linkplain net.minecraft.loot.LootPool loot pool} to the cobblestone loot table
+ * that will be dropped alongside the original cobblestone loot pool.
+ *
+ * Events
+ * {@link net.fabricmc.fabric.api.loot.v3.LootTableEvents} has events to modify existing loot tables,
+ * or outright replace them with a new loot table.
+ *
+ * Extended loot table and pool builders
+ * This API has injected interfaces to add useful methods to
+ * {@linkplain net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder loot table} and
+ * {@linkplain net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder loot pool} builders.
+ * They let you add pre-built objects instead of builders, and collections of objects to the builder
+ * with one method call.
+ */
+package net.fabricmc.fabric.api.loot.v3;
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java
similarity index 97%
rename from fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java
rename to fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java
index 2dfa5cf47..0f4543d4e 100644
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/impl/loot/LootUtil.java
@@ -23,7 +23,7 @@ import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourcePackSource;
import net.minecraft.util.Identifier;
-import net.fabricmc.fabric.api.loot.v2.LootTableSource;
+import net.fabricmc.fabric.api.loot.v3.LootTableSource;
import net.fabricmc.fabric.impl.resource.loader.BuiltinModResourcePackSource;
import net.fabricmc.fabric.impl.resource.loader.FabricResource;
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackCreator;
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/JsonDataLoaderMixin.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/JsonDataLoaderMixin.java
similarity index 100%
rename from fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/JsonDataLoaderMixin.java
rename to fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/JsonDataLoaderMixin.java
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolAccessor.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolAccessor.java
similarity index 91%
rename from fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolAccessor.java
rename to fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolAccessor.java
index f681f0f75..c855bd63a 100644
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolAccessor.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolAccessor.java
@@ -27,8 +27,10 @@ import net.minecraft.loot.entry.LootPoolEntry;
import net.minecraft.loot.function.LootFunction;
import net.minecraft.loot.provider.number.LootNumberProvider;
+import net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder;
+
/**
- * Accesses loot pool fields for {@link net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder#copyOf(LootPool)}.
+ * Accesses loot pool fields for {@link FabricLootPoolBuilder#copyOf(LootPool)}.
* These are normally available in the transitive access widener module.
*/
@Mixin(LootPool.class)
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderMixin.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderMixin.java
similarity index 97%
rename from fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderMixin.java
rename to fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderMixin.java
index d0326b7de..65e068113 100644
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderMixin.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderMixin.java
@@ -29,7 +29,7 @@ import net.minecraft.loot.condition.LootCondition;
import net.minecraft.loot.entry.LootPoolEntry;
import net.minecraft.loot.function.LootFunction;
-import net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder;
+import net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder;
/**
* The implementation of the injected interface {@link FabricLootPoolBuilder}.
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableAccessor.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableAccessor.java
similarity index 89%
rename from fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableAccessor.java
rename to fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableAccessor.java
index 4e8993eed..ac53818e1 100644
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableAccessor.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableAccessor.java
@@ -27,8 +27,10 @@ import net.minecraft.loot.LootTable;
import net.minecraft.loot.function.LootFunction;
import net.minecraft.util.Identifier;
+import net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder;
+
/**
- * Accesses loot table fields for {@link net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder#copyOf(LootTable)}.
+ * Accesses loot table fields for {@link FabricLootTableBuilder#copyOf(LootTable)}.
* These are normally available in the transitive access widener module.
*/
@Mixin(LootTable.class)
diff --git a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableBuilderMixin.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableBuilderMixin.java
similarity index 95%
rename from fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableBuilderMixin.java
rename to fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableBuilderMixin.java
index 91b5ed703..de6613703 100644
--- a/fabric-loot-api-v2/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableBuilderMixin.java
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/LootTableBuilderMixin.java
@@ -32,8 +32,8 @@ import net.minecraft.loot.LootPool;
import net.minecraft.loot.LootTable;
import net.minecraft.loot.function.LootFunction;
-import net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder;
-import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
+import net.fabricmc.fabric.api.loot.v3.FabricLootPoolBuilder;
+import net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder;
/**
* The implementation of the injected interface {@link FabricLootTableBuilder}.
diff --git a/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/ReloadableRegistriesMixin.java b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/ReloadableRegistriesMixin.java
new file mode 100644
index 000000000..a280f685b
--- /dev/null
+++ b/fabric-loot-api-v3/src/main/java/net/fabricmc/fabric/mixin/loot/ReloadableRegistriesMixin.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 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 java.util.List;
+import java.util.Optional;
+import java.util.WeakHashMap;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import com.google.gson.JsonElement;
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
+import com.mojang.serialization.DynamicOps;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Coerce;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+import net.minecraft.loot.LootDataType;
+import net.minecraft.loot.LootTable;
+import net.minecraft.registry.CombinedDynamicRegistries;
+import net.minecraft.registry.MutableRegistry;
+import net.minecraft.registry.Registry;
+import net.minecraft.registry.RegistryKey;
+import net.minecraft.registry.RegistryKeys;
+import net.minecraft.registry.RegistryOps;
+import net.minecraft.registry.RegistryWrapper;
+import net.minecraft.registry.ReloadableRegistries;
+import net.minecraft.registry.ServerDynamicRegistryType;
+import net.minecraft.resource.ResourceManager;
+import net.minecraft.util.Identifier;
+
+import net.fabricmc.fabric.api.loot.v3.FabricLootTableBuilder;
+import net.fabricmc.fabric.api.loot.v3.LootTableEvents;
+import net.fabricmc.fabric.api.loot.v3.LootTableSource;
+import net.fabricmc.fabric.impl.loot.LootUtil;
+
+/**
+ * Implements the events from {@link LootTableEvents}.
+ */
+@Mixin(ReloadableRegistries.class)
+abstract class ReloadableRegistriesMixin {
+ /**
+ * Due to possible cross-thread handling, this uses WeakHashMap instead of ThreadLocal.
+ */
+ @Unique
+ private static final WeakHashMap>> future, Function super List