Skip to content

Commit 84933de

Browse files
committed
feat: scoreboard arguments, entities arguments.
1 parent a8dc10c commit 84933de

File tree

13 files changed

+820
-0
lines changed

13 files changed

+820
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
order: 7
3+
authors:
4+
- JorelAli
5+
- DerEchtePilz
6+
- willkroboth
7+
- misode
8+
- Strokkur424
9+
---
10+
11+
# Entity & Player arguments
12+
13+
## Entity selector argument
14+
15+
![An image of an entity selector argument with a list of suggestions including entity selectors and a player name](/images/arguments/entityselector.png)
16+
17+
Minecraft's [target selectors](https://minecraft.wiki/w/Commands#Target_selectors) (e.g. `@a` or `@e`) are implemented using the subclasses of the `EntitySelectorArgument` class. This allows you to select specific entities based on certain attributes.
18+
19+
There are four `EntitySelectorArgument` subclasses that determine what type of data to return:
20+
21+
- `EntitySelectorArgument.OneEntity` - A single entity, which returns a `Entity` object.
22+
- `EntitySelectorArgument.ManyEntities` - A collection of many entities, which returns a `Collection<Entity>` object.
23+
- `EntitySelectorArgument.OnePlayer` - A single player, which returns a `Player` object.
24+
- `EntitySelectorArgument.ManyPlayers` - A collection of players, which returns a `Collection<Player>` object.
25+
26+
The return type is the type to be cast when retrieved from the [`CommandArguments args`](../arguments) in the command declaration.
27+
28+
::::tip Example - Remove entities command
29+
30+
Say we want a command to remove certain types of entities. Typically, this would be implemented using a simple command like:
31+
32+
```mccmd
33+
/remove <player>
34+
/remove <mob type>
35+
/remove <radius>
36+
```
37+
38+
Instead, we can combine all of these into one by using the `EntitySelectorArgument`. We want to be able to target multiple entities at a time, so we want to use the `EntitySelectorArgument.ManyEntities` constructor. We can simply retrieve the `Collection<Entity>` from this argument and iteratively remove each entity:
39+
40+
:::tabs
41+
===Java
42+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/EntitiesArguments.java#entitySelectorArgumentExample
43+
===Kotlin
44+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/EntitiesArguments.kt#entitySelectorArgumentExample
45+
===Kotlin DSL
46+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/EntitiesArguments.kt#entitySelectorArgumentExampleDSL
47+
:::
48+
49+
We could then use this to target specific entities, for example:
50+
51+
- To remove all cows:
52+
53+
```mccmd
54+
/remove @e[type=cow]
55+
```
56+
57+
- To remove the 10 furthest pigs from the command sender:
58+
59+
```mccmd
60+
/remove @e[type=pig,limit=10,sort=furthest]
61+
```
62+
63+
::::
64+
65+
## Player argument
66+
67+
The `PlayerArgument` class is very similar _(almost identical)_ to `EntitySelectorArgument.OnePlayer`. It returns a `Player` object and requires the player to be online.
68+
69+
:::info
70+
The `PlayerArgument` internally uses the `GameProfile` class from Mojang's authlib, which means that this argument has a slight performance overhead compared to using `EntitySelectorArgument.OnePlayer`
71+
:::
72+
73+
::::tip Example – PlayerArgument without entity selectors
74+
75+
When registering a `PlayerArgument` you might notice that it includes `Entity Selectors` (`@a`, `@e`, `@r`, etc.). If you want to avoid those, you can use argument suggestions to only suggest the player names. For this example, let us create a /warp command:
76+
77+
```mccmd
78+
/warp <player>
79+
```
80+
81+
To get a `PlayerArgument` which only suggests the actual names, we can define it like this:
82+
83+
:::tabs
84+
===Java
85+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/EntitiesArguments.java#buildNoSelectorSuggestions
86+
===Kotlin
87+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/EntitiesArguments.kt#buildNoSelectorSuggestions
88+
:::
89+
90+
Now we can define the rest of the command and include our suggestion inside it like this:
91+
92+
:::tabs
93+
===Java
94+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/EntitiesArguments.java#noSelectorSuggestionsExample
95+
===Kotlin
96+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/EntitiesArguments.kt#noSelectorSuggestionsExample
97+
:::
98+
99+
And there we have it! One thing to note is that entity selectors are still a valid input; they’re just not included in the suggestions.
100+
![WarpCommand](/images/entityselectorplayerexample.gif)
101+
102+
::::
103+
104+
## OfflinePlayer argument
105+
106+
The `OfflinePlayerArgument` class is identical to the `PlayerArgument` class, but instead of returning a `Player` object, it returns an `OfflinePlayer` object. Internally, this argument makes calls to Mojang servers (via Mojang's authlib), meaning it can be slightly slower than alternative methods (such as using a `StringArgument` and suggesting a list of existing offline players).
107+
108+
The `OfflinePlayerArgument` _should_ be able to retrieve players that have never joined the server before.
109+
110+
## Entity type argument
111+
112+
![An image of an entity argument displaying a list of entity type suggestions](/images/arguments/entitytype.png)
113+
114+
The `EntityTypeArgument` class is used to retrieve a type of entity as defined in the [`EntityType`](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html) enum. In other words, this is an entity type, for example, a pig or a zombie.
115+
116+
::::tip Example - Spawning entities
117+
118+
Say we want a command to spawn a specific type of entity, similar to the `/summon` command in Vanilla Minecraft, with the addition of specifying how many entities to spawn. We want to create a command of the following form:
119+
120+
```mccmd
121+
/spawnmob <entity> <amount>
122+
```
123+
124+
Since we're trying to specify an entity type, we will use the `EntityTypeArgument` as our argument type for `<entity>`. We combine this with the `IntegerArgument` class with a specified range of $1 \le \textit{amount} \le 100$:
125+
126+
:::tabs
127+
===Java
128+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/EntitiesArguments.java#entityTypeArgumentExample
129+
===Kotlin
130+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/EntitiesArguments.kt#entityTypeArgumentExample
131+
===Kotlin DSL
132+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/EntitiesArguments.kt#entityTypeArgumentExampleDSL
133+
:::
134+
135+
Note how in this example above, we have to explicitly state `Player player, CommandArguments args`. This is due to a limitation of Java's type inference system which is discussed [here](../../registration#setting-the-commands-executor).
136+
137+
::::
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
order: 8
3+
title: Scoreboard arguments
4+
---
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
order: 2
3+
authors:
4+
- JorelAli
5+
- DerEchtePilz
6+
- willkroboth
7+
---
8+
9+
# Objective arguments
10+
11+
In the CommandAPI, objectives are split into two classes:
12+
13+
- The `ObjectiveArgument` class, which represents objectives as a whole
14+
- The `ObjectiveCriteriaArgument` class, which represents objective criteria
15+
16+
## Objective argument
17+
18+
The objective argument refers to a single scoreboard objective.
19+
20+
::::tip Example – Move objective to sidebar
21+
22+
As an example, let's create a command to move an objective to a player's sidebar. To do this, we will use the following command syntax:
23+
24+
```mccmd
25+
/sidebar <objective>
26+
```
27+
28+
:::tabs
29+
===Java
30+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/scoreboard/ObjectiveArguments.java#objectiveArgumentsExample
31+
===Kotlin
32+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/ObjectiveArguments.kt#objectiveArgumentsExample
33+
===Kotlin DSL
34+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/ObjectiveArguments.kt#objectiveArgumentsExampleDSL
35+
:::
36+
37+
::::
38+
39+
## Objective criteria argument
40+
41+
The `ObjectiveCriteriaArgument` is fairly straight forward - it represents the criteria for an objective. Similar to Bukkit, the objective criteria is simply represented as a `String`, so it must be casted to a `String` when being used.
42+
43+
::::tip Example – Unregister all objectives by criteria
44+
45+
Say we wanted to create a command to unregister all objectives based on a given criteria. Let's create a command with the following form:
46+
47+
```mccmd
48+
/unregisterall <objective critera>
49+
```
50+
51+
To do this, we're going to take advantage of Bukkit's `Scoreboard.getObjectivesByCriteria(String)` method
52+
53+
:::tabs
54+
===Java
55+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/scoreboard/ObjectiveArguments.java#objectiveCriteriaArgumentsExample
56+
===Kotlin
57+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/ObjectiveArguments.kt#objectiveCriteriaArgumentsExample
58+
===Kotlin DSL
59+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/ObjectiveArguments.kt#objectiveCriteriaArgumentsExampleDSL
60+
:::
61+
62+
::::
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
order: 1
3+
authors:
4+
- JorelAli
5+
- DerEchtePilz
6+
- willkroboth
7+
- misode
8+
---
9+
10+
# Scoreboard arguments
11+
12+
The CommandAPI uses two classes to provide information about a scoreboard:
13+
14+
- The `ScoreHolderArgument` class represents **score holder** - a player's name or an entity's UUID that has scores in an objective. This is described in more detail [on the Minecraft Wiki](https://minecraft.wiki/w/Scoreboard#Objectives).
15+
- The `ScoreboardSlotArgument` class represents a **display slot** (sidebar, list or belowName) as well as the team color if the display is the sidebar. This is described in more detail [on the Minecraft Wiki](https://minecraft.wiki/w/Scoreboard#Display_slots).
16+
17+
## Score holder argument
18+
19+
The score holder argument can accept either a single entity or a collection of multiple entities. To specify which one to use, you must use the `ScoreHolderArgument.Single` or `ScoreHolderArgument.Multiple` constructor respectively:
20+
21+
```java
22+
new ScoreHolderArgument.Single(nodeName);
23+
new ScoreHolderArgument.Multiple(nodeName);
24+
```
25+
26+
Depending on which constructor is used, the cast type changes. If you use `ScoreHolderArgument.Single`, the argument must be cast to a `String`. Otherwise, if you use `ScoreHolderArgument.Multiple`, the argument must be cast to a `Collection<String>`.
27+
28+
::::tip Example – Rewarding players with scoreboard objectives
29+
30+
Say we want to reward all players that fit certain criteria. We want a command with the following syntax:
31+
32+
```mccmd
33+
/reward <players>
34+
```
35+
36+
Since we could have multiple players that fit a certain criterion, we want to use `ScoreHolderArgument.Multiple` constructor.
37+
38+
To give this example a bit more context, let's say we want to reward all players that have died less than 10 times on the server. To do this, we will use the following command:
39+
40+
```mccmd
41+
/reward @e[type=player,scores={deaths=..9}]
42+
```
43+
44+
Note how we use `..9` to represent nine or fewer deaths (since ranges are inclusive). Also note how we restrict our input to players via the command using `type=player`. We can now implement our command:
45+
46+
:::tabs
47+
===Java
48+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/scoreboard/ScoreboardArguments.java#scoreHolderArgumentExample
49+
===Kotlin
50+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/ScoreboardArguments.kt#scoreHolderArgumentExample
51+
===Kotlin DSL
52+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/ScoreboardArguments.kt#scoreHolderArgumentExampleDSL
53+
:::
54+
55+
::::
56+
57+
:::info
58+
59+
In the example above, we have our user use the `@e[type=player]` entity selector to restrict the `Collection<String>` so it only returns player names, which allows us to use `Bukkit.getPlayer(playerName)`. In practice, we can’t guarantee that such a selector will be used, so we could update the code to accept both entities and players. For example, we can differentiate between players and entities by using the `UUID.fromString(String)` method:
60+
61+
```java
62+
Collection<String> entitiesAndPlayers = (Collection<String>) args.get(0);
63+
for(String str : entitiesAndPlayers) {
64+
try {
65+
UUID uuid = UUID.fromString(str);
66+
// Is a UUID, so it must by an entity
67+
Bukkit.getEntity(uuid);
68+
} catch(IllegalArgumentException exception) {
69+
// Not a UUID, so it must be a player name
70+
Bukkit.getPlayer(str);
71+
}
72+
}
73+
```
74+
75+
:::
76+
77+
## Scoreboard slot argument
78+
79+
![A scoreboardslotargument showing a list of suggestions of valid Minecraft scoreboard slot positions](/images/arguments/scoreboardslot.png)
80+
81+
The `ScoreboardSlotArgument` represents where scoreboard information is displayed. Since the Bukkit scoreboard `DisplaySlot` is not able to represent the case where team colors are provided, the CommandAPI uses the `ScoreboardSlot` wrapper class as the representation of the `ScoreboardSlotArgument`.
82+
83+
### `ScoreboardSlot` wrapper
84+
85+
The `ScoreboardSlot` wrapper class has three main methods:
86+
87+
```java
88+
enum ScoreboardSlot {
89+
PLAYER_LIST,
90+
SIDEBAR, // Unused, use the other SIDEBAR_TEAM_### values below
91+
BELOW_NAME,
92+
SIDEBAR_TEAM_BLACK,
93+
SIDEBAR_TEAM_DARK_BLUE,
94+
SIDEBAR_TEAM_DARK_GREEN,
95+
SIDEBAR_TEAM_DARK_AQUA,
96+
SIDEBAR_TEAM_DARK_RED,
97+
SIDEBAR_TEAM_DARK_PURPLE,
98+
SIDEBAR_TEAM_GOLD,
99+
SIDEBAR_TEAM_GRAY,
100+
SIDEBAR_TEAM_DARK_GRAY,
101+
SIDEBAR_TEAM_BLUE,
102+
SIDEBAR_TEAM_GREEN,
103+
SIDEBAR_TEAM_AQUA,
104+
SIDEBAR_TEAM_RED,
105+
SIDEBAR_TEAM_LIGHT_PURPLE,
106+
SIDEBAR_TEAM_YELLOW,
107+
SIDEBAR_TEAM_WHITE;
108+
109+
public DisplaySlot getDisplaySlot();
110+
public ChatColor getTeamColor();
111+
public boolean hasTeamColor();
112+
113+
public NamespacedKey getKey();
114+
}
115+
```
116+
117+
The `getDisplaySlot()` method returns the display slot that was chosen. Sidebar scoreboard colors can be accessed via `ScoreboardSlot.SIDEBAR_TEAM_###`. You can also retrieve the color using the `getTeamColor()` method.
118+
119+
::::tip Example – Clearing objectives in a scoreboard slot
120+
121+
Say we want to clear all objectives in a specific scoreboard slot. In this example, we will use the main server scoreboard, which is accessed using `Bukkit.getScoreboardManager.getMainScoreboard()`. We want a command with the following syntax:
122+
123+
```mccmd
124+
/clearobjectives <slot>
125+
```
126+
127+
We implement this simply by using the `ScoreboardSlotArgument` as our argument, and then we can clear the slot using the scoreboard `clearSlot(DisplaySlot)` method.
128+
129+
:::tabs
130+
===Java
131+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/scoreboard/ScoreboardArguments.java#scoreboardSlotArgumentExample
132+
===Kotlin
133+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/ScoreboardArguments.kt#scoreboardSlotArgumentExample
134+
===Kotlin DSL
135+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/ScoreboardArguments.kt#scoreboardSlotArgumentExampleDSL
136+
:::
137+
138+
::::
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
order: 3
3+
authors:
4+
- JorelAli
5+
- DerEchtePilz
6+
- willkroboth
7+
---
8+
9+
# Team arguments
10+
11+
The `TeamArgument` class interacts with the Minecraft scoreboard and represents a team.
12+
13+
::::tip Example - Toggling friendly fire in a team
14+
15+
Let's say we want to create a command to toggle the state of friendly fire in a team. We want a command of the following form
16+
17+
```mccmd
18+
/togglepvp <team>
19+
```
20+
21+
To do this, given a team we want to use the `setAllowFriendlyFire(boolean)` function.
22+
23+
:::tabs
24+
===Java
25+
<<< @/../reference-code/src/main/java/createcommands/arguments/types/scoreboard/TeamArguments.java#teamArgumentsExample
26+
===Kotlin
27+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/TeamArguments.kt#teamArgumentsExample
28+
===Kotlin DSL
29+
<<< @/../reference-code/src/main/kotlin/createcommands/arguments/types/scoreboard/TeamArguments.kt#teamArgumentsExampleDSL
30+
:::
31+
32+
::::

0 commit comments

Comments
 (0)