added optional options for draw_shape and fixed docs
This commit is contained in:
1 parent
4271aa3a8e
commit
46409c8daa
7 files changed
+136
-30
No files matched your search
+56
-8
@@ -906,8 +906,11 @@ sleep(50)
|
||||
|
||||
### `time()`
|
||||
|
||||
Returns the number of milliseconds since 'some point', like Java's `System.nanoTime()`.
|
||||
It returns a float, which has 1 microsecond precision (0.001 ms)
|
||||
Returns the number of milliseconds since 'some point', like Java's `System.nanoTime()`, which varies from system to
|
||||
system and from Java to Java. This measure should NOT be used to determine the current (date)time, but to measure
|
||||
durations of things.
|
||||
it returns a float with time in milliseconds (ms) for convenience and microsecond (μs) resolution for sanity.
|
||||
|
||||
|
||||
<pre>
|
||||
start_time = time();
|
||||
@@ -1513,7 +1516,7 @@ range(5,10) => [5, 6, 7, 8, 9]
|
||||
range(20, 10, -2) => [20, 18, 16, 14, 12]
|
||||
</pre>
|
||||
|
||||
### `element(list, index)` (deprecated)
|
||||
### `element(list, index)(deprecated)`
|
||||
|
||||
Legacy support for older method that worked only on lists. Please use `get(...)` for equivalent support, or `.`
|
||||
operator. Also previous unique behaviours with `put` on lists has been removed to support all type of
|
||||
@@ -3103,24 +3106,69 @@ and `voice`. `pos` can be either a block, triple of coords, or a list of thee nu
|
||||
|
||||
## Particles
|
||||
|
||||
### `particle(name, pos, count?. spread?, speed?, playername?)`
|
||||
### `particle(name, pos, count?. spread?, speed?, player?)`
|
||||
|
||||
Renders a cloud of particles `name` centered around `pos` position, by default `count` 10 of them, default `speed`
|
||||
of 0, and to all players nearby, but these options can be changed via optional arguments. Follow vanilla `/particle`
|
||||
command on details on those options. Valid particle names are
|
||||
for example `'angry_villager', 'item diamond', 'block stone', 'dust 0.8 0.1 0.1 4'`.
|
||||
|
||||
### `particle_line(name, pos, pos2, density?)`
|
||||
### `particle_line(name, pos, pos2, density?, player?)`
|
||||
|
||||
Renders a line of particles from point `pos` to `pos2` with supplied density (defaults to 1), which indicates how far
|
||||
apart you would want particles to appear, so `0.1` means one every 10cm.
|
||||
apart you would want particles to appear, so `0.1` means one every 10cm. If a player (or player name) is supplied, only
|
||||
that player will receive particles.
|
||||
|
||||
### `particle_rect(name, pos, pos2, density?)`
|
||||
|
||||
Renders a cuboid of particles between points `pos` and `pos2` with supplied density.
|
||||
### `particle_box(name, pos, pos2, density?, player?)`
|
||||
### `particle_rect` (deprecated)
|
||||
|
||||
Renders a cuboid of particles between points `pos` and `pos2` with supplied density. If a player (or player name) is
|
||||
supplied, only that player will receive particles.
|
||||
|
||||
## Markers
|
||||
|
||||
### `draw_shape(shape, duration, key?, value?, ... )`, `draw_shape(shape, duration, l(key?, value?, ... ))`, `draw_shape(shape, duration, attribute_map)`
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
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`
|
||||
* Optional attributes:
|
||||
* `width` - line thickness, defaults to 2.0pt
|
||||
|
||||
* `'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`
|
||||
* Optional attributes:
|
||||
* `width` - mesh line thickness, defaults to 2.0pt
|
||||
* `fill` - color for the box faces, defaults to no fill, use shared color attribute format
|
||||
|
||||
### `create_marker(text, pos, rotation?, block?)`
|
||||
|
||||
Spawns a (permanent) marker entity with text or block at position. Returns that entity for further manipulations.
|
||||
|
||||
@@ -66,11 +66,16 @@ Available shapes:
|
||||
* 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`
|
||||
* Optional attributes:
|
||||
* `width` - line thickness, defaults to 2.0pt
|
||||
|
||||
* `'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`
|
||||
* Optional attributes:
|
||||
* `width` - mesh line thickness, defaults to 2.0pt
|
||||
* `fill` - color for the box faces, defaults to no fill, use shared color attribute format
|
||||
|
||||
### `create_marker(text, pos, rotation?, block?)`
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ current_dimension
|
||||
day_time
|
||||
destroy
|
||||
diamond
|
||||
draw_shape
|
||||
drop_item
|
||||
emitted_light
|
||||
entity_area
|
||||
|
||||
@@ -70,7 +70,9 @@
|
||||
|
||||
run save tick_time world_time day_time last_tick_times game_tick seed current_dimension in_dimension
|
||||
|
||||
plop harvest destroy schedule nbt create_marker remove_all_markers load_app_data store_app_data escape_nbt statistic
|
||||
plop harvest destroy schedule nbt draw_shape create_marker remove_all_markers
|
||||
|
||||
load_app_data store_app_data escape_nbt statistic
|
||||
</Keywords>
|
||||
<Keywords name="Keywords3">euler pi null true false</Keywords>
|
||||
<Keywords name="Keywords4">x y z p</Keywords>
|
||||
|
||||
@@ -35,7 +35,7 @@ public class ClientNetworkHandler
|
||||
}
|
||||
});
|
||||
put("TickRate", (p, t) -> TickSpeed.tickrate(((AbstractNumberTag)t).getFloat(), false));
|
||||
put("renderShape", (p, t) -> {
|
||||
put("scShape", (p, t) -> {
|
||||
if (CarpetClient.shapes != null)
|
||||
CarpetClient.shapes.addShape((CompoundTag)t);
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.command.arguments.ParticleArgumentType;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.FloatTag;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
@@ -57,7 +58,7 @@ public class ShapeDispatcher
|
||||
if (ServerNetworkHandler.validCarpetPlayers.contains(player))
|
||||
{
|
||||
if (tag == null) tag = ExpiringShape.toTag(params);
|
||||
ServerNetworkHandler.sendCustomCommand(player,"renderShape", tag);
|
||||
ServerNetworkHandler.sendCustomCommand(player,"scShape", tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -122,7 +123,7 @@ public class ShapeDispatcher
|
||||
Function<Tag, Value> decoder = Param.decoders.get(key);
|
||||
if (decoder==null)
|
||||
{
|
||||
CarpetSettings.LOG.error("Unknown parameter for shape: "+key);
|
||||
CarpetSettings.LOG.info("Unknown parameter for shape: "+key);
|
||||
return null;
|
||||
}
|
||||
Value decodedValue = decoder.apply(tag.get(key));
|
||||
@@ -131,13 +132,13 @@ public class ShapeDispatcher
|
||||
Value shapeValue = options.get("shape");
|
||||
if (shapeValue == null)
|
||||
{
|
||||
CarpetSettings.LOG.error("Shape id missing in "+ String.join(", ", tag.getKeys()));
|
||||
CarpetSettings.LOG.info("Shape id missing in "+ String.join(", ", tag.getKeys()));
|
||||
return null;
|
||||
}
|
||||
Function<Map<String, Value>,ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeValue.getString());
|
||||
if (factory == null)
|
||||
{
|
||||
CarpetSettings.LOG.error("Unknown shape: "+shapeValue.getString());
|
||||
CarpetSettings.LOG.info("Unknown shape: "+shapeValue.getString());
|
||||
return null;
|
||||
}
|
||||
try
|
||||
@@ -146,7 +147,7 @@ public class ShapeDispatcher
|
||||
}
|
||||
catch (InternalExpressionException exc)
|
||||
{
|
||||
CarpetSettings.LOG.error(exc.getMessage());
|
||||
CarpetSettings.LOG.info(exc.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -225,7 +226,10 @@ public class ShapeDispatcher
|
||||
}
|
||||
// list of params that need to be there
|
||||
private final Set<String> required = ImmutableSet.of("duration", "shape", "dim");
|
||||
private final Map<String, Value> optional = ImmutableMap.of("color", new NumericValue(-1), "player", Value.NULL);
|
||||
private final Map<String, Value> optional = ImmutableMap.of(
|
||||
"color", new NumericValue(-1),
|
||||
"player", Value.NULL
|
||||
);
|
||||
protected Set<String> requiredParams() {return required;}
|
||||
// list of params that can be there, with defaults
|
||||
protected Set<String> optionalParams() {return optional.keySet();}
|
||||
@@ -234,7 +238,10 @@ public class ShapeDispatcher
|
||||
public static class Box extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("from", "to");
|
||||
private final Map<String, Value> optional = ImmutableMap.of();
|
||||
private final Map<String, Value> optional = ImmutableMap.of(
|
||||
"width", new NumericValue(2.0),
|
||||
"fill", new NumericValue(0xffffff00)
|
||||
);
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
@@ -243,6 +250,10 @@ public class ShapeDispatcher
|
||||
|
||||
float x1, y1, z1;
|
||||
float x2, y2, z2;
|
||||
float lineWidth;
|
||||
|
||||
protected float fr, fg, fb, fa;
|
||||
protected int fillColor;
|
||||
|
||||
@Override
|
||||
protected void init(Map<String, Value> options)
|
||||
@@ -256,6 +267,12 @@ public class ShapeDispatcher
|
||||
x2 = NumericValue.asNumber(to.get(0)).getFloat();
|
||||
y2 = NumericValue.asNumber(to.get(1)).getFloat();
|
||||
z2 = NumericValue.asNumber(to.get(2)).getFloat();
|
||||
lineWidth = NumericValue.asNumber(options.getOrDefault("width", optional.get("width"))).getFloat();
|
||||
fillColor = NumericValue.asNumber(options.getOrDefault("fill", optional.get("fill"))).getInt();
|
||||
this.fr = (float)(fillColor >> 24 & 0xFF) / 255.0F;
|
||||
this.fg = (float)(fillColor >> 16 & 0xFF) / 255.0F;
|
||||
this.fb = (float)(fillColor >> 8 & 0xFF) / 255.0F;
|
||||
this.fa = (float)(fillColor & 0xFF) / 255.0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -281,6 +298,8 @@ public class ShapeDispatcher
|
||||
hash = 31*hash + Float.hashCode(x2);
|
||||
hash = 31*hash + Float.hashCode(y2);
|
||||
hash = 31*hash + Float.hashCode(z2);
|
||||
hash = 31*hash + Float.hashCode(lineWidth);
|
||||
if (fa != 0.0) hash = 31*hash + fillColor;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -308,7 +327,7 @@ public class ShapeDispatcher
|
||||
public static class Line extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("from", "to");
|
||||
private final Map<String, Value> optional = ImmutableMap.of();
|
||||
private final Map<String, Value> optional = ImmutableMap.of("width", new NumericValue(2.0));
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
@@ -321,6 +340,7 @@ public class ShapeDispatcher
|
||||
|
||||
float x1, y1, z1;
|
||||
float x2, y2, z2;
|
||||
float lineWidth;
|
||||
|
||||
@Override
|
||||
protected void init(Map<String, Value> options)
|
||||
@@ -334,6 +354,7 @@ public class ShapeDispatcher
|
||||
x2 = NumericValue.asNumber(to.get(0)).getFloat();
|
||||
y2 = NumericValue.asNumber(to.get(1)).getFloat();
|
||||
z2 = NumericValue.asNumber(to.get(2)).getFloat();
|
||||
lineWidth = NumericValue.asNumber(options.getOrDefault("width", optional.get("width"))).getFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -361,6 +382,7 @@ public class ShapeDispatcher
|
||||
hash = 31*hash + Float.hashCode(x2);
|
||||
hash = 31*hash + Float.hashCode(y2);
|
||||
hash = 31*hash + Float.hashCode(z2);
|
||||
hash = 31*hash + Float.hashCode(lineWidth);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@@ -374,16 +396,19 @@ public class ShapeDispatcher
|
||||
put("color", ShapeDispatcher::decodeInt);
|
||||
put("from", Vec3Param::decode);
|
||||
put("to", Vec3Param::decode);
|
||||
|
||||
put("width", ShapeDispatcher::decodeFloat);
|
||||
put("fill", ShapeDispatcher::decodeInt);
|
||||
}};
|
||||
Map<String, Param> coders = new HashMap<String, Param>(){{
|
||||
put("shape", new ShapeParam());
|
||||
put("player", new PlayerParam());
|
||||
put("shape", new ShapeParam());
|
||||
put("dim", new DimensionParam());
|
||||
put("duration", new DurationParam());
|
||||
put("color", new ColorParam());
|
||||
put("from", new FromParam());
|
||||
put("to", new ToParam());
|
||||
put("width", new WidthParam());
|
||||
put("fill", new FillColorParam());
|
||||
}};
|
||||
Tag toTag(Value value); //validates value, returning null if not necessary to keep it and serialize
|
||||
Value validate(CarpetContext cc, Value value); // makes sure the value is proper
|
||||
@@ -452,8 +477,6 @@ public class ShapeDispatcher
|
||||
}
|
||||
public static abstract class NumericParam implements Param
|
||||
{
|
||||
@Override
|
||||
public Tag toTag(Value value) { return IntTag.of(NumericValue.asNumber(value).getInt()); }
|
||||
@Override
|
||||
public Value validate(CarpetContext cc, Value value)
|
||||
{
|
||||
@@ -471,15 +494,34 @@ public class ShapeDispatcher
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
public static abstract class PositiveFloatParam extends PositiveParam
|
||||
{
|
||||
@Override
|
||||
public Tag toTag(Value value) { return FloatTag.of(NumericValue.asNumber(value).getFloat()); }
|
||||
|
||||
}
|
||||
public static abstract class PositiveIntParam extends PositiveParam
|
||||
{
|
||||
@Override
|
||||
public Tag toTag(Value value) { return IntTag.of(NumericValue.asNumber(value).getInt()); }
|
||||
|
||||
}
|
||||
public static Value decodeInt(Tag tag) { return new NumericValue(((IntTag)tag).getInt()); }
|
||||
public static class DurationParam extends PositiveParam
|
||||
public static Value decodeFloat(Tag tag) { return new NumericValue(((FloatTag)tag).getFloat()); }
|
||||
public static class DurationParam extends PositiveIntParam
|
||||
{
|
||||
@Override
|
||||
public boolean appliesTo(ExpiringShape shape) { return true; }
|
||||
@Override
|
||||
public String identify() { return "duration"; }
|
||||
}
|
||||
public static class WidthParam extends PositiveFloatParam
|
||||
{
|
||||
@Override
|
||||
public boolean appliesTo(ExpiringShape shape) { return shape instanceof Box || shape instanceof Line; }
|
||||
@Override
|
||||
public String identify() { return "width"; }
|
||||
}
|
||||
|
||||
public static abstract class Vec3Param implements Param
|
||||
{
|
||||
@@ -546,12 +588,22 @@ public class ShapeDispatcher
|
||||
}
|
||||
public static class ColorParam extends NumericParam
|
||||
{
|
||||
@Override
|
||||
public Tag toTag(Value value) { return IntTag.of(NumericValue.asNumber(value).getInt()); }
|
||||
@Override
|
||||
public boolean appliesTo(ExpiringShape shape) { return true; }
|
||||
@Override
|
||||
public String identify() { return "color"; }
|
||||
}
|
||||
|
||||
public static class FillColorParam extends ColorParam
|
||||
{
|
||||
@Override
|
||||
public boolean appliesTo(ExpiringShape shape) { return shape instanceof Box; }
|
||||
@Override
|
||||
public String identify() { return "fill"; }
|
||||
}
|
||||
|
||||
public static class FromParam extends Vec3Param
|
||||
{
|
||||
@Override
|
||||
|
||||
@@ -91,12 +91,9 @@ public class ShapesRenderer
|
||||
if (shape == null) return;
|
||||
BiFunction<MinecraftClient, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape >> shapeFactory;
|
||||
shapeFactory = renderedShapes.get(tag.getString("shape"));
|
||||
|
||||
|
||||
|
||||
if (shapeFactory == null)
|
||||
{
|
||||
CarpetSettings.LOG.error("Unrecognized shape: "+tag.getString("shape"));
|
||||
CarpetSettings.LOG.info("Unrecognized shape: "+tag.getString("shape"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -161,7 +158,7 @@ public class ShapesRenderer
|
||||
@Override
|
||||
public void render(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz)
|
||||
{
|
||||
RenderSystem.lineWidth(2.0F);
|
||||
RenderSystem.lineWidth(shape.lineWidth);
|
||||
bufferBuilder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); // 3
|
||||
drawBoxWireGLLines(bufferBuilder,
|
||||
shape.x1 - cx-renderEpsilon, shape.y1 - cy-renderEpsilon, shape.z1 - cz-renderEpsilon,
|
||||
@@ -173,12 +170,13 @@ public class ShapesRenderer
|
||||
@Override
|
||||
public void render2pass(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz)
|
||||
{
|
||||
if (shape.fa == 0.0) return;
|
||||
RenderSystem.lineWidth(1.0F);
|
||||
bufferBuilder.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR); // 3
|
||||
drawBox(bufferBuilder,
|
||||
shape.x1-cx-renderEpsilon, shape.y1-cy-renderEpsilon, shape.z1-cz-renderEpsilon,
|
||||
shape.x2-cx+renderEpsilon, shape.y2-cy+renderEpsilon, shape.z2-cz+renderEpsilon,
|
||||
shape.r, shape.g, shape.b, shape.a/6
|
||||
shape.fr, shape.fg, shape.fb, shape.fa
|
||||
);
|
||||
tessellator.draw();
|
||||
}
|
||||
@@ -193,7 +191,7 @@ public class ShapesRenderer
|
||||
@Override
|
||||
public void render(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz)
|
||||
{
|
||||
RenderSystem.lineWidth(2.0F);
|
||||
RenderSystem.lineWidth(shape.lineWidth);
|
||||
bufferBuilder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); // 3
|
||||
drawLine(bufferBuilder,
|
||||
shape.x1-cx-renderEpsilon, shape.y1-cy-renderEpsilon, shape.z1-cz-renderEpsilon,
|
||||
|
||||
Reference in new issue
Block a user