Merge branch 'master' into 1.16

This commit is contained in:
gnembon committed 2020-06-03 03:47:55 -03:00
commit bf2d412a66
19 files changed
+690 -78

No files matched your search

+1 -1
View File
@@ -62,7 +62,7 @@ public class CarpetSettings
@Rule(
desc = "sets the language for carpet",
category = FEATURE,
options = {"none", "zh_cn"},
options = {"none", "zh_cn", "zh_tw"},
strict = false,
validate = LanguageValidator.class
)
@@ -9,6 +9,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static carpet.script.CarpetEventServer.Event.PLAYER_CONNECTS;
@Mixin(PlayerManager.class)
public class PlayerManager_coreMixin
{
@@ -16,5 +18,6 @@ public class PlayerManager_coreMixin
private void onPlayerConnected(ClientConnection connection, ServerPlayerEntity player, CallbackInfo ci)
{
CarpetServer.onPlayerLoggedIn(player);
PLAYER_CONNECTS.onPlayerEvent(player);
}
}
@@ -13,6 +13,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static carpet.script.CarpetEventServer.Event.PLAYER_DISCONNECTS;
@Mixin(ServerPlayNetworkHandler.class)
public class ServerPlayNetworkHandler_coreMixin {
@Shadow
@@ -21,5 +23,6 @@ public class ServerPlayNetworkHandler_coreMixin {
@Inject(method = "onDisconnected", at = @At("HEAD"))
private void onPlayerDisconnect(Text reason, CallbackInfo ci) {
CarpetServer.onPlayerLoggedOut(this.player);
if (PLAYER_DISCONNECTS.isNeeded()) PLAYER_DISCONNECTS.onPlayerMessage(player, reason.asString());
}
}
@@ -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);
});
@@ -128,7 +128,13 @@ public class CarpetEventServer
List<LazyValue> argv = argumentSupplier.get(); // empty for onTickDone
ServerCommandSource source = cmdSourceSupplier.get();
assert argv.size() == reqArgs;
callList.removeIf(call -> !CarpetServer.scriptServer.runas(source, call.host, call.function, argv)); // this actually does the calls
List<Callback> fails = new ArrayList<>();
for (Callback call: callList)
{
if (!CarpetServer.scriptServer.runas(source, call.host, call.function, argv))
fails.add(call);
}
for (Callback call : fails) callList.remove(call);
}
}
public boolean addEventCall(ServerCommandSource source, String hostName, String funName, Function<ScriptHost, Boolean> verifier)
@@ -549,6 +555,23 @@ public class CarpetEventServer
), player::getCommandSource);
}
},
PLAYER_CONNECTS("player_connects", 1, false) {
@Override
public void onPlayerEvent(ServerPlayerEntity player)
{
handler.call( () -> Collections.singletonList(((c, t) -> new EntityValue(player))), player::getCommandSource);
}
},
PLAYER_DISCONNECTS("player_disconnects", 2, false) {
@Override
public void onPlayerMessage(ServerPlayerEntity player, String message)
{
handler.call( () -> Arrays.asList(
((c, t) -> new EntityValue(player)),
((c, t) -> new StringValue(message))
), player::getCommandSource);
}
},
STATISTICS("statistic", 4, false)
{
private <T> Identifier getStatId(Stat<T> stat)
@@ -613,6 +636,7 @@ public class CarpetEventServer
public void onTick() { }
public void onChunkGenerated(ServerWorld world, Chunk chunk) { }
public void onPlayerEvent(ServerPlayerEntity player) { }
public void onPlayerMessage(ServerPlayerEntity player, String message) { }
public void onPlayerStatistic(ServerPlayerEntity player, Stat<?> stat, int amount) { }
public void onMountControls(ServerPlayerEntity player, float strafeSpeed, float forwardSpeed, boolean jumping, boolean sneaking) { }
public void onItemAction(ServerPlayerEntity player, Hand enumhand, ItemStack itemstack) { }
@@ -2704,7 +2704,7 @@ public class CarpetExpression
ServerPlayerEntity player = null;
if (params.containsKey("player"))
{
player = (ServerPlayerEntity) ((EntityValue)params.get("player")).getEntity();
player = (ServerPlayerEntity)((EntityValue)params.get("player")).getEntity();
}
ShapeDispatcher.sendShape(
(player==null)?cc.s.getWorld().getPlayers():Collections.singletonList(player),
@@ -2987,6 +2987,12 @@ public class CarpetExpression
return (cc, tt) -> retval;
});
this.expr.addLazyFunction("view_distance", 0, (c, t, lv) -> {
ServerCommandSource s = ((CarpetContext)c).s;
Value retval = new NumericValue(s.getMinecraftServer().getPlayerManager().getViewDistance());
return (cc, tt) -> retval;
});
this.expr.addLazyFunction("in_dimension", 2, (c, t, lv) -> {
ServerCommandSource outerSource = ((CarpetContext)c).s;
Value dimensionValue = lv.get(0).evalValue(c);
@@ -96,7 +96,7 @@ public class CarpetScriptHost extends ScriptHost
public void addUserDefinedFunction(Context ctx, Module module, String funName, FunctionValue function)
{
super.addUserDefinedFunction(ctx, module, funName, function);
// mcarpet
if (ctx.host.main != module) return; // not dealing with automatic imports / exports /configs / apps from imports
if (funName.startsWith("__")) // potential fishy activity
{
if (funName.startsWith("__on_")) // here we can make a determination if we want to only accept events from main module.
@@ -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;
@@ -27,6 +28,7 @@ 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.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.dimension.DimensionType;
@@ -39,6 +41,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -59,7 +62,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
{
@@ -105,16 +108,14 @@ public class ShapeDispatcher
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) ->
{
userParams.keySet().forEach(key -> {
Param param = Param.coders.get(key);
if (param==null) throw new InternalExpressionException("Unknown feature for shape: "+key);
validatedParams.put(key, param.validate(cc, value));
userParams.put(key, param.validate(cc, userParams.get(key)));
});
Function<Map<String, Value>,ExpiringShape> factory = ExpiringShape.shapeProviders.get(shapeType);
if (factory == null) throw new InternalExpressionException("Unknown shape: "+shapeType);
return factory.apply(validatedParams);
return factory.apply(userParams);
}
// client
@@ -126,7 +127,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));
@@ -135,13 +136,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
@@ -150,7 +151,7 @@ public class ShapeDispatcher
}
catch (InternalExpressionException exc)
{
CarpetSettings.LOG.error(exc.getMessage());
CarpetSettings.LOG.info(exc.getMessage());
}
return null;
}
@@ -160,6 +161,7 @@ public class ShapeDispatcher
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));
put("sphere", creator(Sphere::new));
}};
private static Function<Map<String, Value>,ExpiringShape> creator(Supplier<ExpiringShape> shapeFactory)
{
@@ -229,7 +231,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));
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();}
@@ -238,7 +243,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
@@ -247,6 +255,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)
@@ -260,6 +272,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
@@ -285,6 +303,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;
}
@@ -312,7 +332,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
@@ -325,6 +345,7 @@ public class ShapeDispatcher
float x1, y1, z1;
float x2, y2, z2;
float lineWidth;
@Override
protected void init(Map<String, Value> options)
@@ -338,6 +359,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
@@ -365,10 +387,88 @@ 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;
}
}
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);
@Override
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
@Override
protected Set<String> optionalParams() { return Sets.union(super.optionalParams(), optional.keySet()); }
private Sphere()
{
super();
}
float cx, cy, cz;
float radius;
int level;
int subdivisions;
float lineWidth;
@Override
protected void init(Map<String, Value> options)
{
super.init(options);
List<Value> from = ((ListValue)options.get("center")).getItems();
cx = NumericValue.asNumber(from.get(0)).getFloat();
cy = NumericValue.asNumber(from.get(1)).getFloat();
cz = NumericValue.asNumber(from.get(2)).getFloat();
radius = NumericValue.asNumber(options.get("radius")).getFloat();
level = NumericValue.asNumber(options.getOrDefault("level", optional.get("level"))).getInt();
subdivisions = level;
if (subdivisions <= 0)
{
subdivisions = Math.max(10, (int)(10*Math.sqrt(radius)));
}
lineWidth = NumericValue.asNumber(options.getOrDefault("width", optional.get("width"))).getFloat();
}
@Override
public Consumer<ServerPlayerEntity> alternative() { return p ->
{
String particleName = String.format(Locale.ROOT , "dust %.1f %.1f %.1f 1.0", r, g, b);
ParticleEffect particle = getParticleData(particleName);
float pihalf = (float)(Math.PI / 180.0f);
int partno = Math.min(1000,20*subdivisions);
Random rand = p.world.getRandom();
ServerWorld world = p.getServerWorld();
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);
world.spawnParticles(p, particle, true,
x+cx, y+cy, z+cz, 1,
0.0, 0.0, 0.0, 0.0);
}
};}
@Override
public int calcKey()
{
int hash = super.calcKey();
hash = 31*hash + 3;
hash = 31*hash + Float.hashCode(cx);
hash = 31*hash + Float.hashCode(cy);
hash = 31*hash + Float.hashCode(cz);
hash = 31*hash + Float.hashCode(radius);
hash = 31*hash + level;
hash = 31*hash + Float.hashCode(lineWidth);
return hash;
}
}
public interface Param
{
Map<String, Function<Tag, Value>> decoders = new HashMap<String, Function<Tag, Value>>(){{
@@ -378,16 +478,25 @@ public class ShapeDispatcher
put("color", ShapeDispatcher::decodeInt);
put("from", Vec3Param::decode);
put("to", Vec3Param::decode);
put("width", ShapeDispatcher::decodeFloat);
put("fill", ShapeDispatcher::decodeInt);
put("center", Vec3Param::decode);
put("radius", ShapeDispatcher::decodeFloat);
put("level", 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());
put("center", new CenterParam());
put("radius", new RadiusParam());
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
@@ -448,8 +557,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)
{
@@ -467,15 +574,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
{
@@ -542,12 +668,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
@@ -568,6 +704,30 @@ public class ShapeDispatcher
public String identify() { return "to"; }
}
public static class CenterParam extends Vec3Param
{
@Override
public boolean appliesTo(ExpiringShape shape) { return (shape instanceof Sphere); }
@Override
public boolean roundsUpForBlocks() { return false; }
@Override
public String identify() { return "center"; }
}
public static class RadiusParam extends PositiveFloatParam
{
@Override
public boolean appliesTo(ExpiringShape shape) { return shape instanceof Sphere; }
@Override
public String identify() { return "radius"; }
}
public static class LevelParam extends PositiveIntParam
{
@Override
public boolean appliesTo(ExpiringShape shape) { return shape instanceof Sphere; }
@Override
public String identify() { return "level"; }
}
private static boolean isStraight(Vec3d from, Vec3d to, double density)
@@ -13,6 +13,7 @@ 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.math.MathHelper;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
@@ -32,6 +33,7 @@ public class ShapesRenderer
{{
put("line", RenderedLine::new);
put("box", RenderedBox::new);
put("sphere", RenderedSphere::new);
}};
public ShapesRenderer(MinecraftClient minecraftClient)
@@ -93,12 +95,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
{
@@ -163,9 +162,9 @@ public class ShapesRenderer
@Override
public void render(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz)
{
RenderSystem.lineWidth(2.0F);
bufferBuilder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); // 3
drawBoxWireGLLines(bufferBuilder,
RenderSystem.lineWidth(shape.lineWidth);
drawBoxWireGLLines(tessellator, 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, shape.r, shape.g, shape.b
@@ -175,14 +174,15 @@ 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,
drawBoxFaces(tessellator, 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();
}
}
@@ -195,26 +195,43 @@ public class ShapesRenderer
@Override
public void render(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz)
{
RenderSystem.lineWidth(2.0F);
bufferBuilder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); // 3
drawLine(bufferBuilder,
RenderSystem.lineWidth(shape.lineWidth);
drawLine(tessellator, 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
);
tessellator.draw();
}
}
public static class RenderedSphere extends RenderedShape<ShapeDispatcher.Sphere>
{
public RenderedSphere(MinecraftClient client, ShapeDispatcher.ExpiringShape shape)
{
super(client, (ShapeDispatcher.Sphere)shape);
}
@Override
public void render(Tessellator tessellator, BufferBuilder bufferBuilder, float cx, float cy, float cz)
{
RenderSystem.lineWidth(shape.lineWidth);
drawSphereWireframe(tessellator, bufferBuilder,
shape.cx-cx-renderEpsilon, shape.cy-cy-renderEpsilon, shape.cz-cz-renderEpsilon,
shape.radius, shape.subdivisions,
shape.r, shape.g, shape.b, shape.a);
}
}
// some raw shit
public static void drawLine(BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha) {
public static void drawLine(Tessellator tessellator, BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha) {
builder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); // 3
builder.vertex(x1, y1, z1).color(red1, grn1, blu1, alpha).next();
builder.vertex(x2, y2, z2).color(red1, grn1, blu1, alpha).next();
tessellator.draw();
}
public static void drawBoxWireGLLines(BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha, float red2, float grn2, float blu2) {
public static void drawBoxWireGLLines(Tessellator tessellator, BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha, float red2, float grn2, float blu2) {
builder.begin(GL11.GL_LINES, VertexFormats.POSITION_COLOR); // 3
builder.vertex(x1, y1, z1).color(red1, grn2, blu2, alpha).next();
builder.vertex(x2, y1, z1).color(red1, grn2, blu2, alpha).next();
builder.vertex(x1, y1, z1).color(red2, grn1, blu2, alpha).next();
@@ -241,7 +258,8 @@ public class ShapesRenderer
builder.vertex(x2, y2, z2).color(red1, grn1, blu1, alpha).next();
}
public static void drawBox(BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha) {
public static void drawBoxFaces(Tessellator tessellator, BufferBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2, float red1, float grn1, float blu1, float alpha) {
builder.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR); // 3
builder.vertex(x1, y1, z1).color(red1, grn1, blu1, alpha).next();
builder.vertex(x2, y1, z1).color(red1, grn1, blu1, alpha).next();
builder.vertex(x2, y2, z1).color(red1, grn1, blu1, alpha).next();
@@ -271,5 +289,44 @@ public class ShapesRenderer
builder.vertex(x2, y2, z1).color(red1, grn1, blu1, alpha).next();
builder.vertex(x2, y2, z2).color(red1, grn1, blu1, alpha).next();
builder.vertex(x1, y2, z2).color(red1, grn1, blu1, alpha).next();
tessellator.draw();
}
public static void drawSphereWireframe(Tessellator tessellator, BufferBuilder builder,
float cx, float cy, float cz,
float r, int subd,
float red, float grn, float blu, float alpha)
{
float pihalf = (float)(Math.PI / 180.0f);
float step = 180f / (subd/2);
for (float i = 0f; i <= 360.0f; i+=step)
{
builder.begin(GL11.GL_LINE_STRIP, VertexFormats.POSITION_COLOR);
float theta = i * pihalf;
for (float j = 0f; j <= 180.0f; j+=step) {
float phi = j * pihalf;
float x = r * MathHelper.sin(phi) * MathHelper.cos(theta);
float z = r * MathHelper.sin(phi) * MathHelper.sin(theta);
float y = r * MathHelper.cos(phi);
builder.vertex(x+cx, y+cy, z+cz).color(red, grn, blu, alpha).next();
}
tessellator.draw();
}
for (float j = 0f; j <= 180.0f; j+=step)
{
builder.begin(GL11.GL_LINE_LOOP, VertexFormats.POSITION_COLOR);
float phi = j * pihalf;
for (float i = 0f; i <= 360.0f; i+=step)
{
float theta = i * pihalf;
float x = r * MathHelper.sin(phi) * MathHelper.cos(theta);
float z = r * MathHelper.sin(phi) * MathHelper.sin(theta);
float y = r * MathHelper.cos(phi);
builder.vertex(x+cx, y+cy, z+cz).color(red, grn, blu, alpha).next();
}
tessellator.draw();
}
}
}
@@ -5,6 +5,7 @@ import carpet.script.Expression;
import carpet.script.Fluff;
import carpet.script.LazyValue;
import carpet.script.Tokenizer;
import carpet.script.bundled.Module;
import carpet.script.exception.BreakStatement;
import carpet.script.exception.ContinueStatement;
import carpet.script.exception.ExitStatement;
@@ -58,6 +59,8 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
return name;
}
public Module getModule() {return expression.module;}
@Override
public String getPrettyString()
{
@@ -0,0 +1,234 @@
{
"rule.antiCheatDisabled.name": "關閉伺服器作弊檢測",
"rule.antiCheatDisabled.desc": "防止玩家因為“本伺服器不允許飛行”,“移動速度過快”等原因被請出伺服器",
"rule.carpets.name": "放置地毯顯示進階數據",
"rule.carpets.desc": "通過把地毯放置在地上取得更進階信息",
"rule.combineXPOrbs.name": "合併小經驗球",
"rule.combineXPOrbs.desc": "會將大量的小經驗球合併成等效的大經驗球",
"rule.commandCameramode.name": "旁觀者模式",
"rule.commandCameramode.desc": "允許玩家使用/c切換成旁觀者模式,利用/s切換回生存模式",
"rule.commandCameramode.extra.0": "/c及/s不需要op權限也可使用",
"rule.commandDistance.name": "距離測定",
"rule.commandDistance.desc": "使用/distance指令測定兩點的距離",
"rule.commandDistance.extra.0": "可以使用放置棕色地毯來使用此功能,前提是“放置地毯顯示進階數據”已啟用",
"rule.commandDraw.name": "繪製圖形",
"rule.commandDraw.desc": "使用/draw指令以允許繪製一些簡易圖形",
"rule.commandInfo.name": "獲取方塊進階資訊",
"rule.commandInfo.desc": "允許使用/info指令以獲得方塊進階資訊",
"rule.commandInfo.extra.0": "可以使用放置灰色地毯來使用此功能,前提是“放置地毯顯示進階數據”已啟用",
"rule.commandLog.name": "遊戲數據追蹤器",
"rule.commandLog.desc": "允許使用/log指令使在Tab欄位追蹤遊戲部分數據",
"rule.commandPerimeterInfo.name": "刷怪區域追蹤器",
"rule.commandPerimeterInfo.desc": "允許使用/perimeterinfo指令以探查周圍可生怪區域",
"rule.commandPlayer.name": "機器人控制",
"rule.commandPlayer.desc": "允許使用/player指令以控制/召喚已存在的玩家id作為機器人",
"rule.commandScript.name": "地毯腳本控制器",
"rule.commandScript.desc": "允許使用/script相關指令",
"rule.commandScript.extra.0": "一個Scarpet程式語言的遊戲內API",
"rule.commandSpawn.name": "刷怪追蹤器",
"rule.commandSpawn.desc": "允許使用/spawn指令用於怪物生成追蹤",
"rule.commandTick.name": "遊戲時鐘控制器",
"rule.commandTick.desc": "允許使用/tick指令控制遊戲內的伺服器端運行速度",
"rule.commandTrackAI.name": "AI追蹤器",
"rule.commandTrackAI.desc": "允許使用/track指令以追蹤生物的AI",
"rule.ctrlQCraftingFix.name": "ctrlQ合成修復",
"rule.ctrlQCraftingFix.desc": "在合成時允許使用ctrl+Q快捷鍵扔出結果格內所有物品",
"rule.customMOTD.name": "MOTD更改",
"rule.customMOTD.desc": "設置一個不同的MOTD信息",
"rule.customMOTD.extra.0": "設置成'_'時將採用默認的MOTD(從server.properties中讀取的)",
"rule.defaultLoggers.name": "默認開啟的遊戲數據追蹤器",
"rule.defaultLoggers.desc": "為所有新加入的玩家設置部分遊戲數據追蹤器默認為開啟狀態",
"rule.defaultLoggers.extra.0": "比如設置'tps,mobcaps'最為默認遊戲數據追蹤",
"rule.desertShrubs.name": "樹苗在沙漠中乾枯",
"rule.desertShrubs.desc": "樹苗將在附近無水源狀態的沙漠生態群系變成枯灌木",
"rule.disableSpawnChunks.name": "允許出生點區塊被卸載",
"rule.disableSpawnChunks.desc": "允許出生點區塊被卸載",
"rule.explosionNoBlockDamage.name": "爆炸不破壞方塊",
"rule.explosionNoBlockDamage.desc": "任何形式的爆炸都無法摧毀方塊",
"rule.extremeBehaviours.name": "隨機參數極端化",
"rule.extremeBehaviours.desc": "大幅度提升極端情況出現的概率,僅用於測試",
"rule.extremeBehaviours.extra.0": "發射器和投擲器將使用最大隨機刻",
"rule.fastRedstoneDust.name": "紅石粉卡頓優化",
"rule.fastRedstoneDust.desc": "紅石粉卡頓優化 作者 Theosib",
"rule.fillLimit.name": "fill/clone上限更改",
"rule.fillLimit.desc": "將fill/clone上限更改為自己設定的值",
"rule.fillLimit.extra.0": "你必須在1-2千萬之間取一個整數值",
"rule.fillUpdates.name": "fill更新設置",
"rule.fillUpdates.desc": "fill/clone/setblock指令以及結構方塊執行時是否產生更新",
"rule.fillUpdates.extra.0": "設置為true時有更新 設置為false時為無更新",
"rule.flatWorldStructureSpawning.name": "特定建築怪在超平坦世界生成",
"rule.flatWorldStructureSpawning.desc": "允許特定建築的怪物在超平坦世界生成",
"rule.flippinCactus.name": "仙人掌扳手",
"rule.flippinCactus.desc": "允許使用仙人掌調整方塊朝向,並且不會造成更新",
"rule.hardcodeTNTangle.name": "強制TNT角度",
"rule.hardcodeTNTangle.desc": "把TNT水平隨機角度設定為固定值,可用於測試機器",
"rule.hardcodeTNTangle.extra.0": "默認為-1,必須在0與360之間,或者-1",
"rule.hopperCounters.name": "漏斗計數器",
"rule.hopperCounters.desc": "漏斗指向的羊毛方塊會計算吸收的物品並清除",
"rule.hopperCounters.extra.0": "在羊毛方塊上放置紅色或綠色地毯,使用/counter指令可啟用",
"rule.hopperCounters.extra.1": "使用 /counter <color?> reset重置計數器,使用/counter <color?>查詢資訊",
"rule.hopperCounters.extra.2": "在生存模式,在同色羊毛上放置綠色地毯可以查詢,放紅色地毯重置",
"rule.hopperCounters.extra.3": "數據是全伺服器玩家共享的,並且有16色可以使用",
"rule.hopperCounters.extra.4": "物品會被銷毀,每個漏斗每tick銷毀一組物品",
"rule.huskSpawningInTemples.name": "屍殼在沙漠神殿裡生成",
"rule.huskSpawningInTemples.desc": "只有屍殼會在沙漠神殿生成",
"rule.lagFreeSpawning.name": "延遲自然生成",
"rule.lagFreeSpawning.desc": "生物生成需要更少的CPU和RAM",
"rule.leadFix.name": "栓繩修復",
"rule.leadFix.desc": "修復栓繩在未加載區塊中,變得不可見的問題",
"rule.maxEntityCollisions.name": "最大實體擠壓數量",
"rule.maxEntityCollisions.desc": "設定最大實體擠壓限制,0表示無限大",
"rule.mergeTNT.name": "合併TNT",
"rule.mergeTNT.desc": "合併靜止的點燃的tnt實體",
"rule.missingTools.name": "工具缺失修復",
"rule.missingTools.desc": "活塞,玻璃和海綿可以使用合適的工具更快地破壞",
"rule.movableBlockEntities.name": "容器方塊移動",
"rule.movableBlockEntities.desc": "活塞可以推動具有容器標籤的方塊,比如箱子,漏斗",
"rule.onePlayerSleeping.name": "單個玩家睡覺跳過夜晚",
"rule.onePlayerSleeping.desc": "只要伺服器中其中一人睡覺即可跳過全伺服器夜晚",
"rule.optimizedTNT.name": "TNT優化",
"rule.optimizedTNT.desc": "tnt在相同位置或者在流體裡,爆炸將造成更低延遲",
"rule.persistentParrots.name": "鸚鵡停留",
"rule.persistentParrots.desc": "鸚鵡不會離開你的肩膀,除非你受到傷害",
"rule.placementRotationFix.name": "放置旋轉問題修復",
"rule.placementRotationFix.desc": "修復玩家放置方塊時快速轉身造成的問題",
"rule.pushLimit.name": "自訂義推動上限",
"rule.pushLimit.desc": "自訂義活塞推動上限",
"rule.pushLimit.extra.0": "你必須在1-1024中選取一個值,預設是12",
"rule.quasiConnectivity.name": "半連接激活開關",
"rule.quasiConnectivity.desc": "活塞,發射器和投擲器在他們上方方塊激活時是否響應",
"rule.quasiConnectivity.extra.0": "設置為true為開啟 設置為false為禁用",
"rule.railPowerLimit.name": "自訂義動力鐵軌激活距離",
"rule.railPowerLimit.desc": "動力鐵軌激活距離能在此更改",
"rule.railPowerLimit.extra.0": "你必須在1-1024中選取一個數值",
"rule.renewableCoral.name": "可再生珊瑚",
"rule.renewableCoral.desc": "使用骨粉可催熟珊瑚以長成珊瑚方塊結構",
"rule.renewableSponges.name": "可再生海綿",
"rule.renewableSponges.desc": "深海守衛將在被雷擊後變成遠古深海守衛",
"rule.rotatorBlock.name": "仙人掌扳手發射器版",
"rule.rotatorBlock.desc": "發射器中的仙人掌可以旋轉方塊(盡可能以逆時針)",
"rule.scriptsAutoload.name": "Scarpet腳本自動加載",
"rule.scriptsAutoload.desc": "在伺服器/世界加載的時候將會自動從世界文件中加載Scarpet腳本文件",
"rule.scriptsAutoload.extra.0": "/script指令必須為啟用狀態",
"rule.shulkerSpawningInEndCities.name": "可重生界伏蚌",
"rule.shulkerSpawningInEndCities.desc": "界伏蚌將會在終界城市中重生",
"rule.silverFishDropGravel.name": "蠹魚鑽出放塊掉落礫石",
"rule.silverFishDropGravel.desc": "蠹魚鑽出放塊時會掉落礫石",
"rule.smoothClientAnimations.name": "更平暢玩家端動畫",
"rule.smoothClientAnimations.desc": "降低TPS設置時可以使玩家端動畫更加平暢",
"rule.smoothClientAnimations.extra.0": "僅在單人模式中生效,並且會降低玩家端運行速度",
"rule.stackableShulkerBoxes.name": "可堆疊界伏盒",
"rule.stackableShulkerBoxes.desc": "空的界伏盒扔在地上時將會自動堆疊,直到堆疊為1組",
"rule.stackableShulkerBoxes.extra.0": "在物品GUI中,請使用shift鍵+單擊以移動整組界伏盒",
"rule.summonNaturalLightning.name": "召喚閃電自然化",
"rule.summonNaturalLightning.desc": "召喚的閃電將具有自然生成時的特性",
"rule.tntDoNotUpdate.name": "TNT放置時不會被更新",
"rule.tntDoNotUpdate.desc": "TNT在放置時不會產生任何方塊更新(不會激活)",
"rule.tntPrimerMomentumRemoved.name": "移除TNT點燃時隨機動量",
"rule.tntPrimerMomentumRemoved.desc": "TNT點燃時的隨機動量將被移除",
"rule.tntRandomRange.name": "TNT爆炸範圍設置",
"rule.tntRandomRange.desc": "設置TNT隨機爆炸範圍為一個固定的值,設為-1以禁用",
"rule.tntRandomRange.extra.0": "必須啟用optimizedTNT功能",
"rule.tntRandomRange.extra.1": "不能設置為負數,除了-1",
"rule.unloadedEntityFix.name": "未加載實體修復",
"rule.unloadedEntityFix.desc": "進入或者被推入未加載區塊的實體不會消失",
"rule.viewDistance.name": "自訂義視野",
"rule.viewDistance.desc": "改變伺服器端視野距離,設置為0以使用默認值",
"rule.viewDistance.extra.0": "你必須在0(使用伺服器默認設置)-32取一個整數",
"rule.xpNoCooldown.name": "經驗球吸收無冷卻",
"rule.xpNoCooldown.desc": "玩家吸收經驗球不會有冷卻時間",
"rule.portalSuffocationFix.name": "傳送門窒息修復",
"rule.portalSuffocationFix.desc": "使地獄傳送門正確地傳送實體",
"rule.portalSuffocationFix.extra.0": "傳送的實體將不再卡在黑曜石裡",
"rule.portalCreativeDelay.name": "創造模式玩家地獄門傳送延遲",
"rule.portalCreativeDelay.desc": "創造模式下使用地獄傳送門將同生存時產生延遲",
"category.bugfix": "BUG修復",
"category.survival": "生存用",
"category.creative": "創造用",
"category.experimental": "實驗用",
"category.optimization": "優化",
"category.feature": "特性",
"category.command": "指令",
"category.tnt": "TNT",
"category.dispenser": "發射器",
"category.scarpet": "scarpet腳本程式語言",
"category.client": "玩家端",
"ui.browse_categories": "瀏覽分類",
"ui.list_all_%(cat)s_settings": "列出所有 %s 選項",
"ui.version": "版本",
"ui.current_%(mod)s_settings": "目前啟用的 %s 選項",
"ui.switch_to": "切換至",
"ui.settings_are_locked": "選項被鎖定",
"ui.is_set_to": "被設置為",
"ui.unknown_rule": "未知的規則選項",
"ui.current_%(mod)s_startup_settings_from_%(conf)s": "目前啟用的%s選項,從%s中讀取得",
"ui.%(mod)s_settings_matching_'%(query)s'": "%s中符合\"%s\"的選項:",
"ui.all_%(mod)s_settings": "所有的%s選項",
"ui.tags": "分類",
"ui.change_permanently": "設為預設",
"ui.click_to_keep_the_settings_in_%(conf)s_to_save_across_restarts": "點擊此按鈕以使此選項保存於%s,重啟後依舊生效",
"ui.rule_%(rule)s_will_now_default_to_%(value)s": "規則%s將會被默認設置為%s",
"ui.current_value": "當前的值"
}
@@ -229,4 +229,18 @@ __on_player_changes_dimension(player, from_pos, from_dimension, to_pos, to_dimen
print(' - player: '+player);
print(' - from '+from_dimension+' at '+map(from_pos, str('%.2f',_)));
print(' - to '+to_dimension+if(to_pos == null, '', ' at '+map(to_pos, str('%.2f',_))));
)
);
__on_player_connects(player) ->
( // you will never sees it
print('');
print('__on_player_connects(player)');
print('Player '+player+' connects.')
);
__on_player_disconnects(player, reason) ->
( // you will never sees it either
print('');
print('__on_player_disconnects(player)');
print('Player '+player+' disconnects because: '+reason)
);
@@ -12,7 +12,7 @@ global_renderers = m(
l('active', false),
l('handler', '__chunk_renderer'),
l('tasks', m()),
l('range', 4)
l('range', 6)
)),
l('shapes', m(
l('active', false),
@@ -99,7 +99,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);
draw_shape('box', 15, 'from', from, 'to', to+1, 'color', 0x00FFFFFF);
draw_shape('box', 15, 'from', from, 'to', to+1, 'color', 0x00FFFFFF, 'width', 3);
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;
@@ -110,8 +110,8 @@ __structure_renderer(player_name) ->
g = r;
b = 255;
a = 255;
color = a+256*(b+256*(g+256*r));
draw_shape('box', 15, 'from', from, 'to', to+1, 'color', color);
color = 256*(b+256*(g+256*r)); // leaving out a
draw_shape('box', 15, 'from', from, 'to', to+1, 'color', color+a, 'fill', color+a/6);
)
)
);
@@ -126,10 +126,9 @@ __chunk_renderer(player_name) ->
// get lower corner of the chunk
ppos = map(pos(p)/16, floor(_))*16;
ppos:1 = 0;
r = config:'range';
for(range(-r,r), cx =_;
for (range(-r,r), cz = _;
rang = config:'range';
for(range(-rang,rang), cx =_;
for (range(-rang,rang), cz = _;
ref_pos = ppos + l(16*cx,0,16*cz);
if(has(config:'tasks':'slime_chunks') && in_slime_chunk(ref_pos),
player_distance = _euclidean(ppos, ref_pos);
@@ -142,12 +141,12 @@ __chunk_renderer(player_name) ->
b = 30;
a = max(0, 255-player_distance);
color = a+256*(b+256*(g+256*r));
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);
draw_shape('line', 15, 'from', top_00, 'to', top_10, 'color', color, 'width', 3);
draw_shape('line', 15, 'from', top_10, 'to', top_11, 'color', color, 'width', 3);
draw_shape('line', 15, 'from', top_11, 'to', top_01, 'color', color, 'width', 3);
draw_shape('line', 15, 'from', top_01, 'to', top_00, 'color', color, 'width', 3);
draw_shape('line', 15, 'from', top_00, 'to', top_11, 'color', color, 'width', 3);
draw_shape('line', 15, 'from', top_01, 'to', top_10, 'color', color, 'width', 3);
//part = 'dust 0.2 0.8 0.2 2';
//density = 2+player_distance/2;