1 minetest.register_privilege("worldedit", "Can use WorldEdit commands")
\r
5 worldedit.set_pos = {}
\r
10 dofile(minetest.get_modpath("worldedit") .. "/functions.lua")
\r
11 dofile(minetest.get_modpath("worldedit") .. "/mark.lua")
\r
13 --determines whether `nodename` is a valid node name, returning a boolean
\r
14 worldedit.node_is_valid = function(temp_pos, nodename)
\r
15 return minetest.registered_nodes[nodename] ~= nil
\r
16 or minetest.registered_nodes["default:" .. nodename] ~= nil
\r
19 minetest.register_chatcommand("/reset", {
\r
21 description = "Reset the region so that it is empty",
\r
22 privs = {worldedit=true},
\r
23 func = function(name, param)
\r
24 worldedit.pos1[name] = nil
\r
25 worldedit.pos2[name] = nil
\r
26 worldedit.mark_pos1(name)
\r
27 worldedit.mark_pos2(name)
\r
28 minetest.chat_send_player(name, "WorldEdit region reset")
\r
32 minetest.register_chatcommand("/mark", {
\r
34 description = "Show markers at the region positions",
\r
35 privs = {worldedit=true},
\r
36 func = function(name, param)
\r
37 worldedit.mark_pos1(name)
\r
38 worldedit.mark_pos2(name)
\r
39 minetest.chat_send_player(name, "WorldEdit region marked")
\r
43 minetest.register_chatcommand("/pos1", {
\r
45 description = "Set WorldEdit region position 1 to the player's location",
\r
46 privs = {worldedit=true},
\r
47 func = function(name, param)
\r
48 local pos = minetest.env:get_player_by_name(name):getpos()
\r
49 pos.x, pos.y, pos.z = math.floor(pos.x), math.floor(pos.y), math.floor(pos.z)
\r
50 worldedit.pos1[name] = pos
\r
51 worldedit.mark_pos1(name)
\r
52 minetest.chat_send_player(name, "WorldEdit position 1 set to " .. minetest.pos_to_string(pos))
\r
56 minetest.register_chatcommand("/pos2", {
\r
58 description = "Set WorldEdit region position 2 to the player's location",
\r
59 privs = {worldedit=true},
\r
60 func = function(name, param)
\r
61 local pos = minetest.env:get_player_by_name(name):getpos()
\r
62 pos.x, pos.y, pos.z = math.floor(pos.x), math.floor(pos.y), math.floor(pos.z)
\r
63 worldedit.pos2[name] = pos
\r
64 worldedit.mark_pos2(name)
\r
65 minetest.chat_send_player(name, "WorldEdit position 2 set to " .. minetest.pos_to_string(pos))
\r
69 minetest.register_chatcommand("/p", {
\r
71 description = "Set WorldEdit region by punching two nodes, or display the current WorldEdit region",
\r
72 privs = {worldedit=true},
\r
73 func = function(name, param)
\r
74 if param == "set" then --set both WorldEdit positions
\r
75 worldedit.set_pos[name] = 1
\r
76 minetest.chat_send_player(name, "Select positions by punching two nodes")
\r
77 elseif param == "get" then --display current WorldEdit positions
\r
78 if worldedit.pos1[name] ~= nil then
\r
79 minetest.chat_send_player(name, "WorldEdit position 1: " .. minetest.pos_to_string(worldedit.pos1[name]))
\r
81 minetest.chat_send_player(name, "WorldEdit position 1 not set")
\r
83 if worldedit.pos2[name] ~= nil then
\r
84 minetest.chat_send_player(name, "WorldEdit position 2: " .. minetest.pos_to_string(worldedit.pos2[name]))
\r
86 minetest.chat_send_player(name, "WorldEdit position 2 not set")
\r
89 minetest.chat_send_player(name, "Unknown subcommand: " .. param)
\r
94 minetest.register_on_punchnode(function(pos, node, puncher)
\r
95 local name = puncher:get_player_name()
\r
96 if name ~= "" and worldedit.set_pos[name] ~= nil then --currently setting position
\r
97 if worldedit.set_pos[name] == 1 then --setting position 1
\r
98 worldedit.set_pos[name] = 2 --set position 2 on the next invocation
\r
99 worldedit.pos1[name] = pos
\r
100 worldedit.mark_pos1(name)
\r
101 minetest.chat_send_player(name, "WorldEdit region position 1 set to " .. minetest.pos_to_string(pos))
\r
102 else --setting position 2
\r
103 worldedit.set_pos[name] = nil --finished setting positions
\r
104 worldedit.pos2[name] = pos
\r
105 worldedit.mark_pos2(name)
\r
106 minetest.chat_send_player(name, "WorldEdit region position 2 set to " .. minetest.pos_to_string(pos))
\r
111 minetest.register_chatcommand("/volume", {
\r
113 description = "Display the volume of the current WorldEdit region",
\r
114 privs = {worldedit=true},
\r
115 func = function(name, param)
\r
116 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
117 if pos1 == nil or pos2 == nil then
\r
118 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
122 local volume = worldedit.volume(pos1, pos2)
\r
123 minetest.chat_send_player(name, "Current WorldEdit region has a volume of " .. volume .. " nodes (" .. pos2.x - pos1.x .. "*" .. pos2.y - pos1.y .. "*" .. pos2.z - pos1.z .. ")")
\r
127 minetest.register_chatcommand("/set", {
\r
129 description = "Set the current WorldEdit region to <node>",
\r
130 privs = {worldedit=true},
\r
131 func = function(name, param)
\r
132 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
133 if pos1 == nil or pos2 == nil then
\r
134 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
138 if param == "" or not worldedit.node_is_valid(pos1, param) then
\r
139 minetest.chat_send_player(name, "Invalid node name: " .. param)
\r
143 local count = worldedit.set(pos1, pos2, param)
\r
144 minetest.chat_send_player(name, count .. " nodes set")
\r
148 minetest.register_chatcommand("/replace", {
\r
149 params = "<search node> <replace node>",
\r
150 description = "Replace all instances of <search node> with <place node> in the current WorldEdit region",
\r
151 privs = {worldedit=true},
\r
152 func = function(name, param)
\r
153 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
154 if pos1 == nil or pos2 == nil then
\r
155 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
159 local found, _, searchnode, replacenode = param:find("^([^%s]+)%s+([^%s]+)$")
\r
160 if found == nil then
\r
161 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
164 if not worldedit.node_is_valid(pos1, searchnode) then
\r
165 minetest.chat_send_player(name, "Invalid search node name: " .. searchnode)
\r
168 if not worldedit.node_is_valid(pos1, replacenode) then
\r
169 minetest.chat_send_player(name, "Invalid replace node name: " .. replacenode)
\r
173 local count = worldedit.replace(pos1, pos2, searchnode, replacenode)
\r
174 minetest.chat_send_player(name, count .. " nodes replaced")
\r
178 minetest.register_chatcommand("/hollowcylinder", {
\r
179 params = "x/y/z <length> <radius> <node>",
\r
180 description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z axis with length <length> and radius <radius>, composed of <node>",
\r
181 privs = {worldedit=true},
\r
182 func = function(name, param)
\r
183 local pos = worldedit.pos1[name]
\r
185 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
189 local found, _, axis, length, radius, nodename = param:find("^([xyz])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$")
\r
190 if found == nil then
\r
191 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
194 if not worldedit.node_is_valid(pos, nodename) then
\r
195 minetest.chat_send_player(name, "Invalid node name: " .. param)
\r
199 local count = worldedit.hollow_cylinder(pos, axis, tonumber(length), tonumber(radius), nodename)
\r
200 minetest.chat_send_player(name, count .. " nodes added")
\r
204 minetest.register_chatcommand("/cylinder", {
\r
205 params = "x/y/z <length> <radius> <node>",
\r
206 description = "Add cylinder at WorldEdit position 1 along the x/y/z axis with length <length> and radius <radius>, composed of <node>",
\r
207 privs = {worldedit=true},
\r
208 func = function(name, param)
\r
209 local pos = worldedit.pos1[name]
\r
211 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
215 local found, _, axis, length, radius, nodename = param:find("^([xyz])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$")
\r
216 if found == nil then
\r
217 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
220 if not worldedit.node_is_valid(pos, nodename) then
\r
221 minetest.chat_send_player(name, "Invalid node name: " .. param)
\r
225 local count = worldedit.cylinder(pos, axis, tonumber(length), tonumber(radius), nodename)
\r
226 minetest.chat_send_player(name, count .. " nodes added")
\r
230 minetest.register_chatcommand("/copy", {
\r
231 params = "x/y/z <amount>",
\r
232 description = "Copy the current WorldEdit region along the x/y/z axis by <amount> nodes",
\r
233 privs = {worldedit=true},
\r
234 func = function(name, param)
\r
235 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
236 if pos1 == nil or pos2 == nil then
\r
237 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
241 local found, _, axis, amount = param:find("^([xyz])%s+([+-]?%d+)$")
\r
242 if found == nil then
\r
243 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
247 local count = worldedit.copy(pos1, pos2, axis, tonumber(amount))
\r
248 minetest.chat_send_player(name, count .. " nodes copied")
\r
252 minetest.register_chatcommand("/move", {
\r
253 params = "x/y/z <amount>",
\r
254 description = "Move the current WorldEdit region along the x/y/z axis by <amount> nodes",
\r
255 privs = {worldedit=true},
\r
256 func = function(name, param)
\r
257 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
258 if pos1 == nil or pos2 == nil then
\r
259 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
263 local found, _, axis, amount = param:find("^([xyz])%s+([+-]?%d+)$")
\r
264 if found == nil then
\r
265 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
269 local count = worldedit.move(pos1, pos2, axis, tonumber(amount))
\r
270 minetest.chat_send_player(name, count .. " nodes moved")
\r
274 minetest.register_chatcommand("/stack", {
\r
275 params = "x/y/z <count>",
\r
276 description = "Stack the current WorldEdit region along the x/y/z axis <count> times",
\r
277 privs = {worldedit=true},
\r
278 func = function(name, param)
\r
279 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
280 if pos1 == nil or pos2 == nil then
\r
281 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
285 local found, _, axis, count = param:find("^([xyz])%s+([+-]?%d+)$")
\r
286 if found == nil then
\r
287 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
291 local count = worldedit.stack(pos1, pos2, axis, tonumber(count))
\r
292 minetest.chat_send_player(name, count .. " nodes stacked")
\r
296 minetest.register_chatcommand("/transpose", {
\r
297 params = "x/y/z x/y/z",
\r
298 description = "Transpose the current WorldEdit region along the x/y/z and x/y/z axes",
\r
299 privs = {worldedit=true},
\r
300 func = function(name, param)
\r
301 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
302 if pos1 == nil or pos2 == nil then
\r
303 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
307 local found, _, axis1, axis2 = param:find("^([xyz])%s+([xyz])$")
\r
308 if found == nil then
\r
309 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
312 if axis1 == axis2 then
\r
313 minetest.chat_send_player(name, "Invalid usage: axes are the same")
\r
317 local count = worldedit.transpose(pos1, pos2, axis1, axis2)
\r
318 minetest.chat_send_player(name, count .. " nodes transposed")
\r
322 minetest.register_chatcommand("/flip", {
\r
324 description = "Flip the current WorldEdit region along the x/y/z axis",
\r
325 privs = {worldedit=true},
\r
326 func = function(name, param)
\r
327 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
328 if pos1 == nil or pos2 == nil then
\r
329 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
333 if param ~= "x" and param ~= "y" and param ~= "z" then
\r
334 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
338 local count = worldedit.flip(pos1, pos2, param)
\r
339 minetest.chat_send_player(name, count .. " nodes flipped")
\r
343 minetest.register_chatcommand("/rotate", {
\r
344 params = "<angle>",
\r
345 description = "Rotate the current WorldEdit region around the y axis by angle <angle> (90 degree increment)",
\r
346 privs = {worldedit=true},
\r
347 func = function(name, param)
\r
348 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
349 if pos1 == nil or pos2 == nil then
\r
350 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
354 angle = tonumber(param)
\r
355 if angle == nil then
\r
356 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
359 if angle % 90 ~= 0 then
\r
360 minetest.chat_send_player(name, "Invalid usage: angle must be multiple of 90")
\r
364 local count = worldedit.rotate(pos1, pos2, angle)
\r
365 minetest.chat_send_player(name, count .. " nodes rotated")
\r
369 minetest.register_chatcommand("/dig", {
\r
371 description = "Dig the current WorldEdit region",
\r
372 privs = {worldedit=true},
\r
373 func = function(name, param)
\r
374 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
375 if pos1 == nil or pos2 == nil then
\r
376 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
380 local count = worldedit.dig(pos1, pos2)
\r
381 minetest.chat_send_player(name, count .. " nodes dug")
\r
385 minetest.register_chatcommand("/save", {
\r
387 description = "Save the current WorldEdit region to \"(world folder)/schems/<file>.we\"",
\r
388 privs = {worldedit=true},
\r
389 func = function(name, param)
\r
390 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
\r
391 if pos1 == nil or pos2 == nil then
\r
392 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
396 if param == "" then
\r
397 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
401 local result, count = worldedit.serialize(pos1, pos2)
\r
403 local path = minetest.get_worldpath() .. "/schems"
\r
404 local filename = path .. "/" .. param .. ".we"
\r
405 os.execute("mkdir \"" .. path .. "\"") --create directory if it does not already exist
\r
406 local file, err = io.open(filename, "wb")
\r
408 minetest.chat_send_player(name, "Could not save file to \"" .. filename .. "\"")
\r
415 minetest.chat_send_player(name, count .. " nodes saved")
\r
419 minetest.register_chatcommand("/load", {
\r
421 description = "Load nodes from \"(world folder)/schems/<file>.we\" with position 1 of the current WorldEdit region as the origin",
\r
422 privs = {worldedit=true},
\r
423 func = function(name, param)
\r
424 local pos1 = worldedit.pos1[name]
\r
425 if pos1 == nil then
\r
426 minetest.chat_send_player(name, "No WorldEdit region selected")
\r
430 if param == "" then
\r
431 minetest.chat_send_player(name, "Invalid usage: " .. param)
\r
435 local filename = minetest.get_worldpath() .. "/schems/" .. param .. ".we"
\r
436 local file, err = io.open(filename, "rb")
\r
438 minetest.chat_send_player(name, "Could not open file \"" .. filename .. "\"")
\r
441 local value = file:read("*a")
\r
445 if value:find("{") then --old WorldEdit format
\r
446 count = worldedit.deserialize_old(pos1, value)
\r
447 else --new WorldEdit format
\r
448 count = worldedit.deserialize(pos1, value)
\r
451 minetest.chat_send_player(name, count .. " nodes loaded")
\r