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
+294 -160

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
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
+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
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).
+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)`
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)`
+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`
* 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
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
+4 -4
View File
@@ -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);
+1 -1
View File
@@ -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)
{
+27 -17
View File
@@ -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);
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 biome = world.getBiome(pos);
biome = world.getBiome(pos);
}
// in locatebiome
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,10 +299,19 @@ public class ValueConversions
public static Value of(StructureStart<?> structure)
{
if (structure == null || structure == StructureStart.DEFAULT) return Value.NULL;
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()),
@@ -310,12 +319,7 @@ public class ValueConversions
ListValue.fromTriple(box.maxX, box.maxY, box.maxZ)
));
}
BlockBox boundingBox = structure.getBoundingBox();
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)
));
}
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('');