mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-30 15:37:32 +02:00
Remove loot table api
This commit is contained in:
parent
24e4b8765e
commit
34c5f5133e
@ -12,7 +12,6 @@ import net.minestom.server.exception.ExceptionManager;
|
|||||||
import net.minestom.server.extensions.Extension;
|
import net.minestom.server.extensions.Extension;
|
||||||
import net.minestom.server.extensions.ExtensionManager;
|
import net.minestom.server.extensions.ExtensionManager;
|
||||||
import net.minestom.server.fluid.Fluid;
|
import net.minestom.server.fluid.Fluid;
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
import net.minestom.server.gamedata.tags.TagManager;
|
import net.minestom.server.gamedata.tags.TagManager;
|
||||||
import net.minestom.server.instance.Chunk;
|
import net.minestom.server.instance.Chunk;
|
||||||
import net.minestom.server.instance.InstanceManager;
|
import net.minestom.server.instance.InstanceManager;
|
||||||
@ -129,7 +128,6 @@ public final class MinecraftServer {
|
|||||||
private static ResponseDataConsumer responseDataConsumer;
|
private static ResponseDataConsumer responseDataConsumer;
|
||||||
private static String brandName = "Minestom";
|
private static String brandName = "Minestom";
|
||||||
private static Difficulty difficulty = Difficulty.NORMAL;
|
private static Difficulty difficulty = Difficulty.NORMAL;
|
||||||
private static LootTableManager lootTableManager;
|
|
||||||
private static TagManager tagManager;
|
private static TagManager tagManager;
|
||||||
|
|
||||||
public static MinecraftServer init() {
|
public static MinecraftServer init() {
|
||||||
@ -168,7 +166,6 @@ public final class MinecraftServer {
|
|||||||
|
|
||||||
updateManager = new UpdateManager();
|
updateManager = new UpdateManager();
|
||||||
|
|
||||||
lootTableManager = new LootTableManager();
|
|
||||||
tagManager = new TagManager();
|
tagManager = new TagManager();
|
||||||
|
|
||||||
nettyServer = new NettyServer(packetProcessor);
|
nettyServer = new NettyServer(packetProcessor);
|
||||||
@ -609,16 +606,6 @@ public final class MinecraftServer {
|
|||||||
return responseDataConsumer;
|
return responseDataConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the manager handling loot tables.
|
|
||||||
*
|
|
||||||
* @return the loot table manager
|
|
||||||
*/
|
|
||||||
public static LootTableManager getLootTableManager() {
|
|
||||||
checkInitStatus(lootTableManager);
|
|
||||||
return lootTableManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the manager handling dimensions.
|
* Gets the manager handling dimensions.
|
||||||
*
|
*
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
package net.minestom.server.gamedata;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a condition, used by predicates in MC functions and in loot tables.
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Condition {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests this condition. Subclasses are free to throw runtime exceptions if the arguments passed through data are not valid or missing
|
|
||||||
* @param data arguments to give to the condition. May be null if the condition supports it
|
|
||||||
* @return 'true' if the condition passed, 'false' otherwise
|
|
||||||
*/
|
|
||||||
boolean test(Data data);
|
|
||||||
|
|
||||||
Condition ALWAYS_YES = (_d) -> true;
|
|
||||||
Condition ALWAYS_NO = (_d) -> false;
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.conditions;
|
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonDeserializer;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requires 'explosionPower' double argument
|
|
||||||
*/
|
|
||||||
public class SurvivesExplosionCondition implements Condition {
|
|
||||||
private Random rng = new Random();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean test(Data data) {
|
|
||||||
if(data == null)
|
|
||||||
return true; // no explosion here
|
|
||||||
if(!data.hasKey("explosionPower"))
|
|
||||||
return true; // no explosion here
|
|
||||||
return rng.nextDouble() <= 1.0/data.<Double>get("explosionPower");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Deserializer implements JsonDeserializer<SurvivesExplosionCondition> {
|
|
||||||
@Override
|
|
||||||
public SurvivesExplosionCondition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
return new SurvivesExplosionCondition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
import com.google.gson.*;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public abstract class ConditionContainer {
|
|
||||||
private ConditionContainer() {}
|
|
||||||
|
|
||||||
public abstract Condition create(LootTableManager lootTableManager);
|
|
||||||
|
|
||||||
|
|
||||||
static class Deserializer implements JsonDeserializer<ConditionContainer> {
|
|
||||||
|
|
||||||
private final LootTableManager lootTableManager;
|
|
||||||
|
|
||||||
Deserializer(LootTableManager lootTableManager) {
|
|
||||||
this.lootTableManager = lootTableManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConditionContainer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
JsonObject obj = json.getAsJsonObject();
|
|
||||||
String type = obj.get("condition").getAsString();
|
|
||||||
JsonDeserializer<? extends Condition> deserializer = lootTableManager.getConditionDeserializer(NamespaceID.from(type));
|
|
||||||
return new ConditionContainer() {
|
|
||||||
@Override
|
|
||||||
public Condition create(LootTableManager lootTableManager) {
|
|
||||||
return deserializer.deserialize(obj, typeOfT, context);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loot table function that must meet some conditions to be applied
|
|
||||||
*/
|
|
||||||
public class ConditionedFunctionWrapper implements LootTableFunction {
|
|
||||||
|
|
||||||
private final LootTableFunction baseFunction;
|
|
||||||
private final Collection<Condition> conditions;
|
|
||||||
|
|
||||||
public ConditionedFunctionWrapper(LootTableFunction baseFunction, Collection<Condition> conditions) {
|
|
||||||
this.baseFunction = baseFunction;
|
|
||||||
this.conditions = conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack apply(ItemStack stack, Data data) {
|
|
||||||
for (Condition c : conditions) {
|
|
||||||
if (!c.test(data))
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
return baseFunction.apply(stack, data);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,134 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.utils.WeightedRandom;
|
|
||||||
import net.minestom.server.utils.WeightedRandomItem;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class LootTable {
|
|
||||||
|
|
||||||
public static final String LUCK_KEY = "minecraft:luck";
|
|
||||||
|
|
||||||
private final LootTableType type;
|
|
||||||
private final List<LootTable.Pool> pools;
|
|
||||||
|
|
||||||
public LootTable(LootTableType type, List<Pool> pools) {
|
|
||||||
this.type = type;
|
|
||||||
this.pools = pools;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LootTableType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Pool> getPools() {
|
|
||||||
return pools;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ItemStack> generate(Data arguments) {
|
|
||||||
if (arguments == null)
|
|
||||||
arguments = Data.EMPTY;
|
|
||||||
List<ItemStack> output = new LinkedList<>();
|
|
||||||
for (Pool p : pools) {
|
|
||||||
p.generate(output, arguments);
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Pool {
|
|
||||||
private final int minRollCount;
|
|
||||||
private final int maxRollCount;
|
|
||||||
private final int bonusMinRollCount;
|
|
||||||
private final int bonusMaxRollCount;
|
|
||||||
private final List<LootTable.Entry> entries;
|
|
||||||
private final List<Condition> conditions;
|
|
||||||
|
|
||||||
public Pool(int minRollCount, int maxRollCount, int bonusMinRollCount, int bonusMaxRollCount, List<Entry> entries, List<Condition> conditions) {
|
|
||||||
this.minRollCount = minRollCount;
|
|
||||||
this.maxRollCount = maxRollCount;
|
|
||||||
this.bonusMinRollCount = bonusMinRollCount;
|
|
||||||
this.bonusMaxRollCount = bonusMaxRollCount;
|
|
||||||
this.entries = entries;
|
|
||||||
this.conditions = conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Condition> getConditions() {
|
|
||||||
return conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinRollCount() {
|
|
||||||
return minRollCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxRollCount() {
|
|
||||||
return maxRollCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Entry> getEntries() {
|
|
||||||
return entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generate(List<ItemStack> output, Data arguments) {
|
|
||||||
for (Condition c : conditions) {
|
|
||||||
if (!c.test(arguments))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Random rng = new Random();
|
|
||||||
int luck = arguments.getOrDefault(LUCK_KEY, 0);
|
|
||||||
int rollCount = rng.nextInt(maxRollCount - minRollCount + 1 /*inclusive*/) + minRollCount;
|
|
||||||
int bonusRollCount = rng.nextInt(bonusMaxRollCount - bonusMinRollCount + 1 /*inclusive*/) + bonusMinRollCount;
|
|
||||||
bonusRollCount *= luck;
|
|
||||||
// TODO: implement luck (quality/weight) weight=floor( weight + (quality * generic.luck))
|
|
||||||
WeightedRandom<Entry> weightedRandom = new WeightedRandom<>(entries);
|
|
||||||
for (int i = 0; i < rollCount + bonusRollCount; i++) {
|
|
||||||
Entry entry = weightedRandom.get(rng);
|
|
||||||
entry.generateStacks(output, arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract static class Entry implements WeightedRandomItem {
|
|
||||||
private final LootTableEntryType type;
|
|
||||||
private final int weight;
|
|
||||||
private final int quality;
|
|
||||||
private final List<Condition> conditions;
|
|
||||||
|
|
||||||
public Entry(LootTableEntryType type, int weight, int quality, List<Condition> conditions) {
|
|
||||||
this.type = type;
|
|
||||||
this.weight = weight;
|
|
||||||
this.quality = quality;
|
|
||||||
this.conditions = conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Condition> getConditions() {
|
|
||||||
return conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getQuality() {
|
|
||||||
return quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getWeight() {
|
|
||||||
return weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LootTableEntryType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void generateStacks(List<ItemStack> output, Data arguments) {
|
|
||||||
for (Condition c : conditions) {
|
|
||||||
if (!c.test(arguments))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
generate(output, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void generate(List<ItemStack> output, Data arguments);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,115 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Meant only for parsing loot tables
|
|
||||||
*/
|
|
||||||
class LootTableContainer {
|
|
||||||
|
|
||||||
|
|
||||||
private String type;
|
|
||||||
private LootTableContainer.Pool[] pools;
|
|
||||||
|
|
||||||
private LootTableContainer() {}
|
|
||||||
|
|
||||||
public LootTable createTable(LootTableManager lootTableManager) {
|
|
||||||
LootTableType type = lootTableManager.getTableType(NamespaceID.from(this.type));
|
|
||||||
List<LootTable.Pool> pools = new LinkedList<>();
|
|
||||||
if(this.pools != null) {
|
|
||||||
for(Pool p : this.pools) {
|
|
||||||
pools.add(p.create(lootTableManager));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new LootTable(type, pools);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Pool {
|
|
||||||
private ConditionContainer[] conditions;
|
|
||||||
private FunctionContainer[] functions;
|
|
||||||
private RangeContainer rolls;
|
|
||||||
private RangeContainer bonus_rools;
|
|
||||||
|
|
||||||
private Entry[] entries;
|
|
||||||
|
|
||||||
private Pool() {}
|
|
||||||
|
|
||||||
public LootTable.Pool create(LootTableManager lootTableManager) {
|
|
||||||
List<LootTable.Entry> entries = new LinkedList<>();
|
|
||||||
List<Condition> conditions = new LinkedList<>();
|
|
||||||
if(this.entries != null) {
|
|
||||||
for (Entry e : this.entries) {
|
|
||||||
entries.add(e.create(lootTableManager));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(this.conditions != null) {
|
|
||||||
for (ConditionContainer c : this.conditions) {
|
|
||||||
conditions.add(c.create(lootTableManager));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(rolls == null)
|
|
||||||
rolls = new RangeContainer(0,0);
|
|
||||||
if(bonus_rools == null)
|
|
||||||
bonus_rools = new RangeContainer(0,0);
|
|
||||||
return new LootTable.Pool(rolls.getMin(), rolls.getMax(), bonus_rools.getMin(), bonus_rools.getMax(), entries, conditions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Entry {
|
|
||||||
private ConditionContainer[] conditions;
|
|
||||||
private String type;
|
|
||||||
private String name;
|
|
||||||
private Entry[] children;
|
|
||||||
private boolean expand;
|
|
||||||
private FunctionContainer[] functions;
|
|
||||||
private int weight;
|
|
||||||
private int quality;
|
|
||||||
|
|
||||||
private Entry() {}
|
|
||||||
|
|
||||||
public LootTable.Entry create(LootTableManager lootTableManager) {
|
|
||||||
LootTableEntryType entryType = lootTableManager.getEntryType(NamespaceID.from(type));
|
|
||||||
List<Condition> conditions = new LinkedList<>();
|
|
||||||
if(this.conditions != null) {
|
|
||||||
for(ConditionContainer c : this.conditions) {
|
|
||||||
conditions.add(c.create(lootTableManager));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<LootTable.Entry> children = new LinkedList<>();
|
|
||||||
if(this.children != null) {
|
|
||||||
for (Entry c : this.children) {
|
|
||||||
children.add(c.create(lootTableManager));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<LootTableFunction> functions = new LinkedList<>();
|
|
||||||
if(this.functions != null) {
|
|
||||||
for(FunctionContainer c : this.functions) {
|
|
||||||
functions.add(c.create(lootTableManager));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entryType.create(lootTableManager, name, conditions, children, expand, functions, weight, quality);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FunctionContainer {
|
|
||||||
private String function;
|
|
||||||
private ConditionContainer[] conditions;
|
|
||||||
|
|
||||||
private FunctionContainer() {}
|
|
||||||
|
|
||||||
public LootTableFunction create(LootTableManager lootTableManager) {
|
|
||||||
List<Condition> conditions = new LinkedList<>();
|
|
||||||
if(this.conditions != null) {
|
|
||||||
for(ConditionContainer c : this.conditions) {
|
|
||||||
conditions.add(c.create(lootTableManager));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ConditionedFunctionWrapper(lootTableManager.getFunction(NamespaceID.from(function)), conditions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface LootTableEntryType {
|
|
||||||
LootTable.Entry create(LootTableManager lootTableManager, String name, List<Condition> conditions, List<LootTable.Entry> children, boolean expand, List<LootTableFunction> functions, int weight, int quality);
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes to apply to the stack being produced
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface LootTableFunction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies changes to the stack being produced
|
|
||||||
* @param stack
|
|
||||||
* @param data arguments to pass to the function.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ItemStack apply(ItemStack stack, Data data);
|
|
||||||
|
|
||||||
LootTableFunction IDENTITY = (stack, _d) -> stack;
|
|
||||||
}
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonDeserializer;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
|
||||||
import net.minestom.server.utils.NamespaceIDHashMap;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Reader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles loading and configuration of loot tables
|
|
||||||
*/
|
|
||||||
public final class LootTableManager {
|
|
||||||
private NamespaceIDHashMap<JsonDeserializer<? extends Condition>> conditionDeserializers = new NamespaceIDHashMap<>();
|
|
||||||
private NamespaceIDHashMap<LootTableType> tableTypes = new NamespaceIDHashMap<>();
|
|
||||||
private NamespaceIDHashMap<LootTableEntryType> entryTypes = new NamespaceIDHashMap<>();
|
|
||||||
private NamespaceIDHashMap<LootTableFunction> functions = new NamespaceIDHashMap<>();
|
|
||||||
private NamespaceIDHashMap<LootTable> cache = new NamespaceIDHashMap<>();
|
|
||||||
private Gson gson;
|
|
||||||
|
|
||||||
public LootTableManager() {
|
|
||||||
gson = new GsonBuilder()
|
|
||||||
.registerTypeAdapter(RangeContainer.class, new RangeContainer.Deserializer())
|
|
||||||
.registerTypeAdapter(ConditionContainer.class, new ConditionContainer.Deserializer(this))
|
|
||||||
.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a condition factory to the given namespaceID
|
|
||||||
*
|
|
||||||
* @param namespaceID
|
|
||||||
* @param factory
|
|
||||||
*/
|
|
||||||
public <T extends Condition> void registerConditionDeserializer(NamespaceID namespaceID, JsonDeserializer<T> factory) {
|
|
||||||
conditionDeserializers.put(namespaceID, factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a loot table type to the given namespaceID
|
|
||||||
*
|
|
||||||
* @param namespaceID
|
|
||||||
* @param type
|
|
||||||
*/
|
|
||||||
public void registerTableType(NamespaceID namespaceID, LootTableType type) {
|
|
||||||
tableTypes.put(namespaceID, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a loot table entry type to the given namespaceID
|
|
||||||
*
|
|
||||||
* @param namespaceID
|
|
||||||
* @param type
|
|
||||||
*/
|
|
||||||
public void registerEntryType(NamespaceID namespaceID, LootTableEntryType type) {
|
|
||||||
entryTypes.put(namespaceID, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a loot table function to the given namespaceID
|
|
||||||
*
|
|
||||||
* @param namespaceID
|
|
||||||
* @param function
|
|
||||||
*/
|
|
||||||
public void registerFunction(NamespaceID namespaceID, LootTableFunction function) {
|
|
||||||
functions.put(namespaceID, function);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LootTable load(NamespaceID name) throws FileNotFoundException {
|
|
||||||
return null; // FIXME
|
|
||||||
//return load(name, new FileReader(new File(ResourceGatherer.DATA_FOLDER, "data/" + name.getDomain() + "/loot_tables/" + name.getPath() + ".json")));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a loot table with the given name. Loot tables can be cached, so 'reader' is used only on cache misses
|
|
||||||
*
|
|
||||||
* @param name the name to cache the loot table with
|
|
||||||
* @param reader the reader to read the loot table from, if none cached. **Will** be closed no matter the results of this call
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public LootTable load(NamespaceID name, Reader reader) {
|
|
||||||
try (reader) {
|
|
||||||
return cache.computeIfAbsent(name, _name -> create(reader));
|
|
||||||
} catch (IOException e) {
|
|
||||||
MinecraftServer.getExceptionManager().handleException(e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LootTable create(Reader reader) {
|
|
||||||
LootTableContainer container = gson.fromJson(reader, LootTableContainer.class);
|
|
||||||
return container.createTable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the registered table type corresponding to the given namespace ID. If none is registered, throws {@link IllegalArgumentException}
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public LootTableType getTableType(NamespaceID id) {
|
|
||||||
if (!tableTypes.containsKey(id))
|
|
||||||
throw new IllegalArgumentException("Unknown table type: " + id);
|
|
||||||
return tableTypes.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the registered entry type corresponding to the given namespace ID. If none is registered, throws {@link IllegalArgumentException}
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public LootTableEntryType getEntryType(NamespaceID id) {
|
|
||||||
if (!entryTypes.containsKey(id))
|
|
||||||
throw new IllegalArgumentException("Unknown entry type: " + id);
|
|
||||||
return entryTypes.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the registered table type corresponding to the given namespace ID. If none is registered, returns {@link LootTableFunction#IDENTITY}
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public LootTableFunction getFunction(NamespaceID id) {
|
|
||||||
return functions.getOrDefault(id, LootTableFunction.IDENTITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonDeserializer<? extends Condition> getConditionDeserializer(NamespaceID id) {
|
|
||||||
return conditionDeserializers.getOrDefault(id, (json, typeOfT, context) -> Condition.ALWAYS_NO);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
public interface LootTableType {
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables;
|
|
||||||
|
|
||||||
import com.google.gson.*;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
public class RangeContainer {
|
|
||||||
|
|
||||||
private int min;
|
|
||||||
private int max;
|
|
||||||
|
|
||||||
RangeContainer() {}
|
|
||||||
|
|
||||||
public RangeContainer(int min, int max) {
|
|
||||||
this.min = min;
|
|
||||||
this.max = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMin() {
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMax() {
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Deserializer implements JsonDeserializer<RangeContainer> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RangeContainer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
RangeContainer range = new RangeContainer();
|
|
||||||
if(json.isJsonPrimitive()) {
|
|
||||||
range.min = json.getAsInt();
|
|
||||||
range.max = json.getAsInt();
|
|
||||||
} else if(json.isJsonObject()) {
|
|
||||||
JsonObject obj = json.getAsJsonObject();
|
|
||||||
if(!obj.has("min"))
|
|
||||||
throw new IllegalArgumentException("Missing 'min' property");
|
|
||||||
if(!obj.has("max"))
|
|
||||||
throw new IllegalArgumentException("Missing 'max' property");
|
|
||||||
range.min = obj.get("min").getAsInt();
|
|
||||||
range.max = obj.get("max").getAsInt();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Range must be single integer or an object with 'min' and 'max' properties");
|
|
||||||
}
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AlternativesEntry extends LootTable.Entry {
|
|
||||||
private final List<LootTable.Entry> children;
|
|
||||||
|
|
||||||
public AlternativesEntry(AlternativesType type, List<LootTable.Entry> children, int weight, int quality, List<Condition> conditions) {
|
|
||||||
super(type, weight, quality, conditions);
|
|
||||||
this.children = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate(List<ItemStack> output, Data arguments) {
|
|
||||||
for (LootTable.Entry c : children) {
|
|
||||||
int previousSize = output.size();
|
|
||||||
c.generateStacks(output, arguments);
|
|
||||||
int newSize = output.size();
|
|
||||||
if (newSize != previousSize) { // an entry managed to generate, stop here
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableEntryType;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableFunction;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* minecraft:alternatives
|
|
||||||
*/
|
|
||||||
public class AlternativesType implements LootTableEntryType {
|
|
||||||
@Override
|
|
||||||
public LootTable.Entry create(LootTableManager lootTableManager, String name, List<Condition> conditions, List<LootTable.Entry> children, boolean expand, List<LootTableFunction> functions, int weight, int quality) {
|
|
||||||
return new AlternativesEntry(this, children, weight, quality, conditions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AnotherLootTableEntry extends LootTable.Entry {
|
|
||||||
private final LootTable table;
|
|
||||||
|
|
||||||
public AnotherLootTableEntry(AnotherLootTableType type, LootTable table, int weight, int quality, List<Condition> conditions) {
|
|
||||||
super(type, weight, quality, conditions);
|
|
||||||
this.table = table;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate(List<ItemStack> output, Data arguments) {
|
|
||||||
output.addAll(table.generate(arguments));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableEntryType;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableFunction;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows to sample from a different loot table
|
|
||||||
*
|
|
||||||
* minecraft:loot_table
|
|
||||||
*/
|
|
||||||
public class AnotherLootTableType implements LootTableEntryType {
|
|
||||||
@Override
|
|
||||||
public LootTable.Entry create(LootTableManager lootTableManager, String name, List<Condition> conditions, List<LootTable.Entry> children, boolean expand, List<LootTableFunction> functions, int weight, int quality) {
|
|
||||||
try {
|
|
||||||
return new AnotherLootTableEntry(this, lootTableManager.load(NamespaceID.from(name)), weight, quality, conditions);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
throw new IllegalArgumentException(name+" is not a valid loot table name", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class DynamicEntry extends LootTable.Entry {
|
|
||||||
|
|
||||||
public static final String DROP_LIST_KEY = "minestom:loot_table_drop_list";
|
|
||||||
|
|
||||||
private final DynamicEntry.Type entryType;
|
|
||||||
|
|
||||||
public DynamicEntry(DynamicType type, DynamicEntry.Type entryType, int weight, int quality, List<Condition> conditions) {
|
|
||||||
super(type, weight, quality, conditions);
|
|
||||||
this.entryType = entryType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate(List<ItemStack> output, Data arguments) {
|
|
||||||
List<ItemStack> toDrop = arguments.getOrDefault(DROP_LIST_KEY, Collections.emptyList());
|
|
||||||
output.addAll(toDrop);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicEntry.Type getEntryType() {
|
|
||||||
return entryType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Type {
|
|
||||||
SELF,
|
|
||||||
CONTENTS
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableEntryType;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableFunction;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* minecraft:dynamic
|
|
||||||
*/
|
|
||||||
public class DynamicType implements LootTableEntryType {
|
|
||||||
@Override
|
|
||||||
public LootTable.Entry create(LootTableManager lootTableManager, String name, List<Condition> conditions, List<LootTable.Entry> children, boolean expand, List<LootTableFunction> functions, int weight, int quality) {
|
|
||||||
return new DynamicEntry(this, DynamicEntry.Type.valueOf(name.toUpperCase()), weight, quality, conditions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class GroupEntry extends LootTable.Entry {
|
|
||||||
private final List<LootTable.Entry> children;
|
|
||||||
|
|
||||||
public GroupEntry(GroupType type, List<LootTable.Entry> children, int weight, int quality, List<Condition> conditions) {
|
|
||||||
super(type, weight, quality, conditions);
|
|
||||||
this.children = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate(List<ItemStack> output, Data arguments) {
|
|
||||||
for (LootTable.Entry child : children) {
|
|
||||||
child.generateStacks(output, arguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableEntryType;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableFunction;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* minecraft:group
|
|
||||||
*/
|
|
||||||
public class GroupType implements LootTableEntryType {
|
|
||||||
@Override
|
|
||||||
public LootTable.Entry create(LootTableManager lootTableManager, String name, List<Condition> conditions, List<LootTable.Entry> children, boolean expand, List<LootTableFunction> functions, int weight, int quality) {
|
|
||||||
return new GroupEntry(this, children, weight, quality, conditions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableFunction;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.item.Material;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ItemEntry extends LootTable.Entry {
|
|
||||||
|
|
||||||
private final List<LootTableFunction> functions;
|
|
||||||
private final Material item;
|
|
||||||
|
|
||||||
ItemEntry(ItemType type, Material baseItem, int weight, int quality, List<LootTableFunction> functions, List<Condition> conditions) {
|
|
||||||
super(type, weight, quality, conditions);
|
|
||||||
this.item = baseItem;
|
|
||||||
this.functions = new LinkedList<>(functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate(List<ItemStack> output, Data arguments) {
|
|
||||||
ItemStack stack = ItemStack.of(item);
|
|
||||||
for (LootTableFunction function : functions) {
|
|
||||||
stack = function.apply(stack, arguments);
|
|
||||||
}
|
|
||||||
if (!stack.isAir()) {
|
|
||||||
output.add(stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<LootTableFunction> getFunctions() {
|
|
||||||
return functions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Material getItem() {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableEntryType;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableFunction;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
import net.minestom.server.item.Material;
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* minecraft:item
|
|
||||||
*/
|
|
||||||
public class ItemType implements LootTableEntryType {
|
|
||||||
@Override
|
|
||||||
public LootTable.Entry create(LootTableManager lootTableManager, String name, List<Condition> conditions, List<LootTable.Entry> children, boolean expand, List<LootTableFunction> functions, int weight, int quality) {
|
|
||||||
NamespaceID itemID = NamespaceID.from(name);
|
|
||||||
return new ItemEntry(this, Material.fromNamespaceId(itemID), weight, quality, functions, conditions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SequenceEntry extends LootTable.Entry {
|
|
||||||
private final List<LootTable.Entry> children;
|
|
||||||
|
|
||||||
public SequenceEntry(SequenceType type, List<LootTable.Entry> children, int weight, int quality, List<Condition> conditions) {
|
|
||||||
super(type, weight, quality, conditions);
|
|
||||||
this.children = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate(List<ItemStack> output, Data arguments) {
|
|
||||||
for (LootTable.Entry c : children) {
|
|
||||||
int previousSize = output.size();
|
|
||||||
c.generateStacks(output, arguments);
|
|
||||||
int newSize = output.size();
|
|
||||||
if (newSize == previousSize) { // an entry failed to generate, stop here
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableEntryType;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableFunction;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* minecraft:sequence
|
|
||||||
*/
|
|
||||||
public class SequenceType implements LootTableEntryType {
|
|
||||||
@Override
|
|
||||||
public LootTable.Entry create(LootTableManager lootTableManager, String name, List<Condition> conditions, List<LootTable.Entry> children, boolean expand, List<LootTableFunction> functions, int weight, int quality) {
|
|
||||||
return new SequenceEntry(this, children, weight, quality, conditions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.tags.Tag;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.item.Material;
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class TagEntry extends LootTable.Entry {
|
|
||||||
private final Tag tag;
|
|
||||||
private final boolean expand;
|
|
||||||
private Random rng = new Random();
|
|
||||||
|
|
||||||
TagEntry(TagType type, Tag tag, boolean expand, int weight, int quality, List<Condition> conditions) {
|
|
||||||
super(type, weight, quality, conditions);
|
|
||||||
this.tag = tag;
|
|
||||||
this.expand = expand;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate(List<ItemStack> output, Data arguments) {
|
|
||||||
Set<NamespaceID> values = tag.getValues();
|
|
||||||
if (values.isEmpty())
|
|
||||||
return;
|
|
||||||
Material[] asArrayOfItems = new Material[values.size()];
|
|
||||||
int ptr = 0;
|
|
||||||
for (NamespaceID id : values) {
|
|
||||||
asArrayOfItems[ptr++] = Material.fromNamespaceId(id);
|
|
||||||
}
|
|
||||||
if (expand) {
|
|
||||||
Material selectedMaterial = asArrayOfItems[rng.nextInt(asArrayOfItems.length)];
|
|
||||||
output.add(ItemStack.of(selectedMaterial));
|
|
||||||
} else {
|
|
||||||
for (Material material : asArrayOfItems) {
|
|
||||||
output.add(ItemStack.of(material));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.entries;
|
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.gamedata.Condition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableEntryType;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableFunction;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
import net.minestom.server.gamedata.tags.Tag;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* minecraft:tag
|
|
||||||
*/
|
|
||||||
public class TagType implements LootTableEntryType {
|
|
||||||
@Override
|
|
||||||
public LootTable.Entry create(LootTableManager lootTableManager, String name, List<Condition> conditions, List<LootTable.Entry> children, boolean expand, List<LootTableFunction> functions, int weight, int quality) {
|
|
||||||
return new TagEntry(this, MinecraftServer.getTagManager().getTag(Tag.BasicType.ITEMS, name), expand, weight, quality, conditions);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
package net.minestom.server.gamedata.loottables.tabletypes;
|
|
||||||
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableType;
|
|
||||||
|
|
||||||
public class BlockType implements LootTableType {
|
|
||||||
}
|
|
@ -1,140 +0,0 @@
|
|||||||
package loottables;
|
|
||||||
|
|
||||||
import net.minestom.server.data.Data;
|
|
||||||
import net.minestom.server.data.DataImpl;
|
|
||||||
import net.minestom.server.gamedata.conditions.SurvivesExplosionCondition;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTable;
|
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
|
||||||
import net.minestom.server.gamedata.loottables.entries.ItemEntry;
|
|
||||||
import net.minestom.server.gamedata.loottables.entries.ItemType;
|
|
||||||
import net.minestom.server.gamedata.loottables.tabletypes.BlockType;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.item.Material;
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TestLootTables {
|
|
||||||
|
|
||||||
private LootTableManager tableManager;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void init() {
|
|
||||||
tableManager = new LootTableManager();
|
|
||||||
tableManager.registerConditionDeserializer(NamespaceID.from("minecraft:survives_explosion"), new SurvivesExplosionCondition.Deserializer());
|
|
||||||
tableManager.registerTableType(NamespaceID.from("minecraft:block"), new BlockType());
|
|
||||||
tableManager.registerEntryType(NamespaceID.from("minecraft:item"), new ItemType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void loadFromString() {
|
|
||||||
// from acacia_button.json
|
|
||||||
final String lootTableJson = "{\n" +
|
|
||||||
" \"type\": \"minecraft:block\",\n" +
|
|
||||||
" \"pools\": [\n" +
|
|
||||||
" {\n" +
|
|
||||||
" \"rolls\": 1,\n" +
|
|
||||||
" \"entries\": [\n" +
|
|
||||||
" {\n" +
|
|
||||||
" \"type\": \"minecraft:item\",\n" +
|
|
||||||
" \"name\": \"minecraft:acacia_button\"\n" +
|
|
||||||
" }\n" +
|
|
||||||
" ],\n" +
|
|
||||||
" \"conditions\": [\n" +
|
|
||||||
" {\n" +
|
|
||||||
" \"condition\": \"minecraft:survives_explosion\"\n" +
|
|
||||||
" }\n" +
|
|
||||||
" ]\n" +
|
|
||||||
" }\n" +
|
|
||||||
" ]\n" +
|
|
||||||
"}";
|
|
||||||
LootTable lootTable = tableManager.load(NamespaceID.from("blocks/acacia_button"), new StringReader(lootTableJson));
|
|
||||||
Assertions.assertTrue(lootTable.getType() instanceof BlockType);
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().size());
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().get(0).getMinRollCount());
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().get(0).getMaxRollCount());
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().get(0).getEntries().size());
|
|
||||||
Assertions.assertTrue(lootTable.getPools().get(0).getEntries().get(0).getType() instanceof ItemType);
|
|
||||||
Assertions.assertTrue(lootTable.getPools().get(0).getEntries().get(0) instanceof ItemEntry);
|
|
||||||
ItemEntry entry = (ItemEntry) lootTable.getPools().get(0).getEntries().get(0);
|
|
||||||
Assertions.assertEquals(Material.ACACIA_BUTTON, entry.getItem());
|
|
||||||
Assertions.assertEquals(0, entry.getFunctions().size());
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().get(0).getConditions().size());
|
|
||||||
Assertions.assertTrue(lootTable.getPools().get(0).getConditions().get(0) instanceof SurvivesExplosionCondition);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void loadFromFile() throws FileNotFoundException {
|
|
||||||
LootTable lootTable = tableManager.load(NamespaceID.from("blocks/acacia_button"));
|
|
||||||
Assertions.assertTrue(lootTable.getType() instanceof BlockType);
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().size());
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().get(0).getMinRollCount());
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().get(0).getMaxRollCount());
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().get(0).getEntries().size());
|
|
||||||
Assertions.assertTrue(lootTable.getPools().get(0).getEntries().get(0).getType() instanceof ItemType);
|
|
||||||
Assertions.assertTrue(lootTable.getPools().get(0).getEntries().get(0) instanceof ItemEntry);
|
|
||||||
ItemEntry entry = (ItemEntry) lootTable.getPools().get(0).getEntries().get(0);
|
|
||||||
Assertions.assertEquals(Material.ACACIA_BUTTON, entry.getItem());
|
|
||||||
Assertions.assertEquals(0, entry.getFunctions().size());
|
|
||||||
Assertions.assertEquals(1, lootTable.getPools().get(0).getConditions().size());
|
|
||||||
Assertions.assertTrue(lootTable.getPools().get(0).getConditions().get(0) instanceof SurvivesExplosionCondition);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void caching() throws FileNotFoundException {
|
|
||||||
LootTable lootTable1 = tableManager.load(NamespaceID.from("blocks/acacia_button"));
|
|
||||||
LootTable lootTable2 = tableManager.load(NamespaceID.from("blocks/acacia_button"));
|
|
||||||
Assertions.assertSame(lootTable1, lootTable2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void simpleGenerate() throws FileNotFoundException {
|
|
||||||
LootTable lootTable = tableManager.load(NamespaceID.from("blocks/acacia_button"));
|
|
||||||
Data arguments = new DataImpl();
|
|
||||||
List<ItemStack> stacks = lootTable.generate(arguments);
|
|
||||||
Assertions.assertEquals(1, stacks.size());
|
|
||||||
Assertions.assertEquals(Material.ACACIA_BUTTON, stacks.get(0).getMaterial());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExplosion() throws FileNotFoundException {
|
|
||||||
LootTable lootTable = tableManager.load(NamespaceID.from("blocks/acacia_button"));
|
|
||||||
Data arguments = new DataImpl();
|
|
||||||
// negative value will force the condition to fail
|
|
||||||
arguments.set("explosionPower", -1.0, Double.class);
|
|
||||||
List<ItemStack> stacks = lootTable.generate(arguments);
|
|
||||||
Assertions.assertEquals(0, stacks.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void unknownCondition() {
|
|
||||||
// from acacia_button.json
|
|
||||||
final String lootTableJson = "{\n" +
|
|
||||||
" \"type\": \"minecraft:block\",\n" +
|
|
||||||
" \"pools\": [\n" +
|
|
||||||
" {\n" +
|
|
||||||
" \"rolls\": 1,\n" +
|
|
||||||
" \"entries\": [\n" +
|
|
||||||
" {\n" +
|
|
||||||
" \"type\": \"minecraft:item\",\n" +
|
|
||||||
" \"name\": \"minecraft:acacia_button\"\n" +
|
|
||||||
" }\n" +
|
|
||||||
" ],\n" +
|
|
||||||
" \"conditions\": [\n" +
|
|
||||||
" {\n" +
|
|
||||||
" \"condition\": \"minestom:unknown\"\n" +
|
|
||||||
" }\n" +
|
|
||||||
" ]\n" +
|
|
||||||
" }\n" +
|
|
||||||
" ]\n" +
|
|
||||||
"}";
|
|
||||||
LootTable lootTable = tableManager.load(NamespaceID.from("blocks/none"), new StringReader(lootTableJson));
|
|
||||||
List<ItemStack> stacks = lootTable.generate(Data.EMPTY);
|
|
||||||
Assertions.assertEquals(0, stacks.size());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user