mirror of
https://github.com/FabricMC/fabric.git
synced 2024-12-03 12:57:08 -05:00
fabric-loot-api-v3 (#3903)
* fabric-loot-api-v3 * Review fixes * Fix tests * More fixes
This commit is contained in:
parent
d57e92a907
commit
3f89f5a5c6
37 changed files with 852 additions and 108 deletions
7
deprecated/fabric-loot-api-v2/build.gradle
Normal file
7
deprecated/fabric-loot-api-v2/build.gradle
Normal file
|
@ -0,0 +1,7 @@
|
|||
version = getSubprojectVersion(project)
|
||||
|
||||
moduleDependencies(project, [
|
||||
'fabric-api-base',
|
||||
'fabric-resource-loader-v0',
|
||||
'fabric-loot-api-v3'
|
||||
])
|
|
@ -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.
|
||||
*
|
||||
* <p>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);
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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);
|
||||
}
|
||||
}
|
|
@ -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<Replace> REPLACE = EventFactory.createArrayBacked(Replace.class, listeners -> (key, original, source) -> {
|
||||
for (Replace listener : listeners) {
|
||||
@Nullable LootTable replaced = listener.replaceLootTable(key, original, source);
|
||||
|
@ -82,7 +88,10 @@ public final class LootTableEvents {
|
|||
* });
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.LootTableEvents#MODIFY} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Event<Modify> MODIFY = EventFactory.createArrayBacked(Modify.class, listeners -> (key, tableBuilder, source) -> {
|
||||
for (Modify listener : listeners) {
|
||||
listener.modifyLootTable(key, tableBuilder, source);
|
||||
|
@ -91,13 +100,17 @@ public final class LootTableEvents {
|
|||
|
||||
/**
|
||||
* This event can be used for post-processing after all loot tables have been loaded and modified by Fabric.
|
||||
*
|
||||
* @deprecated Please use {@link net.fabricmc.fabric.api.loot.v3.LootTableEvents#ALL_LOADED} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Event<Loaded> ALL_LOADED = EventFactory.createArrayBacked(Loaded.class, listeners -> (resourceManager, lootManager) -> {
|
||||
for (Loaded listener : listeners) {
|
||||
listener.onLootTablesLoaded(resourceManager, lootManager);
|
||||
}
|
||||
});
|
||||
|
||||
@Deprecated
|
||||
public interface Replace {
|
||||
/**
|
||||
* Replaces loot tables.
|
||||
|
@ -111,6 +124,7 @@ public final class LootTableEvents {
|
|||
LootTable replaceLootTable(RegistryKey<LootTable> key, LootTable original, LootTableSource source);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public interface Modify {
|
||||
/**
|
||||
* Called when a loot table is loading to modify loot tables.
|
||||
|
@ -122,6 +136,7 @@ public final class LootTableEvents {
|
|||
void modifyLootTable(RegistryKey<LootTable> key, LootTable.Builder tableBuilder, LootTableSource source);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public interface Loaded {
|
||||
/**
|
||||
* Called when all loot tables have been loaded and {@link LootTableEvents#REPLACE} and {@link LootTableEvents#MODIFY} have been invoked.
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Describes where a loot table has been loaded from.
|
||||
* @deprecated Use {@link net.fabricmc.fabric.api.loot.v3.LootTableSource} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public enum LootTableSource {
|
||||
/**
|
||||
* A loot table loaded from the default data pack.
|
||||
*/
|
||||
VANILLA(true),
|
||||
|
||||
/**
|
||||
* A loot table loaded from mods' bundled resources.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>{@link #VANILLA} and {@link #MOD} are builtin.
|
||||
*
|
||||
* @return {@code true} if builtin, {@code false} otherwise
|
||||
*/
|
||||
public boolean isBuiltin() {
|
||||
return builtin;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -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 {
|
||||
}
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.mixin.loot.v2",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"LootPoolBuilderMixin",
|
||||
"LootTableBuilderMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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<LootTable> key = RegistryKey.of(RegistryKeys.LOOT_TABLE, id);
|
||||
// Populated inside JsonDataLoaderMixin
|
||||
LootTableSource source = LootUtil.SOURCES.get().getOrDefault(id, LootTableSource.DATA_PACK);
|
||||
// Invoke the REPLACE event for the current loot table.
|
||||
LootTable replacement = LootTableEvents.REPLACE.invoker().replaceLootTable(key, table, source);
|
||||
|
||||
if (replacement != null) {
|
||||
// Set the loot table to MODIFY to be the replacement loot table.
|
||||
// The MODIFY event will also see it as a replaced loot table via the source.
|
||||
table = replacement;
|
||||
source = LootTableSource.REPLACED;
|
||||
}
|
||||
|
||||
// Turn the current table into a modifiable builder and invoke the MODIFY event.
|
||||
LootTable.Builder builder = FabricLootTableBuilder.copyOf(table);
|
||||
LootTableEvents.MODIFY.invoker().modifyLootTable(key, builder, source);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Inject(method = "method_58279", at = @At("RETURN"))
|
||||
private static void onLootTablesLoaded(LootDataType lootDataType, ResourceManager resourceManager, RegistryOps registryOps, CallbackInfoReturnable<MutableRegistry> cir) {
|
||||
if (lootDataType != LootDataType.LOOT_TABLES) return;
|
||||
|
||||
LootTableEvents.ALL_LOADED.invoker().onLootTablesLoaded(resourceManager, (Registry<LootTable>) cir.getReturnValue());
|
||||
LootUtil.SOURCES.remove();
|
||||
}
|
||||
}
|
29
fabric-loot-api-v3/README.md
Normal file
29
fabric-loot-api-v3/README.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Fabric Loot API (v3)
|
||||
|
||||
This module includes APIs for modifying and creating loot tables.
|
||||
|
||||
## [Loot table events](src/main/java/net/fabricmc/fabric/api/loot/v3/LootTableEvents.java)
|
||||
|
||||
This class provides two events for modifying loot tables.
|
||||
|
||||
`LootTableEvents.REPLACE` runs first and lets you replace loot tables completely.
|
||||
|
||||
`LootTableEvents.MODIFY` runs after and lets you modify loot tables, including the ones created in `REPLACE`,
|
||||
by adding new loot pools or loot functions to them.
|
||||
|
||||
### Loot table sources
|
||||
|
||||
Both events have access to a [loot table source](src/main/java/net/fabricmc/fabric/api/loot/v3/LootTableSource.java)
|
||||
that you can use to check where a loot table is loaded from.
|
||||
|
||||
For example, you can use this to check if a loot table is from a user data pack and
|
||||
not modify the user-provided data in your event.
|
||||
|
||||
## Enhanced loot table and loot pool builders
|
||||
|
||||
`LootTable.Builder` and `LootPool.Builder` implement
|
||||
injected interfaces ([`FabricLootTableBuilder`](src/main/java/net/fabricmc/fabric/api/loot/v3/FabricLootTableBuilder.java)
|
||||
and [`FabricLootPoolBuilder`](src/main/java/net/fabricmc/fabric/api/loot/v3/FabricLootPoolBuilder.java))
|
||||
which have additional methods for dealing with already-built objects and collections of objects.
|
||||
|
||||
Those interfaces also have `copyOf` methods for creating copies of existing loot tables/pools as builders.
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v2;
|
||||
package net.fabricmc.fabric.api.loot.v3;
|
||||
|
||||
import java.util.Collection;
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v2;
|
||||
package net.fabricmc.fabric.api.loot.v3;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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.v3;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryWrapper;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
||||
/**
|
||||
* Events for manipulating loot tables.
|
||||
*/
|
||||
public final class LootTableEvents {
|
||||
private LootTableEvents() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This event can be used to replace loot tables.
|
||||
* If a loot table is replaced, the iteration will stop for that loot table.
|
||||
*/
|
||||
public static final Event<Replace> REPLACE = EventFactory.createArrayBacked(Replace.class, listeners -> (key, original, source, registries) -> {
|
||||
for (Replace listener : listeners) {
|
||||
@Nullable LootTable replaced = listener.replaceLootTable(key, original, source, registries);
|
||||
|
||||
if (replaced != null) {
|
||||
return replaced;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
/**
|
||||
* This event can be used to modify loot tables.
|
||||
* The main use case is to add items to vanilla or mod loot tables (e.g. modded seeds to grass).
|
||||
*
|
||||
* <p>You can also modify loot tables that are created by {@link #REPLACE}.
|
||||
* They have the loot table source {@link LootTableSource#REPLACED}.
|
||||
*
|
||||
* <h2>Example: adding diamonds to the cobblestone loot table</h2>
|
||||
* 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.
|
||||
*
|
||||
* <p>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<Modify> MODIFY = EventFactory.createArrayBacked(Modify.class, listeners -> (key, tableBuilder, source, registries) -> {
|
||||
for (Modify listener : listeners) {
|
||||
listener.modifyLootTable(key, tableBuilder, source, registries);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* This event can be used for post-processing after all loot tables have been loaded and modified by Fabric.
|
||||
*/
|
||||
public static final Event<Loaded> ALL_LOADED = EventFactory.createArrayBacked(Loaded.class, listeners -> (resourceManager, lootManager) -> {
|
||||
for (Loaded listener : listeners) {
|
||||
listener.onLootTablesLoaded(resourceManager, lootManager);
|
||||
}
|
||||
});
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Replace {
|
||||
/**
|
||||
* Replaces loot tables.
|
||||
*
|
||||
* @param key the loot table key
|
||||
* @param original the original loot table
|
||||
* @param source the source of the original loot table
|
||||
* @param registries the registry wrapper lookup
|
||||
* @return the new loot table, or null if it wasn't replaced
|
||||
*/
|
||||
@Nullable
|
||||
LootTable replaceLootTable(RegistryKey<LootTable> key, LootTable original, LootTableSource source, RegistryWrapper.WrapperLookup registries);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Modify {
|
||||
/**
|
||||
* Called when a loot table is loading to modify loot tables.
|
||||
*
|
||||
* @param key the loot table key
|
||||
* @param tableBuilder a builder of the loot table being loaded
|
||||
* @param source the source of the loot table
|
||||
* @param registries the registry wrapper lookup
|
||||
*/
|
||||
void modifyLootTable(RegistryKey<LootTable> key, LootTable.Builder tableBuilder, LootTableSource source, RegistryWrapper.WrapperLookup registries);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Loaded {
|
||||
/**
|
||||
* Called when all loot tables have been loaded and {@link LootTableEvents#REPLACE} and {@link LootTableEvents#MODIFY} have been invoked.
|
||||
*
|
||||
* @param resourceManager the server resource manager
|
||||
* @param lootRegistry the loot registry
|
||||
*/
|
||||
void onLootTablesLoaded(ResourceManager resourceManager, Registry<LootTable> lootRegistry);
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v2;
|
||||
package net.fabricmc.fabric.api.loot.v3;
|
||||
|
||||
/**
|
||||
* Describes where a loot table has been loaded from.
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Fabric Loot API for manipulating and creating loot tables.
|
||||
*
|
||||
* <h2>Events</h2>
|
||||
* {@link net.fabricmc.fabric.api.loot.v3.LootTableEvents} has events to modify existing loot tables,
|
||||
* or outright replace them with a new loot table.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <h2>Extended loot table and pool builders</h2>
|
||||
* 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;
|
|
@ -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;
|
|
@ -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)
|
|
@ -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}.
|
|
@ -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)
|
|
@ -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}.
|
|
@ -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<RegistryOps<JsonElement>, RegistryWrapper.WrapperLookup> WRAPPERS = new WeakHashMap<>();
|
||||
|
||||
@WrapOperation(method = "reload", at = @At(value = "INVOKE", target = "Lnet/minecraft/registry/ReloadableRegistries$ReloadableWrapperLookup;getOps(Lcom/mojang/serialization/DynamicOps;)Lnet/minecraft/registry/RegistryOps;"))
|
||||
private static RegistryOps<JsonElement> storeOps(@Coerce RegistryWrapper.WrapperLookup registries, DynamicOps<JsonElement> ops, Operation<RegistryOps<JsonElement>> original) {
|
||||
RegistryOps<JsonElement> created = original.call(registries, ops);
|
||||
WRAPPERS.put(created, registries);
|
||||
return created;
|
||||
}
|
||||
|
||||
@WrapOperation(method = "reload", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;thenApplyAsync(Ljava/util/function/Function;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"))
|
||||
private static CompletableFuture<CombinedDynamicRegistries<ServerDynamicRegistryType>> removeOps(CompletableFuture<List<MutableRegistry<?>>> future, Function<? super List<MutableRegistry<?>>, ? extends CombinedDynamicRegistries<ServerDynamicRegistryType>> fn, Executor executor, Operation<CompletableFuture<CombinedDynamicRegistries<ServerDynamicRegistryType>>> original, @Local RegistryOps<JsonElement> ops) {
|
||||
return original.call(future.thenApply(v -> {
|
||||
WRAPPERS.remove(ops);
|
||||
return v;
|
||||
}), fn, executor);
|
||||
}
|
||||
|
||||
@WrapOperation(method = "method_58278", at = @At(value = "INVOKE", target = "Ljava/util/Optional;ifPresent(Ljava/util/function/Consumer;)V"))
|
||||
private static <T> void modifyLootTable(Optional<T> optionalTable, Consumer<? super T> action, Operation<Void> original, @Local(argsOnly = true) Identifier id, @Local(argsOnly = true) RegistryOps<JsonElement> ops) {
|
||||
original.call(optionalTable.map(table -> modifyLootTable(table, id, ops)), action);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static <T> T modifyLootTable(T value, Identifier id, RegistryOps<JsonElement> ops) {
|
||||
if (!(value instanceof LootTable table)) return value;
|
||||
|
||||
if (table == LootTable.EMPTY) {
|
||||
// This is a special table and cannot be modified.
|
||||
return value;
|
||||
}
|
||||
|
||||
RegistryKey<LootTable> key = RegistryKey.of(RegistryKeys.LOOT_TABLE, id);
|
||||
// Populated above.
|
||||
RegistryWrapper.WrapperLookup registries = WRAPPERS.get(ops);
|
||||
// Populated inside JsonDataLoaderMixin
|
||||
LootTableSource source = LootUtil.SOURCES.get().getOrDefault(id, LootTableSource.DATA_PACK);
|
||||
// Invoke the REPLACE event for the current loot table.
|
||||
LootTable replacement = LootTableEvents.REPLACE.invoker().replaceLootTable(key, table, source, registries);
|
||||
|
||||
if (replacement != null) {
|
||||
// Set the loot table to MODIFY to be the replacement loot table.
|
||||
// The MODIFY event will also see it as a replaced loot table via the source.
|
||||
table = replacement;
|
||||
source = LootTableSource.REPLACED;
|
||||
}
|
||||
|
||||
// Turn the current table into a modifiable builder and invoke the MODIFY event.
|
||||
LootTable.Builder builder = FabricLootTableBuilder.copyOf(table);
|
||||
LootTableEvents.MODIFY.invoker().modifyLootTable(key, builder, source, registries);
|
||||
|
||||
return (T) builder.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Inject(method = "method_58279", at = @At("RETURN"))
|
||||
private static <T> void onLootTablesLoaded(LootDataType<T> lootDataType, ResourceManager resourceManager, RegistryOps<JsonElement> registryOps, CallbackInfoReturnable<MutableRegistry<?>> cir) {
|
||||
if (lootDataType != LootDataType.LOOT_TABLES) return;
|
||||
|
||||
LootTableEvents.ALL_LOADED.invoker().onLootTablesLoaded(resourceManager, (Registry<LootTable>) cir.getReturnValue());
|
||||
LootUtil.SOURCES.remove();
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-loot-api-v2",
|
||||
"name": "Fabric Loot API (v2)",
|
||||
"id": "fabric-loot-api-v3",
|
||||
"name": "Fabric Loot API (v3)",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"icon": "assets/fabric-loot-api-v2/icon.png",
|
||||
"icon": "assets/fabric-loot-api-v3/icon.png",
|
||||
"contact": {
|
||||
"homepage": "https://fabricmc.net",
|
||||
"irc": "irc://irc.esper.net:6667/fabric",
|
||||
|
@ -22,13 +22,13 @@
|
|||
},
|
||||
"description": "Hooks for manipulating loot tables.",
|
||||
"mixins": [
|
||||
"fabric-loot-api-v2.mixins.json"
|
||||
"fabric-loot-api-v3.mixins.json"
|
||||
],
|
||||
"custom": {
|
||||
"fabric-api:module-lifecycle": "stable",
|
||||
"loom:injected_interfaces": {
|
||||
"net/minecraft/class_52\u0024class_53": ["net/fabricmc/fabric/api/loot/v2/FabricLootTableBuilder"],
|
||||
"net/minecraft/class_55\u0024class_56": ["net/fabricmc/fabric/api/loot/v2/FabricLootPoolBuilder"]
|
||||
"net/minecraft/class_52\u0024class_53": ["net/fabricmc/fabric/api/loot/v3/FabricLootTableBuilder"],
|
||||
"net/minecraft/class_55\u0024class_56": ["net/fabricmc/fabric/api/loot/v3/FabricLootPoolBuilder"]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,18 +16,27 @@
|
|||
|
||||
package net.fabricmc.fabric.test.loot;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.Enchantments;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.condition.SurvivesExplosionLootCondition;
|
||||
import net.minecraft.loot.entry.ItemEntry;
|
||||
import net.minecraft.loot.function.SetEnchantmentsLootFunction;
|
||||
import net.minecraft.loot.function.SetNameLootFunction;
|
||||
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
|
||||
import net.fabricmc.fabric.api.loot.v2.LootTableSource;
|
||||
import net.fabricmc.fabric.api.loot.v3.LootTableEvents;
|
||||
import net.fabricmc.fabric.api.loot.v3.LootTableSource;
|
||||
|
||||
public class LootTest implements ModInitializer {
|
||||
@Override
|
||||
|
@ -35,7 +44,7 @@ public class LootTest implements ModInitializer {
|
|||
// Test loot table load event
|
||||
// The LootTable.Builder LootPool.Builder methods here should use
|
||||
// prebuilt entries and pools to test the injected methods.
|
||||
LootTableEvents.REPLACE.register((key, original, source) -> {
|
||||
LootTableEvents.REPLACE.register((key, original, source, registries) -> {
|
||||
if (Blocks.BLACK_WOOL.getLootTableKey() == key) {
|
||||
if (source != LootTableSource.VANILLA) {
|
||||
throw new AssertionError("black wool loot table should have LootTableSource.VANILLA, got " + source);
|
||||
|
@ -53,7 +62,7 @@ public class LootTest implements ModInitializer {
|
|||
});
|
||||
|
||||
// Test that the event is stopped when the loot table is replaced
|
||||
LootTableEvents.REPLACE.register((key, original, source) -> {
|
||||
LootTableEvents.REPLACE.register((key, original, source, registries) -> {
|
||||
if (Blocks.BLACK_WOOL.getLootTableKey() == key) {
|
||||
throw new AssertionError("Event should have been stopped from replaced loot table");
|
||||
}
|
||||
|
@ -61,7 +70,7 @@ public class LootTest implements ModInitializer {
|
|||
return null;
|
||||
});
|
||||
|
||||
LootTableEvents.MODIFY.register((key, tableBuilder, source) -> {
|
||||
LootTableEvents.MODIFY.register((key, tableBuilder, source, registries) -> {
|
||||
if (Blocks.BLACK_WOOL.getLootTableKey() == key && source != LootTableSource.REPLACED) {
|
||||
throw new AssertionError("black wool loot table should have LootTableSource.REPLACED, got " + source);
|
||||
}
|
||||
|
@ -93,6 +102,18 @@ public class LootTest implements ModInitializer {
|
|||
}
|
||||
});
|
||||
|
||||
LootTableEvents.MODIFY.register((key, tableBuilder, source, registries) -> {
|
||||
if (EntityType.SALMON.getLootTableId() == key) {
|
||||
Optional<RegistryEntry<Enchantment>> lure = registries.getOptionalWrapper(RegistryKeys.ENCHANTMENT).flatMap(registry -> registry.getOptional(Enchantments.LURE));
|
||||
|
||||
lure.ifPresent((lureEnchantment) -> tableBuilder.pool(LootPool.builder().with(
|
||||
ItemEntry.builder(Items.FISHING_ROD)
|
||||
).apply(
|
||||
new SetEnchantmentsLootFunction.Builder().enchantment(lureEnchantment, ConstantLootNumberProvider.create(1))
|
||||
)));
|
||||
}
|
||||
});
|
||||
|
||||
LootTableEvents.ALL_LOADED.register((resourceManager, lootRegistry) -> {
|
||||
LootTable blackWoolTable = lootRegistry.get(Blocks.BLACK_WOOL.getLootTableKey());
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-loot-api-v2-testmod",
|
||||
"name": "Fabric Loot Table API (v2) Test Mod",
|
||||
"id": "fabric-loot-api-v3-testmod",
|
||||
"name": "Fabric Loot Table API (v3) Test Mod",
|
||||
"version": "1.0.0",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"depends": {
|
||||
"fabric-loot-api-v2": "*"
|
||||
"fabric-loot-api-v3": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"main": [
|
|
@ -36,6 +36,7 @@ fabric-key-binding-api-v1-version=1.0.47
|
|||
fabric-keybindings-v0-version=0.2.45
|
||||
fabric-lifecycle-events-v1-version=2.3.11
|
||||
fabric-loot-api-v2-version=3.0.11
|
||||
fabric-loot-api-v3-version=1.0.0
|
||||
fabric-message-api-v1-version=6.0.13
|
||||
fabric-model-loading-api-v1-version=2.0.0
|
||||
fabric-networking-api-v1-version=4.2.0
|
||||
|
|
|
@ -37,7 +37,7 @@ include 'fabric-item-api-v1'
|
|||
include 'fabric-item-group-api-v1'
|
||||
include 'fabric-key-binding-api-v1'
|
||||
include 'fabric-lifecycle-events-v1'
|
||||
include 'fabric-loot-api-v2'
|
||||
include 'fabric-loot-api-v3'
|
||||
include 'fabric-message-api-v1'
|
||||
include 'fabric-model-loading-api-v1'
|
||||
include 'fabric-networking-api-v1'
|
||||
|
@ -62,6 +62,7 @@ include 'deprecated:fabric-command-api-v1'
|
|||
include 'deprecated:fabric-commands-v0'
|
||||
include 'deprecated:fabric-convention-tags-v1'
|
||||
include 'deprecated:fabric-keybindings-v0'
|
||||
include 'deprecated:fabric-loot-api-v2'
|
||||
include 'deprecated:fabric-renderer-registries-v1'
|
||||
include 'deprecated:fabric-rendering-data-attachment-v1'
|
||||
include 'deprecated:fabric-rendering-v0'
|
||||
|
|
Loading…
Reference in a new issue