added params and changed syntax for draw_shape
This commit is contained in:
1 parent
6e4b5ebaf6
commit
a86c127c72
6 files changed
+461
-189
No files matched your search
@@ -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<String, Value> 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<Value> 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;
|
||||
});
|
||||
|
||||
@@ -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<String, ParticleEffect> particleCache = new HashMap<>();
|
||||
|
||||
public static void sendShape(List<ServerPlayerEntity> players, DimensionType dim, ExpiringShape shape)
|
||||
public static void sendShape(List<ServerPlayerEntity> players, ExpiringShape shape, Map<String, Value> params)
|
||||
{
|
||||
Consumer<ServerPlayerEntity> 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<String, Value> parseParams(List<Value> items)
|
||||
{
|
||||
// parses params from API function
|
||||
if (items.size()%2 == 1) throw new InternalExpressionException("Shape parameters list needs to be of even size");
|
||||
Map<String, Value> 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<String, Value> userParams)
|
||||
{
|
||||
userParams.put("shape", new StringValue(shapeType));
|
||||
Map<String, Value> 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<Map<String, Value>,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<String, Value> options = new HashMap<>();
|
||||
for (String key : tag.getKeys())
|
||||
{
|
||||
Function<Tag, Value> 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<Map<String, Value>,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<String, Function<Map<String, Value>,ExpiringShape>> shapeProviders = new HashMap<String, Function<Map<String, Value>, ExpiringShape>>(){{
|
||||
put("line", creator(Line::new));
|
||||
put("box", creator(Box::new));
|
||||
}};
|
||||
private static Function<Map<String, Value>,ExpiringShape> creator(Supplier<ExpiringShape> 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<String, Value> 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<String, Value> options)
|
||||
{
|
||||
Set<String> optional = optionalParams();
|
||||
Set<String> required = requiredParams();
|
||||
Set<String> 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<String, Value> 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<ServerPlayerEntity> 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<String> required = ImmutableSet.of("duration", "shape", "dim");
|
||||
private final Map<String, Value> optional = ImmutableMap.of("color", new NumericValue(-1));
|
||||
protected Set<String> requiredParams() {return required;}
|
||||
// list of params that can be there, with defaults
|
||||
protected Set<String> optionalParams() {return optional.keySet();}
|
||||
}
|
||||
|
||||
public static class Box extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("from", "to");
|
||||
private final Map<String, Value> optional = ImmutableMap.of();
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
protected Set<String> 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<String, Value> 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<Value> 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<Value> 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<String> required = ImmutableSet.of("from", "to");
|
||||
private final Map<String, Value> optional = ImmutableMap.of();
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
protected Set<String> 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<String, Value> 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<Value> 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<Value> 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<ServerPlayerEntity> alternative()
|
||||
{
|
||||
@@ -261,6 +367,215 @@ public class ShapeDispatcher
|
||||
}
|
||||
}
|
||||
|
||||
public interface Param
|
||||
{
|
||||
Map<String, Function<Tag, Value>> decoders = new HashMap<String, Function<Tag, Value>>(){{
|
||||
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<String, Param> coders = new HashMap<String, Param>(){{
|
||||
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<DimensionType> 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<Value> 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<Value> 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))
|
||||
|
||||
@@ -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<DimensionType, Int2ObjectOpenHashMap<RenderedShape<? extends ShapeDispatcher.ExpiringShape>>> shapes;
|
||||
private MinecraftClient client;
|
||||
|
||||
private Map<String, BiFunction<MinecraftClient, CompoundTag, RenderedShape<? extends ShapeDispatcher.ExpiringShape >>> renderedShapes
|
||||
= new HashMap<String, BiFunction<MinecraftClient, CompoundTag, RenderedShape<? extends ShapeDispatcher.ExpiringShape>>>()
|
||||
private Map<String, BiFunction<MinecraftClient, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape >>> renderedShapes
|
||||
= new HashMap<String, BiFunction<MinecraftClient, ShapeDispatcher.ExpiringShape, RenderedShape<? extends ShapeDispatcher.ExpiringShape>>>()
|
||||
{{
|
||||
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<MinecraftClient, CompoundTag, RenderedShape<? extends ShapeDispatcher.ExpiringShape >> shapeFactory;
|
||||
shapeFactory = renderedShapes.get(type);
|
||||
//CarpetSettings.LOG.error("Received tag: "+tag.asString());
|
||||
ShapeDispatcher.ExpiringShape shape = ShapeDispatcher.fromTag(tag);
|
||||
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: "+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<ShapeDispatcher.Box>
|
||||
{
|
||||
|
||||
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<ShapeDispatcher.Line>
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user