]> git.lizzy.rs Git - worldedit.git/commitdiff
Fix worldedit.spiral and the correspondign chat command, //spiral.
authorBrett O'Donnell <cornernote@gmail.com>
Wed, 26 Sep 2012 22:36:11 +0000 (18:36 -0400)
committerAnthony Zhang <azhang9@gmail.com>
Wed, 26 Sep 2012 22:36:11 +0000 (18:36 -0400)
README.md
functions.lua
init.lua

index 5324efb0284c1fc3493f53a3790c97c20b67a3c5..f6dbf8776db5ec5a11de74286fbc56f5eaaa69c8 100644 (file)
--- 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.
index 9f75468cfed14000027447a314ddb5fde2127158..2d949c65bf2fdcb43f6f6e061010941bbbcffaca 100644 (file)
@@ -267,6 +267,72 @@ worldedit.pyramid = function(pos, height, nodename)
        return count\r
 end\r
 \r
+--adds a spiral at `pos` with width `width`, height `height`, space between walls `spacer`, composed of `nodename`, returning the number of nodes added\r
+worldedit.spiral = function(pos, width, height, spacer, nodename) --wip: clean this up\r
+       -- spiral matrix - http://rosettacode.org/wiki/Spiral_matrix#Lua\r
+       av, sn = math.abs, function(s) return s~=0 and s/av(s) or 0 end\r
+       local function sindex(z, x) -- returns the value at (x, z) in a spiral that starts at 1 and goes outwards\r
+               if z == -x and z >= x then return (2*z+1)^2 end\r
+               local l = math.max(av(z), av(x))\r
+               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\r
+       end\r
+       local function spiralt(side)\r
+               local ret, id, start, stop = {}, 0, math.floor((-side+1)/2), math.floor((side-1)/2)\r
+               for i = 1, side do\r
+                       for j = 1, side do\r
+                               local id = side^2 - sindex(stop - i + 1,start + j - 1)\r
+                               ret[id] = {x=i,z=j}\r
+                       end\r
+               end\r
+               return ret\r
+       end\r
+       -- connect the joined parts\r
+       local spiral = spiralt(width)\r
+       height = tonumber(height)\r
+       if height < 1 then height = 1 end\r
+       spacer = tonumber(spacer)-1\r
+       if spacer < 1 then spacer = 1 end\r
+       local count = 0\r
+       local node = {name=nodename}\r
+       local np,lp\r
+       for y=0,height do\r
+               lp = nil\r
+               for _,v in ipairs(spiral) do\r
+                       np = {x=pos.x+v.x*spacer, y=pos.y+y, z=pos.z+v.z*spacer}\r
+                       if lp~=nil then\r
+                               if lp.x~=np.x then \r
+                                       if lp.x<np.x then \r
+                                               for i=lp.x+1,np.x do\r
+                                                       minetest.env:add_node({x=i, y=np.y, z=np.z}, node)\r
+                                                       count = count + 1\r
+                                               end\r
+                                       else\r
+                                               for i=np.x,lp.x-1 do\r
+                                                       minetest.env:add_node({x=i, y=np.y, z=np.z}, node)\r
+                                                       count = count + 1\r
+                                               end\r
+                                       end\r
+                               end\r
+                               if lp.z~=np.z then \r
+                                       if lp.z<np.z then \r
+                                               for i=lp.z+1,np.z do\r
+                                                       minetest.env:add_node({x=np.x, y=np.y, z=i}, node)\r
+                                                       count = count + 1\r
+                                               end\r
+                                       else\r
+                                               for i=np.z,lp.z-1 do\r
+                                                       minetest.env:add_node({x=np.x, y=np.y, z=i}, node)\r
+                                                       count = count + 1\r
+                                               end\r
+                                       end\r
+                               end\r
+                       end\r
+                       lp = np\r
+               end\r
+       end\r
+       return count\r
+end\r
+\r
 --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\r
 worldedit.copy = function(pos1, pos2, axis, amount)\r
        local pos1, pos2 = worldedit.sort_pos(pos1, pos2)\r
index da462c57a883f429ec355f99d3c0c5e96e8fd5a1..84cf4fe6880862994b9c4d571a198deb0b9301b2 100644 (file)
--- a/init.lua
+++ b/init.lua
@@ -271,6 +271,36 @@ minetest.register_chatcommand("/hollowcylinder", {
        end,\r
 })\r
 \r
+minetest.register_chatcommand("/cylinder", {\r
+       params = "x/y/z/? <length> <radius> <node>",\r
+       description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>",\r
+       privs = {worldedit=true},\r
+       func = function(name, param)\r
+               local pos = worldedit.pos1[name]\r
+               if pos == nil then\r
+                       minetest.chat_send_player(name, "No WorldEdit region selected")\r
+                       return\r
+               end\r
+\r
+               local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$")\r
+               if found == nil then\r
+                       minetest.chat_send_player(name, "Invalid usage: " .. param)\r
+                       return\r
+               end\r
+               if axis == "?" then\r
+                       axis, sign = worldedit.player_axis(name)\r
+                       length = length * sign\r
+               end\r
+               if not worldedit.node_is_valid(pos, nodename) then\r
+                       minetest.chat_send_player(name, "Invalid node name: " .. param)\r
+                       return\r
+               end\r
+\r
+               local count = worldedit.cylinder(pos, axis, tonumber(length), tonumber(radius), nodename)\r
+               minetest.chat_send_player(name, count .. " nodes added")\r
+       end,\r
+})\r
+\r
 minetest.register_chatcommand("/pyramid", {\r
        params = "<height> <node>",\r
        description = "Add pyramid at WorldEdit position 1 with height <height>, composed of <node>",\r
@@ -297,9 +327,9 @@ minetest.register_chatcommand("/pyramid", {
        end,\r
 })\r
 \r
-minetest.register_chatcommand("/cylinder", {\r
-       params = "x/y/z/? <length> <radius> <node>",\r
-       description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length <length> and radius <radius>, composed of <node>",\r
+minetest.register_chatcommand("/spiral", {\r
+       params = "<width> <height> <space> <node>",\r
+       description = "Add spiral at WorldEdit position 1 with width <width>, height <height>, space between walls <space>, composed of <node>",\r
        privs = {worldedit=true},\r
        func = function(name, param)\r
                local pos = worldedit.pos1[name]\r
@@ -308,22 +338,18 @@ minetest.register_chatcommand("/cylinder", {
                        return\r
                end\r
 \r
-               local found, _, axis, length, radius, nodename = param:find("^([xyz%?])%s+([+-]?%d+)%s+(%d+)%s+([^%s]+)$")\r
+               local found, _, width, height, space, nodename = param:find("(%d+)%s+(%d+)%s+(%d+)%s+([^%s]+)$")\r
                if found == nil then\r
                        minetest.chat_send_player(name, "Invalid usage: " .. param)\r
                        return\r
                end\r
-               if axis == "?" then\r
-                       axis, sign = worldedit.player_axis(name)\r
-                       length = length * sign\r
-               end\r
                if not worldedit.node_is_valid(pos, nodename) then\r
                        minetest.chat_send_player(name, "Invalid node name: " .. param)\r
                        return\r
                end\r
 \r
-               local count = worldedit.cylinder(pos, axis, tonumber(length), tonumber(radius), nodename)\r
-               minetest.chat_send_player(name, count .. " nodes added")\r
+               local count = worldedit.spiral(pos, tonumber(width), tonumber(height), tonumber(space), nodename)\r
+               minetest.chat_send_player(name, count .. " nodes changed")\r
        end,\r
 })\r
 \r