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