### //spiral <size> <node>
-Add Spiral at WorldEdit position 1 with size <size>, composed of <node>.
+Add spiral at WorldEdit position 1 with size <size>, composed of <node>.
//spiral 8 dirt
//spiral 5 default:glass
### worldedit.spiral(pos, size, nodename)
-Adds a Spiral at `pos` with size `size`.
+Adds a spiral at `pos` with size `size`.
Returns the number of nodes changed.
-dofile(minetest.get_modpath("worldedit") .. "/spirals.lua")\r
--modifies positions `pos1` and `pos2` so that each component of `pos1` is less than or equal to its corresponding conent of `pos2`, returning two new positions\r
worldedit.sort_pos = function(pos1, pos2)\r
pos1 = {x=pos1.x, y=pos1.y, z=pos1.z}\r
\r
--adds a spiral at `pos` with size `size`, returning the number of nodes changed\r
worldedit.spiral = function(pos, size, nodename)\r
- local shift_x,shift_y\r
+ local shift_x, shift_y\r
sa = spiralt(size)\r
- shift_y = #sa -- "Height" of the Array\r
- local fe = sa[1]\r
- shift_x = #fe -- "Width" of the Array\r
- fe = nil\r
- \r
- local count = 0\r
- for x,v in ipairs(sa) do\r
- for y, z in ipairs(v) do\r
- minetest.env:add_node({x=pos.x-shift_x+x,y=pos.y-shift_y+y,z=pos.z+z}, {name=nodename})\r
- count = count + 1\r
- end\r
- end\r
- \r
+ shift_y = #sa -- "Height" of the Array\r
+ local fe = sa[1]\r
+ shift_x = #fe -- "Width" of the Array\r
+ fe = nil\r
+\r
+ local count = 0\r
+ local node = {name=nodename}\r
+ for x, v in ipairs(sa) do\r
+ for y, z in ipairs(v) do\r
+ minetest.env:add_node({x=pos.x - shift_x + x,y=pos.y - shift_y + y,z=pos.z + z}, node)\r
+ count = count + 1\r
+ end\r
+ end\r
return count\r
end\r
\r
+--wip: \r
+sign = function(s)\r
+ if s > 0 then\r
+ return 1\r
+ end\r
+ if s < 0 then\r
+ return -1\r
+ end\r
+ return 0\r
+end\r
+\r
+--wip: needs to be faster\r
+function spiral_index(y, x) -- returns the value at (x, y) in a spiral that starts at 1 and goes outwards\r
+ if y == -x and y >= x then\r
+ return (2 * y + 1) ^ 2\r
+ end\r
+ local l = math.max(math.abs(y), math.abs(x))\r
+ local value\r
+ if math.abs(y) == l then\r
+ value = x\r
+ if y < 0 then\r
+ value = -value\r
+ end\r
+ else\r
+ value = y\r
+ if x < 0 then\r
+ value = -value\r
+ end\r
+ end\r
+ t1 = l * 2\r
+ if x + y < 0 then\r
+ t1 = -t1\r
+ end\r
+ t2 = y ^ 2 - x ^ 2\r
+ if t2 < 0 then\r
+ t2 = -t2\r
+ end\r
+ return ((2 * l - 1) ^ 2) + (l * 4) + t1 + (t2 * (l - value))\r
+end\r
+\r
+--wip: needs to be faster\r
+function spiralt(side)\r
+ local spiral = {}\r
+ local start, stop = math.floor((-side+1)/2), math.floor((side-1)/2)\r
+ for i = 1, side do\r
+ spiral[i] = {}\r
+ for j = 1, side do\r
+ spiral[i][j] = side ^ 2 - spiral_index(stop - i + 1,start + j - 1) --moves the coordinates so (0,0) is at the center of the spiral\r
+ end\r
+ end\r
+ return spiral\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
or minetest.registered_nodes["default:" .. nodename] ~= nil\r
end\r
\r
+--determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1)\r
worldedit.player_axis = function(name)\r
local dir = minetest.env:get_player_by_name(name):get_look_dir()\r
- if dir.x > dir.y then\r
- if dir.x > dir.z then\r
- return "x"\r
+ local x, y, z = math.abs(dir.x), math.abs(dir.y), math.abs(dir.z)\r
+ if x > y then\r
+ if x > z then\r
+ return "x", dir.x > 0 and 1 or -1\r
end\r
- elseif dir.y > dir.z then\r
- return "y"\r
+ elseif y > z then\r
+ return "y", dir.y > 0 and 1 or -1\r
end\r
- return "z"\r
+ return "z", dir.z > 0 and 1 or -1\r
end\r
\r
minetest.register_chatcommand("/reset", {\r
return\r
end\r
if axis == "?" then\r
- axis = worldedit.player_axis(name)\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
end,\r
})\r
\r
-\r
minetest.register_chatcommand("/spiral", {\r
params = "<size> <node>",\r
- description = "Add Spiral at WorldEdit position 1 with size <size>, composed of <node>",\r
+ description = "Add spiral at WorldEdit position 1 with size <size>, composed of <node>",\r
privs = {worldedit=true},\r
func = function(name, param)\r
local pos = worldedit.pos1[name]\r
return\r
end\r
if axis == "?" then\r
- axis = worldedit.player_axis(name)\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
if axis == "?" then\r
- axis = worldedit.player_axis(name)\r
+ axis, sign = worldedit.player_axis(name)\r
+ amount = amount * sign\r
end\r
\r
local count = worldedit.copy(pos1, pos2, axis, tonumber(amount))\r
return\r
end\r
if axis == "?" then\r
- axis = worldedit.player_axis(name)\r
+ axis, sign = worldedit.player_axis(name)\r
+ amount = amount * sign\r
end\r
\r
local count = worldedit.move(pos1, pos2, axis, tonumber(amount))\r
return\r
end\r
if axis == "?" then\r
- axis = worldedit.player_axis(name)\r
+ axis, sign = worldedit.player_axis(name)\r
+ count = count * sign\r
end\r
\r
local count = worldedit.stack(pos1, pos2, axis, tonumber(count))\r
+++ /dev/null
-av, sn = math.abs, function(s) return s~=0 and s/av(s) or 0 end
-function sindex(y, x) -- returns the value at (x, y) in a spiral that starts at 1 and goes outwards
- if y == -x and y >= x then return (2*y+1)^2 end
- local l = math.max(av(y), av(x))
- return (2*l-1)^2+4*l+2*l*sn(x+y)+sn(y^2-x^2)*(l-(av(y)==l and sn(y)*x or sn(x)*y)) -- OH GOD WHAT
-end
-
-function spiralt(side)
- local ret, start, stop = {}, math.floor((-side+1)/2), math.floor((side-1)/2)
- for i = 1, side do
- ret[i] = {}
- for j = 1, side do
- ret[i][j] = side^2 - sindex(stop - i + 1,start + j - 1) --moves the coordinates so (0,0) is at the center of the spiral
- end
- end
- return ret
-end