Merge branch 'master' into 1.16
# Conflicts: # src/main/java/carpet/script/utils/ShapeDispatcher.java
This commit is contained in:
commit
8fe3508fdd
5 files changed
+271
-82
No files matched your search
@@ -111,7 +111,7 @@ public class ShapeDispatcher
|
||||
userParams.keySet().forEach(key -> {
|
||||
Param param = Param.coders.get(key);
|
||||
if (param==null) throw new InternalExpressionException("Unknown feature for shape: "+key);
|
||||
userParams.put(key, param.validate(cc, userParams.get(key)));
|
||||
userParams.put(key, param.validate(userParams, cc, userParams.get(key)));
|
||||
});
|
||||
Function<Map<String, Value>,ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeType);
|
||||
if (factory == null) throw new InternalExpressionException("Unknown shape: "+shapeType);
|
||||
@@ -176,6 +176,9 @@ public class ShapeDispatcher
|
||||
protected int color;
|
||||
protected int duration = 0;
|
||||
private int key;
|
||||
protected int followEntity;
|
||||
protected DimensionType entityDimension;
|
||||
|
||||
|
||||
protected ExpiringShape() { }
|
||||
|
||||
@@ -214,8 +217,19 @@ public class ShapeDispatcher
|
||||
this.b = (float)(color >> 8 & 0xFF) / 255.0F;
|
||||
this.a = (float)(color & 0xFF) / 255.0F;
|
||||
key = 0;
|
||||
followEntity = -1;
|
||||
entityDimension = null;
|
||||
if (options.containsKey("follow"))
|
||||
{
|
||||
followEntity = NumericValue.asNumber(options.getOrDefault("follow", optional.get("follow"))).getInt();
|
||||
entityDimension = Registry.DIMENSION_TYPE.get(new Identifier(options.get("dim").getString()));
|
||||
}
|
||||
}
|
||||
public int getExpiry() { return duration; }
|
||||
public Vec3d toAbsolute(Entity e, float x, float y, float z)
|
||||
{
|
||||
return e.getPos().add(x,y,z);
|
||||
}
|
||||
public abstract Consumer<ServerPlayerEntity> alternative();
|
||||
public int key()
|
||||
{
|
||||
@@ -227,13 +241,15 @@ public class ShapeDispatcher
|
||||
{
|
||||
int hash = 17;
|
||||
hash = 31*hash + color;
|
||||
hash = 31*hash + followEntity;
|
||||
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),
|
||||
"player", Value.NULL
|
||||
"player", Value.NULL,
|
||||
"follow", new NumericValue(-1)
|
||||
);
|
||||
protected Set<String> requiredParams() {return required;}
|
||||
// list of params that can be there, with defaults
|
||||
@@ -283,13 +299,26 @@ public class ShapeDispatcher
|
||||
@Override
|
||||
public Consumer<ServerPlayerEntity> alternative()
|
||||
{
|
||||
|
||||
String particleName = String.format(Locale.ROOT , "dust %.1f %.1f %.1f 1.0", r, g, b);
|
||||
ParticleEffect particle = getParticleData(particleName);
|
||||
double dx = x1-x2;
|
||||
double dy = y1-y2;
|
||||
double dz = z1-z2;
|
||||
double density = Math.max(2.0, Math.sqrt(dx*dx+dy*dy+dz*dz) /50) / (a+0.1);
|
||||
return p -> mesh(Collections.singletonList(p), particle, density, x1, y1, z1, x2, y2, z2);
|
||||
return p ->
|
||||
{
|
||||
if (followEntity == -1)
|
||||
{
|
||||
mesh(Collections.singletonList(p), particle, density, x1, y1, z1, x2, y2, z2);
|
||||
return;
|
||||
}
|
||||
Entity e = p.getServer().getWorld(entityDimension).getEntityById(followEntity);
|
||||
if (e == null) return;
|
||||
Vec3d rel1 = toAbsolute(e, x1, y1, z1);
|
||||
Vec3d rel2 = toAbsolute(e, x2, y2, z2);
|
||||
mesh(Collections.singletonList(p), particle, density, rel1.x, rel1.y, rel1.z, rel2.x, rel2.y, rel2.z);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -373,7 +402,20 @@ public class ShapeDispatcher
|
||||
double dy = y1-y2;
|
||||
double dz = z1-z2;
|
||||
double density = Math.max(2.0, Math.sqrt(dx*dx+dy*dy+dz*dz) /50) / (a+0.1);
|
||||
return p -> drawParticleLine(Collections.singletonList(p), particle, pos1, pos2, density);
|
||||
return p ->
|
||||
{
|
||||
if (followEntity == -1)
|
||||
{
|
||||
drawParticleLine(Collections.singletonList(p), particle, pos1, pos2, density);
|
||||
return;
|
||||
}
|
||||
|
||||
Entity e = p.getServer().getWorld(entityDimension).getEntityById(followEntity);
|
||||
if (e == null) return;
|
||||
Vec3d rel1 = toAbsolute(e, x1, y1, z1);
|
||||
Vec3d rel2 = toAbsolute(e, x2, y2, z2);
|
||||
drawParticleLine(Collections.singletonList(p), particle, rel1, rel2, density);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -395,7 +437,11 @@ public class ShapeDispatcher
|
||||
public static class Sphere extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("center", "radius");
|
||||
private final Map<String, Value> optional = ImmutableMap.of("width", new NumericValue(2.0), "level", Value.ZERO);
|
||||
private final Map<String, Value> optional = ImmutableMap.of(
|
||||
"width", new NumericValue(2.0),
|
||||
"level", Value.ZERO,
|
||||
"fill", new NumericValue(0xffffff00)
|
||||
);
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
@@ -412,6 +458,9 @@ public class ShapeDispatcher
|
||||
int subdivisions;
|
||||
float lineWidth;
|
||||
|
||||
protected float fr, fg, fb, fa;
|
||||
protected int fillColor;
|
||||
|
||||
@Override
|
||||
protected void init(Map<String, Value> options)
|
||||
{
|
||||
@@ -428,6 +477,11 @@ public class ShapeDispatcher
|
||||
subdivisions = Math.max(10, (int)(10*Math.sqrt(radius)));
|
||||
}
|
||||
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
|
||||
@@ -439,15 +493,32 @@ public class ShapeDispatcher
|
||||
int partno = Math.min(1000,20*subdivisions);
|
||||
Random rand = p.world.getRandom();
|
||||
ServerWorld world = p.getServerWorld();
|
||||
|
||||
float ccx, ccy, ccz;
|
||||
if (followEntity == -1)
|
||||
{
|
||||
ccx = cx; ccy = cy; ccz = cz;
|
||||
}
|
||||
else
|
||||
{
|
||||
Entity e = p.getServer().getWorld(entityDimension).getEntityById(followEntity);
|
||||
if (e == null) return;
|
||||
Vec3d rel1 = toAbsolute(e, cx, cy, cz);
|
||||
ccx = (float)rel1.x; ccy = (float)rel1.y; ccz = (float)rel1.z;
|
||||
}
|
||||
|
||||
for (int i=0; i<partno; i++)
|
||||
{
|
||||
float theta = 360.0f*rand.nextFloat()*pihalf;
|
||||
float phi = 180f*rand.nextFloat()*pihalf;
|
||||
float x = radius * MathHelper.sin(phi) * MathHelper.cos(theta);
|
||||
float y = radius * MathHelper.sin(phi) * MathHelper.sin(theta);
|
||||
float z = radius * MathHelper.cos(phi);
|
||||
//float theta = 360.0f*rand.nextFloat()*pihalf;
|
||||
//float phi = 180f*rand.nextFloat()*pihalf;
|
||||
float theta = (float)Math.asin(rand.nextFloat()*2.0-1.0);
|
||||
float phi = (float)(2*Math.PI*rand.nextFloat());
|
||||
|
||||
float x = radius * MathHelper.cos(theta) * MathHelper.cos(phi);
|
||||
float y = radius * MathHelper.cos(theta) * MathHelper.sin(phi);
|
||||
float z = radius * MathHelper.sin(theta);
|
||||
world.spawnParticles(p, particle, true,
|
||||
x+cx, y+cy, z+cz, 1,
|
||||
x+ccx, y+ccy, z+ccz, 1,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
};}
|
||||
@@ -463,7 +534,7 @@ public class ShapeDispatcher
|
||||
hash = 31*hash + Float.hashCode(radius);
|
||||
hash = 31*hash + level;
|
||||
hash = 31*hash + Float.hashCode(lineWidth);
|
||||
|
||||
if (fa != 0.0) hash = 31*hash + fillColor;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@@ -476,6 +547,8 @@ public class ShapeDispatcher
|
||||
put("dim", StringParam::decode);
|
||||
put("duration", ShapeDispatcher::decodeInt);
|
||||
put("color", ShapeDispatcher::decodeInt);
|
||||
put("follow", EntityParam::decode);
|
||||
|
||||
put("from", Vec3Param::decode);
|
||||
put("to", Vec3Param::decode);
|
||||
put("width", ShapeDispatcher::decodeFloat);
|
||||
@@ -490,6 +563,8 @@ public class ShapeDispatcher
|
||||
put("dim", new DimensionParam());
|
||||
put("duration", new DurationParam());
|
||||
put("color", new ColorParam());
|
||||
put("follow", new FollowParam());
|
||||
|
||||
put("from", new FromParam());
|
||||
put("to", new ToParam());
|
||||
put("width", new WidthParam());
|
||||
@@ -499,7 +574,7 @@ public class ShapeDispatcher
|
||||
put("level", new LevelParam());
|
||||
}};
|
||||
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
|
||||
Value validate(Map<String, Value> options, CarpetContext cc, Value value); // makes sure the value is proper
|
||||
boolean appliesTo(ExpiringShape shape); // check if applies to the shape
|
||||
String identify();
|
||||
}
|
||||
@@ -509,7 +584,7 @@ public class ShapeDispatcher
|
||||
public Tag toTag(Value value) { return null; }
|
||||
|
||||
@Override
|
||||
public Value validate(CarpetContext cc, Value value)
|
||||
public Value validate(Map<String, Value> options, CarpetContext cc, Value value)
|
||||
{
|
||||
ServerPlayerEntity player = EntityValue.getPlayerByValue(cc.s.getMinecraftServer(), value);
|
||||
if (player == null)
|
||||
@@ -528,13 +603,19 @@ public class ShapeDispatcher
|
||||
{
|
||||
@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(Map<String, Value> options, 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
|
||||
@@ -543,7 +624,7 @@ public class ShapeDispatcher
|
||||
public static class ShapeParam extends StringParam
|
||||
{
|
||||
@Override
|
||||
public Value validate(CarpetContext cc, Value value)
|
||||
public Value validate(Map<String, Value> options, CarpetContext cc, Value value)
|
||||
{
|
||||
String shape = value.getString();
|
||||
if (!ExpiringShape.shapeProviders.containsKey(shape))
|
||||
@@ -558,7 +639,7 @@ public class ShapeDispatcher
|
||||
public static abstract class NumericParam implements Param
|
||||
{
|
||||
@Override
|
||||
public Value validate(CarpetContext cc, Value value)
|
||||
public Value validate(Map<String, Value> options, CarpetContext cc, Value value)
|
||||
{
|
||||
if (!(value instanceof NumericValue))
|
||||
throw new InternalExpressionException("'" + identify() + "' needs to be a number");
|
||||
@@ -567,9 +648,9 @@ public class ShapeDispatcher
|
||||
}
|
||||
public static abstract class PositiveParam extends NumericParam
|
||||
{
|
||||
@Override public Value validate(CarpetContext cc, Value value)
|
||||
@Override public Value validate(Map<String, Value> options, CarpetContext cc, Value value)
|
||||
{
|
||||
Value ret = super.validate(cc, value);
|
||||
Value ret = super.validate(options, cc, value);
|
||||
if (((NumericValue)ret).getDouble()<=0) throw new InternalExpressionException("'"+identify()+"' should be positive");
|
||||
return ret;
|
||||
}
|
||||
@@ -610,10 +691,12 @@ public class ShapeDispatcher
|
||||
public abstract String identify();
|
||||
|
||||
@Override
|
||||
public Value validate(CarpetContext cc, Value value)
|
||||
public Value validate(Map<String, Value> options, CarpetContext cc, Value value)
|
||||
{
|
||||
if (value instanceof BlockValue)
|
||||
{
|
||||
if (options.containsKey("follow"))
|
||||
throw new InternalExpressionException(identify()+" parameter cannot use blocks as positions for relative positioning due to 'follow' attribute being present");
|
||||
BlockPos pos = ((BlockValue) value).getPos();
|
||||
int offset = roundsUpForBlocks()?1:0;
|
||||
return ListValue.of(
|
||||
@@ -635,6 +718,8 @@ public class ShapeDispatcher
|
||||
}
|
||||
if (value instanceof EntityValue)
|
||||
{
|
||||
if (options.containsKey("follow"))
|
||||
throw new InternalExpressionException(identify()+" parameter cannot use entity as positions for relative positioning due to 'follow' attribute being present");
|
||||
Entity e = ((EntityValue) value).getEntity();
|
||||
return ListValue.of(
|
||||
new NumericValue(e.getX()),
|
||||
@@ -679,7 +764,7 @@ public class ShapeDispatcher
|
||||
public static class FillColorParam extends ColorParam
|
||||
{
|
||||
@Override
|
||||
public boolean appliesTo(ExpiringShape shape) { return shape instanceof Box; }
|
||||
public boolean appliesTo(ExpiringShape shape) { return shape instanceof Box || shape instanceof Sphere; }
|
||||
@Override
|
||||
public String identify() { return "fill"; }
|
||||
}
|
||||
@@ -687,7 +772,7 @@ public class ShapeDispatcher
|
||||
public static class FromParam extends Vec3Param
|
||||
{
|
||||
@Override
|
||||
public boolean appliesTo(ExpiringShape shape) { return (shape instanceof Line) || (shape instanceof Box); }
|
||||
public boolean appliesTo(ExpiringShape shape) { return shape instanceof Line || shape instanceof Box; }
|
||||
@Override
|
||||
public boolean roundsUpForBlocks() { return false; }
|
||||
@Override
|
||||
@@ -727,6 +812,35 @@ public class ShapeDispatcher
|
||||
@Override
|
||||
public String identify() { return "level"; }
|
||||
}
|
||||
public abstract static class EntityParam implements Param
|
||||
{
|
||||
|
||||
@Override
|
||||
public Tag toTag(Value value)
|
||||
{
|
||||
return IntTag.of(NumericValue.asNumber(value).getInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value validate(Map<String, Value> options, CarpetContext cc, Value value)
|
||||
{
|
||||
if (value instanceof EntityValue) return new NumericValue(((EntityValue) value).getEntity().getEntityId());
|
||||
ServerPlayerEntity player = EntityValue.getPlayerByValue(cc.s.getMinecraftServer(), value);
|
||||
if (player == null)
|
||||
throw new InternalExpressionException(identify()+" parameter needs to represent an entity or player");
|
||||
return new NumericValue(player.getEntityId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(ExpiringShape shape) { return true; }
|
||||
|
||||
public static Value decode(Tag tag) { return new NumericValue(((IntTag)tag).getInt()); }
|
||||
}
|
||||
public static class FollowParam extends EntityParam
|
||||
{
|
||||
@Override
|
||||
public String identify() { return "follow"; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user