]> git.lizzy.rs Git - worldedit.git/blob - init.lua
Add //mark command and document it.
[worldedit.git] / init.lua
1 minetest.register_privilege("worldedit", "Can use WorldEdit commands")\r
2 \r
3 worldedit = {}\r
4 \r
5 worldedit.set_pos = {}\r
6 \r
7 worldedit.pos1 = {}\r
8 worldedit.pos2 = {}\r
9 \r
10 dofile(minetest.get_modpath("worldedit") .. "/functions.lua")\r
11 dofile(minetest.get_modpath("worldedit") .. "/mark.lua")\r
12 \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         local originalnode = minetest.env:get_node(temp_pos) --save the original node to restore later\r
16         minetest.env:add_node(temp_pos, {name=nodename}) --attempt to add the node\r
17         local value = minetest.env:get_node(temp_pos).name --obtain the name of the newly added node\r
18         if value == nodename or value == "default:" .. nodename then --successfully added node\r
19                 minetest.env:add_node(temp_pos, originalnode) --restore the original node\r
20                 return true --node is valid\r
21         end\r
22         return false --node is not valid\r
23 end\r
24 \r
25 minetest.register_chatcommand("/reset", {\r
26         params = "",\r
27         description = "Reset the region so that it is empty",\r
28         privs = {worldedit=true},\r
29         func = function(name, param)\r
30                 worldedit.pos1[name] = nil\r
31                 worldedit.pos2[name] = nil\r
32                 worldedit.mark_pos1(name)\r
33                 worldedit.mark_pos2(name)\r
34                 minetest.chat_send_player(name, "WorldEdit region reset")\r
35         end,\r
36 })\r
37 \r
38 minetest.register_chatcommand("/mark", {\r
39         params = "",\r
40         description = "Show markers at the region positions",\r
41         privs = {worldedit=true},\r
42         func = function(name, param)\r
43                 worldedit.mark_pos1(name)\r
44                 worldedit.mark_pos2(name)\r
45                 minetest.chat_send_player(name, "WorldEdit region marked")\r
46         end,\r
47 })\r
48 \r
49 minetest.register_chatcommand("/pos1", {\r
50         params = "",\r
51         description = "Set WorldEdit region position 1 to the player's location",\r
52         privs = {worldedit=true},\r
53         func = function(name, param)\r
54                 local pos = minetest.env:get_player_by_name(name):getpos()\r
55                 pos.x, pos.y, pos.z = math.floor(pos.x), math.floor(pos.y), math.floor(pos.z)\r
56                 worldedit.pos1[name] = pos\r
57                 worldedit.mark_pos1(name)\r
58                 minetest.chat_send_player(name, "WorldEdit position 1 set to " .. minetest.pos_to_string(pos))\r
59         end,\r
60 })\r
61 \r
62 minetest.register_chatcommand("/pos2", {\r
63         params = "",\r
64         description = "Set WorldEdit region position 2 to the player's location",\r
65         privs = {worldedit=true},\r
66         func = function(name, param)\r
67                 local pos = minetest.env:get_player_by_name(name):getpos()\r
68                 pos.x, pos.y, pos.z = math.floor(pos.x), math.floor(pos.y), math.floor(pos.z)\r
69                 worldedit.pos2[name] = pos\r
70                 worldedit.mark_pos2(name)\r
71                 minetest.chat_send_player(name, "WorldEdit position 2 set to " .. minetest.pos_to_string(pos))\r
72         end,\r
73 })\r
74 \r
75 minetest.register_chatcommand("/p", {\r
76         params = "set/get",\r
77         description = "Set WorldEdit region by punching two nodes, or display the current WorldEdit region",\r
78         privs = {worldedit=true},\r
79         func = function(name, param)\r
80                 if param == "set" then --set both WorldEdit positions\r
81                         worldedit.set_pos[name] = 1\r
82                         minetest.chat_send_player(name, "Select positions by punching two nodes")\r
83                 elseif param == "get" then --display current WorldEdit positions\r
84                         if worldedit.pos1[name] ~= nil then\r
85                                 minetest.chat_send_player(name, "WorldEdit position 1: " .. minetest.pos_to_string(worldedit.pos1[name]))\r
86                         else\r
87                                 minetest.chat_send_player(name, "WorldEdit position 1 not set")\r
88                         end\r
89                         if worldedit.pos2[name] ~= nil then\r
90                                 minetest.chat_send_player(name, "WorldEdit position 2: " .. minetest.pos_to_string(worldedit.pos2[name]))\r
91                         else\r
92                                 minetest.chat_send_player(name, "WorldEdit position 2 not set")\r
93                         end\r
94                 else\r
95                         minetest.chat_send_player(name, "Unknown subcommand: " .. param)\r
96                 end\r
97         end,\r
98 })\r
99 \r
100 minetest.register_on_punchnode(function(pos, node, puncher)\r
101         local name = puncher:get_player_name()\r
102         if name ~= "" and worldedit.set_pos[name] ~= nil then --currently setting position\r
103                 if worldedit.set_pos[name] == 1 then --setting position 1\r
104                         worldedit.set_pos[name] = 2 --set position 2 on the next invocation\r
105                         worldedit.pos1[name] = pos\r
106                         worldedit.mark_pos1(name)\r
107                         minetest.chat_send_player(name, "WorldEdit region position 1 set to " .. minetest.pos_to_string(pos))\r
108                 else --setting position 2\r
109                         worldedit.set_pos[name] = nil --finished setting positions\r
110                         worldedit.pos2[name] = pos\r
111                         worldedit.mark_pos2(name)\r
112                         minetest.chat_send_player(name, "WorldEdit region position 2 set to " .. minetest.pos_to_string(pos))\r
113                 end\r
114         end\r
115 end)\r
116 \r
117 minetest.register_chatcommand("/volume", {\r
118         params = "",\r
119         description = "Display the volume of the current WorldEdit region",\r
120         privs = {worldedit=true},\r
121         func = function(name, param)\r
122                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
123                 if pos1 == nil or pos2 == nil then\r
124                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
125                         return\r
126                 end\r
127 \r
128                 local volume = worldedit.volume(pos1, pos2)\r
129                 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
130         end,\r
131 })\r
132 \r
133 minetest.register_chatcommand("/set", {\r
134         params = "<node>",\r
135         description = "Set the current WorldEdit region to <node>",\r
136         privs = {worldedit=true},\r
137         func = function(name, param)\r
138                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
139                 if pos1 == nil or pos2 == nil then\r
140                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
141                         return\r
142                 end\r
143 \r
144                 if param == "" or not worldedit.node_is_valid(pos1, param) then\r
145                         minetest.chat_send_player(name, "Invalid node name: " .. param)\r
146                         return\r
147                 end\r
148 \r
149                 local count = worldedit.set(pos1, pos2, param)\r
150                 minetest.chat_send_player(name, count .. " nodes set")\r
151         end,\r
152 })\r
153 \r
154 minetest.register_chatcommand("/replace", {\r
155         params = "<search node> <replace node>",\r
156         description = "Replace all instances of <search node> with <place node> in the current WorldEdit region",\r
157         privs = {worldedit=true},\r
158         func = function(name, param)\r
159                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
160                 if pos1 == nil or pos2 == nil then\r
161                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
162                         return\r
163                 end\r
164 \r
165                 local found, _, searchnode, replacenode = param:find("([^%s]+)%s+([^%s]+)")\r
166                 if found == nil then\r
167                         minetest.chat_send_player(name, "Invalid usage: " .. param)\r
168                         return\r
169                 end\r
170                 if not worldedit.node_is_valid(pos1, searchnode) then\r
171                         minetest.chat_send_player(name, "Invalid search node name: " .. searchnode)\r
172                         return\r
173                 end\r
174                 if not worldedit.node_is_valid(pos1, replacenode) then\r
175                         minetest.chat_send_player(name, "Invalid replace node name: " .. replacenode)\r
176                         return\r
177                 end\r
178 \r
179                 local count = worldedit.replace(pos1, pos2, searchnode, replacenode)\r
180                 minetest.chat_send_player(name, count .. " nodes replaced")\r
181         end,\r
182 })\r
183 \r
184 minetest.register_chatcommand("/copy", {\r
185         params = "x/y/z <amount>",\r
186         description = "Copy the current WorldEdit region along the x/y/z axis by <amount> nodes",\r
187         privs = {worldedit=true},\r
188         func = function(name, param)\r
189                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
190                 if pos1 == nil or pos2 == nil then\r
191                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
192                         return\r
193                 end\r
194 \r
195                 local found, _, axis, amount = param:find("([xyz])%s+([+-]?%d+)")\r
196                 if found == nil then\r
197                         minetest.chat_send_player(name, "Invalid usage: " .. param)\r
198                         return\r
199                 end\r
200 \r
201                 local count = worldedit.copy(pos1, pos2, axis, tonumber(amount))\r
202                 minetest.chat_send_player(name, count .. " nodes copied")\r
203         end,\r
204 })\r
205 \r
206 minetest.register_chatcommand("/move", {\r
207         params = "x/y/z <amount>",\r
208         description = "Move the current WorldEdit region along the x/y/z axis by <amount> nodes",\r
209         privs = {worldedit=true},\r
210         func = function(name, param)\r
211                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
212                 if pos1 == nil or pos2 == nil then\r
213                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
214                         return\r
215                 end\r
216 \r
217                 local found, _, axis, amount = param:find("([xyz])%s+([+-]?%d+)")\r
218                 if found == nil then\r
219                         minetest.chat_send_player(name, "Invalid usage: " .. param)\r
220                         return\r
221                 end\r
222 \r
223                 local count = worldedit.move(pos1, pos2, axis, tonumber(amount))\r
224                 minetest.chat_send_player(name, count .. " nodes moved")\r
225         end,\r
226 })\r
227 \r
228 minetest.register_chatcommand("/stack", {\r
229         params = "x/y/z <count>",\r
230         description = "Stack the current WorldEdit region along the x/y/z axis <count> times",\r
231         privs = {worldedit=true},\r
232         func = function(name, param)\r
233                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
234                 if pos1 == nil or pos2 == nil then\r
235                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
236                         return\r
237                 end\r
238 \r
239                 local found, _, axis, count = param:find("([xyz])%s+([+-]?%d+)")\r
240                 if found == nil then\r
241                         minetest.chat_send_player(name, "Invalid usage: " .. param)\r
242                         return\r
243                 end\r
244 \r
245                 local count = worldedit.stack(pos1, pos2, axis, tonumber(count))\r
246                 minetest.chat_send_player(name, count .. " nodes stacked")\r
247         end,\r
248 })\r
249 \r
250 minetest.register_chatcommand("/dig", {\r
251         params = "",\r
252         description = "Dig the current WorldEdit region",\r
253         privs = {worldedit=true},\r
254         func = function(name, param)\r
255                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
256                 if pos1 == nil or pos2 == nil then\r
257                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
258                         return\r
259                 end\r
260 \r
261                 local count = worldedit.dig(pos1, pos2)\r
262                 minetest.chat_send_player(name, count .. " nodes dug")\r
263         end,\r
264 })\r
265 \r
266 minetest.register_chatcommand("/save", {\r
267         params = "<file>",\r
268         description = "Save the current WorldEdit region to \"(world folder)/schems/<file>.we\"",\r
269         privs = {worldedit=true},\r
270         func = function(name, param)\r
271                 local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]\r
272                 if pos1 == nil or pos2 == nil then\r
273                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
274                         return\r
275                 end\r
276 \r
277                 if param == "" then\r
278                         minetest.chat_send_player(name, "Invalid usage: " .. param)\r
279                         return\r
280                 end\r
281 \r
282                 local result, count = worldedit.serialize(pos1, pos2)\r
283 \r
284                 local path = minetest.get_worldpath() .. "/schems"\r
285                 local filename = path .. "/" .. param .. ".we"\r
286                 os.execute("mkdir \"" .. path .. "\"") --create directory if it does not already exist\r
287                 local file, err = io.open(filename, "wb")\r
288                 if err ~= nil then\r
289                         minetest.chat_send_player(name, "Could not save file to \"" .. filename .. "\"")\r
290                         return\r
291                 end\r
292                 file:write(result)\r
293                 file:flush()\r
294                 file:close()\r
295 \r
296                 minetest.chat_send_player(name, count .. " nodes saved")\r
297         end,\r
298 })\r
299 \r
300 minetest.register_chatcommand("/load", {\r
301         params = "<file>",\r
302         description = "Load nodes from \"(world folder)/schems/<file>.we\" with position 1 of the current WorldEdit region as the origin",\r
303         privs = {worldedit=true},\r
304         func = function(name, param)\r
305                 local pos1 = worldedit.pos1[name]\r
306                 if pos1 == nil then\r
307                         minetest.chat_send_player(name, "No WorldEdit region selected")\r
308                         return\r
309                 end\r
310 \r
311                 if param == "" then\r
312                         minetest.chat_send_player(name, "Invalid usage: " .. param)\r
313                         return\r
314                 end\r
315 \r
316                 local filename = minetest.get_worldpath() .. "/schems/" .. param .. ".we"\r
317                 local file, err = io.open(filename, "rb")\r
318                 if err ~= nil then\r
319                         minetest.chat_send_player(name, "Could not open file \"" .. filename .. "\"")\r
320                         return\r
321                 end\r
322                 local value = file:read("*a")\r
323                 file:close()\r
324 \r
325                 local count\r
326                 if value:find("{") then --old WorldEdit format\r
327                         count = worldedit.deserialize_old(pos1, value)\r
328                 else --new WorldEdit format\r
329                         count = worldedit.deserialize(pos1, value)\r
330                 end\r
331 \r
332                 minetest.chat_send_player(name, count .. " nodes loaded")\r
333         end,\r
334 })