Multi literal arguments

So far, we've described normal arguments and literal arguments. We've described the nuances with literal arguments and how they're not really "arguments", so they don't appear in the CommandArguments args for commands.

Now forget all of that. Multi literal arguments are the same as literal arguments but they do appear in the CommandArguments args for commands (i.e. they are listed). Multi literal arguments are just a way better alternative to literal arguments. The multi literal argument constructor allows you to provide a String nodeName and a String... literals of possible values which you can use for your command declaration.

The multi literal argument has all of the same benefits of a regular literal argument - they are hardcoded options that the user must enter - they don't allow other values.

Developer's Note:

For 9.1.0, all previously existing MultiLiteralArgument constructors have been deprecated! They will be removed in a future version.

The new constructor looks like this:

public MultiLiteralArgument(String nodeName, String... literals)

Example - Using multi literals to make the gamemode command

In this example, we'll show how to use multi literals to declare Minecraft's /gamemode command. As you can see from the example code below, the argument declaration and command declaration is the same as if you were declaring any normal argument or command.

new CommandAPICommand("gamemode")
    .withArguments(new MultiLiteralArgument("gamemodes", "adventure", "creative", "spectator", "survival"))
    .executesPlayer((player, args) -> {
        // The literal string that the player enters IS available in the args[]
        switch ((String) args.get("gamemodes")) {
            case "adventure":
                player.setGameMode(GameMode.ADVENTURE);
                break;
            case "creative":
                player.setGameMode(GameMode.CREATIVE);
                break;
            case "spectator":
                player.setGameMode(GameMode.SPECTATOR);
                break;
            case "survival":
                player.setGameMode(GameMode.SURVIVAL);
                break;
            default:
                player.sendMessage("Invalid gamemode: " + args.get("gamemodes"));
                break;
        }
    }) 
    .register();
CommandAPICommand("gamemode")
    .withArguments(MultiLiteralArgument("gamemodes", "adventure", "creative", "spectator", "survival"))
    .executesPlayer(PlayerCommandExecutor { player, args ->
        // The literal string that the player enters IS available in the args[]
        when (args["gamemodes"] as String) {
            "adventure" -> player.gameMode = GameMode.ADVENTURE
            "creative" -> player.gameMode = GameMode.CREATIVE
            "spectator" -> player.gameMode = GameMode.SPECTATOR
            "survival" -> player.gameMode = GameMode.SURVIVAL
        }
    })
    .register()
commandAPICommand("gamemode") {
    multiLiteralArgument(nodeName = "gamemodes", "adventure", "creative", "spectator", "survival") // Adding this for now, needed because ambiguous methods exist
    playerExecutor { player, args ->
        // The literal string that the player enters IS available in the args[]
        when (args["gamemodes"] as String) {
            "adventure" -> player.gameMode = GameMode.ADVENTURE
            "creative" -> player.gameMode = GameMode.CREATIVE
            "spectator" -> player.gameMode = GameMode.SPECTATOR
            "survival" -> player.gameMode = GameMode.SURVIVAL
        }
    }
}

An important thing to note is that we don't have to implement a default case for the above switch statements, because the CommandAPI will only permit valid options of a MultiLiteralArgument to reach the executor. If the user enters an invalid option, the command doesn't run.