2012-07-14 03:46:33 +02:00
--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
worldedit.sort_pos = function ( pos1 , pos2 )
pos1 = { x = pos1.x , y = pos1.y , z = pos1.z }
pos2 = { x = pos2.x , y = pos2.y , z = pos2.z }
if pos1.x > pos2.x then
pos2.x , pos1.x = pos1.x , pos2.x
end
if pos1.y > pos2.y then
pos2.y , pos1.y = pos1.y , pos2.y
end
if pos1.z > pos2.z then
pos2.z , pos1.z = pos1.z , pos2.z
end
return pos1 , pos2
end
--determines the volume of the region defined by positions `pos1` and `pos2`, returning the volume
worldedit.volume = function ( pos1 , pos2 )
local pos1 , pos2 = worldedit.sort_pos ( pos1 , pos2 )
return ( pos2.x - pos1.x + 1 ) * ( pos2.y - pos1.y + 1 ) * ( pos2.z - pos1.z + 1 )
end
2012-07-14 04:14:25 +02:00
--sets a region defined by positions `pos1` and `pos2` to `nodename`, returning the number of nodes filled
worldedit.set = function ( pos1 , pos2 , nodename )
2012-07-14 03:46:33 +02:00
local pos1 , pos2 = worldedit.sort_pos ( pos1 , pos2 )
local env = minetest.env
local node = { name = nodename }
local pos = { x = pos1.x , y = 0 , z = 0 }
while pos.x <= pos2.x do
pos.y = pos1.y
while pos.y <= pos2.y do
pos.z = pos1.z
while pos.z <= pos2.z do
env : add_node ( pos , node )
pos.z = pos.z + 1
end
pos.y = pos.y + 1
end
pos.x = pos.x + 1
end
return worldedit.volume ( pos1 , pos2 )
end
--replaces all instances of `searchnode` with `replacenode` in a region defined by positions `pos1` and `pos2`, returning the number of nodes replaced
worldedit.replace = function ( pos1 , pos2 , searchnode , replacenode )
local pos1 , pos2 = worldedit.sort_pos ( pos1 , pos2 )
local env = minetest.env
if searchnode : find ( " : " ) == nil then
searchnode = " default: " .. searchnode
end
local pos = { x = pos1.x , y = 0 , z = 0 }
local node = { name = replacenode }
local count = 0
while pos.x <= pos2.x do
pos.y = pos1.y
while pos.y <= pos2.y do
pos.z = pos1.z
while pos.z <= pos2.z do
if env : get_node ( pos ) . name == searchnode then
env : add_node ( pos , node )
count = count + 1
end
pos.z = pos.z + 1
end
pos.y = pos.y + 1
end
pos.x = pos.x + 1
end
return count
end
2012-07-14 04:14:25 +02:00
--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
2012-07-14 03:46:33 +02:00
worldedit.copy = function ( pos1 , pos2 , axis , amount )
local pos1 , pos2 = worldedit.sort_pos ( pos1 , pos2 )
local env = minetest.env
if amount < 0 then
local pos = { x = pos1.x , y = 0 , z = 0 }
while pos.x <= pos2.x do
pos.y = pos1.y
while pos.y <= pos2.y do
pos.z = pos1.z
while pos.z <= pos2.z do
local node = env : get_node ( pos , node )
local value = pos [ axis ]
pos [ axis ] = value - amount
env : add_node ( pos , node )
pos [ axis ] = value
pos.z = pos.z + 1
end
pos.y = pos.y + 1
end
pos.x = pos.x + 1
end
else
local pos = { x = pos2.x , y = 0 , z = 0 }
while pos.x >= pos1.x do
pos.y = pos2.y
while pos.y >= pos1.y do
pos.z = pos2.z
while pos.z >= pos1.z do
local node = minetest.env : get_node ( pos , node )
local value = pos [ axis ]
pos [ axis ] = value + amount
minetest.env : add_node ( pos , node )
pos [ axis ] = value
pos.z = pos.z - 1
end
pos.y = pos.y - 1
end
pos.x = pos.x - 1
end
end
return worldedit.volume ( pos1 , pos2 )
end
2012-07-14 04:14:25 +02:00
--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
2012-07-14 03:46:33 +02:00
worldedit.move = function ( pos1 , pos2 , axis , amount )
local pos1 , pos2 = worldedit.sort_pos ( pos1 , pos2 )
local env = minetest.env
if amount < 0 then
local pos = { x = pos1.x , y = 0 , z = 0 }
while pos.x <= pos2.x do
pos.y = pos1.y
while pos.y <= pos2.y do
pos.z = pos1.z
while pos.z <= pos2.z do
local node = env : get_node ( pos , node )
env : remove_node ( pos )
local value = pos [ axis ]
pos [ axis ] = value - amount
env : add_node ( pos , node )
pos [ axis ] = value
pos.z = pos.z + 1
end
pos.y = pos.y + 1
end
pos.x = pos.x + 1
end
else
local pos = { x = pos2.x , y = 0 , z = 0 }
while pos.x >= pos1.x do
pos.y = pos2.y
while pos.y >= pos1.y do
pos.z = pos2.z
while pos.z >= pos1.z do
local node = minetest.env : get_node ( pos , node )
env : remove_node ( pos )
local value = pos [ axis ]
pos [ axis ] = value + amount
minetest.env : add_node ( pos , node )
pos [ axis ] = value
pos.z = pos.z - 1
end
pos.y = pos.y - 1
end
pos.x = pos.x - 1
end
end
return worldedit.volume ( pos1 , pos2 )
end
2012-07-14 04:14:25 +02:00
--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
2012-07-14 03:46:33 +02:00
worldedit.stack = function ( pos1 , pos2 , axis , count )
local pos1 , pos2 = worldedit.sort_pos ( pos1 , pos2 )
local length = pos2 [ axis ] - pos1 [ axis ] + 1
local amount = 0
local copy = worldedit.copy
if count < 0 then
count = - count
length = - length
end
for i = 1 , count do
amount = amount + length
copy ( pos1 , pos2 , axis , amount )
end
return worldedit.volume ( pos1 , pos2 )
end
--digs a region defined by positions `pos1` and `pos2`, returning the number of nodes dug
worldedit.dig = function ( pos1 , pos2 )
local pos1 , pos2 = worldedit.sort_pos ( pos1 , pos2 )
local env = minetest.env
local pos = { x = pos1.x , y = 0 , z = 0 }
while pos.x <= pos2.x do
pos.y = pos1.y
while pos.y <= pos2.y do
pos.z = pos1.z
while pos.z <= pos2.z do
env : dig_node ( pos )
pos.z = pos.z + 1
end
pos.y = pos.y + 1
end
pos.x = pos.x + 1
end
return worldedit.volume ( pos1 , pos2 )
end
--converts the region defined by positions `pos1` and `pos2` into a single string, returning the serialized data and the number of nodes serialized
worldedit.serialize = function ( pos1 , pos2 )
2012-07-16 18:37:02 +02:00
local pos1 , pos2 = worldedit.sort_pos ( pos1 , pos2 )
2012-07-14 03:46:33 +02:00
local pos = { x = pos1.x , y = 0 , z = 0 }
local count = 0
local result = { }
local env = minetest.env
while pos.x <= pos2.x do
pos.y = pos1.y
while pos.y <= pos2.y do
pos.z = pos1.z
while pos.z <= pos2.z do
local node = env : get_node ( pos )
if node.name ~= " air " and node.name ~= " ignore " then
count = count + 1
result [ count ] = pos.x - pos1.x .. " " .. pos.y - pos1.y .. " " .. pos.z - pos1.z .. " " .. node.name .. " " .. node.param1 .. " " .. node.param2
end
pos.z = pos.z + 1
end
pos.y = pos.y + 1
end
pos.x = pos.x + 1
end
result = table.concat ( result , " \n " )
return result , count
end
--loads the nodes represented by string `value` at position `originpos`, returning the number of nodes deserialized
worldedit.deserialize = function ( originpos , value )
local pos = { x = 0 , y = 0 , z = 0 }
local node = { name = " " , param1 = 0 , param2 = 0 }
local count = 0
local env = minetest.env
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
pos.x = originpos.x + tonumber ( x )
pos.y = originpos.y + tonumber ( y )
pos.z = originpos.z + tonumber ( z )
node.name = name
node.param1 = param1
node.param2 = param2
env : add_node ( pos , node )
count = count + 1
end
return count
2012-07-20 04:54:26 +02:00
end
--loads the nodes represented by string `value` at position `originpos`, returning the number of nodes deserialized
--based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile) by ChillCode, available under the MIT license (GPL compatible)
worldedit.deserialize_old = function ( originpos , value )
--obtain the node table
local count = 0
local get_tables = loadstring ( value )
if get_tables == nil then --error loading value
return count
end
local tables = get_tables ( )
--transform the node table into an array of nodes
for i = 1 , # tables do
for j , v in pairs ( tables [ i ] ) do
if type ( v ) == " table " then
tables [ i ] [ j ] = tables [ v [ 1 ] ]
end
end
end
--load the node array
local env = minetest.env
for i , v in ipairs ( tables [ 1 ] ) do
local pos = v [ 1 ]
pos.x , pos.y , pos.z = originpos.x + pos.x , originpos.y + pos.y , originpos.z + pos.z
env : add_node ( pos , v [ 2 ] )
count = count + 1
end
return count
2012-07-14 03:46:33 +02:00
end