diff --git a/docs/scarpet/api/BlocksAndWorldAccess.md b/docs/scarpet/api/BlocksAndWorldAccess.md index 14d2792d..6f02cc1b 100644 --- a/docs/scarpet/api/BlocksAndWorldAccess.md +++ b/docs/scarpet/api/BlocksAndWorldAccess.md @@ -72,7 +72,10 @@ set(x,y,z,'hopper', l('facing', 'north'), nbt('{Items:[{Slot:1b,id:"minecraft:sl ### `without_updates(expr)` -Evaluates subexpression without causing updates when blocks change in the world +Evaluates subexpression without causing updates when blocks change in the world. + +For synchronization sake, as well as from the fact that suppressed update can only happen within a tick, +the call to the `expr` is docked on the main server task. Consider following scenario: We would like to generate a bunch of terrain in a flat world following a perlin noise generator. The following code causes a cascading effect as blocks placed on chunk borders will cause other chunks to get diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 85e1573a..b6b01917 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -759,16 +759,21 @@ public class CarpetExpression this.expr.addLazyFunction("without_updates", 1, (c, t, lv) -> { boolean previous = CarpetSettings.impendingFillSkipUpdates; - try + if (previous) return lv.get(0); + Value [] result = new Value[]{Value.NULL}; + ((CarpetContext)c).s.getMinecraftServer().submitAndJoin( () -> { - CarpetSettings.impendingFillSkipUpdates = true; - Value ret = lv.get(0).evalValue(c, t); - return (cc, tt) -> ret; - } - finally - { - CarpetSettings.impendingFillSkipUpdates = previous; - } + try + { + CarpetSettings.impendingFillSkipUpdates = true; + result[0] = lv.get(0).evalValue(c, t); + } + finally + { + CarpetSettings.impendingFillSkipUpdates = previous; + } + }); + return (cc, tt) -> result[0]; }); this.expr.addLazyFunction("set", -1, (c, t, lv) -> @@ -3249,18 +3254,13 @@ public class CarpetExpression throw new InternalExpressionException("Incorrect dimension string: "+dimString); innerSource = outerSource.withWorld(outerSource.getMinecraftServer().getWorld(dim)); } - } - try - { - ((CarpetContext) c).s = innerSource; - Value retval = lv.get(1).evalValue(c); - return (cc, tt) -> retval; - } - finally - { - ((CarpetContext) c).s = outerSource; - } - + }; + if (innerSource.getWorld() == outerSource.getWorld()) return lv.get(1); + Context newCtx = c.recreate(); + ((CarpetContext) newCtx).s = innerSource; + newCtx.variables = c.variables; + Value retval = lv.get(1).evalValue(newCtx); + return (cc, tt) -> retval; }); this.expr.addLazyFunction("plop", 4, (c, t, lv) ->{ diff --git a/src/main/java/carpet/script/Context.java b/src/main/java/carpet/script/Context.java index 8d1cd434..50548fb3 100644 --- a/src/main/java/carpet/script/Context.java +++ b/src/main/java/carpet/script/Context.java @@ -20,7 +20,7 @@ public class Context public static final int LVALUE = 9; public static final int MAPDEF = 10; - public final Map variables = new HashMap<>(); + public Map variables = new HashMap<>(); public final ScriptHost host; diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index e79cb4e9..7506e9c1 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -13,7 +13,7 @@ "sources": "https://github.com/gnembon/fabric-carpet" }, - "license": "GNU LGPL V3", + "license": "MIT", "icon": "assets/carpet/icon.png", "environment": "*",