Merge branch 'master' into 1.17
This commit is contained in:
commit
4f7ebdd9ff
23 files changed
+305
-171
No files matched your search
+41
-49
@@ -2204,21 +2204,34 @@ Deprecated by `block_state(pos, name)`
|
||||
If used with a `block` argument only, it returns a map of block properties and their values. If a block has no properties, returns an
|
||||
empty map.
|
||||
|
||||
If `property` is specified, returns value of that property, or `null` if property is not applicable.
|
||||
If `property` is specified, returns a string value of that property, or `null` if property is not applicable.
|
||||
|
||||
Returned values or properties are always strings. It is expected from the user to know what to expect and convert
|
||||
values to numbers using `number()` function or booleans using `bool()` function. Returned string values can be directly used
|
||||
back in state definition in various applications where block properties are required.
|
||||
|
||||
`block_state` can also accept block names as input, returning block's default state.
|
||||
|
||||
<pre>
|
||||
set(x,y,z,'iron_trapdoor','half','top'); block_state(x,y,z) => {waterlogged: false, half: top, open: false, ...}
|
||||
set(x,y,z,'iron_trapdoor','half','top'); block_state(x,y,z,'half') => top
|
||||
block_state('iron_trapdoor','half') => top
|
||||
set(x,y,z,'air'); block_state(x,y,z,'half') => null
|
||||
block_state(block('iron_trapdoor[half=top]'),'half') => top
|
||||
block_state(block('iron_trapdoor[half=top]'),'powered') => false
|
||||
bool(block_state(block('iron_trapdoor[half=top]'),'powered')) => 0
|
||||
</pre>
|
||||
|
||||
### `block_list()`, `block_list(tag)`
|
||||
|
||||
Returns list of all blocks. If tag is provided, returns list of blocks that belong to this block tag.
|
||||
|
||||
### `block_tags()`, `block_tags(block)`, `block_tags(block, tag)`
|
||||
|
||||
Without arguments, returns list of available tags, with block supplied (either by coordinates, or via block name), returns lost
|
||||
of tags the block belongs to, and if a tag is specified, returns `null` if tag is invalid, `false` if this block doesn't belong
|
||||
to this tag, and `true` if the block belongs to the tag.
|
||||
|
||||
### `block_data(pos)`
|
||||
|
||||
Return NBT string associated with specific location, or null if the block does not carry block data. Can be currently
|
||||
@@ -2460,9 +2473,12 @@ This function is tentative - will likely change when chunk ticket API is properl
|
||||
Scarpet provides convenient methods to access and modify information about structures as well as spawn in-game
|
||||
structures and features. List of available options and names that you can use depends mostly if you are using scarpet
|
||||
with minecraft 1.16.1 and below or 1.16.2 and above since in 1.16.2 Mojang has added JSON support for worldgen features
|
||||
meaning that since 1.16.2 - they have official names that can be used by datapacks and scarpet
|
||||
meaning that since 1.16.2 - they have official names that can be used by datapacks and scarpet. If you have most recent
|
||||
scarpet on 1.16.4, you can use `plop()` to get all available worldgen features including custom features and structures
|
||||
controlled by datapacks. It returns a map of lists in the following categories:
|
||||
`'scarpet_custom'`, `'configured_features'`, `'structures'`, `'features'`, `'configured_structures'`
|
||||
|
||||
### Previous Structure Names, including variants (as of MC 1.16.3)
|
||||
### Previous Structure Names, including variants (MC1.16.1 and below)
|
||||
* `'monument'`: Ocean Monument. Generates at fixed Y coordinate, surrounds itself with water.
|
||||
* `'fortress'`: Nether Fortress. Altitude varies, but its bounded by the code.
|
||||
* `'mansion'`: Woodland Mansion
|
||||
@@ -2492,7 +2508,7 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
||||
* `'bastion_remnant_treasure'`: Treasure room version of a piglin bastion (1.16)
|
||||
* `'bastion_remnant_bridge'` : Bridge version of a piglin bastion (1.16)
|
||||
|
||||
### Feature Names (as of mc1.16.1)
|
||||
### Feature Names (1.16.1 and below)
|
||||
|
||||
* `'oak'`
|
||||
* `'oak_beehive'`: oak with a hive (1.15+).
|
||||
@@ -2556,13 +2572,17 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
||||
* `'twisting_vines'` (1.16)
|
||||
* `'basalt_pillar'` (1.16)
|
||||
|
||||
### Standard Structures (as of 1.16.2+)
|
||||
### Standard Structures (as of MC1.16.2+)
|
||||
|
||||
Use `plop():'structures'`, but it always returns the following:
|
||||
|
||||
`'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'endcity'`, `'fortress'`, `'igloo'`,
|
||||
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'monument'`, `'nether_fossil'`, `'ocean_ruin'`,
|
||||
`'pillager_outpost'`, `'ruined_portal'`, `'shipwreck'`, `'stronghold'`, `'swamp_hut'`, `'village'`
|
||||
|
||||
### Structure Variants (as of 1.16.2+)
|
||||
### Structure Variants (as of MC1.16.2+)
|
||||
|
||||
Use `plop():'configured_structures'`, but it always returns the following:
|
||||
|
||||
`'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'end_city'`, `'fortress'`, `'igloo'`,
|
||||
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'mineshaft_mesa'`, `'monument'`, `'nether_fossil'`,
|
||||
@@ -2571,48 +2591,16 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
||||
`'ruined_portal_swamp'`, `'shipwreck'`, `'shipwreck_beached'`, `'stronghold'`, `'swamp_hut'`,
|
||||
`'village_desert'`, `'village_plains'`, `'village_savanna'`, `'village_snovy'`, `'village_taiga'`
|
||||
|
||||
### World Generation Features (as of 1.16.2+)
|
||||
### World Generation Features (as of MC1.16.2+)
|
||||
|
||||
`'acacia'`, `'amethyst_geode'` (1.17+), `'bamboo'`, `'bamboo_light'`, `'bamboo_vegetation'`, `'basalt_blobs'`, `'basalt_pillar'`,
|
||||
`'birch'`, `'birch_bees_0002'`, `'birch_bees_002'`, `'birch_bees_005'`, `'birch_other'`, `'birch_tall'`,
|
||||
`'blackstone_blobs'`, `'blue_ice'`, `'bonus_chest'`, `'brown_mushroom_giant'`, `'brown_mushroom_nether'`,
|
||||
`'brown_mushroom_normal'`, `'brown_mushroom_swamp'`, `'brown_mushroom_taiga'`, `'chorus_plant'`,
|
||||
`'crimson_forest_vegetation'`, `'crimson_fungi'`, `'crimson_fungi_planted'`, `'dark_forest_vegetation_brown'`,
|
||||
`'dark_forest_vegetation_red'`, `'dark_oak'`, `'delta'`, `'desert_well'`, `'disk_clay'`, `'disk_gravel'`,
|
||||
`'disk_sand'`, `'end_gateway'`, `'end_gateway_delayed'`, `'end_island'`, `'end_island_decorated'`, `'end_spike'`,
|
||||
`'fancy_oak'`, `'fancy_oak_bees_0002'`, `'fancy_oak_bees_002'`, `'fancy_oak_bees_005'`, `'flower_default'`,
|
||||
`'flower_forest'`, `'flower_plain'`, `'flower_plain_decorated'`, `'flower_swamp'`, `'flower_warm'`,
|
||||
`'forest_flower_trees'`, `'forest_flower_vegetation'`, `'forest_flower_vegetation_common'`, `'forest_rock'`,
|
||||
`'fossil'`, `'freeze_top_layer'`, `'glowstone'`, `'glowstone_extra'`, `'huge_brown_mushroom'`,
|
||||
`'huge_red_mushroom'`, `'ice_patch'`, `'ice_spike'`, `'iceberg_blue'`, `'iceberg_packed'`, `'jungle_bush'`,
|
||||
`'jungle_tree'`, `'jungle_tree_no_vine'`, `'kelp_cold'`, `'kelp_warm'`, `'lake_lava'`, `'lake_water'`,
|
||||
`'large_basalt_columns'`, `'mega_jungle_tree'`, `'mega_pine'`, `'mega_spruce'`, `'monster_room'`,
|
||||
`'mushroom_field_vegetation'`, `'nether_sprouts'`, `'nope'`, `'oak'`, `'oak_badlands'`, `'oak_bees_0002'`,
|
||||
`'oak_bees_002'`, `'oak_bees_005'`, `'ore_andesite'`, `'ore_blackstone'`, `'ore_coal'`, `'ore_debris_large'`,
|
||||
`'ore_debris_small'`, `'ore_diamond'`, `'ore_diorite'`, `'ore_dirt'`, `'ore_emerald'`, `'ore_gold'`,
|
||||
`'ore_gold_deltas'`, `'ore_gold_extra'`, `'ore_gold_nether'`, `'ore_granite'`, `'ore_gravel'`,
|
||||
`'ore_gravel_nether'`, `'ore_infested'`, `'ore_iron'`, `'ore_lapis'`, `'ore_magma'`, `'ore_quartz_deltas'`,
|
||||
`'ore_quartz_nether'`, `'ore_redstone'`, `'ore_soul_sand'`, `'patch_berry_bush'`, `'patch_berry_decorated'`,
|
||||
`'patch_berry_sparse'`, `'patch_brown_mushroom'`, `'patch_cactus'`, `'patch_cactus_decorated'`,
|
||||
`'patch_cactus_desert'`, `'patch_crimson_roots'`, `'patch_dead_bush'`, `'patch_dead_bush_2'`,
|
||||
`'patch_dead_bush_badlands'`, `'patch_fire'`, `'patch_grass_badlands'`, `'patch_grass_forest'`,
|
||||
`'patch_grass_jungle'`, `'patch_grass_normal'`, `'patch_grass_plain'`, `'patch_grass_savanna'`,
|
||||
`'patch_grass_taiga'`, `'patch_grass_taiga_2'`, `'patch_large_fern'`, `'patch_melon'`, `'patch_pumpkin'`,
|
||||
`'patch_red_mushroom'`, `'patch_soul_fire'`, `'patch_sugar_cane'`, `'patch_sugar_cane_badlands'`,
|
||||
`'patch_sugar_cane_desert'`, `'patch_sugar_cane_swamp'`, `'patch_sunflower'`, `'patch_taiga_grass'`,
|
||||
`'patch_tall_grass'`, `'patch_tall_grass_2'`, `'patch_waterlilly'`, `'pile_hay'`, `'pile_ice'`,
|
||||
`'pile_melon'`, `'pile_pumpkin'`, `'pile_snow'`, `'pine'`, `'plain_vegetation'`, `'red_mushroom_giant'`,
|
||||
`'red_mushroom_nether'`, `'red_mushroom_normal'`, `'red_mushroom_swamp'`, `'red_mushroom_taiga'`,
|
||||
`'sea_pickle'`, `'seagrass_cold'`, `'seagrass_deep'`, `'seagrass_deep_cold'`, `'seagrass_deep_warm'`,
|
||||
`'seagrass_normal'`, `'seagrass_river'`, `'seagrass_simple'`, `'seagrass_swamp'`, `'seagrass_warm'`,
|
||||
`'small_basalt_columns'`, `'spring_closed'`, `'spring_closed_double'`, `'spring_delta'`, `'spring_lava'`,
|
||||
`'spring_lava_double'`, `'spring_open'`, `'spring_water'`, `'spruce'`, `'spruce_snovy'`, `'super_birch_bees_0002'`,
|
||||
`'swamp_tree'`, `'taiga_vegetation'`, `'trees_giant'`, `'trees_giant_spruce'`, `'trees_jungle'`,
|
||||
`'trees_jungle_edge'`, `'trees_mountain'`, `'trees_mountain_edge'`, `'trees_savanna'`, `'trees_shattered_savanna'`,
|
||||
`'trees_water'`, `'twisting_vines'`, `'vines'`, `'void_start_platform'`, `'warm_ocean_vegetation'`,
|
||||
`'warped_forest_vegetation'`, `'warped_fungi'`, `'warped_fungi_planted'`, `'weeping_vines'`
|
||||
Use `plop():'features'` and `plop():'configured_features'` for a list of available options. Your output may vary based on
|
||||
datapacks installed in your world.
|
||||
|
||||
### Custom Scarpet Features (1.16.2+)
|
||||
### Custom Scarpet Features
|
||||
|
||||
Use `plop():'scarpet_custom'` for a full list.
|
||||
|
||||
These contain some popular features and structures that are impossible or difficult to obtain with vanilla structures/features.
|
||||
|
||||
* `'bastion_remnant_bridge'` - Bridge version of a bastion remnant
|
||||
* `'bastion_remnant_hoglin_stable'` - Hoglin stables version of a bastion remnant
|
||||
@@ -2638,7 +2626,7 @@ making it preferred for scoping ungenerated terrain, but it takes some compute r
|
||||
Unlike `'structure'` this will return a tentative structure location. Random factors in world generation may prevent
|
||||
the actual structure from forming.
|
||||
|
||||
If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or
|
||||
If structure is specified, it will return `null` if a chunk is not eligible or invalid, `true` if the structure should appear, or
|
||||
a map with two values: `'box'` for a pair of coordinates indicating bounding box of the structure, and `'pieces'` for
|
||||
list of elements of the structure (as a tuple), with its name, direction, and box coordinates of the piece.
|
||||
|
||||
@@ -2655,7 +2643,7 @@ the first case it returns a map of structures at a given position, keyed by stru
|
||||
the bounding box of the structure - a pair of two 3-value coords (see examples). When called with an extra structure
|
||||
name, returns a map with two values, `'box'` for bounding box of the structure, and `'pieces'` for a list of
|
||||
components for that structure, with their name, direction and two sets of coordinates
|
||||
indicating the bounding box of the structure piece.
|
||||
indicating the bounding box of the structure piece. If structure is invalid, its data will be `null`.
|
||||
|
||||
Requires a `Standard Structure` name (see above).
|
||||
|
||||
@@ -3950,6 +3938,10 @@ Triggered when a server receives a request to deploy elytra, regardless if the f
|
||||
### `__on_player_wakes_up(player)`
|
||||
Player wakes up from the bed mid sleep, but not when it is kicked out of bed because it finished sleeping.
|
||||
|
||||
### `__on_player_escapes_sleep(player)`
|
||||
Same as `player_wakes_up` but only triggered when pressing the ESC button. Not sure why Mojang decided to send that event
|
||||
twice when pressing escape, but might be interesting to be able to detect that.
|
||||
|
||||
### `__on_player_starts_sneaking(player)`
|
||||
### `__on_player_stops_sneaking(player)`
|
||||
### `__on_player_starts_sprinting(player)`
|
||||
@@ -4217,7 +4209,7 @@ Reads the `property` of the `team` if no `value` is specified. If a `value` is a
|
||||
|
||||
* `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))
|
||||
* 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
|
||||
|
||||
@@ -248,21 +248,34 @@ Deprecated by `block_state(pos, name)`
|
||||
If used with a `block` argument only, it returns a map of block properties and their values. If a block has no properties, returns an
|
||||
empty map.
|
||||
|
||||
If `property` is specified, returns value of that property, or `null` if property is not applicable.
|
||||
If `property` is specified, returns a string value of that property, or `null` if property is not applicable.
|
||||
|
||||
Returned values or properties are always strings. It is expected from the user to know what to expect and convert
|
||||
values to numbers using `number()` function or booleans using `bool()` function. Returned string values can be directly used
|
||||
back in state definition in various applications where block properties are required.
|
||||
|
||||
`block_state` can also accept block names as input, returning block's default state.
|
||||
|
||||
<pre>
|
||||
set(x,y,z,'iron_trapdoor','half','top'); block_state(x,y,z) => {waterlogged: false, half: top, open: false, ...}
|
||||
set(x,y,z,'iron_trapdoor','half','top'); block_state(x,y,z,'half') => top
|
||||
block_state('iron_trapdoor','half') => top
|
||||
set(x,y,z,'air'); block_state(x,y,z,'half') => null
|
||||
block_state(block('iron_trapdoor[half=top]'),'half') => top
|
||||
block_state(block('iron_trapdoor[half=top]'),'powered') => false
|
||||
bool(block_state(block('iron_trapdoor[half=top]'),'powered')) => 0
|
||||
</pre>
|
||||
|
||||
### `block_list()`, `block_list(tag)`
|
||||
|
||||
Returns list of all blocks. If tag is provided, returns list of blocks that belong to this block tag.
|
||||
|
||||
### `block_tags()`, `block_tags(block)`, `block_tags(block, tag)`
|
||||
|
||||
Without arguments, returns list of available tags, with block supplied (either by coordinates, or via block name), returns lost
|
||||
of tags the block belongs to, and if a tag is specified, returns `null` if tag is invalid, `false` if this block doesn't belong
|
||||
to this tag, and `true` if the block belongs to the tag.
|
||||
|
||||
### `block_data(pos)`
|
||||
|
||||
Return NBT string associated with specific location, or null if the block does not carry block data. Can be currently
|
||||
@@ -512,9 +525,12 @@ This function is tentative - will likely change when chunk ticket API is properl
|
||||
Scarpet provides convenient methods to access and modify information about structures as well as spawn in-game
|
||||
structures and features. List of available options and names that you can use depends mostly if you are using scarpet
|
||||
with minecraft 1.16.1 and below or 1.16.2 and above since in 1.16.2 Mojang has added JSON support for worldgen features
|
||||
meaning that since 1.16.2 - they have official names that can be used by datapacks and scarpet
|
||||
meaning that since 1.16.2 - they have official names that can be used by datapacks and scarpet. If you have most recent
|
||||
scarpet on 1.16.4, you can use `plop()` to get all available worldgen features including custom features and structures
|
||||
controlled by datapacks. It returns a map of lists in the following categories:
|
||||
`'scarpet_custom'`, `'configured_features'`, `'structures'`, `'features'`, `'configured_structures'`
|
||||
|
||||
### Previous Structure Names, including variants (as of MC 1.16.3)
|
||||
### Previous Structure Names, including variants (MC1.16.1 and below)
|
||||
* `'monument'`: Ocean Monument. Generates at fixed Y coordinate, surrounds itself with water.
|
||||
* `'fortress'`: Nether Fortress. Altitude varies, but its bounded by the code.
|
||||
* `'mansion'`: Woodland Mansion
|
||||
@@ -544,7 +560,7 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
||||
* `'bastion_remnant_treasure'`: Treasure room version of a piglin bastion (1.16)
|
||||
* `'bastion_remnant_bridge'` : Bridge version of a piglin bastion (1.16)
|
||||
|
||||
### Feature Names (as of mc1.16.1)
|
||||
### Feature Names (1.16.1 and below)
|
||||
|
||||
* `'oak'`
|
||||
* `'oak_beehive'`: oak with a hive (1.15+).
|
||||
@@ -608,13 +624,17 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
||||
* `'twisting_vines'` (1.16)
|
||||
* `'basalt_pillar'` (1.16)
|
||||
|
||||
### Standard Structures (as of 1.16.2+)
|
||||
### Standard Structures (as of MC1.16.2+)
|
||||
|
||||
Use `plop():'structures'`, but it always returns the following:
|
||||
|
||||
`'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'endcity'`, `'fortress'`, `'igloo'`,
|
||||
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'monument'`, `'nether_fossil'`, `'ocean_ruin'`,
|
||||
`'pillager_outpost'`, `'ruined_portal'`, `'shipwreck'`, `'stronghold'`, `'swamp_hut'`, `'village'`
|
||||
|
||||
### Structure Variants (as of 1.16.2+)
|
||||
### Structure Variants (as of MC1.16.2+)
|
||||
|
||||
Use `plop():'configured_structures'`, but it always returns the following:
|
||||
|
||||
`'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'end_city'`, `'fortress'`, `'igloo'`,
|
||||
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'mineshaft_mesa'`, `'monument'`, `'nether_fossil'`,
|
||||
@@ -623,48 +643,16 @@ meaning that since 1.16.2 - they have official names that can be used by datapac
|
||||
`'ruined_portal_swamp'`, `'shipwreck'`, `'shipwreck_beached'`, `'stronghold'`, `'swamp_hut'`,
|
||||
`'village_desert'`, `'village_plains'`, `'village_savanna'`, `'village_snovy'`, `'village_taiga'`
|
||||
|
||||
### World Generation Features (as of 1.16.2+)
|
||||
### World Generation Features (as of MC1.16.2+)
|
||||
|
||||
`'acacia'`, `'amethyst_geode'` (1.17+), `'bamboo'`, `'bamboo_light'`, `'bamboo_vegetation'`, `'basalt_blobs'`, `'basalt_pillar'`,
|
||||
`'birch'`, `'birch_bees_0002'`, `'birch_bees_002'`, `'birch_bees_005'`, `'birch_other'`, `'birch_tall'`,
|
||||
`'blackstone_blobs'`, `'blue_ice'`, `'bonus_chest'`, `'brown_mushroom_giant'`, `'brown_mushroom_nether'`,
|
||||
`'brown_mushroom_normal'`, `'brown_mushroom_swamp'`, `'brown_mushroom_taiga'`, `'chorus_plant'`,
|
||||
`'crimson_forest_vegetation'`, `'crimson_fungi'`, `'crimson_fungi_planted'`, `'dark_forest_vegetation_brown'`,
|
||||
`'dark_forest_vegetation_red'`, `'dark_oak'`, `'delta'`, `'desert_well'`, `'disk_clay'`, `'disk_gravel'`,
|
||||
`'disk_sand'`, `'end_gateway'`, `'end_gateway_delayed'`, `'end_island'`, `'end_island_decorated'`, `'end_spike'`,
|
||||
`'fancy_oak'`, `'fancy_oak_bees_0002'`, `'fancy_oak_bees_002'`, `'fancy_oak_bees_005'`, `'flower_default'`,
|
||||
`'flower_forest'`, `'flower_plain'`, `'flower_plain_decorated'`, `'flower_swamp'`, `'flower_warm'`,
|
||||
`'forest_flower_trees'`, `'forest_flower_vegetation'`, `'forest_flower_vegetation_common'`, `'forest_rock'`,
|
||||
`'fossil'`, `'freeze_top_layer'`, `'glowstone'`, `'glowstone_extra'`, `'huge_brown_mushroom'`,
|
||||
`'huge_red_mushroom'`, `'ice_patch'`, `'ice_spike'`, `'iceberg_blue'`, `'iceberg_packed'`, `'jungle_bush'`,
|
||||
`'jungle_tree'`, `'jungle_tree_no_vine'`, `'kelp_cold'`, `'kelp_warm'`, `'lake_lava'`, `'lake_water'`,
|
||||
`'large_basalt_columns'`, `'mega_jungle_tree'`, `'mega_pine'`, `'mega_spruce'`, `'monster_room'`,
|
||||
`'mushroom_field_vegetation'`, `'nether_sprouts'`, `'nope'`, `'oak'`, `'oak_badlands'`, `'oak_bees_0002'`,
|
||||
`'oak_bees_002'`, `'oak_bees_005'`, `'ore_andesite'`, `'ore_blackstone'`, `'ore_coal'`, `'ore_debris_large'`,
|
||||
`'ore_debris_small'`, `'ore_diamond'`, `'ore_diorite'`, `'ore_dirt'`, `'ore_emerald'`, `'ore_gold'`,
|
||||
`'ore_gold_deltas'`, `'ore_gold_extra'`, `'ore_gold_nether'`, `'ore_granite'`, `'ore_gravel'`,
|
||||
`'ore_gravel_nether'`, `'ore_infested'`, `'ore_iron'`, `'ore_lapis'`, `'ore_magma'`, `'ore_quartz_deltas'`,
|
||||
`'ore_quartz_nether'`, `'ore_redstone'`, `'ore_soul_sand'`, `'patch_berry_bush'`, `'patch_berry_decorated'`,
|
||||
`'patch_berry_sparse'`, `'patch_brown_mushroom'`, `'patch_cactus'`, `'patch_cactus_decorated'`,
|
||||
`'patch_cactus_desert'`, `'patch_crimson_roots'`, `'patch_dead_bush'`, `'patch_dead_bush_2'`,
|
||||
`'patch_dead_bush_badlands'`, `'patch_fire'`, `'patch_grass_badlands'`, `'patch_grass_forest'`,
|
||||
`'patch_grass_jungle'`, `'patch_grass_normal'`, `'patch_grass_plain'`, `'patch_grass_savanna'`,
|
||||
`'patch_grass_taiga'`, `'patch_grass_taiga_2'`, `'patch_large_fern'`, `'patch_melon'`, `'patch_pumpkin'`,
|
||||
`'patch_red_mushroom'`, `'patch_soul_fire'`, `'patch_sugar_cane'`, `'patch_sugar_cane_badlands'`,
|
||||
`'patch_sugar_cane_desert'`, `'patch_sugar_cane_swamp'`, `'patch_sunflower'`, `'patch_taiga_grass'`,
|
||||
`'patch_tall_grass'`, `'patch_tall_grass_2'`, `'patch_waterlilly'`, `'pile_hay'`, `'pile_ice'`,
|
||||
`'pile_melon'`, `'pile_pumpkin'`, `'pile_snow'`, `'pine'`, `'plain_vegetation'`, `'red_mushroom_giant'`,
|
||||
`'red_mushroom_nether'`, `'red_mushroom_normal'`, `'red_mushroom_swamp'`, `'red_mushroom_taiga'`,
|
||||
`'sea_pickle'`, `'seagrass_cold'`, `'seagrass_deep'`, `'seagrass_deep_cold'`, `'seagrass_deep_warm'`,
|
||||
`'seagrass_normal'`, `'seagrass_river'`, `'seagrass_simple'`, `'seagrass_swamp'`, `'seagrass_warm'`,
|
||||
`'small_basalt_columns'`, `'spring_closed'`, `'spring_closed_double'`, `'spring_delta'`, `'spring_lava'`,
|
||||
`'spring_lava_double'`, `'spring_open'`, `'spring_water'`, `'spruce'`, `'spruce_snovy'`, `'super_birch_bees_0002'`,
|
||||
`'swamp_tree'`, `'taiga_vegetation'`, `'trees_giant'`, `'trees_giant_spruce'`, `'trees_jungle'`,
|
||||
`'trees_jungle_edge'`, `'trees_mountain'`, `'trees_mountain_edge'`, `'trees_savanna'`, `'trees_shattered_savanna'`,
|
||||
`'trees_water'`, `'twisting_vines'`, `'vines'`, `'void_start_platform'`, `'warm_ocean_vegetation'`,
|
||||
`'warped_forest_vegetation'`, `'warped_fungi'`, `'warped_fungi_planted'`, `'weeping_vines'`
|
||||
Use `plop():'features'` and `plop():'configured_features'` for a list of available options. Your output may vary based on
|
||||
datapacks installed in your world.
|
||||
|
||||
### Custom Scarpet Features (1.16.2+)
|
||||
### Custom Scarpet Features
|
||||
|
||||
Use `plop():'scarpet_custom'` for a full list.
|
||||
|
||||
These contain some popular features and structures that are impossible or difficult to obtain with vanilla structures/features.
|
||||
|
||||
* `'bastion_remnant_bridge'` - Bridge version of a bastion remnant
|
||||
* `'bastion_remnant_hoglin_stable'` - Hoglin stables version of a bastion remnant
|
||||
@@ -690,7 +678,7 @@ making it preferred for scoping ungenerated terrain, but it takes some compute r
|
||||
Unlike `'structure'` this will return a tentative structure location. Random factors in world generation may prevent
|
||||
the actual structure from forming.
|
||||
|
||||
If structure is specified, it will return `null` if a chunk is not eligible, `true` if the structure should appear, or
|
||||
If structure is specified, it will return `null` if a chunk is not eligible or invalid, `true` if the structure should appear, or
|
||||
a map with two values: `'box'` for a pair of coordinates indicating bounding box of the structure, and `'pieces'` for
|
||||
list of elements of the structure (as a tuple), with its name, direction, and box coordinates of the piece.
|
||||
|
||||
@@ -707,7 +695,7 @@ the first case it returns a map of structures at a given position, keyed by stru
|
||||
the bounding box of the structure - a pair of two 3-value coords (see examples). When called with an extra structure
|
||||
name, returns a map with two values, `'box'` for bounding box of the structure, and `'pieces'` for a list of
|
||||
components for that structure, with their name, direction and two sets of coordinates
|
||||
indicating the bounding box of the structure piece.
|
||||
indicating the bounding box of the structure piece. If structure is invalid, its data will be `null`.
|
||||
|
||||
Requires a `Standard Structure` name (see above).
|
||||
|
||||
|
||||
@@ -170,6 +170,10 @@ Triggered when a server receives a request to deploy elytra, regardless if the f
|
||||
### `__on_player_wakes_up(player)`
|
||||
Player wakes up from the bed mid sleep, but not when it is kicked out of bed because it finished sleeping.
|
||||
|
||||
### `__on_player_escapes_sleep(player)`
|
||||
Same as `player_wakes_up` but only triggered when pressing the ESC button. Not sure why Mojang decided to send that event
|
||||
twice when pressing escape, but might be interesting to be able to detect that.
|
||||
|
||||
### `__on_player_starts_sneaking(player)`
|
||||
### `__on_player_stops_sneaking(player)`
|
||||
### `__on_player_starts_sprinting(player)`
|
||||
|
||||
@@ -69,7 +69,7 @@ Reads the `property` of the `team` if no `value` is specified. If a `value` is a
|
||||
|
||||
* `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))
|
||||
* 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
|
||||
|
||||
@@ -5,9 +5,11 @@ blast_resistance
|
||||
block
|
||||
block_data
|
||||
block_light
|
||||
block_list
|
||||
block_sound
|
||||
block_state
|
||||
block_tick
|
||||
block_tags
|
||||
blocks_daylight
|
||||
blocks_movement
|
||||
brightness
|
||||
|
||||
@@ -28,6 +28,7 @@ __on_player_switches_slot(player, from, to) ->
|
||||
__on_player_swaps_hands(player) ->
|
||||
__on_player_uses_item(player, item_tuple, hand) ->
|
||||
__on_player_wakes_up(player) ->
|
||||
__on_player_escapes_sleep(player) ->
|
||||
__on_statistic(player, category, event, value) ->
|
||||
__on_tick() ->
|
||||
__on_tick_ender() ->
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
transparent opacity blocks_daylight emitted_light light block_light sky_light see_sky brightness
|
||||
hardness blast_resistance top loaded suffocates power ticks_randomly update block_tick random_tick in_slime_chunk
|
||||
set without_updates
|
||||
blocks_movement block_sound material map_colour block_state block_data poi set_poi
|
||||
blocks_movement block_sound material map_colour block_state block_list block_tags block_data poi set_poi
|
||||
place_item set_biome biome loaded_status generation_status inhabited_time spawn_potential chunk_tickets
|
||||
structure_eligibility structures structure_references set_structure reset_chunk reload_chunk custom_dimension
|
||||
add_chunk_ticket
|
||||
@@ -115,6 +115,7 @@
|
||||
__on_player_swaps_hands
|
||||
__on_player_uses_item
|
||||
__on_player_wakes_up
|
||||
__on_player_escapes_sleep
|
||||
__on_statistic
|
||||
__on_tick
|
||||
__on_tick_ender
|
||||
|
||||
@@ -49,7 +49,7 @@ public class FeatureGenerator
|
||||
return custom.plop(world, pos);
|
||||
}
|
||||
Identifier id = new Identifier(featureName);
|
||||
ConfiguredStructureFeature<?, ?> structureFeature = BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.get(id);
|
||||
ConfiguredStructureFeature<?, ?> structureFeature = world.getRegistryManager().get(Registry.CONFIGURED_STRUCTURE_FEATURE_WORLDGEN).get(id);
|
||||
if (structureFeature != null)
|
||||
{
|
||||
return ((StructureFeatureInterface)structureFeature.feature).plopAnywhere(
|
||||
@@ -58,7 +58,7 @@ public class FeatureGenerator
|
||||
|
||||
}
|
||||
|
||||
ConfiguredFeature<?, ?> feature = BuiltinRegistries.CONFIGURED_FEATURE.get(id);
|
||||
ConfiguredFeature<?, ?> feature = world.getRegistryManager().get(Registry.CONFIGURED_FEATURE_WORLDGEN).get(id);
|
||||
if (feature != null)
|
||||
{
|
||||
CarpetSettings.skipGenerationChecks = true;
|
||||
@@ -77,7 +77,7 @@ public class FeatureGenerator
|
||||
public static ConfiguredStructureFeature<?, ?> resolveConfiguredStructure(String name, ServerWorld world, BlockPos pos)
|
||||
{
|
||||
Identifier id = new Identifier(name);
|
||||
ConfiguredStructureFeature<?, ?> configuredStructureFeature = BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.get(id);
|
||||
ConfiguredStructureFeature<?, ?> configuredStructureFeature = world.getRegistryManager().get(Registry.CONFIGURED_STRUCTURE_FEATURE_WORLDGEN).get(id);
|
||||
if (configuredStructureFeature != null) return configuredStructureFeature;
|
||||
StructureFeature<?> structureFeature = Registry.STRUCTURE_FEATURE.get(id);
|
||||
if (structureFeature == null) return null;
|
||||
@@ -137,7 +137,7 @@ public class FeatureGenerator
|
||||
{
|
||||
ConfiguredStructureFeature<?, ?> configuredFeature = world.getBiome(pos).getGenerationSettings().method_30978(structure.configure(null));
|
||||
if (configuredFeature.config != null || !tryHard) return configuredFeature;
|
||||
return BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getEntries().stream().
|
||||
return world.getRegistryManager().get(Registry.CONFIGURED_STRUCTURE_FEATURE_WORLDGEN).getEntries().stream().
|
||||
filter(cS -> cS.getValue().feature == structure).
|
||||
findFirst().map(Map.Entry::getValue).orElse(null);
|
||||
}
|
||||
@@ -168,7 +168,7 @@ public class FeatureGenerator
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Map<String, Thing> featureMap = new HashMap<String, Thing>() {{
|
||||
public static final Map<String, Thing> featureMap = new HashMap<String, Thing>() {{
|
||||
put("oak_bees", simpleTree(ConfiguredFeatures.OAK.getConfig().setTreeDecorators(ImmutableList.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
put("fancy_oak_bees", simpleTree(ConfiguredFeatures.FANCY_OAK.getConfig().setTreeDecorators(ImmutableList.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
put("birch_bees", simpleTree(ConfiguredFeatures.BIRCH.getConfig().setTreeDecorators(ImmutableList.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.packet.c2s.play.ButtonClickC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.CraftRequestC2SPacket;
|
||||
@@ -27,6 +28,7 @@ import static carpet.script.CarpetEventServer.Event.PLAYER_CLICKS_BLOCK;
|
||||
import static carpet.script.CarpetEventServer.Event.PLAYER_DEPLOYS_ELYTRA;
|
||||
import static carpet.script.CarpetEventServer.Event.PLAYER_DROPS_ITEM;
|
||||
import static carpet.script.CarpetEventServer.Event.PLAYER_DROPS_STACK;
|
||||
import static carpet.script.CarpetEventServer.Event.PLAYER_ESCAPES_SLEEP;
|
||||
import static carpet.script.CarpetEventServer.Event.PLAYER_INTERACTS_WITH_ENTITY;
|
||||
import static carpet.script.CarpetEventServer.Event.PLAYER_RELEASED_ITEM;
|
||||
import static carpet.script.CarpetEventServer.Event.PLAYER_RIDES;
|
||||
@@ -205,7 +207,11 @@ public class ServerPlayNetworkHandler_scarpetEventsMixin
|
||||
private void onWakeUp(ClientCommandC2SPacket clientCommandC2SPacket_1, CallbackInfo ci)
|
||||
{
|
||||
//weird one - doesn't seem to work, maybe MP
|
||||
PLAYER_WAKES_UP.onPlayerEvent(player);
|
||||
if (player.isSleeping())
|
||||
PLAYER_WAKES_UP.onPlayerEvent(player);
|
||||
else
|
||||
PLAYER_ESCAPES_SLEEP.onPlayerEvent(player);
|
||||
|
||||
}
|
||||
|
||||
@Inject(method = "onClientCommand", at = @At(
|
||||
|
||||
@@ -337,6 +337,14 @@ public class CarpetEventServer
|
||||
handler.call( () -> Collections.singletonList(new EntityValue(player)), player::getCommandSource);
|
||||
}
|
||||
};
|
||||
public static final Event PLAYER_ESCAPES_SLEEP = new Event("player_escapes_sleep", 1, false)
|
||||
{
|
||||
@Override
|
||||
public void onPlayerEvent(ServerPlayerEntity player)
|
||||
{
|
||||
handler.call( () -> Collections.singletonList(new EntityValue(player)), player::getCommandSource);
|
||||
}
|
||||
};
|
||||
public static final Event PLAYER_RIDES = new Event("player_rides", 5, false)
|
||||
{
|
||||
@Override
|
||||
|
||||
@@ -658,18 +658,18 @@ public class Expression
|
||||
case UNARY_OPERATOR:
|
||||
{
|
||||
final LazyValue value = stack.pop();
|
||||
LazyValue result = (c, t) -> operators.get(token.surface).lazyEval(c, t, this, token, value, null).evalValue(c);
|
||||
LazyValue result = (c, t) -> operators.get(token.surface).lazyEval(c, t, this, token, value, null).evalValue(c, t);
|
||||
stack.push(result);
|
||||
break;
|
||||
}
|
||||
case OPERATOR:
|
||||
final LazyValue v1 = stack.pop();
|
||||
final LazyValue v2 = stack.pop();
|
||||
LazyValue result = (c,t) -> operators.get(token.surface).lazyEval(c, t,this, token, v2, v1).evalValue(c);
|
||||
LazyValue result = (c,t) -> operators.get(token.surface).lazyEval(c, t,this, token, v2, v1).evalValue(c, t);
|
||||
stack.push(result);
|
||||
break;
|
||||
case VARIABLE:
|
||||
stack.push((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c));
|
||||
stack.push((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t));
|
||||
break;
|
||||
case FUNCTION:
|
||||
String name = token.surface;
|
||||
@@ -700,7 +700,7 @@ public class Expression
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
stack.push((c, t) -> f.lazyEval(c, t, this, token, p).evalValue(c));
|
||||
stack.push((c, t) -> f.lazyEval(c, t, this, token, p).evalValue(c, t));
|
||||
break;
|
||||
case OPEN_PAREN:
|
||||
stack.push(LazyValue.PARAMS_START);
|
||||
|
||||
@@ -149,7 +149,7 @@ public abstract class Fluff
|
||||
{
|
||||
try
|
||||
{
|
||||
return (c, type_ignored) -> AbstractOperator.this.eval(v1.evalValue(c), v2.evalValue(c));
|
||||
return (c, type_ignored) -> AbstractOperator.this.eval(v1.evalValue(c, type), v2.evalValue(c, type));
|
||||
}
|
||||
catch (RuntimeException exc)
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@ import carpet.script.value.EntityValue;
|
||||
import carpet.script.value.FormattedTextValue;
|
||||
import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.ListValue;
|
||||
import carpet.script.value.MapValue;
|
||||
import carpet.script.value.NBTSerializableValue;
|
||||
import carpet.script.value.NullValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
@@ -60,6 +61,7 @@ import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.EulerAngle;
|
||||
import net.minecraft.util.math.Vec2f;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -67,6 +69,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -304,7 +307,7 @@ public class Auxiliary {
|
||||
pointLocator = Vector3Argument.findIn(cc, lv, 1, true);
|
||||
if (lv.size()>pointLocator.offset)
|
||||
{
|
||||
BlockArgument blockLocator = BlockArgument.findIn(cc, lv, pointLocator.offset, true, true);
|
||||
BlockArgument blockLocator = BlockArgument.findIn(cc, lv, pointLocator.offset, true, true, false);
|
||||
if (blockLocator.block != null) targetBlock = blockLocator.block.getBlockState();
|
||||
if (lv.size() > blockLocator.offset)
|
||||
{
|
||||
@@ -619,6 +622,29 @@ public class Auxiliary {
|
||||
});
|
||||
|
||||
expression.addLazyFunction("plop", -1, (c, t, lv) ->{
|
||||
if (lv.size() == 0)
|
||||
{
|
||||
Map<Value, Value> plopData = new HashMap<>();
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
DynamicRegistryManager registryManager = cc.s.getWorld().getRegistryManager();
|
||||
plopData.put(StringValue.of("scarpet_custom"),
|
||||
ListValue.wrap(FeatureGenerator.featureMap.keySet().stream().sorted().map(StringValue::of).collect(Collectors.toList()))
|
||||
);
|
||||
plopData.put(StringValue.of("features"),
|
||||
ListValue.wrap(Registry.FEATURE.getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
|
||||
);
|
||||
plopData.put(StringValue.of("configured_features"),
|
||||
ListValue.wrap(registryManager.get(Registry.CONFIGURED_FEATURE_WORLDGEN).getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
|
||||
);
|
||||
plopData.put(StringValue.of("structures"),
|
||||
ListValue.wrap(Registry.STRUCTURE_FEATURE.getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
|
||||
);
|
||||
plopData.put(StringValue.of("configured_structures"),
|
||||
ListValue.wrap(registryManager.get(Registry.CONFIGURED_STRUCTURE_FEATURE_WORLDGEN).getIds().stream().sorted().map(ValueConversions::of).collect(Collectors.toList()))
|
||||
);
|
||||
Value ret = MapValue.wrap(plopData);
|
||||
return (_c, _t) -> ret;
|
||||
}
|
||||
BlockArgument locator = BlockArgument.findIn((CarpetContext)c, lv, 0);
|
||||
if (lv.size() <= locator.offset)
|
||||
throw new InternalExpressionException("'plop' needs extra argument indicating what to plop");
|
||||
@@ -656,23 +682,7 @@ public class Auxiliary {
|
||||
|
||||
expression.addLazyFunction("logger", -1, (c, t, lv) ->
|
||||
{
|
||||
//CarpetSettings.LOG.error("Standard Structures:");
|
||||
//CarpetSettings.LOG.error(Registry.STRUCTURE_FEATURE.getIds().stream().map(i -> "`'"+NBTSerializableValue.nameFromRegistryId(i)+"'`").sorted(). collect(Collectors.joining(", ")));
|
||||
//CarpetSettings.LOG.error("");
|
||||
//CarpetSettings.LOG.error("Configured Structures:");
|
||||
//CarpetSettings.LOG.error(BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getIds().stream().map(i -> "`'"+NBTSerializableValue.nameFromRegistryId(i)+"'`").sorted().collect(Collectors.joining(", ")));
|
||||
//CarpetSettings.LOG.error("");
|
||||
//CarpetSettings.LOG.error("Features:");
|
||||
//CarpetSettings.LOG.error(Registry.FEATURE.getIds().stream().map(i -> "`'"+NBTSerializableValue.nameFromRegistryId(i)+"'`").sorted().collect(Collectors.joining(", ")));
|
||||
//CarpetSettings.LOG.error("");
|
||||
//CarpetSettings.LOG.error("Configured Features:");
|
||||
//CarpetSettings.LOG.error(BuiltinRegistries.CONFIGURED_FEATURE.getIds().stream().map(i -> "`'"+NBTSerializableValue.nameFromRegistryId(i)+"'`").sorted().collect(Collectors.joining(", ")));
|
||||
//CarpetSettings.LOG.error("");
|
||||
//CarpetSettings.LOG.error("Custom:");
|
||||
//CarpetSettings.LOG.error(FeatureGenerator.featureMap.keySet().stream().map(i -> "`'"+i+"'`").sorted().collect(Collectors.joining(", ")));
|
||||
|
||||
//CarpetSettings.LOG.error(Registry.ENTITY_TYPE.getIds().stream().sorted().map(ValueConversions::simplify).collect(Collectors.joining("`, `")));
|
||||
|
||||
Value res;
|
||||
|
||||
if(lv.size()==1)
|
||||
|
||||
@@ -262,7 +262,7 @@ public class Scoreboards {
|
||||
if(!(propertyVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the second argument");
|
||||
|
||||
switch (propertyVal.getString()) {
|
||||
case "collision_rule":
|
||||
case "collisionRule":
|
||||
if(!modifying) {
|
||||
Value ret = new StringValue(team.getCollisionRule().name);
|
||||
return (_c, _t) -> ret;
|
||||
@@ -287,7 +287,7 @@ public class Scoreboards {
|
||||
team.setColor(color);
|
||||
|
||||
break;
|
||||
case "death_message_visibility":
|
||||
case "deathMessageVisibility":
|
||||
if(!modifying) {
|
||||
Value ret = new StringValue(team.getDeathMessageVisibilityRule().name);
|
||||
return (_c, _t) -> ret;
|
||||
@@ -300,7 +300,7 @@ public class Scoreboards {
|
||||
team.setDeathMessageVisibilityRule(deathMessageVisibility);
|
||||
|
||||
break;
|
||||
case "display_name":
|
||||
case "displayName":
|
||||
if(!modifying) {
|
||||
Value ret = new FormattedTextValue(team.getDisplayName());
|
||||
return (_c, _t) -> ret;
|
||||
@@ -319,7 +319,7 @@ public class Scoreboards {
|
||||
team.setDisplayName(displayName);
|
||||
|
||||
break;
|
||||
case "friendly_fire":
|
||||
case "friendlyFire":
|
||||
if(!modifying) {
|
||||
Value ret = new NumericValue(team.isFriendlyFireAllowed());
|
||||
return (_c, _t) -> ret;
|
||||
@@ -330,7 +330,7 @@ public class Scoreboards {
|
||||
boolean friendlyFire = settingVal.getBoolean();
|
||||
team.setFriendlyFireAllowed(friendlyFire);
|
||||
break;
|
||||
case "nametag_visibility":
|
||||
case "nametagVisibility":
|
||||
if(!modifying) {
|
||||
Value ret = new StringValue(team.getNameTagVisibilityRule().name);
|
||||
return (_c, _t) -> ret;
|
||||
@@ -361,7 +361,7 @@ public class Scoreboards {
|
||||
|
||||
team.setPrefix(prefix);
|
||||
break;
|
||||
case "see_friendly_invisibles":
|
||||
case "seeFriendlyInvisibles":
|
||||
if(!modifying) {
|
||||
Value ret = new NumericValue(team.shouldShowFriendlyInvisibles());
|
||||
return (_c, _t) -> ret;
|
||||
|
||||
@@ -18,6 +18,7 @@ import carpet.script.LazyValue;
|
||||
import carpet.script.argument.BlockArgument;
|
||||
import carpet.script.argument.Vector3Argument;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.utils.BiomeInfo;
|
||||
import carpet.script.utils.WorldTools;
|
||||
import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.EntityValue;
|
||||
@@ -66,6 +67,7 @@ import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.Property;
|
||||
import net.minecraft.structure.StructureStart;
|
||||
import net.minecraft.tag.TagManager;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Clearable;
|
||||
import net.minecraft.util.Identifier;
|
||||
@@ -101,6 +103,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -997,7 +1000,7 @@ public class WorldAccess {
|
||||
// block_state(block, property)
|
||||
expression.addLazyFunction("block_state", -1, (c, t, lv) ->
|
||||
{
|
||||
BlockArgument locator = BlockArgument.findIn((CarpetContext) c, lv, 0);
|
||||
BlockArgument locator = BlockArgument.findIn((CarpetContext) c, lv, 0, true);
|
||||
BlockState state = locator.block.getBlockState();
|
||||
StateManager<Block, BlockState> states = state.getBlock().getStateManager();
|
||||
if (locator.offset == lv.size())
|
||||
@@ -1018,16 +1021,71 @@ public class WorldAccess {
|
||||
return (_c, _t) -> retval;
|
||||
});
|
||||
|
||||
expression.addLazyFunction("block_list", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
{
|
||||
Value ret = ListValue.wrap(Registry.BLOCK.getIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
|
||||
return (_c, _t) -> ret;
|
||||
}
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
TagManager tagManager = cc.s.getMinecraftServer().getTagManager();
|
||||
String tag = lv.get(0).evalValue(c).getString();
|
||||
net.minecraft.tag.Tag<Block> blockTag = tagManager.getBlocks().getTag(new Identifier(tag));
|
||||
if (blockTag == null) return LazyValue.NULL;
|
||||
Value ret = ListValue.wrap(blockTag.values().stream().map(b -> ValueConversions.of(Registry.BLOCK.getId(b))).collect(Collectors.toList()));
|
||||
return (_c, _t) -> ret;
|
||||
});
|
||||
|
||||
expression.addLazyFunction("block_tags", -1, (c, t, lv) ->
|
||||
{
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
TagManager tagManager = cc.s.getMinecraftServer().getTagManager();
|
||||
if (lv.size() == 0)
|
||||
{
|
||||
Value ret = ListValue.wrap(tagManager.getBlocks().getTagIds().stream().map(ValueConversions::of).collect(Collectors.toList()));
|
||||
return (_c, _t) -> ret;
|
||||
}
|
||||
BlockArgument blockLocator = BlockArgument.findIn(cc, lv, 0, true);
|
||||
if (blockLocator.offset == lv.size())
|
||||
{
|
||||
Value ret = ListValue.wrap(tagManager.getBlocks().getTagsFor(blockLocator.block.getBlockState().getBlock()).stream().map(ValueConversions::of).collect(Collectors.toList()));
|
||||
return (_c, _t) -> ret;
|
||||
}
|
||||
String tag = lv.get(blockLocator.offset).evalValue(c).getString();
|
||||
net.minecraft.tag.Tag<Block> blockTag = tagManager.getBlocks().getTag(new Identifier(tag));
|
||||
if (blockTag == null) return LazyValue.NULL;
|
||||
return blockLocator.block.getBlockState().isIn(blockTag)?LazyValue.TRUE:LazyValue.FALSE;
|
||||
});
|
||||
|
||||
|
||||
expression.addLazyFunction("biome", -1, (c, t, lv) -> {
|
||||
CarpetContext cc = (CarpetContext)c;
|
||||
BlockArgument locator = BlockArgument.findIn(cc, lv, 0);
|
||||
ServerWorld world = cc.s.getWorld();
|
||||
BlockPos pos = locator.block.getPos();
|
||||
Biome biome = world.getBiome(pos);
|
||||
BlockArgument locator = BlockArgument.findIn(cc, lv, 0, false, false, true);
|
||||
Biome biome;
|
||||
if (locator.replacement != null)
|
||||
{
|
||||
biome = cc.s.getMinecraftServer().getRegistryManager().get(Registry.BIOME_KEY).get(new Identifier(locator.replacement));
|
||||
if (biome == null) throw new InternalExpressionException("Unknown biome: "+locator.replacement);
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerWorld world = cc.s.getWorld();
|
||||
BlockPos pos = locator.block.getPos();
|
||||
biome = world.getBiome(pos);
|
||||
}
|
||||
// in locatebiome
|
||||
Identifier biomeId = cc.s.getMinecraftServer().getRegistryManager().get(Registry.BIOME_KEY).getId(biome);
|
||||
Value res = new StringValue(NBTSerializableValue.nameFromRegistryId(biomeId));
|
||||
return (_c, _t) -> res;
|
||||
if (locator.offset == lv.size())
|
||||
{
|
||||
Identifier biomeId = cc.s.getMinecraftServer().getRegistryManager().get(Registry.BIOME_KEY).getId(biome);
|
||||
Value res = new StringValue(NBTSerializableValue.nameFromRegistryId(biomeId));
|
||||
return (_c, _t) -> res;
|
||||
}
|
||||
String biomeFeature = lv.get(locator.offset).evalValue(c).getString();
|
||||
Function<Biome, Value> featureProvider = BiomeInfo.biomeFeatures.get(biomeFeature);
|
||||
if (featureProvider == null) throw new InternalExpressionException("Unknown biome feature: "+biomeFeature);
|
||||
Value ret = featureProvider.apply(biome);
|
||||
return (_c, _t) -> ret;
|
||||
});
|
||||
|
||||
expression.addLazyFunction("set_biome", -1, (c, t, lv) ->
|
||||
@@ -1128,7 +1186,17 @@ public class WorldAccess {
|
||||
Map<Value, Value> ret = new HashMap<>();
|
||||
for(StructureFeature<?> str : StructureFeature.STRUCTURES.values())
|
||||
{
|
||||
StructureStart start = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize);
|
||||
StructureStart<?> start;
|
||||
try
|
||||
{
|
||||
start = FeatureGenerator.shouldStructureStartAt(world, pos, str, needSize);
|
||||
}
|
||||
catch (NullPointerException npe)
|
||||
{
|
||||
CarpetSettings.LOG.error("Failed to detect structure: "+str.getName());
|
||||
start = null;
|
||||
}
|
||||
|
||||
if (start == null) continue;
|
||||
|
||||
Value key = new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_FEATURE.getId(str)));
|
||||
|
||||
@@ -16,22 +16,30 @@ import java.util.List;
|
||||
public class BlockArgument extends Argument
|
||||
{
|
||||
public final BlockValue block;
|
||||
public final String replacement;
|
||||
private BlockArgument(BlockValue b, int o)
|
||||
{
|
||||
super(o);
|
||||
block = b;
|
||||
replacement = null;
|
||||
}
|
||||
private BlockArgument(BlockValue b, int o, String replacement)
|
||||
{
|
||||
super(o);
|
||||
block = b;
|
||||
this.replacement = replacement;
|
||||
}
|
||||
public static BlockArgument findIn(CarpetContext c, List<LazyValue> params, int offset)
|
||||
{
|
||||
return findIn(c, params,offset, false, false);
|
||||
return findIn(c, params,offset, false, false, false);
|
||||
}
|
||||
|
||||
public static BlockArgument findIn(CarpetContext c, List<LazyValue> params, int offset, boolean acceptString)
|
||||
{
|
||||
return findIn(c, params,offset, acceptString, false);
|
||||
return findIn(c, params,offset, acceptString, false, false);
|
||||
}
|
||||
|
||||
public static BlockArgument findIn(CarpetContext c, List<LazyValue> params, int offset, boolean acceptString, boolean optional)
|
||||
public static BlockArgument findIn(CarpetContext c, List<LazyValue> params, int offset, boolean acceptString, boolean optional, boolean anyString)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -41,6 +49,10 @@ public class BlockArgument extends Argument
|
||||
{
|
||||
return new BlockArgument(null, 1+offset);
|
||||
}
|
||||
if (anyString && v1 instanceof StringValue)
|
||||
{
|
||||
return new BlockArgument(null, 1+offset, v1.getString());
|
||||
}
|
||||
if (acceptString && v1 instanceof StringValue)
|
||||
{
|
||||
return new BlockArgument(BlockValue.fromString(v1.getString()), 1+offset);
|
||||
|
||||
@@ -45,11 +45,10 @@ public class Functions {
|
||||
{
|
||||
FunctionArgument<LazyValue> functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
|
||||
FunctionValue fun = functionArgument.function;
|
||||
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), functionArgument.args).evalValue(c);
|
||||
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
|
||||
return fun.callInContext(c, t, functionArgument.args);
|
||||
}
|
||||
// gimme signature
|
||||
String name = lv.get(0).evalValue(c).getString();
|
||||
String name = lv.get(0).evalValue(c, Context.NONE).getString();
|
||||
List<String> args = new ArrayList<>();
|
||||
List<String> globals = new ArrayList<>();
|
||||
String varArgs = null;
|
||||
|
||||
@@ -70,7 +70,7 @@ public class Loops {
|
||||
// expr receives bounded variable '_' indicating iteration
|
||||
expression.addLazyFunction("loop", 2, (c, t, lv) ->
|
||||
{
|
||||
long limit = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
||||
long limit = NumericValue.asNumber(lv.get(0).evalValue(c, Context.NONE)).getLong();
|
||||
Value lastOne = Value.NULL;
|
||||
LazyValue expr = lv.get(1);
|
||||
//scoping
|
||||
@@ -99,7 +99,7 @@ public class Loops {
|
||||
// receives bounded variable '_' with the expression
|
||||
expression.addLazyFunction("map", 2, (c, t, lv) ->
|
||||
{
|
||||
Value rval= lv.get(0).evalValue(c);
|
||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||
if (!(rval instanceof AbstractListValue))
|
||||
throw new InternalExpressionException("First argument of 'map' function should be a list or iterator");
|
||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||
@@ -144,7 +144,7 @@ public class Loops {
|
||||
// produces list of values for which the expression is true
|
||||
expression.addLazyFunction("filter", 2, (c, t, lv) ->
|
||||
{
|
||||
Value rval= lv.get(0).evalValue(c);
|
||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||
if (!(rval instanceof AbstractListValue))
|
||||
throw new InternalExpressionException("First argument of 'filter' function should be a list or iterator");
|
||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||
@@ -191,7 +191,7 @@ public class Loops {
|
||||
expression.addLazyFunction("first", 2, (c, t, lv) ->
|
||||
{
|
||||
|
||||
Value rval= lv.get(0).evalValue(c);
|
||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||
if (!(rval instanceof AbstractListValue))
|
||||
throw new InternalExpressionException("First argument of 'first' function should be a list or iterator");
|
||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||
@@ -242,7 +242,7 @@ public class Loops {
|
||||
// returns true if expr is true for all items
|
||||
expression.addLazyFunction("all", 2, (c, t, lv) ->
|
||||
{
|
||||
Value rval= lv.get(0).evalValue(c);
|
||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||
if (!(rval instanceof AbstractListValue))
|
||||
throw new InternalExpressionException("First argument of 'all' function should be a list or iterator");
|
||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||
@@ -306,7 +306,7 @@ public class Loops {
|
||||
// can be substituted for first and all, but first is more efficient and all doesn't require knowing list size
|
||||
expression.addLazyFunction("for", 2, (c, t, lv) ->
|
||||
{
|
||||
Value rval= lv.get(0).evalValue(c);
|
||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||
if (!(rval instanceof AbstractListValue))
|
||||
throw new InternalExpressionException("First argument of 'for' function should be a list or iterator");
|
||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||
@@ -358,8 +358,8 @@ public class Loops {
|
||||
{
|
||||
LazyValue expr = lv.get(1);
|
||||
|
||||
Value acc = lv.get(2).evalValue(c);
|
||||
Value rval= lv.get(0).evalValue(c);
|
||||
Value acc = lv.get(2).evalValue(c, Context.NONE);
|
||||
Value rval= lv.get(0).evalValue(c, Context.NONE);
|
||||
if (!(rval instanceof AbstractListValue))
|
||||
throw new InternalExpressionException("First argument of 'reduce' should be a list or iterator");
|
||||
Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package carpet.script.utils;
|
||||
|
||||
import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class BiomeInfo
|
||||
{
|
||||
public final static Map<String, Function<Biome, Value>> biomeFeatures = new HashMap<String, Function<Biome, Value>>(){{
|
||||
put("top_material", b -> new BlockValue( b.getGenerationSettings().getSurfaceConfig().getTopMaterial(), null, null));
|
||||
put("under_material", b -> new BlockValue( b.getGenerationSettings().getSurfaceConfig().getUnderMaterial(), null, null));
|
||||
put("category", b -> StringValue.of(b.getCategory().getName()));
|
||||
put("temperature", b -> NumericValue.of(b.getTemperature()));
|
||||
put("fog_color", b -> ValueConversions.ofRGB(b.getFogColor()));
|
||||
put("foliage_color", b -> ValueConversions.ofRGB(b.getFoliageColor()));
|
||||
put("sky_color", b -> ValueConversions.ofRGB(b.getSkyColor()));
|
||||
put("water_color", b -> ValueConversions.ofRGB(b.getWaterColor()));
|
||||
put("water_fog_color", b -> ValueConversions.ofRGB(b.getWaterFogColor()));
|
||||
put("humidity", b -> NumericValue.of(b.getDownfall()));
|
||||
put("precipitation", b -> StringValue.of(b.getPrecipitation().getName()));
|
||||
put("depth", b -> NumericValue.of(b.getDepth()));
|
||||
put("scale", b -> NumericValue.of(b.getScale()));
|
||||
//put("features", b -> b.getGenerationSettings().getFeatures())
|
||||
}};
|
||||
}
|
||||
@@ -150,11 +150,11 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
return varArgs != null;
|
||||
}
|
||||
|
||||
public LazyValue callInContext(Expression callingExpression, Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||
public LazyValue callInContext(Context c, Integer type, List<LazyValue> lazyParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
return lazyEval(c, type, e, t, lazyParams);
|
||||
return lazyEval(c, type, expression, token, lazyParams);
|
||||
}
|
||||
catch (ExpressionException exc)
|
||||
{
|
||||
@@ -164,12 +164,12 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||
catch (InternalExpressionException exc)
|
||||
{
|
||||
exc.stack.add(this);
|
||||
throw new ExpressionException(c, e, t, exc.getMessage(), exc.stack);
|
||||
throw new ExpressionException(c, expression, token, exc.getMessage(), exc.stack);
|
||||
}
|
||||
|
||||
catch (ArithmeticException exc)
|
||||
{
|
||||
throw new ExpressionException(c, e, t, "Your math is wrong, "+exc.getMessage(), Collections.singletonList(this));
|
||||
throw new ExpressionException(c, expression, token, "Your math is wrong, "+exc.getMessage(), Collections.singletonList(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ public class NumericValue extends Value
|
||||
{
|
||||
if (value == null) return Value.NULL;
|
||||
if (value.doubleValue() == value.longValue()) return new NumericValue(value.longValue());
|
||||
if (value instanceof Float) return new NumericValue(0.000_001D * Math.round(1_000_000.0D*value.doubleValue()));
|
||||
return new NumericValue(value.doubleValue());
|
||||
}
|
||||
|
||||
|
||||
@@ -299,23 +299,27 @@ public class ValueConversions
|
||||
public static Value of(StructureStart<?> structure)
|
||||
{
|
||||
if (structure == null || structure == StructureStart.DEFAULT) return Value.NULL;
|
||||
List<Value> pieces = new ArrayList<>();
|
||||
for (StructurePiece piece : structure.getChildren())
|
||||
{
|
||||
BlockBox box = piece.getBoundingBox();
|
||||
pieces.add(ListValue.of(
|
||||
new StringValue( NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_PIECE.getId(piece.getType()))),
|
||||
(piece.getFacing()== null)?Value.NULL: new StringValue(piece.getFacing().getName()),
|
||||
ListValue.fromTriple(box.minX, box.minY, box.minZ),
|
||||
ListValue.fromTriple(box.maxX, box.maxY, box.maxZ)
|
||||
));
|
||||
}
|
||||
BlockBox boundingBox = structure.getBoundingBox();
|
||||
if (boundingBox.maxX < boundingBox.minX || boundingBox.maxY < boundingBox.minY || boundingBox.maxZ < boundingBox.minZ) return Value.NULL;
|
||||
Map<Value, Value> ret = new HashMap<>();
|
||||
ret.put(new StringValue("box"), ListValue.of(
|
||||
ListValue.fromTriple(boundingBox.minX, boundingBox.minY, boundingBox.minZ),
|
||||
ListValue.fromTriple(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ)
|
||||
));
|
||||
List<Value> pieces = new ArrayList<>();
|
||||
for (StructurePiece piece : structure.getChildren())
|
||||
{
|
||||
BlockBox box = piece.getBoundingBox();
|
||||
if (box.maxX >= box.minX && box.maxY >= box.minY && box.maxZ >= box.minZ)
|
||||
{
|
||||
pieces.add(ListValue.of(
|
||||
new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_PIECE.getId(piece.getType()))),
|
||||
(piece.getFacing() == null) ? Value.NULL : new StringValue(piece.getFacing().getName()),
|
||||
ListValue.fromTriple(box.minX, box.minY, box.minZ),
|
||||
ListValue.fromTriple(box.maxX, box.maxY, box.maxZ)
|
||||
));
|
||||
}
|
||||
}
|
||||
ret.put(new StringValue("pieces"), ListValue.wrap(pieces));
|
||||
return MapValue.wrap(ret);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,12 @@ __on_player_wakes_up(player) -> (
|
||||
print('Player '+player+' wakes up')
|
||||
);
|
||||
|
||||
__on_player_escapes_sleep(player) -> (
|
||||
print('');
|
||||
print('__on_player_escapes_sleep(player)');
|
||||
print('Player '+player+' wakes up using ESC key')
|
||||
);
|
||||
|
||||
__on_player_rides(player, forward, strafe, jumping, sneaking) ->
|
||||
(
|
||||
print('');
|
||||
|
||||
Reference in new issue
Block a user