Add //hollowcylinder and //cylinder commands, add worldedit.hollow_cylinder and worldedit.cylinder API functions, document both, use better node validity check.

This commit is contained in:
Anthony Zhang 2012-08-18 00:51:20 -04:00
parent 87f23b8647
commit 66c7f1fb96
3 changed files with 192 additions and 8 deletions

View File

@ -83,6 +83,22 @@ Replace all instances of <search node> with <place node> in the current WorldEdi
//replace dirt flowers:flower_waterlily
//replace flowers:flower_rose flowers:flower_tulip
### //hollowcylinder x/y/z <length> <radius> <node>
Add hollow cylinder at WorldEdit position 1 along the x/y/z axis with length <length> and radius <radius>, composed of <node>.
//hollowcylinder x +5 8 dirt
//hollowcylinder y 28 10 default:glass
//hollowcylinder z -12 3 mesecons:mesecon
### //cylinder x/y/z <length> <radius> <node>
Add cylinder at WorldEdit position 1 along the x/y/z axis with length <length> and radius <radius>, composed of <node>.
//cylinder x +5 8 dirt
//cylinder y 28 10 default:glass
//cylinder z -12 3 mesecons:mesecon
### //copy x/y/z <amount>
Copy the current WorldEdit region along the x/y/z axis by <amount> 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.

View File

@ -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)

View File

@ -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 <length> <radius> <node>",
description = "Add hollow cylinder at WorldEdit position 1 along the x/y/z axis with length <length> and radius <radius>, composed of <node>",
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 <length> <radius> <node>",
description = "Add cylinder at WorldEdit position 1 along the x/y/z axis with length <length> and radius <radius>, composed of <node>",
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 <amount>",
description = "Copy the current WorldEdit region along the x/y/z axis by <amount> nodes",