local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
\r
local dim = vector.add(vector.subtract(pos2, pos1), 1)\r
- if math.abs(amount) < dim[axis] then\r
- -- Source and destination region are overlapping\r
- -- FIXME: I can't be bothered, so just defer to the legacy code for now.\r
- return worldedit.legacy_move(pos1, pos2, axis, amount)\r
+ local overlap = math.abs(amount) < dim[axis]\r
+ -- Decide if we need to copy metadata backwards\r
+ local backwards = overlap and amount > 0\r
+\r
+ local function nuke_area(my_off, my_dim)\r
+ if my_dim.x == 0 or my_dim.y == 0 or my_dim.z == 0 then\r
+ return\r
+ end\r
+ local my_pos1 = vector.add(pos1, my_off)\r
+ local my_pos2 = vector.subtract(vector.add(my_pos1, my_dim), 1)\r
+ worldedit.set(my_pos1, my_pos2, "air")\r
+ worldedit.delete_meta(my_pos1, my_pos2)\r
end\r
\r
-- Copy stuff to new location\r
local off = {x=0, y=0, z=0}\r
off[axis] = amount\r
- worldedit.copy2(pos1, pos2, off)\r
+ worldedit.copy2(pos1, pos2, off, backwards)\r
-- Nuke old area\r
- worldedit.set(pos1, pos2, "air")\r
- worldedit.delete_meta(pos1, pos2)\r
-\r
- return worldedit.volume(pos1, pos2)\r
-end\r
-\r
--- This function is not offical part of the API and may be removed at any time.\r
-function worldedit.legacy_move(pos1, pos2, axis, amount)\r
- local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
-\r
- worldedit.keep_loaded(pos1, pos2)\r
-\r
- local get_node, get_meta, set_node, remove_node = minetest.get_node,\r
- minetest.get_meta, minetest.set_node, minetest.remove_node\r
- -- Copy things backwards when negative to avoid corruption.\r
- if amount < 0 then\r
- local pos = {}\r
- pos.x = pos1.x\r
- while pos.x <= pos2.x do\r
- pos.y = pos1.y\r
- while pos.y <= pos2.y do\r
- pos.z = pos1.z\r
- while pos.z <= pos2.z do\r
- local node = get_node(pos) -- Obtain current node\r
- local meta = get_meta(pos):to_table() -- Get metadata of current node\r
- remove_node(pos) -- Remove current node\r
- local value = pos[axis] -- Store current position\r
- pos[axis] = value + amount -- Move along axis\r
- set_node(pos, node) -- Move node to new position\r
- get_meta(pos):from_table(meta) -- Set metadata of new node\r
- pos[axis] = value -- Restore old position\r
- pos.z = pos.z + 1\r
- end\r
- pos.y = pos.y + 1\r
- end\r
- pos.x = pos.x + 1\r
- end\r
+ if not overlap then\r
+ nuke_area({x=0, y=0, z=0}, dim)\r
else\r
- local pos = {}\r
- pos.x = pos2.x\r
- while pos.x >= pos1.x do\r
- pos.y = pos2.y\r
- while pos.y >= pos1.y do\r
- pos.z = pos2.z\r
- while pos.z >= pos1.z do\r
- local node = get_node(pos) -- Obtain current node\r
- local meta = get_meta(pos):to_table() -- Get metadata of current node\r
- remove_node(pos) -- Remove current node\r
- local value = pos[axis] -- Store current position\r
- pos[axis] = value + amount -- Move along axis\r
- set_node(pos, node) -- Move node to new position\r
- get_meta(pos):from_table(meta) -- Set metadata of new node\r
- pos[axis] = value -- Restore old position\r
- pos.z = pos.z - 1\r
- end\r
- pos.y = pos.y - 1\r
- end\r
- pos.x = pos.x - 1\r
+ -- Source and destination region are overlapping, which means we can't\r
+ -- blindly delete the [pos1, pos2] area\r
+ local leftover = vector.new(dim) -- size of the leftover slice\r
+ leftover[axis] = math.abs(amount)\r
+ if amount > 0 then\r
+ nuke_area({x=0, y=0, z=0}, leftover)\r
+ else\r
+ local top = {x=0, y=0, z=0} -- offset of the leftover slice from pos1\r
+ top[axis] = dim[axis] - 1\r
+ nuke_area(top, leftover)\r
end\r
end\r
+\r
return worldedit.volume(pos1, pos2)\r
end\r
\r
-\r
--- Duplicates a region along `axis` `amount` times.\r
-- Stacking is spread across server steps.\r
-- @param pos1\r