summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md13
-rw-r--r--functions.lua66
-rw-r--r--init.lua46
3 files changed, 115 insertions, 10 deletions
diff --git a/README.md b/README.md
index 5324efb..f6dbf87 100644
--- a/README.md
+++ b/README.md
@@ -133,6 +133,13 @@ Add pyramid at WorldEdit position 1 with height <height>, composed of <node>.
//pyramid 5 default:glass
//pyramid 2 stone
+### //spiral <width> <height> <spacer> <node>
+
+Add spiral at WorldEdit position 1 with width <width>, height <height>, space between walls <spacer>, composed of <node>.
+
+ //spiral 20 5 3 dirt
+ //spiral 5 2 1 default:glass
+ //spiral 7 1 5 stone
### //copy x/y/z/? <amount>
@@ -274,6 +281,12 @@ Adds a pyramid at `pos` with height `height`.
Returns the number of nodes added.
+### worldedit.spiral(pos, width, height, spacer, nodename)
+
+Adds a spiral at `pos` with width `width`, height `height`, space between walls `spacer`, composed of `nodename`.
+
+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 9f75468..2d949c6 100644
--- a/functions.lua
+++ b/functions.lua
@@ -267,6 +267,72 @@ worldedit.pyramid = function(pos, height, nodename)
return count
end
+--adds a spiral at `pos` with width `width`, height `height`, space between walls `spacer`, composed of `nodename`, returning the number of nodes added
+worldedit.spiral = function(pos, width, height, spacer, nodename) --wip: clean this up
+ -- spiral matrix - http://rosettacode.org/wiki/Spiral_matrix#Lua
+ av, sn = math.abs, function(s) return s~=0 and s/av(s) or 0 end
+ local function sindex(z, x) -- returns the value at (x, z) in a spiral that starts at 1 and goes outwards
+ if z == -x and z >= x then return (2*z+1)^2 end
+ local l = math.max(av(z), av(x))
+ return (2*l-1)^2+4*l+2*l*sn(x+z)+sn(z^2-x^2)*(l-(av(z)==l and sn(z)*x or sn(x)*z)) -- OH GOD WHAT
+ end
+ local function spiralt(side)
+ local ret, id, start, stop = {}, 0, math.floor((-side+1)/2), math.floor((side-1)/2)
+ for i = 1, side do
+ for j = 1, side do
+ local id = side^2 - sindex(stop - i + 1,start + j - 1)
+ ret[id] = {x=i,z=j}
+ end
+ end
+ return ret
+ end
+ -- connect the joined parts
+ local spiral = spiralt(width)
+ height = tonumber(height)
+ if height < 1 then height = 1 end
+ spacer = tonumber(spacer)-1
+ if spacer < 1 then spacer = 1 end
+ local count = 0
+ local node = {name=nodename}
+ local np,lp
+ for y=0,height do
+ lp = nil
+ for _,v in ipairs(spiral) do
+ np = {x=pos.x+v.x*spacer, y=pos.y+y, z=pos.z+v.z*spacer}
+ if lp~=nil then
+ if lp.x~=np.x then
+ if lp.x<np.x then
+ for i=lp.x+1,np.x do
+ minetest.env:add_node({x=i, y=np.y, z=np.z}, node)
+ count = count + 1
+ end
+ else
+ for i=np.x,lp.x-1 do
+ minetest.env:add_node({x=i, y=np.y, z=np.z}, node)
+ count = count + 1
+ end
+ end
+ end
+ if lp.z~=np.z then
+ if lp.z<np.z then
+ for i=lp.z+1,np.z do
+ minetest.env:add_node({x=np.x, y=np.y, z=i}, node)
+ count = count + 1
+ end
+ else
+ for i=np.z,lp.z-1 do
+ minetest.env:add_node({x=np.x, y=np.y, z=i}, node)
+ count = count + 1
+ end
+ end
+ end
+ end
+ lp = np
+ end
+ 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 da462c5..84cf4fe 100644
--- a/init.lua
+++ b/init.lua
@@ -271,6 +271,36 @@ minetest.register_chatcommand("/hollowcylinder", {
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 axis == "?" then
+ axis, sign = worldedit.player_axis(name)
+ length = length * sign
+ 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("/pyramid", {
params = "<height> <node>",
description = "Add pyramid at WorldEdit position 1 with height <height>, composed of <node>",
@@ -297,9 +327,9 @@ minetest.register_chatcommand("/pyramid", {
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>",
+minetest.register_chatcommand("/spiral", {
+ params = "<width> <height> <space> <node>",
+ description = "Add spiral at WorldEdit position 1 with width <width>, height <height>, space between walls <space>, composed of <node>",
privs = {worldedit=true},
func = function(name, param)
local pos = worldedit.pos1[name]
@@ -308,22 +338,18 @@ minetest.register_chatcommand("/cylinder", {
return
end
- local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$")
+ local found, _, width, height, space, nodename = param:find("(%d+)%s+(%d+)%s+(%d+)%s+([^%s]+)$")
if found == nil then
minetest.chat_send_player(name, "Invalid usage: " .. param)
return
end
- if axis == "?" then
- axis, sign = worldedit.player_axis(name)
- length = length * sign
- 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")
+ local count = worldedit.spiral(pos, tonumber(width), tonumber(height), tonumber(space), nodename)
+ minetest.chat_send_player(name, count .. " nodes changed")
end,
})