From 550e53aec7cdb70915210c85a830ab85a8508200 Mon Sep 17 00:00:00 2001 From: gnembon Date: Mon, 23 Nov 2020 22:08:06 -0400 Subject: [PATCH 01/11] Scoreboard for invalid objective shouldn't fail since objective names are not fixed and provided by players. --- docs/scarpet/api/Scoreboard.md | 6 ++++-- src/main/java/carpet/script/api/Scoreboards.java | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/scarpet/api/Scoreboard.md b/docs/scarpet/api/Scoreboard.md index b638fb93..d2feb12d 100644 --- a/docs/scarpet/api/Scoreboard.md +++ b/docs/scarpet/api/Scoreboard.md @@ -3,7 +3,8 @@ ### `scoreboard()`, `scoreboard(objective)`, `scoreboard(objective, key)`, `scoreboard(objective, key, value)` Displays or modifies individual scoreboard values. With no arguments, returns the list of current objectives. -With specified `objective`, lists all keys (players) associated with current objective. With specified `objective`, +With specified `objective`, lists all keys (players) associated with current objective, or `null` if objective does not exist. +With specified `objective` and `key`, returns current value of the objective for a given player (key). With additional `value` sets a new scoreboard value, returning previous value associated with the `key`. @@ -26,4 +27,5 @@ for the objective. ### `scoreboard_display(place, objective)` -sets display location for a specified `objective`. If `objective` is `null`, then display is cleared. +sets display location for a specified `objective`. If `objective` is `null`, then display is cleared. If objective is invalid, +returns `null`. diff --git a/src/main/java/carpet/script/api/Scoreboards.java b/src/main/java/carpet/script/api/Scoreboards.java index 748d1124..fbce0245 100644 --- a/src/main/java/carpet/script/api/Scoreboards.java +++ b/src/main/java/carpet/script/api/Scoreboards.java @@ -56,7 +56,7 @@ public class Scoreboards { } String objectiveName = lv.get(0).evalValue(c).getString(); ScoreboardObjective objective = scoreboard.getObjective(objectiveName); - if (objective == null) throw new InternalExpressionException("Unknown objective: "+objectiveName); + if (objective == null) return LazyValue.NULL; if (lv.size()==1) { Value ret = ListValue.wrap(scoreboard.getAllPlayerScores(objective).stream().map(s -> new StringValue(s.getPlayerName())).collect(Collectors.toList())); @@ -143,7 +143,7 @@ public class Scoreboards { } String objectiveString = target.getString(); ScoreboardObjective objective = scoreboard.getObjective(objectiveString); - if (objective == null) throw new InternalExpressionException("Objective doesn't exist: "+objectiveString); + if (objective == null) return LazyValue.NULL; scoreboard.setObjectiveSlot(slot, objective); return (_c, _t) -> new NumericValue(slot); }); From 7645312856c1c5970bd5b47970c07a381fc75c75 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Nov 2020 02:08:37 +0000 Subject: [PATCH 02/11] Merge docs for 'Scoreboard for invalid objective shouldn't fail since objective names are not fixed and provided by players.' --- docs/scarpet/Full.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index c0bde734..01d76d85 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -4120,7 +4120,8 @@ that have functions listed above will be automatically bounded and unbounded whe ### `scoreboard()`, `scoreboard(objective)`, `scoreboard(objective, key)`, `scoreboard(objective, key, value)` Displays or modifies individual scoreboard values. With no arguments, returns the list of current objectives. -With specified `objective`, lists all keys (players) associated with current objective. With specified `objective`, +With specified `objective`, lists all keys (players) associated with current objective, or `null` if objective does not exist. +With specified `objective` and `key`, returns current value of the objective for a given player (key). With additional `value` sets a new scoreboard value, returning previous value associated with the `key`. @@ -4143,7 +4144,8 @@ for the objective. ### `scoreboard_display(place, objective)` -sets display location for a specified `objective`. If `objective` is `null`, then display is cleared. +sets display location for a specified `objective`. If `objective` is `null`, then display is cleared. If objective is invalid, +returns `null`. # Auxiliary aspects Collection of other methods that control smaller, yet still important aspects of the game From fee127a942a3b6c8ec58f2957a934b0378efcb9c Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 24 Nov 2020 19:38:38 -0400 Subject: [PATCH 03/11] hide beta builtin apps --- src/main/java/carpet/script/CarpetScriptServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index 5b76e085..3bb77a7d 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -168,7 +168,7 @@ public class CarpetScriptServer { for (Module mi : bundledModuleData) { - if (!mi.isLibrary()) moduleNames.add(mi.getName()); + if (!mi.isLibrary() && !mi.getName().endsWith("_beta")) moduleNames.add(mi.getName()); } } File folder = server.getSavePath(WorldSavePath.ROOT).resolve("scripts").toFile(); From aeb3e382a63771ad2d0cf2003b75f461c8a6f182 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Wed, 25 Nov 2020 00:40:55 +0100 Subject: [PATCH 04/11] Replacing draw and distance with apps (#553) * added draw.sc app Now working on distance app * Adding apps as carpet rules * adding distance app Co-authored-by: altrisi --- src/main/java/carpet/CarpetSettings.java | 22 +++ .../carpet/script/CarpetScriptServer.java | 2 + .../assets/carpet/scripts/distance_rc_1.sc | 88 +++++++++++ .../assets/carpet/scripts/draw_rc_1.sc | 142 ++++++++++++++++++ .../resources/assets/carpet/scripts/math.scl | 4 +- 5 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/assets/carpet/scripts/distance_rc_1.sc create mode 100644 src/main/resources/assets/carpet/scripts/draw_rc_1.sc diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index 86004ff1..39675149 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -73,6 +73,7 @@ public class CarpetSettings /* These will be turned when events can be added / removed in code + Then also gotta remember to remove relevant rules @Rule( desc = "Turns on internal camera path tracing app", @@ -97,9 +98,29 @@ public class CarpetSettings appSource = "ai_tracker" ) public static boolean commandAITracker = true; + + @Rule( + desc = "Enables /draw commands", + extra = { + "... allows for drawing simple shapes or", + "other shapes which are sorta difficult to do normally" + }, + appSource = "draw", + category = {FEATURE, SCARPET, COMMAND} + ) + public static String commandDraw = "true"; + + @Rule( + desc = "Enables /distance command to measure in game distance between points", + extra = "Also enables brown carpet placement action if 'carpets' rule is turned on as well", + appSource = "distance", + category = {FEATURE, SCARPET, COMMAND} + ) + public static String commandDistance = "true"; */ + @Rule(desc = "Gbhs sgnf sadsgras fhskdpri!", category = EXPERIMENTAL) public static boolean superSecretSetting = false; @@ -374,6 +395,7 @@ public class CarpetSettings @Rule(desc = "Enables /draw commands", extra = {"... allows for drawing simple shapes or","other shapes which are sorta difficult to do normally"}, category = COMMAND) public static String commandDraw = "true"; + @Rule( desc = "Enables /script command", extra = "An in-game scripting API for Scarpet programming language", diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index 3bb77a7d..2b96b604 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -84,6 +84,8 @@ public class CarpetScriptServer registerBuiltInScript(BundledModule.carpetNative("math", true)); registerBuiltInScript(BundledModule.carpetNative("chunk_display", false)); registerBuiltInScript(BundledModule.carpetNative("ai_tracker", false)); + registerSettingsApp(BundledModule.carpetNative("draw_rc_1", false)); + registerSettingsApp(BundledModule.carpetNative("distance_rc_1", false)); } public CarpetScriptServer(MinecraftServer server) diff --git a/src/main/resources/assets/carpet/scripts/distance_rc_1.sc b/src/main/resources/assets/carpet/scripts/distance_rc_1.sc new file mode 100644 index 00000000..a3428132 --- /dev/null +++ b/src/main/resources/assets/carpet/scripts/distance_rc_1.sc @@ -0,0 +1,88 @@ +import('math','_euclidean','_manhattan','_round'); + +__config()->{ + 'commands'->{ + 'from '->'set_start', + 'from to '->'_calculate', + 'to '->_(end_pos)->(_calculate(null,end_pos)), + 'toggle_line'->'_toggle_line' + }, + 'scope'->'player' +}; + +global_position=null; +global_end_position=null; + +global_show_line=false; + +global_line = { + 'start_pos'->global_position, + 'end_pos'->global_end_position +}; + +set_start(pos)->( + global_position= pos; + print(player(),format('gi Initial point set to: ', 'g '+pos,'?/tp '+(str(pos)-','-'['-']'))) +); + +_toggle_line()->( + global_show_line= !global_show_line; + if(global_show_line, + print('Toggled lines on'); + if(global_end_position,_draw_line()),//making sure that there is a start an end pos, and Ive made it so there is no end pos without start pos + print('Toggled lines off') + ); + null +); + +_calculate(start_pos, end_pos)->( + if(start_pos!=null, + set_start(start_pos); + calculate(end_pos), + if(global_position, + calculate(end_pos), + print(player(),format('r There was no initial point for '+player())); + set_start(end_pos) + ) + ) +); + +__on_player_right_clicks_block(player, item_tuple, hand, block, face, hitvec) ->( + pos = pos_offset(block,face);//for clicking against the wall. + if(block=='brown_carpet' && system_info('world_carpet_rules'):'carpets'=='true', + if(global_position==null||player~'sneaking',//wont complain for first carpet + set_start(pos), + _calculate(null,pos) + ) + ) +); + +calculate(end_pos)->( + start_pos = global_position; + [dx,dy,dz] = map(start_pos-end_pos,abs(_)); + + manhattan = _round(_manhattan([dx, dy, dz],[0,0,0]),100);//rounding to nearest 0.01 for precision, but not ridiculous decimal places + spherical = _round(_euclidean([dx, dy, dz],[0,0,0]),100); + cylindrical = _round(_euclidean([dx, 0, dz],[0,0,0]),100);//useful for chunk distances etc. + + print(player(),format( + 'w Distance between ', + 'c '+start_pos,'?/tp '+(str(start_pos)-','-'['-']'), 'w and ', + 'c '+end_pos,'?/tp '+(str(end_pos)-','-'['-']'), 'w :\n', + 'w - Spherical: ', 'wb '+spherical+'\n', + 'w - Cylindrical: ', 'wb '+cylindrical+'\n', + 'w - Manhattan: ', 'wb '+manhattan + )); + + global_end_position = end_pos; + + schedule(0,'_draw_line'); +); + +_draw_line()->( + if(global_show_line,//It will always draw from the global positions, so it will turn on if there is a line + draw_shape('line',20,'from',global_position,'to',global_end_position, 'player',player(),'color',0x000000FF); + draw_shape('label',20,'pos',global_end_position,'text',_round(_euclidean(global_position,global_end_position),100),'color',0x000000FF); + schedule(20,'_draw_line') + ) +); diff --git a/src/main/resources/assets/carpet/scripts/draw_rc_1.sc b/src/main/resources/assets/carpet/scripts/draw_rc_1.sc new file mode 100644 index 00000000..0927b318 --- /dev/null +++ b/src/main/resources/assets/carpet/scripts/draw_rc_1.sc @@ -0,0 +1,142 @@ +import('math','_euclidean_sq','_vec_length'); + +__config() -> { + 'commands'->{ + 'sphere
'->['draw_sphere',null,true], + 'sphere
replace '->['draw_sphere',true], + 'ball
'->['draw_sphere',null,false], + 'ball
replace '->['draw_sphere',false], + 'diamond
'->['draw_diamond',null], + 'diamond
replace '->'draw_diamond', + 'pyramid
'->['draw_pyramid',null, true], + 'pyramid
replace '->['draw_pyramid', true], + 'cone
'->['draw_pyramid',null, false], + 'cone
replace '->['draw_pyramid', false], + 'cuboid
'->['draw_prism', null, true], + 'cuboid
replace '->['draw_prism', true], + 'cylinder
'->['draw_prism', null, false], + 'cylinder
replace '->['draw_prism', false] + }, + 'arguments'->{ + 'center'->{'type'->'pos', 'loaded'->'true'}, + 'radius'->{'type'->'int', 'suggest'->[], 'min'->0},//to avoid default suggestions + 'replacement'->{'type'->'block'}, + 'height'->{'type'->'int', 'suggest'->[],'min'->0}, + 'orientation'->{'type'->'term', 'suggest'->['x','y','z']}, + 'pointing'->{'type'->'term','suggest'->['up','down']}, + 'hollow'->{'type'->'term','suggest'->['hollow','solid']}, + }, + 'scope'->'global' +}; + + +//"Boilerplate" code + +set_block(x, y, z, block, replacement)-> ( + if(block != block(x, y, z), + without_updates(set([x, y, z],block)); + global_affected:0 += [x, y, z]; + global_affected:1 += 1; + ); +); + +global_affected = [[],0]; + +affected(player) -> ( + print(player,format('gi Filled ' + global_affected:1 + ' blocks')); + affected = global_affected:1; + + if(system_info('world_carpet_rules'):'fillUpdates', + for(global_affected:0,update(_));//updating if fillUpdates is true + ); + + global_affected = [[],0]; + affected +); + +length_sq(vec) -> _vec_length(vec)^2; + +fill_flat(pos, offset, dr, rectangle, orientation, block, hollow, replacement)->( + r = floor(dr); + drsq = dr^2; + if(orientation=='x', + scan(pos,0,-r,-r, + if((!hollow && (rectangle || _y^2 + _z^2 <= drsq))||//if not hollow, vry simple + (hollow && ((rectangle && (abs(_y) == r || abs(_z) ==r)) || //If hollow and it's a rectangle + (!rectangle && (_y^2 + _z^2 <= drsq && (abs(_y)+1)^ 2 + (abs(_z)+1)^2 >= drsq)))),//If hollow and not rectangle + set_block(_x+offset,_y,_z,block, replacement) + ) + ), + orientation == 'y', + scan(pos,-r,0,-r, + if((!hollow && (rectangle || _x^2 + _z^2 <= drsq))||//if not hollow, vry simple + (hollow && ((rectangle && (abs(_x) == r || abs(_z) ==r)) || //If hollow and it's a rectangle + (!rectangle && (_x^2 + _z^2 <= drsq && (abs(_x)+1)^ 2 + (abs(_z)+1)^2 >= drsq)))),//If hollow and not rectangle + set_block(_x,_y+offset,_z,block, replacement) + ) + ), + orientation == 'z', + scan(pos,-r,-r,0, + if((!hollow && (rectangle || _y^2 + _x^2 <= drsq))||//if not hollow, vry simple + (hollow && ((rectangle && (abs(_y) == r || abs(_x) ==r)) || //If hollow and it's a rectangle + (!rectangle && (_y^2 + _x^2 <= drsq && (abs(_y)+1)^ 2 + (abs(_x)+1)^2 >= drsq)))),//If hollow and not rectangle + set_block(_x,_y,_z+offset,block, replacement) + ) + ), + print(player(),format('r Error while running command: orientation can only be "x", "y" or "z", '+orientation+' is invalid.')); + global_affected = [[],0]; + ); +); + +//drawing commands + +draw_sphere(centre, radius, block, replacement, hollow)->( + scan(centre,[radius,radius,radius], + l = length_sq([_x,_y,_z]-centre); + if((l<=radius^2+radius) && (!hollow || l>=radius^2-radius), + set_block(_x, _y, _z, block, replacement) + ) + ); + + affected(player()); +); + +draw_diamond(pos, radius, block, replacement)->( + + c_for(r=0, r( + + hollow = fill_type=='hollow'; + pointup = pointing=='up'; + + for(range(height), + r = if(pointup, radius - radius * _ / height -1, radius * _ / height); + fill_flat(pos, _, r, is_square, orientation, block, if((pointup&&_==0)||(!pointup && _==height-1),false,hollow),replacement)//Always close bottom off + ); + affected(player()) +); + +draw_prism(pos, rad, height, orientation, block, fill_type, replacement, is_square)->( + + hollow = fill_type =='hollow'; + radius = rad+0.5; + + for(range(height), + fill_flat(pos, _, radius, is_square, orientation, block, if(_==0 || _==height-1,false,hollow), replacement)//Always close ends off + ); + affected(player()) +); diff --git a/src/main/resources/assets/carpet/scripts/math.scl b/src/main/resources/assets/carpet/scripts/math.scl index adef1621..d6e7c26b 100644 --- a/src/main/resources/assets/carpet/scripts/math.scl +++ b/src/main/resources/assets/carpet/scripts/math.scl @@ -1,3 +1,5 @@ _euclidean_sq(vec1, vec2) -> reduce(vec1 - vec2, _a + _*_, 0); _euclidean(vec1, vec2) -> sqrt(reduce(vec1 - vec2, _a + _*_, 0)); -_vec_length(vec) -> sqrt(reduce(vec, _a + _*_, 0)); \ No newline at end of file +_manhattan(vec1, vec2) -> reduce(vec1-vec2,_a+abs(_),0); +_vec_length(vec) -> sqrt(reduce(vec, _a + _*_, 0)); +_round(num,precision) -> round(num*precision)/precision; From 724b63df8a6a0fad235cc11da3fffd0b72aa33b8 Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 24 Nov 2020 19:43:21 -0400 Subject: [PATCH 05/11] using beta as a indicator --- src/main/java/carpet/script/CarpetScriptServer.java | 4 ++-- .../carpet/scripts/{distance_rc_1.sc => distance_beta.sc} | 0 .../assets/carpet/scripts/{draw_rc_1.sc => draw_beta.sc} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/main/resources/assets/carpet/scripts/{distance_rc_1.sc => distance_beta.sc} (100%) rename src/main/resources/assets/carpet/scripts/{draw_rc_1.sc => draw_beta.sc} (100%) diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index 2b96b604..18c0e656 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -84,8 +84,8 @@ public class CarpetScriptServer registerBuiltInScript(BundledModule.carpetNative("math", true)); registerBuiltInScript(BundledModule.carpetNative("chunk_display", false)); registerBuiltInScript(BundledModule.carpetNative("ai_tracker", false)); - registerSettingsApp(BundledModule.carpetNative("draw_rc_1", false)); - registerSettingsApp(BundledModule.carpetNative("distance_rc_1", false)); + registerSettingsApp(BundledModule.carpetNative("draw_beta", false)); + registerSettingsApp(BundledModule.carpetNative("distance_beta", false)); } public CarpetScriptServer(MinecraftServer server) diff --git a/src/main/resources/assets/carpet/scripts/distance_rc_1.sc b/src/main/resources/assets/carpet/scripts/distance_beta.sc similarity index 100% rename from src/main/resources/assets/carpet/scripts/distance_rc_1.sc rename to src/main/resources/assets/carpet/scripts/distance_beta.sc diff --git a/src/main/resources/assets/carpet/scripts/draw_rc_1.sc b/src/main/resources/assets/carpet/scripts/draw_beta.sc similarity index 100% rename from src/main/resources/assets/carpet/scripts/draw_rc_1.sc rename to src/main/resources/assets/carpet/scripts/draw_beta.sc From 209c3b926209aa656950eb005f7168afd921e021 Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 24 Nov 2020 22:52:05 -0400 Subject: [PATCH 06/11] fixed issues with reload and missing command handler --- .../java/carpet/commands/ScriptCommand.java | 4 +-- .../java/carpet/script/CarpetScriptHost.java | 13 ++++--- .../carpet/script/CarpetScriptServer.java | 34 +++++++++++++------ .../java/carpet/settings/SettingsManager.java | 2 +- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/main/java/carpet/commands/ScriptCommand.java b/src/main/java/carpet/commands/ScriptCommand.java index 3b916bba..29973381 100644 --- a/src/main/java/carpet/commands/ScriptCommand.java +++ b/src/main/java/carpet/commands/ScriptCommand.java @@ -244,13 +244,13 @@ public class ScriptCommand suggests( (cc, bb) -> suggestMatching(CarpetServer.scriptServer.listAvailableModules(true),bb)). executes((cc) -> { - boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), true, false, null); + boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, true, false, false); return success?1:0; }). then(literal("global"). executes((cc) -> { - boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), false, false, null); + boolean success = CarpetServer.scriptServer.addScriptHost(cc.getSource(), StringArgumentType.getString(cc, "app"), null, false, false, false); return success?1:0; } ) diff --git a/src/main/java/carpet/script/CarpetScriptHost.java b/src/main/java/carpet/script/CarpetScriptHost.java index bb85e001..b7f27fcb 100644 --- a/src/main/java/carpet/script/CarpetScriptHost.java +++ b/src/main/java/carpet/script/CarpetScriptHost.java @@ -57,7 +57,10 @@ public class CarpetScriptHost extends ScriptHost public Map appConfig; public Map appArgTypes; - private CarpetScriptHost(CarpetScriptServer server, Module code, boolean perUser, ScriptHost parent, Map config, Map argTypes) + Function commandValidator; + boolean isRuleApp; + + private CarpetScriptHost(CarpetScriptServer server, Module code, boolean perUser, ScriptHost parent, Map config, Map argTypes, Function commandValidator, boolean isRuleApp) { super(code, perUser, parent); this.saveTimeout = 0; @@ -74,11 +77,13 @@ public class CarpetScriptHost extends ScriptHost } appConfig = config; appArgTypes = argTypes; + this.commandValidator = commandValidator; + this.isRuleApp = isRuleApp; } - public static CarpetScriptHost create(CarpetScriptServer scriptServer, Module module, boolean perPlayer, ServerCommandSource source) + public static CarpetScriptHost create(CarpetScriptServer scriptServer, Module module, boolean perPlayer, ServerCommandSource source, Function commandValidator, boolean isRuleApp) { - CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null, Collections.emptyMap(), new HashMap<>()); + CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null, Collections.emptyMap(), new HashMap<>(), commandValidator, isRuleApp); // parse code and convert to expression if (module != null) { @@ -169,7 +174,7 @@ public class CarpetScriptHost extends ScriptHost @Override protected ScriptHost duplicate() { - return new CarpetScriptHost(scriptServer, main, false, this, appConfig, appArgTypes); + return new CarpetScriptHost(scriptServer, main, false, this, appConfig, appArgTypes, commandValidator, isRuleApp); } @Override diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index 18c0e656..69fd0327 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -84,8 +84,8 @@ public class CarpetScriptServer registerBuiltInScript(BundledModule.carpetNative("math", true)); registerBuiltInScript(BundledModule.carpetNative("chunk_display", false)); registerBuiltInScript(BundledModule.carpetNative("ai_tracker", false)); - registerSettingsApp(BundledModule.carpetNative("draw_beta", false)); - registerSettingsApp(BundledModule.carpetNative("distance_beta", false)); + registerBuiltInScript(BundledModule.carpetNative("draw_beta", false)); + registerBuiltInScript(BundledModule.carpetNative("distance_beta", false)); } public CarpetScriptServer(MinecraftServer server) @@ -103,7 +103,7 @@ public class CarpetScriptServer tickStart = 0L; stopAll = false; holyMoly = server.getCommandManager().getDispatcher().getRoot().getChildren().stream().map(CommandNode::getName).collect(Collectors.toSet()); - globalHost = CarpetScriptHost.create(this, null, false, null); + globalHost = CarpetScriptHost.create(this, null, false, null, p -> true, false); } public void initializeForWorld() @@ -119,7 +119,7 @@ public class CarpetScriptServer Messenger.m(server.getCommandSource(), "Auto-loading world scarpet apps"); for (String moduleName: listAvailableModules(false)) { - addScriptHost(server.getCommandSource(), moduleName, true, true, null); + addScriptHost(server.getCommandSource(), moduleName, null, true, true, false); } } @@ -195,10 +195,11 @@ public class CarpetScriptServer return modules.get(name); } - public boolean addScriptHost(ServerCommandSource source, String name, boolean perPlayer, boolean autoload, Function commandValidator) + public boolean addScriptHost(ServerCommandSource source, String name, Function commandValidator, + boolean perPlayer, boolean autoload, boolean isRuleApp) { //TODO add per player modules to support player actions better on a server - boolean isRuleApp = commandValidator != null; + if (commandValidator == null) commandValidator = p -> true; long start = System.nanoTime(); name = name.toLowerCase(Locale.ROOT); boolean reload = false; @@ -214,7 +215,7 @@ public class CarpetScriptServer Messenger.m(source, "r Failed to add "+name+" app"); return false; } - CarpetScriptHost newHost = CarpetScriptHost.create(this, module, perPlayer, source); + CarpetScriptHost newHost = CarpetScriptHost.create(this, module, perPlayer, source, commandValidator, isRuleApp); if (newHost == null) { Messenger.m(source, "r Failed to add "+name+" app"); @@ -436,13 +437,26 @@ public class CarpetScriptServer } } + static class TransferData + { + boolean perUser; + Function commandValidator; + boolean isRuleApp; + private TransferData(CarpetScriptHost host) + { + perUser = host.perUser; + commandValidator = host.commandValidator; + isRuleApp = host.isRuleApp; + } + } + public void reload(MinecraftServer server) { - Map apps = new HashMap<>(); - modules.forEach((s, h) -> apps.put(s, h.perUser)); + Map apps = new HashMap<>(); + modules.forEach((s, h) -> apps.put(s, new TransferData(h))); apps.keySet().forEach(s -> removeScriptHost(server.getCommandSource(), s, false, false)); CarpetEventServer.Event.clearAllBuiltinEvents(); init(); - apps.forEach((s, pp) -> addScriptHost(server.getCommandSource(), s, pp, false, null)); + apps.forEach((s, data) -> addScriptHost(server.getCommandSource(), s,data.commandValidator, data.perUser,false, data.isRuleApp)); } } diff --git a/src/main/java/carpet/settings/SettingsManager.java b/src/main/java/carpet/settings/SettingsManager.java index bc43f6ea..268bb308 100644 --- a/src/main/java/carpet/settings/SettingsManager.java +++ b/src/main/java/carpet/settings/SettingsManager.java @@ -190,7 +190,7 @@ public class SettingsManager { if (rule.getBoolValue() || (rule.type == String.class && !rule.get().equals("false"))) { - CarpetServer.scriptServer.addScriptHost(source, rule.scarpetApp, false, false, s -> canUseCommand(s, rule.get())); + CarpetServer.scriptServer.addScriptHost(source, rule.scarpetApp, s -> canUseCommand(s, rule.get()), false, false, true); } else { CarpetServer.scriptServer.removeScriptHost(source, rule.scarpetApp, false, true); } From 4c6d449553fc6fa6d4373a899011fd4d22bf9681 Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 24 Nov 2020 22:53:45 -0400 Subject: [PATCH 07/11] tweaks to distance beta app --- .../assets/carpet/scripts/distance_beta.sc | 69 ++++++++++--------- .../resources/assets/carpet/scripts/math.scl | 2 +- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/main/resources/assets/carpet/scripts/distance_beta.sc b/src/main/resources/assets/carpet/scripts/distance_beta.sc index a3428132..b1b3bc6d 100644 --- a/src/main/resources/assets/carpet/scripts/distance_beta.sc +++ b/src/main/resources/assets/carpet/scripts/distance_beta.sc @@ -2,44 +2,46 @@ import('math','_euclidean','_manhattan','_round'); __config()->{ 'commands'->{ - 'from '->'set_start', - 'from to '->'_calculate', - 'to '->_(end_pos)->(_calculate(null,end_pos)), + 'from '->'set_start', + 'from to '->'_calculate', + 'to '->_(end_pos)->(_calculate(null,end_pos)), 'toggle_line'->'_toggle_line' }, - 'scope'->'player' + 'arguments' -> { + 'start' -> {'type' -> 'location'}, + 'end' -> {'type' -> 'location'} + } }; -global_position=null; -global_end_position=null; +global_start=null; +global_end=null; global_show_line=false; -global_line = { - 'start_pos'->global_position, - 'end_pos'->global_end_position -}; +__mktp(pos) -> str('!/tp %.6f %.6f %.6f', pos); set_start(pos)->( - global_position= pos; - print(player(),format('gi Initial point set to: ', 'g '+pos,'?/tp '+(str(pos)-','-'['-']'))) + global_start = pos; + global_end = null; + print(player(),format('gi Initial point set to: ', 'g '+pos, __mktp(pos))) ); _toggle_line()->( global_show_line= !global_show_line; if(global_show_line, print('Toggled lines on'); - if(global_end_position,_draw_line()),//making sure that there is a start an end pos, and Ive made it so there is no end pos without start pos + _draw_line() + , // else print('Toggled lines off') ); - null ); _calculate(start_pos, end_pos)->( if(start_pos!=null, set_start(start_pos); - calculate(end_pos), - if(global_position, + calculate(end_pos) + , // else + if(global_start, calculate(end_pos), print(player(),format('r There was no initial point for '+player())); set_start(end_pos) @@ -47,42 +49,43 @@ _calculate(start_pos, end_pos)->( ) ); -__on_player_right_clicks_block(player, item_tuple, hand, block, face, hitvec) ->( - pos = pos_offset(block,face);//for clicking against the wall. +__on_player_places_block(player, item_tuple, hand, block) ->( if(block=='brown_carpet' && system_info('world_carpet_rules'):'carpets'=='true', - if(global_position==null||player~'sneaking',//wont complain for first carpet - set_start(pos), - _calculate(null,pos) + effective_pos = pos(block)+[0.5, 0, 0.5]; + if(global_start==null||player~'sneaking',//wont complain for first carpet + set_start(effective_pos), + _calculate(null, effective_pos) ) ) ); calculate(end_pos)->( - start_pos = global_position; - [dx,dy,dz] = map(start_pos-end_pos,abs(_)); - - manhattan = _round(_manhattan([dx, dy, dz],[0,0,0]),100);//rounding to nearest 0.01 for precision, but not ridiculous decimal places - spherical = _round(_euclidean([dx, dy, dz],[0,0,0]),100); - cylindrical = _round(_euclidean([dx, 0, dz],[0,0,0]),100);//useful for chunk distances etc. + global_end = end_pos; + manhattan = _round(_manhattan(global_start, global_end),0.001);//rounding to nearest 0.01 for precision, but not ridiculous decimal places + spherical = _round(_euclidean(global_start, global_end), 0.001); + //useful for chunk distances etc. + cylindrical = _round(_euclidean(global_start, [global_end:0, global_start:1, global_end:2]), 0.001); + print(player(),format( 'w Distance between ', - 'c '+start_pos,'?/tp '+(str(start_pos)-','-'['-']'), 'w and ', - 'c '+end_pos,'?/tp '+(str(end_pos)-','-'['-']'), 'w :\n', + 'c '+str('[%.1f, %.1f, %.1f]', global_start), __mktp(global_start), + 'w and ', + 'c '+str('[%.1f, %.1f, %.1f]', global_end), __mktp(global_end), 'w :\n', 'w - Spherical: ', 'wb '+spherical+'\n', 'w - Cylindrical: ', 'wb '+cylindrical+'\n', 'w - Manhattan: ', 'wb '+manhattan )); - global_end_position = end_pos; - schedule(0,'_draw_line'); ); _draw_line()->( if(global_show_line,//It will always draw from the global positions, so it will turn on if there is a line - draw_shape('line',20,'from',global_position,'to',global_end_position, 'player',player(),'color',0x000000FF); - draw_shape('label',20,'pos',global_end_position,'text',_round(_euclidean(global_position,global_end_position),100),'color',0x000000FF); + if ( global_start && global_end, + draw_shape('line',20,'from',global_start,'to',global_end, 'player',player()); + draw_shape('label',20,'pos',global_end,'text',_round(_euclidean(global_start,global_end),0.001)); + ); schedule(20,'_draw_line') ) ); diff --git a/src/main/resources/assets/carpet/scripts/math.scl b/src/main/resources/assets/carpet/scripts/math.scl index d6e7c26b..4af9ae32 100644 --- a/src/main/resources/assets/carpet/scripts/math.scl +++ b/src/main/resources/assets/carpet/scripts/math.scl @@ -2,4 +2,4 @@ _euclidean_sq(vec1, vec2) -> reduce(vec1 - vec2, _a + _*_, 0); _euclidean(vec1, vec2) -> sqrt(reduce(vec1 - vec2, _a + _*_, 0)); _manhattan(vec1, vec2) -> reduce(vec1-vec2,_a+abs(_),0); _vec_length(vec) -> sqrt(reduce(vec, _a + _*_, 0)); -_round(num,precision) -> round(num*precision)/precision; +_round(num,precision) -> round(num/precision)*precision; From 5615bddf9bfd6a67d494ce17c15150d06ffaa006 Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 25 Nov 2020 00:14:46 -0400 Subject: [PATCH 08/11] returns false on 'set' when setblock fails. --- src/main/java/carpet/script/api/WorldAccess.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index d0216e25..3b285911 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -739,11 +739,12 @@ public class WorldAccess { return (c_, t_) -> Value.FALSE; BlockState finalSourceBlockState = sourceBlockState; BlockPos targetPos = targetLocator.block.getPos(); + Boolean[] result = new Boolean[]{true}; cc.s.getMinecraftServer().submitAndJoin( () -> { Clearable.clear(world.getBlockEntity(targetPos)); - world.setBlockState(targetPos, finalSourceBlockState, 2); - if (finalData != null) + boolean success = world.setBlockState(targetPos, finalSourceBlockState, 2); + if (success && finalData != null) { BlockEntity be = world.getBlockEntity(targetPos); if (be != null) @@ -756,7 +757,9 @@ public class WorldAccess { be.markDirty(); } } + result[0] = success; }); + if (!result[0]) return LazyValue.FALSE; Value retval = new BlockValue(finalSourceBlockState, world, targetLocator.block.getPos()); return (c_, t_) -> retval; }); From 2a403c36c81600411c3f592e4b48dd0888716b6e Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 25 Nov 2020 01:49:56 -0400 Subject: [PATCH 09/11] added deprecation warnings, fixes #568 --- .../java/carpet/script/CarpetEventServer.java | 14 ++++++++++- .../java/carpet/script/CarpetScriptHost.java | 11 +++++++++ src/main/java/carpet/script/Expression.java | 23 ++++++++++++++++++- src/main/java/carpet/script/ScriptHost.java | 16 ++++++++++++- .../java/carpet/script/api/Auxiliary.java | 3 +++ .../java/carpet/script/api/WorldAccess.java | 3 +++ .../resources/assets/carpet/scripts/camera.sc | 4 ++-- 7 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/main/java/carpet/script/CarpetEventServer.java b/src/main/java/carpet/script/CarpetEventServer.java index 9280acd0..e31dda16 100644 --- a/src/main/java/carpet/script/CarpetEventServer.java +++ b/src/main/java/carpet/script/CarpetEventServer.java @@ -268,6 +268,12 @@ public class CarpetEventServer }; public static final Event NETHER_TICK = new Event("tick_nether", 0, true) { + @Override + public boolean deprecated() + { + return true; + } + @Override public void onTick() { @@ -279,6 +285,11 @@ public class CarpetEventServer }; public static final Event ENDER_TICK = new Event("tick_ender", 0, true) { + @Override + public boolean deprecated() + { + return true; + } @Override public void onTick() { @@ -804,6 +815,7 @@ public class CarpetEventServer { return handler.callList.size() > 0; } + public boolean deprecated() {return false;} //stubs for calls just to ease calls in vanilla code so they don't need to deal with scarpet value types public void onTick() { } public void onChunkGenerated(ServerWorld world, Chunk chunk) { } @@ -900,10 +912,10 @@ public class CarpetEventServer private boolean canAddEvent(Event event, ScriptHost host) { + if (event.deprecated()) host.issueDeprecation(event.name+" event"); return !(event.globalOnly && (host.perUser || host.parent != null)); } - public boolean removeEventFromCommand(ServerCommandSource source, String event, String funName) { Event ev = Event.getEvent(event, CarpetServer.scriptServer); diff --git a/src/main/java/carpet/script/CarpetScriptHost.java b/src/main/java/carpet/script/CarpetScriptHost.java index b7f27fcb..5981a863 100644 --- a/src/main/java/carpet/script/CarpetScriptHost.java +++ b/src/main/java/carpet/script/CarpetScriptHost.java @@ -744,4 +744,15 @@ public class CarpetScriptHost extends ScriptHost { return scriptServer; } + + @Override + public boolean issueDeprecation(String feature) + { + if(super.issueDeprecation(feature)) + { + Messenger.m(responsibleSource, "rb '"+feature+"' is deprecated and soon will be removed. Please consult the docs for their replacement"); + return true; + } + return false; + } } diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 3f68c110..2db94244 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -366,7 +366,28 @@ public class Expression public void alias(String copy, String original) { - functions.put(copy, functions.get(original)); + ILazyFunction originalFunction = functions.get(original); + functions.put(copy, new ILazyFunction() + { + @Override + public int getNumParams() + { + return originalFunction.getNumParams(); + } + + @Override + public boolean numParamsVaries() + { + return originalFunction.numParamsVaries(); + } + + @Override + public LazyValue lazyEval(Context c, Integer type, Expression expr, Tokenizer.Token token, List lazyParams) + { + c.host.issueDeprecation(copy+"(...)"); + return originalFunction.lazyEval(c, type, expr, token, lazyParams); + } + }); } diff --git a/src/main/java/carpet/script/ScriptHost.java b/src/main/java/carpet/script/ScriptHost.java index ac0f1803..c55861a6 100644 --- a/src/main/java/carpet/script/ScriptHost.java +++ b/src/main/java/carpet/script/ScriptHost.java @@ -8,9 +8,11 @@ import carpet.script.value.FunctionValue; import carpet.script.value.Value; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; -import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -34,6 +36,8 @@ public abstract class ScriptHost private final Map locks = new ConcurrentHashMap<>(); protected boolean inTermination = false; + private final Set deprecations = new HashSet<>(); + public Random getRandom(long aLong) { if (randomizers.size() > 1024) @@ -379,4 +383,14 @@ public abstract class ScriptHost { errorSnooper=null; } + + public static final Logger DEPRECATION_LOG = LogManager.getLogger("Scarpet Deprecation Warnings"); + + public boolean issueDeprecation(String feature) + { + if (deprecations.contains(feature)) return false; + deprecations.add(feature); + DEPRECATION_LOG.warn("'"+feature+"' is deprecated and soon will be removed. Please consult the docs for their replacement"); + return true; + } } diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index 167ae4f1..6e115aa3 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -577,6 +577,7 @@ public class Auxiliary { expression.addLazyFunction("seed", -1, (c, t, lv) -> { ServerCommandSource s = ((CarpetContext)c).s; + c.host.issueDeprecation("seed()"); Value ret = new NumericValue(s.getWorld().getSeed()); return (cc, tt) -> ret; }); @@ -785,6 +786,7 @@ public class Auxiliary { boolean shared = false; if (lv.size()>0) { + c.host.issueDeprecation("load_app_data(...) with arguments"); file = recognizeResource(lv.get(0).evalValue(c)); if (lv.size() > 1) { @@ -807,6 +809,7 @@ public class Auxiliary { boolean shared = false; if (lv.size()>1) { + c.host.issueDeprecation("store_app_data(...) with more than one argument"); file = recognizeResource(lv.get(1).evalValue(c)); if (lv.size() > 2) { diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index 3b285911..8c1417c5 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -543,6 +543,7 @@ public class WorldAccess { // Deprecated, use loaded_status as more indicative expression.addLazyFunction("loaded_ep", -1, (c, t, lv) -> { + c.host.issueDeprecation("loaded_ep(...)"); BlockPos pos = BlockArgument.findIn((CarpetContext)c, lv, 0).block.getPos(); Value retval = ((CarpetContext)c).s.getWorld().getChunkManager().shouldTickChunk(new ChunkPos(pos))?Value.TRUE : Value.FALSE; return (c_, t_) -> retval; @@ -965,6 +966,7 @@ public class WorldAccess { // Deprecated for block_state() expression.addLazyFunction("property", -1, (c, t, lv) -> { + c.host.issueDeprecation("property(...)"); BlockArgument locator = BlockArgument.findIn((CarpetContext) c, lv, 0); BlockState state = locator.block.getBlockState(); if (lv.size() <= locator.offset) @@ -981,6 +983,7 @@ public class WorldAccess { // Deprecated for block_state() expression.addLazyFunction("block_properties", -1, (c, t, lv) -> { + c.host.issueDeprecation("block_properties(...)"); BlockArgument locator = BlockArgument.findIn((CarpetContext) c, lv, 0); BlockState state = locator.block.getBlockState(); StateManager states = state.getBlock().getStateManager(); diff --git a/src/main/resources/assets/carpet/scripts/camera.sc b/src/main/resources/assets/carpet/scripts/camera.sc index 0ba530e6..7d146cdd 100644 --- a/src/main/resources/assets/carpet/scripts/camera.sc +++ b/src/main/resources/assets/carpet/scripts/camera.sc @@ -638,14 +638,14 @@ save_as(file) -> //otherwise mojang will interpret 0.0d as 0i and fail to insert put(path_nbt:'points', point_nbt, _i); ); - store_app_data(path_nbt, file); + write_file(file, 'nbt', path_nbt); 'stored path as '+file; ); // loads path under the local file that load(file) -> ( - path_nbt = load_app_data(file); + path_nbt = read_file(file, 'nbt'); if (!path_nbt, exit('No path to load: '+file)); new_points = map(get(path_nbt, 'points[]'), l(_:'pos[]', _:'duration', _:'type')); if (!new_points || first(new_points, length(_:0) != 5), From 53aec581bb63cc34d1eb3a32bebe903ef41826b1 Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 25 Nov 2020 01:50:32 -0400 Subject: [PATCH 10/11] simplify affected, not count set failures in draw --- .../assets/carpet/scripts/draw_beta.sc | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/resources/assets/carpet/scripts/draw_beta.sc b/src/main/resources/assets/carpet/scripts/draw_beta.sc index 0927b318..ff819431 100644 --- a/src/main/resources/assets/carpet/scripts/draw_beta.sc +++ b/src/main/resources/assets/carpet/scripts/draw_beta.sc @@ -34,27 +34,27 @@ __config() -> { set_block(x, y, z, block, replacement)-> ( if(block != block(x, y, z), - without_updates(set([x, y, z],block)); - global_affected:0 += [x, y, z]; - global_affected:1 += 1; + without_updates( if (set([x, y, z],block), + global_affected += [x, y, z]; + )); ); ); -global_affected = [[],0]; +global_affected = []; affected(player) -> ( - print(player,format('gi Filled ' + global_affected:1 + ' blocks')); - affected = global_affected:1; + affected = length(global_affected); + print(player,format('gi Filled ' + affected + ' blocks')); if(system_info('world_carpet_rules'):'fillUpdates', - for(global_affected:0,update(_));//updating if fillUpdates is true + for(global_affected,update(_));//updating if fillUpdates is true ); - global_affected = [[],0]; + global_affected = []; affected ); -length_sq(vec) -> _vec_length(vec)^2; +length_sq(vec) -> reduce(vec, _a + _*_, 0); fill_flat(pos, offset, dr, rectangle, orientation, block, hollow, replacement)->( r = floor(dr); @@ -84,7 +84,7 @@ fill_flat(pos, offset, dr, rectangle, orientation, block, hollow, replacement)-> ) ), print(player(),format('r Error while running command: orientation can only be "x", "y" or "z", '+orientation+' is invalid.')); - global_affected = [[],0]; + global_affected = []; ); ); From 1e7457c27f620269ed480920192d413b312912d5 Mon Sep 17 00:00:00 2001 From: gnembon Date: Wed, 25 Nov 2020 02:07:46 -0400 Subject: [PATCH 11/11] wording fixes #558 --- src/main/java/carpet/settings/Validator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/carpet/settings/Validator.java b/src/main/java/carpet/settings/Validator.java index 6f90bd60..3afa6dd4 100644 --- a/src/main/java/carpet/settings/Validator.java +++ b/src/main/java/carpet/settings/Validator.java @@ -38,8 +38,8 @@ public abstract class Validator return newValue; } @Override - public String description() { return "Its a client command so can be issued when connecting to non-carpet servers. " + - "In client-server setting it will only affect the executing player, so each player needs to type it" + + public String description() { return "Its a client command so can be issued and potentially be effective when connecting to non-carpet/vanilla servers. " + + "In these situations (on vanilla servers) it will only affect the executing player, so each player needs to type it" + " separately for the desired effect";} }