Ranged arguments
Ranged arguments allow players to provide a range between two numbers, all within a single argument. The CommandAPI provides two ranged arguments, IntegerRangeArgument
for ranges with only integer values, and FloatRangeArgument
for ranged with potential floating point values.
These consist of values such as:
Input | What it means |
---|---|
5 | The number 5 |
5..10 | Numbers between 5 and 10, including 5 and 10 |
5.. | Numbers greater than or equal to 5 (bounded by Java's max number size) |
..5 | Numbers less than or equal to 5 (bounded by Java's min number size) |
This allows you to let users define a range of values, which can be used to limit a value, such as the number of players in a region or for a random number generator.
The IntegerRange & FloatRange class
The CommandAPI returns an IntegerRange
from the IntegerRangeArgument
, and a FloatRange
from the FloatRangeArgument
, which represents the upper and lower bounds of the numbers provided by the command sender, as well as a method to check if a number is within that range.
The IntegerRange
class has the following methods:
class IntegerRange {
public int getLowerBound();
public int getUpperBound();
public boolean isInRange(int);
}
The FloatRange
class has the following methods:
class FloatRange {
public float getLowerBound();
public float getUpperBound();
public boolean isInRange(float);
}
Example - Searching chests for certain items
Say you're working on a plugin for server administrators to help them find restricted items. A method of doing so would be to search chests in a given radius for certain items. As such, we can use the following syntax:
/searchchests <range> <item>
Now, we simply create our arguments using IntegerRangeArgument
for our range and ItemStackArgument
as the item to search for. We can then find all chests in a given area and determine if it is within the range provided by the command sender by using range.isInRange(distance)
:
new CommandAPICommand("searchrange")
.withArguments(new IntegerRangeArgument("range")) // Range argument
.withArguments(new ItemStackArgument("item")) // The item to search for
.executesPlayer((player, args) -> {
// Retrieve the range from the arguments
IntegerRange range = (IntegerRange) args.get("range");
ItemStack itemStack = (ItemStack) args.get("item");
// Store the locations of chests with certain items
List<Location> locations = new ArrayList<>();
// Iterate through all chunks, and then all tile entities within each chunk
for (Chunk chunk : player.getWorld().getLoadedChunks()) {
for (BlockState blockState : chunk.getTileEntities()) {
// The distance between the block and the player
int distance = (int) blockState.getLocation().distance(player.getLocation());
// Check if the distance is within the specified range
if (range.isInRange(distance)) {
// Check if the tile entity is a chest
if (blockState instanceof Chest chest) {
// Check if the chest contains the item specified by the player
if (chest.getInventory().contains(itemStack.getType())) {
locations.add(chest.getLocation());
}
}
}
}
}
// Output the locations of the chests, or whether no chests were found
if (locations.isEmpty()) {
player.sendMessage("No chests were found");
} else {
player.sendMessage("Found " + locations.size() + " chests:");
locations.forEach(location -> {
player.sendMessage(" Found at: "
+ location.getX() + ", "
+ location.getY() + ", "
+ location.getZ());
});
}
})
.register();
CommandAPICommand("searchrange")
.withArguments(IntegerRangeArgument("range")) // Range argument
.withArguments(ItemStackArgument("item")) // The item to search for
.executesPlayer(PlayerCommandExecutor { player, args ->
// Retrieve the range from the arguments
val range = args["range"] as IntegerRange
val itemStack = args["item"] as ItemStack
// Store the locations of chests with certain items
val locations = mutableListOf<Location>()
// Iterate through all chunks, and then all tile entities within each chunk
for (chunk in player.world.loadedChunks) {
for (blockState in chunk.tileEntities) {
// The distance between the block and the player
val distance = blockState.location.distance(player.location).toInt()
// Check if the distance is within the specified range
if (range.isInRange(distance)) {
// Check if the tile entity is a chest
if (blockState is Chest) {
// Check if the chest contains the item specified by the player
if (blockState.inventory.contains(itemStack.type)) {
locations.add(blockState.location)
}
}
}
}
}
// Output the locations of the chests, or whether no chests were found
if (locations.isEmpty()) {
player.sendMessage("No chests were found")
} else {
player.sendMessage("Found ${locations.size} chests:")
locations.forEach {
player.sendMessage(" Found at: ${it.x}, ${it.y}, ${it.z}")
}
}
})
.register()
commandAPICommand("searchrange") {
integerRangeArgument("range") // Range argument
itemStackArgument("item") // The item to search for
playerExecutor { player, args ->
// Retrieve the range from the arguments
val range = args["range"] as IntegerRange
val itemStack = args["item"] as ItemStack
// Store the locations of chests with certain items
val locations = mutableListOf<Location>()
// Iterate through all chunks, and then all tile entities within each chunk
for (chunk in player.world.loadedChunks) {
for (blockState in chunk.tileEntities) {
// The distance between the block and the player
val distance = blockState.location.distance(player.location).toInt()
// Check if the distance is within the specified range
if (range.isInRange(distance)) {
// Check if the tile entity is a chest
if (blockState is Chest) {
// Check if the chest contains the item specified by the player
if (blockState.inventory.contains(itemStack.type)) {
locations.add(blockState.location)
}
}
}
}
}
// Output the locations of the chests, or whether no chests were found
if (locations.isEmpty()) {
player.sendMessage("No chests were found")
} else {
player.sendMessage("Found ${locations.size} chests:")
locations.forEach {
player.sendMessage(" Found at: ${it.x}, ${it.y}, ${it.z}")
}
}
}
}