forked from FabricMC/fabric
Loot table manipulation API (#160)
This commit is contained in:
parent
6dad974e70
commit
05f11b75e4
20 changed files with 827 additions and 11 deletions
|
@ -20,18 +20,13 @@ import net.fabricmc.fabric.impl.registry.LootEntryTypeRegistryImpl;
|
|||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
|
||||
/**
|
||||
* Fabric's extensions to {@code net.minecraft.world.loot.entry.LootEntries} for registering
|
||||
* custom loot entry types.
|
||||
*
|
||||
* @see #register
|
||||
* @deprecated Use {@link net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface LootEntryTypeRegistry {
|
||||
@Deprecated
|
||||
final LootEntryTypeRegistry INSTANCE = LootEntryTypeRegistryImpl.INSTANCE;
|
||||
|
||||
/**
|
||||
* Registers a loot entry type by its serializer.
|
||||
*
|
||||
* @param serializer the loot entry serializer
|
||||
*/
|
||||
@Deprecated
|
||||
void register(LootEntry.Serializer<?> serializer);
|
||||
}
|
||||
|
|
|
@ -21,10 +21,9 @@ import net.minecraft.world.loot.entry.LootEntries;
|
|||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Deprecated
|
||||
public final class LootEntryTypeRegistryImpl implements LootEntryTypeRegistry {
|
||||
private static Consumer<LootEntry.Serializer<?>> registerFunction;
|
||||
public static final LootEntryTypeRegistryImpl INSTANCE = new LootEntryTypeRegistryImpl();
|
||||
private static final Method REGISTER_METHOD;
|
||||
|
||||
|
|
6
fabric-loot-tables-v1/build.gradle
Normal file
6
fabric-loot-tables-v1/build.gradle
Normal file
|
@ -0,0 +1,6 @@
|
|||
archivesBaseName = "fabric-loot-tables-v1"
|
||||
version = "0.1.0"
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.LootTableRange;
|
||||
import net.minecraft.world.loot.condition.LootCondition;
|
||||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An interface implemented by all {@code net.minecraft.world.loot.LootPool} instances when
|
||||
* Fabric API is present. Contains accessors for various fields.
|
||||
*/
|
||||
public interface FabricLootPool {
|
||||
default LootPool asVanilla() {
|
||||
return (LootPool) this;
|
||||
}
|
||||
List<LootEntry> getEntries();
|
||||
List<LootCondition> getConditions();
|
||||
List<LootFunction> getFunctions();
|
||||
LootTableRange getRollsRange();
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import net.fabricmc.fabric.mixin.loot.LootPoolBuilderHooks;
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.LootTableRange;
|
||||
import net.minecraft.world.loot.condition.LootCondition;
|
||||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
|
||||
public class FabricLootPoolBuilder extends LootPool.Builder {
|
||||
private final LootPoolBuilderHooks extended = (LootPoolBuilderHooks) this;
|
||||
|
||||
private FabricLootPoolBuilder() {}
|
||||
|
||||
private FabricLootPoolBuilder(LootPool pool) {
|
||||
copyFrom(pool, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder withRolls(LootTableRange range) {
|
||||
super.withRolls(range);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder withEntry(LootEntry.Builder<?> entry) {
|
||||
super.withEntry(entry);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder withCondition(LootCondition.Builder condition) {
|
||||
super.method_356(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder withFunction(LootFunction.Builder function) {
|
||||
super.method_353(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootPoolBuilder withEntry(LootEntry entry) {
|
||||
extended.getEntries().add(entry);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootPoolBuilder withCondition(LootCondition condition) {
|
||||
extended.getConditions().add(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootPoolBuilder withFunction(LootFunction function) {
|
||||
extended.getFunctions().add(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the entries, conditions and functions of the {@code pool} to this
|
||||
* builder.
|
||||
*
|
||||
* This is equal to {@code copyFrom(pool, false)}.
|
||||
*/
|
||||
public FabricLootPoolBuilder copyFrom(LootPool pool) {
|
||||
return copyFrom(pool, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the entries, conditions and functions of the {@code pool} to this
|
||||
* builder.
|
||||
*
|
||||
* If {@code copyRolls} is true, the {@link FabricLootPool#getRollsRange 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());
|
||||
|
||||
if (copyRolls) {
|
||||
withRolls(extendedPool.getRollsRange());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static FabricLootPoolBuilder builder() {
|
||||
return new FabricLootPoolBuilder();
|
||||
}
|
||||
|
||||
public static FabricLootPoolBuilder of(LootPool pool) {
|
||||
return new FabricLootPoolBuilder(pool);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.LootSupplier;
|
||||
import net.minecraft.world.loot.context.LootContextType;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An interface implemented by all {@code net.minecraft.world.loot.LootSupplier} instances when
|
||||
* Fabric API is present. Contains accessors for various fields.
|
||||
*/
|
||||
public interface FabricLootSupplier {
|
||||
default LootSupplier asVanilla() {
|
||||
return (LootSupplier) this;
|
||||
}
|
||||
List<LootPool> getPools();
|
||||
List<LootFunction> getFunctions();
|
||||
LootContextType getType();
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import net.fabricmc.fabric.mixin.loot.LootSupplierBuilderHooks;
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.LootSupplier;
|
||||
import net.minecraft.world.loot.context.LootContextType;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class FabricLootSupplierBuilder extends LootSupplier.Builder {
|
||||
private final LootSupplierBuilderHooks extended = (LootSupplierBuilderHooks) this;
|
||||
|
||||
protected FabricLootSupplierBuilder() {}
|
||||
|
||||
private FabricLootSupplierBuilder(LootSupplier supplier) {
|
||||
copyFrom(supplier, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withPool(LootPool.Builder pool) {
|
||||
super.withPool(pool);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withType(LootContextType type) {
|
||||
super.withType(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withFunction(LootFunction.Builder function) {
|
||||
super.method_335(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withPool(LootPool pool) {
|
||||
extended.getPools().add(pool);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withFunction(LootFunction function) {
|
||||
extended.getFunctions().add(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withPools(Collection<LootPool> pools) {
|
||||
pools.forEach(this::withPool);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withFunctions(Collection<LootFunction> functions) {
|
||||
functions.forEach(this::withFunction);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the pools and functions of the {@code supplier} to this builder.
|
||||
* This is equal to {@code copyFrom(supplier, false)}.
|
||||
*/
|
||||
public FabricLootSupplierBuilder copyFrom(LootSupplier supplier) {
|
||||
return copyFrom(supplier, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the pools and functions of the {@code supplier} to this builder.
|
||||
* If {@code copyType} is true, the {@link FabricLootSupplier#getType type} of the supplier is also copied.
|
||||
*/
|
||||
public FabricLootSupplierBuilder copyFrom(LootSupplier supplier, boolean copyType) {
|
||||
FabricLootSupplier extendedSupplier = (FabricLootSupplier) supplier;
|
||||
extended.getPools().addAll(extendedSupplier.getPools());
|
||||
extended.getFunctions().addAll(extendedSupplier.getFunctions());
|
||||
|
||||
if (copyType) {
|
||||
withType(extendedSupplier.getType());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static FabricLootSupplierBuilder builder() {
|
||||
return new FabricLootSupplierBuilder();
|
||||
}
|
||||
|
||||
public static FabricLootSupplierBuilder of(LootSupplier supplier) {
|
||||
return new FabricLootSupplierBuilder(supplier);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.v1;
|
||||
|
||||
import net.fabricmc.fabric.impl.loot.LootEntryTypeRegistryImpl;
|
||||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
|
||||
/**
|
||||
* Fabric's extensions to {@code net.minecraft.world.loot.entry.LootEntries} for registering
|
||||
* custom loot entry types.
|
||||
*
|
||||
* @see #register
|
||||
*/
|
||||
public interface LootEntryTypeRegistry {
|
||||
final LootEntryTypeRegistry INSTANCE = LootEntryTypeRegistryImpl.INSTANCE;
|
||||
|
||||
/**
|
||||
* Registers a loot entry type by its serializer.
|
||||
*
|
||||
* @param serializer the loot entry serializer
|
||||
*/
|
||||
void register(LootEntry.Serializer<?> serializer);
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.Lazy;
|
||||
import net.minecraft.world.loot.*;
|
||||
import net.minecraft.world.loot.condition.LootCondition;
|
||||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
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 LootJsonParser() {
|
||||
|
||||
}
|
||||
|
||||
public static <T> T read(Reader json, Class<T> c) {
|
||||
return JsonHelper.deserialize(GSON.get(), json, c);
|
||||
}
|
||||
|
||||
public static <T> T read(String json, Class<T> c) {
|
||||
return JsonHelper.deserialize(GSON.get(), json, c);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1.event;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.loot.LootManager;
|
||||
import net.minecraft.world.loot.LootSupplier;
|
||||
|
||||
/**
|
||||
* An event handler that is called when loot tables are loaded.
|
||||
* Use {@link #EVENT} to register instances.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface LootTableLoadingCallback {
|
||||
@FunctionalInterface
|
||||
interface LootTableSetter {
|
||||
void set(LootSupplier supplier);
|
||||
}
|
||||
|
||||
final Event<LootTableLoadingCallback> EVENT = EventFactory.createArrayBacked(
|
||||
LootTableLoadingCallback.class,
|
||||
(listeners) -> (resourceManager, manager, id, supplier, setter) -> {
|
||||
for (LootTableLoadingCallback callback : listeners) {
|
||||
callback.onLootTableLoading(resourceManager, manager, id, supplier, setter);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
void onLootTableLoading(ResourceManager resourceManager, LootManager manager, Identifier id, FabricLootSupplierBuilder supplier, LootTableSetter setter);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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.world.loot.entry.LootEntries;
|
||||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class LootEntryTypeRegistryImpl implements net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry {
|
||||
public static final LootEntryTypeRegistryImpl INSTANCE = new LootEntryTypeRegistryImpl();
|
||||
private static final Method REGISTER_METHOD;
|
||||
|
||||
static {
|
||||
Method target = null;
|
||||
for (Method m : LootEntries.class.getDeclaredMethods()) {
|
||||
if (m.getParameterCount() == 1 && m.getParameterTypes()[0] == LootEntry.Serializer.class) {
|
||||
if (target != null) {
|
||||
throw new RuntimeException("More than one register-like method found in LootEntries!");
|
||||
} else {
|
||||
target = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
throw new RuntimeException("Could not find register-like method in LootEntries!");
|
||||
} else {
|
||||
REGISTER_METHOD = target;
|
||||
REGISTER_METHOD.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private LootEntryTypeRegistryImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(LootEntry.Serializer<?> serializer) {
|
||||
try {
|
||||
REGISTER_METHOD.invoke(null, serializer);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.condition.LootCondition;
|
||||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(LootPool.Builder.class)
|
||||
public interface LootPoolBuilderHooks {
|
||||
@Accessor
|
||||
List<LootEntry> getEntries();
|
||||
@Accessor
|
||||
List<LootCondition> getConditions();
|
||||
@Accessor
|
||||
List<LootFunction> getFunctions();
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.LootSupplier;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(LootSupplier.Builder.class)
|
||||
public interface LootSupplierBuilderHooks {
|
||||
@Accessor
|
||||
List<LootPool> getPools();
|
||||
@Accessor
|
||||
List<LootFunction> getFunctions();
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.loot.LootManager;
|
||||
import net.minecraft.world.loot.LootSupplier;
|
||||
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.CallbackInfo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(LootManager.class)
|
||||
public class MixinLootManager {
|
||||
@Shadow @Final private Map<Identifier, LootSupplier> suppliers;
|
||||
|
||||
@Inject(method = "apply", at = @At("RETURN"))
|
||||
private void apply(ResourceManager manager, CallbackInfo info) {
|
||||
Map<Identifier, LootSupplier> newSuppliers = new HashMap<>();
|
||||
|
||||
suppliers.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.create());
|
||||
});
|
||||
|
||||
for (Identifier id : newSuppliers.keySet()) {
|
||||
suppliers.put(id, newSuppliers.get(id));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootPool;
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.LootTableRange;
|
||||
import net.minecraft.world.loot.condition.LootCondition;
|
||||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
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 java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(LootPool.class)
|
||||
public abstract class MixinLootPool implements FabricLootPool {
|
||||
@Shadow @Final private LootEntry[] entries;
|
||||
|
||||
@Shadow @Final private LootCondition[] conditions;
|
||||
|
||||
@Shadow @Final private LootFunction[] functions;
|
||||
|
||||
@Override
|
||||
public List<LootEntry> getEntries() {
|
||||
return Arrays.asList(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootCondition> getConditions() {
|
||||
return Arrays.asList(conditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootFunction> getFunctions() {
|
||||
return Arrays.asList(functions);
|
||||
}
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract LootTableRange getRollsRange();
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplier;
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.LootSupplier;
|
||||
import net.minecraft.world.loot.context.LootContextType;
|
||||
import net.minecraft.world.loot.function.LootFunction;
|
||||
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 java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(LootSupplier.class)
|
||||
public abstract class MixinLootSupplier implements FabricLootSupplier {
|
||||
@Shadow @Final private LootPool[] pools;
|
||||
@Shadow @Final private LootFunction[] functions;
|
||||
|
||||
@Override
|
||||
public List<LootPool> getPools() {
|
||||
return Arrays.asList(pools);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootFunction> getFunctions() {
|
||||
return Arrays.asList(functions);
|
||||
}
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract LootContextType getType();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.mixin.loot",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"LootPoolBuilderHooks",
|
||||
"LootSupplierBuilderHooks",
|
||||
"MixinLootManager",
|
||||
"MixinLootPool",
|
||||
"MixinLootSupplier"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
13
fabric-loot-tables-v1/src/main/resources/fabric.mod.json
Normal file
13
fabric-loot-tables-v1/src/main/resources/fabric.mod.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-loot-tables-v1",
|
||||
"version": "${version}",
|
||||
"license": "Apache-2.0",
|
||||
"depends": {
|
||||
"fabricloader": ">=0.4.0",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"mixins": [
|
||||
"fabric-loot-tables-v1.mixins.json"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.loot;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.loot.LootTableLoadingCallback;
|
||||
import net.fabricmc.fabric.api.loot.FabricLootPoolBuilder;
|
||||
import net.fabricmc.fabric.api.loot.LootUtilities;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.world.loot.ConstantLootTableRange;
|
||||
import net.minecraft.world.loot.LootPool;
|
||||
import net.minecraft.world.loot.condition.SurvivesExplosionLootCondition;
|
||||
import net.minecraft.world.loot.entry.ItemEntry;
|
||||
import net.minecraft.world.loot.entry.LootEntry;
|
||||
|
||||
public class LootTableMod implements ModInitializer {
|
||||
private static final String LOOT_ENTRY_JSON = "{\"type\":\"minecraft:item\",\"name\":\"minecraft:apple\"}";
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LootTableLoadingCallback.EVENT.register((manager, id, supplier) -> {
|
||||
if ("minecraft:blocks/dirt".equals(id.toString())) {
|
||||
LootEntry entryFromString = LootUtilities.readEntryFromJson(LOOT_ENTRY_JSON);
|
||||
|
||||
LootPool pool = FabricLootPoolBuilder.builder()
|
||||
.withEntry(ItemEntry.builder(Items.FEATHER))
|
||||
.withEntry(entryFromString)
|
||||
.withRolls(ConstantLootTableRange.create(1))
|
||||
.withCondition(SurvivesExplosionLootCondition.method_871())
|
||||
.build();
|
||||
|
||||
supplier.withPool(pool);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ include 'fabric-events-interaction-v0'
|
|||
include 'fabric-events-lifecycle-v0'
|
||||
include 'fabric-item-groups-v0'
|
||||
include 'fabric-keybindings-v0'
|
||||
include 'fabric-loot-tables-v1'
|
||||
include 'fabric-mining-levels-v0'
|
||||
include 'fabric-models-v0'
|
||||
include 'fabric-networking-v0'
|
||||
|
|
Loading…
Reference in a new issue