]> git.lizzy.rs Git - worldedit.git/blob - worldedit_commands/init.lua
f2bd1187f7897e9fc514146a38c91bc5f6d7378d
[worldedit.git] / worldedit_commands / init.lua
1 minetest.register_privilege("worldedit", "Can use WorldEdit commands")\r
2 \r
3 --wip: fold the hollow stuff into the main functions and add a hollow flag at the end, then add the compatibility stuff\r
4 \r
5 worldedit.set_pos = {}\r
6 worldedit.inspect = {}\r
7 \r
8 worldedit.pos1 = {}\r
9 worldedit.pos2 = {}\r
10 if minetest.place_schematic then\r
11         worldedit.prob_pos = {}\r
12         worldedit.prob_list = {}\r
13 end\r
14 \r
15 dofile(minetest.get_modpath("worldedit_commands") .. "/mark.lua")\r
16 \r
17 worldedit.player_notify = function(name, message)\r
18         minetest.chat_send_player(name, "WorldEdit -!- " .. message, false)\r
19 end\r
20 \r
21 --determines whether `nodename` is a valid node name, returning a boolean\r
22 worldedit.normalize_nodename = function(nodename)\r
23         local fullname = ItemStack({name=nodename}):get_name() --resolve aliases of node names to full names\r
24         if minetest.registered_nodes[fullname] or fullname == "air" then --directly found node name or alias of nodename\r
25                 return fullname\r
26         end\r
27         for key, value in pairs(minetest.registered_nodes) do\r
28                 if key:find(":" .. nodename, 1, true) then --found in mod\r
29                         return key\r
30                 end\r
31         end\r
32         nodename = nodename:lower() --lowercase both for case insensitive comparison\r
33         for key, value in pairs(minetest.registered_nodes) do\r
34                 if value.description:lower() == nodename then --found in description\r
35                         return key\r
36                 end\r
37         end\r
38         return nil\r
39 end\r
40 \r
41 --determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1)\r
42 worldedit.player_axis = function(name)\r
43         local dir = minetest.get_player_by_name(name):get_look_dir()\r
44         local x, y, z = math.abs(dir.x), math.abs(dir.y), math.abs(dir.z)\r
45         if x > y then\r
46                 if x > z then\r
47                         return "x", dir.x > 0 and 1 or -1\r
48                 end\r
49         elseif y > z then\r
50                 return "y", dir.y > 0 and 1 or -1\r
51         end\r
52         return "z", dir.z > 0 and 1 or -1\r
53 end\r
54 \r
55 minetest.register_chatcommand("/about", {\r
56         params = "",\r
57         description = "Get information about the mod",\r
58         func = function(name, param)\r
59                 worldedit.player_notify(name, "WorldEdit " .. worldedit.version_string .. " is available on this server. Type /help to get a list of commands, or get more information at https://github.com/Uberi/MineTest-WorldEdit/")\r
60         end,\r
61 })\r
62 \r
63 minetest.register_chatcommand("/inspect", {\r
64         params = "on/off/1/0/true/false/yes/no/enable/disable",\r
65         description = "Enable or disable node inspection",\r
66         privs = {worldedit=true},\r
67         func = function(name, param)\r
68                 if param == "on" or param == "1" or param == "true" or param == "yes" or param == "enable" then\r
69                         worldedit.inspect[name] = true\r
70                         worldedit.player_notify(name, "node inspection enabled")\r
71                 elseif param == "off" or param == "0" or param == "false" or param == "no" or param == "disable" then\r
72                         worldedit.inspect[name] = nil\r
73                         worldedit.player_notify(name, "node inspection disabled")\r
74                 else\r
75                         worldedit.player_notify(name, "invalid usage: " .. param)\r
76                 end\r
77         end,\r
78 })\r
79 \r
80 minetest.register_on_punchnode(function(pos, node, puncher)\r
81         local name = puncher:get_player_name()\r
82         if worldedit.inspect[name] then\r
83                 if minetest.check_player_privs(name, {worldedit=true}) then\r
84                         message = "inspector: " .. node.name .. " at " .. minetest.pos_to_string(pos) .. " (param1=" .. node.param1 .. ", param2=" .. node.param2 .. ")"\r
85                 else\r
86                         message = "inspector: worldedit privileges required"\r
87                 end\r
88                 worldedit.player_notify(name, message)\r
89         end\r
90 end)\r
91 \r
92 minetest.register_chatcommand("/reset", {\r
93         params = "",\r
94         description = "Reset the region so that it is empty",\r
95         privs = {worldedit=true},\r
96         func = function(name, param)\r
97                 worldedit.pos1[name] = nil\r
98                 worldedit.pos2[name] = nil\r
99                 worldedit.mark_pos1(name)\r
100                 worldedit.mark_pos2(name)\r
101                 worldedit.set_pos[name] = nil\r
102                 worldedit.player_notify(name, "region reset")\r
103         end,\r
104 })\r
105 \r
106 minetest.register_chatcommand("/mark", {\r
107         params = "",\r
108         description = "Show markers at the region positions",\r
109         privs = {worldedit=true},\r
110         func = function(name, param)\r
111                 worldedit.mark_pos1(name)\r
112                 worldedit.mark_pos2(name)\r
113                 worldedit.player_notify(name, "region marked")\r
114         end,\r
115 })\r
116 \r
117 minetest.register_chatcommand("/unmark", {\r
118         params = "",\r
119         description = "Hide markers if currently shown",\r
120         privs = {worldedit=true},\r
121         func = function(name, param)\r
122                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
123                 worldedit.pos1[name] = nil\r
124                 worldedit.pos2[name] = nil\r
125                 worldedit.mark_pos1(name)\r
126                 worldedit.mark_pos2(name)\r
127                 worldedit.pos1[name] = pos1\r
128                 worldedit.pos2[name] = pos2\r
129                 worldedit.player_notify(name, "region unmarked")\r
130         end,\r
131 })\r
132 \r
133 minetest.register_chatcommand("/pos1", {\r
134         params = "",\r
135         description = "Set WorldEdit region position 1 to the player's location",\r
136         privs = {worldedit=true},\r
137         func = function(name, param)\r
138                 local pos = minetest.get_player_by_name(name):getpos()\r
139                 pos.x, pos.y, pos.z = math.floor(pos.x + 0.5), math.floor(pos.y + 0.5), math.floor(pos.z + 0.5)\r
140                 worldedit.pos1[name] = pos\r
141                 worldedit.mark_pos1(name)\r
142                 worldedit.player_notify(name, "position 1 set to " .. minetest.pos_to_string(pos))\r
143         end,\r
144 })\r
145 \r
146 minetest.register_chatcommand("/pos2", {\r
147         params = "",\r
148         description = "Set WorldEdit region position 2 to the player's location",\r
149         privs = {worldedit=true},\r
150         func = function(name, param)\r
151                 local pos = minetest.get_player_by_name(name):getpos()\r
152                 pos.x, pos.y, pos.z = math.floor(pos.x + 0.5), math.floor(pos.y + 0.5), math.floor(pos.z + 0.5)\r
153                 worldedit.pos2[name] = pos\r
154                 worldedit.mark_pos2(name)\r
155                 worldedit.player_notify(name, "position 2 set to " .. minetest.pos_to_string(pos))\r
156         end,\r
157 })\r
158 \r
159 minetest.register_chatcommand("/p", {\r
160         params = "set/set1/set2/get",\r
161         description = "Set WorldEdit region, WorldEdit position 1, or WorldEdit position 2 by punching nodes, or display the current WorldEdit region",\r
162         privs = {worldedit=true},\r
163         func = function(name, param)\r
164                 if param == "set" then --set both WorldEdit positions\r
165                         worldedit.set_pos[name] = "pos1"\r
166                         worldedit.player_notify(name, "select positions by punching two nodes")\r
167                 elseif param == "set1" then --set WorldEdit position 1\r
168                         worldedit.set_pos[name] = "pos1only"\r
169                         worldedit.player_notify(name, "select position 1 by punching a node")\r
170                 elseif param == "set2" then --set WorldEdit position 2\r
171                         worldedit.set_pos[name] = "pos2"\r
172                         worldedit.player_notify(name, "select position 2 by punching a node")\r
173                 elseif param == "get" then --display current WorldEdit positions\r
174                         if worldedit.pos1[name] ~= nil then\r
175                                 worldedit.player_notify(name, "position 1: " .. minetest.pos_to_string(worldedit.pos1[name]))\r
176                         else\r
177                                 worldedit.player_notify(name, "position 1 not set")\r
178                         end\r
179                         if worldedit.pos2[name] ~= nil then\r
180                                 worldedit.player_notify(name, "position 2: " .. minetest.pos_to_string(worldedit.pos2[name]))\r
181                         else\r
182                                 worldedit.player_notify(name, "position 2 not set")\r
183                         end\r
184                 else\r
185                         worldedit.player_notify(name, "unknown subcommand: " .. param)\r
186                 end\r
187         end,\r
188 })\r
189 \r
190 minetest.register_chatcommand("/fixedpos", {\r
191         params = "set1/set2 x y z",\r
192         description = "Set a WorldEdit region position to the position at (<x>, <y>, <z>)",\r
193         privs = {worldedit=true},\r
194         func = function(name, param)\r
195                 local found, _, flag, x, y, z = param:find("^(set[12])%s+([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)$")\r
196                 if found == nil then\r
197                         worldedit.player_notify(name, "invalid usage: " .. param)\r
198                         return\r
199                 end\r
200                 local pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}\r
201                 if flag == "set1" then\r
202                         worldedit.pos1[name] = pos\r
203                         worldedit.mark_pos1(name)\r
204                         worldedit.player_notify(name, "position 1 set to " .. minetest.pos_to_string(pos))\r
205                 else --flag == "set2"\r
206                         worldedit.pos2[name] = pos\r
207                         worldedit.mark_pos2(name)\r
208                         worldedit.player_notify(name, "position 2 set to " .. minetest.pos_to_string(pos))\r
209                 end\r
210         end,\r
211 })\r
212 \r
213 minetest.register_on_punchnode(function(pos, node, puncher)\r
214         local name = puncher:get_player_name()\r
215         if name ~= "" and worldedit.set_pos[name] ~= nil then --currently setting position\r
216                 if worldedit.set_pos[name] == "pos1" then --setting position 1\r
217                         worldedit.pos1[name] = pos\r
218                         worldedit.mark_pos1(name)\r
219                         worldedit.set_pos[name] = "pos2" --set position 2 on the next invocation\r
220                         worldedit.player_notify(name, "position 1 set to " .. minetest.pos_to_string(pos))\r
221                 elseif worldedit.set_pos[name] == "pos1only" then --setting position 1 only\r
222                         worldedit.pos1[name] = pos\r
223                         worldedit.mark_pos1(name)\r
224                         worldedit.set_pos[name] = nil --finished setting positions\r
225                         worldedit.player_notify(name, "position 1 set to " .. minetest.pos_to_string(pos))\r
226                 elseif worldedit.set_pos[name] == "pos2" then --setting position 2\r
227                         worldedit.pos2[name] = pos\r
228                         worldedit.mark_pos2(name)\r
229                         worldedit.set_pos[name] = nil --finished setting positions\r
230                         worldedit.player_notify(name, "position 2 set to " .. minetest.pos_to_string(pos))\r
231                 elseif worldedit.set_pos[name] == "prob" then --setting Minetest schematic node probabilities\r
232                         worldedit.prob_pos[name] = pos\r
233                         minetest.show_formspec(puncher:get_player_name(), "prob_val_enter", "field[text;;]")\r
234                 end\r
235         end\r
236 end)\r
237 \r
238 minetest.register_chatcommand("/volume", {\r
239         params = "",\r
240         description = "Display the volume of the current WorldEdit region",\r
241         privs = {worldedit=true},\r
242         func = function(name, param)\r
243                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
244                 if pos1 == nil or pos2 == nil then\r
245                         worldedit.player_notify(name, "no region selected")\r
246                         return\r
247                 end\r
248 \r
249                 local volume = worldedit.volume(pos1, pos2)\r
250                 local abs = math.abs\r
251                 worldedit.player_notify(name, "current region has a volume of " .. volume .. " nodes ("\r
252                         .. abs(pos2.x - pos1.x) + 1 .. "*"\r
253                         .. abs(pos2.y - pos1.y) + 1 .. "*"\r
254                         .. abs(pos2.z - pos1.z) + 1 .. ")")\r
255         end,\r
256 })\r
257 \r
258 minetest.register_chatcommand("/set", {\r
259         params = "<node>",\r
260         description = "Set the current WorldEdit region to <node>",\r
261         privs = {worldedit=true},\r
262         func = function(name, param)\r
263                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
264                 if pos1 == nil or pos2 == nil then\r
265                         worldedit.player_notify(name, "no region selected")\r
266                         return\r
267                 end\r
268 \r
269                 local node = worldedit.normalize_nodename(param)\r
270                 if param == "" or not node then\r
271                         worldedit.player_notify(name, "invalid node name: " .. param)\r
272                         return\r
273                 end\r
274 \r
275                 local count = worldedit.set(pos1, pos2, node)\r
276                 worldedit.player_notify(name, count .. " nodes set")\r
277         end,\r
278 })\r
279 \r
280 minetest.register_chatcommand("/replace", {\r
281         params = "<search node> <replace node>",\r
282         description = "Replace all instances of <search node> with <replace node> in the current WorldEdit region",\r
283         privs = {worldedit=true},\r
284         func = function(name, param)\r
285                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
286                 if pos1 == nil or pos2 == nil then\r
287                         worldedit.player_notify(name, "no region selected")\r
288                         return\r
289                 end\r
290 \r
291                 local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+(.+)$")\r
292                 if found == nil then\r
293                         worldedit.player_notify(name, "invalid usage: " .. param)\r
294                         return\r
295                 end\r
296                 local newsearchnode = worldedit.normalize_nodename(searchnode)\r
297                 if not newsearchnode then\r
298                         worldedit.player_notify(name, "invalid search node name: " .. searchnode)\r
299                         return\r
300                 end\r
301                 local newreplacenode = worldedit.normalize_nodename(replacenode)\r
302                 if not newreplacenode then\r
303                         worldedit.player_notify(name, "invalid replace node name: " .. replacenode)\r
304                         return\r
305                 end\r
306 \r
307                 local count = worldedit.replace(pos1, pos2, newsearchnode, newreplacenode)\r
308                 worldedit.player_notify(name, count .. " nodes replaced")\r
309         end,\r
310 })\r
311 \r
312 minetest.register_chatcommand("/replaceinverse", {\r
313         params = "<search node> <replace node>",\r
314         description = "Replace all nodes other than <search node> with <replace node> in the current WorldEdit region",\r
315         privs = {worldedit=true},\r
316         func = function(name, param)\r
317                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
318                 if pos1 == nil or pos2 == nil then\r
319                         worldedit.player_notify(name, "no region selected")\r
320                         return\r
321                 end\r
322 \r
323                 local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+(.+)$")\r
324                 if found == nil then\r
325                         worldedit.player_notify(name, "invalid usage: " .. param)\r
326                         return\r
327                 end\r
328                 local newsearchnode = worldedit.normalize_nodename(searchnode)\r
329                 if not newsearchnode then\r
330                         worldedit.player_notify(name, "invalid search node name: " .. searchnode)\r
331                         return\r
332                 end\r
333                 local newreplacenode = worldedit.normalize_nodename(replacenode)\r
334                 if not newreplacenode then\r
335                         worldedit.player_notify(name, "invalid replace node name: " .. replacenode)\r
336                         return\r
337                 end\r
338 \r
339                 local count = worldedit.replaceinverse(pos1, pos2, searchnode, replacenode)\r
340                 worldedit.player_notify(name, count .. " nodes replaced")\r
341         end,\r
342 })\r
343 \r
344 minetest.register_chatcommand("/hollowsphere", {\r
345         params = "<radius> <node>",\r
346         description = "Add hollow sphere centered at WorldEdit position 1 with radius <radius>, composed of <node>",\r
347         privs = {worldedit=true},\r
348         func = function(name, param)\r
349                 local pos = worldedit.pos1[name]\r
350                 if pos == nil then\r
351                         worldedit.player_notify(name, "no region selected")\r
352                         return\r
353                 end\r
354 \r
355                 local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")\r
356                 if found == nil then\r
357                         worldedit.player_notify(name, "invalid usage: " .. param)\r
358                         return\r
359                 end\r
360                 local node = worldedit.normalize_nodename(nodename)\r
361                 if not node then\r
362                         worldedit.player_notify(name, "invalid node name: " .. nodename)\r
363                         return\r
364                 end\r
365 \r
366                 local count = worldedit.hollow_sphere(pos, tonumber(radius), node)\r
367                 worldedit.player_notify(name, count .. " nodes added")\r
368         end,\r
369 })\r
370 \r
371 minetest.register_chatcommand("/sphere", {\r
372         params = "<radius> <node>",\r
373         description = "Add sphere centered at WorldEdit position 1 with radius <radius>, composed of <node>",\r
374         privs = {worldedit=true},\r
375         func = function(name, param)\r
376                 local pos = worldedit.pos1[name]\r
377                 if pos == nil then\r
378                         worldedit.player_notify(name, "no region selected")\r
379                         return\r
380                 end\r
381 \r
382                 local found, _, radius, nodename = param:find("^(%d+)%s+(.+)$")\r
383                 if found == nil then\r
384                         worldedit.player_notify(name, "invalid usage: " .. param)\r
385                         return\r
386                 end\r
387                 local node = worldedit.normalize_nodename(nodename)\r
388                 if not node then\r
389                         worldedit.player_notify(name, "invalid node name: " .. nodename)\r
390                         return\r
391                 end\r
392 \r
393                 local count = worldedit.sphere(pos, tonumber(radius), node)\r
394                 worldedit.player_notify(name, count .. " nodes added")\r
395         end,\r
396 })\r
397 \r
398 minetest.register_chatcommand("/hollowdome", {\r
399         params = "<radius> <node>",\r
400         description = "Add hollow dome centered at WorldEdit position 1 with radius <radius>, composed of <node>",\r
401         privs = {worldedit=true},\r
402         func = function(name, param)\r
403                 local pos = worldedit.pos1[name]\r
404                 if pos == nil then\r
405                         worldedit.player_notify(name, "no region selected")\r
406                         return\r
407                 end\r
408 \r
409                 local found, _, radius, nodename = param:find("^([+-]?%d+)%s+(.+)$")\r
410                 if found == nil then\r
411                         worldedit.player_notify(name, "invalid usage: " .. param)\r
412                         return\r
413                 end\r
414                 local node = worldedit.normalize_nodename(nodename)\r
415                 if not node then\r
416                         worldedit.player_notify(name, "invalid node name: " .. nodename)\r
417                         return\r
418                 end\r
419 \r
420                 local count = worldedit.hollow_dome(pos, tonumber(radius), node)\r
421                 worldedit.player_notify(name, count .. " nodes added")\r
422         end,\r
423 })\r
424 \r
425 minetest.register_chatcommand("/dome", {\r
426         params = "<radius> <node>",\r
427         description = "Add dome centered at WorldEdit position 1 with radius <radius>, composed of <node>",\r
428         privs = {worldedit=true},\r
429         func = function(name, param)\r
430                 local pos = worldedit.pos1[name]\r
431                 if pos == nil then\r
432                         worldedit.player_notify(name, "no region selected")\r
433                         return\r
434                 end\r
435 \r
436                 local found, _, radius, nodename = param:find("^([+-]?%d+)%s+(.+)$")\r
437                 if found == nil then\r
438                         worldedit.player_notify(name, "invalid usage: " .. param)\r
439                         return\r
440                 end\r
441                 local node = worldedit.normalize_nodename(nodename)\r
442                 if not node then\r
443                         worldedit.player_notify(name, "invalid node name: " .. nodename)\r
444                         return\r
445                 end\r
446 \r
447                 local count = worldedit.dome(pos, tonumber(radius), node)\r
448                 worldedit.player_notify(name, count .. " nodes added")\r
449         end,\r
450 })\r
451 \r
452 minetest.register_chatcommand("/hollowcylinder", {\r
453         params = "x/y/z/? <length> <radius> <node>",\r
454         description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>",\r
455         privs = {worldedit=true},\r
456         func = function(name, param)\r
457                 local pos = worldedit.pos1[name]\r
458                 if pos == nil then\r
459                         worldedit.player_notify(name, "no region selected")\r
460                         return\r
461                 end\r
462 \r
463                 local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")\r
464                 if found == nil then\r
465                         worldedit.player_notify(name, "invalid usage: " .. param)\r
466                         return\r
467                 end\r
468                 length, radius = tonumber(length), tonumber(radius)\r
469                 if axis == "?" then\r
470                         axis, sign = worldedit.player_axis(name)\r
471                         length = length * sign\r
472                 end\r
473                 local node = worldedit.normalize_nodename(nodename)\r
474                 if not node then\r
475                         worldedit.player_notify(name, "invalid node name: " .. nodename)\r
476                         return\r
477                 end\r
478 \r
479                 local count = worldedit.hollow_cylinder(pos, axis, length, radius, node)\r
480                 worldedit.player_notify(name, count .. " nodes added")\r
481         end,\r
482 })\r
483 \r
484 minetest.register_chatcommand("/cylinder", {\r
485         params = "x/y/z/? <length> <radius> <node>",\r
486         description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>",\r
487         privs = {worldedit=true},\r
488         func = function(name, param)\r
489                 local pos = worldedit.pos1[name]\r
490                 if pos == nil then\r
491                         worldedit.player_notify(name, "no region selected")\r
492                         return\r
493                 end\r
494 \r
495                 local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+(.+)$")\r
496                 if found == nil then\r
497                         worldedit.player_notify(name, "invalid usage: " .. param)\r
498                         return\r
499                 end\r
500                 length, radius = tonumber(length), tonumber(radius)\r
501                 if axis == "?" then\r
502                         axis, sign = worldedit.player_axis(name)\r
503                         length = length * sign\r
504                 end\r
505                 local node = worldedit.normalize_nodename(nodename)\r
506                 if not node then\r
507                         worldedit.player_notify(name, "invalid node name: " .. nodename)\r
508                         return\r
509                 end\r
510 \r
511                 local count = worldedit.cylinder(pos, axis, length, radius, node)\r
512                 worldedit.player_notify(name, count .. " nodes added")\r
513         end,\r
514 })\r
515 \r
516 minetest.register_chatcommand("/pyramid", {\r
517         params = "x/y/z/? <height> <node>",\r
518         description = "Add pyramid centered at WorldEdit position 1 along the x/y/z/? axis with height <height>, composed of <node>",\r
519         privs = {worldedit=true},\r
520         func = function(name, param)\r
521                 local pos = worldedit.pos1[name]\r
522                 if pos == nil then\r
523                         worldedit.player_notify(name, "no region selected")\r
524                         return\r
525                 end\r
526 \r
527                 local found, _, axis, height, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(.+)$")\r
528                 if found == nil then\r
529                         worldedit.player_notify(name, "invalid usage: " .. param)\r
530                         return\r
531                 end\r
532                 height = tonumber(height)\r
533                 if axis == "?" then\r
534                         axis, sign = worldedit.player_axis(name)\r
535                         height = height * sign\r
536                 end\r
537                 local node = worldedit.normalize_nodename(nodename)\r
538                 if not node then\r
539                         worldedit.player_notify(name, "invalid node name: " .. nodename)\r
540                         return\r
541                 end\r
542 \r
543                 local count = worldedit.pyramid(pos, axis, height, node)\r
544                 worldedit.player_notify(name, count .. " nodes added")\r
545         end,\r
546 })\r
547 \r
548 minetest.register_chatcommand("/spiral", {\r
549         params = "<length> <height> <space> <node>",\r
550         description = "Add spiral centered at WorldEdit position 1 with side length <length>, height <height>, space between walls <space>, composed of <node>",\r
551         privs = {worldedit=true},\r
552         func = function(name, param)\r
553                 local pos = worldedit.pos1[name]\r
554                 if pos == nil then\r
555                         worldedit.player_notify(name, "no region selected")\r
556                         return\r
557                 end\r
558 \r
559                 local found, _, length, height, space, nodename = param:find("^(%d+)%s+(%d+)%s+(%d+)%s+(.+)$")\r
560                 if found == nil then\r
561                         worldedit.player_notify(name, "invalid usage: " .. param)\r
562                         return\r
563                 end\r
564                 local node = worldedit.normalize_nodename(nodename)\r
565                 if not node then\r
566                         worldedit.player_notify(name, "invalid node name: " .. nodename)\r
567                         return\r
568                 end\r
569 \r
570                 local count = worldedit.spiral(pos, tonumber(length), tonumber(height), tonumber(space), node)\r
571                 worldedit.player_notify(name, count .. " nodes added")\r
572         end,\r
573 })\r
574 \r
575 minetest.register_chatcommand("/copy", {\r
576         params = "x/y/z/? <amount>",\r
577         description = "Copy the current WorldEdit region along the x/y/z/? axis by <amount> nodes",\r
578         privs = {worldedit=true},\r
579         func = function(name, param)\r
580                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
581                 if pos1 == nil or pos2 == nil then\r
582                         worldedit.player_notify(name, "no region selected")\r
583                         return\r
584                 end\r
585 \r
586                 local found, _, axis, amount = param:find("^([xyz%?])%s+([+-]?%d+)$")\r
587                 if found == nil then\r
588                         worldedit.player_notify(name, "invalid usage: " .. param)\r
589                         return\r
590                 end\r
591                 amount = tonumber(amount)\r
592                 if axis == "?" then\r
593                         axis, sign = worldedit.player_axis(name)\r
594                         amount = amount * sign\r
595                 end\r
596 \r
597                 local count = worldedit.copy(pos1, pos2, axis, amount)\r
598                 worldedit.player_notify(name, count .. " nodes copied")\r
599         end,\r
600 })\r
601 \r
602 minetest.register_chatcommand("/move", {\r
603         params = "x/y/z/? <amount>",\r
604         description = "Move the current WorldEdit region along the x/y/z/? axis by <amount> nodes",\r
605         privs = {worldedit=true},\r
606         func = function(name, param)\r
607                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
608                 if pos1 == nil or pos2 == nil then\r
609                         worldedit.player_notify(name, "no region selected")\r
610                         return\r
611                 end\r
612 \r
613                 local found, _, axis, amount = param:find("^([xyz%?])%s+([+-]?%d+)$")\r
614                 if found == nil then\r
615                         worldedit.player_notify(name, "invalid usage: " .. param)\r
616                         return\r
617                 end\r
618                 amount = tonumber(amount)\r
619                 if axis == "?" then\r
620                         axis, sign = worldedit.player_axis(name)\r
621                         amount = amount * sign\r
622                 end\r
623 \r
624                 local count = worldedit.move(pos1, pos2, axis, amount)\r
625 \r
626                 pos1[axis] = pos1[axis] + amount\r
627                 pos2[axis] = pos2[axis] + amount\r
628                 worldedit.mark_pos1(name)\r
629                 worldedit.mark_pos2(name)\r
630                 worldedit.player_notify(name, count .. " nodes moved")\r
631         end,\r
632 })\r
633 \r
634 minetest.register_chatcommand("/stack", {\r
635         params = "x/y/z/? <count>",\r
636         description = "Stack the current WorldEdit region along the x/y/z/? axis <count> times",\r
637         privs = {worldedit=true},\r
638         func = function(name, param)\r
639                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
640                 if pos1 == nil or pos2 == nil then\r
641                         worldedit.player_notify(name, "no region selected")\r
642                         return\r
643                 end\r
644 \r
645                 local found, _, axis, count = param:find("^([xyz%?])%s+([+-]?%d+)$")\r
646                 if found == nil then\r
647                         worldedit.player_notify(name, "invalid usage: " .. param)\r
648                         return\r
649                 end\r
650                 count = tonumber(count)\r
651                 if axis == "?" then\r
652                         axis, sign = worldedit.player_axis(name)\r
653                         count = count * sign\r
654                 end\r
655 \r
656                 local count = worldedit.stack(pos1, pos2, axis, count)\r
657                 worldedit.player_notify(name, count .. " nodes stacked")\r
658         end,\r
659 })\r
660 \r
661 minetest.register_chatcommand("/scale", {\r
662         params = "<factor>",\r
663         description = "Scale the current WorldEdit positions and region by a factor of positive integer <factor> with position 1 as the origin",\r
664         privs = {worldedit=true},\r
665         func = function(name, param)\r
666                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
667                 if pos1 == nil or pos2 == nil then\r
668                         worldedit.player_notify(name, "no region selected")\r
669                         return\r
670                 end\r
671 \r
672                 local factor = tonumber(param)\r
673                 if not factor or factor ~= math.floor(factor) or factor <= 0 then\r
674                         worldedit.player_notify(name, "invalid scaling factor: " .. param)\r
675                 end\r
676 \r
677                 local count, pos1, pos2 = worldedit.scale(pos1, pos2, factor)\r
678 \r
679                 --reset markers to scaled positions\r
680                 worldedit.pos1[name] = pos1\r
681                 worldedit.pos2[name] = pos2\r
682                 worldedit.mark_pos1(name)\r
683                 worldedit.mark_pos2(name)\r
684 \r
685                 worldedit.player_notify(name, count .. " nodes scaled")\r
686         end,\r
687 })\r
688 \r
689 minetest.register_chatcommand("/transpose", {\r
690         params = "x/y/z/? x/y/z/?",\r
691         description = "Transpose the current WorldEdit region along the x/y/z/? and x/y/z/? axes",\r
692         privs = {worldedit=true},\r
693         func = function(name, param)\r
694                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
695                 if pos1 == nil or pos2 == nil then\r
696                         worldedit.player_notify(name, "no region selected")\r
697                         return\r
698                 end\r
699 \r
700                 local found, _, axis1, axis2 = param:find("^([xyz%?])%s+([xyz%?])$")\r
701                 if found == nil then\r
702                         worldedit.player_notify(name, "invalid usage: " .. param)\r
703                         return\r
704                 end\r
705                 if axis1 == "?" then\r
706                         axis1 = worldedit.player_axis(name)\r
707                 end\r
708                 if axis2 == "?" then\r
709                         axis2 = worldedit.player_axis(name)\r
710                 end\r
711                 if axis1 == axis2 then\r
712                         worldedit.player_notify(name, "invalid usage: axes must be different")\r
713                         return\r
714                 end\r
715 \r
716                 local count, pos1, pos2 = worldedit.transpose(pos1, pos2, axis1, axis2)\r
717 \r
718                 --reset markers to transposed positions\r
719                 worldedit.pos1[name] = pos1\r
720                 worldedit.pos2[name] = pos2\r
721                 worldedit.mark_pos1(name)\r
722                 worldedit.mark_pos2(name)\r
723 \r
724                 worldedit.player_notify(name, count .. " nodes transposed")\r
725         end,\r
726 })\r
727 \r
728 minetest.register_chatcommand("/flip", {\r
729         params = "x/y/z/?",\r
730         description = "Flip the current WorldEdit region along the x/y/z/? axis",\r
731         privs = {worldedit=true},\r
732         func = function(name, param)\r
733                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
734                 if pos1 == nil or pos2 == nil then\r
735                         worldedit.player_notify(name, "no region selected")\r
736                         return\r
737                 end\r
738 \r
739                 if param == "?" then\r
740                         param = worldedit.player_axis(name)\r
741                 end\r
742                 if param ~= "x" and param ~= "y" and param ~= "z" then\r
743                         worldedit.player_notify(name, "invalid usage: " .. param)\r
744                         return\r
745                 end\r
746 \r
747                 local count = worldedit.flip(pos1, pos2, param)\r
748                 worldedit.player_notify(name, count .. " nodes flipped")\r
749         end,\r
750 })\r
751 \r
752 minetest.register_chatcommand("/rotate", {\r
753         params = "<axis> <angle>",\r
754         description = "Rotate the current WorldEdit region around the axis <axis> by angle <angle> (90 degree increment)",\r
755         privs = {worldedit=true},\r
756         func = function(name, param)\r
757                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
758                 if pos1 == nil or pos2 == nil then\r
759                         worldedit.player_notify(name, "no region selected")\r
760                         return\r
761                 end\r
762 \r
763                 local found, _, axis, angle = param:find("^([xyz%?])%s+([+-]?%d+)$")\r
764                 if found == nil then\r
765                         worldedit.player_notify(name, "invalid usage: " .. param)\r
766                         return\r
767                 end\r
768                 if axis == "?" then\r
769                         axis = worldedit.player_axis(name)\r
770                 end\r
771                 if angle % 90 ~= 0 then\r
772                         worldedit.player_notify(name, "invalid usage: angle must be multiple of 90")\r
773                         return\r
774                 end\r
775 \r
776                 local count, pos1, pos2 = worldedit.rotate(pos1, pos2, axis, angle)\r
777 \r
778                 --reset markers to rotated positions\r
779                 worldedit.pos1[name] = pos1\r
780                 worldedit.pos2[name] = pos2\r
781                 worldedit.mark_pos1(name)\r
782                 worldedit.mark_pos2(name)\r
783 \r
784                 worldedit.player_notify(name, count .. " nodes rotated")\r
785         end,\r
786 })\r
787 \r
788 minetest.register_chatcommand("/orient", {\r
789         params = "<angle>",\r
790         description = "Rotate oriented nodes in the current WorldEdit region around the Y axis by angle <angle> (90 degree increment)",\r
791         privs = {worldedit=true},\r
792         func = function(name, param)\r
793                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
794                 if pos1 == nil or pos2 == nil then\r
795                         worldedit.player_notify(name, "no region selected")\r
796                         return\r
797                 end\r
798 \r
799                 local found, _, angle = param:find("^([+-]?%d+)$")\r
800                 if found == nil then\r
801                         worldedit.player_notify(name, "invalid usage: " .. param)\r
802                         return\r
803                 end\r
804                 if angle % 90 ~= 0 then\r
805                         worldedit.player_notify(name, "invalid usage: angle must be multiple of 90")\r
806                         return\r
807                 end\r
808 \r
809                 local count = worldedit.orient(pos1, pos2, angle)\r
810 \r
811                 worldedit.player_notify(name, count .. " nodes oriented")\r
812         end,\r
813 })\r
814 \r
815 minetest.register_chatcommand("/fixlight", {\r
816         params = "",\r
817         description = "Fix the lighting in the current WorldEdit region",\r
818         privs = {worldedit=true},\r
819         func = function(name, param)\r
820                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
821                 if pos1 == nil or pos2 == nil then\r
822                         worldedit.player_notify(name, "no region selected")\r
823                         return\r
824                 end\r
825 \r
826                 local count = worldedit.fixlight(pos1, pos2)\r
827                 worldedit.player_notify(name, count .. " nodes updated")\r
828         end,\r
829 })\r
830 \r
831 minetest.register_chatcommand("/hide", {\r
832         params = "",\r
833         description = "Hide all nodes in the current WorldEdit region non-destructively",\r
834         privs = {worldedit=true},\r
835         func = function(name, param)\r
836                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
837                 if pos1 == nil or pos2 == nil then\r
838                         worldedit.player_notify(name, "no region selected")\r
839                         return\r
840                 end\r
841 \r
842                 local count = worldedit.hide(pos1, pos2)\r
843                 worldedit.player_notify(name, count .. " nodes hidden")\r
844         end,\r
845 })\r
846 \r
847 minetest.register_chatcommand("/suppress", {\r
848         params = "<node>",\r
849         description = "Suppress all <node> in the current WorldEdit region non-destructively",\r
850         privs = {worldedit=true},\r
851         func = function(name, param)\r
852                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
853                 if pos1 == nil or pos2 == nil then\r
854                         worldedit.player_notify(name, "no region selected")\r
855                         return\r
856                 end\r
857 \r
858                 local node = worldedit.normalize_nodename(param)\r
859                 if param == "" or not node then\r
860                         worldedit.player_notify(name, "invalid node name: " .. param)\r
861                         return\r
862                 end\r
863 \r
864                 local count = worldedit.suppress(pos1, pos2, node)\r
865                 worldedit.player_notify(name, count .. " nodes suppressed")\r
866         end,\r
867 })\r
868 \r
869 minetest.register_chatcommand("/highlight", {\r
870         params = "<node>",\r
871         description = "Highlight <node> in the current WorldEdit region by hiding everything else non-destructively",\r
872         privs = {worldedit=true},\r
873         func = function(name, param)\r
874                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
875                 if pos1 == nil or pos2 == nil then\r
876                         worldedit.player_notify(name, "no region selected")\r
877                         return\r
878                 end\r
879 \r
880                 local node = worldedit.normalize_nodename(param)\r
881                 if param == "" or not node then\r
882                         worldedit.player_notify(name, "invalid node name: " .. param)\r
883                         return\r
884                 end\r
885 \r
886                 local count = worldedit.highlight(pos1, pos2, node)\r
887                 worldedit.player_notify(name, count .. " nodes highlighted")\r
888         end,\r
889 })\r
890 \r
891 minetest.register_chatcommand("/restore", {\r
892         params = "",\r
893         description = "Restores nodes hidden with WorldEdit in the current WorldEdit region",\r
894         privs = {worldedit=true},\r
895         func = function(name, param)\r
896                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
897                 if pos1 == nil or pos2 == nil then\r
898                         worldedit.player_notify(name, "no region selected")\r
899                         return\r
900                 end\r
901 \r
902                 local count = worldedit.restore(pos1, pos2)\r
903                 worldedit.player_notify(name, count .. " nodes restored")\r
904         end,\r
905 })\r
906 \r
907 minetest.register_chatcommand("/save", {\r
908         params = "<file>",\r
909         description = "Save the current WorldEdit region to \"(world folder)/schems/<file>.we\"",\r
910         privs = {worldedit=true},\r
911         func = function(name, param)\r
912                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
913                 if pos1 == nil or pos2 == nil then\r
914                         worldedit.player_notify(name, "no region selected")\r
915                         return\r
916                 end\r
917 \r
918                 if param == "" then\r
919                         worldedit.player_notify(name, "invalid usage: " .. param)\r
920                         return\r
921                 end\r
922 \r
923                 local result, count = worldedit.serialize(pos1, pos2)\r
924 \r
925                 local path = minetest.get_worldpath() .. "/schems"\r
926                 local filename = path .. "/" .. param .. ".we"\r
927                 os.execute("mkdir \"" .. path .. "\"") --create directory if it does not already exist\r
928                 local file, err = io.open(filename, "wb")\r
929                 if err ~= nil then\r
930                         worldedit.player_notify(name, "could not save file to \"" .. filename .. "\"")\r
931                         return\r
932                 end\r
933                 file:write(result)\r
934                 file:flush()\r
935                 file:close()\r
936 \r
937                 worldedit.player_notify(name, count .. " nodes saved")\r
938         end,\r
939 })\r
940 \r
941 minetest.register_chatcommand("/allocate", {\r
942         params = "<file>",\r
943         description = "Set the region defined by nodes from \"(world folder)/schems/<file>.we\" as the current WorldEdit region",\r
944         privs = {worldedit=true},\r
945         func = function(name, param)\r
946                 local pos1 = worldedit.pos1[name]\r
947                 if pos1 == nil then\r
948                         worldedit.player_notify(name, "no region selected")\r
949                         return\r
950                 end\r
951 \r
952                 if param == "" then\r
953                         worldedit.player_notify(name, "invalid usage: " .. param)\r
954                         return\r
955                 end\r
956 \r
957                 local filename = minetest.get_worldpath() .. "/schems/" .. param .. ".we"\r
958                 local file, err = io.open(filename, "rb")\r
959                 if err ~= nil then\r
960                         worldedit.player_notify(name, "could not open file \"" .. filename .. "\"")\r
961                         return\r
962                 end\r
963                 local value = file:read("*a")\r
964                 file:close()\r
965 \r
966                 if worldedit.valueversion(value) == 0 then --unknown version\r
967                         worldedit.player_notify(name, "invalid file: file is invalid or created with newer version of WorldEdit")\r
968                         return\r
969                 end\r
970                 local nodepos1, nodepos2, count = worldedit.allocate(pos1, value)\r
971 \r
972                 worldedit.pos1[name] = nodepos1\r
973                 worldedit.mark_pos1(name)\r
974                 worldedit.pos2[name] = nodepos2\r
975                 worldedit.mark_pos2(name)\r
976 \r
977                 worldedit.player_notify(name, count .. " nodes allocated")\r
978         end,\r
979 })\r
980 \r
981 minetest.register_chatcommand("/load", {\r
982         params = "<file>",\r
983         description = "Load nodes from \"(world folder)/schems/<file>[.we[m]]\" with position 1 of the current WorldEdit region as the origin",\r
984         privs = {worldedit=true},\r
985         func = function(name, param)\r
986                 local pos1 = worldedit.pos1[name]\r
987                 if pos1 == nil then\r
988                         worldedit.player_notify(name, "no region selected")\r
989                         return\r
990                 end\r
991 \r
992                 if param == "" then\r
993                         worldedit.player_notify(name, "invalid usage: " .. param)\r
994                         return\r
995                 end\r
996 \r
997                 --find the file in the world path\r
998                 local testpaths = {\r
999                         minetest.get_worldpath() .. "/schems/" .. param,\r
1000                         minetest.get_worldpath() .. "/schems/" .. param .. ".we",\r
1001                         minetest.get_worldpath() .. "/schems/" .. param .. ".wem",\r
1002                 }\r
1003                 local file, err\r
1004                 for index, path in ipairs(testpaths) do\r
1005                         file, err = io.open(path, "rb")\r
1006                         if not err then\r
1007                                 break\r
1008                         end\r
1009                 end\r
1010                 if err then\r
1011                         worldedit.player_notify(name, "could not open file \"" .. param .. "\"")\r
1012                         return\r
1013                 end\r
1014                 local value = file:read("*a")\r
1015                 file:close()\r
1016 \r
1017                 if worldedit.valueversion(value) == 0 then --unknown version\r
1018                         worldedit.player_notify(name, "invalid file: file is invalid or created with newer version of WorldEdit")\r
1019                         return\r
1020                 end\r
1021 \r
1022                 local count = worldedit.deserialize(pos1, value)\r
1023 \r
1024                 worldedit.player_notify(name, count .. " nodes loaded")\r
1025         end,\r
1026 })\r
1027 \r
1028 minetest.register_chatcommand("/lua", {\r
1029         params = "<code>",\r
1030         description = "Executes <code> as a Lua chunk in the global namespace",\r
1031         privs = {worldedit=true, server=true},\r
1032         func = function(name, param)\r
1033                 local err = worldedit.lua(param)\r
1034                 if err then\r
1035                         worldedit.player_notify(name, "code error: " .. err)\r
1036                 else\r
1037                         worldedit.player_notify(name, "code successfully executed", false)\r
1038                 end\r
1039         end,\r
1040 })\r
1041 \r
1042 minetest.register_chatcommand("/luatransform", {\r
1043         params = "<code>",\r
1044         description = "Executes <code> as a Lua chunk in the global namespace with the variable pos available, for each node in the current WorldEdit region",\r
1045         privs = {worldedit=true, server=true},\r
1046         func = function(name, param)\r
1047                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
1048                 if pos1 == nil or pos2 == nil then\r
1049                         worldedit.player_notify(name, "no region selected")\r
1050                         return\r
1051                 end\r
1052 \r
1053                 local err = worldedit.luatransform(pos1, pos2, param)\r
1054                 if err then\r
1055                         worldedit.player_notify(name, "code error: " .. err, false)\r
1056                 else\r
1057                         worldedit.player_notify(name, "code successfully executed", false)\r
1058                 end\r
1059         end,\r
1060 })\r
1061 \r
1062 if minetest.place_schematic then\r
1063 minetest.register_chatcommand("/mtschemcreate", {\r
1064         params = "<file>",\r
1065         description = "Save the current WorldEdit region using the Minetest Schematic format to \"(world folder)/schems/<filename>.mts\"",\r
1066         privs = {worldedit=true},\r
1067         func = function(name, param)\r
1068                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
1069                 if pos1 == nil or pos2 == nil then\r
1070                         worldedit.player_notify(name, "No region selected")\r
1071                         return\r
1072                 end\r
1073                 if param == nil then\r
1074                         worldedit.player_notify(name, "No filename specified")\r
1075                         return\r
1076                 end\r
1077 \r
1078                 local path = minetest.get_worldpath() .. "/schems"\r
1079                 local filename = path .. "/" .. param .. ".mts"\r
1080                 os.execute("mkdir \"" .. path .. "\"") --create directory if it does not already exist\r
1081 \r
1082                 local ret = minetest.create_schematic(pos1, pos2, worldedit.prob_list[name], filename)\r
1083                 if ret == nil then\r
1084                         worldedit.player_notify(name, "Failed to create Minetest schematic", false)\r
1085                 else\r
1086                         worldedit.player_notify(name, "Saved Minetest schematic to " .. param, false)\r
1087                 end\r
1088                 worldedit.prob_list[name] = {}\r
1089         end,\r
1090 })\r
1091 \r
1092 minetest.register_chatcommand("/mtschemplace", {\r
1093         params = "<file>",\r
1094         description = "Load nodes from \"(world folder)/schems/<file>.mts\" with position 1 of the current WorldEdit region as the origin",\r
1095         privs = {worldedit=true},\r
1096         func = function(name, param)\r
1097                 local pos = worldedit.pos1[name]\r
1098                 if pos == nil then\r
1099                         worldedit.player_notify(name, "No position selected")\r
1100                         return\r
1101                 end\r
1102                 if param == nil then\r
1103                         worldedit.player_notify(name, "No filename specified")\r
1104                         return\r
1105                 end\r
1106 \r
1107                 local path = minetest.get_worldpath() .. "/schems/" .. param .. ".mts"\r
1108                 if minetest.place_schematic(pos, path) == nil then\r
1109                         worldedit.player_notify(name, "Failed to place Minetest schematic", false)\r
1110                 else\r
1111                         worldedit.player_notify(name, "Placed Minetest schematic " .. param ..\r
1112                                 " at " .. minetest.pos_to_string(pos), false)\r
1113                 end\r
1114         end,\r
1115 })\r
1116 \r
1117 minetest.register_chatcommand("/mtschemprob", {\r
1118         params = "start/finish/get",\r
1119         description = "Begins node probability entry for Minetest schematics, gets the nodes that have probabilities set, or ends node probability entry",\r
1120         privs = {worldedit=true},\r
1121         func = function(name, param)\r
1122                 if param == "start" then --start probability setting\r
1123                         worldedit.set_pos[name] = "prob"\r
1124                         worldedit.prob_list[name] = {}\r
1125                         worldedit.player_notify(name, "select Minetest schematic probability values by punching nodes")\r
1126                 elseif param == "finish" then --finish probability setting\r
1127                         worldedit.set_pos[name] = nil\r
1128                         worldedit.player_notify(name, "finished Minetest schematic probability selection")\r
1129                 elseif param == "get" then --get all nodes that had probabilities set on them\r
1130                         local text = ""\r
1131                         local problist = worldedit.prob_list[name]\r
1132                         if problist == nil then\r
1133                                 return\r
1134                         end\r
1135                         for k,v in pairs(problist) do\r
1136                                 local prob = math.floor(((v["prob"] / 256) * 100) * 100 + 0.5) / 100\r
1137                                 text = text .. minetest.pos_to_string(v["pos"]) .. ": " .. prob .. "% | "\r
1138                         end\r
1139                         worldedit.player_notify(name, "Currently set node probabilities:")\r
1140                         worldedit.player_notify(name, text)\r
1141                 else\r
1142                         worldedit.player_notify(name, "unknown subcommand: " .. param)\r
1143                 end\r
1144         end,\r
1145 })\r
1146 \r
1147 minetest.register_on_player_receive_fields(\r
1148         function(player, formname, fields)\r
1149                 if (formname == "prob_val_enter") and (fields.text ~= "") then\r
1150                         local name = player:get_player_name()\r
1151                         local prob_entry = {pos=worldedit.prob_pos[name], prob=tonumber(fields.text)}\r
1152                         local index = table.getn(worldedit.prob_list[name]) + 1\r
1153                         worldedit.prob_list[name][index] = prob_entry\r
1154                 end\r
1155         end\r
1156 )\r
1157 end\r
1158 \r
1159 minetest.register_chatcommand("/clearobjects", {\r
1160         params = "",\r
1161         description = "Clears all objects within the WorldEdit region",\r
1162         privs = {worldedit=true},\r
1163         func = function(name, param)\r
1164                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
1165                 if pos1 == nil or pos2 == nil then\r
1166                         worldedit.player_notify(name, "no region selected")\r
1167                         return\r
1168                 end\r
1169 \r
1170                 local count = worldedit.clearobjects(pos1, pos2)\r
1171                 worldedit.player_notify(name, count .. " objects cleared")\r
1172         end,\r
1173 })\r