mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-14 19:25:23 -05:00
Loot table API v2
- Deprecates all classes and methods that use outdated Yarn names. - Adds FabricLootTable and FabricLootTableBuilder to replace the LootSupplier naming variants. - Deprecates LootEntryTypeRegistry and LootJsonParser as their functionality is exposed in vanilla now. - Adds methods to FabricLootPoolBuilder for working with collections as builder parameters. - FabricLootPool and FabricLootTable/Supplier now return immutable lists instead of modifiable fixed-size ones. Co-authored-by: i509VCB <i509vcb@gmail.com>
This commit is contained in:
parent
14b3ae007b
commit
9e7660c677
54 changed files with 1573 additions and 184 deletions
11
deprecated/fabric-loot-tables-v1/build.gradle
Normal file
11
deprecated/fabric-loot-tables-v1/build.gradle
Normal file
|
@ -0,0 +1,11 @@
|
|||
archivesBaseName = "fabric-loot-tables-v1"
|
||||
version = getSubprojectVersion(project)
|
||||
|
||||
moduleDependencies(project, [
|
||||
'fabric-api-base',
|
||||
'fabric-loot-api-v2'
|
||||
])
|
||||
|
||||
dependencies {
|
||||
testmodRuntimeOnly(project(path: ':fabric-resource-loader-v0', configuration: 'namedElements'))
|
||||
}
|
|
@ -19,15 +19,18 @@ package net.fabricmc.fabric.api.loot.v1;
|
|||
import java.util.List;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.provider.number.LootNumberProvider;
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
import net.minecraft.loot.provider.number.LootNumberProvider;
|
||||
|
||||
/**
|
||||
* An interface implemented by all {@code net.minecraft.loot.LootPool} instances when
|
||||
* Fabric API is present. Contains accessors for various fields.
|
||||
*
|
||||
* @deprecated Replaced with transitive access wideners in Fabric Transitive Access Wideners (v1).
|
||||
*/
|
||||
@Deprecated
|
||||
public interface FabricLootPool {
|
||||
default LootPool asVanilla() {
|
||||
return (LootPool) this;
|
|
@ -22,17 +22,21 @@ import net.minecraft.loot.provider.number.LootNumberProvider;
|
|||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.mixin.loot.table.LootPoolBuilderHooks;
|
||||
|
||||
/**
|
||||
* @deprecated Replaced with {@link net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class FabricLootPoolBuilder extends LootPool.Builder {
|
||||
private final LootPoolBuilderHooks extended = (LootPoolBuilderHooks) this;
|
||||
|
||||
private FabricLootPoolBuilder() { }
|
||||
|
||||
private FabricLootPoolBuilder(LootPool pool) {
|
||||
copyFrom(pool, true);
|
||||
}
|
||||
|
||||
private net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder asV2() {
|
||||
return (net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder rolls(LootNumberProvider range) {
|
||||
super.rolls(range);
|
||||
|
@ -58,17 +62,17 @@ public class FabricLootPoolBuilder extends LootPool.Builder {
|
|||
}
|
||||
|
||||
public FabricLootPoolBuilder withEntry(LootPoolEntry entry) {
|
||||
extended.getEntries().add(entry);
|
||||
asV2().with(entry);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootPoolBuilder withCondition(LootCondition condition) {
|
||||
extended.getConditions().add(condition);
|
||||
asV2().conditionally(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootPoolBuilder withFunction(LootFunction function) {
|
||||
extended.getFunctions().add(function);
|
||||
asV2().apply(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -89,13 +93,13 @@ public class FabricLootPoolBuilder extends LootPool.Builder {
|
|||
* <p>If {@code copyRolls} is true, the {@link FabricLootPool#getRolls rolls} of the pool are also copied.
|
||||
*/
|
||||
public FabricLootPoolBuilder copyFrom(LootPool pool, boolean copyRolls) {
|
||||
FabricLootPool extendedPool = (FabricLootPool) pool;
|
||||
extended.getConditions().addAll(extendedPool.getConditions());
|
||||
extended.getFunctions().addAll(extendedPool.getFunctions());
|
||||
extended.getEntries().addAll(extendedPool.getEntries());
|
||||
FabricLootPool extended = (FabricLootPool) pool;
|
||||
asV2().with(extended.getEntries());
|
||||
asV2().conditionally(extended.getConditions());
|
||||
asV2().apply(extended.getFunctions());
|
||||
|
||||
if (copyRolls) {
|
||||
rolls(extendedPool.getRolls());
|
||||
rolls(extended.getRolls());
|
||||
}
|
||||
|
||||
return this;
|
|
@ -24,9 +24,12 @@ import net.minecraft.loot.context.LootContextType;
|
|||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
/**
|
||||
* An interface implemented by all {@code net.minecraft.loot.LootSupplier} instances when
|
||||
* An interface implemented by all {@link LootTable} instances when
|
||||
* Fabric API is present. Contains accessors for various fields.
|
||||
*
|
||||
* @deprecated Replaced with transitive access wideners in Fabric Transitive Access Wideners (v1).
|
||||
*/
|
||||
@Deprecated
|
||||
public interface FabricLootSupplier {
|
||||
default LootTable asVanilla() {
|
||||
return (LootTable) this;
|
||||
|
@ -34,5 +37,7 @@ public interface FabricLootSupplier {
|
|||
|
||||
List<LootPool> getPools();
|
||||
List<LootFunction> getFunctions();
|
||||
LootContextType getType();
|
||||
default LootContextType getType() {
|
||||
return asVanilla().getType(); // Vanilla has this now
|
||||
}
|
||||
}
|
|
@ -23,17 +23,23 @@ import net.minecraft.loot.LootTable;
|
|||
import net.minecraft.loot.context.LootContextType;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.mixin.loot.table.LootSupplierBuilderHooks;
|
||||
import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
|
||||
|
||||
/**
|
||||
* @deprecated Replaced with {@link FabricLootTableBuilder}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class FabricLootSupplierBuilder extends LootTable.Builder {
|
||||
private final LootSupplierBuilderHooks extended = (LootSupplierBuilderHooks) this;
|
||||
|
||||
protected FabricLootSupplierBuilder() { }
|
||||
|
||||
private FabricLootSupplierBuilder(LootTable supplier) {
|
||||
copyFrom(supplier, true);
|
||||
}
|
||||
|
||||
private FabricLootTableBuilder asV2() {
|
||||
return (FabricLootTableBuilder) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder pool(LootPool.Builder pool) {
|
||||
super.pool(pool);
|
||||
|
@ -53,22 +59,22 @@ public class FabricLootSupplierBuilder extends LootTable.Builder {
|
|||
}
|
||||
|
||||
public FabricLootSupplierBuilder withPool(LootPool pool) {
|
||||
extended.getPools().add(pool);
|
||||
asV2().pool(pool);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withFunction(LootFunction function) {
|
||||
extended.getFunctions().add(function);
|
||||
asV2().apply(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withPools(Collection<LootPool> pools) {
|
||||
pools.forEach(this::withPool);
|
||||
asV2().pools(pools);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withFunctions(Collection<LootFunction> functions) {
|
||||
functions.forEach(this::withFunction);
|
||||
asV2().apply(functions);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -86,8 +92,8 @@ public class FabricLootSupplierBuilder extends LootTable.Builder {
|
|||
*/
|
||||
public FabricLootSupplierBuilder copyFrom(LootTable supplier, boolean copyType) {
|
||||
FabricLootSupplier extendedSupplier = (FabricLootSupplier) supplier;
|
||||
extended.getPools().addAll(extendedSupplier.getPools());
|
||||
extended.getFunctions().addAll(extendedSupplier.getFunctions());
|
||||
asV2().pools(extendedSupplier.getPools());
|
||||
asV2().apply(extendedSupplier.getFunctions());
|
||||
|
||||
if (copyType) {
|
||||
type(extendedSupplier.getType());
|
|
@ -23,11 +23,13 @@ import net.minecraft.util.JsonSerializer;
|
|||
import net.fabricmc.fabric.impl.loot.table.LootEntryTypeRegistryImpl;
|
||||
|
||||
/**
|
||||
* Fabric's extensions to {@code net.minecraft.loot.entry.LootEntries} for registering
|
||||
* Fabric's extensions to {@link net.minecraft.loot.entry.LootPoolEntryTypes} for registering
|
||||
* custom loot entry types.
|
||||
*
|
||||
* @see #register
|
||||
* @deprecated Use {@link net.minecraft.util.registry.Registry#LOOT_POOL_ENTRY_TYPE} from vanilla instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface LootEntryTypeRegistry {
|
||||
LootEntryTypeRegistry INSTANCE = new LootEntryTypeRegistryImpl();
|
||||
|
|
@ -17,37 +17,26 @@
|
|||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import net.minecraft.loot.LootGsons;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.Lazy;
|
||||
import net.minecraft.loot.LootManager;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link LootGsons#getTableGsonBuilder()} from vanilla instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class LootJsonParser {
|
||||
/* Reading this from LootManager to access all serializers from vanilla. */
|
||||
private static final Lazy<Gson> GSON = new Lazy<>(() -> {
|
||||
try {
|
||||
Field gsonField = Stream.of(LootManager.class.getDeclaredFields())
|
||||
.filter(field -> field.getType() == Gson.class)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("Gson not found in LootManager!"));
|
||||
gsonField.setAccessible(true);
|
||||
return (Gson) gsonField.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Exception while getting Gson instance from LootManager", e);
|
||||
}
|
||||
});
|
||||
private static final Gson GSON = LootGsons.getTableGsonBuilder().create();
|
||||
|
||||
private LootJsonParser() { }
|
||||
|
||||
public static <T> T read(Reader json, Class<T> c) {
|
||||
return JsonHelper.deserialize(GSON.get(), json, c);
|
||||
return JsonHelper.deserialize(GSON, json, c);
|
||||
}
|
||||
|
||||
public static <T> T read(String json, Class<T> c) {
|
||||
return JsonHelper.deserialize(GSON.get(), json, c);
|
||||
return JsonHelper.deserialize(GSON, json, c);
|
||||
}
|
||||
}
|
|
@ -28,9 +28,13 @@ import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
|||
/**
|
||||
* An event handler that is called when loot tables are loaded.
|
||||
* Use {@link #EVENT} to register instances.
|
||||
*
|
||||
* @deprecated Replaced with {@link net.fabricmc.fabric.api.loot.v2.LootTableEvents}.
|
||||
*/
|
||||
@Deprecated
|
||||
@FunctionalInterface
|
||||
public interface LootTableLoadingCallback {
|
||||
@Deprecated
|
||||
@FunctionalInterface
|
||||
interface LootTableSetter {
|
||||
void set(LootTable supplier);
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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.table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.context.LootContextType;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplier;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
|
||||
|
||||
/**
|
||||
* A {@link FabricLootSupplierBuilder} that caches all methods so they can be applied to a v2 {@link FabricLootTableBuilder}.
|
||||
* Used for hooking {@code LootTableLoadingCallback} to the two different {@link net.fabricmc.fabric.api.loot.v2.LootTableEvents}.
|
||||
*/
|
||||
public class BufferingLootTableBuilder extends FabricLootSupplierBuilder {
|
||||
private final List<Consumer<LootTable.Builder>> modifications = new ArrayList<>();
|
||||
|
||||
private FabricLootSupplierBuilder addAction(Consumer<LootTable.Builder> action) {
|
||||
modifications.add(action);
|
||||
return this;
|
||||
}
|
||||
|
||||
private FabricLootSupplierBuilder addV2Action(Consumer<FabricLootTableBuilder> action) {
|
||||
return addAction(builder -> action.accept((FabricLootTableBuilder) builder));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder pool(LootPool.Builder pool) {
|
||||
super.pool(pool);
|
||||
return addAction(builder -> builder.pool(pool));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder type(LootContextType type) {
|
||||
super.type(type);
|
||||
return addAction(builder -> builder.type(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder apply(LootFunction.Builder function) {
|
||||
super.apply(function);
|
||||
return addAction(builder -> builder.apply(function));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withPool(LootPool pool) {
|
||||
super.withPool(pool);
|
||||
return addV2Action(builder -> builder.pool(pool));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withFunction(LootFunction function) {
|
||||
super.withFunction(function);
|
||||
return addV2Action(builder -> builder.apply(function));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withPools(Collection<LootPool> pools) {
|
||||
super.withPools(pools);
|
||||
return addV2Action(builder -> builder.pools(pools));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withFunctions(Collection<LootFunction> functions) {
|
||||
super.withFunctions(functions);
|
||||
return addV2Action(builder -> builder.apply(functions));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder copyFrom(LootTable supplier, boolean copyType) {
|
||||
super.copyFrom(supplier, copyType);
|
||||
return addV2Action(builder -> {
|
||||
FabricLootSupplier extended = (FabricLootSupplier) supplier;
|
||||
builder.pools(extended.getPools());
|
||||
builder.apply(extended.getFunctions());
|
||||
|
||||
if (copyType) {
|
||||
((LootTable.Builder) builder).type(supplier.getType());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void init(LootTable original) {
|
||||
super.type(original.getType());
|
||||
super.withPools(((FabricLootSupplier) original).getPools());
|
||||
super.withFunctions(((FabricLootSupplier) original).getFunctions());
|
||||
}
|
||||
|
||||
public void applyTo(LootTable.Builder builder) {
|
||||
for (Consumer<LootTable.Builder> modification : modifications) {
|
||||
modification.accept(builder);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,16 +17,16 @@
|
|||
package net.fabricmc.fabric.impl.loot.table;
|
||||
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.entry.LootPoolEntryType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonSerializer;
|
||||
|
||||
import net.fabricmc.fabric.mixin.loot.table.LootPoolEntryTypesAccessor;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public final class LootEntryTypeRegistryImpl implements net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry {
|
||||
public LootEntryTypeRegistryImpl() { }
|
||||
|
||||
@Override
|
||||
public void register(Identifier id, JsonSerializer<? extends LootPoolEntry> serializer) {
|
||||
LootPoolEntryTypesAccessor.register(id.toString(), serializer);
|
||||
Registry.register(Registry.LOOT_POOL_ENTRY_TYPE, id, new LootPoolEntryType(serializer));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.table;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
|
||||
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
|
||||
|
||||
public final class LootTablesV1Init implements ModInitializer {
|
||||
private static final ThreadLocal<Map<Identifier, BufferingLootTableBuilder>> BUFFERS = ThreadLocal.withInitial(HashMap::new);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LootTableEvents.REPLACE.register((resourceManager, lootManager, id, original, source) -> {
|
||||
BufferingLootTableBuilder builder = new BufferingLootTableBuilder();
|
||||
builder.init(original);
|
||||
BUFFERS.get().put(id, builder);
|
||||
|
||||
LootTable[] result = new LootTable[1];
|
||||
LootTableLoadingCallback.EVENT.invoker().onLootTableLoading(
|
||||
resourceManager,
|
||||
lootManager,
|
||||
id,
|
||||
builder,
|
||||
table -> result[0] = table
|
||||
);
|
||||
|
||||
return result[0];
|
||||
});
|
||||
|
||||
LootTableEvents.MODIFY.register((resourceManager, lootManager, id, tableBuilder, source) -> {
|
||||
Map<Identifier, BufferingLootTableBuilder> buffers = BUFFERS.get();
|
||||
|
||||
if (buffers.containsKey(id)) {
|
||||
try {
|
||||
buffers.get(id).applyTo(tableBuilder);
|
||||
} finally {
|
||||
buffers.remove(id);
|
||||
|
||||
if (buffers.isEmpty()) {
|
||||
BUFFERS.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -16,19 +16,18 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.loot.table;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.provider.number.LootNumberProvider;
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
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.v1.FabricLootPool;
|
||||
|
||||
|
@ -36,32 +35,37 @@ import net.fabricmc.fabric.api.loot.v1.FabricLootPool;
|
|||
public abstract class MixinLootPool implements FabricLootPool {
|
||||
@Shadow
|
||||
@Final
|
||||
private LootPoolEntry[] entries;
|
||||
LootPoolEntry[] entries;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private LootCondition[] conditions;
|
||||
LootCondition[] conditions;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private LootFunction[] functions;
|
||||
LootFunction[] functions;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
LootNumberProvider rolls;
|
||||
|
||||
@Override
|
||||
public List<LootPoolEntry> getEntries() {
|
||||
return Arrays.asList(entries);
|
||||
return ImmutableList.copyOf(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootCondition> getConditions() {
|
||||
return Arrays.asList(conditions);
|
||||
return ImmutableList.copyOf(conditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootFunction> getFunctions() {
|
||||
return Arrays.asList(functions);
|
||||
return ImmutableList.copyOf(functions);
|
||||
}
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract LootNumberProvider getRolls();
|
||||
public LootNumberProvider getRolls() {
|
||||
return rolls;
|
||||
}
|
||||
}
|
|
@ -16,17 +16,15 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.loot.table;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.context.LootContextType;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplier;
|
||||
|
@ -35,22 +33,19 @@ import net.fabricmc.fabric.api.loot.v1.FabricLootSupplier;
|
|||
public abstract class MixinLootSupplier implements FabricLootSupplier {
|
||||
@Shadow
|
||||
@Final
|
||||
private LootPool[] pools;
|
||||
LootPool[] pools;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private LootFunction[] functions;
|
||||
LootFunction[] functions;
|
||||
|
||||
@Override
|
||||
public List<LootPool> getPools() {
|
||||
return Arrays.asList(pools);
|
||||
return ImmutableList.copyOf(pools);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootFunction> getFunctions() {
|
||||
return Arrays.asList(functions);
|
||||
return ImmutableList.copyOf(functions);
|
||||
}
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract LootContextType getType();
|
||||
}
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -3,10 +3,6 @@
|
|||
"package": "net.fabricmc.fabric.mixin.loot.table",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"LootPoolBuilderHooks",
|
||||
"LootPoolEntryTypesAccessor",
|
||||
"LootSupplierBuilderHooks",
|
||||
"MixinLootManager",
|
||||
"MixinLootPool",
|
||||
"MixinLootSupplier"
|
||||
],
|
|
@ -17,13 +17,17 @@
|
|||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.4.0",
|
||||
"fabric-api-base": "*"
|
||||
"fabric-api-base": "*",
|
||||
"fabric-loot-api-v2": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"main": ["net.fabricmc.fabric.impl.loot.table.LootTablesV1Init"]
|
||||
},
|
||||
"description": "Hooks for manipulating loot tables.",
|
||||
"mixins": [
|
||||
"fabric-loot-tables-v1.mixins.json"
|
||||
],
|
||||
"custom": {
|
||||
"fabric-api:module-lifecycle": "stable"
|
||||
"fabric-api:module-lifecycle": "deprecated"
|
||||
}
|
||||
}
|
|
@ -20,28 +20,31 @@ import com.google.gson.Gson;
|
|||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
|
||||
import net.minecraft.loot.LootGsons;
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.condition.SurvivesExplosionLootCondition;
|
||||
import net.minecraft.loot.entry.ItemEntry;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.entry.TagEntry;
|
||||
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootPoolBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry;
|
||||
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
|
||||
|
||||
public class LootTest implements ModInitializer {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LootTest.class);
|
||||
public class LootV1Test implements ModInitializer {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LootV1Test.class);
|
||||
|
||||
private static final Gson LOOT_GSON = LootGsons.getTableGsonBuilder().create();
|
||||
private static final String LOOT_ENTRY_JSON = "{\"type\":\"minecraft:item\",\"name\":\"minecraft:apple\"}";
|
||||
|
@ -53,7 +56,9 @@ public class LootTest implements ModInitializer {
|
|||
|
||||
// Test loot table load event
|
||||
LootTableLoadingCallback.EVENT.register((resourceManager, manager, id, supplier, setter) -> {
|
||||
if ("minecraft:blocks/dirt".equals(id.toString())) {
|
||||
// Add feathers and apples to dirt (only one drops at the time since they're in the same pool),
|
||||
// and replace grass block drops with wheat
|
||||
if (Blocks.DIRT.getLootTableId().equals(id)) {
|
||||
LootPoolEntry entryFromString = LOOT_GSON.fromJson(LOOT_ENTRY_JSON, LootPoolEntry.class);
|
||||
|
||||
LootPool pool = FabricLootPoolBuilder.builder()
|
||||
|
@ -64,6 +69,11 @@ public class LootTest implements ModInitializer {
|
|||
.build();
|
||||
|
||||
supplier.withPool(pool);
|
||||
} else if (Blocks.GRASS_BLOCK.getLootTableId().equals(id)) {
|
||||
LootTable table = FabricLootSupplierBuilder.builder()
|
||||
.pool(FabricLootPoolBuilder.builder().with(ItemEntry.builder(Items.WHEAT)))
|
||||
.build();
|
||||
setter.set(table);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.fabricmc.fabric.test.loot.LootTest"
|
||||
"net.fabricmc.fabric.test.loot.LootV1Test"
|
||||
]
|
||||
}
|
||||
}
|
29
fabric-loot-api-v2/README.md
Normal file
29
fabric-loot-api-v2/README.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Fabric Loot API (v2)
|
||||
|
||||
This module includes APIs for modifying and creating loot tables.
|
||||
|
||||
## [Loot table events](src/main/java/net/fabricmc/fabric/api/loot/v2/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/v2/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/v2/FabricLootTableBuilder.java)
|
||||
and [`FabricLootPoolBuilder`](src/main/java/net/fabricmc/fabric/api/loot/v2/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.
|
7
fabric-loot-api-v2/build.gradle
Normal file
7
fabric-loot-api-v2/build.gradle
Normal file
|
@ -0,0 +1,7 @@
|
|||
archivesBaseName = "fabric-loot-api-v2"
|
||||
version = getSubprojectVersion(project)
|
||||
|
||||
moduleDependencies(project, [
|
||||
'fabric-api-base',
|
||||
'fabric-resource-loader-v0'
|
||||
])
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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.List;
|
||||
|
||||
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;
|
||||
|
||||
import net.fabricmc.fabric.mixin.loot.LootPoolAccessor;
|
||||
|
||||
/**
|
||||
* Convenience extensions to {@link LootPool.Builder}
|
||||
* for adding pre-built objects or collections.
|
||||
*
|
||||
* <p>This interface is automatically injected to {@link LootPool.Builder}.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface FabricLootPoolBuilder {
|
||||
/**
|
||||
* Adds an entry to this builder.
|
||||
*
|
||||
* @param entry the added loot entry
|
||||
* @return this builder
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
static LootPool.Builder copyOf(LootPool pool) {
|
||||
LootPoolAccessor accessor = (LootPoolAccessor) pool;
|
||||
return LootPool.builder()
|
||||
.rolls(accessor.fabric_getRolls())
|
||||
.bonusRolls(accessor.fabric_getBonusRolls())
|
||||
.with(List.of(accessor.fabric_getEntries()))
|
||||
.conditionally(List.of(accessor.fabric_getConditions()))
|
||||
.apply(List.of(accessor.fabric_getFunctions()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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.List;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.mixin.loot.LootTableAccessor;
|
||||
|
||||
/**
|
||||
* Convenience extensions to {@link LootTable.Builder}
|
||||
* for adding pre-built objects or collections.
|
||||
*
|
||||
* <p>This interface is automatically injected to {@link LootTable.Builder}.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface FabricLootTableBuilder {
|
||||
/**
|
||||
* Adds a loot pool to this builder.
|
||||
*
|
||||
* @param pool the added pool
|
||||
* @return this builder
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
default LootTable.Builder apply(Collection<? extends LootFunction> functions) {
|
||||
throw new UnsupportedOperationException("Implemented via mixin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder copy of a loot table.
|
||||
*
|
||||
* @param table the loot table
|
||||
* @return the copied builder
|
||||
*/
|
||||
static LootTable.Builder copyOf(LootTable table) {
|
||||
LootTable.Builder builder = LootTable.builder();
|
||||
LootTableAccessor accessor = (LootTableAccessor) table;
|
||||
|
||||
builder.type(table.getType());
|
||||
builder.pools(List.of(accessor.fabric_getPools()));
|
||||
builder.apply(List.of(accessor.fabric_getFunctions()));
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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 org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.loot.LootManager;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
|
||||
/**
|
||||
* Events for manipulating loot tables.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public static final Event<Replace> REPLACE = EventFactory.createArrayBacked(Replace.class, listeners -> (resourceManager, lootManager, id, original, source) -> {
|
||||
for (Replace listener : listeners) {
|
||||
@Nullable LootTable replaced = listener.replaceLootTable(resourceManager, lootManager, id, original, source);
|
||||
|
||||
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>
|
||||
* <pre>
|
||||
* {@code
|
||||
* LootTableEvents.MODIFY.register((resourceManager, lootManager, id, tableBuilder, source) -> {
|
||||
* // If the loot table is for the cobblestone block and it is not overridden by a user:
|
||||
* if (Blocks.COBBLESTONE.getLootTableId().equals(id) && 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);
|
||||
* }
|
||||
* });
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public static final Event<Modify> MODIFY = EventFactory.createArrayBacked(Modify.class, listeners -> (resourceManager, lootManager, id, tableBuilder, source) -> {
|
||||
for (Modify listener : listeners) {
|
||||
listener.modifyLootTable(resourceManager, lootManager, id, tableBuilder, source);
|
||||
}
|
||||
});
|
||||
|
||||
public interface Replace {
|
||||
/**
|
||||
* Replaces loot tables.
|
||||
*
|
||||
* @param resourceManager the server resource manager
|
||||
* @param lootManager the loot manager
|
||||
* @param id the loot table ID
|
||||
* @param original the original loot table
|
||||
* @param source the source of the original loot table
|
||||
* @return the new loot table, or null if it wasn't replaced
|
||||
*/
|
||||
@Nullable
|
||||
LootTable replaceLootTable(ResourceManager resourceManager, LootManager lootManager, Identifier id, LootTable original, LootTableSource source);
|
||||
}
|
||||
|
||||
public interface Modify {
|
||||
/**
|
||||
* Called when a loot table is loading to modify loot tables.
|
||||
*
|
||||
* @param resourceManager the server resource manager
|
||||
* @param lootManager the loot manager
|
||||
* @param id the loot table ID
|
||||
* @param tableBuilder a builder of the loot table being loaded
|
||||
* @param source the source of the loot table
|
||||
*/
|
||||
void modifyLootTable(ResourceManager resourceManager, LootManager lootManager, Identifier id, LootTable.Builder tableBuilder, LootTableSource source);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
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,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.v2.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.v2.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.v2.FabricLootTableBuilder loot table} and
|
||||
* {@linkplain net.fabricmc.fabric.api.loot.v2.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.v2;
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.resource.ResourcePackSource;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v2.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;
|
||||
|
||||
public final class LootUtil {
|
||||
public static LootTableSource determineSource(Identifier lootTableId, ResourceManager resourceManager) {
|
||||
Identifier resourceId = new Identifier(lootTableId.getNamespace(), "loot_tables/%s.json".formatted(lootTableId.getPath()));
|
||||
|
||||
Resource resource = resourceManager.getResource(resourceId).orElse(null);
|
||||
|
||||
if (resource != null) {
|
||||
ResourcePackSource packSource = ((FabricResource) resource).getFabricPackSource();
|
||||
|
||||
if (packSource == ResourcePackSource.PACK_SOURCE_BUILTIN) {
|
||||
return LootTableSource.VANILLA;
|
||||
} else if (packSource == ModResourcePackCreator.RESOURCE_PACK_SOURCE || packSource instanceof BuiltinModResourcePackSource) {
|
||||
return LootTableSource.MOD;
|
||||
}
|
||||
}
|
||||
|
||||
// If not builtin or mod, assume external data pack.
|
||||
// It might also be a virtual loot table injected via mixin instead of being loaded
|
||||
// from a resource, but we can't determine that here.
|
||||
return LootTableSource.DATA_PACK;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.JsonObject;
|
||||
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;
|
||||
|
||||
import net.minecraft.loot.LootManager;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.LootTables;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
|
||||
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(LootManager.class)
|
||||
abstract class LootManagerMixin {
|
||||
@Shadow
|
||||
private Map<Identifier, LootTable> tables;
|
||||
|
||||
@Inject(method = "apply", at = @At("RETURN"))
|
||||
private void apply(Map<Identifier, JsonObject> jsonMap, ResourceManager resourceManager, Profiler profiler, CallbackInfo info) {
|
||||
// The builder for the new LootManager.tables map with modified loot tables.
|
||||
// We're using an immutable map to match vanilla.
|
||||
ImmutableMap.Builder<Identifier, LootTable> newTables = ImmutableMap.builder();
|
||||
|
||||
tables.forEach((id, table) -> {
|
||||
if (id.equals(LootTables.EMPTY)) {
|
||||
// This is a special table and cannot be modified.
|
||||
// Vanilla also warns about that.
|
||||
return;
|
||||
}
|
||||
|
||||
// noinspection ConstantConditions
|
||||
LootManager lootManager = (LootManager) (Object) this;
|
||||
LootTableSource source = LootUtil.determineSource(id, resourceManager);
|
||||
|
||||
// Invoke the REPLACE event for the current loot table.
|
||||
LootTable replacement = LootTableEvents.REPLACE.invoker().replaceLootTable(resourceManager, lootManager, id, 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(resourceManager, lootManager, id, builder, source);
|
||||
|
||||
// Turn the builder back into a loot table and store it in the new table.
|
||||
newTables.put(id, builder.build());
|
||||
});
|
||||
|
||||
// Finally, store the new loot table map in the field.
|
||||
tables = newTables.build();
|
||||
}
|
||||
}
|
|
@ -14,9 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot.table;
|
||||
|
||||
import java.util.List;
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
@ -25,13 +23,26 @@ import net.minecraft.loot.LootPool;
|
|||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
import net.minecraft.loot.provider.number.LootNumberProvider;
|
||||
|
||||
@Mixin(LootPool.Builder.class)
|
||||
public interface LootPoolBuilderHooks {
|
||||
@Accessor
|
||||
List<LootPoolEntry> getEntries();
|
||||
@Accessor
|
||||
List<LootCondition> getConditions();
|
||||
@Accessor
|
||||
List<LootFunction> getFunctions();
|
||||
/**
|
||||
* Accesses loot pool fields for {@link net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder#copyOf(LootPool)}.
|
||||
* These are normally available in the transitive access widener module.
|
||||
*/
|
||||
@Mixin(LootPool.class)
|
||||
public interface LootPoolAccessor {
|
||||
@Accessor("rolls")
|
||||
LootNumberProvider fabric_getRolls();
|
||||
|
||||
@Accessor("bonusRolls")
|
||||
LootNumberProvider fabric_getBonusRolls();
|
||||
|
||||
@Accessor("entries")
|
||||
LootPoolEntry[] fabric_getEntries();
|
||||
|
||||
@Accessor("conditions")
|
||||
LootCondition[] fabric_getConditions();
|
||||
|
||||
@Accessor("functions")
|
||||
LootFunction[] fabric_getFunctions();
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
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;
|
||||
|
||||
/**
|
||||
* The implementation of the injected interface {@link FabricLootPoolBuilder}.
|
||||
* Simply implements the new methods by adding the relevant objects inside the lists.
|
||||
*/
|
||||
@Mixin(LootPool.Builder.class)
|
||||
abstract class LootPoolBuilderMixin implements FabricLootPoolBuilder {
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootPoolEntry> entries;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootCondition> conditions;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootFunction> functions;
|
||||
|
||||
@Unique
|
||||
private LootPool.Builder self() {
|
||||
// noinspection ConstantConditions
|
||||
return (LootPool.Builder) (Object) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootPool.Builder with(LootPoolEntry entry) {
|
||||
this.entries.add(entry);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootPool.Builder with(Collection<? extends LootPoolEntry> entries) {
|
||||
this.entries.addAll(entries);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootPool.Builder conditionally(LootCondition condition) {
|
||||
this.conditions.add(condition);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootPool.Builder conditionally(Collection<? extends LootCondition> conditions) {
|
||||
this.conditions.addAll(conditions);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootPool.Builder apply(LootFunction function) {
|
||||
this.functions.add(function);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootPool.Builder apply(Collection<? extends LootFunction> functions) {
|
||||
this.functions.addAll(functions);
|
||||
return self();
|
||||
}
|
||||
}
|
|
@ -14,9 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot.table;
|
||||
|
||||
import java.util.List;
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
@ -25,10 +23,15 @@ import net.minecraft.loot.LootPool;
|
|||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
@Mixin(LootTable.Builder.class)
|
||||
public interface LootSupplierBuilderHooks {
|
||||
@Accessor
|
||||
List<LootPool> getPools();
|
||||
@Accessor
|
||||
List<LootFunction> getFunctions();
|
||||
/**
|
||||
* Accesses loot table fields for {@link net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder#copyOf(LootTable)}.
|
||||
* These are normally available in the transitive access widener module.
|
||||
*/
|
||||
@Mixin(LootTable.class)
|
||||
public interface LootTableAccessor {
|
||||
@Accessor("pools")
|
||||
LootPool[] fabric_getPools();
|
||||
|
||||
@Accessor("functions")
|
||||
LootFunction[] fabric_getFunctions();
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
|
||||
|
||||
/**
|
||||
* The implementation of the injected interface {@link FabricLootTableBuilder}.
|
||||
* Simply implements the new methods by adding the relevant objects inside the lists.
|
||||
*/
|
||||
@Mixin(LootTable.Builder.class)
|
||||
abstract class LootTableBuilderMixin implements FabricLootTableBuilder {
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootPool> pools;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootFunction> functions;
|
||||
|
||||
@Unique
|
||||
private LootTable.Builder self() {
|
||||
// noinspection ConstantConditions
|
||||
return (LootTable.Builder) (Object) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootTable.Builder pool(LootPool pool) {
|
||||
this.pools.add(pool);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootTable.Builder apply(LootFunction function) {
|
||||
this.functions.add(function);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootTable.Builder pools(Collection<? extends LootPool> pools) {
|
||||
this.pools.addAll(pools);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootTable.Builder apply(Collection<? extends LootFunction> functions) {
|
||||
this.functions.addAll(functions);
|
||||
return self();
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.mixin.loot",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"LootManagerMixin",
|
||||
"LootPoolAccessor",
|
||||
"LootPoolBuilderMixin",
|
||||
"LootTableAccessor",
|
||||
"LootTableBuilderMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
34
fabric-loot-api-v2/src/main/resources/fabric.mod.json
Normal file
34
fabric-loot-api-v2/src/main/resources/fabric.mod.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"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.4.0",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-resource-loader-v0": "*"
|
||||
},
|
||||
"description": "Hooks for manipulating loot tables.",
|
||||
"mixins": [
|
||||
"fabric-loot-api-v2.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"]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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.test.loot;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
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.SetNameLootFunction;
|
||||
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;
|
||||
|
||||
public class LootTest implements ModInitializer {
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// 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((resourceManager, lootManager, id, original, source) -> {
|
||||
if (Blocks.BLACK_WOOL.getLootTableId().equals(id)) {
|
||||
if (source != LootTableSource.VANILLA) {
|
||||
throw new AssertionError("black wool loot table should have LootTableSource.VANILLA");
|
||||
}
|
||||
|
||||
// Replace black wool drops with an iron ingot
|
||||
LootPool pool = LootPool.builder()
|
||||
.with(ItemEntry.builder(Items.IRON_INGOT).build())
|
||||
.build();
|
||||
|
||||
return LootTable.builder().pool(pool).build();
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
// Test that the event is stopped when the loot table is replaced
|
||||
LootTableEvents.REPLACE.register((resourceManager, lootManager, id, original, source) -> {
|
||||
if (Blocks.BLACK_WOOL.getLootTableId().equals(id)) {
|
||||
throw new AssertionError("Event should have been stopped from replaced loot table");
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
LootTableEvents.MODIFY.register((resourceManager, lootManager, id, tableBuilder, source) -> {
|
||||
if (Blocks.BLACK_WOOL.getLootTableId().equals(id) && source != LootTableSource.REPLACED) {
|
||||
throw new AssertionError("black wool loot table should have LootTableSource.REPLACED");
|
||||
}
|
||||
|
||||
if (Blocks.WHITE_WOOL.getLootTableId().equals(id)) {
|
||||
if (source != LootTableSource.VANILLA) {
|
||||
throw new AssertionError("white wool loot table should have LootTableSource.VANILLA");
|
||||
}
|
||||
|
||||
// Add gold ingot with custom name to white wool drops
|
||||
LootPool pool = LootPool.builder()
|
||||
.with(ItemEntry.builder(Items.GOLD_INGOT).build())
|
||||
.conditionally(SurvivesExplosionLootCondition.builder().build())
|
||||
.apply(SetNameLootFunction.builder(Text.literal("Gold from White Wool")).build())
|
||||
.build();
|
||||
|
||||
tableBuilder.pool(pool);
|
||||
}
|
||||
|
||||
// We modify red wool to drop diamonds in the test mod resources.
|
||||
if (Blocks.RED_WOOL.getLootTableId().equals(id) && source != LootTableSource.MOD) {
|
||||
throw new AssertionError("red wool loot table should have LootTableSource.MOD");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "minecraft:diamond"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
16
fabric-loot-api-v2/src/testmod/resources/fabric.mod.json
Normal file
16
fabric-loot-api-v2/src/testmod/resources/fabric.mod.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-loot-api-v2-testmod",
|
||||
"name": "Fabric Loot Table API (v2) Test Mod",
|
||||
"version": "1.0.0",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"depends": {
|
||||
"fabric-loot-api-v2": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.fabricmc.fabric.test.loot.LootTest"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
archivesBaseName = "fabric-loot-tables-v1"
|
||||
version = getSubprojectVersion(project)
|
||||
|
||||
moduleDependencies(project, [
|
||||
'fabric-api-base'
|
||||
])
|
|
@ -1,60 +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.table;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.JsonObject;
|
||||
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;
|
||||
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
import net.minecraft.loot.LootManager;
|
||||
import net.minecraft.loot.LootTable;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
|
||||
|
||||
@Mixin(LootManager.class)
|
||||
public class MixinLootManager {
|
||||
@Shadow private Map<Identifier, LootTable> tables;
|
||||
|
||||
@Inject(method = "apply", at = @At("RETURN"))
|
||||
private void apply(Map<Identifier, JsonObject> objectMap, ResourceManager manager, Profiler profiler, CallbackInfo info) {
|
||||
Map<Identifier, LootTable> newSuppliers = new HashMap<>();
|
||||
|
||||
tables.forEach((id, supplier) -> {
|
||||
FabricLootSupplierBuilder builder = FabricLootSupplierBuilder.of(supplier);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
LootTableLoadingCallback.EVENT.invoker().onLootTableLoading(
|
||||
manager, (LootManager) (Object) this, id, builder, (s) -> newSuppliers.put(id, s)
|
||||
);
|
||||
|
||||
newSuppliers.computeIfAbsent(id, (i) -> builder.build());
|
||||
});
|
||||
|
||||
tables = ImmutableMap.copyOf(newSuppliers);
|
||||
}
|
||||
}
|
|
@ -14,20 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot.table;
|
||||
package net.fabricmc.fabric.impl.resource.loader;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
import net.minecraft.resource.ResourcePackSource;
|
||||
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.entry.LootPoolEntryType;
|
||||
import net.minecraft.loot.entry.LootPoolEntryTypes;
|
||||
import net.minecraft.util.JsonSerializer;
|
||||
|
||||
@Mixin(LootPoolEntryTypes.class)
|
||||
public interface LootPoolEntryTypesAccessor {
|
||||
@Invoker("register")
|
||||
static LootPoolEntryType register(String id, JsonSerializer<? extends LootPoolEntry> serializer) {
|
||||
throw new UnsupportedOperationException("Mixin dummy");
|
||||
}
|
||||
public interface FabricNamespaceResourceManagerEntry {
|
||||
void setFabricPackSource(ResourcePackSource packSource);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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.resource.loader;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.resource.ResourcePackSource;
|
||||
|
||||
/**
|
||||
* Extensions to {@link net.minecraft.resource.Resource}.
|
||||
* Automatically implemented there via a mixin.
|
||||
* Currently, this is only for use in other Fabric API modules.
|
||||
*/
|
||||
public interface FabricResource {
|
||||
/**
|
||||
* Gets the resource pack source of this resource.
|
||||
* The source is used to separate vanilla/mod resources from user resources in Fabric API.
|
||||
*
|
||||
* <p>Custom {@link net.minecraft.resource.Resource} implementations should override this method.
|
||||
*
|
||||
* @return the resource pack source
|
||||
*/
|
||||
default ResourcePackSource getFabricPackSource() {
|
||||
LoggerFactory.getLogger(FabricResource.class).error("Unknown Resource implementation {}, returning PACK_SOURCE_NONE as the source", getClass().getName());
|
||||
return ResourcePackSource.PACK_SOURCE_NONE;
|
||||
}
|
||||
|
||||
void setFabricPackSource(ResourcePackSource packSource);
|
||||
}
|
|
@ -128,7 +128,9 @@ public abstract class GroupResourcePack implements ResourcePack {
|
|||
|
||||
for (ModResourcePack pack : packs) {
|
||||
if (pack.contains(manager.getType(), id)) {
|
||||
resources.add(((NamespaceResourceManager) manager).new Entry(id, metadataId, pack));
|
||||
final NamespaceResourceManager.Entry entry = ((NamespaceResourceManager) manager).new Entry(id, metadataId, pack);
|
||||
((FabricNamespaceResourceManagerEntry) entry).setFabricPackSource(ModResourcePackCreator.RESOURCE_PACK_SOURCE);
|
||||
resources.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.resource.loader;
|
||||
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourcePackSource;
|
||||
|
||||
/**
|
||||
* Tracks the sources of resource packs in a global weak hash map.
|
||||
* {@link ResourcePack} doesn't hold a reference to its {@link ResourcePackSource}
|
||||
* so we store the source in the map when the resource packs are created.
|
||||
* See {@link net.fabricmc.fabric.mixin.resource.loader.ResourcePackProfileMixin ResourcePackProfileMixin}.
|
||||
*
|
||||
* <p>The sources are later read for use in {@link FabricResource} and {@link FabricResourceImpl}.
|
||||
* See {@link net.fabricmc.fabric.mixin.resource.loader.NamespaceResourceManagerMixin NamespaceResourceManagerMixin}.
|
||||
*/
|
||||
public final class ResourcePackSourceTracker {
|
||||
// Use a weak hash map so that if resource packs would be deleted, this won't keep them alive.
|
||||
private static final WeakHashMap<ResourcePack, ResourcePackSource> SOURCES = new WeakHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets the source of a pack.
|
||||
*
|
||||
* @param pack the resource pack
|
||||
* @return the source, or {@link ResourcePackSource#PACK_SOURCE_NONE} if not tracked
|
||||
*/
|
||||
public static ResourcePackSource getSource(ResourcePack pack) {
|
||||
return SOURCES.getOrDefault(pack, ResourcePackSource.PACK_SOURCE_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source of a pack.
|
||||
*
|
||||
* @param pack the resource pack
|
||||
* @param source the source
|
||||
*/
|
||||
public static void setSource(ResourcePack pack, ResourcePackSource source) {
|
||||
SOURCES.put(pack, source);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.resource.loader;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.resource.NamespaceResourceManager;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourcePackSource;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.FabricNamespaceResourceManagerEntry;
|
||||
import net.fabricmc.fabric.impl.resource.loader.FabricResource;
|
||||
|
||||
@Mixin(NamespaceResourceManager.Entry.class)
|
||||
public class NamespaceResourceManagerEntryMixin implements FabricNamespaceResourceManagerEntry {
|
||||
@Unique
|
||||
private @Nullable ResourcePackSource fabric_packSource;
|
||||
|
||||
@Override
|
||||
public void setFabricPackSource(ResourcePackSource packSource) {
|
||||
this.fabric_packSource = packSource;
|
||||
}
|
||||
|
||||
@Inject(method = "toReference", at = @At("RETURN"))
|
||||
public void toReference(CallbackInfoReturnable<Resource> cir) {
|
||||
Resource resource = cir.getReturnValue();
|
||||
((FabricResource) resource).setFabricPackSource(fabric_packSource);
|
||||
}
|
||||
}
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.resource.loader;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -31,7 +33,10 @@ import net.minecraft.resource.ResourcePack;
|
|||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.FabricNamespaceResourceManagerEntry;
|
||||
import net.fabricmc.fabric.impl.resource.loader.FabricResource;
|
||||
import net.fabricmc.fabric.impl.resource.loader.GroupResourcePack;
|
||||
import net.fabricmc.fabric.impl.resource.loader.ResourcePackSourceTracker;
|
||||
|
||||
/**
|
||||
* Patches getAllResources and method_41265 to work with GroupResourcePack.
|
||||
|
@ -74,4 +79,31 @@ public class NamespaceResourceManagerMixin {
|
|||
|
||||
return entries.add(entry);
|
||||
}
|
||||
|
||||
/* The two injectors below set the resource pack sources (see FabricResourceImpl)
|
||||
* for resources created in NamespaceResourceManager.getAllResources and NamespaceResourceManager.getResource.
|
||||
*
|
||||
* Since (in 1.18.2) ResourceImpl doesn't hold a reference to its resource pack,
|
||||
* we have to get the source from the resource pack when the resource is created.
|
||||
* These are the main creation sites for resources in 1.18.2
|
||||
* along with DefaultResourcePack.getResource and Fabric API's GroupResourcePack,
|
||||
* which also either track the source similarly or provide other types of Resource instances
|
||||
* that have a different FabricResource implementation.
|
||||
*/
|
||||
@Inject(method = "getAllResources", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", remap = false, shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void trackSourceOnGetAllResources(Identifier id, CallbackInfoReturnable<List<Resource>> cir, List<NamespaceResourceManager.Entry> entries, Identifier identifier, String string, Iterator var5, NamespaceResourceManager.FilterablePack filterablePack, ResourcePack resourcePack) {
|
||||
// After the created resource has been added, read it from the list and set its source
|
||||
// to match the tracked source of its resource pack.
|
||||
if (entries.get(entries.size() - 1) instanceof FabricNamespaceResourceManagerEntry entry) {
|
||||
entry.setFabricPackSource(ResourcePackSourceTracker.getSource(resourcePack));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "getResource", at = @At(value = "RETURN", ordinal = 1), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void trackSourceOnGetResource(Identifier identifier, CallbackInfoReturnable<Optional<Resource>> cir, int i, NamespaceResourceManager.FilterablePack filterablePack, ResourcePack resourcePack) {
|
||||
// Set the resource's source to match the tracked source of its resource pack.
|
||||
if (cir.getReturnValue().orElseThrow() instanceof FabricResource resource) {
|
||||
resource.setFabricPackSource(ResourcePackSourceTracker.getSource(resourcePack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.resource.loader;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourcePackSource;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.FabricResource;
|
||||
|
||||
/**
|
||||
* Implements {@link FabricResource} (resource source getter/setter)
|
||||
* for vanilla's basic {@link Resource} used for most game resources.
|
||||
*
|
||||
* @see NamespaceResourceManagerMixin the usage site for this mixin
|
||||
*/
|
||||
@Mixin(Resource.class)
|
||||
class ResourceMixin implements FabricResource {
|
||||
@Unique
|
||||
private @Nullable ResourcePackSource fabric_packSource;
|
||||
|
||||
@Override
|
||||
public ResourcePackSource getFabricPackSource() {
|
||||
return Objects.requireNonNullElse(fabric_packSource, ResourcePackSource.PACK_SOURCE_NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFabricPackSource(ResourcePackSource packSource) {
|
||||
this.fabric_packSource = packSource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.resource.loader;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.resource.ResourcePack;
|
||||
import net.minecraft.resource.ResourcePackProfile;
|
||||
import net.minecraft.resource.ResourcePackSource;
|
||||
|
||||
import net.fabricmc.fabric.impl.resource.loader.ResourcePackSourceTracker;
|
||||
|
||||
/**
|
||||
* Implements resource pack source tracking (for {@link net.fabricmc.fabric.impl.resource.loader.FabricResource}).
|
||||
* {@link ResourcePack} doesn't hold a reference to its {@link ResourcePackSource}
|
||||
* so we store the source in a global tracker when the resource packs are created.
|
||||
*
|
||||
* @see ResourcePackSourceTracker
|
||||
*/
|
||||
@Mixin(ResourcePackProfile.class)
|
||||
abstract class ResourcePackProfileMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private ResourcePackSource source;
|
||||
|
||||
@Inject(method = "createResourcePack", at = @At("RETURN"))
|
||||
private void onCreateResourcePack(CallbackInfoReturnable<ResourcePack> info) {
|
||||
ResourcePackSourceTracker.setSource(info.getReturnValue(), source);
|
||||
}
|
||||
}
|
|
@ -3,3 +3,4 @@ accessWidener v2 named
|
|||
accessible method net/minecraft/resource/NamespaceResourceManager$Entry <init> (Lnet/minecraft/resource/NamespaceResourceManager;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/resource/ResourcePack;)V
|
||||
accessible field net/minecraft/resource/NamespaceResourceManager$Entry id Lnet/minecraft/util/Identifier;
|
||||
accessible field net/minecraft/resource/NamespaceResourceManager$Entry pack Lnet/minecraft/resource/ResourcePack;
|
||||
accessible class net/minecraft/resource/NamespaceResourceManager$FilterablePack
|
||||
|
|
|
@ -10,10 +10,13 @@
|
|||
"MainMixin",
|
||||
"MinecraftServerMixin",
|
||||
"NamespaceResourceManagerAccessor",
|
||||
"NamespaceResourceManagerEntryMixin",
|
||||
"NamespaceResourceManagerMixin",
|
||||
"ReloadableResourceManagerImplMixin",
|
||||
"ResourcePackManagerAccessor",
|
||||
"ResourceMixin",
|
||||
"ResourcePackManagerMixin",
|
||||
"ResourcePackManagerAccessor",
|
||||
"ResourcePackProfileMixin",
|
||||
"SimpleResourceReloadMixin",
|
||||
"TestServerMixin"
|
||||
],
|
||||
|
|
|
@ -15,6 +15,15 @@ transitive-accessible method net/minecraft/screen/ScreenHandlerType <init> (Lnet
|
|||
transitive-accessible class net/minecraft/client/gui/screen/ingame/HandledScreens$Provider
|
||||
transitive-accessible method net/minecraft/client/gui/screen/ingame/HandledScreens register (Lnet/minecraft/screen/ScreenHandlerType;Lnet/minecraft/client/gui/screen/ingame/HandledScreens$Provider;)V
|
||||
|
||||
# Data contained in loot tables and pools
|
||||
transitive-accessible field net/minecraft/loot/LootPool entries [Lnet/minecraft/loot/entry/LootPoolEntry;
|
||||
transitive-accessible field net/minecraft/loot/LootPool conditions [Lnet/minecraft/loot/condition/LootCondition;
|
||||
transitive-accessible field net/minecraft/loot/LootPool functions [Lnet/minecraft/loot/function/LootFunction;
|
||||
transitive-accessible field net/minecraft/loot/LootPool rolls Lnet/minecraft/loot/provider/number/LootNumberProvider;
|
||||
transitive-accessible field net/minecraft/loot/LootPool bonusRolls Lnet/minecraft/loot/provider/number/LootNumberProvider;
|
||||
transitive-accessible field net/minecraft/loot/LootTable pools [Lnet/minecraft/loot/LootPool;
|
||||
transitive-accessible field net/minecraft/loot/LootTable functions [Lnet/minecraft/loot/function/LootFunction;
|
||||
|
||||
### Generated access wideners below
|
||||
# Constructors of non-abstract block classes
|
||||
transitive-accessible method net/minecraft/block/AirBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
|
||||
|
|
|
@ -15,4 +15,13 @@ transitive-accessible method net/minecraft/screen/ScreenHandlerType <init> (Lnet
|
|||
transitive-accessible class net/minecraft/client/gui/screen/ingame/HandledScreens$Provider
|
||||
transitive-accessible method net/minecraft/client/gui/screen/ingame/HandledScreens register (Lnet/minecraft/screen/ScreenHandlerType;Lnet/minecraft/client/gui/screen/ingame/HandledScreens$Provider;)V
|
||||
|
||||
# Data contained in loot tables and pools
|
||||
transitive-accessible field net/minecraft/loot/LootPool entries [Lnet/minecraft/loot/entry/LootPoolEntry;
|
||||
transitive-accessible field net/minecraft/loot/LootPool conditions [Lnet/minecraft/loot/condition/LootCondition;
|
||||
transitive-accessible field net/minecraft/loot/LootPool functions [Lnet/minecraft/loot/function/LootFunction;
|
||||
transitive-accessible field net/minecraft/loot/LootPool rolls Lnet/minecraft/loot/provider/number/LootNumberProvider;
|
||||
transitive-accessible field net/minecraft/loot/LootPool bonusRolls Lnet/minecraft/loot/provider/number/LootNumberProvider;
|
||||
transitive-accessible field net/minecraft/loot/LootTable pools [Lnet/minecraft/loot/LootPool;
|
||||
transitive-accessible field net/minecraft/loot/LootTable functions [Lnet/minecraft/loot/function/LootFunction;
|
||||
|
||||
### Generated access wideners below
|
||||
|
|
|
@ -30,6 +30,7 @@ fabric-item-groups-v0-version=0.3.21
|
|||
fabric-key-binding-api-v1-version=1.0.17
|
||||
fabric-keybindings-v0-version=0.2.15
|
||||
fabric-lifecycle-events-v1-version=2.0.8
|
||||
fabric-loot-api-v2-version=1.0.0
|
||||
fabric-loot-tables-v1-version=1.0.15
|
||||
fabric-mining-level-api-v1-version=2.1.5
|
||||
fabric-models-v0-version=0.3.14
|
||||
|
|
|
@ -29,7 +29,7 @@ include 'fabric-item-api-v1'
|
|||
include 'fabric-item-groups-v0'
|
||||
include 'fabric-key-binding-api-v1'
|
||||
include 'fabric-lifecycle-events-v1'
|
||||
include 'fabric-loot-tables-v1'
|
||||
include 'fabric-loot-api-v2'
|
||||
include 'fabric-mining-level-api-v1'
|
||||
include 'fabric-models-v0'
|
||||
include 'fabric-networking-api-v1'
|
||||
|
@ -60,3 +60,4 @@ include 'deprecated:fabric-keybindings-v0'
|
|||
include 'deprecated:fabric-networking-v0'
|
||||
include 'deprecated:fabric-renderer-registries-v1'
|
||||
include 'deprecated:fabric-rendering-v0'
|
||||
include 'deprecated:fabric-loot-tables-v1'
|
||||
|
|
Loading…
Reference in a new issue