Location arguments

A Location argument showing the options '', ' ' and ' ~ ~'

In the CommandAPI, there are two arguments used to represent location. The LocationArgument argument, which represents a 3D location \( (x, y, z) \) and the Location2DArgument, which represents 2D location \( (x, z) \).


Location (3D space)

The LocationArgument class is used to specify a location in the command sender's current world, returning a Bukkit Location object. It allows the user to enter three numbers as coordinates, or use relative coordinates (i.e. the ~ and ^ operators).

The LocationArgument constructor requires a LocationType, which specifies the type of location that is accepted by the command. The LocationType enum consists of two values:

LocationType.BLOCK_POSITION

BLOCK_POSITION refers to integer block coordinates. When in-game as a player, the suggested location is the coordinates of block you are looking at when you type the command.

BLOCK_POSITION

LocationType.PRECISE_POSITION

PRECISE_PRECISION uses exact coordinates, using the double primitive type. When in-game as a player, the suggested location is the exact coordinates of where your cursor is pointing at when you type the command.

PRECISE_POSITION

If no LocationType is provided, the LocationArgument will use PRECISE_POSITION by default.

The LocationArgument constructor can also accept a boolean centerPosition. If set to true, when using LocationType.PRECISE_POSITION, if an integer is provided in the value, it will add 0.5 to the x and z coordinates to center the position within a block. If set to false, the integer value will be provided as is.

If no centerPosition parameter is provided, the LocationArgument will use centerPosition = true by default.

Example - LocationArgument precise position centering

Say you use the following constructor, which sets centerPosition to true:

new LocationArgument("location", LocationType.PRECISE_POSITION, true);
LocationArgument("location", LocationType.PRECISE_POSITION, true)

Integer positions are centered

Let's also say you use the following location using this location argument in a command:

10 20 30

The resulting location will be the following, which centers the position of the x and z coordinates. This does not change the y coordinate:

10.5 20 30.5

Non-integer positions remain as normal

If you use the following location using this location argument in a command:

10.2 20.2 30.2

The resulting location will be the following, which does not change the x and z coordinates, because the positions are not integers:

10.2 20.2 30.2

Say you use the following constructor, which sets centerPosition to false:

new LocationArgument("location", LocationType.PRECISE_POSITION, false);
LocationArgument("location", LocationType.PRECISE_POSITION, false)

Integer positions are not centered

Let's also say you use the following location using this location argument in a command:

10 20 30

The resulting location will be the following, which does not modify the position of the x and z coordinates:

10 20 30

Example - Break block using coordinates

We can declare a simple command to break a block:

/break <location>

Simply put, given the coordinates provided to the command, "break" the block by setting it's type to Material.AIR. For this example, we're referring to block specific coordinates, so we want to use LocationType.BLOCK_POSITION:

new CommandAPICommand("break")
    // We want to target blocks in particular, so use BLOCK_POSITION
    .withArguments(new LocationArgument("block", LocationType.BLOCK_POSITION))
    .executesPlayer((player, args) -> {
        Location location = (Location) args.get("block");
        location.getBlock().setType(Material.AIR);
    })
    .register();
CommandAPICommand("break")
    // We want to target blocks in particular, so use BLOCK_POSITION
    .withArguments(LocationArgument("block", LocationType.BLOCK_POSITION))
    .executesPlayer(PlayerCommandExecutor { _, args ->
        (args["block"] as Location).block.type = Material.AIR
    })
    .register()
commandAPICommand("break") {
    // We want to target blocks in particular, so use BLOCK_POSITION
    locationArgument("block", LocationType.BLOCK_POSITION)
    playerExecutor { _, args ->
        (args["block"] as Location).block.type = Material.AIR
    }
}

Location (2D space)

A location 2D argument showing the options '' and ' ~'

The Location2DArgument is pretty much identical in use to the LocationArgument for 3D coordinates, except instead of returning a Location object, it instead returns a Location2D object that extends Location (thus, being compatible anywhere you would normally be able to use Location).