Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing optional arguments #393

Merged
merged 28 commits into from
Jan 4, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
cdb4c08
implementing optional arguments
DerEchtePilz Jan 3, 2023
96a03ec
Add optional arguments to the Kotlin DSL. Rename commandapi-kotlin-bu…
DerEchtePilz Jan 4, 2023
5b46749
add missing JavaDocs on AbstractArgument#setOptional(boolean)
DerEchtePilz Jan 4, 2023
2ad5828
fixing build error
DerEchtePilz Jan 4, 2023
3cf8297
adding documentation for optional arguments
DerEchtePilz Jan 4, 2023
6eb09e5
fixing dependency in the Bukkit Kotlin DSL example
DerEchtePilz Jan 4, 2023
7c4f635
address code review
DerEchtePilz Jan 4, 2023
a25547d
create optional_arguments.md
DerEchtePilz Jan 4, 2023
d1c0088
change /kill command to /sayhi
DerEchtePilz Jan 4, 2023
5ad1a21
make Mardown Linter happy (hopefully)
DerEchtePilz Jan 4, 2023
c82feff
fix wrong enchor end
DerEchtePilz Jan 4, 2023
f777925
address code review
DerEchtePilz Jan 4, 2023
33228d4
convert tabs to spaces in Examples.java
DerEchtePilz Jan 4, 2023
c226296
Merge branch 'dev/dev' into dev/dev
JorelAli Jan 4, 2023
210bed6
refactor AbstractCommandAPICommand#register()
DerEchtePilz Jan 4, 2023
afbd40a
Merge branch 'DerEchtePilz:dev/dev' into 'dev/dev'
DerEchtePilz Jan 4, 2023
7e36de1
simplifying AbstractCommandAPICommand#getArgumentsToRegister()
DerEchtePilz Jan 4, 2023
458b8d8
refactor AbstractCommandAPICommand#register() again
DerEchtePilz Jan 4, 2023
3e7c6ca
Add a section 'Setting existing arguments as optional arguments' to o…
DerEchtePilz Jan 4, 2023
d913acc
remove the List parameter from AbstractCommandAPICommand#getCommandsT…
DerEchtePilz Jan 4, 2023
6266990
Merge branch 'dev/dev' into dev/dev
DerEchtePilz Jan 4, 2023
ce835c6
fix a bug where a required argument would be registered as an optiona…
DerEchtePilz Jan 4, 2023
473bc75
implement multiple getOrDefault methods for the CommandArguments class
DerEchtePilz Jan 4, 2023
a31b755
adding documentation for the getOrDefault method
DerEchtePilz Jan 4, 2023
572beb9
address code review
DerEchtePilz Jan 4, 2023
c8c4960
make CommandArguments#get(int) not throw an ArrayIndexOutOfBoundsExce…
DerEchtePilz Jan 4, 2023
3008d60
Merge branch 'dev/dev' into dev/dev
DerEchtePilz Jan 4, 2023
a76530d
fix variable names after merge
DerEchtePilz Jan 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1306,21 +1306,17 @@ void resultingcommandexecutor3(){
{
/* ANCHOR: argumentkillcmd */
new CommandAPICommand("kill")
.withOptionalArguments(new PlayerArgument("target"))
.executesPlayer((player, args) -> {
player.setHealth(0);
Player target = (Player) args.get("target");
if (target != null) {
target.setHealth(0.0);
} else {
player.setHealth(0.0);
}
})
.register();
/* ANCHOR_END: argumentkillcmd */

/* ANCHOR: argumentkillcmd2 */
// Register our second /kill <target> command
new CommandAPICommand("kill")
.withArguments(new PlayerArgument("target"))
.executesPlayer((player, args) -> {
((Player) args.get(0)).setHealth(0);
})
.register();
/* ANCHOR_END: argumentkillcmd2 */
}

@SuppressWarnings("unused")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1233,21 +1233,16 @@ CommandAPICommand("mycommand")
fun argumentkillcmd() {
/* ANCHOR: argumentkillcmd */
CommandAPICommand("kill")
.executesPlayer(PlayerCommandExecutor { player, _ ->
player.setHealth(0.0)
})
.register()
.withOptionalArguments(PlayerArgument("target"))
.executesPlayer(PlayerCommandExecutor { player, args ->
val target: Player? = args.get("target") as Player?
DerEchtePilz marked this conversation as resolved.
Show resolved Hide resolved
if (target != null) {
target.health = 0.0
} else {
player.health = 0.0
}
}).register()
DerEchtePilz marked this conversation as resolved.
Show resolved Hide resolved
/* ANCHOR_END: argumentkillcmd */

/* ANCHOR: argumentkillcmd2 */
// Register our second /kill <target> command
CommandAPICommand("kill")
.withArguments(PlayerArgument("target"))
.executesPlayer(PlayerCommandExecutor { _, args ->
(args[0] as Player).setHealth(0.0)
})
.register()
/* ANCHOR_END: argumentkillcmd2 */
}

@Suppress("unused")
Expand Down Expand Up @@ -1727,7 +1722,7 @@ fun argumentsuggestions2_2() {
/* ANCHOR: ArgumentSuggestions2_2 */
val arguments = listOf<Argument<*>>(
PlayerArgument("friend").replaceSuggestions(ArgumentSuggestions.strings({ info ->
Friends.getFriends(info.sender())
Friends.getFriends(info.sender())
}))
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1386,21 +1386,17 @@ commandAPICommand("mycommand") {
fun argumentkillcmd() {
/* ANCHOR: argumentkillcmd */
commandAPICommand("kill") {
playerExecutor { player, _ ->
player.health = 0.0
optionalArgument(PlayerArgument("target"))
playerExecutor { player, args ->
val target: Player? = args["target"] as Player?
if (target != null) {
target.health = 0.0
} else {
player.health = 0.0
}
}
}
/* ANCHOR_END: argumentkillcmd */

/* ANCHOR: argumentkillcmd2 */
// Register our second /kill <target> command#
commandAPICommand("kill") {
playerArgument("target")
playerExecutor { _, args ->
(args[0] as Player).health = 0.0
}
}
/* ANCHOR_END: argumentkillcmd2 */
}

@Suppress("unused")
Expand Down
35 changes: 15 additions & 20 deletions docssrc/src/arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,13 @@ The type to cast each argument (declared in the `dev.jorel.commandapi.arguments`

## Optional/Different Arguments

Sometimes, you want to register a command that has a different effect whether arguments are included or not. For example, take the `/kill` command. If you run `/kill` on its own, it will kill the command sender. If however you run `/kill <target>`, it will kill the target. In other words, we have the following command command syntax:
Sometimes, you want to register a command that has a different effect whether arguments are included or not. For example, take the `/kill` command. If you run `/kill` on its own, it will kill the command sender. If however you run `/kill <target>`, it will kill the target. In other words, we have the following command syntax:

```mccmd
/kill - Kills yourself
/kill <target> - Kills a target player
```

As shown by the command syntax, we need to register _two commands_.

<div class="example">

### Example - /kill command with two separate arguments
Expand All @@ -181,7 +179,7 @@ For example, say we're registering a command `/kill`:
/kill <target> - Kills a target player
```

We first register the first `/kill` command as normal:
For that, we are going to register a command `/kill`. To add optional arguments, we are going to use the `withOptionalArguments(Argument... args)` method:

<div class="multi-pre">

Expand All @@ -199,26 +197,23 @@ We first register the first `/kill` command as normal:

</div>

Now we declare our command with arguments for our second command. Then, we can register our second command `/kill <target>` as usual:
This gives us the ability to run both `/kill` and `/kill <target>` with the same command name "kill", but have different results based on the arguments used.

<div class="multi-pre">
In this example, we use the simpler, inline `.withOptionalArguments(Argument... arguments)` method to register our argument. There is no difference to using this method as opposed to explicitly declaring a list and using `.withOptionalArguments(List<Argument> arguments)`, so feel free to use whichever method you want!
DerEchtePilz marked this conversation as resolved.
Show resolved Hide resolved

```java,Java
{{#include ../../commandapi-documentation-code/src/main/java/dev/jorel/commandapi/examples/java/Examples.java:argumentkillcmd2}}
```

```kotlin,Kotlin
{{#include ../../commandapi-documentation-code/src/main/kotlin/dev/jorel/commandapi/examples/kotlin/Examples.kt:argumentkillcmd2}}
```

```kotlin,Kotlin_DSL
{{#include ../../commandapi-documentation-code/src/main/kotlin/dev/jorel/commandapi/examples/kotlin/ExamplesKotlinDSL.kt:argumentkillcmd2}}
```
You will also notice that we use `args.get("target")` to get the Player out of the arguments. This is safer than using `args.get(0)` because that will result in an `ArrayIndexOutOfBoundsException` whereas calling `args.get("target")` will return `null` if the argument was not provided.

</div>

This gives us the ability to run both `/kill` and `/kill <target>` with the same command name "kill", but have different results based on the arguments used.
One thing to note when using the `withOptionalArguments` method is that this calls the `setOptional()` method internally. This means that the following two examples are identical:
```java
new CommandAPICommand("optional")
.withOptionalArguments(new PlayerArgument("target"))
```

In this example, we use the simpler, inline `.withArguments(Argument... arguments)` method to register our argument. There is no difference to using this method as opposed to explicitly declaring a list and using `.withArguments(List<Argument> arguments)`, so feel free to use whichever method you want!
```java
new CommandAPICommand("optional")
.withArguments(new PlayerArgument("target").setOptional(true))
```

</div>
However, calling `withOptionalArguments` is safer because it makes sure that the argument is optional.