1 worldedit = worldedit or {}
\r
2 local minetest = minetest --local copy of global
\r
4 --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
5 worldedit.sort_pos = function(pos1, pos2)
\r
6 pos1 = {x=pos1.x, y=pos1.y, z=pos1.z}
\r
7 pos2 = {x=pos2.x, y=pos2.y, z=pos2.z}
\r
8 if pos1.x > pos2.x then
\r
9 pos2.x, pos1.x = pos1.x, pos2.x
\r
11 if pos1.y > pos2.y then
\r
12 pos2.y, pos1.y = pos1.y, pos2.y
\r
14 if pos1.z > pos2.z then
\r
15 pos2.z, pos1.z = pos1.z, pos2.z
\r
20 --determines the volume of the region defined by positions `pos1` and `pos2`, returning the volume
\r
21 worldedit.volume = function(pos1, pos2)
\r
22 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
23 return (pos2.x - pos1.x + 1) * (pos2.y - pos1.y + 1) * (pos2.z - pos1.z + 1)
\r
26 --sets a region defined by positions `pos1` and `pos2` to `nodename`, returning the number of nodes filled
\r
27 worldedit.set = function(pos1, pos2, nodenames)
\r
28 if type(nodenames) == 'string' then
\r
29 nodenames = {nodenames}
\r
32 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
34 --set up voxel manipulator
\r
35 local manip = minetest.get_voxel_manip()
\r
36 local emerged_pos1, emerged_pos2 = manip:read_from_map(pos1, pos2)
\r
37 local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
\r
39 --fill emerged area with ignore
\r
41 local ignore = minetest.get_content_id("ignore")
\r
42 for i = 1, worldedit.volume(emerged_pos1, emerged_pos2) do
\r
46 --fill selected area with node
\r
48 for i,v in ipairs(nodenames) do
\r
49 node_ids[i] = minetest.get_content_id(nodenames[i])
\r
51 for i in area:iterp(pos1, pos2) do
\r
52 nodes[i] = node_ids[math.random(#node_ids)]
\r
56 manip:set_data(nodes)
\r
57 manip:write_to_map()
\r
60 return worldedit.volume(pos1, pos2)
\r
63 --replaces all instances of `searchnode` with `replacenode` in a region defined by positions `pos1` and `pos2`, returning the number of nodes replaced
\r
64 worldedit.replace = function(pos1, pos2, searchnode, replacenode)
\r
65 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
67 --set up voxel manipulator
\r
68 local manip = minetest.get_voxel_manip()
\r
69 local emerged_pos1, emerged_pos2 = manip:read_from_map(pos1, pos2)
\r
70 local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
\r
72 local nodes = manip:get_data()
\r
73 local searchnode_id = minetest.get_content_id(searchnode)
\r
74 local replacenode_id = minetest.get_content_id(replacenode)
\r
76 for i in area:iterp(pos1, pos2) do --replace searchnode with replacenode
\r
77 if nodes[i] == searchnode_id then
\r
78 nodes[i] = replacenode_id
\r
84 manip:set_data(nodes)
\r
85 manip:write_to_map()
\r
91 --replaces all nodes other than `searchnode` with `replacenode` in a region defined by positions `pos1` and `pos2`, returning the number of nodes replaced
\r
92 worldedit.replaceinverse = function(pos1, pos2, searchnode, replacenode)
\r
93 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
95 --set up voxel manipulator
\r
96 local manip = minetest.get_voxel_manip()
\r
97 local emerged_pos1, emerged_pos2 = manip:read_from_map(pos1, pos2)
\r
98 local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
\r
100 local nodes = manip:get_data()
\r
101 local searchnode_id = minetest.get_content_id(searchnode)
\r
102 local replacenode_id = minetest.get_content_id(replacenode)
\r
104 for i in area:iterp(pos1, pos2) do --replace anything that is not searchnode with replacenode
\r
105 if nodes[i] ~= searchnode_id then
\r
106 nodes[i] = replacenode_id
\r
112 manip:set_data(nodes)
\r
113 manip:write_to_map()
\r
119 worldedit.copy = function(pos1, pos2, axis, amount) --wip: replace the old version below
\r
120 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
122 if amount == 0 then
\r
126 local other1, other2
\r
127 if axis == "x" then
\r
128 other1, other2 = "y", "z"
\r
129 elseif axis == "y" then
\r
130 other1, other2 = "x", "z"
\r
132 other1, other2 = "x", "y"
\r
135 --make area stay loaded
\r
136 local manip = minetest.get_voxel_manip()
\r
137 manip:read_from_map(pos1, pos2)
\r
139 --prepare slice along axis
\r
142 [other1]=pos2[other1] - pos1[other1] + 1,
\r
143 [other2]=pos2[other2] - pos1[other2] + 1,
\r
146 local schematic = {size=extent, data=nodes}
\r
148 local currentpos = {x=pos1.x, y=pos1.y, z=pos1.z}
\r
149 local stride = {x=1, y=extent.x, z=extent.x * extent.y}
\r
150 local get_node = minetest.get_node
\r
151 for index1 = 1, extent[axis] do --go through each slice
\r
152 --copy slice into schematic
\r
153 local newindex1 = (index1 + offset[axis]) * stride[axis] + 1 --offset contributed by axis plus 1 to make it 1-indexed
\r
154 for index2 = 1, extent[other1] do
\r
155 local newindex2 = newindex1 + (index2 + offset[other1]) * stride[other1]
\r
156 for index3 = 1, extent[other2] do
\r
157 local i = newindex2 + (index3 + offset[other2]) * stride[other2]
\r
158 local node = get_node(pos)
\r
159 node.param1 = 255 --node will always appear
\r
164 --copy schematic to target
\r
165 currentpos[axis] = currentpos[axis] + amount
\r
166 place_schematic(currentpos, schematic)
\r
170 currentpos[axis] = currentpos[axis] + 1
\r
172 return worldedit.volume(pos1, pos2)
\r
175 worldedit.copy2 = function(pos1, pos2, direction, volume)
\r
176 -- the overlap shouldn't matter as long as we
\r
177 -- 1) start at the furthest separated corner
\r
178 -- 2) complete an edge before moving inward, either edge works
\r
179 -- 3) complete a face before moving inward, similarly
\r
182 -- 1) find the furthest destination in the direction, of each axis
\r
183 -- 2) call those the furthest separated corner
\r
184 -- 3) make sure to iterate inward from there
\r
185 -- 4) nested loop to make sure complete edge, complete face, then complete cube.
\r
187 local get_node, get_meta, add_node = minetest.get_node, minetest.get_meta, minetest.add_node
\r
188 local somemeta = get_meta(pos1) -- hax lol
\r
189 local to_table = somemeta.to_table
\r
190 local from_table = somemeta.from_table
\r
193 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
194 local manip = minetest.get_voxel_manip()
\r
195 manip:read_from_map(pos1, pos2)
\r
197 local sx,sy,sz -- direction sign
\r
198 local ix,iy,iz -- initial destination
\r
199 local ex,ey,ez -- final destination
\r
200 local originalx,originaly,originalz -- source
\r
201 -- vim -> :'<,'>s/\<\([ioes]\?\)x\>/\1y/g
\r
202 if direction.x > 0 then
\r
204 ix = originalx + direction.x
\r
205 ex = pos1.x + direction.x
\r
207 elseif direction.x < 0 then
\r
209 ix = originalx + direction.x
\r
210 ex = pos2.x + direction.x
\r
214 ix = originalx -- whatever
\r
219 if direction.y > 0 then
\r
221 iy = originaly + direction.y
\r
222 ey = pos1.y + direction.y
\r
224 elseif direction.y < 0 then
\r
226 iy = originaly + direction.y
\r
227 ey = pos2.y + direction.y
\r
231 iy = originaly -- whatever
\r
236 if direction.z > 0 then
\r
238 iz = originalz + direction.z
\r
239 ez = pos1.z + direction.z
\r
241 elseif direction.z < 0 then
\r
243 iz = originalz + direction.z
\r
244 ez = pos2.z + direction.z
\r
248 iz = originalz -- whatever
\r
252 -- print('copy',originalx,ix,ex,sx,originaly,iy,ey,sy,originalz,iz,ez,sz)
\r
257 for x = ix,ex,sx do
\r
259 for y = iy,ey,sy do
\r
261 for z = iz,ez,sz do
\r
262 -- reusing pos1/pos2 as source/dest here
\r
263 pos1.x = ox; pos1.y = oy; pos1.z = oz
\r
264 pos2.x = x; pos2.y = y; pos2.z = z
\r
265 local node = get_node(pos1)
\r
266 local meta = to_table(get_meta(pos1)) --get meta of current node
\r
267 add_node(pos2,node)
\r
268 from_table(get_meta(pos2),meta)
\r
277 worldedit.stack2 = function(pos1, pos2, direction, amount, finished)
\r
279 local translated = {x=0,y=0,z=0}
\r
280 local function nextone()
\r
281 if i <= amount then
\r
283 translated.x = translated.x + direction.x
\r
284 translated.y = translated.y + direction.y
\r
285 translated.z = translated.z + direction.z
\r
286 worldedit.copy2(pos1,pos2,translated,volume)
\r
287 minetest.after(0,nextone)
\r
298 --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
299 worldedit.copy = function(pos1, pos2, axis, amount)
\r
300 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
302 --make area stay loaded
\r
303 local manip = minetest.get_voxel_manip()
\r
304 manip:read_from_map(pos1, pos2)
\r
306 local get_node, get_meta, add_node = minetest.get_node, minetest.get_meta, minetest.add_node
\r
308 local pos = {x=pos1.x, y=0, z=0}
\r
309 while pos.x <= pos2.x do
\r
311 while pos.y <= pos2.y do
\r
313 while pos.z <= pos2.z do
\r
314 local node = get_node(pos) --obtain current node
\r
315 local meta = get_meta(pos):to_table() --get meta of current node
\r
316 local value = pos[axis] --store current position
\r
317 pos[axis] = value + amount --move along axis
\r
318 add_node(pos, node) --copy node to new position
\r
319 get_meta(pos):from_table(meta) --set metadata of new node
\r
320 pos[axis] = value --restore old position
\r
328 local pos = {x=pos2.x, y=0, z=0}
\r
329 while pos.x >= pos1.x do
\r
331 while pos.y >= pos1.y do
\r
333 while pos.z >= pos1.z do
\r
334 local node = get_node(pos) --obtain current node
\r
335 local meta = get_meta(pos):to_table() --get meta of current node
\r
336 local value = pos[axis] --store current position
\r
337 pos[axis] = value + amount --move along axis
\r
338 add_node(pos, node) --copy node to new position
\r
339 get_meta(pos):from_table(meta) --set metadata of new node
\r
340 pos[axis] = value --restore old position
\r
348 return worldedit.volume(pos1, pos2)
\r
351 --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
352 worldedit.move = function(pos1, pos2, axis, amount)
\r
353 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
355 --make area stay loaded
\r
356 local manip = minetest.get_voxel_manip()
\r
357 manip:read_from_map(pos1, pos2)
\r
359 --wip: move slice by slice using schematic method in the move axis and transfer metadata in separate loop (and if the amount is greater than the length in the axis, copy whole thing at a time and erase original after, using schematic method)
\r
360 local get_node, get_meta, add_node, remove_node = minetest.get_node, minetest.get_meta, minetest.add_node, minetest.remove_node
\r
362 local pos = {x=pos1.x, y=0, z=0}
\r
363 while pos.x <= pos2.x do
\r
365 while pos.y <= pos2.y do
\r
367 while pos.z <= pos2.z do
\r
368 local node = get_node(pos) --obtain current node
\r
369 local meta = get_meta(pos):to_table() --get metadata of current node
\r
371 local value = pos[axis] --store current position
\r
372 pos[axis] = value + amount --move along axis
\r
373 add_node(pos, node) --move node to new position
\r
374 get_meta(pos):from_table(meta) --set metadata of new node
\r
375 pos[axis] = value --restore old position
\r
383 local pos = {x=pos2.x, y=0, z=0}
\r
384 while pos.x >= pos1.x do
\r
386 while pos.y >= pos1.y do
\r
388 while pos.z >= pos1.z do
\r
389 local node = get_node(pos) --obtain current node
\r
390 local meta = get_meta(pos):to_table() --get metadata of current node
\r
392 local value = pos[axis] --store current position
\r
393 pos[axis] = value + amount --move along axis
\r
394 add_node(pos, node) --move node to new position
\r
395 get_meta(pos):from_table(meta) --set metadata of new node
\r
396 pos[axis] = value --restore old position
\r
404 return worldedit.volume(pos1, pos2)
\r
407 --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
408 worldedit.stack = function(pos1, pos2, axis, count)
\r
409 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
410 local length = pos2[axis] - pos1[axis] + 1
\r
416 local copy = worldedit.copy
\r
417 for i = 1, count do
\r
418 amount = amount + length
\r
419 copy(pos1, pos2, axis, amount)
\r
421 return worldedit.volume(pos1, pos2) * count
\r
424 --stretches the region defined by positions `pos1` and `pos2` by an factor of positive integers `stretchx`, `stretchy`. and `stretchz` along the X, Y, and Z axes, respectively, with `pos1` as the origin, returning the number of nodes scaled, the new scaled position 1, and the new scaled position 2
\r
425 worldedit.stretch = function(pos1, pos2, stretchx, stretchy, stretchz) --wip: test this
\r
426 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
428 --prepare schematic of large node
\r
429 local get_node, get_meta, place_schematic = minetest.get_node, minetest.get_meta, minetest.place_schematic
\r
430 local placeholder_node = {name="", param1=255, param2=0}
\r
432 for i = 1, stretchx * stretchy * stretchz do
\r
433 nodes[i] = placeholder_node
\r
435 local schematic = {size={x=stretchx, y=stretchy, z=stretchz}, data=nodes}
\r
437 local sizex, sizey, sizez = stretchx - 1, stretchy - 1, stretchz - 1
\r
439 --make area stay loaded
\r
440 local manip = minetest.get_voxel_manip()
\r
442 x=pos1.x + (pos2.x - pos1.x) * stretchx + sizex,
\r
443 y=pos1.y + (pos2.y - pos1.y) * stretchy + sizey,
\r
444 z=pos1.z + (pos2.z - pos1.z) * stretchz + sizez,
\r
446 manip:read_from_map(pos1, new_pos2)
\r
448 local pos = {x=pos2.x, y=0, z=0}
\r
449 local bigpos = {x=0, y=0, z=0}
\r
450 while pos.x >= pos1.x do
\r
452 while pos.y >= pos1.y do
\r
454 while pos.z >= pos1.z do
\r
455 local node = get_node(pos) --obtain current node
\r
456 local meta = get_meta(pos):to_table() --get meta of current node
\r
458 --calculate far corner of the big node
\r
459 local posx = pos1.x + (pos.x - pos1.x) * stretchx
\r
460 local posy = pos1.y + (pos.y - pos1.y) * stretchy
\r
461 local posz = pos1.z + (pos.z - pos1.z) * stretchz
\r
463 --create large node
\r
464 placeholder_node.name = node.name
\r
465 placeholder_node.param2 = node.param2
\r
466 bigpos.x, bigpos.y, bigpos.z = posx, posy, posz
\r
467 place_schematic(bigpos, schematic)
\r
469 --fill in large node meta
\r
470 if next(meta.fields) ~= nil or next(meta.inventory) ~= nil then --node has meta fields
\r
471 for x = 0, sizex do
\r
472 for y = 0, sizey do
\r
473 for z = 0, sizez do
\r
474 bigpos.x, bigpos.y, bigpos.z = posx + x, posy + y, posz + z
\r
475 get_meta(bigpos):from_table(meta) --set metadata of new node
\r
486 return worldedit.volume(pos1, pos2) * stretchx * stretchy * stretchz, pos1, new_pos2
\r
489 --transposes a region defined by the positions `pos1` and `pos2` between the `axis1` and `axis2` axes, returning the number of nodes transposed, the new transposed position 1, and the new transposed position 2
\r
490 worldedit.transpose = function(pos1, pos2, axis1, axis2)
\r
491 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
494 local extent1, extent2 = pos2[axis1] - pos1[axis1], pos2[axis2] - pos1[axis2]
\r
496 if extent1 > extent2 then
\r
497 compare = function(extent1, extent2)
\r
498 return extent1 > extent2
\r
501 compare = function(extent1, extent2)
\r
502 return extent1 < extent2
\r
506 --calculate the new position 2 after transposition
\r
507 local new_pos2 = {x=pos2.x, y=pos2.y, z=pos2.z}
\r
508 new_pos2[axis1] = pos1[axis1] + extent2
\r
509 new_pos2[axis2] = pos1[axis2] + extent1
\r
511 --make area stay loaded
\r
512 local manip = minetest.get_voxel_manip()
\r
513 local upperbound = {x=pos2.x, y=pos2.y, z=pos2.z}
\r
514 if upperbound[axis1] < new_pos2[axis1] then upperbound[axis1] = new_pos2[axis1] end
\r
515 if upperbound[axis2] < new_pos2[axis2] then upperbound[axis2] = new_pos2[axis2] end
\r
516 manip:read_from_map(pos1, upperbound)
\r
518 local pos = {x=pos1.x, y=0, z=0}
\r
519 local get_node, get_meta, add_node = minetest.get_node, minetest.get_meta, minetest.add_node
\r
520 while pos.x <= pos2.x do
\r
522 while pos.y <= pos2.y do
\r
524 while pos.z <= pos2.z do
\r
525 local extent1, extent2 = pos[axis1] - pos1[axis1], pos[axis2] - pos1[axis2]
\r
526 if compare(extent1, extent2) then --transpose only if below the diagonal
\r
527 local node1 = get_node(pos)
\r
528 local meta1 = get_meta(pos):to_table()
\r
529 local value1, value2 = pos[axis1], pos[axis2] --save position values
\r
530 pos[axis1], pos[axis2] = pos1[axis1] + extent2, pos1[axis2] + extent1 --swap axis extents
\r
531 local node2 = get_node(pos)
\r
532 local meta2 = get_meta(pos):to_table()
\r
533 add_node(pos, node1)
\r
534 get_meta(pos):from_table(meta1)
\r
535 pos[axis1], pos[axis2] = value1, value2 --restore position values
\r
536 add_node(pos, node2)
\r
537 get_meta(pos):from_table(meta2)
\r
545 return worldedit.volume(pos1, pos2), pos1, new_pos2
\r
548 --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
549 worldedit.flip = function(pos1, pos2, axis)
\r
550 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
552 --make area stay loaded
\r
553 local manip = minetest.get_voxel_manip()
\r
554 manip:read_from_map(pos1, pos2)
\r
556 --wip: flip the region slice by slice along the flip axis using schematic method
\r
557 local pos = {x=pos1.x, y=0, z=0}
\r
558 local start = pos1[axis] + pos2[axis]
\r
559 pos2[axis] = pos1[axis] + math.floor((pos2[axis] - pos1[axis]) / 2)
\r
560 local get_node, get_meta, add_node = minetest.get_node, minetest.get_meta, minetest.add_node
\r
561 while pos.x <= pos2.x do
\r
563 while pos.y <= pos2.y do
\r
565 while pos.z <= pos2.z do
\r
566 local node1 = get_node(pos)
\r
567 local meta1 = get_meta(pos):to_table()
\r
568 local value = pos[axis]
\r
569 pos[axis] = start - value
\r
570 local node2 = get_node(pos)
\r
571 local meta2 = get_meta(pos):to_table()
\r
572 add_node(pos, node1)
\r
573 get_meta(pos):from_table(meta1)
\r
575 add_node(pos, node2)
\r
576 get_meta(pos):from_table(meta2)
\r
583 return worldedit.volume(pos1, pos2)
\r
586 --rotates a region defined by the positions `pos1` and `pos2` by `angle` degrees clockwise around axis `axis` (90 degree increment), returning the number of nodes rotated
\r
587 worldedit.rotate = function(pos1, pos2, axis, angle)
\r
588 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
591 if axis == "x" then
\r
592 axis1, axis2 = "z", "y"
\r
593 elseif axis == "y" then
\r
594 axis1, axis2 = "x", "z"
\r
596 axis1, axis2 = "y", "x"
\r
598 angle = angle % 360
\r
601 if angle == 90 then
\r
602 worldedit.flip(pos1, pos2, axis1)
\r
603 count, pos1, pos2 = worldedit.transpose(pos1, pos2, axis1, axis2)
\r
604 elseif angle == 180 then
\r
605 worldedit.flip(pos1, pos2, axis1)
\r
606 count = worldedit.flip(pos1, pos2, axis2)
\r
607 elseif angle == 270 then
\r
608 worldedit.flip(pos1, pos2, axis2)
\r
609 count, pos1, pos2 = worldedit.transpose(pos1, pos2, axis1, axis2)
\r
611 return count, pos1, pos2
\r
614 --rotates all oriented nodes in a region defined by the positions `pos1` and `pos2` by `angle` degrees clockwise (90 degree increment) around the Y axis, returning the number of nodes oriented
\r
615 worldedit.orient = function(pos1, pos2, angle) --wip: support 6D facedir rotation along arbitrary axis
\r
616 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
617 local registered_nodes = minetest.registered_nodes
\r
619 local wallmounted = {
\r
620 [90]={[0]=0, [1]=1, [2]=5, [3]=4, [4]=2, [5]=3},
\r
621 [180]={[0]=0, [1]=1, [2]=3, [3]=2, [4]=5, [5]=4},
\r
622 [270]={[0]=0, [1]=1, [2]=4, [3]=5, [4]=3, [5]=2}
\r
625 [90]={[0]=1, [1]=2, [2]=3, [3]=0},
\r
626 [180]={[0]=2, [1]=3, [2]=0, [3]=1},
\r
627 [270]={[0]=3, [1]=0, [2]=1, [3]=2}
\r
630 angle = angle % 360
\r
634 local wallmounted_substitution = wallmounted[angle]
\r
635 local facedir_substitution = facedir[angle]
\r
637 --make area stay loaded
\r
638 local manip = minetest.get_voxel_manip()
\r
639 manip:read_from_map(pos1, pos2)
\r
642 local get_node, get_meta, add_node = minetest.get_node, minetest.get_meta, minetest.add_node
\r
643 local pos = {x=pos1.x, y=0, z=0}
\r
644 while pos.x <= pos2.x do
\r
646 while pos.y <= pos2.y do
\r
648 while pos.z <= pos2.z do
\r
649 local node = get_node(pos)
\r
650 local def = registered_nodes[node.name]
\r
652 if def.paramtype2 == "wallmounted" then
\r
653 node.param2 = wallmounted_substitution[node.param2]
\r
654 local meta = get_meta(pos):to_table()
\r
655 add_node(pos, node)
\r
656 get_meta(pos):from_table(meta)
\r
658 elseif def.paramtype2 == "facedir" then
\r
659 node.param2 = facedir_substitution[node.param2]
\r
660 local meta = get_meta(pos):to_table()
\r
661 add_node(pos, node)
\r
662 get_meta(pos):from_table(meta)
\r
675 --fixes the lighting in a region defined by positions `pos1` and `pos2`, returning the number of nodes updated
\r
676 worldedit.fixlight = function(pos1, pos2)
\r
677 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
679 --make area stay loaded
\r
680 local manip = minetest.get_voxel_manip()
\r
681 manip:read_from_map(pos1, pos2)
\r
683 local nodes = minetest.find_nodes_in_area(pos1, pos2, "air")
\r
684 local dig_node = minetest.dig_node
\r
685 for _, pos in ipairs(nodes) do
\r
691 --clears all objects in a region defined by the positions `pos1` and `pos2`, returning the number of objects cleared
\r
692 worldedit.clearobjects = function(pos1, pos2)
\r
693 local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
\r
695 --make area stay loaded
\r
696 local manip = minetest.get_voxel_manip()
\r
697 manip:read_from_map(pos1, pos2)
\r
699 local pos1x, pos1y, pos1z = pos1.x, pos1.y, pos1.z
\r
700 local pos2x, pos2y, pos2z = pos2.x + 1, pos2.y + 1, pos2.z + 1
\r
701 local center = {x=(pos1x + pos2x) / 2, y=(pos1y + pos2y) / 2, z=(pos1z + pos2z) / 2} --center of region
\r
702 local radius = ((center.x - pos1x + 0.5) + (center.y - pos1y + 0.5) + (center.z - pos1z + 0.5)) ^ 0.5 --bounding sphere radius
\r
704 for _, obj in pairs(minetest.get_objects_inside_radius(center, radius)) do --all objects in bounding sphere
\r
705 local entity = obj:get_luaentity()
\r
706 if not (entity and entity.name:find("^worldedit:")) then --avoid WorldEdit entities
\r
707 local pos = obj:getpos()
\r
708 if pos.x >= pos1x and pos.x <= pos2x
\r
709 and pos.y >= pos1y and pos.y <= pos2y
\r
710 and pos.z >= pos1z and pos.z <= pos2z then --inside region
\r