From 66839ca6a50f363d80b76c083446147c02ec6ddd Mon Sep 17 00:00:00 2001 From: Anthony Zhang Date: Fri, 13 Jul 2012 21:46:33 -0400 Subject: Initial commit. --- functions.lua | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 functions.lua (limited to 'functions.lua') diff --git a/functions.lua b/functions.lua new file mode 100644 index 0000000..2226e4c --- /dev/null +++ b/functions.lua @@ -0,0 +1,248 @@ +--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 + +--fills a region defined by positions `pos1` and `pos2` with `nodename`, returning the number of nodes filled +worldedit.fill = function(pos1, pos2, nodename) + 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 + +--copies the region defined by positions `pos1` and `pos2` along the `axis` axis by `amount` nodes, returning the number of nodes copied +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 + +--moves the region defined by positions `pos1` and `pos2` along the `axis` axis by `amount` nodes, returning the number of nodes moved +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 + +--duplicates the region defined by positions `pos1` and `pos2` along the `axis` axis `count` times, returning the number of nodes stacked +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) + 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 +end \ No newline at end of file -- cgit v1.2.3