diff --git a/src/main/java/carpet/network/ClientNetworkHandler.java b/src/main/java/carpet/network/ClientNetworkHandler.java index 7c1336c3..96524117 100644 --- a/src/main/java/carpet/network/ClientNetworkHandler.java +++ b/src/main/java/carpet/network/ClientNetworkHandler.java @@ -11,7 +11,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket; import net.minecraft.util.PacketByteBuf; -import net.minecraft.world.dimension.DimensionType; import java.util.HashMap; import java.util.Map; @@ -38,14 +37,7 @@ public class ClientNetworkHandler put("TickRate", (p, t) -> TickSpeed.tickrate(((AbstractNumberTag)t).getFloat(), false)); put("renderShape", (p, t) -> { if (CarpetClient.shapes != null) - { - CompoundTag boxData = (CompoundTag)t; - CarpetClient.shapes.addShape( - boxData.getString("type"), - DimensionType.byRawId(boxData.getInt("dim")), - boxData - ); - } + CarpetClient.shapes.addShape((CompoundTag)t); }); }}; diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 42bad5a4..d9198cb1 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -2651,94 +2651,46 @@ public class CarpetExpression this.expr.alias("particle_rect", "particle_box"); - this.expr.addLazyFunction("marker_box", -1, (c, t, lv) -> + this.expr.addLazyFunction("draw_shape", -1, (c, t, lv) -> { CarpetContext cc = (CarpetContext)c; - Vector3Argument from = Vector3Argument.findIn(cc, lv, 0); - Vector3Argument to = Vector3Argument.findIn(cc, lv, from.offset); - int duration = 10; - int color = -1; // hwite - ServerPlayerEntity player = null; - - if (lv.size() > to.offset+0 ) + if (lv.size() < 3) throw new InternalExpressionException("'draw_shape' takes at least three parameters, shape name, duration, and its params"); + String shapeType = lv.get(0).evalValue(c).getString(); + Value duration = NumericValue.asNumber(lv.get(1).evalValue(c)); + Map params; + if (lv.size() == 3) { - duration = NumericValue.asNumber(lv.get(to.offset).evalValue(c)).getInt(); - if (duration <= 0) + Value paramValue = lv.get(2).evalValue(c); + if (paramValue instanceof MapValue) { - throw new InternalExpressionException("Particle density should be positive"); + params = new HashMap<>(); + ((MapValue) paramValue).getMap().entrySet().forEach(e -> params.put(e.getKey().getString(),e.getValue())); } - if (lv.size() > to.offset + 1) + else if (paramValue instanceof ListValue) { - color = NumericValue.asNumber(lv.get(to.offset+1).evalValue(c)).getInt(); - - - if (lv.size() > to.offset + 2) - { - Value playerValue = lv.get(to.offset + 2).evalValue(c); - if (playerValue instanceof EntityValue) - { - Entity e = ((EntityValue) playerValue).getEntity(); - if (!(e instanceof ServerPlayerEntity)) - throw new InternalExpressionException("'particle_box' player argument has to be a player"); - player = (ServerPlayerEntity) e; - } - else - { - player = cc.s.getMinecraftServer().getPlayerManager().getPlayer(playerValue.getString()); - } - } + params = ShapeDispatcher.parseParams(((ListValue) paramValue).getItems()); } + else throw new InternalExpressionException("Parameters for 'draw_shape' need to be defined either in a list or a map"); + } + else + { + List paramList = new ArrayList<>(); + for (int i=2; i < lv.size(); i++) paramList.add(lv.get(i).evalValue(c)); + params = ShapeDispatcher.parseParams(paramList); + } + params.putIfAbsent("dim", new StringValue(cc.s.getWorld().getDimension().getType().toString())); + params.putIfAbsent("duration", duration); + + ShapeDispatcher.ExpiringShape shape = ShapeDispatcher.create(cc, shapeType, params); + ServerPlayerEntity player = null; + if (params.containsKey("player")) + { + player = (ServerPlayerEntity) ((EntityValue)params.get("player")).getEntity(); } ShapeDispatcher.sendShape( (player==null)?cc.s.getWorld().getPlayers():Collections.singletonList(player), - cc.s.getWorld().getDimension().getType(), - new ShapeDispatcher.Box(duration, from.vec, to.vec, color) - ); - return LazyValue.TRUE; - }); - - this.expr.addLazyFunction("marker_line", -1, (c, t, lv) -> - { - CarpetContext cc = (CarpetContext)c; - Vector3Argument from = Vector3Argument.findIn(cc, lv, 0); - Vector3Argument to = Vector3Argument.findIn(cc, lv, from.offset); - int duration = 10; - int color = -1; // hwite - ServerPlayerEntity player = null; - - if (lv.size() > to.offset+0 ) - { - duration = NumericValue.asNumber(lv.get(to.offset).evalValue(c)).getInt(); - if (duration <= 0) - { - throw new InternalExpressionException("Particle density should be positive"); - } - if (lv.size() > to.offset + 1) - { - color = NumericValue.asNumber(lv.get(to.offset+1).evalValue(c)).getInt(); - - - if (lv.size() > to.offset + 2) - { - Value playerValue = lv.get(to.offset + 2).evalValue(c); - if (playerValue instanceof EntityValue) - { - Entity e = ((EntityValue) playerValue).getEntity(); - if (!(e instanceof ServerPlayerEntity)) - throw new InternalExpressionException("'particle_box' player argument has to be a player"); - player = (ServerPlayerEntity) e; - } - else - { - player = cc.s.getMinecraftServer().getPlayerManager().getPlayer(playerValue.getString()); - } - } - } - } - ShapeDispatcher.sendShape( - (player==null)?cc.s.getWorld().getPlayers():Collections.singletonList(player), - cc.s.getWorld().getDimension().getType(), - new ShapeDispatcher.Line(duration, from.vec, to.vec, color) + shape, + params ); return LazyValue.TRUE; }); diff --git a/src/main/java/carpet/script/utils/ShapeDispatcher.java b/src/main/java/carpet/script/utils/ShapeDispatcher.java index e898974d..e37e5245 100644 --- a/src/main/java/carpet/script/utils/ShapeDispatcher.java +++ b/src/main/java/carpet/script/utils/ShapeDispatcher.java @@ -1,16 +1,34 @@ package carpet.script.utils; +import carpet.CarpetSettings; import carpet.network.ServerNetworkHandler; +import carpet.script.CarpetContext; import carpet.script.Expression; import carpet.script.exception.InternalExpressionException; +import carpet.script.value.BlockValue; +import carpet.script.value.EntityValue; +import carpet.script.value.ListValue; +import carpet.script.value.NumericValue; +import carpet.script.value.StringValue; +import carpet.script.value.Value; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import com.mojang.brigadier.StringReader; 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.IntTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; import net.minecraft.particle.ParticleEffect; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.registry.Registry; import net.minecraft.world.dimension.DimensionType; import java.util.Collections; @@ -18,7 +36,11 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; import static java.lang.Math.sqrt; @@ -26,7 +48,7 @@ public class ShapeDispatcher { private static final Map particleCache = new HashMap<>(); - public static void sendShape(List players, DimensionType dim, ExpiringShape shape) + public static void sendShape(List players, ExpiringShape shape, Map params) { Consumer alternative = null; CompoundTag tag = null; @@ -34,8 +56,7 @@ public class ShapeDispatcher { if (ServerNetworkHandler.validCarpetPlayers.contains(player)) { - if (tag == null) tag = shape.toTag(); - tag.putInt("dim", dim.getRawId()); + if (tag == null) tag = ExpiringShape.toTag(params); ServerNetworkHandler.sendCustomCommand(player,"renderShape", tag); } else @@ -46,11 +67,6 @@ public class ShapeDispatcher } } - public static void sendBox(ServerPlayerEntity player, int duration, Vec3d from, Vec3d to, int color) - { - - } - public static ParticleEffect getParticleData(String name) { ParticleEffect particle = particleCache.get(name); @@ -68,32 +84,134 @@ public class ShapeDispatcher return particle; } + public static Map parseParams(List items) + { + // parses params from API function + if (items.size()%2 == 1) throw new InternalExpressionException("Shape parameters list needs to be of even size"); + Map param = new HashMap<>(); + int i = 0; + while(i < items.size()) + { + String name = items.get(i).getString(); + Value val = items.get(i+1); + param.put(name, val); + i += 2; + } + return param; + } + + public static ExpiringShape create(CarpetContext cc, String shapeType, Map userParams) + { + userParams.put("shape", new StringValue(shapeType)); + Map validatedParams = new HashMap<>(); + userParams.forEach((key, value) -> + { + Param param = Param.coders.get(key); + if (param==null) throw new InternalExpressionException("Unknown feature for shape: "+key); + validatedParams.put(key, param.validate(cc, value)); + }); + Function,ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeType); + if (factory == null) throw new InternalExpressionException("Unknown shape: "+shapeType); + return factory.apply(validatedParams); + } + + // client + public static ExpiringShape fromTag(CompoundTag tag) + { + Map options = new HashMap<>(); + for (String key : tag.getKeys()) + { + Function decoder = Param.decoders.get(key); + if (decoder==null) + { + CarpetSettings.LOG.error("Unknown parameter for shape: "+key); + return null; + } + Value decodedValue = decoder.apply(tag.get(key)); + options.put(key, decodedValue); + } + Value shapeValue = options.get("shape"); + if (shapeValue == null) + { + CarpetSettings.LOG.error("Shape id missing in "+ String.join(", ", tag.getKeys())); + return null; + } + Function,ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeValue.getString()); + if (factory == null) + { + CarpetSettings.LOG.error("Unknown shape: "+shapeValue.getString()); + return null; + } + try + { + return factory.apply(options); + } + catch (InternalExpressionException exc) + { + CarpetSettings.LOG.error(exc.getMessage()); + } + return null; + } public abstract static class ExpiringShape { + public static final Map,ExpiringShape>> shapeProviders = new HashMap, ExpiringShape>>(){{ + put("line", creator(Line::new)); + put("box", creator(Box::new)); + }}; + private static Function,ExpiringShape> creator(Supplier shapeFactory) + { + return o -> { + ExpiringShape shape = shapeFactory.get(); + shape.fromOptions(o); + return shape; + }; + } + protected float r, g, b, a; protected int color; protected int duration = 0; private int key; - public ExpiringShape(int duration, int color) + + protected ExpiringShape() { } + + public static CompoundTag toTag(Map params) { + CompoundTag tag = new CompoundTag(); + params.forEach((k, v) -> { + Tag valTag = Param.coders.get(k).toTag(v); + if (valTag != null) tag.put(k, valTag); + }); + return tag; + } + + private void fromOptions(Map options) + { + Set optional = optionalParams(); + Set required = requiredParams(); + Set all = Sets.union(optional, required); + if (!all.containsAll(options.keySet())) + throw new InternalExpressionException("Received unexpected parameters for shape: "+Sets.difference(options.keySet(), all)); + if (!options.keySet().containsAll(required)) + throw new InternalExpressionException("Missing required parameters for shape: "+Sets.difference(required, options.keySet())); + options.keySet().forEach(k ->{ + if (!Param.coders.get(k).appliesTo(this)) + throw new InternalExpressionException("Parameter "+k+" doesn't apply for shape "+options.get("shape").getString()); + }); + init(options); + } + + protected void init(Map options) + { + duration = NumericValue.asNumber(options.get("duration")).getInt(); + color = NumericValue.asNumber(options.getOrDefault("color", optional.get("color"))).getInt(); this.r = (float)(color >> 24 & 0xFF) / 255.0F; this.g = (float)(color >> 16 & 0xFF) / 255.0F; this.b = (float)(color >> 8 & 0xFF) / 255.0F; this.a = (float)(color & 0xFF) / 255.0F; - this.color = color; - this.duration = duration; key = 0; } - - public int getExpiry() { return duration; }; - public CompoundTag toTag() - { - CompoundTag tag = new CompoundTag(); - tag.putInt("color", color); - tag.putInt("duration", duration); - return tag; - }; + public int getExpiry() { return duration; } public abstract Consumer alternative(); public int key() { @@ -106,46 +224,40 @@ public class ShapeDispatcher int hash = 17; hash = 31*hash + color; return hash; - }; + } + // 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)); + protected Set requiredParams() {return required;} + // list of params that can be there, with defaults + protected Set optionalParams() {return optional.keySet();} } public static class Box extends ExpiringShape { + private final Set required = ImmutableSet.of("from", "to"); + private final Map optional = ImmutableMap.of(); + @Override + protected Set requiredParams() { return Sets.union(super.requiredParams(), required); } + @Override + protected Set optionalParams() { return Sets.union(super.optionalParams(), optional.keySet()); } + public Box() { } + float x1, y1, z1; float x2, y2, z2; - public Box(int duration, Vec3d from, Vec3d to, int color) - { - super(duration, color); - x1 = (float)from.x; - y1 = (float)from.y; - z1 = (float)from.z; - x2 = (float)to.x; - y2 = (float)to.y; - z2 = (float)to.z; - } - - - public static ExpiringShape fromTag(CompoundTag tag) - { - return new Box(tag.getInt("duration"), - new Vec3d(tag.getFloat("x1"), tag.getFloat("y1"), tag.getFloat("z1")), - new Vec3d(tag.getFloat("x2"), tag.getFloat("y2"), tag.getFloat("z2")), - tag.getInt("color") - ); - } @Override - public CompoundTag toTag() + protected void init(Map options) { - CompoundTag tag = super.toTag(); - tag.putFloat("x1", x1); - tag.putFloat("y1", y1); - tag.putFloat("z1", z1); - tag.putFloat("x2", x2); - tag.putFloat("y2", y2); - tag.putFloat("z2", z2); - tag.putString("type", "debugBox"); - return tag; + super.init(options); + List from = ((ListValue)options.get("from")).getItems(); + x1 = NumericValue.asNumber(from.get(0)).getFloat(); + y1 = NumericValue.asNumber(from.get(1)).getFloat(); + z1 = NumericValue.asNumber(from.get(2)).getFloat(); + List to = ((ListValue)options.get("to")).getItems(); + x2 = NumericValue.asNumber(to.get(0)).getFloat(); + y2 = NumericValue.asNumber(to.get(1)).getFloat(); + z2 = NumericValue.asNumber(to.get(2)).getFloat(); } @Override @@ -197,41 +309,35 @@ public class ShapeDispatcher public static class Line extends ExpiringShape { + private final Set required = ImmutableSet.of("from", "to"); + private final Map optional = ImmutableMap.of(); + @Override + protected Set requiredParams() { return Sets.union(super.requiredParams(), required); } + @Override + protected Set optionalParams() { return Sets.union(super.optionalParams(), optional.keySet()); } + + private Line() + { + super(); + } + float x1, y1, z1; float x2, y2, z2; - public Line(int duration, Vec3d from, Vec3d to, int color) - { - super(duration, color); - x1 = (float)from.x; - y1 = (float)from.y; - z1 = (float)from.z; - x2 = (float)to.x; - y2 = (float)to.y; - z2 = (float)to.z; - } @Override - public CompoundTag toTag() + protected void init(Map options) { - CompoundTag tag = super.toTag(); - tag.putFloat("x1", x1); - tag.putFloat("y1", y1); - tag.putFloat("z1", z1); - tag.putFloat("x2", x2); - tag.putFloat("y2", y2); - tag.putFloat("z2", z2); - tag.putString("type", "debugLine"); - return tag; + super.init(options); + List from = ((ListValue)options.get("from")).getItems(); + x1 = NumericValue.asNumber(from.get(0)).getFloat(); + y1 = NumericValue.asNumber(from.get(1)).getFloat(); + z1 = NumericValue.asNumber(from.get(2)).getFloat(); + List to = ((ListValue)options.get("to")).getItems(); + x2 = NumericValue.asNumber(to.get(0)).getFloat(); + y2 = NumericValue.asNumber(to.get(1)).getFloat(); + z2 = NumericValue.asNumber(to.get(2)).getFloat(); } - public static ExpiringShape fromTag(CompoundTag tag) - { - return new Line(tag.getInt("duration"), - new Vec3d(tag.getFloat("x1"), tag.getFloat("y1"), tag.getFloat("z1")), - new Vec3d(tag.getFloat("x2"), tag.getFloat("y2"), tag.getFloat("z2")), - tag.getInt("color") - ); - } @Override public Consumer alternative() { @@ -261,6 +367,215 @@ public class ShapeDispatcher } } + public interface Param + { + Map> decoders = new HashMap>(){{ + put("shape", StringParam::decode); + put("dim", StringParam::decode); + put("duration", ShapeDispatcher::decodeInt); + put("color", ShapeDispatcher::decodeInt); + put("from", Vec3Param::decode); + put("to", Vec3Param::decode); + + }}; + Map coders = new HashMap(){{ + put("shape", new ShapeParam()); + put("player", new PlayerParam()); + put("dim", new DimensionParam()); + put("duration", new DurationParam()); + put("color", new ColorParam()); + put("from", new FromParam()); + put("to", new ToParam()); + }}; + 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 + boolean appliesTo(ExpiringShape shape); // check if applies to the shape + String identify(); + } + public static class PlayerParam implements Param + { + @Override // doesn't need to be converted + public Tag toTag(Value value) { return null; } + + @Override + public Value validate(CarpetContext cc, Value value) + { + ServerPlayerEntity player = EntityValue.getPlayerByValue(cc.s.getMinecraftServer(), value); + if (player == null) + throw new InternalExpressionException("'player' parameter needs to represent an existing player"); + return new EntityValue(player); + } + + @Override + public boolean appliesTo(ExpiringShape shape) { return true; } + @Override + public String identify() { return "player"; } + + public static Value decode(Tag tag) { throw new RuntimeException("player tag should not be passed to the client"); } + } + public abstract static class StringParam implements Param + { + @Override + public Tag toTag(Value value) { return StringTag.of(value.getString()); } + @Override + public Value validate(CarpetContext cc, Value value) { return value; } + public static Value decode(Tag tag) { return new StringValue(tag.asString()); } + } + + public static class DimensionParam extends StringParam + { + @Override + public Value validate(CarpetContext cc, Value value) + { + String dimStr = value.getString(); + Optional dimOp = Registry.DIMENSION_TYPE.getOrEmpty(new Identifier(dimStr)); + if (!dimOp.isPresent()) throw new InternalExpressionException("Unknown dimension "+dimStr); + return value; + } + @Override + public boolean appliesTo(ExpiringShape shape) { return true; } + @Override + public String identify() { return "dim"; } + } + public static class ShapeParam extends StringParam + { + @Override + public Value validate(CarpetContext cc, Value value) + { + String shape = value.getString(); + if (!ExpiringShape.shapeProviders.containsKey(shape)) + throw new InternalExpressionException("Unknown shape: "+shape); + return value; + } + @Override + public boolean appliesTo(ExpiringShape shape) { return true; } + @Override + public String identify() { return "shape"; } + } + 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) + { + if (!(value instanceof NumericValue)) + throw new InternalExpressionException("'" + identify() + "' needs to be a number"); + return value; + } + } + public static abstract class PositiveParam extends NumericParam + { + @Override public Value validate(CarpetContext cc, Value value) + { + Value ret = super.validate(cc, value); + if (((NumericValue)ret).getDouble()<=0) throw new InternalExpressionException("'"+identify()+"' should be positive"); + return ret; + } + } + + public static Value decodeInt(Tag tag) { return new NumericValue(((IntTag)tag).getInt()); } + public static class DurationParam extends PositiveParam + { + @Override + public boolean appliesTo(ExpiringShape shape) { return true; } + @Override + public String identify() { return "duration"; } + } + + public static abstract class Vec3Param implements Param + { + + public abstract boolean roundsUpForBlocks(); + public abstract String identify(); + + @Override + public Value validate(CarpetContext cc, Value value) + { + if (value instanceof BlockValue) + { + BlockPos pos = ((BlockValue) value).getPos(); + int offset = roundsUpForBlocks()?1:0; + return ListValue.of( + new NumericValue(pos.getX()+offset), + new NumericValue(pos.getY()+offset), + new NumericValue(pos.getZ()+offset) + ); + } + if (value instanceof ListValue) + { + List values = ((ListValue) value).getItems(); + if (values.size()!=3) throw new InternalExpressionException("'"+identify()+"' requires 3 numerical values"); + for (Value component : values) + { + if (!(component instanceof NumericValue)) + throw new InternalExpressionException("'"+identify()+"' requires 3 numerical values"); + } + return value; + } + if (value instanceof EntityValue) + { + Entity e = ((EntityValue) value).getEntity(); + return ListValue.of( + new NumericValue(e.getX()), + new NumericValue(e.getY()), + new NumericValue(e.getZ()) + ); + } + CarpetSettings.LOG.error("Value: "+value.getString()); + throw new InternalExpressionException("'"+identify()+"' requires a triple, block or entity to indicate position"); + } + + public static Value decode(Tag tag) + { + CompoundTag ctag = (CompoundTag)tag; + return ListValue.of( + new NumericValue(ctag.getFloat("x")), + new NumericValue(ctag.getFloat("y")), + new NumericValue(ctag.getFloat("z")) + ); + } + @Override + public Tag toTag(Value value) + { + List lv = ((ListValue)value).getItems(); + CompoundTag tag = new CompoundTag(); + tag.putFloat("x", NumericValue.asNumber(lv.get(0)).getFloat()); + tag.putFloat("y", NumericValue.asNumber(lv.get(1)).getFloat()); + tag.putFloat("z", NumericValue.asNumber(lv.get(2)).getFloat()); + return tag; + } + } + public static class ColorParam extends NumericParam + { + @Override + public boolean appliesTo(ExpiringShape shape) { return true; } + @Override + public String identify() { return "color"; } + } + + public static class FromParam extends Vec3Param + { + @Override + public boolean appliesTo(ExpiringShape shape) { return (shape instanceof Line) || (shape instanceof Box); } + @Override + public boolean roundsUpForBlocks() { return false; } + @Override + public String identify() { return "from"; } + } + + public static class ToParam extends Vec3Param + { + @Override + public boolean appliesTo(ExpiringShape shape) { return (shape instanceof Line) || (shape instanceof Box); } + @Override + public boolean roundsUpForBlocks() { return true; } + @Override + public String identify() { return "to"; } + } + + + private static boolean isStraight(Vec3d from, Vec3d to, double density) { if ( (from.x == to.x && from.y == to.y) || (from.x == to.x && from.z == to.z) || (from.y == to.y && from.z == to.z)) diff --git a/src/main/java/carpet/script/utils/ShapesRenderer.java b/src/main/java/carpet/script/utils/ShapesRenderer.java index d6db7387..4bb50aa7 100644 --- a/src/main/java/carpet/script/utils/ShapesRenderer.java +++ b/src/main/java/carpet/script/utils/ShapesRenderer.java @@ -11,6 +11,8 @@ import net.minecraft.client.render.VertexFormats; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; import net.minecraft.world.IWorld; import net.minecraft.world.dimension.DimensionType; import org.lwjgl.opengl.GL11; @@ -24,11 +26,11 @@ public class ShapesRenderer private final Map>> shapes; private MinecraftClient client; - private Map>> renderedShapes - = new HashMap>>() + private Map>> renderedShapes + = new HashMap>>() {{ - put("debugBox", RenderedBox::new); - put("debugLine", RenderedLine::new); + put("line", RenderedLine::new); + put("box", RenderedBox::new); }}; public ShapesRenderer(MinecraftClient minecraftClient) @@ -82,17 +84,24 @@ public class ShapesRenderer RenderSystem.shadeModel(7424); } - public void addShape(String type, DimensionType dim, CompoundTag tag) + public void addShape(CompoundTag tag) { - BiFunction> shapeFactory; - shapeFactory = renderedShapes.get(type); + //CarpetSettings.LOG.error("Received tag: "+tag.asString()); + ShapeDispatcher.ExpiringShape shape = ShapeDispatcher.fromTag(tag); + if (shape == null) return; + BiFunction> shapeFactory; + shapeFactory = renderedShapes.get(tag.getString("shape")); + + + if (shapeFactory == null) { - CarpetSettings.LOG.error("Unrecognized shape: "+type); + CarpetSettings.LOG.error("Unrecognized shape: "+tag.getString("shape")); } else { - RenderedShape rshape = shapeFactory.apply(client, tag); + RenderedShape rshape = shapeFactory.apply(client, shape); + DimensionType dim = Registry.DIMENSION_TYPE.get(new Identifier(tag.getString("dim"))); int key = rshape.key(); synchronized (shapes) { @@ -144,9 +153,9 @@ public class ShapesRenderer public static class RenderedBox extends RenderedShape { - public RenderedBox(MinecraftClient client, CompoundTag boxData) + private RenderedBox(MinecraftClient client, ShapeDispatcher.ExpiringShape shape) { - super(client, (ShapeDispatcher.Box)ShapeDispatcher.Box.fromTag(boxData)); + super(client, (ShapeDispatcher.Box)shape); } @Override @@ -177,9 +186,9 @@ public class ShapesRenderer public static class RenderedLine extends RenderedShape { - public RenderedLine(MinecraftClient client, CompoundTag boxData) + public RenderedLine(MinecraftClient client, ShapeDispatcher.ExpiringShape shape) { - super(client, (ShapeDispatcher.Line)ShapeDispatcher.Line.fromTag(boxData)); + super(client, (ShapeDispatcher.Line)shape); } @Override public void render(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz) diff --git a/src/main/java/carpet/script/value/NumericValue.java b/src/main/java/carpet/script/value/NumericValue.java index 087d0f2e..fa6a58c9 100644 --- a/src/main/java/carpet/script/value/NumericValue.java +++ b/src/main/java/carpet/script/value/NumericValue.java @@ -56,6 +56,10 @@ public class NumericValue extends Value { return value; } + public float getFloat() + { + return value.floatValue(); + } public static long floor(double double_1) { long int_1 = (long)double_1; diff --git a/src/main/resources/assets/carpet/scripts/overlay.sc b/src/main/resources/assets/carpet/scripts/overlay.sc index 95d4fca5..3adebc96 100644 --- a/src/main/resources/assets/carpet/scripts/overlay.sc +++ b/src/main/resources/assets/carpet/scripts/overlay.sc @@ -95,7 +95,7 @@ __structure_renderer(player_name) -> total_size = _euclidean(from, to); density = max(10, total_size/10); //particle_box('dust 0 1 1 2', from, to+1, density); - marker_box(from, to+1, 15, 0x00FFFFFF ); + draw_shape('box', 15, 'from', from, 'to', to+1, 'color', 0x00FFFFFF); structure_pieces = slice(sort_key(structure_pieces, _euclidean_sq((_:2+_:3)/2,ppos)), 0, config:'max_pieces'); for (structure_pieces, l(piece, direction, from, to) = _; //factor = 1- _i / config:'max_pieces' / 2; @@ -107,7 +107,7 @@ __structure_renderer(player_name) -> b = 255; a = 255; color = a+256*(b+256*(g+256*r)); - marker_box(from, to+1, 15, color); + draw_shape('box', 15, 'from', from, 'to', to+1, 'color', color); ) ) ); @@ -133,20 +133,20 @@ __chunk_renderer(player_name) -> top_11 = ref_pos + l(16, top('terrain', ref_pos+l(15,0,15))+10, 16); top_10 = ref_pos + l(16, top('terrain', ref_pos+l(15, 0, 0))+10, 0); top_01 = ref_pos + l(0, top('terrain', ref_pos+l(0, 0, 15))+10, 16); - part = 'dust 0.2 0.8 0.2 2'; - density = 2+player_distance/2; r = 30; g = 220; b = 30; a = max(0, 255-player_distance); color = a+256*(b+256*(g+256*r)); - marker_line(top_00, top_10, 15, color); - marker_line(top_10, top_11, 15, color); - marker_line(top_11, top_01, 15, color); - marker_line(top_01, top_00, 15, color); - marker_line(top_00, top_11, 15, color); - marker_line(top_01, top_10, 15, color); + draw_shape('box', 15, 'from', top_00, 'to', top_10, 'color', color); + draw_shape('box', 15, 'from', top_10, 'to', top_11, 'color', color); + draw_shape('box', 15, 'from', top_11, 'to', top_01, 'color', color); + draw_shape('box', 15, 'from', top_01, 'to', top_00, 'color', color); + draw_shape('box', 15, 'from', top_00, 'to', top_11, 'color', color); + draw_shape('box', 15, 'from', top_01, 'to', top_10, 'color', color); + //part = 'dust 0.2 0.8 0.2 2'; + //density = 2+player_distance/2; //particle_line(part, top_00, top_10, density); //particle_line(part, top_10, top_11, density); //particle_line(part, top_11, top_01, density);