diff options
| -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,
  })
 | 
