Merge branch 'master' into 1.17

This commit is contained in:
gnembon committed 2020-11-28 12:13:07 -04:00
commit 4f7ebdd9ff
23 files changed
+306 -172

No files matched your search

+41 -49
View File
@@ -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 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. 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 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 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. 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> <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) => {waterlogged: false, half: top, open: false, ...}
set(x,y,z,'iron_trapdoor','half','top'); block_state(x,y,z,'half') => top 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 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]'),'half') => top
block_state(block('iron_trapdoor[half=top]'),'powered') => false block_state(block('iron_trapdoor[half=top]'),'powered') => false
bool(block_state(block('iron_trapdoor[half=top]'),'powered')) => 0 bool(block_state(block('iron_trapdoor[half=top]'),'powered')) => 0
</pre> </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)` ### `block_data(pos)`
Return NBT string associated with specific location, or null if the block does not carry block data. Can be currently 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 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 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 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. * `'monument'`: Ocean Monument. Generates at fixed Y coordinate, surrounds itself with water.
* `'fortress'`: Nether Fortress. Altitude varies, but its bounded by the code. * `'fortress'`: Nether Fortress. Altitude varies, but its bounded by the code.
* `'mansion'`: Woodland Mansion * `'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_treasure'`: Treasure room version of a piglin bastion (1.16)
* `'bastion_remnant_bridge'` : Bridge 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'`
* `'oak_beehive'`: oak with a hive (1.15+). * `'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) * `'twisting_vines'` (1.16)
* `'basalt_pillar'` (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'`, `'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'endcity'`, `'fortress'`, `'igloo'`,
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'monument'`, `'nether_fossil'`, `'ocean_ruin'`, `'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'monument'`, `'nether_fossil'`, `'ocean_ruin'`,
`'pillager_outpost'`, `'ruined_portal'`, `'shipwreck'`, `'stronghold'`, `'swamp_hut'`, `'village'` `'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'`, `'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'end_city'`, `'fortress'`, `'igloo'`,
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'mineshaft_mesa'`, `'monument'`, `'nether_fossil'`, `'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'`, `'ruined_portal_swamp'`, `'shipwreck'`, `'shipwreck_beached'`, `'stronghold'`, `'swamp_hut'`,
`'village_desert'`, `'village_plains'`, `'village_savanna'`, `'village_snovy'`, `'village_taiga'` `'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'`, Use `plop():'features'` and `plop():'configured_features'` for a list of available options. Your output may vary based on
`'birch'`, `'birch_bees_0002'`, `'birch_bees_002'`, `'birch_bees_005'`, `'birch_other'`, `'birch_tall'`, datapacks installed in your world.
`'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'`
### 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_bridge'` - Bridge version of a bastion remnant
* `'bastion_remnant_hoglin_stable'` - Hoglin stables 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 Unlike `'structure'` this will return a tentative structure location. Random factors in world generation may prevent
the actual structure from forming. 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 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. 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 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 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 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). 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)` ### `__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. 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_starts_sneaking(player)`
### `__on_player_stops_sneaking(player)` ### `__on_player_stops_sneaking(player)`
### `__on_player_starts_sprinting(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` * `color`
* Type: String * 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` * `displayName`
* Type: String or FormattedText, when querying returns FormattedText * Type: String or FormattedText, when querying returns FormattedText
+36 -48
View File
@@ -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 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. 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 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 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. 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> <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) => {waterlogged: false, half: top, open: false, ...}
set(x,y,z,'iron_trapdoor','half','top'); block_state(x,y,z,'half') => top 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 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]'),'half') => top
block_state(block('iron_trapdoor[half=top]'),'powered') => false block_state(block('iron_trapdoor[half=top]'),'powered') => false
bool(block_state(block('iron_trapdoor[half=top]'),'powered')) => 0 bool(block_state(block('iron_trapdoor[half=top]'),'powered')) => 0
</pre> </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)` ### `block_data(pos)`
Return NBT string associated with specific location, or null if the block does not carry block data. Can be currently 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 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 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 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. * `'monument'`: Ocean Monument. Generates at fixed Y coordinate, surrounds itself with water.
* `'fortress'`: Nether Fortress. Altitude varies, but its bounded by the code. * `'fortress'`: Nether Fortress. Altitude varies, but its bounded by the code.
* `'mansion'`: Woodland Mansion * `'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_treasure'`: Treasure room version of a piglin bastion (1.16)
* `'bastion_remnant_bridge'` : Bridge 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'`
* `'oak_beehive'`: oak with a hive (1.15+). * `'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) * `'twisting_vines'` (1.16)
* `'basalt_pillar'` (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'`, `'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'endcity'`, `'fortress'`, `'igloo'`,
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'monument'`, `'nether_fossil'`, `'ocean_ruin'`, `'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'monument'`, `'nether_fossil'`, `'ocean_ruin'`,
`'pillager_outpost'`, `'ruined_portal'`, `'shipwreck'`, `'stronghold'`, `'swamp_hut'`, `'village'` `'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'`, `'bastion_remnant'`, `'buried_treasure'`, `'desert_pyramid'`, `'end_city'`, `'fortress'`, `'igloo'`,
`'jungle_pyramid'`, `'mansion'`, `'mineshaft'`, `'mineshaft_mesa'`, `'monument'`, `'nether_fossil'`, `'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'`, `'ruined_portal_swamp'`, `'shipwreck'`, `'shipwreck_beached'`, `'stronghold'`, `'swamp_hut'`,
`'village_desert'`, `'village_plains'`, `'village_savanna'`, `'village_snovy'`, `'village_taiga'` `'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'`, Use `plop():'features'` and `plop():'configured_features'` for a list of available options. Your output may vary based on
`'birch'`, `'birch_bees_0002'`, `'birch_bees_002'`, `'birch_bees_005'`, `'birch_other'`, `'birch_tall'`, datapacks installed in your world.
`'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'`
### 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_bridge'` - Bridge version of a bastion remnant
* `'bastion_remnant_hoglin_stable'` - Hoglin stables 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 Unlike `'structure'` this will return a tentative structure location. Random factors in world generation may prevent
the actual structure from forming. 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 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. 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 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 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 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). Requires a `Standard Structure` name (see above).
+4
View File
@@ -170,6 +170,10 @@ Triggered when a server receives a request to deploy elytra, regardless if the f
### `__on_player_wakes_up(player)` ### `__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. 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_starts_sneaking(player)`
### `__on_player_stops_sneaking(player)` ### `__on_player_stops_sneaking(player)`
### `__on_player_starts_sprinting(player)` ### `__on_player_starts_sprinting(player)`
+1 -1
View File
@@ -69,7 +69,7 @@ Reads the `property` of the `team` if no `value` is specified. If a `value` is a
* `color` * `color`
* Type: String * 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` * `displayName`
* Type: String or FormattedText, when querying returns FormattedText * Type: String or FormattedText, when querying returns FormattedText
@@ -5,9 +5,11 @@ blast_resistance
block block
block_data block_data
block_light block_light
block_list
block_sound block_sound
block_state block_state
block_tick block_tick
block_tags
blocks_daylight blocks_daylight
blocks_movement blocks_movement
brightness brightness
+2 -1
View File
@@ -27,7 +27,8 @@ __on_player_stops_sprinting(player) ->
__on_player_switches_slot(player, from, to) -> __on_player_switches_slot(player, from, to) ->
__on_player_swaps_hands(player) -> __on_player_swaps_hands(player) ->
__on_player_uses_item(player, item_tuple, hand) -> __on_player_uses_item(player, item_tuple, hand) ->
__on_player_wakes_up(player) -> __on_player_wakes_up(player) ->
__on_player_escapes_sleep(player) ->
__on_statistic(player, category, event, value) -> __on_statistic(player, category, event, value) ->
__on_tick() -> __on_tick() ->
__on_tick_ender() -> __on_tick_ender() ->
@@ -53,7 +53,7 @@
transparent opacity blocks_daylight emitted_light light block_light sky_light see_sky brightness 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 hardness blast_resistance top loaded suffocates power ticks_randomly update block_tick random_tick in_slime_chunk
set without_updates 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 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 structure_eligibility structures structure_references set_structure reset_chunk reload_chunk custom_dimension
add_chunk_ticket add_chunk_ticket
@@ -115,6 +115,7 @@
__on_player_swaps_hands __on_player_swaps_hands
__on_player_uses_item __on_player_uses_item
__on_player_wakes_up __on_player_wakes_up
__on_player_escapes_sleep
__on_statistic __on_statistic
__on_tick __on_tick
__on_tick_ender __on_tick_ender
@@ -49,7 +49,7 @@ public class FeatureGenerator
return custom.plop(world, pos); return custom.plop(world, pos);
} }
Identifier id = new Identifier(featureName); 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) if (structureFeature != null)
{ {
return ((StructureFeatureInterface)structureFeature.feature).plopAnywhere( 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) if (feature != null)
{ {
CarpetSettings.skipGenerationChecks = true; CarpetSettings.skipGenerationChecks = true;
@@ -77,7 +77,7 @@ public class FeatureGenerator
public static ConfiguredStructureFeature<?, ?> resolveConfiguredStructure(String name, ServerWorld world, BlockPos pos) public static ConfiguredStructureFeature<?, ?> resolveConfiguredStructure(String name, ServerWorld world, BlockPos pos)
{ {
Identifier id = new Identifier(name); 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; if (configuredStructureFeature != null) return configuredStructureFeature;
StructureFeature<?> structureFeature = Registry.STRUCTURE_FEATURE.get(id); StructureFeature<?> structureFeature = Registry.STRUCTURE_FEATURE.get(id);
if (structureFeature == null) return null; if (structureFeature == null) return null;
@@ -137,7 +137,7 @@ public class FeatureGenerator
{ {
ConfiguredStructureFeature<?, ?> configuredFeature = world.getBiome(pos).getGenerationSettings().method_30978(structure.configure(null)); ConfiguredStructureFeature<?, ?> configuredFeature = world.getBiome(pos).getGenerationSettings().method_30978(structure.configure(null));
if (configuredFeature.config != null || !tryHard) return configuredFeature; 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). filter(cS -> cS.getValue().feature == structure).
findFirst().map(Map.Entry::getValue).orElse(null); findFirst().map(Map.Entry::getValue).orElse(null);
} }
@@ -168,7 +168,7 @@ public class FeatureGenerator
return null; 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("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("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))))); put("birch_bees", simpleTree(ConfiguredFeatures.BIRCH.getConfig().setTreeDecorators(ImmutableList.of(new BeehiveTreeDecorator(1.0F)))));
@@ -1,5 +1,6 @@
package carpet.mixins; package carpet.mixins;
import carpet.CarpetSettings;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.c2s.play.ButtonClickC2SPacket; import net.minecraft.network.packet.c2s.play.ButtonClickC2SPacket;
import net.minecraft.network.packet.c2s.play.CraftRequestC2SPacket; 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_DEPLOYS_ELYTRA;
import static carpet.script.CarpetEventServer.Event.PLAYER_DROPS_ITEM; 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_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_INTERACTS_WITH_ENTITY;
import static carpet.script.CarpetEventServer.Event.PLAYER_RELEASED_ITEM; import static carpet.script.CarpetEventServer.Event.PLAYER_RELEASED_ITEM;
import static carpet.script.CarpetEventServer.Event.PLAYER_RIDES; import static carpet.script.CarpetEventServer.Event.PLAYER_RIDES;
@@ -205,7 +207,11 @@ public class ServerPlayNetworkHandler_scarpetEventsMixin
private void onWakeUp(ClientCommandC2SPacket clientCommandC2SPacket_1, CallbackInfo ci) private void onWakeUp(ClientCommandC2SPacket clientCommandC2SPacket_1, CallbackInfo ci)
{ {
//weird one - doesn't seem to work, maybe MP //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( @Inject(method = "onClientCommand", at = @At(
@@ -337,6 +337,14 @@ public class CarpetEventServer
handler.call( () -> Collections.singletonList(new EntityValue(player)), player::getCommandSource); 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) public static final Event PLAYER_RIDES = new Event("player_rides", 5, false)
{ {
@Override @Override
+4 -4
View File
@@ -658,18 +658,18 @@ public class Expression
case UNARY_OPERATOR: case UNARY_OPERATOR:
{ {
final LazyValue value = stack.pop(); 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); stack.push(result);
break; break;
} }
case OPERATOR: case OPERATOR:
final LazyValue v1 = stack.pop(); final LazyValue v1 = stack.pop();
final LazyValue v2 = 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); stack.push(result);
break; break;
case VARIABLE: case VARIABLE:
stack.push((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c)); stack.push((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c, t));
break; break;
case FUNCTION: case FUNCTION:
String name = token.surface; String name = token.surface;
@@ -700,7 +700,7 @@ public class Expression
stack.pop(); 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; break;
case OPEN_PAREN: case OPEN_PAREN:
stack.push(LazyValue.PARAMS_START); stack.push(LazyValue.PARAMS_START);
+1 -1
View File
@@ -149,7 +149,7 @@ public abstract class Fluff
{ {
try 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) catch (RuntimeException exc)
{ {
+27 -17
View File
@@ -24,6 +24,7 @@ import carpet.script.value.EntityValue;
import carpet.script.value.FormattedTextValue; import carpet.script.value.FormattedTextValue;
import carpet.script.value.FunctionValue; import carpet.script.value.FunctionValue;
import carpet.script.value.ListValue; import carpet.script.value.ListValue;
import carpet.script.value.MapValue;
import carpet.script.value.NBTSerializableValue; import carpet.script.value.NBTSerializableValue;
import carpet.script.value.NullValue; import carpet.script.value.NullValue;
import carpet.script.value.NumericValue; 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.EulerAngle;
import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec2f;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair; 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.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@@ -304,7 +307,7 @@ public class Auxiliary {
pointLocator = Vector3Argument.findIn(cc, lv, 1, true); pointLocator = Vector3Argument.findIn(cc, lv, 1, true);
if (lv.size()>pointLocator.offset) 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 (blockLocator.block != null) targetBlock = blockLocator.block.getBlockState();
if (lv.size() > blockLocator.offset) if (lv.size() > blockLocator.offset)
{ {
@@ -619,6 +622,29 @@ public class Auxiliary {
}); });
expression.addLazyFunction("plop", -1, (c, t, lv) ->{ 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); BlockArgument locator = BlockArgument.findIn((CarpetContext)c, lv, 0);
if (lv.size() <= locator.offset) if (lv.size() <= locator.offset)
throw new InternalExpressionException("'plop' needs extra argument indicating what to plop"); 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) -> 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("`, `"))); //CarpetSettings.LOG.error(Registry.ENTITY_TYPE.getIds().stream().sorted().map(ValueConversions::simplify).collect(Collectors.joining("`, `")));
Value res; Value res;
if(lv.size()==1) 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"); if(!(propertyVal instanceof StringValue)) throw new InternalExpressionException("'team_property' requires a string as the second argument");
switch (propertyVal.getString()) { switch (propertyVal.getString()) {
case "collision_rule": case "collisionRule":
if(!modifying) { if(!modifying) {
Value ret = new StringValue(team.getCollisionRule().name); Value ret = new StringValue(team.getCollisionRule().name);
return (_c, _t) -> ret; return (_c, _t) -> ret;
@@ -287,7 +287,7 @@ public class Scoreboards {
team.setColor(color); team.setColor(color);
break; break;
case "death_message_visibility": case "deathMessageVisibility":
if(!modifying) { if(!modifying) {
Value ret = new StringValue(team.getDeathMessageVisibilityRule().name); Value ret = new StringValue(team.getDeathMessageVisibilityRule().name);
return (_c, _t) -> ret; return (_c, _t) -> ret;
@@ -300,7 +300,7 @@ public class Scoreboards {
team.setDeathMessageVisibilityRule(deathMessageVisibility); team.setDeathMessageVisibilityRule(deathMessageVisibility);
break; break;
case "display_name": case "displayName":
if(!modifying) { if(!modifying) {
Value ret = new FormattedTextValue(team.getDisplayName()); Value ret = new FormattedTextValue(team.getDisplayName());
return (_c, _t) -> ret; return (_c, _t) -> ret;
@@ -319,7 +319,7 @@ public class Scoreboards {
team.setDisplayName(displayName); team.setDisplayName(displayName);
break; break;
case "friendly_fire": case "friendlyFire":
if(!modifying) { if(!modifying) {
Value ret = new NumericValue(team.isFriendlyFireAllowed()); Value ret = new NumericValue(team.isFriendlyFireAllowed());
return (_c, _t) -> ret; return (_c, _t) -> ret;
@@ -330,7 +330,7 @@ public class Scoreboards {
boolean friendlyFire = settingVal.getBoolean(); boolean friendlyFire = settingVal.getBoolean();
team.setFriendlyFireAllowed(friendlyFire); team.setFriendlyFireAllowed(friendlyFire);
break; break;
case "nametag_visibility": case "nametagVisibility":
if(!modifying) { if(!modifying) {
Value ret = new StringValue(team.getNameTagVisibilityRule().name); Value ret = new StringValue(team.getNameTagVisibilityRule().name);
return (_c, _t) -> ret; return (_c, _t) -> ret;
@@ -361,7 +361,7 @@ public class Scoreboards {
team.setPrefix(prefix); team.setPrefix(prefix);
break; break;
case "see_friendly_invisibles": case "seeFriendlyInvisibles":
if(!modifying) { if(!modifying) {
Value ret = new NumericValue(team.shouldShowFriendlyInvisibles()); Value ret = new NumericValue(team.shouldShowFriendlyInvisibles());
return (_c, _t) -> ret; return (_c, _t) -> ret;
@@ -18,6 +18,7 @@ import carpet.script.LazyValue;
import carpet.script.argument.BlockArgument; import carpet.script.argument.BlockArgument;
import carpet.script.argument.Vector3Argument; import carpet.script.argument.Vector3Argument;
import carpet.script.exception.InternalExpressionException; import carpet.script.exception.InternalExpressionException;
import carpet.script.utils.BiomeInfo;
import carpet.script.utils.WorldTools; import carpet.script.utils.WorldTools;
import carpet.script.value.BlockValue; import carpet.script.value.BlockValue;
import carpet.script.value.EntityValue; import carpet.script.value.EntityValue;
@@ -66,6 +67,7 @@ import net.minecraft.sound.SoundCategory;
import net.minecraft.state.StateManager; import net.minecraft.state.StateManager;
import net.minecraft.state.property.Property; import net.minecraft.state.property.Property;
import net.minecraft.structure.StructureStart; import net.minecraft.structure.StructureStart;
import net.minecraft.tag.TagManager;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Clearable; import net.minecraft.util.Clearable;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@@ -101,6 +103,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -997,7 +1000,7 @@ public class WorldAccess {
// block_state(block, property) // block_state(block, property)
expression.addLazyFunction("block_state", -1, (c, t, lv) -> 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(); BlockState state = locator.block.getBlockState();
StateManager<Block, BlockState> states = state.getBlock().getStateManager(); StateManager<Block, BlockState> states = state.getBlock().getStateManager();
if (locator.offset == lv.size()) if (locator.offset == lv.size())
@@ -1018,16 +1021,71 @@ public class WorldAccess {
return (_c, _t) -> retval; 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) -> { expression.addLazyFunction("biome", -1, (c, t, lv) -> {
CarpetContext cc = (CarpetContext)c; CarpetContext cc = (CarpetContext)c;
BlockArgument locator = BlockArgument.findIn(cc, lv, 0); BlockArgument locator = BlockArgument.findIn(cc, lv, 0, false, false, true);
ServerWorld world = cc.s.getWorld(); Biome biome;
BlockPos pos = locator.block.getPos(); if (locator.replacement != null)
Biome biome = world.getBiome(pos); {
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 // in locatebiome
Identifier biomeId = cc.s.getMinecraftServer().getRegistryManager().get(Registry.BIOME_KEY).getId(biome); if (locator.offset == lv.size())
Value res = new StringValue(NBTSerializableValue.nameFromRegistryId(biomeId)); {
return (_c, _t) -> res; 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) -> expression.addLazyFunction("set_biome", -1, (c, t, lv) ->
@@ -1128,7 +1186,17 @@ public class WorldAccess {
Map<Value, Value> ret = new HashMap<>(); Map<Value, Value> ret = new HashMap<>();
for(StructureFeature<?> str : StructureFeature.STRUCTURES.values()) 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; if (start == null) continue;
Value key = new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.STRUCTURE_FEATURE.getId(str))); 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 class BlockArgument extends Argument
{ {
public final BlockValue block; public final BlockValue block;
public final String replacement;
private BlockArgument(BlockValue b, int o) private BlockArgument(BlockValue b, int o)
{ {
super(o); super(o);
block = b; 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) 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) 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 try
{ {
@@ -41,6 +49,10 @@ public class BlockArgument extends Argument
{ {
return new BlockArgument(null, 1+offset); return new BlockArgument(null, 1+offset);
} }
if (anyString && v1 instanceof StringValue)
{
return new BlockArgument(null, 1+offset, v1.getString());
}
if (acceptString && v1 instanceof StringValue) if (acceptString && v1 instanceof StringValue)
{ {
return new BlockArgument(BlockValue.fromString(v1.getString()), 1+offset); 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); FunctionArgument<LazyValue> functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
FunctionValue fun = functionArgument.function; FunctionValue fun = functionArgument.function;
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), functionArgument.args).evalValue(c); return fun.callInContext(c, t, functionArgument.args);
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
} }
// gimme signature // 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> args = new ArrayList<>();
List<String> globals = new ArrayList<>(); List<String> globals = new ArrayList<>();
String varArgs = null; String varArgs = null;
@@ -70,7 +70,7 @@ public class Loops {
// expr receives bounded variable '_' indicating iteration // expr receives bounded variable '_' indicating iteration
expression.addLazyFunction("loop", 2, (c, t, lv) -> 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; Value lastOne = Value.NULL;
LazyValue expr = lv.get(1); LazyValue expr = lv.get(1);
//scoping //scoping
@@ -99,7 +99,7 @@ public class Loops {
// receives bounded variable '_' with the expression // receives bounded variable '_' with the expression
expression.addLazyFunction("map", 2, (c, t, lv) -> 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)) if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'map' function should be a list or iterator"); throw new InternalExpressionException("First argument of 'map' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator(); Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -144,7 +144,7 @@ public class Loops {
// produces list of values for which the expression is true // produces list of values for which the expression is true
expression.addLazyFunction("filter", 2, (c, t, lv) -> 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)) if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'filter' function should be a list or iterator"); throw new InternalExpressionException("First argument of 'filter' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator(); Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -191,7 +191,7 @@ public class Loops {
expression.addLazyFunction("first", 2, (c, t, lv) -> 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)) if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'first' function should be a list or iterator"); throw new InternalExpressionException("First argument of 'first' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator(); Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -242,7 +242,7 @@ public class Loops {
// returns true if expr is true for all items // returns true if expr is true for all items
expression.addLazyFunction("all", 2, (c, t, lv) -> 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)) if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'all' function should be a list or iterator"); throw new InternalExpressionException("First argument of 'all' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).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 // 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) -> 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)) if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'for' function should be a list or iterator"); throw new InternalExpressionException("First argument of 'for' function should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).iterator(); Iterator<Value> iterator = ((AbstractListValue) rval).iterator();
@@ -358,8 +358,8 @@ public class Loops {
{ {
LazyValue expr = lv.get(1); LazyValue expr = lv.get(1);
Value acc = lv.get(2).evalValue(c); Value acc = lv.get(2).evalValue(c, Context.NONE);
Value rval= lv.get(0).evalValue(c); Value rval= lv.get(0).evalValue(c, Context.NONE);
if (!(rval instanceof AbstractListValue)) if (!(rval instanceof AbstractListValue))
throw new InternalExpressionException("First argument of 'reduce' should be a list or iterator"); throw new InternalExpressionException("First argument of 'reduce' should be a list or iterator");
Iterator<Value> iterator = ((AbstractListValue) rval).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; 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 try
{ {
return lazyEval(c, type, e, t, lazyParams); return lazyEval(c, type, expression, token, lazyParams);
} }
catch (ExpressionException exc) catch (ExpressionException exc)
{ {
@@ -164,12 +164,12 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
catch (InternalExpressionException exc) catch (InternalExpressionException exc)
{ {
exc.stack.add(this); 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) 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 == null) return Value.NULL;
if (value.doubleValue() == value.longValue()) return new NumericValue(value.longValue()); 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()); return new NumericValue(value.doubleValue());
} }
@@ -299,23 +299,27 @@ public class ValueConversions
public static Value of(StructureStart<?> structure) public static Value of(StructureStart<?> structure)
{ {
if (structure == null || structure == StructureStart.DEFAULT) return Value.NULL; 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(); 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<>(); Map<Value, Value> ret = new HashMap<>();
ret.put(new StringValue("box"), ListValue.of( ret.put(new StringValue("box"), ListValue.of(
ListValue.fromTriple(boundingBox.minX, boundingBox.minY, boundingBox.minZ), ListValue.fromTriple(boundingBox.minX, boundingBox.minY, boundingBox.minZ),
ListValue.fromTriple(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ) 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)); ret.put(new StringValue("pieces"), ListValue.wrap(pieces));
return MapValue.wrap(ret); return MapValue.wrap(ret);
} }
@@ -17,6 +17,12 @@ __on_player_wakes_up(player) -> (
print('Player '+player+' wakes up') 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) -> __on_player_rides(player, forward, strafe, jumping, sneaking) ->
( (
print(''); print('');