From 5280cda3ee1ec89ce52d3e9af29fe5f1e71d3f2e Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 16 Dec 2020 02:05:05 -0400 Subject: [PATCH] set can now accept map of properties. --- docs/scarpet/api/BlocksAndWorldAccess.md | 25 +++++++++++-------- .../java/carpet/script/api/WorldAccess.java | 15 +++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/docs/scarpet/api/BlocksAndWorldAccess.md b/docs/scarpet/api/BlocksAndWorldAccess.md index 990ae027..a7419d0f 100644 --- a/docs/scarpet/api/BlocksAndWorldAccess.md +++ b/docs/scarpet/api/BlocksAndWorldAccess.md @@ -36,18 +36,19 @@ print(b); // 'stone', block was evaluated 'eagerly' but call to `block` All the functions below can be used with block value, queried with coord triple, or 3-long list. All `pos` in the functions referenced below refer to either method of passing block position. -### `set(pos, block, property?, value?, ..., block_data?)`, `set(pos, block, l(property?, value?, ...), block_data?)` +### `set(pos, block, property?, value?, ..., block_data?)`, `set(pos, block, [property?, value?, ...], block_data?)`, `set(pos, block, {property? -> value?, ...}, block_data?)` -First part of the `set` function is either a coord triple, list of three numbers, or other block with coordinates. -Second part, `block` is either block value as a result of `block()` function string value indicating the block name, -and optional `property - value` pairs for extra block properties. Optional `block_data` include the block data to +First argument for the `set` function is either a coord triple, list of three numbers, or a world localized block value. +Second argument, `block`, is either an existing block value, a result of `block()` function, or a string value indicating the block name +with optional state and block data. It is then followed by an optional +`property - value` pairs for extra block state (which can also be provided in a list or a map). Optional `block_data` include the block data to be set for the target block. If `block` is specified only by name, then if a destination block is the same the `set` operation is skipped, otherwise is executed, for other potential extra -properties. +properties that the original source block may have contained. -The returned value is either the block state that has been set, or `false` if block setting was skipped +The returned value is either the block state that has been set, or `false` if block setting was skipped, or failed
 set(0,5,0,'bedrock')  => bedrock
@@ -63,11 +64,15 @@ scan(0,100,0,20,20,20,set(_,block('glass')))
 b = block('glass'); scan(0,100,0,20,20,20,set(_,b))
     // yet another option, skips all parsing
 set(x,y,z,'iron_trapdoor')  // sets bottom iron trapdoor
-set(x,y,z,'iron_trapdoor[half=top]')  // Incorrect. sets bottom iron trapdoor - no parsing of properties
-set(x,y,z,'iron_trapdoor','half','top') // correct - top trapdoor
-set(x,y,z, block('iron_trapdoor[half=top]')) // also correct, block() provides extra parsing
+
+set(x,y,z,'iron_trapdoor[half=top]')  // sets the top trapdoor
+set(x,y,z,'iron_trapdoor','half','top') // also correct - top trapdoor
+set(x,y,z,'iron_trapdoor', ['half','top']) // same
+set(x,y,z,'iron_trapdoor', {'half' -> 'top'}) // same
+set(x,y,z, block('iron_trapdoor[half=top]')) // also correct, block() provides extra parsing of block state
+
 set(x,y,z,'hopper[facing=north]{Items:[{Slot:1b,id:"minecraft:slime_ball",Count:16b}]}') // extra block data
-set(x,y,z,'hopper', l('facing', 'north'), nbt('{Items:[{Slot:1b,id:"minecraft:slime_ball",Count:16b}]}') ) // same
+set(x,y,z,'hopper', {'facing' -> 'north'}, nbt('{Items:[{Slot:1b,id:"minecraft:slime_ball",Count:16b}]}') ) // same
 
### `without_updates(expr)` diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index 82221c84..d15da361 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -777,6 +777,21 @@ public class WorldAccess { } args = ((ListValue) args.get(0)).getItems(); } + else if (args.get(0) instanceof MapValue) + { + if (args.size() == 2) + { + Value dataValue = NBTSerializableValue.fromValue( args.get(1)); + if (dataValue instanceof NBTSerializableValue) + { + data = ((NBTSerializableValue) dataValue).getCompoundTag(); + } + } + Map state = ((MapValue) args.get(0)).getMap(); + List mapargs = new ArrayList<>(); + state.forEach( (k, v) -> {mapargs.add(k); mapargs.add(v);}); + args = mapargs; + } else { if ((args.size() & 1) == 1)