diff --git a/README.md b/README.md index 19004a8..80d1e05 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,13 @@ Applies env.json operations to Minecraft Vanilla data types. "type": "any", // passes if at least one rule passes "rule": [] // the rules }, + { + "type": "not", // reverses the rule + "rule": { // the rule + "type": "...", + "rule": "..." + } + }, { "type": "dimension", // passes if the current dimension matches this one "rule": "minecraft:overworld" // the dimension, can also be a tag diff --git a/src/main/java/fr/firstmegagame4/env/json/api/rule/EnvJsonRule.java b/src/main/java/fr/firstmegagame4/env/json/api/rule/EnvJsonRule.java index 4f68b56..c8dfadf 100644 --- a/src/main/java/fr/firstmegagame4/env/json/api/rule/EnvJsonRule.java +++ b/src/main/java/fr/firstmegagame4/env/json/api/rule/EnvJsonRule.java @@ -25,6 +25,11 @@ enum Type { */ ANY, + /** + * Reverses the rule. + */ + NOT, + /** * Represents a dimension rule where the object should be. */ diff --git a/src/main/java/fr/firstmegagame4/env/json/api/rule/NotEnvJsonRule.java b/src/main/java/fr/firstmegagame4/env/json/api/rule/NotEnvJsonRule.java new file mode 100644 index 0000000..4241c0d --- /dev/null +++ b/src/main/java/fr/firstmegagame4/env/json/api/rule/NotEnvJsonRule.java @@ -0,0 +1,6 @@ +package fr.firstmegagame4.env.json.api.rule; + +public interface NotEnvJsonRule extends EnvJsonRule { + + EnvJsonRule rule(); +} diff --git a/src/main/java/fr/firstmegagame4/env/json/impl/EnvJsonParser.java b/src/main/java/fr/firstmegagame4/env/json/impl/EnvJsonParser.java index 4d7c2e7..1699f19 100644 --- a/src/main/java/fr/firstmegagame4/env/json/impl/EnvJsonParser.java +++ b/src/main/java/fr/firstmegagame4/env/json/impl/EnvJsonParser.java @@ -51,6 +51,10 @@ private static AnyEnvJsonRule parseAnyRule(JsonArray list) { return new AnyEnvJsonRuleImpl(EnvJsonParser.parseRules(list)); } + private static NotEnvJsonRule parseNotRule(JsonObject rule) { + return new NotEnvJsonRuleImpl(EnvJsonParser.parseRule(EnvJsonRule.Type.valueOf(rule.get("type").getAsString().toUpperCase()), () -> rule.get("rule"))); + } + private static DimensionEnvJsonRule parseDimensionRule(String string) { if (string.startsWith("#")) { return new DimensionEnvJsonRuleImpl(EnvJsonUtils.tryParse(RegistryKeys.WORLD, string)); @@ -91,27 +95,28 @@ private static VoidEnvJsonRule parseVoidRule(String string) { return new VoidEnvJsonRuleImpl(VoidEnvJsonRule.Localization.valueOf(string.toUpperCase())); } + private static EnvJsonRule parseRule(EnvJsonRule.Type type, Supplier supplier) { + return switch (type) { + case SEQUENCE -> EnvJsonParser.parseSequenceRule(supplier.get().getAsJsonArray()); + case ANY -> EnvJsonParser.parseAnyRule(supplier.get().getAsJsonArray()); + case NOT -> EnvJsonParser.parseNotRule(supplier.get().getAsJsonObject()); + case DIMENSION -> EnvJsonParser.parseDimensionRule(supplier.get().getAsString()); + case BIOME -> EnvJsonParser.parseBiomeRule(supplier.get().getAsString()); + case X_COORD -> EnvJsonParser.parseCoordRule(CoordEnvJsonRule.Coord.X, supplier.get().getAsJsonObject()); + case Y_COORD -> EnvJsonParser.parseCoordRule(CoordEnvJsonRule.Coord.Y, supplier.get().getAsJsonObject()); + case Z_COORD -> EnvJsonParser.parseCoordRule(CoordEnvJsonRule.Coord.Z, supplier.get().getAsJsonObject()); + case SUBMERGED -> EnvJsonParser.parseSubmergedRule(supplier.get().getAsBoolean()); + case SKY -> EnvJsonParser.parseSkyRule(supplier.get().getAsString()); + case WATER -> EnvJsonParser.parseWaterRule(supplier.get().getAsString()); + case VOID -> EnvJsonParser.parseVoidRule(supplier.get().getAsString()); + }; + } + private static List parseRules(JsonArray array) { List rules = new ArrayList<>(); for (JsonElement element : array) { JsonObject rule = element.getAsJsonObject(); - EnvJsonRule.Type type = EnvJsonRule.Type.valueOf(rule.get("type").getAsString().toUpperCase()); - Supplier supplier = () -> rule.get("rule"); - rules.add( - switch (type) { - case SEQUENCE -> EnvJsonParser.parseSequenceRule(supplier.get().getAsJsonArray()); - case ANY -> EnvJsonParser.parseAnyRule(supplier.get().getAsJsonArray()); - case DIMENSION -> EnvJsonParser.parseDimensionRule(supplier.get().getAsString()); - case BIOME -> EnvJsonParser.parseBiomeRule(supplier.get().getAsString()); - case X_COORD -> EnvJsonParser.parseCoordRule(CoordEnvJsonRule.Coord.X, supplier.get().getAsJsonObject()); - case Y_COORD -> EnvJsonParser.parseCoordRule(CoordEnvJsonRule.Coord.Y, supplier.get().getAsJsonObject()); - case Z_COORD -> EnvJsonParser.parseCoordRule(CoordEnvJsonRule.Coord.Z, supplier.get().getAsJsonObject()); - case SUBMERGED -> EnvJsonParser.parseSubmergedRule(supplier.get().getAsBoolean()); - case SKY -> EnvJsonParser.parseSkyRule(supplier.get().getAsString()); - case WATER -> EnvJsonParser.parseWaterRule(supplier.get().getAsString()); - case VOID -> EnvJsonParser.parseVoidRule(supplier.get().getAsString()); - } - ); + rules.add(EnvJsonParser.parseRule(EnvJsonRule.Type.valueOf(rule.get("type").getAsString().toUpperCase()), () -> rule.get("rule"))); } return rules; } diff --git a/src/main/java/fr/firstmegagame4/env/json/impl/rule/NotEnvJsonRuleImpl.java b/src/main/java/fr/firstmegagame4/env/json/impl/rule/NotEnvJsonRuleImpl.java new file mode 100644 index 0000000..741dfb0 --- /dev/null +++ b/src/main/java/fr/firstmegagame4/env/json/impl/rule/NotEnvJsonRuleImpl.java @@ -0,0 +1,27 @@ +package fr.firstmegagame4.env.json.impl.rule; + +import fr.firstmegagame4.env.json.api.EnvJsonVisitor; +import fr.firstmegagame4.env.json.api.rule.EnvJsonRule; +import fr.firstmegagame4.env.json.api.rule.NotEnvJsonRule; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public class NotEnvJsonRuleImpl extends EnvJsonRuleImpl implements NotEnvJsonRule { + + private final EnvJsonRule rule; + + public NotEnvJsonRuleImpl(EnvJsonRule rule) { + super(Type.NOT); + this.rule = rule; + } + + @Override + public EnvJsonRule rule() { + return this.rule; + } + + @Override + public boolean apply(EnvJsonVisitor visitor) { + return !this.rule.apply(visitor); + } +}