List arguments
List arguments allows users to provide a list of values. This argument uses an underlying GreedyStringArgument
, so the greedy string argument rule applies - this argument can only be used at the end of an argument list.
The ListArgumentBuilder
Unlike other arguments, because this argument can be interpreted in various different ways, this argument can only be created using a ListArgumentBuilder
, instead of directly accessing the ListArgument
constructor. The ListArgumentBuilder
loosely follows the following format:
\begin{align} &\quad\texttt{Create a ListArgumentBuilder} \\ \rightarrow&\quad\texttt{(Provide the list delimiter)} \\ \rightarrow&\quad\texttt{Provide the list to pull suggestions from} \\ \rightarrow&\quad\texttt{Provide the mapper of the list items to a string} \\ \rightarrow&\quad\texttt{Build the ListArgument} \end{align}
Construction
First, you have to create a ListArgumentBuilder
parameterized over the type that the list will generate. For example, if you want to create a list of Strings, you would use new ListArgumentBuilder<String>
.
- The
nodeName
parameter represents the name of the node to use for the argument. - The optional
delimiter
argument specifies the delimiter (separator) to use between entries. If a delimiter is not provided, a space" "
will be used as the delimiter.
public ListArgumentBuilder<T>(String nodeName);
public ListArgumentBuilder<T>(String nodeName, String delimiter);
\[\downarrow\]
Allowing duplicates (Optional)
If you want your users to enter duplicate entries in your list, you can use the
allowDuplicates
method to set whether duplicates are allowed. By default, duplicates are disabled.When duplicates are enabled, items that have been entered before can be displayed again in the list of suggestions:
ListArgumentBuilder.allowDuplicates(true);
When duplicates are disabled, items that have already been entered will not appear in the list of suggestions:
ListArgumentBuilder.allowDuplicates(false);
\[\downarrow\]
Providing the list
The ListArgument
requires a list that the list argument can pull suggestions and validation from. The ListArgument
does not support values which are not present in the provided list. There are three methods that can be used to provide a list for the ListArgument
:
-
Providing an immutable list (a list that doesn't change) using the
Collection<T>
parameter:public ListArgumentBuilder withList(Collection<T> list);
-
Providing a list that is determined when suggestions are being displayed to the user and before the command has been executed using the
Supplier<Collection<T>>
parameter:public ListArgumentBuilder withList(Supplier<Collection<T>> list);
-
Providing a list that is determined when suggestions are being displayed to the user and before the command has been executed, that also depends on the
CommandSender
running the command, using theFunction<CommandSender, Collection<T>>
parameter:public ListArgumentBuilder withList(Function<CommandSender, Collection<T>> list);
\[\downarrow\]
Providing a list mapping function
In order to display suggestions, the ListArgument
needs to know how to convert a list entry to a string. For example, a Location
may be converted into "x,y,z"
. The ListArgumentBuilder
provides three methods for providing a mapping function:
-
The
withStringMapper()
method converts the object to a string using the object's.toString()
method. If the object is null, this method will populate it with the string"null"
:public ListArgumentBuilder withStringMapper();
-
The
withMapper()
method requires a function that maps the object to a string:public ListArgumentBuilder withMapper(Function<T, String> mapper);
-
The
withStringTooltipMapper()
method requires a function that maps the object to anIStringTooltip
. This allows you to also provide hover tooltips for the current item:public ListArgumentBuilder withStringTooltipMapper(Function<T, IStringTooltip> mapper);
\[\downarrow\]
Building the ListArgumentBuilder
To finish building the ListArgument
, call the build()
method:
public ListArgument<T> build();
Examples
Example - Multi-give command
Say you wanted to give yourself multiple items in a single command. For this command, we'll use the following syntax, which lets you provide the number of items to give, and a list of materials:
/multigive <amount> <materials>
To do this, we create a command with an IntegerArgument
to specify the amount (between 1 and 64), and a ListArgument
that accepts a list of Material
objects. We use the ListArgumentBuilder
to provide a list of materials as well as a mapping function that converts the material's name to a lowercase string. By default, we use a space delimiter (separator) for arguments in the list.
new CommandAPICommand("multigive")
.withArguments(new IntegerArgument("amount", 1, 64))
.withArguments(new ListArgumentBuilder<Material>("materials")
.withList(List.of(Material.values()))
.withMapper(material -> material.name().toLowerCase())
.build()
)
.executesPlayer((player, args) -> {
int amount = (int) args[0];
List<Material> theList = (List<Material>) args[1];
for(Material item : theList) {
player.getInventory().addItem(new ItemStack(item, amount));
}
})
.register();