From 39c1230f2a8d509fd86d79812c0091eaa10a5260 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Wed, 17 Apr 2024 18:53:58 +0700 Subject: [PATCH] Add ExpressionLootCondition --- .../melontini/commander/impl/Commander.java | 7 +++++- .../commander/impl/util/eval/EvalUtils.java | 10 +++++--- .../ArithmeticaLootNumberProvider.java | 2 +- .../util/loot/ExpressionLootCondition.java | 25 +++++++++++++++++++ .../impl/util/macro/PatternParser.java | 2 +- 5 files changed, 40 insertions(+), 6 deletions(-) rename src/main/java/me/melontini/commander/impl/util/{ => loot}/ArithmeticaLootNumberProvider.java (93%) create mode 100644 src/main/java/me/melontini/commander/impl/util/loot/ExpressionLootCondition.java diff --git a/src/main/java/me/melontini/commander/impl/Commander.java b/src/main/java/me/melontini/commander/impl/Commander.java index 96c2f88..8449140 100644 --- a/src/main/java/me/melontini/commander/impl/Commander.java +++ b/src/main/java/me/melontini/commander/impl/Commander.java @@ -10,8 +10,9 @@ import me.melontini.commander.impl.builtin.BuiltInEvents; import me.melontini.commander.impl.builtin.BuiltInSelectors; import me.melontini.commander.impl.event.data.DynamicEventManager; -import me.melontini.commander.impl.util.ArithmeticaLootNumberProvider; import me.melontini.commander.impl.util.eval.EvalUtils; +import me.melontini.commander.impl.util.loot.ArithmeticaLootNumberProvider; +import me.melontini.commander.impl.util.loot.ExpressionLootCondition; import me.melontini.commander.impl.util.mappings.MappingKeeper; import me.melontini.commander.impl.util.mappings.MinecraftDownloader; import me.melontini.dark_matter.api.base.util.Exceptions; @@ -21,8 +22,11 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.mappingio.tree.MemoryMappingTree; +import net.minecraft.loot.condition.LootConditionType; import net.minecraft.loot.provider.number.LootNumberProviderType; import net.minecraft.loot.provider.number.LootNumberProviderTypes; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; import net.minecraft.util.Util; @@ -40,6 +44,7 @@ public class Commander implements ModInitializer { public static final PrependingLogger LOGGER = PrependingLogger.get(); public static final LootNumberProviderType ARITHMETICA_PROVIDER = LootNumberProviderTypes.register("commander:arithmetica", ExtraCodecs.toJsonSerializer(Arithmetica.CODEC.xmap(ArithmeticaLootNumberProvider::new, ArithmeticaLootNumberProvider::value))); + public static final LootConditionType EXPRESSION_CONDITION = Registry.register(Registries.LOOT_CONDITION_TYPE, id("expression"), new LootConditionType(ExtraCodecs.toJsonSerializer(ExpressionLootCondition.CODEC))); public static final Path COMMANDER_PATH = FabricLoader.getInstance().getGameDir().resolve(".commander"); public static final String MINECRAFT_VERSION = getVersion(); diff --git a/src/main/java/me/melontini/commander/impl/util/eval/EvalUtils.java b/src/main/java/me/melontini/commander/impl/util/eval/EvalUtils.java index 58fe399..f38ce39 100644 --- a/src/main/java/me/melontini/commander/impl/util/eval/EvalUtils.java +++ b/src/main/java/me/melontini/commander/impl/util/eval/EvalUtils.java @@ -130,14 +130,18 @@ public static EvaluationValue evaluate(LootContext context, Expression exp) { } public static DataResult parseEither(Either either) { - return either.map(d -> DataResult.success(Arithmetica.constant(d)), string -> parseExpression(string).map(func -> Arithmetica.of(context -> func.apply(context).getNumberValue().doubleValue(), string))); + return either.map(d -> DataResult.success(Arithmetica.constant(d)), string -> wrapExpression(parseExpression(string)).map(func -> Arithmetica.of(context -> func.apply(context).getNumberValue().doubleValue(), string))); } - public static DataResult> parseExpression(String expression) { + public static DataResult> wrapExpression(DataResult result) { + return result.map(expression -> context -> evaluate(context, expression)); + } + + public static DataResult parseExpression(String expression) { try { Expression exp = new Expression(expression.replace(":", "__idcl__"), CONFIGURATION); exp.validate(); - return DataResult.success(context -> evaluate(context, exp)); + return DataResult.success(exp); } catch (Throwable throwable) { return DataResult.error(throwable::getLocalizedMessage); } diff --git a/src/main/java/me/melontini/commander/impl/util/ArithmeticaLootNumberProvider.java b/src/main/java/me/melontini/commander/impl/util/loot/ArithmeticaLootNumberProvider.java similarity index 93% rename from src/main/java/me/melontini/commander/impl/util/ArithmeticaLootNumberProvider.java rename to src/main/java/me/melontini/commander/impl/util/loot/ArithmeticaLootNumberProvider.java index f4c5a04..585a1fc 100644 --- a/src/main/java/me/melontini/commander/impl/util/ArithmeticaLootNumberProvider.java +++ b/src/main/java/me/melontini/commander/impl/util/loot/ArithmeticaLootNumberProvider.java @@ -1,4 +1,4 @@ -package me.melontini.commander.impl.util; +package me.melontini.commander.impl.util.loot; import me.melontini.commander.api.expression.Arithmetica; import me.melontini.commander.impl.Commander; diff --git a/src/main/java/me/melontini/commander/impl/util/loot/ExpressionLootCondition.java b/src/main/java/me/melontini/commander/impl/util/loot/ExpressionLootCondition.java new file mode 100644 index 0000000..3c0eb7d --- /dev/null +++ b/src/main/java/me/melontini/commander/impl/util/loot/ExpressionLootCondition.java @@ -0,0 +1,25 @@ +package me.melontini.commander.impl.util.loot; + +import com.ezylang.evalex.Expression; +import com.mojang.serialization.Codec; +import me.melontini.commander.impl.Commander; +import me.melontini.commander.impl.util.eval.EvalUtils; +import net.minecraft.loot.condition.LootCondition; +import net.minecraft.loot.condition.LootConditionType; +import net.minecraft.loot.context.LootContext; + +public record ExpressionLootCondition(Expression expression) implements LootCondition { + public static final Codec CODEC = Codec.STRING + .comapFlatMap(EvalUtils::parseExpression, exp -> exp.getExpressionString().replace("__idcl__", ":")) + .xmap(ExpressionLootCondition::new, ExpressionLootCondition::expression); + + @Override + public LootConditionType getType() { + return Commander.EXPRESSION_CONDITION; + } + + @Override + public boolean test(LootContext context) { + return EvalUtils.evaluate(context, expression).getBooleanValue(); + } +} diff --git a/src/main/java/me/melontini/commander/impl/util/macro/PatternParser.java b/src/main/java/me/melontini/commander/impl/util/macro/PatternParser.java index 9586a3d..d07f38e 100644 --- a/src/main/java/me/melontini/commander/impl/util/macro/PatternParser.java +++ b/src/main/java/me/melontini/commander/impl/util/macro/PatternParser.java @@ -47,7 +47,7 @@ private static String sb(Consumer consumer) { } public static DataResult> parseExpression(String expression, String cast) { - var result = EvalUtils.parseExpression(expression); + var result = EvalUtils.wrapExpression(EvalUtils.parseExpression(expression)); if (cast != null) { return switch (cast) { case "long" -> result.map(function -> context -> String.valueOf(function.apply(context).getNumberValue().longValue()));