diff --git a/docs/scarpet/api/Auxiliary.md b/docs/scarpet/api/Auxiliary.md index 7d9da627..a8b097dc 100644 --- a/docs/scarpet/api/Auxiliary.md +++ b/docs/scarpet/api/Auxiliary.md @@ -36,19 +36,41 @@ supplied, only that player will receive particles. ## Markers -### `marker_box(from, to, duration?, color?, player?)` +### `draw_shape(shape, duration, key?, value?, ... )`, `draw_shape(shape, duration, l(key?, value?, ... ))`, `draw_shape(shape, duration, attribute_map)` -Draws a box with `from` and `to` corners in the box. The boxes will dissipate after `duration` ticks (defaults to 10). -The color is an integer that indicate red, green, blue and alpha components in the form of `0xRRGGBBAA`, with the -default of `-1`, so white opaque, or `0xFFFFFFFF`. If player is specified, only displays for that player, otherwise all -players will see them. `marker_box` requires proper client synchronization to display these, and on non-supported -clients, the box will be replaced with close matching dust particles, so using of `marker_box` is safe to use for -scripts regardless who is targeted. The only consideration is that with vanilla clients, duration of particles cannot -be controlled, and last whatever the original particles do. +Draws a shape in the world that will expire in `duration` ticks. Other attributes of the shape should be provided as +consecutive key - value argument pairs, either as next arguments, or packed in a list, or supplied as a proper key-value +`map`. Arguments may include shared shape attributes, which are all optional, as well as shape-specific attributes, that +could be either optional or required. Shapes will draw properly on all carpet clients. Other connected players that don't +have carpet installed will still be able to see the required shapes in the form of dust particles. Replacement shapes +are not required to follow all attributes precisely, but will allow vanilla clients to receive some experience of your +apps. One of the attributes that will definitely not be honored is the duration - particles will be send once +per shape and last whatever they typically last in the game. -### `marker_line(from, to, duration?, color?, player?)` +Shapes will fail to draw and raise a runtime error if not all its required parameters +are specified and all available shapes have some parameters that are required, so make sure to have them in place: -Draws a marker line on client's screen. Uses similar setup as `marker_box`. +On the client, shapes can recognize that they are being redrawn again with the same parameters, disregarding the +duration parameter. This updates the expiry on the drawn shape to the new value, instead of adding new shape in its +place. This can be used for toggling the shapes on and off that has been send previously with very large durations, +or simply refresh the shapes periodically in more dynamic applications. + +Optional shared shape attributes: + * `color` - integer value indicating the main color of the shape in the form of red, green, blue and alpha components + in the form of `0xRRGGBBAA`, with the default of `-1`, so white opaque, or `0xFFFFFFFF`. + * `player` - name or player entity to send the shape to. If specified, the shapes will appear only for the specified + player, otherwise it will be send to all players in the dimension. + +Available shapes: + * `'line'` - draws a straight line between two points + * Required attributes: + * `from` - triple coordinates, entity, or block value indicating one end of the line + * `to` - other end of the line, same format as `from` + + * `'box'` - draws a box with corners in specified points + * Required attributes: + * `from` - triple coordinates, entity, or block value indicating one corner of the box + * `to` - other corner, same format as `from` ### `create_marker(text, pos, rotation?, block?)` diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index d9198cb1..e14eeb8b 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -2685,7 +2685,7 @@ public class CarpetExpression ServerPlayerEntity player = null; if (params.containsKey("player")) { - player = (ServerPlayerEntity) ((EntityValue)params.get("player")).getEntity(); + player = (ServerPlayerEntity)((EntityValue)params.get("player")).getEntity(); } ShapeDispatcher.sendShape( (player==null)?cc.s.getWorld().getPlayers():Collections.singletonList(player), diff --git a/src/main/java/carpet/script/utils/ShapeDispatcher.java b/src/main/java/carpet/script/utils/ShapeDispatcher.java index e37e5245..0aaadb12 100644 --- a/src/main/java/carpet/script/utils/ShapeDispatcher.java +++ b/src/main/java/carpet/script/utils/ShapeDispatcher.java @@ -103,16 +103,14 @@ public class ShapeDispatcher public static ExpiringShape create(CarpetContext cc, String shapeType, Map userParams) { userParams.put("shape", new StringValue(shapeType)); - Map validatedParams = new HashMap<>(); - userParams.forEach((key, value) -> - { + userParams.keySet().forEach(key -> { Param param = Param.coders.get(key); if (param==null) throw new InternalExpressionException("Unknown feature for shape: "+key); - validatedParams.put(key, param.validate(cc, value)); + userParams.put(key, param.validate(cc, userParams.get(key))); }); Function,ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeType); if (factory == null) throw new InternalExpressionException("Unknown shape: "+shapeType); - return factory.apply(validatedParams); + return factory.apply(userParams); } // client @@ -227,7 +225,7 @@ public class ShapeDispatcher } // list of params that need to be there private final Set required = ImmutableSet.of("duration", "shape", "dim"); - private final Map optional = ImmutableMap.of("color", new NumericValue(-1)); + private final Map optional = ImmutableMap.of("color", new NumericValue(-1), "player", Value.NULL); protected Set requiredParams() {return required;} // list of params that can be there, with defaults protected Set optionalParams() {return optional.keySet();}