diff --git a/src/main/java/net/minestom/server/gamedata/conditions/SurvivesExplosionCondition.java b/src/main/java/net/minestom/server/gamedata/conditions/SurvivesExplosionCondition.java index 2dc0080b0..84f087165 100644 --- a/src/main/java/net/minestom/server/gamedata/conditions/SurvivesExplosionCondition.java +++ b/src/main/java/net/minestom/server/gamedata/conditions/SurvivesExplosionCondition.java @@ -1,8 +1,13 @@ 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; /** @@ -19,4 +24,11 @@ public class SurvivesExplosionCondition implements Condition { return true; // no explosion here return rng.nextDouble() <= 1.0/data.get("explosionPower"); } + + public static class Deserializer implements JsonDeserializer { + @Override + public SurvivesExplosionCondition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + return new SurvivesExplosionCondition(); + } + } } diff --git a/src/main/java/net/minestom/server/gamedata/loottables/ConditionContainer.java b/src/main/java/net/minestom/server/gamedata/loottables/ConditionContainer.java new file mode 100644 index 000000000..8d23962a5 --- /dev/null +++ b/src/main/java/net/minestom/server/gamedata/loottables/ConditionContainer.java @@ -0,0 +1,36 @@ +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 { + + 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 deserializer = lootTableManager.getConditionDeserializer(NamespaceID.from(type)); + return new ConditionContainer() { + @Override + public Condition create(LootTableManager lootTableManager) { + return deserializer.deserialize(obj, typeOfT, context); + } + }; + } + } +} diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTableContainer.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTableContainer.java index 2149a1a78..c2f9ff04c 100644 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTableContainer.java +++ b/src/main/java/net/minestom/server/gamedata/loottables/LootTableContainer.java @@ -95,16 +95,6 @@ class LootTableContainer { } } - private class ConditionContainer { - private String condition; - - private ConditionContainer() {} - - public Condition create(LootTableManager lootTableManager) { - return lootTableManager.getCondition(NamespaceID.from(condition)); - } - } - private class FunctionContainer { private String function; private ConditionContainer[] conditions; diff --git a/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java b/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java index 2580b78bc..769c6b30c 100644 --- a/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java +++ b/src/main/java/net/minestom/server/gamedata/loottables/LootTableManager.java @@ -2,6 +2,7 @@ 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.gamedata.Condition; import net.minestom.server.registry.ResourceGatherer; import net.minestom.server.utils.NamespaceID; @@ -14,26 +15,27 @@ import java.io.*; */ public class LootTableManager { - private NamespaceIDHashMap conditions = new NamespaceIDHashMap<>(); + private NamespaceIDHashMap> conditionDeserializers = new NamespaceIDHashMap<>(); private NamespaceIDHashMap tableTypes = new NamespaceIDHashMap<>(); private NamespaceIDHashMap entryTypes = new NamespaceIDHashMap<>(); private NamespaceIDHashMap functions = new NamespaceIDHashMap<>(); private NamespaceIDHashMap cache = new NamespaceIDHashMap<>(); - private static Gson gson; + private Gson gson; - static { + public LootTableManager() { gson = new GsonBuilder() .registerTypeAdapter(RangeContainer.class, new RangeContainer.Deserializer()) + .registerTypeAdapter(ConditionContainer.class, new ConditionContainer.Deserializer(this)) .create(); } /** - * Registers a condition to the given namespaceID + * Registers a condition factory to the given namespaceID * @param namespaceID - * @param condition + * @param factory */ - public void registerCondition(NamespaceID namespaceID, Condition condition) { - conditions.put(namespaceID, condition); + public void registerConditionDeserializer(NamespaceID namespaceID, JsonDeserializer factory) { + conditionDeserializers.put(namespaceID, factory); } /** @@ -88,15 +90,6 @@ public class LootTableManager { return container.createTable(this); } - /** - * Returns the registered condition corresponding to the given namespace ID. If none is registered, returns {@link Condition#ALWAYS_NO}. - * @param id - * @return - */ - public Condition getCondition(NamespaceID id) { - return conditions.getOrDefault(id, Condition.ALWAYS_NO); - } - /** * Returns the registered table type corresponding to the given namespace ID. If none is registered, throws {@link IllegalArgumentException} * @param id @@ -127,4 +120,8 @@ public class LootTableManager { public LootTableFunction getFunction(NamespaceID id) { return functions.getOrDefault(id, LootTableFunction.IDENTITY); } + + public JsonDeserializer getConditionDeserializer(NamespaceID id) { + return conditionDeserializers.getOrDefault(id, (json, typeOfT, context) -> Condition.ALWAYS_NO); + } } diff --git a/src/main/java/net/minestom/server/utils/Position.java b/src/main/java/net/minestom/server/utils/Position.java index 7617545eb..51600f378 100644 --- a/src/main/java/net/minestom/server/utils/Position.java +++ b/src/main/java/net/minestom/server/utils/Position.java @@ -95,6 +95,20 @@ public class Position { return this; } + public void copy(Vector position) { + this.x = position.getX(); + this.y = position.getY(); + this.z = position.getZ(); + } + + public void copy(Position position) { + this.x = position.getX(); + this.y = position.getY(); + this.z = position.getZ(); + this.yaw = position.getYaw(); + this.pitch = position.getPitch(); + } + public Position clone() { return new Position(getX(), getY(), getZ(), getYaw(), getPitch()); } diff --git a/src/test/java/loottables/TestLootTables.java b/src/test/java/loottables/TestLootTables.java index e7d459eb9..ef61a7a2d 100644 --- a/src/test/java/loottables/TestLootTables.java +++ b/src/test/java/loottables/TestLootTables.java @@ -28,7 +28,7 @@ public class TestLootTables { RegistryMain.registerBlocks(); RegistryMain.registerItems(); tableManager = new LootTableManager(); - tableManager.registerCondition(NamespaceID.from("minecraft:survives_explosion"), new SurvivesExplosionCondition()); + 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()); }