diff --git a/README.md b/README.md index 99b06ff..cc40630 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,22 @@ Replace all instances of with in the current WorldEdi //replace dirt flowers:flower_waterlily //replace flowers:flower_rose flowers:flower_tulip +### //hollowcylinder x/y/z + +Add hollow cylinder at WorldEdit position 1 along the x/y/z axis with length and radius , composed of . + + //hollowcylinder x +5 8 dirt + //hollowcylinder y 28 10 default:glass + //hollowcylinder z -12 3 mesecons:mesecon + +### //cylinder x/y/z + +Add cylinder at WorldEdit position 1 along the x/y/z axis with length and radius , composed of . + + //cylinder x +5 8 dirt + //cylinder y 28 10 default:glass + //cylinder z -12 3 mesecons:mesecon + ### //copy x/y/z Copy the current WorldEdit region along the x/y/z axis by nodes. @@ -173,6 +189,18 @@ Replaces all instances of `searchnode` with `replacenode` in a region defined by Returns the number of nodes replaced. +### worldedit.hollow_cylinder(pos, axis, length, radius, nodename) + +Adds a hollow cylinder at `pos` along the `axis` axis ("x" or "y" or "z") with length `length` and radius `radius`. + +Returns the number of nodes added. + +### worldedit.cylinder(pos, axis, length, radius, nodename) + +Adds a cylinder at `pos` along the `axis` axis ("x" or "y" or "z") with length `length` and radius `radius`. + +Returns the number of nodes added. + ### worldedit.copy(pos1, pos2, axis, amount) Copies the region defined by positions `pos1` and `pos2` along the `axis` axis ("x" or "y" or "z") by `amount` nodes. diff --git a/functions.lua b/functions.lua index 625fafb..270b50e 100644 --- a/functions.lua +++ b/functions.lua @@ -72,6 +72,116 @@ worldedit.replace = function(pos1, pos2, searchnode, replacenode) return count end +--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 +worldedit.hollow_cylinder = function(pos, axis, length, radius, nodename) + local other1, other2 + if axis == "x" then + other1, other2 = "y", "z" + elseif axis == "y" then + other1, other2 = "x", "z" + else --axis == "z" + other1, other2 = "x", "y" + end + + local env = minetest.env + local currentpos = {x=pos.x, y=pos.y, z=pos.z} + local node = {name=nodename} + local count = 0 + for i = 1, length do + local offset1, offset2 = 0, radius + local delta = -radius + while offset1 <= offset2 do + --add node at each octant + local first1, first2 = pos[other1] + offset1, pos[other1] - offset1 + local second1, second2 = pos[other2] + offset2, pos[other2] - offset2 + currentpos[other1], currentpos[other2] = first1, second1 + env:add_node(currentpos, node) --octant 1 + currentpos[other1] = first2 + env:add_node(currentpos, node) --octant 4 + currentpos[other2] = second2 + env:add_node(currentpos, node) --octant 5 + currentpos[other1] = first1 + env:add_node(currentpos, node) --octant 8 + local first1, first2 = pos[other1] + offset2, pos[other1] - offset2 + local second1, second2 = pos[other2] + offset1, pos[other2] - offset1 + currentpos[other1], currentpos[other2] = first1, second1 + env:add_node(currentpos, node) --octant 2 + currentpos[other1] = first2 + env:add_node(currentpos, node) --octant 3 + currentpos[other2] = second2 + env:add_node(currentpos, node) --octant 6 + currentpos[other1] = first1 + env:add_node(currentpos, node) --octant 7 + + count = count + 8 --wip: broken + + --move to next location + delta = delta + (offset1 * 2) + 1 + if delta >= 0 then + offset2 = offset2 - 1 + delta = delta - (offset2 * 2) + end + offset1 = offset1 + 1 + end + currentpos[axis] = currentpos[axis] + 1 + end + return count +end + +--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 +worldedit.cylinder = function(pos, axis, length, radius, nodename) + local other1, other2 + if axis == "x" then + other1, other2 = "y", "z" + elseif axis == "y" then + other1, other2 = "x", "z" + else --axis == "z" + other1, other2 = "x", "y" + end + + local env = minetest.env + local currentpos = {x=pos.x, y=pos.y, z=pos.z} + local node = {name=nodename} + local count = 0 + for i = 1, length do + local offset1, offset2 = 0, radius + local delta = -radius + while offset1 <= offset2 do + --connect each pair of octants + currentpos[other1] = pos[other1] - offset1 + local second1, second2 = pos[other2] + offset2, pos[other2] - offset2 + for i = 0, offset1 * 2 do + currentpos[other2] = second1 + env:add_node(currentpos, node) --octant 1 to 4 + currentpos[other2] = second2 + env:add_node(currentpos, node) --octant 5 to 8 + currentpos[other1] = currentpos[other1] + 1 + end + currentpos[other1] = pos[other1] - offset2 + local second1, second2 = pos[other2] + offset1, pos[other2] - offset1 + for i = 0, offset2 * 2 do + currentpos[other2] = second1 + env:add_node(currentpos, node) --octant 2 to 3 + currentpos[other2] = second2 + env:add_node(currentpos, node) --octant 6 to 7 + currentpos[other1] = currentpos[other1] + 1 + end + + count = count + (offset1 * 4) + (offset2 * 4) + 4 --wip: broken + + --move to next location + delta = delta + (offset1 * 2) + 1 + offset1 = offset1 + 1 + if delta >= 0 then + offset2 = offset2 - 1 + delta = delta - (offset2 * 2) + end + end + currentpos[axis] = currentpos[axis] + 1 + end + return count +end + --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 worldedit.copy = function(pos1, pos2, axis, amount) local pos1, pos2 = worldedit.sort_pos(pos1, pos2) diff --git a/init.lua b/init.lua index 5c37567..eae615b 100644 --- a/init.lua +++ b/init.lua @@ -12,14 +12,8 @@ dofile(minetest.get_modpath("worldedit") .. "/mark.lua") --determines whether `nodename` is a valid node name, returning a boolean worldedit.node_is_valid = function(temp_pos, nodename) - local originalnode = minetest.env:get_node(temp_pos) --save the original node to restore later - minetest.env:add_node(temp_pos, {name=nodename}) --attempt to add the node - local value = minetest.env:get_node(temp_pos).name --obtain the name of the newly added node - if value == nodename or value == "default:" .. nodename then --successfully added node - minetest.env:add_node(temp_pos, originalnode) --restore the original node - return true --node is valid - end - return false --node is not valid + return minetest.registered_nodes[nodename] ~= nil + or minetest.registered_nodes["default:" .. nodename] ~= nil end minetest.register_chatcommand("/reset", { @@ -181,6 +175,58 @@ minetest.register_chatcommand("/replace", { end, }) +minetest.register_chatcommand("/hollowcylinder", { + params = "x/y/z ", + description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z axis with length and radius , composed of ", + privs = {worldedit=true}, + func = function(name, param) + local pos = worldedit.pos1[name] + if pos == nil then + minetest.chat_send_player(name, "No WorldEdit region selected") + return + end + + local found, _, axis, length, radius, nodename = param:find("^([xyz])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$") + if found == nil then + minetest.chat_send_player(name, "Invalid usage: " .. param) + return + end + if not worldedit.node_is_valid(pos, nodename) then + minetest.chat_send_player(name, "Invalid node name: " .. param) + return + end + + local count = worldedit.hollow_cylinder(pos, axis, tonumber(length), tonumber(radius), nodename) + minetest.chat_send_player(name, count .. " nodes added") + end, +}) + +minetest.register_chatcommand("/cylinder", { + params = "x/y/z ", + description = "Add cylinder at WorldEdit position 1 along the x/y/z axis with length and radius , composed of ", + privs = {worldedit=true}, + func = function(name, param) + local pos = worldedit.pos1[name] + if pos == nil then + minetest.chat_send_player(name, "No WorldEdit region selected") + return + end + + local found, _, axis, length, radius, nodename = param:find("^([xyz])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$") + if found == nil then + minetest.chat_send_player(name, "Invalid usage: " .. param) + return + end + if not worldedit.node_is_valid(pos, nodename) then + minetest.chat_send_player(name, "Invalid node name: " .. param) + return + end + + local count = worldedit.cylinder(pos, axis, tonumber(length), tonumber(radius), nodename) + minetest.chat_send_player(name, count .. " nodes added") + end, +}) + minetest.register_chatcommand("/copy", { params = "x/y/z ", description = "Copy the current WorldEdit region along the x/y/z axis by nodes",