Skip to content

Custom commands

Antoine Willerval edited this page Jan 6, 2020 · 1 revision

The mod can handle for you (good because forge can't), you only need to create an instance of ModdedCommand.

new ModdedCommand("mycommand") {};

To register it you need to use the method void fr.atesab.act.ATEMod#registerCommand(ModdedCommand command);

ACTMod.registerCommand(new ModdedCommand("mycommand") {});

A command can't be registered more than once.

Basic command

Basic command without argument

To add a non argument behavior by overriding the Command onNoArgument(); method that return a Brigadier Command to execute.

new ModdedCommand("hello") {
    @Override
    protected Command<CommandSource> onNoArgument() {
        return context -> {
            context.getSource().sendFeedback(createText("Hello", TextFormatting.LIGHT_PURPLE), false);
            return 1;
        };
    }
};

NB: here the ITextComponent ModdedCommand#createText(String text, TextFormatting color); method is used to easily create a Text Component for Minecraft.

Basic command with argument(s)

After if you want to add a behavior for arguments by overriding the protected LiteralArgumentBuilder onArgument(LiteralArgumentBuilder command); method, this method give you the Brigadier LiteralArgumentBuilder to add your argument(s).

new ModdedCommand("hello") {

    @Override
    protected LiteralArgumentBuilder<CommandSource> onArgument(LiteralArgumentBuilder<CommandSource> command) {
        return command.then(Commands.argument("myname", StringArgumentType.greedyString()).executes(context -> {
            context.getSource().sendFeedback(
                    createText("Hello ", TextFormatting.LIGHT_PURPLE).appendSibling(
                            createText(StringArgumentType.getString(context, "myname"), TextFormatting.AQUA)),
                    false);
            return 1;
        }));
    }
}

The command will take a String called myname and say Hello , the Minecraft method <T> RequiredArgumentBuilder<CommandSource, T> net.minecraft.command.Commands#argument(String name, ArgumentType<T> type); can be useful to create arguments without the <> operators.

Final code

Here the complete code.

new ModdedCommand("hello") {
    @Override
    protected Command<CommandSource> onNoArgument() {
        return context -> {
            context.getSource().sendFeedback(createText("Hello world", TextFormatting.LIGHT_PURPLE), false);
            return 1;
        };
    }

    @Override
    protected LiteralArgumentBuilder<CommandSource> onArgument(LiteralArgumentBuilder<CommandSource> command) {
        return command.then(Commands.argument("myname", StringArgumentType.greedyString()).executes(context -> {
            context.getSource().sendFeedback(
                    createText("Hello ", TextFormatting.LIGHT_PURPLE).appendSibling(
                            createText(StringArgumentType.getString(context, "myname"), TextFormatting.AQUA)),
                    false);
            return 1;
        }));
    }
};

Complexe node command

You may also want to create a node command, a command with sub/child-commands, the ModdedCommand also provide this with the method ModdedCommand registerSubCommand(ModdedCommand subCommand); and ModdedCommand registerDefaultSubCommand(ModdedCommand subCommand);. The start is the same as basic command but you need to add child after. I also recommand to not create an anonymous class for node command.

Register sub command

import fr.atesab.act.command.ModdedCommand;
import fr.atesab.act.command.ModdedCommandHelp;
import fr.atesab.act.command.ModdedCommandRandomFireWorks;

import net.minecraft.util.text.TextFormatting;

public class ModdedCommandMyNode extends ModdedCommand {

    public ModdedCommandMyNode() {
        super("mynode");
        registerDefaultSubCommand(new ModdedCommandHelp(this, "My node", 
                TextFormatting.DARK_AQUA, TextFormatting.AQUA, TextFormatting.WHITE));
        registerSubCommand(new ModdedCommandRandomFireWorks());
    }

}

The class ModdedCommandHelp is a good tool to create an help sub command for your node, you can customise the title and the colors of the command.

A child command is like a command and can't be registered more than once.

Better helped sub command

The class ModdedCommandHelp also read some information about the ModdedCommand added by calling the constructors ModdedCommand(String name, String description, ModdedCommandHelp.CommandClickOption clickOption); and ModdedCommand(String name, String description, ModdedCommandHelp.CommandClickOption clickOption, boolean displayInHelp);. The description is a translation key, the clickOption can be ModdedCommandHelp.CommandClickOption.doCommand or ModdedCommandHelp.CommandClickOption.suggestCommand to suggest or to do your command when clicking in the help command on it.

registerSubCommand(new ModdedCommand("hello", "mymod.cmd.hello", CommandClickOption.doCommand, true) {
    @Override
    protected Command<CommandSource> onNoArgument() {
        return c -> {
            c.getSource().sendFeedback(createText("Hello", TextFormatting.RED), false);
            return 1;
        };
    }
});

Final code

Here the complete code.

import net.minecraft.command.CommandSource;
import net.minecraft.util.text.TextFormatting;

import com.mojang.brigadier.Command;

import fr.atesab.act.command.ModdedCommandHelp;
import fr.atesab.act.command.ModdedCommandRandomFireWorks;
import fr.atesab.act.command.ModdedCommandHelp.CommandClickOption;

public class ModdedCommandMyNode extends ModdedCommand {

    public ModdedCommandMyNode() {
        super("mynode");
        registerDefaultSubCommand(new ModdedCommandHelp(this, "My node", TextFormatting.DARK_AQUA, TextFormatting.AQUA,
                TextFormatting.WHITE));
        registerSubCommand(new ModdedCommandRandomFireWorks());
        
        registerSubCommand(new ModdedCommand("hello", "mymod.cmd.hello", CommandClickOption.doCommand, true) {
            @Override
            protected Command<CommandSource> onNoArgument() {
                return c -> {
                    c.getSource().sendFeedback(createText("Hello", TextFormatting.RED), false);
                    return 1;
                };
            }
        });
    }

}