]> git.lizzy.rs Git - worldedit.git/blob - functions.lua
00f73fc16b0e9e55e40f7041aca4498d3049e759
[worldedit.git] / functions.lua
1 --modifies positions `pos1` and `pos2` so that each component of `pos1` is less than or equal to its corresponding conent of `pos2`, returning two new positions\r
2 worldedit.sort_pos = function(pos1, pos2)\r
3         pos1 = {x=pos1.x, y=pos1.y, z=pos1.z}\r
4         pos2 = {x=pos2.x, y=pos2.y, z=pos2.z}\r
5         if pos1.x > pos2.x then\r
6                 pos2.x, pos1.x = pos1.x, pos2.x\r
7         end\r
8         if pos1.y > pos2.y then\r
9                 pos2.y, pos1.y = pos1.y, pos2.y\r
10         end\r
11         if pos1.z > pos2.z then\r
12                 pos2.z, pos1.z = pos1.z, pos2.z\r
13         end\r
14         return pos1, pos2\r
15 end\r
16 \r
17 --determines the volume of the region defined by positions `pos1` and `pos2`, returning the volume\r
18 worldedit.volume = function(pos1, pos2)\r
19         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
20         return (pos2.x - pos1.x + 1) * (pos2.y - pos1.y + 1) * (pos2.z - pos1.z + 1)\r
21 end\r
22 \r
23 --sets a region defined by positions `pos1` and `pos2` to `nodename`, returning the number of nodes filled\r
24 worldedit.set = function(pos1, pos2, nodename)\r
25         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
26         local env = minetest.env\r
27 \r
28         local node = {name=nodename}\r
29         local pos = {x=pos1.x, y=0, z=0}\r
30         while pos.x <= pos2.x do\r
31                 pos.y = pos1.y\r
32                 while pos.y <= pos2.y do\r
33                         pos.z = pos1.z\r
34                         while pos.z <= pos2.z do\r
35                                 env:add_node(pos, node)\r
36                                 pos.z = pos.z + 1\r
37                         end\r
38                         pos.y = pos.y + 1\r
39                 end\r
40                 pos.x = pos.x + 1\r
41         end\r
42         return worldedit.volume(pos1, pos2)\r
43 end\r
44 \r
45 --replaces all instances of `searchnode` with `replacenode` in a region defined by positions `pos1` and `pos2`, returning the number of nodes replaced\r
46 worldedit.replace = function(pos1, pos2, searchnode, replacenode)\r
47         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
48         local env = minetest.env\r
49 \r
50         if minetest.registered_nodes[searchnode] == nil then\r
51                 searchnode = "default:" .. searchnode\r
52         end\r
53     if minetest.registered_nodes[replacenode] == nil then\r
54                 replacenode = "default:" .. replacenode\r
55         end\r
56 \r
57         local pos = {x=pos1.x, y=0, z=0}\r
58         local node = {name=replacenode}\r
59         local count = 0\r
60         while pos.x <= pos2.x do\r
61                 pos.y = pos1.y\r
62                 while pos.y <= pos2.y do\r
63                         pos.z = pos1.z\r
64                         while pos.z <= pos2.z do\r
65                                 if env:get_node(pos).name == searchnode then\r
66                                         env:add_node(pos, node)\r
67                                         count = count + 1\r
68                                 end\r
69                                 pos.z = pos.z + 1\r
70                         end\r
71                         pos.y = pos.y + 1\r
72                 end\r
73                 pos.x = pos.x + 1\r
74         end\r
75         return count\r
76 end\r
77 \r
78 --adds a hollow cylinder at `pos` along the `axis` axis ("x" or "y" or "z") with length `length` and radius `radius`, returning the number of nodes added\r
79 worldedit.hollow_cylinder = function(pos, axis, length, radius, nodename)\r
80         local other1, other2\r
81         if axis == "x" then\r
82                 other1, other2 = "y", "z"\r
83         elseif axis == "y" then\r
84                 other1, other2 = "x", "z"\r
85         else --axis == "z"\r
86                 other1, other2 = "x", "y"\r
87         end\r
88 \r
89         local env = minetest.env\r
90         local currentpos = {x=pos.x, y=pos.y, z=pos.z}\r
91         local node = {name=nodename}\r
92         local count = 0\r
93         for i = 1, length do\r
94                 local offset1, offset2 = 0, radius\r
95                 local delta = -radius\r
96                 while offset1 <= offset2 do\r
97                         --add node at each octant\r
98                         local first1, first2 = pos[other1] + offset1, pos[other1] - offset1\r
99                         local second1, second2 = pos[other2] + offset2, pos[other2] - offset2\r
100                         currentpos[other1], currentpos[other2] = first1, second1\r
101                         env:add_node(currentpos, node) --octant 1\r
102                         currentpos[other1] = first2\r
103                         env:add_node(currentpos, node) --octant 4\r
104                         currentpos[other2] = second2\r
105                         env:add_node(currentpos, node) --octant 5\r
106                         currentpos[other1] = first1\r
107                         env:add_node(currentpos, node) --octant 8\r
108                         local first1, first2 = pos[other1] + offset2, pos[other1] - offset2\r
109                         local second1, second2 = pos[other2] + offset1, pos[other2] - offset1\r
110                         currentpos[other1], currentpos[other2] = first1, second1\r
111                         env:add_node(currentpos, node) --octant 2\r
112                         currentpos[other1] = first2\r
113                         env:add_node(currentpos, node) --octant 3\r
114                         currentpos[other2] = second2\r
115                         env:add_node(currentpos, node) --octant 6\r
116                         currentpos[other1] = first1\r
117                         env:add_node(currentpos, node) --octant 7\r
118 \r
119                         count = count + 8 --wip: broken\r
120 \r
121                         --move to next location\r
122                         delta = delta + (offset1 * 2) + 1\r
123                         if delta >= 0 then\r
124                                 offset2 = offset2 - 1\r
125                                 delta = delta - (offset2 * 2)\r
126                         end\r
127                         offset1 = offset1 + 1\r
128                 end\r
129                 currentpos[axis] = currentpos[axis] + 1\r
130         end\r
131         return count\r
132 end\r
133 \r
134 --adds a cylinder at `pos` along the `axis` axis ("x" or "y" or "z") with length `length` and radius `radius`, returning the number of nodes added\r
135 worldedit.cylinder = function(pos, axis, length, radius, nodename)\r
136         local other1, other2\r
137         if axis == "x" then\r
138                 other1, other2 = "y", "z"\r
139         elseif axis == "y" then\r
140                 other1, other2 = "x", "z"\r
141         else --axis == "z"\r
142                 other1, other2 = "x", "y"\r
143         end\r
144 \r
145         local env = minetest.env\r
146         local currentpos = {x=pos.x, y=pos.y, z=pos.z}\r
147         local node = {name=nodename}\r
148         local count = 0\r
149         for i = 1, length do\r
150                 local offset1, offset2 = 0, radius\r
151                 local delta = -radius\r
152                 while offset1 <= offset2 do\r
153                         --connect each pair of octants\r
154                         currentpos[other1] = pos[other1] - offset1\r
155                         local second1, second2 = pos[other2] + offset2, pos[other2] - offset2\r
156                         for i = 0, offset1 * 2 do\r
157                                 currentpos[other2] = second1\r
158                                 env:add_node(currentpos, node) --octant 1 to 4\r
159                                 currentpos[other2] = second2\r
160                                 env:add_node(currentpos, node) --octant 5 to 8\r
161                                 currentpos[other1] = currentpos[other1] + 1\r
162                         end\r
163                         currentpos[other1] = pos[other1] - offset2\r
164                         local second1, second2 = pos[other2] + offset1, pos[other2] - offset1\r
165                         for i = 0, offset2 * 2 do\r
166                                 currentpos[other2] = second1\r
167                                 env:add_node(currentpos, node) --octant 2 to 3\r
168                                 currentpos[other2] = second2\r
169                                 env:add_node(currentpos, node) --octant 6 to 7\r
170                                 currentpos[other1] = currentpos[other1] + 1\r
171                         end\r
172 \r
173                         count = count + (offset1 * 4) + (offset2 * 4) + 4 --wip: broken\r
174 \r
175                         --move to next location\r
176                         delta = delta + (offset1 * 2) + 1\r
177                         offset1 = offset1 + 1\r
178                         if delta >= 0 then\r
179                                 offset2 = offset2 - 1\r
180                                 delta = delta - (offset2 * 2)\r
181                         end\r
182                 end\r
183                 currentpos[axis] = currentpos[axis] + 1\r
184         end\r
185         return count\r
186 end\r
187 \r
188 --adds a spiral at `pos` with size `size`, returning the number of nodes changed\r
189 worldedit.spiral = function(pos, size, nodename)\r
190         local shift_x, shift_y\r
191         sa = spiralt(size)\r
192         shift_y = #sa -- "Height" of the Array\r
193         local fe = sa[1]\r
194         shift_x = #fe -- "Width" of the Array\r
195         fe = nil\r
196 \r
197         local count = 0\r
198         local node = {name=nodename}\r
199         for x, v in ipairs(sa) do\r
200                 for y, z in ipairs(v) do\r
201                         minetest.env:add_node({x=pos.x - shift_x + x,y=pos.y - shift_y + y,z=pos.z + z}, node)\r
202                         count = count + 1\r
203                 end\r
204         end\r
205         return count\r
206 end\r
207 \r
208 --wip: \r
209 sign = function(s)\r
210         if s > 0 then\r
211                 return 1\r
212         end\r
213         if s < 0 then\r
214                 return -1\r
215         end\r
216         return 0\r
217 end\r
218 \r
219 --wip: needs to be faster\r
220 function spiral_index(y, x) -- returns the value at (x, y) in a spiral that starts at 1 and goes outwards\r
221         if y == -x and y >= x then\r
222                 return (2 * y + 1) ^ 2\r
223         end\r
224         local l = math.max(math.abs(y), math.abs(x))\r
225         local value\r
226         if math.abs(y) == l then\r
227                 value = x\r
228                 if y < 0 then\r
229                         value = -value\r
230                 end\r
231         else\r
232                 value = y\r
233                 if x < 0 then\r
234                         value = -value\r
235                 end\r
236         end\r
237         t1 = l * 2\r
238         if x + y < 0 then\r
239                 t1 = -t1\r
240         end\r
241         t2 = y ^ 2 - x ^ 2\r
242         if t2 < 0 then\r
243                 t2 = -t2\r
244         end\r
245         return ((2 * l - 1) ^ 2) + (l * 4) + t1 + (t2 * (l - value))\r
246 end\r
247 \r
248 --wip: needs to be faster\r
249 function spiralt(side)\r
250         local spiral = {}\r
251         local start, stop = math.floor((-side+1)/2), math.floor((side-1)/2)\r
252         for i = 1, side do\r
253                 spiral[i] = {}\r
254                 for j = 1, side do\r
255                         spiral[i][j] = side ^ 2 - spiral_index(stop - i + 1,start + j - 1) --moves the coordinates so (0,0) is at the center of the spiral\r
256                 end\r
257         end\r
258         return spiral\r
259 end\r
260 \r
261 --copies the region defined by positions `pos1` and `pos2` along the `axis` axis ("x" or "y" or "z") by `amount` nodes, returning the number of nodes copied\r
262 worldedit.copy = function(pos1, pos2, axis, amount)\r
263         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
264         local env = minetest.env\r
265 \r
266         if amount < 0 then\r
267                 local pos = {x=pos1.x, y=0, z=0}\r
268                 while pos.x <= pos2.x do\r
269                         pos.y = pos1.y\r
270                         while pos.y <= pos2.y do\r
271                                 pos.z = pos1.z\r
272                                 while pos.z <= pos2.z do\r
273                                         local node = env:get_node(pos)\r
274                                         local meta1 = env:get_meta(pos):to_table()\r
275                                         local value = pos[axis]\r
276                                         pos[axis] = value + amount\r
277                                         env:add_node(pos, node)\r
278                                         local meta2 = env:get_meta(pos)\r
279                                         meta2:from_table(meta1)\r
280                                         pos[axis] = value\r
281                                         pos.z = pos.z + 1\r
282                                 end\r
283                                 pos.y = pos.y + 1\r
284                         end\r
285                         pos.x = pos.x + 1\r
286                 end\r
287         else\r
288                 local pos = {x=pos2.x, y=0, z=0}\r
289                 while pos.x >= pos1.x do\r
290                         pos.y = pos2.y\r
291                         while pos.y >= pos1.y do\r
292                                 pos.z = pos2.z\r
293                                 while pos.z >= pos1.z do\r
294                                         local node = minetest.env:get_node(pos)\r
295                                         local meta1 = env:get_meta(pos):to_table()\r
296                                         local value = pos[axis]\r
297                                         pos[axis] = value + amount\r
298                                         minetest.env:add_node(pos, node)\r
299                                         local meta2 = env:get_meta(pos)\r
300                                         meta2:from_table(meta1)\r
301                                         pos[axis] = value\r
302                                         pos.z = pos.z - 1\r
303                                 end\r
304                                 pos.y = pos.y - 1\r
305                         end\r
306                         pos.x = pos.x - 1\r
307                 end\r
308         end\r
309         return worldedit.volume(pos1, pos2)\r
310 end\r
311 \r
312 --moves the region defined by positions `pos1` and `pos2` along the `axis` axis ("x" or "y" or "z") by `amount` nodes, returning the number of nodes moved\r
313 worldedit.move = function(pos1, pos2, axis, amount)\r
314         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
315         local env = minetest.env\r
316 \r
317         if amount < 0 then\r
318                 local pos = {x=pos1.x, y=0, z=0}\r
319                 while pos.x <= pos2.x do\r
320                         pos.y = pos1.y\r
321                         while pos.y <= pos2.y do\r
322                                 pos.z = pos1.z\r
323                                 while pos.z <= pos2.z do\r
324                                         local node = env:get_node(pos)\r
325                                         local meta1 = env:get_meta(pos):to_table()\r
326                                         env:remove_node(pos)\r
327                                         local value = pos[axis]\r
328                                         pos[axis] = value + amount\r
329                                         env:add_node(pos, node)\r
330                                         local meta2 = env:get_meta(pos)\r
331                                         meta2:from_table(meta1)\r
332                                         pos[axis] = value\r
333                                         pos.z = pos.z + 1\r
334                                 end\r
335                                 pos.y = pos.y + 1\r
336                         end\r
337                         pos.x = pos.x + 1\r
338                 end\r
339         else\r
340                 local pos = {x=pos2.x, y=0, z=0}\r
341                 while pos.x >= pos1.x do\r
342                         pos.y = pos2.y\r
343                         while pos.y >= pos1.y do\r
344                                 pos.z = pos2.z\r
345                                 while pos.z >= pos1.z do\r
346                                         local node = env:get_node(pos)\r
347                                         local meta1 = env:get_meta(pos):to_table()\r
348                                         env:remove_node(pos)\r
349                                         local value = pos[axis]\r
350                                         pos[axis] = value + amount\r
351                                         env:add_node(pos, node)\r
352                                         local meta2 = env:get_meta(pos)\r
353                                         meta2:from_table(meta1)\r
354                                         pos[axis] = value\r
355                                         pos.z = pos.z - 1\r
356                                 end\r
357                                 pos.y = pos.y - 1\r
358                         end\r
359                         pos.x = pos.x - 1\r
360                 end\r
361         end\r
362         return worldedit.volume(pos1, pos2)\r
363 end\r
364 \r
365 --duplicates the region defined by positions `pos1` and `pos2` along the `axis` axis ("x" or "y" or "z") `count` times, returning the number of nodes stacked\r
366 worldedit.stack = function(pos1, pos2, axis, count)\r
367         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
368         local length = pos2[axis] - pos1[axis] + 1\r
369         local amount = 0\r
370         local copy = worldedit.copy\r
371         if count < 0 then\r
372                 count = -count\r
373                 length = -length\r
374         end\r
375         for i = 1, count do\r
376                 amount = amount + length\r
377                 copy(pos1, pos2, axis, amount)\r
378         end\r
379         return worldedit.volume(pos1, pos2)\r
380 end\r
381 \r
382 --transposes a region defined by the positions `pos1` and `pos2` between the `axis1` and `axis2` axes, returning the number of nodes transposed\r
383 worldedit.transpose = function(pos1, pos2, axis1, axis2)\r
384         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
385 \r
386         local pos = {x=pos1.x, y=0, z=0}\r
387         local env = minetest.env\r
388         while pos.x <= pos2.x do\r
389                 pos.y = pos1.y\r
390                 while pos.y <= pos2.y do\r
391                         pos.z = pos1.z\r
392                         while pos.z <= pos2.z do\r
393                                 local extent1, extent2 = pos[axis1] - pos1[axis1], pos[axis2] - pos1[axis2]\r
394                                 if extent1 < extent2 then\r
395                                         local node1 = env:get_node(pos)\r
396                                         local meta1a = env:get_meta(pos):to_table()\r
397                                         local value1, value2 = pos[axis1], pos[axis2]\r
398                                         pos[axis1], pos[axis2] = pos1[axis1] + extent2, pos1[axis2] + extent1\r
399                                         local node2 = env:get_node(pos)\r
400                                         local meta2a = env:get_meta(pos):to_table()\r
401                                         env:add_node(pos, node1)\r
402                                         local meta1b = env:get_meta(pos)\r
403                                         meta1b:from_table(meta1a)\r
404                                         pos[axis1], pos[axis2] = pos1[axis1] + extent1, pos1[axis2] + extent2\r
405                                         env:add_node(pos, node2)\r
406                                         local meta2b = env:get_meta(pos)\r
407                                         meta2b:from_table(meta2a)\r
408                                 end\r
409                                 pos.z = pos.z + 1\r
410                         end\r
411                         pos.y = pos.y + 1\r
412                 end\r
413                 pos.x = pos.x + 1\r
414         end\r
415         return worldedit.volume(pos1, pos2)\r
416 end\r
417 \r
418 --flips a region defined by the positions `pos1` and `pos2` along the `axis` axis ("x" or "y" or "z"), returning the number of nodes flipped\r
419 worldedit.flip = function(pos1, pos2, axis)\r
420         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
421 \r
422         local pos = {x=pos1.x, y=0, z=0}\r
423         local start = pos1[axis] + pos2[axis]\r
424         pos2[axis] = pos1[axis] + math.floor((pos2[axis] - pos1[axis]) / 2)\r
425         local env = minetest.env\r
426         while pos.x <= pos2.x do\r
427                 pos.y = pos1.y\r
428                 while pos.y <= pos2.y do\r
429                         pos.z = pos1.z\r
430                         while pos.z <= pos2.z do\r
431                                 local node1 = env:get_node(pos)\r
432                                 local meta1a = env:get_meta(pos):to_table()\r
433                                 local value = pos[axis]\r
434                                 pos[axis] = start - value\r
435                                 local node2 = env:get_node(pos)\r
436                                 local meta2a = env:get_meta(pos):to_table()\r
437                                 env:add_node(pos, node1)\r
438                                 local meta1b = env:get_meta(pos)\r
439                                 meta1b:from_table(meta1a)\r
440                                 pos[axis] = value\r
441                                 env:add_node(pos, node2)\r
442                                 local meta2b = env:get_meta(pos)\r
443                                 meta2b:from_table(meta2a)\r
444                                 pos.z = pos.z + 1\r
445                         end\r
446                         pos.y = pos.y + 1\r
447                 end\r
448                 pos.x = pos.x + 1\r
449         end\r
450         return worldedit.volume(pos1, pos2)\r
451 end\r
452 \r
453 --rotates a region defined by the positions `pos1` and `pos2` by `angle` degrees clockwise (if you are looking in the negative direction) around the `axis` (supporting 90 degree increments only), returning the number of nodes rotated\r
454 worldedit.rotate = function(pos1, pos2, axis, angle)\r
455         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
456 \r
457         if axis == 'x' then\r
458                 axes = {'z', 'y'}\r
459         elseif axis == 'y' then\r
460                 axes = {'x', 'z'}\r
461         else--if axis == 'z' then\r
462                 axes = {'y', 'x'}\r
463         end\r
464         angle = angle % 360\r
465 \r
466         local pos = {x=pos1.x, y=0, z=0}\r
467         local newpos = {x=0, y=0, z=0}\r
468         local offsetx, offsetz\r
469         local env = minetest.env\r
470 \r
471         if angle == 90 then\r
472                 worldedit.transpose(pos1, pos2, axes[1], axes[2])\r
473                 worldedit.flip(pos1, pos2, axes[2])\r
474         elseif angle == 180 then\r
475                 worldedit.flip(pos1, pos2, axes[1])\r
476                 worldedit.flip(pos1, pos2, axes[2])\r
477         elseif angle == 270 then\r
478                 worldedit.transpose(pos1, pos2, axes[1], axes[2])\r
479                 worldedit.flip(pos1, pos2, axes[1])\r
480         else\r
481                 return 0\r
482         end\r
483         return worldedit.volume(pos1, pos2)\r
484 end\r
485 \r
486 --digs a region defined by positions `pos1` and `pos2`, returning the number of nodes dug\r
487 worldedit.dig = function(pos1, pos2)\r
488         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
489         local env = minetest.env\r
490 \r
491         local pos = {x=pos1.x, y=0, z=0}\r
492         while pos.x <= pos2.x do\r
493                 pos.y = pos1.y\r
494                 while pos.y <= pos2.y do\r
495                         pos.z = pos1.z\r
496                         while pos.z <= pos2.z do\r
497                                 env:dig_node(pos)\r
498                                 pos.z = pos.z + 1\r
499                         end\r
500                         pos.y = pos.y + 1\r
501                 end\r
502                 pos.x = pos.x + 1\r
503         end\r
504         return worldedit.volume(pos1, pos2)\r
505 end\r
506 \r
507 --converts the region defined by positions `pos1` and `pos2` into a single string, returning the serialized data and the number of nodes serialized\r
508 worldedit.serialize = function(pos1, pos2)\r
509         local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
510         local pos = {x=pos1.x, y=0, z=0}\r
511         local count = 0\r
512         local result = {}\r
513         local env = minetest.env\r
514         while pos.x <= pos2.x do\r
515                 pos.y = pos1.y\r
516                 while pos.y <= pos2.y do\r
517                         pos.z = pos1.z\r
518                         while pos.z <= pos2.z do\r
519                                 local node = env:get_node(pos)\r
520                                 if node.name ~= "air" and node.name ~= "ignore" then\r
521                                         count = count + 1\r
522                                         result[count] = pos.x - pos1.x .. " " .. pos.y - pos1.y .. " " .. pos.z - pos1.z .. " " .. node.name .. " " .. node.param1 .. " " .. node.param2\r
523                                 end\r
524                                 pos.z = pos.z + 1\r
525                         end\r
526                         pos.y = pos.y + 1\r
527                 end\r
528                 pos.x = pos.x + 1\r
529         end\r
530         result = table.concat(result, "\n")\r
531         return result, count\r
532 end\r
533 \r
534 --loads the nodes represented by string `value` at position `originpos`, returning the number of nodes deserialized\r
535 worldedit.deserialize = function(originpos, value)\r
536         local pos = {x=0, y=0, z=0}\r
537         local node = {name="", param1=0, param2=0}\r
538         local count = 0\r
539         local env = minetest.env\r
540         for x, y, z, name, param1, param2 in value:gmatch("([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)%s+([^%s]+)%s+(%d+)%s+(%d+)[^\r\n]*[\r\n]*") do\r
541                 pos.x = originpos.x + tonumber(x)\r
542                 pos.y = originpos.y + tonumber(y)\r
543                 pos.z = originpos.z + tonumber(z)\r
544                 node.name = name\r
545                 node.param1 = param1\r
546                 node.param2 = param2\r
547                 env:add_node(pos, node)\r
548                 count = count + 1\r
549         end\r
550         return count\r
551 end\r
552 \r
553 --loads the nodes represented by string `value` at position `originpos`, returning the number of nodes deserialized\r
554 --based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile) by ChillCode, available under the MIT license (GPL compatible)\r
555 worldedit.deserialize_old = function(originpos, value)\r
556         --obtain the node table\r
557         local count = 0\r
558         local get_tables = loadstring(value)\r
559         if get_tables == nil then --error loading value\r
560                 return count\r
561         end\r
562         local tables = get_tables()\r
563 \r
564         --transform the node table into an array of nodes\r
565         for i = 1, #tables do\r
566                 for j, v in pairs(tables[i]) do\r
567                         if type(v) == "table" then\r
568                                 tables[i][j] = tables[v[1]]\r
569                         end\r
570                 end\r
571         end\r
572 \r
573         --load the node array\r
574         local env = minetest.env\r
575         for i, v in ipairs(tables[1]) do\r
576                 local pos = v[1]\r
577                 pos.x, pos.y, pos.z = originpos.x + pos.x, originpos.y + pos.y, originpos.z + pos.z\r
578                 env:add_node(pos, v[2])\r
579                 count = count + 1\r
580         end\r
581         return count\r
582 end\r