From d980ab6d915b98d2bc98eee9c585bfdd5197bcd6 Mon Sep 17 00:00:00 2001 From: gnembon Date: Sun, 29 Nov 2020 19:33:28 -0400 Subject: [PATCH] added blockpredicate argument support --- docs/scarpet/api/Overview.md | 14 ++++++++++++++ .../assets/carpet/scripts/draw_beta.sc | 17 ++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/docs/scarpet/api/Overview.md b/docs/scarpet/api/Overview.md index 1beac900..f81da3a5 100644 --- a/docs/scarpet/api/Overview.md +++ b/docs/scarpet/api/Overview.md @@ -206,6 +206,20 @@ Here is a list of built-in types, with their return value formats, as well as a * `'pos'`: block position as a triple of coordinates. Customized with `'loaded'`, if true requiring the position to be loaded. * `'block'`: a valid block state wrapped in a block value (including block properties and data) + * `'blockpredicate`': returns a 4-tuple indicating conditions of a block to match: block name, block tag, + map of required state properties, and tag to match. Either block name or block tag are `null` but not both. + Property map is always specified, but its empty for no conditions, and matching nbt tag can be `null` indicating + no requirements. Technically the 'all-matching' predicate would be `[null, null, {}, null]`, but + block name or block tag is always specified. One can use the following routine to match a block agains this predicate: + ``` + block_to_match = block(x,y,z); + [block_name, block_tag, properties, nbt_tag] = block_predicate; + + (block_name == null || block_name == block_to_match) && + (block_tag == null || block_tags(block_to_match, block_tag)) && + all(properties, block_state(block_to_match, _) == properties:_) && + (!tag || tag_matches(block_data(block_to_match), tag)) + ``` * `'teamcolor'`: name of a team, and an integer color value of one of 16 valid team colors. * `'columnpos'`: a pair of x and z coordinates. * `'dimension'`: string representing a valid dimension in the world. diff --git a/src/main/resources/assets/carpet/scripts/draw_beta.sc b/src/main/resources/assets/carpet/scripts/draw_beta.sc index ff819431..c88739d1 100644 --- a/src/main/resources/assets/carpet/scripts/draw_beta.sc +++ b/src/main/resources/assets/carpet/scripts/draw_beta.sc @@ -20,7 +20,7 @@ __config() -> { 'arguments'->{ 'center'->{'type'->'pos', 'loaded'->'true'}, 'radius'->{'type'->'int', 'suggest'->[], 'min'->0},//to avoid default suggestions - 'replacement'->{'type'->'block'}, + 'replacement'->{'type'->'blockpredicate'}, 'height'->{'type'->'int', 'suggest'->[],'min'->0}, 'orientation'->{'type'->'term', 'suggest'->['x','y','z']}, 'pointing'->{'type'->'term','suggest'->['up','down']}, @@ -32,9 +32,20 @@ __config() -> { //"Boilerplate" code +_block_matches(existing, block_predicate) -> +( + [name, block_tag, properties, nbt] = block_predicate; + + (name == null || name == existing) && + (block_tag == null || block_tags(existing, block_tag)) && + all(properties, block_state(existing, _) == properties:_) && + (!tag || tag_matches(block_data(existing), tag)) +); + set_block(x, y, z, block, replacement)-> ( - if(block != block(x, y, z), - without_updates( if (set([x, y, z],block), + existing = block(x, y, z); + if(block != existing && (replacement && _block_matches(existing, replacement) ), + without_updates( if (set(existing,block), global_affected += [x, y, z]; )); );