diff --git a/src/main/java/carpet/script/CarpetScriptHost.java b/src/main/java/carpet/script/CarpetScriptHost.java index 27a74848..92da9ed7 100644 --- a/src/main/java/carpet/script/CarpetScriptHost.java +++ b/src/main/java/carpet/script/CarpetScriptHost.java @@ -210,7 +210,7 @@ public class CarpetScriptHost extends ScriptHost switch (tok.type) { case VARIABLE: - LazyValue var = getGlobalVariable(tok.surface.toLowerCase(Locale.ROOT)); + LazyValue var = getGlobalVariable(tok.surface); if (var != null) { argv.add(var); diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 9031d021..041d2221 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -321,7 +321,6 @@ public class Expression public void addUnaryFunction(String name, Function fun) { - name = name.toLowerCase(Locale.ROOT); functions.put(name, new AbstractFunction(1) { @Override @@ -334,7 +333,6 @@ public class Expression public void addBinaryFunction(String name, BiFunction fun) { - name = name.toLowerCase(Locale.ROOT); functions.put(name, new AbstractFunction(2) { @Override @@ -350,7 +348,6 @@ public class Expression public void addFunction(String name, Function, Value> fun) { - name = name.toLowerCase(Locale.ROOT); functions.put(name, new AbstractFunction(-1) { @Override @@ -377,7 +374,6 @@ public class Expression public void addLazyFunction(String name, int num_params, TriFunction, LazyValue> fun) { - name = name.toLowerCase(Locale.ROOT); functions.put(name, new AbstractLazyFunction(num_params) { @Override @@ -396,7 +392,6 @@ public class Expression } public FunctionValue addContextFunction(Context context, String name, Expression expr, Tokenizer.Token token, List arguments, List outers, LazyValue code) { - name = name.toLowerCase(Locale.ROOT); if (functions.containsKey(name)) throw new ExpressionException(context, expr, token, "Function "+name+" would mask a built-in function"); Map contextValues = new HashMap<>(); @@ -434,6 +429,7 @@ public class Expression if (lv.size() < 1) throw new InternalExpressionException("'import' needs at least a module name to import, and list of values to import"); String moduleName = lv.get(0).evalValue(c).getString(); c.host.importModule(c, moduleName); + moduleName = moduleName.toLowerCase(Locale.ROOT); if (lv.size() > 1) c.host.importNames(c, module, moduleName, lv.subList(1, lv.size()).stream().map((l) -> l.evalValue(c).getString()).collect(Collectors.toList())); if (t == Context.VOID) @@ -2289,7 +2285,7 @@ public class Expression stack.push((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c)); break; case FUNCTION: - String name = token.surface.toLowerCase(Locale.ROOT); + String name = token.surface; ILazyFunction f; ArrayList p; boolean isKnown = functions.containsKey(name); // globals will be evaluated lazily, not at compile time via . @@ -2376,7 +2372,7 @@ public class Expression case OPERATOR: if (stack.peek() < 2) { - if (token.surface.equalsIgnoreCase(";")) + if (token.surface.equals(";")) { throw new ExpressionException(c, this, token, "Unnecessary semicolon"); } @@ -2386,7 +2382,7 @@ public class Expression stack.set(stack.size() - 1, stack.peek() - 2 + 1); break; case FUNCTION: - ILazyFunction f = functions.get(token.surface.toLowerCase(Locale.ROOT));// don't validate global - userdef functions + ILazyFunction f = functions.get(token.surface);// don't validate global - userdef functions int numParams = stack.pop(); if (f != null && !f.numParamsVaries() && numParams != f.getNumParams()) { diff --git a/src/main/java/carpet/script/ScriptHost.java b/src/main/java/carpet/script/ScriptHost.java index e2dac757..385d07b3 100644 --- a/src/main/java/carpet/script/ScriptHost.java +++ b/src/main/java/carpet/script/ScriptHost.java @@ -10,6 +10,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; @@ -107,7 +108,7 @@ public abstract class ScriptHost public void importModule(Context c, String moduleName) { - if (modules.containsKey(moduleName)) return; // aready imported + if (modules.containsKey(moduleName.toLowerCase(Locale.ROOT))) return; // aready imported Module module = getModuleOrLibraryByName(moduleName); if (modules.containsKey(module.getName())) return; // aready imported, once again, in case some discrepancies in names? modules.put(module.getName(), module); diff --git a/src/main/java/carpet/script/Tokenizer.java b/src/main/java/carpet/script/Tokenizer.java index 61668abc..30fac871 100644 --- a/src/main/java/carpet/script/Tokenizer.java +++ b/src/main/java/carpet/script/Tokenizer.java @@ -370,12 +370,14 @@ public class Tokenizer implements Iterator token.type == Token.TokenType.HEX_LITERAL || token.type == Token.TokenType.VARIABLE || token.type == Token.TokenType.STRINGPARAM || + ( token.type == Token.TokenType.MARKER && ( previousToken.surface.equalsIgnoreCase("{") || previousToken.surface.equalsIgnoreCase("["))) || token.type == Token.TokenType.FUNCTION ) &&( previousToken.type == Token.TokenType.VARIABLE || previousToken.type == Token.TokenType.FUNCTION || previousToken.type == Token.TokenType.LITERAL || previousToken.type == Token.TokenType.CLOSE_PAREN || + ( previousToken.type == Token.TokenType.MARKER && ( previousToken.surface.equalsIgnoreCase("}") || previousToken.surface.equalsIgnoreCase("]"))) || previousToken.type == Token.TokenType.HEX_LITERAL || previousToken.type == Token.TokenType.STRINGPARAM ) diff --git a/src/main/java/carpet/script/utils/ShapeDispatcher.java b/src/main/java/carpet/script/utils/ShapeDispatcher.java index 980592f3..86ba6a03 100644 --- a/src/main/java/carpet/script/utils/ShapeDispatcher.java +++ b/src/main/java/carpet/script/utils/ShapeDispatcher.java @@ -547,14 +547,13 @@ public class ShapeDispatcher super.init(options); from = vecFromValue(options.get("from")); to = vecFromValue(options.get("to")); - if (from.equals(to)) throw new InternalExpressionException("Box dimensions are invalid - cannot draw a zero-size boxes"); } @Override public Consumer alternative() { ParticleEffect particle = replacementParticle(); - double density = Math.max(2.0, from.distanceTo(to) /50) / (a+0.1); + double density = Math.max(2.0, from.distanceTo(to) /50/ (a+0.1)) ; return p -> { if (p.world.getRegistryKey() == shapeDimension) @@ -630,7 +629,6 @@ public class ShapeDispatcher super.init(options); from = vecFromValue(options.get("from")); to = vecFromValue(options.get("to")); - if (from.equals(to)) throw new InternalExpressionException("Line dimensions are invalid - cannot draw a zero-length lines"); } @Override @@ -1285,13 +1283,33 @@ public class ShapeDispatcher public static int drawParticleLine(List players, ParticleEffect particle, Vec3d from, Vec3d to, double density) { - if (isStraight(from, to, density)) return drawOptimizedParticleLine(players, particle, from, to, density); - double lineLengthSq = from.squaredDistanceTo(to); - if (lineLengthSq == 0) return 0; - Vec3d incvec = to.subtract(from).multiply(2*density/MathHelper.sqrt(lineLengthSq)); + double distance = from.squaredDistanceTo(to); + if (distance == 0) return 0; int pcount = 0; + if (distance < 100) + { + Random rand = players.get(0).getServerWorld().random; + int particles = (int)(distance/density)+1; + Vec3d towards = to.subtract(from); + for (int i = 0; i < particles; i++) + { + Vec3d at = from.add(towards.multiply( rand.nextDouble())); + for (ServerPlayerEntity player : players) + { + player.getServerWorld().spawnParticles(player, particle, true, + at.x, at.y, at.z, 1, + 0.0, 0.0, 0.0, 0.0); + pcount ++; + } + } + return pcount; + } + + if (isStraight(from, to, density)) return drawOptimizedParticleLine(players, particle, from, to, density); + Vec3d incvec = to.subtract(from).multiply(2*density/MathHelper.sqrt(distance)); + for (Vec3d delta = new Vec3d(0.0,0.0,0.0); - delta.lengthSquared() if (!global_running, return()); show_activity = (p~'holds':0 == 'redstone_torch'); yval = setup:'plot_center':1+16; + base_update = global_update_interval; + random_component = ceil(0.4*base_update); + duration_max = ceil(1.5*base_update); in_dimension( setup:'plot_dimension', l(sx, sy, sz) = setup:'source_center'; l(px, py, pz) = setup:'plot_center'; @@ -160,10 +164,10 @@ __chunk_visualizer_tick(p) -> l(cached_status, expiry) = global_status_cache:source_pos; changed = (status != cached_status); if ( changed || (expiry < now), - global_status_cache:source_pos = l(status, now+100+floor(rand(40))); + global_status_cache:source_pos = l(status, now+base_update+floor(rand(random_component))); bpos = l(dx/2, yval, dz/2); bcol = global_chunk_colors:status:((dx+dz)%2); - shapes += l('box', 150, 'from', bpos, 'to', bpos + l(0.5,0,0.5), + shapes += l('box', duration_max, 'from', bpos, 'to', bpos + l(0.5,0,0.5), 'color', 0xffffff00, 'fill', bcol+128, 'follow', p, 'snap', 'xz'); if (changed, pbcol = global_chunk_colors:cached_status:((dx+dz)%2);