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 , composed of . //pyramid 5 default:glass //pyramid 2 stone +### //spiral + +Add spiral at WorldEdit position 1 with width , height , space between walls , composed of . + + //spiral 20 5 3 dirt + //spiral 5 2 1 default:glass + //spiral 7 1 5 stone ### //copy x/y/z/? @@ -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