diff options
author | Brett O'Donnell <cornernote@gmail.com> | 2012-09-26 18:36:11 -0400 |
---|---|---|
committer | Anthony Zhang <azhang9@gmail.com> | 2012-09-26 18:36:11 -0400 |
commit | a82ab9176f831b4f1beb9d2f3c3a7d582abf8b44 (patch) | |
tree | 94cccae40f75d943e73a672c28e9a75a3dff115a | |
parent | 382c57d008dfa8e1c26263d572d606e5d0f7f2ce (diff) |
Fix worldedit.spiral and the correspondign chat command, //spiral.
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | functions.lua | 66 | ||||
-rw-r--r-- | init.lua | 46 |
3 files changed, 115 insertions, 10 deletions
@@ -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)
@@ -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,
})
|