Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

Commit

Permalink
Split math expressions into Arithmetica
Browse files Browse the repository at this point in the history
Add `cmd:arithmetica` brigadier command.
Add `commander:arithmetica` loot number provider.
Add `commander:print_arithmetica` event command.
Narrow down selector context to just loot.
  • Loading branch information
melontini committed Apr 2, 2024
1 parent e43e597 commit aaf9bf6
Show file tree
Hide file tree
Showing 16 changed files with 300 additions and 42 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ dependencies {
implementation include("net.objecthunter:exp4j:${project.exp4j_version}")
}

loom {
accessWidenerPath = file("src/main/resources/commander.accesswidener")
}

processResources {
inputs.property "version", project.version
inputs.property "minecraft_version", project.minecraft_version
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/me/melontini/commander/Commander.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@
import me.melontini.commander.builtin.BuiltInEvents;
import me.melontini.commander.builtin.BuiltInSelectors;
import me.melontini.commander.data.DynamicEventManager;
import me.melontini.commander.util.math.ArithmeticaLootNumberProvider;
import me.melontini.dark_matter.api.base.util.PrependingLogger;
import me.melontini.dark_matter.api.data.loading.ServerReloadersEvent;
import net.fabricmc.api.ModInitializer;
import net.minecraft.loot.provider.number.LootNumberProviderType;
import net.minecraft.loot.provider.number.LootNumberProviderTypes;
import net.minecraft.util.Identifier;

//TODO:
// Better validation during `apply`
// Scoreboard fields
public class Commander implements ModInitializer {

public static final PrependingLogger LOGGER = PrependingLogger.get();
public static final LootNumberProviderType ARITHMETICA_PROVIDER = LootNumberProviderTypes.register("commander:arithmetica", new ArithmeticaLootNumberProvider.Serializer());;

public static Identifier id(String path) {
return new Identifier("commander", path);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.melontini.commander.builtin;

import lombok.experimental.UtilityClass;
import me.melontini.commander.builtin.brigadier.ArithmeticaCommand;
import me.melontini.commander.builtin.brigadier.ExplodeCommand;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;

Expand All @@ -10,6 +11,7 @@ public class BrigadierCommands {
public static void init() {
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
ExplodeCommand.register(dispatcher);
ArithmeticaCommand.register(dispatcher);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.experimental.UtilityClass;
import me.melontini.commander.builtin.commands.action.CancelCommand;
import me.melontini.commander.builtin.commands.action.CommandCommand;
import me.melontini.commander.builtin.commands.action.PrintArithmetica;
import me.melontini.commander.builtin.commands.action.PrintCommand;
import me.melontini.commander.builtin.commands.logic.AllOfCommand;
import me.melontini.commander.builtin.commands.logic.AnyOfCommand;
Expand All @@ -24,6 +25,7 @@ public class BuiltInCommands {
public static final CommandType CANCEL = CommandType.register(id("cancel"), CancelCommand.CODEC);
public static final CommandType COMMANDS = CommandType.register(id("commands"), CommandCommand.CODEC);
public static final CommandType PRINT = CommandType.register(id("print"), PrintCommand.CODEC);
public static final CommandType PRINT_ARITHMETICA = CommandType.register(id("print_arithmetica"), PrintArithmetica.CODEC);

public static void init() {
BrigadierCommands.init();
Expand Down
26 changes: 13 additions & 13 deletions src/main/java/me/melontini/commander/builtin/BuiltInSelectors.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,37 @@
@SuppressWarnings("unused")
public final class BuiltInSelectors {

public static final Selector SERVER = Selector.register(mc("server"), context -> context.lootContext().getWorld().getServer().getCommandSource());
public static final Selector SERVER = Selector.register(mc("server"), context -> context.getWorld().getServer().getCommandSource());
public static final Selector ORIGIN = Selector.register(mc("origin"), context -> {
var world = context.lootContext().getWorld();
var o = context.lootContext().requireParameter(LootContextParameters.ORIGIN);
var world = context.getWorld();
var o = context.requireParameter(LootContextParameters.ORIGIN);

return new ServerCommandSource(world.getServer(), o, Vec2f.ZERO,
world, 4, world.getRegistryKey().getValue().toString(), TextUtil.literal(world.getRegistryKey().getValue().toString()),
world.getServer(), null);
});
public static final Selector THIS_ENTITY = Selector.register(mc("this_entity"), context -> forEntity(context.lootContext().requireParameter(LootContextParameters.THIS_ENTITY)), MacroBuilder.forEntity());
public static final Selector KILLER_ENTITY = Selector.register(mc("killer_entity"), context -> forEntity(context.lootContext().requireParameter(LootContextParameters.KILLER_ENTITY)), MacroBuilder.forEntity());
public static final Selector DIRECT_KILLER_ENTITY = Selector.register(mc("direct_killer_entity"), context -> forEntity(context.lootContext().requireParameter(LootContextParameters.DIRECT_KILLER_ENTITY)), MacroBuilder.forEntity());
public static final Selector LAST_DAMAGE_PLAYER = Selector.register(mc("last_damage_player"), context -> forEntity(context.lootContext().requireParameter(LootContextParameters.LAST_DAMAGE_PLAYER)), MacroBuilder.forEntity());
public static final Selector THIS_ENTITY = Selector.register(mc("this_entity"), context -> forEntity(context.requireParameter(LootContextParameters.THIS_ENTITY)), MacroBuilder.forEntity());
public static final Selector KILLER_ENTITY = Selector.register(mc("killer_entity"), context -> forEntity(context.requireParameter(LootContextParameters.KILLER_ENTITY)), MacroBuilder.forEntity());
public static final Selector DIRECT_KILLER_ENTITY = Selector.register(mc("direct_killer_entity"), context -> forEntity(context.requireParameter(LootContextParameters.DIRECT_KILLER_ENTITY)), MacroBuilder.forEntity());
public static final Selector LAST_DAMAGE_PLAYER = Selector.register(mc("last_damage_player"), context -> forEntity(context.requireParameter(LootContextParameters.LAST_DAMAGE_PLAYER)), MacroBuilder.forEntity());
public static final Selector BLOCK_ENTITY = Selector.register(mc("block_entity"), context -> {
var be = context.lootContext().requireParameter(LootContextParameters.BLOCK_ENTITY);
return new ServerCommandSource(context.lootContext().getWorld().getServer(), Vec3d.ofCenter(be.getPos()), Vec2f.ZERO,
var be = context.requireParameter(LootContextParameters.BLOCK_ENTITY);
return new ServerCommandSource(context.getWorld().getServer(), Vec3d.ofCenter(be.getPos()), Vec2f.ZERO,
(ServerWorld) be.getWorld(), 4, "BlockEntity", TextUtil.literal("BlockEntity"),
context.lootContext().getWorld().getServer(), null);
context.getWorld().getServer(), null);
});

public static final Selector DAMAGE_SOURCE_SOURCE = Selector.register(id("damage_source/source"), context -> {
var s = context.lootContext().requireParameter(LootContextParameters.DAMAGE_SOURCE).getSource();
var s = context.requireParameter(LootContextParameters.DAMAGE_SOURCE).getSource();
return s != null ? forEntity(s) : null;
}, MacroBuilder.forEntity());
public static final Selector DAMAGE_SOURCE_ATTACKER = Selector.register(id("damage_source/attacker"), context -> {
var s = context.lootContext().requireParameter(LootContextParameters.DAMAGE_SOURCE).getAttacker();
var s = context.requireParameter(LootContextParameters.DAMAGE_SOURCE).getAttacker();
return s != null ? forEntity(s) : null;
}, MacroBuilder.forEntity());

public static final Selector RANDOM_PLAYER = Selector.register(id("random_player"), context -> {
var l = context.lootContext().getWorld().getServer().getPlayerManager().getPlayerList();
var l = context.getWorld().getServer().getPlayerManager().getPlayerList();
if (l == null || l.isEmpty()) return null;
return forEntity(Utilities.pickAtRandom(l));
}, MacroBuilder.forEntity());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package me.melontini.commander.builtin.brigadier;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.datafixers.util.Either;
import me.melontini.commander.Commander;
import me.melontini.commander.util.macro.PatternParser;
import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.context.LootContextParameterSet;
import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.loot.context.LootContextTypes;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;

public class ArithmeticaCommand {

public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(CommandManager.literal("cmd:arithmetica")
.then(CommandManager.argument("expression", StringArgumentType.string())
.executes(context -> {
try {
String expression = StringArgumentType.getString(context, "expression");

var r = PatternParser.parseArithmetica(Either.right(expression));
if (r.error().isPresent()) {
context.getSource().sendError(Text.literal(r.error().get().message()));
return 0;
}
LootContext context1 = new LootContext.Builder(new LootContextParameterSet.Builder(context.getSource().getWorld())
.add(LootContextParameters.ORIGIN, context.getSource().getPosition())
.addOptional(LootContextParameters.THIS_ENTITY, context.getSource().getEntity())
.build(LootContextTypes.COMMAND)).build(null);

context.getSource().sendMessage(Text.literal(String.valueOf(r.result().orElseThrow().asDouble(context1))));
return 1;
} catch (Throwable t) {
Commander.LOGGER.error(t);
throw t;
}
})));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package me.melontini.commander.builtin.commands.action;

import com.mojang.serialization.Codec;
import me.melontini.commander.builtin.BuiltInCommands;
import me.melontini.commander.command.Command;
import me.melontini.commander.command.CommandType;
import me.melontini.commander.event.EventContext;
import me.melontini.commander.util.math.Arithmetica;

public record PrintArithmetica(Arithmetica arithmetica) implements Command {

public static final Codec<PrintArithmetica> CODEC = Arithmetica.CODEC.xmap(PrintArithmetica::new, PrintArithmetica::arithmetica).fieldOf("arithmetica").codec();

@Override
public boolean execute(EventContext context) {
System.out.println(arithmetica().apply(context.lootContext()));
return true;
}

@Override
public CommandType type() {
return BuiltInCommands.PRINT_ARITHMETICA;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public record ConditionedSelector(Optional<LootCondition> condition, Selector ot
).apply(data, ConditionedSelector::new)), SelectorTypes.CODEC).xmap(e -> e.map(Function.identity(), selector -> new ConditionedSelector(Optional.empty(), selector)), Either::left);

public Optional<ServerCommandSource> select(EventContext context) {
var source = other.select(context);
var source = other.select(context.lootContext());
if (source == null) return Optional.empty();
if (condition.isEmpty()) return Optional.of(source);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package me.melontini.commander.command.selector;

import me.melontini.commander.data.types.SelectorTypes;
import me.melontini.commander.event.EventContext;
import net.minecraft.loot.context.LootContext;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
Expand All @@ -18,5 +18,5 @@ static Selector register(Identifier identifier, Selector selector, Consumer<Macr
return SelectorTypes.register(identifier, selector, extractors);
}

@Nullable ServerCommandSource select(EventContext context);
@Nullable ServerCommandSource select(LootContext context);
}
33 changes: 33 additions & 0 deletions src/main/java/me/melontini/commander/util/StdFunctions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package me.melontini.commander.util;

import com.google.common.collect.ImmutableSet;
import me.melontini.dark_matter.api.base.util.MathUtil;
import net.minecraft.util.math.MathHelper;
import net.objecthunter.exp4j.function.Function;

import java.util.Set;

public class StdFunctions {

public static final Set<Function> FUNCTIONS = ImmutableSet.<Function>builder()
.add(func("round", 1, args -> Math.round(args[0])))
.add(func("random", 2, args -> MathUtil.nextDouble(args[0], args[1])))
.add(func("clamp", 3, args -> MathHelper.clamp(args[0], args[1], args[2])))
.add(func("min", 2, args -> Math.min(args[0], args[1])))
.add(func("max", 2, args -> Math.max(args[0], args[1])))
.add(func("lerp", 3, args -> MathHelper.lerp(args[0], args[1], args[2])))
.build();

private static Function func(String name, int args, Calc calc) {
return new Function(name, args) {
@Override
public double apply(double... args) {
return calc.calc(args);
}
};
}

private interface Calc {
double calc(double... args);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package me.melontini.commander.util.macro;

import me.melontini.commander.event.EventContext;
import net.minecraft.loot.context.LootContext;

import java.util.function.Function;

public record DynamicMacro(String original, Function<EventContext, StringBuilder> start) implements BrigadierMacro {
public record DynamicMacro(String original, Function<LootContext, StringBuilder> start) implements BrigadierMacro {

public String build(EventContext context) {
return start.apply(context).toString();
return start.apply(context.lootContext()).toString();
}
}
Loading

0 comments on commit aaf9bf6

Please sign in to comment.