Merge branch 'master' into 1.17
# Conflicts: # src/main/java/carpet/script/value/NBTSerializableValue.java
This commit is contained in:
commit
f4f289b0ec
14 files changed
+817
-175
No files matched your search
+110
-17
@@ -1913,6 +1913,11 @@ Here is a list of built-in types, with their return value formats, as well as a
|
|||||||
* `'players'`: returning a list of valid player name string, logged in or not. If configured with `'single'` returns only one player or `null`.
|
* `'players'`: returning a list of valid player name string, logged in or not. If configured with `'single'` returns only one player or `null`.
|
||||||
* `'intrange'`: same as `'floatrange'`, but requiring integers.
|
* `'intrange'`: same as `'floatrange'`, but requiring integers.
|
||||||
* `'enchantment'`: name of an enchantment
|
* `'enchantment'`: name of an enchantment
|
||||||
|
* `'slot'`: provides a list of inventory type and slot. Can be configured with `'restrict'` requiring
|
||||||
|
`'player'`, `'enderchest'`, `'equipment'`, `'armor'`, `'weapon'`, `'container'`, `'villager'` or `'horse'` restricting selection of
|
||||||
|
available slots. Scarpet supports all vanilla slots, except for `horse.chest` - chest item, not items themselves. This you would
|
||||||
|
need to manage yourself via nbt directly. Also, for entities that change their capacity, like llamas, you need to check yourself if
|
||||||
|
the specified container slot is valid for your entity.
|
||||||
* `'item'`: triple of item type, count of 1, and nbt.
|
* `'item'`: triple of item type, count of 1, and nbt.
|
||||||
* `'message'`: text with expanded embedded player names
|
* `'message'`: text with expanded embedded player names
|
||||||
* `'effect'`: string representing a status effect
|
* `'effect'`: string representing a status effect
|
||||||
@@ -3586,29 +3591,30 @@ health back to the villager after being harmed.
|
|||||||
## Manipulating inventories of blocks and entities
|
## Manipulating inventories of blocks and entities
|
||||||
|
|
||||||
Most functions in this category require inventory as the first argument. Inventory could be specified by an entity,
|
Most functions in this category require inventory as the first argument. Inventory could be specified by an entity,
|
||||||
or a block, or position (three coordinates) of a potential block with inventory. Player enderchest inventory require
|
or a block, or position (three coordinates) of a potential block with inventory, or can be preceded with inventory
|
||||||
two arguments, keyword `'enderchest'`, followed by the player entity argument, or a single argument as a string of a
|
type.
|
||||||
form: `'enderchest_steve'`. If your player name starts with enderchest, it can be always accessed by passing a player
|
Inventory type can be `null` (default), `'enderchest'` denoting player enderchest storage, or `'equipment'` applying to
|
||||||
|
entities hand and armour pieces. Then the type can be followed by entity, block or position coordinates.
|
||||||
|
For instance, player enderchest inventory requires
|
||||||
|
two arguments, keyword `'enderchest'`, followed by the player entity argument, (or a single argument as a string of a
|
||||||
|
form: `'enderchest_steve'` for legacy support). If your player name starts with `'enderchest_'`, first of all, tough luck,
|
||||||
|
but then it can be always accessed by passing a player
|
||||||
entity value. If all else fails, it will try to identify first three arguments as coordinates of a block position of
|
entity value. If all else fails, it will try to identify first three arguments as coordinates of a block position of
|
||||||
a block inventory. Player inventories can also be called by their name.
|
a block inventory. Player inventories can also be called by their name.
|
||||||
|
|
||||||
You can also use `'equipment'` as a keyword preceeding an entity indicating the need of access that entity as a mob.
|
A few living entities can have both: their regular inventory, and their equipment inventory.
|
||||||
Equipment inventory
|
Player's regular inventory already contains the equipment, but you can access the equipment part as well, as well as
|
||||||
consists of its armour and hand items, and a few living entites can have both, their regular inventory, and their equipment inventory. For some
|
their enderchest separately. For entity types that only have
|
||||||
entities (players) their regular inventory already contains the equipment. For entity types that only have
|
their equipment inventory, the equipment is returned by default (`null` type).
|
||||||
their equipment inventory, the equipment is returned by default.
|
|
||||||
|
If that's confusing see examples under `inventory_size` on how to access inventories. All other `inventory_...()` functions
|
||||||
|
use the same scheme.
|
||||||
|
|
||||||
<pre>
|
|
||||||
inventory_size(player()) => 41 // items
|
|
||||||
inventory_size('enderchest', player()) => 27 // equipment
|
|
||||||
inventory_size('equipment', player()) => 6 // equipment
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
If the entity or a block doesn't have
|
If the entity or a block doesn't have
|
||||||
an inventory, they typically do nothing and return null.
|
an inventory, all API functions typically do nothing and return null.
|
||||||
|
|
||||||
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
||||||
Manipulating of the nbt data can be costly, but retrieving them from the tuple to match other aspects is cheap
|
|
||||||
|
|
||||||
### `stack_limit(item)`
|
### `stack_limit(item)`
|
||||||
|
|
||||||
@@ -3681,14 +3687,26 @@ item name that serves as a replacement after crafting is done. Currently it can
|
|||||||
### `inventory_size(inventory)`
|
### `inventory_size(inventory)`
|
||||||
|
|
||||||
Returns the size of the inventory for the entity or block in question. Returns null if the block or entity don't
|
Returns the size of the inventory for the entity or block in question. Returns null if the block or entity don't
|
||||||
have an inventory
|
have an inventory.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
inventory_size(player()) => 41
|
inventory_size(player()) => 41
|
||||||
inventory_size('enderchest', player()) => 27 // enderchest
|
inventory_size('enderchest', player()) => 27 // enderchest
|
||||||
inventory_size('equipment', player()) => 6 // equipment
|
inventory_size('equipment', player()) => 6 // equipment
|
||||||
|
inventory_size(null, player()) => 41 // default inventory for players
|
||||||
|
|
||||||
inventory_size(x,y,z) => 27 // chest
|
inventory_size(x,y,z) => 27 // chest
|
||||||
inventory_size(block(pos)) => 5 // hopper
|
inventory_size(block(pos)) => 5 // hopper
|
||||||
|
|
||||||
|
horse = spawn('horse', x, y, z);
|
||||||
|
inventory_size(horse); => 2 // default horse inventory
|
||||||
|
inventory_size('equipment', horse); => 6 // unused horse equipment inventory
|
||||||
|
inventory_size(null, horse); => 2 // default horse
|
||||||
|
|
||||||
|
creeper = spawn('creeper', x, y, z);
|
||||||
|
inventory_size(creeper); => 6 // default creeper inventory is equipment since it has no other
|
||||||
|
inventory_size('equipment', creeper); => 6 // unused horse equipment inventory
|
||||||
|
inventory_size(null, creeper); => 6 // creeper default is its equipment
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
### `inventory_has_items(inventory)`
|
### `inventory_has_items(inventory)`
|
||||||
@@ -4157,8 +4175,83 @@ for the objective.
|
|||||||
|
|
||||||
### `scoreboard_display(place, objective)`
|
### `scoreboard_display(place, objective)`
|
||||||
|
|
||||||
sets display location for a specified `objective`. If `objective` is `null`, then display is cleared. If objective is invalid,
|
Sets display location for a specified `objective`. If `objective` is `null`, then display is cleared. If objective is invalid,
|
||||||
returns `null`.
|
returns `null`.
|
||||||
|
|
||||||
|
# Team
|
||||||
|
|
||||||
|
### `team_list()`, `team_list(team)`
|
||||||
|
|
||||||
|
Returns all available teams as a list with no arguments.
|
||||||
|
|
||||||
|
When a `team` is specified, it returns all the players inside that team. If the `team` is invalid, returns `null`.
|
||||||
|
|
||||||
|
### `team_add(team)`, `team_add(team,player)`
|
||||||
|
|
||||||
|
With one argument, creates a new `team` and returns its name if successful, or `null` if team already exists.
|
||||||
|
|
||||||
|
|
||||||
|
`team_add('admin')` -> Create a team with the name 'admin'
|
||||||
|
`team_add('admin','Steve')` -> Joing the player 'Steve' into the team 'admin'
|
||||||
|
|
||||||
|
If a `player` is specified, the player will join the given `team`. Returns `true` if player joined the team, or `false` if nothing changed since the player was already in this team. If the team is invalid, returns `null`
|
||||||
|
|
||||||
|
### `team_remove(team)`
|
||||||
|
|
||||||
|
Removes a `team`. Returns `true` if the team was deleted, or `null` if the team is invalid.
|
||||||
|
|
||||||
|
### `team_leave(player)`
|
||||||
|
|
||||||
|
Removes the `player` from the team he is in. Returns `true` if the player left a team, otherwise `false`.
|
||||||
|
|
||||||
|
`team_leave('Steve')` -> Removes Steve from the team he is currently in
|
||||||
|
`for(team_list('admin'), team_leave('admin', _))` -> Remove all players from team 'admin'
|
||||||
|
|
||||||
|
### `team_property(team,property,value?)`
|
||||||
|
|
||||||
|
Reads the `property` of the `team` if no `value` is specified. If a `value` is added as a third argument, it sets the `property` to that `value`.
|
||||||
|
|
||||||
|
* `collisionRule`
|
||||||
|
* Type: String
|
||||||
|
* Options: always, never, pushOtherTeams, pushOwnTeam
|
||||||
|
|
||||||
|
* `color`
|
||||||
|
* Type: String
|
||||||
|
* Options: See [team command](https://minecraft.gamepedia.com/Commands/team#Arguments) (same strings as `'teamcolor'` [command argument](https://github.com/gnembon/fabric-carpet/blob/master/docs/scarpet/Full.md#command-argument-types] options))
|
||||||
|
|
||||||
|
* `displayName`
|
||||||
|
* Type: String or FormattedText, when querying returns FormattedText
|
||||||
|
|
||||||
|
* `prefix`
|
||||||
|
* Type: String or FormattedText, when querying returns FormattedText
|
||||||
|
|
||||||
|
* `suffix`
|
||||||
|
* Type: String or FormattedText, when querying returns FormattedText
|
||||||
|
|
||||||
|
* `friendlyFire`
|
||||||
|
* Type: boolean
|
||||||
|
|
||||||
|
* `seeFriendlyInvisibles`
|
||||||
|
* Type: boolean
|
||||||
|
|
||||||
|
* `nametagVisibility`
|
||||||
|
* Type: String
|
||||||
|
* Options: always, never, hideForOtherTeams, hideForOwnTeam
|
||||||
|
|
||||||
|
* `deathMessageVisibility`
|
||||||
|
* Type: String
|
||||||
|
* Options: always, never, hideForOtherTeams, hideForOwnTeam
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```
|
||||||
|
team_property('admin','color','dark_red') Make the team color for team 'admin' dark red
|
||||||
|
team_property('admin','prefix',format('r Admin | ')) Set prefix of all players in 'admin'
|
||||||
|
team_property('admin','display_name','Administrators') Set display name for team 'admin'
|
||||||
|
team_property('admin','seeFriendlyInvisibles',true) Make all players in 'admin' see other admins even when invisible
|
||||||
|
team_property('admin','deathMessageVisibility','hideForOtherTeams') Make all players in 'admin' see other admins even when invisible
|
||||||
|
```
|
||||||
|
|
||||||
# Auxiliary aspects
|
# Auxiliary aspects
|
||||||
|
|
||||||
Collection of other methods that control smaller, yet still important aspects of the game
|
Collection of other methods that control smaller, yet still important aspects of the game
|
||||||
|
|||||||
@@ -3,29 +3,30 @@
|
|||||||
## Manipulating inventories of blocks and entities
|
## Manipulating inventories of blocks and entities
|
||||||
|
|
||||||
Most functions in this category require inventory as the first argument. Inventory could be specified by an entity,
|
Most functions in this category require inventory as the first argument. Inventory could be specified by an entity,
|
||||||
or a block, or position (three coordinates) of a potential block with inventory. Player enderchest inventory require
|
or a block, or position (three coordinates) of a potential block with inventory, or can be preceded with inventory
|
||||||
two arguments, keyword `'enderchest'`, followed by the player entity argument, or a single argument as a string of a
|
type.
|
||||||
form: `'enderchest_steve'`. If your player name starts with enderchest, it can be always accessed by passing a player
|
Inventory type can be `null` (default), `'enderchest'` denoting player enderchest storage, or `'equipment'` applying to
|
||||||
|
entities hand and armour pieces. Then the type can be followed by entity, block or position coordinates.
|
||||||
|
For instance, player enderchest inventory requires
|
||||||
|
two arguments, keyword `'enderchest'`, followed by the player entity argument, (or a single argument as a string of a
|
||||||
|
form: `'enderchest_steve'` for legacy support). If your player name starts with `'enderchest_'`, first of all, tough luck,
|
||||||
|
but then it can be always accessed by passing a player
|
||||||
entity value. If all else fails, it will try to identify first three arguments as coordinates of a block position of
|
entity value. If all else fails, it will try to identify first three arguments as coordinates of a block position of
|
||||||
a block inventory. Player inventories can also be called by their name.
|
a block inventory. Player inventories can also be called by their name.
|
||||||
|
|
||||||
You can also use `'equipment'` as a keyword preceeding an entity indicating the need of access that entity as a mob.
|
A few living entities can have both: their regular inventory, and their equipment inventory.
|
||||||
Equipment inventory
|
Player's regular inventory already contains the equipment, but you can access the equipment part as well, as well as
|
||||||
consists of its armour and hand items, and a few living entites can have both, their regular inventory, and their equipment inventory. For some
|
their enderchest separately. For entity types that only have
|
||||||
entities (players) their regular inventory already contains the equipment. For entity types that only have
|
their equipment inventory, the equipment is returned by default (`null` type).
|
||||||
their equipment inventory, the equipment is returned by default.
|
|
||||||
|
If that's confusing see examples under `inventory_size` on how to access inventories. All other `inventory_...()` functions
|
||||||
|
use the same scheme.
|
||||||
|
|
||||||
<pre>
|
|
||||||
inventory_size(player()) => 41 // items
|
|
||||||
inventory_size('enderchest', player()) => 27 // equipment
|
|
||||||
inventory_size('equipment', player()) => 6 // equipment
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
If the entity or a block doesn't have
|
If the entity or a block doesn't have
|
||||||
an inventory, they typically do nothing and return null.
|
an inventory, all API functions typically do nothing and return null.
|
||||||
|
|
||||||
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
Most items returned are in the form of a triple of item name, count, and nbt or the extra data associated with an item.
|
||||||
Manipulating of the nbt data can be costly, but retrieving them from the tuple to match other aspects is cheap
|
|
||||||
|
|
||||||
### `stack_limit(item)`
|
### `stack_limit(item)`
|
||||||
|
|
||||||
@@ -98,14 +99,26 @@ item name that serves as a replacement after crafting is done. Currently it can
|
|||||||
### `inventory_size(inventory)`
|
### `inventory_size(inventory)`
|
||||||
|
|
||||||
Returns the size of the inventory for the entity or block in question. Returns null if the block or entity don't
|
Returns the size of the inventory for the entity or block in question. Returns null if the block or entity don't
|
||||||
have an inventory
|
have an inventory.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
inventory_size(player()) => 41
|
inventory_size(player()) => 41
|
||||||
inventory_size('enderchest', player()) => 27 // enderchest
|
inventory_size('enderchest', player()) => 27 // enderchest
|
||||||
inventory_size('equipment', player()) => 6 // equipment
|
inventory_size('equipment', player()) => 6 // equipment
|
||||||
|
inventory_size(null, player()) => 41 // default inventory for players
|
||||||
|
|
||||||
inventory_size(x,y,z) => 27 // chest
|
inventory_size(x,y,z) => 27 // chest
|
||||||
inventory_size(block(pos)) => 5 // hopper
|
inventory_size(block(pos)) => 5 // hopper
|
||||||
|
|
||||||
|
horse = spawn('horse', x, y, z);
|
||||||
|
inventory_size(horse); => 2 // default horse inventory
|
||||||
|
inventory_size('equipment', horse); => 6 // unused horse equipment inventory
|
||||||
|
inventory_size(null, horse); => 2 // default horse
|
||||||
|
|
||||||
|
creeper = spawn('creeper', x, y, z);
|
||||||
|
inventory_size(creeper); => 6 // default creeper inventory is equipment since it has no other
|
||||||
|
inventory_size('equipment', creeper); => 6 // unused horse equipment inventory
|
||||||
|
inventory_size(null, creeper); => 6 // creeper default is its equipment
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
### `inventory_has_items(inventory)`
|
### `inventory_has_items(inventory)`
|
||||||
|
|||||||
@@ -214,6 +214,11 @@ Here is a list of built-in types, with their return value formats, as well as a
|
|||||||
* `'players'`: returning a list of valid player name string, logged in or not. If configured with `'single'` returns only one player or `null`.
|
* `'players'`: returning a list of valid player name string, logged in or not. If configured with `'single'` returns only one player or `null`.
|
||||||
* `'intrange'`: same as `'floatrange'`, but requiring integers.
|
* `'intrange'`: same as `'floatrange'`, but requiring integers.
|
||||||
* `'enchantment'`: name of an enchantment
|
* `'enchantment'`: name of an enchantment
|
||||||
|
* `'slot'`: provides a list of inventory type and slot. Can be configured with `'restrict'` requiring
|
||||||
|
`'player'`, `'enderchest'`, `'equipment'`, `'armor'`, `'weapon'`, `'container'`, `'villager'` or `'horse'` restricting selection of
|
||||||
|
available slots. Scarpet supports all vanilla slots, except for `horse.chest` - chest item, not items themselves. This you would
|
||||||
|
need to manage yourself via nbt directly. Also, for entities that change their capacity, like llamas, you need to check yourself if
|
||||||
|
the specified container slot is valid for your entity.
|
||||||
* `'item'`: triple of item type, count of 1, and nbt.
|
* `'item'`: triple of item type, count of 1, and nbt.
|
||||||
* `'message'`: text with expanded embedded player names
|
* `'message'`: text with expanded embedded player names
|
||||||
* `'effect'`: string representing a status effect
|
* `'effect'`: string representing a status effect
|
||||||
|
|||||||
@@ -27,5 +27,80 @@ for the objective.
|
|||||||
|
|
||||||
### `scoreboard_display(place, objective)`
|
### `scoreboard_display(place, objective)`
|
||||||
|
|
||||||
sets display location for a specified `objective`. If `objective` is `null`, then display is cleared. If objective is invalid,
|
Sets display location for a specified `objective`. If `objective` is `null`, then display is cleared. If objective is invalid,
|
||||||
returns `null`.
|
returns `null`.
|
||||||
|
|
||||||
|
# Team
|
||||||
|
|
||||||
|
### `team_list()`, `team_list(team)`
|
||||||
|
|
||||||
|
Returns all available teams as a list with no arguments.
|
||||||
|
|
||||||
|
When a `team` is specified, it returns all the players inside that team. If the `team` is invalid, returns `null`.
|
||||||
|
|
||||||
|
### `team_add(team)`, `team_add(team,player)`
|
||||||
|
|
||||||
|
With one argument, creates a new `team` and returns its name if successful, or `null` if team already exists.
|
||||||
|
|
||||||
|
|
||||||
|
`team_add('admin')` -> Create a team with the name 'admin'
|
||||||
|
`team_add('admin','Steve')` -> Joing the player 'Steve' into the team 'admin'
|
||||||
|
|
||||||
|
If a `player` is specified, the player will join the given `team`. Returns `true` if player joined the team, or `false` if nothing changed since the player was already in this team. If the team is invalid, returns `null`
|
||||||
|
|
||||||
|
### `team_remove(team)`
|
||||||
|
|
||||||
|
Removes a `team`. Returns `true` if the team was deleted, or `null` if the team is invalid.
|
||||||
|
|
||||||
|
### `team_leave(player)`
|
||||||
|
|
||||||
|
Removes the `player` from the team he is in. Returns `true` if the player left a team, otherwise `false`.
|
||||||
|
|
||||||
|
`team_leave('Steve')` -> Removes Steve from the team he is currently in
|
||||||
|
`for(team_list('admin'), team_leave('admin', _))` -> Remove all players from team 'admin'
|
||||||
|
|
||||||
|
### `team_property(team,property,value?)`
|
||||||
|
|
||||||
|
Reads the `property` of the `team` if no `value` is specified. If a `value` is added as a third argument, it sets the `property` to that `value`.
|
||||||
|
|
||||||
|
* `collisionRule`
|
||||||
|
* Type: String
|
||||||
|
* Options: always, never, pushOtherTeams, pushOwnTeam
|
||||||
|
|
||||||
|
* `color`
|
||||||
|
* Type: String
|
||||||
|
* Options: See [team command](https://minecraft.gamepedia.com/Commands/team#Arguments) (same strings as `'teamcolor'` [command argument](https://github.com/gnembon/fabric-carpet/blob/master/docs/scarpet/Full.md#command-argument-types] options))
|
||||||
|
|
||||||
|
* `displayName`
|
||||||
|
* Type: String or FormattedText, when querying returns FormattedText
|
||||||
|
|
||||||
|
* `prefix`
|
||||||
|
* Type: String or FormattedText, when querying returns FormattedText
|
||||||
|
|
||||||
|
* `suffix`
|
||||||
|
* Type: String or FormattedText, when querying returns FormattedText
|
||||||
|
|
||||||
|
* `friendlyFire`
|
||||||
|
* Type: boolean
|
||||||
|
|
||||||
|
* `seeFriendlyInvisibles`
|
||||||
|
* Type: boolean
|
||||||
|
|
||||||
|
* `nametagVisibility`
|
||||||
|
* Type: String
|
||||||
|
* Options: always, never, hideForOtherTeams, hideForOwnTeam
|
||||||
|
|
||||||
|
* `deathMessageVisibility`
|
||||||
|
* Type: String
|
||||||
|
* Options: always, never, hideForOtherTeams, hideForOwnTeam
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```
|
||||||
|
team_property('admin','color','dark_red') Make the team color for team 'admin' dark red
|
||||||
|
team_property('admin','prefix',format('r Admin | ')) Set prefix of all players in 'admin'
|
||||||
|
team_property('admin','display_name','Administrators') Set display name for team 'admin'
|
||||||
|
team_property('admin','seeFriendlyInvisibles',true) Make all players in 'admin' see other admins even when invisible
|
||||||
|
team_property('admin','deathMessageVisibility','hideForOtherTeams') Make all players in 'admin' see other admins even when invisible
|
||||||
|
```
|
||||||
|
|
||||||
@@ -84,6 +84,11 @@ scoreboard
|
|||||||
scoreboard_add
|
scoreboard_add
|
||||||
scoreboard_remove
|
scoreboard_remove
|
||||||
scoreboard_display
|
scoreboard_display
|
||||||
|
team_add
|
||||||
|
team_list
|
||||||
|
team_remove
|
||||||
|
team_leave
|
||||||
|
team_property
|
||||||
see_sky
|
see_sky
|
||||||
set
|
set
|
||||||
set_biome
|
set_biome
|
||||||
|
|||||||
@@ -60,6 +60,8 @@
|
|||||||
|
|
||||||
scoreboard scoreboard_add scoreboard_remove scoreboard_display
|
scoreboard scoreboard_add scoreboard_remove scoreboard_display
|
||||||
|
|
||||||
|
team_add team_list team_remove team_leave team_property
|
||||||
|
|
||||||
player spawn entity_id entity_list entity_area entity_selector query modify entity_event entity_load_handler entity_types
|
player spawn entity_id entity_list entity_area entity_selector query modify entity_event entity_load_handler entity_types
|
||||||
|
|
||||||
stack_limit item_category recipe_data crafting_remaining_item
|
stack_limit item_category recipe_data crafting_remaining_item
|
||||||
|
|||||||
@@ -60,6 +60,8 @@
|
|||||||
|
|
||||||
scoreboard scoreboard_add scoreboard_remove scoreboard_display
|
scoreboard scoreboard_add scoreboard_remove scoreboard_display
|
||||||
|
|
||||||
|
team_add team_list team_remove team_leave team_property
|
||||||
|
|
||||||
player spawn entity_id entity_list entity_area entity_selector query modify entity_event
|
player spawn entity_id entity_list entity_area entity_selector query modify entity_event
|
||||||
|
|
||||||
stack_limit item_category recipe_data crafting_remaining_item
|
stack_limit item_category recipe_data crafting_remaining_item
|
||||||
|
|||||||
@@ -9,14 +9,20 @@ import carpet.script.value.ListValue;
|
|||||||
import carpet.script.value.NullValue;
|
import carpet.script.value.NullValue;
|
||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
|
import carpet.script.value.FormattedTextValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.scoreboard.Scoreboard;
|
import net.minecraft.scoreboard.Scoreboard;
|
||||||
|
import net.minecraft.scoreboard.ServerScoreboard;
|
||||||
import net.minecraft.scoreboard.ScoreboardCriterion;
|
import net.minecraft.scoreboard.ScoreboardCriterion;
|
||||||
import net.minecraft.scoreboard.ScoreboardObjective;
|
import net.minecraft.scoreboard.ScoreboardObjective;
|
||||||
import net.minecraft.scoreboard.ScoreboardPlayerScore;
|
import net.minecraft.scoreboard.ScoreboardPlayerScore;
|
||||||
|
import net.minecraft.scoreboard.Team;
|
||||||
|
import net.minecraft.scoreboard.AbstractTeam;
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -147,5 +153,249 @@ public class Scoreboards {
|
|||||||
scoreboard.setObjectiveSlot(slot, objective);
|
scoreboard.setObjectiveSlot(slot, objective);
|
||||||
return (_c, _t) -> new NumericValue(slot);
|
return (_c, _t) -> new NumericValue(slot);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
expression.addLazyFunction("team_list", -1, (c, t, lv) ->
|
||||||
|
{
|
||||||
|
if(lv.size() > 1) throw new InternalExpressionException("'team_list' requires zero or one parameters");
|
||||||
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
|
||||||
|
if(lv.size() == 0) {
|
||||||
|
Value ret = ListValue.wrap(scoreboard.getTeamNames().stream().map(StringValue::of).collect(Collectors.toList()));
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
} else if(lv.size() == 1) {
|
||||||
|
Team team = scoreboard.getTeam(lv.get(0).evalValue(c).getString());
|
||||||
|
if(team == null) return LazyValue.NULL;
|
||||||
|
Value ret = ListValue.wrap(team.getPlayerList().stream().map(StringValue::of).collect(Collectors.toList()));
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
} else {
|
||||||
|
return LazyValue.NULL;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
expression.addLazyFunction("team_add", -1, (c, t, lv) ->
|
||||||
|
{
|
||||||
|
if(!(lv.size() < 3 && lv.size() > 0)) throw new InternalExpressionException("'team_add' requires one or two parameters");
|
||||||
|
|
||||||
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
|
||||||
|
String teamName = lv.get(0).evalValue(c).getString();
|
||||||
|
|
||||||
|
if(lv.size() == 1) {
|
||||||
|
if(scoreboard.getTeam(teamName) == null) {
|
||||||
|
scoreboard.addTeam(teamName);
|
||||||
|
Value ret = new StringValue(teamName);
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
} else {
|
||||||
|
return LazyValue.NULL;
|
||||||
|
}
|
||||||
|
} else if(lv.size() == 2) {
|
||||||
|
Value playerVal = lv.get(1).evalValue(c);
|
||||||
|
|
||||||
|
String player = EntityValue.getPlayerNameByValue(playerVal);
|
||||||
|
if(player == null) return LazyValue.NULL;
|
||||||
|
|
||||||
|
Team team = scoreboard.getTeam(teamName);
|
||||||
|
if(team == null) return LazyValue.NULL;
|
||||||
|
|
||||||
|
if(team.isEqual(scoreboard.getPlayerTeam(player))) {
|
||||||
|
return LazyValue.FALSE;
|
||||||
|
} else {
|
||||||
|
scoreboard.addPlayerToTeam(player,scoreboard.getTeam(teamName));
|
||||||
|
return LazyValue.TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return LazyValue.NULL;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expression.addLazyFunction("team_remove", 1, (c, t, lv) ->
|
||||||
|
{
|
||||||
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
|
||||||
|
Value teamVal = lv.get(0).evalValue(c);
|
||||||
|
|
||||||
|
String team = teamVal.getString();
|
||||||
|
|
||||||
|
if(scoreboard.getTeam(team) != null) {
|
||||||
|
scoreboard.removeTeam(scoreboard.getTeam(team));
|
||||||
|
return LazyValue.TRUE;
|
||||||
|
} else {
|
||||||
|
return LazyValue.NULL;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
expression.addLazyFunction("team_leave", 1, (c, t, lv) ->
|
||||||
|
{
|
||||||
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
|
||||||
|
Value playerVal = lv.get(0).evalValue(c);
|
||||||
|
|
||||||
|
String player = EntityValue.getPlayerNameByValue(playerVal);
|
||||||
|
if(player == null) return LazyValue.NULL;
|
||||||
|
|
||||||
|
Value ret = new NumericValue(scoreboard.clearPlayerTeam(player));
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
expression.addLazyFunction("team_property", -1, (c, t, lv) ->
|
||||||
|
{
|
||||||
|
CarpetContext cc = (CarpetContext)c;
|
||||||
|
ServerScoreboard scoreboard = cc.s.getMinecraftServer().getScoreboard();
|
||||||
|
|
||||||
|
if(lv.size() < 2 || lv.size() > 3) throw new InternalExpressionException("'team_property' requires two or three arguments");
|
||||||
|
|
||||||
|
Value teamVal = lv.get(0).evalValue(c);
|
||||||
|
Value propertyVal = lv.get(1).evalValue(c);
|
||||||
|
|
||||||
|
Value settingVal = null;
|
||||||
|
boolean modifying = false;
|
||||||
|
if(lv.size() == 3) {
|
||||||
|
modifying = true;
|
||||||
|
settingVal = lv.get(2).evalValue(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
Team team = scoreboard.getTeam(teamVal.getString());
|
||||||
|
if(team == null) return LazyValue.NULL;
|
||||||
|
|
||||||
|
if(!(propertyVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the second argument");
|
||||||
|
|
||||||
|
switch (propertyVal.getString()) {
|
||||||
|
case "collision_rule":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new StringValue(team.getCollisionRule().name);
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
AbstractTeam.CollisionRule collisionRule = AbstractTeam.CollisionRule.getRule(settingVal.getString());
|
||||||
|
if(collisionRule == null) throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
||||||
|
team.setCollisionRule(collisionRule);
|
||||||
|
break;
|
||||||
|
case "color":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new StringValue(team.getColor().getName());
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
Formatting color = Formatting.byName(settingVal.getString().toUpperCase());
|
||||||
|
if(color == null || !color.isColor()) throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
||||||
|
team.setColor(color);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "death_message_visibility":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new StringValue(team.getDeathMessageVisibilityRule().name);
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
AbstractTeam.VisibilityRule deathMessageVisibility = AbstractTeam.VisibilityRule.getRule(settingVal.getString());
|
||||||
|
if(deathMessageVisibility == null) throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
||||||
|
team.setDeathMessageVisibilityRule(deathMessageVisibility);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "display_name":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new FormattedTextValue(team.getDisplayName());
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string or formatted text as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
Text displayName;
|
||||||
|
|
||||||
|
if(settingVal instanceof FormattedTextValue) {
|
||||||
|
displayName = ((FormattedTextValue) settingVal).getText();
|
||||||
|
} else {
|
||||||
|
displayName = new LiteralText(settingVal.getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
team.setDisplayName(displayName);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "friendly_fire":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new NumericValue(team.isFriendlyFireAllowed());
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof NumericValue)) throw new InternalExpressionException("'team_property' requires a boolean as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
boolean friendlyFire = settingVal.getBoolean();
|
||||||
|
team.setFriendlyFireAllowed(friendlyFire);
|
||||||
|
break;
|
||||||
|
case "nametag_visibility":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new StringValue(team.getNameTagVisibilityRule().name);
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
AbstractTeam.VisibilityRule nametagVisibility = AbstractTeam.VisibilityRule.getRule(settingVal.getString());
|
||||||
|
if(nametagVisibility == null) throw new InternalExpressionException("Unknown value for property " + propertyVal.getString() + ": " + settingVal.getString());
|
||||||
|
team.setNameTagVisibilityRule(nametagVisibility);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "prefix":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new FormattedTextValue(team.getPrefix());
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property ' requires a string or formatted text as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
Text prefix;
|
||||||
|
|
||||||
|
if(settingVal instanceof FormattedTextValue) {
|
||||||
|
prefix = ((FormattedTextValue) settingVal).getText();
|
||||||
|
} else {
|
||||||
|
prefix = new LiteralText(settingVal.getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
team.setPrefix(prefix);
|
||||||
|
break;
|
||||||
|
case "see_friendly_invisibles":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new NumericValue(team.shouldShowFriendlyInvisibles());
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof NumericValue)) throw new InternalExpressionException("'team_property' requires a boolean as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
boolean seeFriendlyInvisibles = settingVal.getBoolean();
|
||||||
|
team.setShowFriendlyInvisibles(seeFriendlyInvisibles);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "suffix":
|
||||||
|
if(!modifying) {
|
||||||
|
Value ret = new FormattedTextValue(team.getSuffix());
|
||||||
|
return (_c, _t) -> ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(settingVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string or formatted text as the third argument for the property " + propertyVal.getString());
|
||||||
|
|
||||||
|
Text suffix;
|
||||||
|
|
||||||
|
if(settingVal instanceof FormattedTextValue) {
|
||||||
|
suffix = ((FormattedTextValue) settingVal).getText();
|
||||||
|
} else {
|
||||||
|
suffix = new LiteralText(settingVal.getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
team.setSuffix(suffix);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InternalExpressionException("team property " + propertyVal.getString() + " is not a valid property");
|
||||||
|
}
|
||||||
|
return LazyValue.TRUE;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ import net.minecraft.command.argument.EntitySummonArgumentType;
|
|||||||
import net.minecraft.command.argument.GameProfileArgumentType;
|
import net.minecraft.command.argument.GameProfileArgumentType;
|
||||||
import net.minecraft.command.argument.IdentifierArgumentType;
|
import net.minecraft.command.argument.IdentifierArgumentType;
|
||||||
import net.minecraft.command.argument.ItemEnchantmentArgumentType;
|
import net.minecraft.command.argument.ItemEnchantmentArgumentType;
|
||||||
|
import net.minecraft.command.argument.ItemSlotArgumentType;
|
||||||
import net.minecraft.command.argument.ItemStackArgumentType;
|
import net.minecraft.command.argument.ItemStackArgumentType;
|
||||||
import net.minecraft.command.argument.MessageArgumentType;
|
import net.minecraft.command.argument.MessageArgumentType;
|
||||||
import net.minecraft.command.argument.MobEffectArgumentType;
|
import net.minecraft.command.argument.MobEffectArgumentType;
|
||||||
@@ -78,11 +79,14 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.Vec2f;
|
import net.minecraft.util.math.Vec2f;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -158,6 +162,7 @@ public abstract class CommandArgument
|
|||||||
),
|
),
|
||||||
// item_predicate ?? //same as item but accepts tags, not sure right now
|
// item_predicate ?? //same as item but accepts tags, not sure right now
|
||||||
// slot // item_slot
|
// slot // item_slot
|
||||||
|
new SlotArgument(),
|
||||||
new VanillaUnconfigurableArgument("item", ItemStackArgumentType::itemStack,
|
new VanillaUnconfigurableArgument("item", ItemStackArgumentType::itemStack,
|
||||||
(c, p) -> ValueConversions.of(ItemStackArgumentType.getItemStackArgument(c, p).createStack(1, false)), false
|
(c, p) -> ValueConversions.of(ItemStackArgumentType.getItemStackArgument(c, p).createStack(1, false)), false
|
||||||
),
|
),
|
||||||
@@ -849,6 +854,100 @@ public abstract class CommandArgument
|
|||||||
return IntArgument::new;
|
return IntArgument::new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static class SlotArgument extends CommandArgument
|
||||||
|
{
|
||||||
|
private String restrict;
|
||||||
|
private static final Map<String, Pair<Set<Integer>, Set<String>>> RESTRICTED_CONTAINERS = new HashMap<String, Pair<Set<Integer>, Set<String>>>(){{
|
||||||
|
int i;
|
||||||
|
for (String source : Arrays.asList("player", "enderchest", "equipment", "armor", "weapon", "container", "villager", "horse"))
|
||||||
|
put(source, Pair.of(new HashSet<>(), new HashSet<>()));
|
||||||
|
for (i = 0; i < 41; i++) get("player").getLeft().add(i);
|
||||||
|
for(i = 0; i < 41; i++) get("player").getRight().add("container." + i);
|
||||||
|
for(i = 0; i < 9; i++) get("player").getRight().add("hotbar." + i);
|
||||||
|
for(i = 0; i < 27; i++) get("player").getRight().add("inventory." + i);
|
||||||
|
for (String place : Arrays.asList("weapon", "weapon.mainhand", "weapon.offhand"))
|
||||||
|
{
|
||||||
|
get("player").getRight().add(place);
|
||||||
|
get("equipment").getRight().add(place);
|
||||||
|
get("weapon").getRight().add(place);
|
||||||
|
}
|
||||||
|
for (String place : Arrays.asList("armor.feet","armor.legs", "armor.chest","armor.head"))
|
||||||
|
{
|
||||||
|
get("player").getRight().add(place);
|
||||||
|
get("equipment").getRight().add(place);
|
||||||
|
get("armor").getRight().add(place);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 27; i++) get("enderchest").getLeft().add(200+i);
|
||||||
|
for(i = 0; i < 27; i++) get("enderchest").getRight().add("enderchest." + i);
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++) get("equipment").getLeft().add(98+i);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) get("armor").getLeft().add(100+i);
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) get("weapon").getLeft().add(98+i);
|
||||||
|
|
||||||
|
for (i = 0; i < 54; i++) get("container").getLeft().add(i);
|
||||||
|
for(i = 0; i < 41; i++) get("container").getRight().add("container." + i);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) get("villager").getLeft().add(i);
|
||||||
|
for(i = 0; i < 8; i++) get("villager").getRight().add("villager." + i);
|
||||||
|
|
||||||
|
for (i = 0; i < 15; i++) get("horse").getLeft().add(500+i);
|
||||||
|
for(i = 0; i < 15; i++) get("horse").getRight().add("horse." + i);
|
||||||
|
get("horse").getLeft().add(400);
|
||||||
|
get("horse").getRight().add("horse.saddle");
|
||||||
|
get("horse").getLeft().add(401);
|
||||||
|
get("horse").getRight().add("horse.armor");
|
||||||
|
}};
|
||||||
|
|
||||||
|
protected SlotArgument()
|
||||||
|
{
|
||||||
|
super("slot", ItemSlotArgumentType.itemSlot().getExamples(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ArgumentType<?> getArgumentType() throws CommandSyntaxException
|
||||||
|
{
|
||||||
|
return ItemSlotArgumentType.itemSlot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Value getValueFromContext(CommandContext<ServerCommandSource> context, String param) throws CommandSyntaxException
|
||||||
|
{
|
||||||
|
int slot = ItemSlotArgumentType.getItemSlot(context, param);
|
||||||
|
if (restrict != null && !RESTRICTED_CONTAINERS.get(restrict).getLeft().contains(slot))
|
||||||
|
{
|
||||||
|
throw new SimpleCommandExceptionType(new LiteralText("Incorrect slot restricted to "+restrict)).create();
|
||||||
|
}
|
||||||
|
return ValueConversions.ofVanillaSlotResult(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||||
|
{
|
||||||
|
super.configure(config, host);
|
||||||
|
if (config.containsKey("restrict"))
|
||||||
|
{
|
||||||
|
restrict = config.get("restrict").getString().toLowerCase(Locale.ROOT);
|
||||||
|
needsMatching = true;
|
||||||
|
if (!RESTRICTED_CONTAINERS.containsKey(restrict))
|
||||||
|
throw new InternalExpressionException("Incorrect slot restriction: "+restrict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Collection<String> getOptions(CommandContext<ServerCommandSource> context, CarpetScriptHost host) throws CommandSyntaxException
|
||||||
|
{
|
||||||
|
return restrict==null?super.getOptions(context, host):RESTRICTED_CONTAINERS.get(restrict).getRight();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Supplier<CommandArgument> factory()
|
||||||
|
{
|
||||||
|
return SlotArgument::new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
private interface ValueExtractor
|
private interface ValueExtractor
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package carpet.script.utils;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.Inventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class EquipmentInventory implements Inventory
|
||||||
|
{
|
||||||
|
private static final List<EquipmentSlot> slotToSlot = Arrays.asList(
|
||||||
|
EquipmentSlot.MAINHAND,
|
||||||
|
EquipmentSlot.FEET, EquipmentSlot.LEGS, EquipmentSlot.CHEST, EquipmentSlot.HEAD,
|
||||||
|
EquipmentSlot.OFFHAND
|
||||||
|
);
|
||||||
|
|
||||||
|
LivingEntity mob;
|
||||||
|
public EquipmentInventory(LivingEntity mob)
|
||||||
|
{
|
||||||
|
this.mob = mob;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
for (EquipmentSlot slot: slotToSlot)
|
||||||
|
if (!mob.getEquippedStack(slot).isEmpty()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getStack(int slot)
|
||||||
|
{
|
||||||
|
EquipmentSlot slotSlot;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
slotSlot = slotToSlot.get(slot);
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException ignored)
|
||||||
|
{
|
||||||
|
//going out of the index should be really exceptional
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return mob.getEquippedStack(slotSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack removeStack(int slot, int amount)
|
||||||
|
{
|
||||||
|
EquipmentSlot slotSlot;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
slotSlot = slotToSlot.get(slot);
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException ignored)
|
||||||
|
{
|
||||||
|
//going out of the index should be really exceptional
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ItemStack stack = mob.getEquippedStack(slotSlot);
|
||||||
|
stack.decrement(amount);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack removeStack(int slot)
|
||||||
|
{
|
||||||
|
EquipmentSlot slotSlot;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
slotSlot = slotToSlot.get(slot);
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException ignored)
|
||||||
|
{
|
||||||
|
//going out of the index should be really exceptional
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ItemStack previous = mob.getEquippedStack(slotSlot);
|
||||||
|
mob.equipStack(slotSlot, ItemStack.EMPTY);
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStack(int slot, ItemStack stack)
|
||||||
|
{
|
||||||
|
EquipmentSlot slotSlot;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
slotSlot = slotToSlot.get(slot);
|
||||||
|
}
|
||||||
|
catch (IndexOutOfBoundsException ignored)
|
||||||
|
{
|
||||||
|
//going out of the index should be really exceptional
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mob.equipStack(slotSlot, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markDirty()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlayerUse(PlayerEntity player)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
for (EquipmentSlot slot: slotToSlot)
|
||||||
|
mob.equipStack(slot, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package carpet.script.utils;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
|
||||||
import net.minecraft.entity.LivingEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.inventory.Inventory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
|
|
||||||
public class LivingInventory implements Inventory
|
|
||||||
{
|
|
||||||
private static final Int2ObjectMap<EquipmentSlot> slotToSlot = new Int2ObjectOpenHashMap<EquipmentSlot>(){{
|
|
||||||
put(0, EquipmentSlot.MAINHAND);
|
|
||||||
put(1, EquipmentSlot.FEET);
|
|
||||||
put(2, EquipmentSlot.LEGS);
|
|
||||||
put(3, EquipmentSlot.CHEST);
|
|
||||||
put(4, EquipmentSlot.HEAD);
|
|
||||||
put(5, EquipmentSlot.OFFHAND);
|
|
||||||
}};
|
|
||||||
|
|
||||||
LivingEntity mob;
|
|
||||||
public LivingInventory(LivingEntity mob)
|
|
||||||
{
|
|
||||||
this.mob = mob;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size()
|
|
||||||
{
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty()
|
|
||||||
{
|
|
||||||
for (EquipmentSlot slot: EquipmentSlot.values())
|
|
||||||
if (!mob.getEquippedStack(slot).isEmpty()) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack getStack(int slot)
|
|
||||||
{
|
|
||||||
EquipmentSlot slotSlot = slotToSlot.getOrDefault(slot, null);
|
|
||||||
if (slotSlot == null) return null;
|
|
||||||
return mob.getEquippedStack(slotToSlot.get(slot));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack removeStack(int slot, int amount)
|
|
||||||
{
|
|
||||||
EquipmentSlot slotSlot = slotToSlot.getOrDefault(slot, null);
|
|
||||||
if (slotSlot == null) return null;
|
|
||||||
ItemStack stack = mob.getEquippedStack(slotSlot);
|
|
||||||
stack.decrement(amount);
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack removeStack(int slot)
|
|
||||||
{
|
|
||||||
EquipmentSlot slotSlot = slotToSlot.getOrDefault(slot, null);
|
|
||||||
if (slotSlot == null) return null;
|
|
||||||
ItemStack previous = mob.getEquippedStack(slotSlot);
|
|
||||||
mob.equipStack(slotSlot, ItemStack.EMPTY);
|
|
||||||
return previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setStack(int slot, ItemStack stack)
|
|
||||||
{
|
|
||||||
EquipmentSlot slotSlot = slotToSlot.getOrDefault(slot, null);
|
|
||||||
if (slotSlot == null) return;
|
|
||||||
mob.equipStack(slotSlot, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void markDirty()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlayerUse(PlayerEntity player)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear()
|
|
||||||
{
|
|
||||||
for (EquipmentSlot slot: EquipmentSlot.values())
|
|
||||||
mob.equipStack(slot, ItemStack.EMPTY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -144,6 +144,28 @@ public class EntityValue extends Value
|
|||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getPlayerNameByValue(Value value)
|
||||||
|
{
|
||||||
|
String playerName = null;
|
||||||
|
if (value instanceof EntityValue)
|
||||||
|
{
|
||||||
|
Entity e = ((EntityValue) value).getEntity();
|
||||||
|
if (e instanceof ServerPlayerEntity)
|
||||||
|
{
|
||||||
|
playerName = e.getEntityName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (value.isNull())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
playerName = value.getString();
|
||||||
|
}
|
||||||
|
return playerName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString()
|
public String getString()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import carpet.fakes.InventoryBearerInterface;
|
|||||||
import carpet.script.CarpetContext;
|
import carpet.script.CarpetContext;
|
||||||
import carpet.script.LazyValue;
|
import carpet.script.LazyValue;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.utils.LivingInventory;
|
import carpet.script.utils.EquipmentInventory;
|
||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@@ -175,47 +175,15 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static InventoryLocator locateInventory(CarpetContext c, List<LazyValue> params, int offset)
|
public static InventoryLocator locateInventory(CarpetContext c, List<LazyValue> params, int offset)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Inventory inv = null;
|
Value v1 = params.get(offset).evalValue(c);
|
||||||
Value v1 = params.get(0 + offset).evalValue(c);
|
if (v1.isNull())
|
||||||
if (v1 instanceof EntityValue)
|
|
||||||
{
|
{
|
||||||
Entity e = ((EntityValue) v1).getEntity();
|
offset ++;
|
||||||
if (e instanceof PlayerEntity) inv = ((PlayerEntity) e).getInventory();
|
v1 = params.get(offset).evalValue(c);
|
||||||
else if (e instanceof Inventory) inv = (Inventory) e;
|
|
||||||
else if (e instanceof VillagerEntity) inv = ((VillagerEntity) e).getInventory();
|
|
||||||
else if (e instanceof InventoryBearerInterface) inv = ((InventoryBearerInterface)e).getCMInventory();
|
|
||||||
else if (e instanceof LivingEntity) inv = new LivingInventory((MobEntity) e);
|
|
||||||
if (inv == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new InventoryLocator(e, e.getBlockPos(), inv, offset + 1);
|
|
||||||
}
|
|
||||||
else if (v1 instanceof BlockValue)
|
|
||||||
{
|
|
||||||
BlockPos pos = ((BlockValue) v1).getPos();
|
|
||||||
if (pos == null)
|
|
||||||
throw new InternalExpressionException("Block to access inventory needs to be positioned in the world");
|
|
||||||
inv = getInventoryAt(c.s.getWorld(), pos);
|
|
||||||
if (inv == null)
|
|
||||||
return null;
|
|
||||||
return new InventoryLocator(pos, pos, inv, offset + 1);
|
|
||||||
}
|
|
||||||
else if (v1 instanceof ListValue)
|
|
||||||
{
|
|
||||||
List<Value> args = ((ListValue) v1).getItems();
|
|
||||||
BlockPos pos = new BlockPos(
|
|
||||||
NumericValue.asNumber(args.get(0)).getDouble(),
|
|
||||||
NumericValue.asNumber(args.get(1)).getDouble(),
|
|
||||||
NumericValue.asNumber(args.get(2)).getDouble());
|
|
||||||
inv = getInventoryAt(c.s.getWorld(), pos);
|
|
||||||
if (inv == null)
|
|
||||||
return null;
|
|
||||||
return new InventoryLocator(pos, pos, inv, offset + 1);
|
|
||||||
}
|
}
|
||||||
else if (v1 instanceof StringValue)
|
else if (v1 instanceof StringValue)
|
||||||
{
|
{
|
||||||
@@ -227,16 +195,14 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
if (player == null) throw new InternalExpressionException("enderchest inventory requires player argument");
|
if (player == null) throw new InternalExpressionException("enderchest inventory requires player argument");
|
||||||
return new InventoryLocator(player, player.getBlockPos(), player.getEnderChestInventory(), offset + 2, true);
|
return new InventoryLocator(player, player.getBlockPos(), player.getEnderChestInventory(), offset + 2, true);
|
||||||
}
|
}
|
||||||
else if (strVal.equals("equipment"))
|
if (strVal.equals("equipment"))
|
||||||
{
|
{
|
||||||
Value v2 = params.get(1 + offset).evalValue(c);
|
Value v2 = params.get(1 + offset).evalValue(c);
|
||||||
if (!(v2 instanceof EntityValue)) throw new InternalExpressionException("mob inventory requires a mob argument");
|
if (!(v2 instanceof EntityValue)) throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
||||||
Entity e = ((EntityValue) v2).getEntity();
|
Entity e = ((EntityValue) v2).getEntity();
|
||||||
if (!(e instanceof LivingEntity)) throw new InternalExpressionException("mob inventory requires a mob argument");
|
if (!(e instanceof LivingEntity)) throw new InternalExpressionException("Equipment inventory requires a living entity argument");
|
||||||
return new InventoryLocator(e, e.getBlockPos(), new LivingInventory((LivingEntity) e), offset + 2, false);
|
return new InventoryLocator(e, e.getBlockPos(), new EquipmentInventory((LivingEntity) e), offset + 2);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
boolean isEnder = strVal.startsWith("enderchest_");
|
boolean isEnder = strVal.startsWith("enderchest_");
|
||||||
if (isEnder) strVal = strVal.substring(11); // len("enderchest_")
|
if (isEnder) strVal = strVal.substring(11); // len("enderchest_")
|
||||||
ServerPlayerEntity player = c.s.getMinecraftServer().getPlayerManager().getPlayer(strVal);
|
ServerPlayerEntity player = c.s.getMinecraftServer().getPlayerManager().getPlayer(strVal);
|
||||||
@@ -244,17 +210,52 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
|||||||
return new InventoryLocator(
|
return new InventoryLocator(
|
||||||
player,
|
player,
|
||||||
player.getBlockPos(),
|
player.getBlockPos(),
|
||||||
isEnder ? player.getEnderChestInventory() : player.getInventory(),
|
isEnder ? player.getEnderChestInventory() : player.inventory,
|
||||||
offset + 1,
|
offset + 1,
|
||||||
isEnder
|
isEnder
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (v1 instanceof EntityValue)
|
||||||
|
{
|
||||||
|
Inventory inv = null;
|
||||||
|
Entity e = ((EntityValue) v1).getEntity();
|
||||||
|
if (e instanceof PlayerEntity) inv = ((PlayerEntity) e).getInventory();
|
||||||
|
else if (e instanceof Inventory) inv = (Inventory) e;
|
||||||
|
else if (e instanceof VillagerEntity) inv = ((VillagerEntity) e).getInventory();
|
||||||
|
else if (e instanceof InventoryBearerInterface) inv = ((InventoryBearerInterface)e).getCMInventory();
|
||||||
|
else if (e instanceof LivingEntity) return new InventoryLocator(e, e.getBlockPos(), new EquipmentInventory((MobEntity) e), offset+1);
|
||||||
|
if (inv == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new InventoryLocator(e, e.getBlockPos(), inv, offset+1);
|
||||||
|
}
|
||||||
|
if (v1 instanceof BlockValue)
|
||||||
|
{
|
||||||
|
BlockPos pos = ((BlockValue) v1).getPos();
|
||||||
|
if (pos == null)
|
||||||
|
throw new InternalExpressionException("Block to access inventory needs to be positioned in the world");
|
||||||
|
Inventory inv = getInventoryAt(c.s.getWorld(), pos);
|
||||||
|
if (inv == null)
|
||||||
|
return null;
|
||||||
|
return new InventoryLocator(pos, pos, inv, offset+1);
|
||||||
|
}
|
||||||
|
if (v1 instanceof ListValue)
|
||||||
|
{
|
||||||
|
List<Value> args = ((ListValue) v1).getItems();
|
||||||
|
BlockPos pos = new BlockPos(
|
||||||
|
NumericValue.asNumber(args.get(0)).getDouble(),
|
||||||
|
NumericValue.asNumber(args.get(1)).getDouble(),
|
||||||
|
NumericValue.asNumber(args.get(2)).getDouble());
|
||||||
|
Inventory inv = getInventoryAt(c.s.getWorld(), pos);
|
||||||
|
if (inv == null)
|
||||||
|
return null;
|
||||||
|
return new InventoryLocator(pos, pos, inv, offset+1);
|
||||||
}
|
}
|
||||||
BlockPos pos = new BlockPos(
|
BlockPos pos = new BlockPos(
|
||||||
NumericValue.asNumber(v1).getDouble(),
|
NumericValue.asNumber(v1).getDouble(),
|
||||||
NumericValue.asNumber(params.get(1 + offset).evalValue(c)).getDouble(),
|
NumericValue.asNumber(params.get(1 + offset).evalValue(c)).getDouble(),
|
||||||
NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble());
|
NumericValue.asNumber(params.get(2 + offset).evalValue(c)).getDouble());
|
||||||
inv = getInventoryAt(c.s.getWorld(), pos);
|
Inventory inv = getInventoryAt(c.s.getWorld(), pos);
|
||||||
if (inv == null)
|
if (inv == null)
|
||||||
return null;
|
return null;
|
||||||
return new InventoryLocator(pos, pos, inv, offset + 3);
|
return new InventoryLocator(pos, pos, inv, offset + 3);
|
||||||
|
|||||||
@@ -330,4 +330,49 @@ public class ValueConversions
|
|||||||
}
|
}
|
||||||
throw new InternalExpressionException("Unknown property type: "+p.getName());
|
throw new InternalExpressionException("Unknown property type: "+p.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final Map<Integer, ListValue> slotIdsToSlotParams = new HashMap<Integer, ListValue>() {{
|
||||||
|
int n;
|
||||||
|
//covers blocks, player hotbar and inventory, and all default inventories
|
||||||
|
for(n = 0; n < 54; ++n) {
|
||||||
|
put(n, ListValue.of(Value.NULL, NumericValue.of(n)));
|
||||||
|
}
|
||||||
|
for(n = 0; n < 27; ++n) {
|
||||||
|
put(200+n, ListValue.of(StringValue.of("enderchest"), NumericValue.of(n)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// villager
|
||||||
|
for(n = 0; n < 8; ++n) {
|
||||||
|
put(300+n, ListValue.of(Value.NULL, NumericValue.of(n)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// horse, llamas, donkeys, etc.
|
||||||
|
// two first slots are for saddle and armour
|
||||||
|
for(n = 0; n < 15; ++n) {
|
||||||
|
put(500+n, ListValue.of(Value.NULL, NumericValue.of(n+2)));
|
||||||
|
}
|
||||||
|
Value equipment = StringValue.of("equipment");
|
||||||
|
// weapon main hand
|
||||||
|
put(98, ListValue.of(equipment, NumericValue.of(0)));
|
||||||
|
// offhand
|
||||||
|
put(99, ListValue.of(equipment, NumericValue.of(5)));
|
||||||
|
// feet, legs, chest, head
|
||||||
|
for(n = 0; n < 4; ++n) {
|
||||||
|
put(100+n, ListValue.of(equipment, NumericValue.of(n+1)));
|
||||||
|
}
|
||||||
|
//horse defaults saddle
|
||||||
|
put(400, ListValue.of(Value.NULL, NumericValue.of(0)));
|
||||||
|
// armor
|
||||||
|
put(401, ListValue.of(Value.NULL, NumericValue.of(1)));
|
||||||
|
// chest itself on the donkey is wierd - use NBT to alter that.
|
||||||
|
//hashMap.put("horse.chest", 499);
|
||||||
|
}};
|
||||||
|
|
||||||
|
public static Value ofVanillaSlotResult(int itemSlot)
|
||||||
|
{
|
||||||
|
Value ret = slotIdsToSlotParams.get(itemSlot);
|
||||||
|
if (ret == null) return ListValue.of(Value.NULL, NumericValue.of(itemSlot));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user