diff --git a/README.md b/README.md index a52d96a..a83f2f4 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,15 @@ Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length //cylinder y 28 10 default:glass //cylinder z -12 3 mesecons:mesecon //cylinder ? 2 4 stone + +### //spiral + +Add Spiral at WorldEdit position 1 with size , composed of . + + //spiral 8 dirt + //spiral 5 default:glass + //spiral 2 stone + ### //copy x/y/z/? @@ -216,6 +225,12 @@ Adds a cylinder at `pos` along the `axis` axis ("x" or "y" or "z") with length ` Returns the number of nodes added. +### worldedit.spiral(pos, size, nodename) + +Adds a Spiral at `pos` with size `size`. + +Returns the number of nodes changed. + ### 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. @@ -286,4 +301,4 @@ This mod is licensed under the [GNU Affero General Public License](http://www.gn Basically, this means everyone is free to use, modify, and distribute the files, as long as these modifications are also licensed the same way. -Most importantly, the Affero variant of the GPL requires you to publish your modifications in source form, even if the mod is run only on the server, and not distributed. \ No newline at end of file +Most importantly, the Affero variant of the GPL requires you to publish your modifications in source form, even if the mod is run only on the server, and not distributed. diff --git a/functions.lua b/functions.lua index 270b50e..ee549de 100644 --- a/functions.lua +++ b/functions.lua @@ -1,3 +1,4 @@ +dofile(minetest.get_modpath("worldedit") .. "/spirals.lua") --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 worldedit.sort_pos = function(pos1, pos2) pos1 = {x=pos1.x, y=pos1.y, z=pos1.z} @@ -182,6 +183,26 @@ worldedit.cylinder = function(pos, axis, length, radius, nodename) return count end +--adds a spiral at `pos` with size `size`, returning the number of nodes changed +worldedit.spiral = function(pos, size, nodename) + local shift_x,shift_y + sa = spiralt(size) + shift_y = #sa -- "Height" of the Array + local fe = sa[1] + shift_x = #fe -- "Width" of the Array + fe = nil + + local count = 0 + for x,v in ipairs(sa) do + for y, z in ipairs(v) do + minetest.env:add_node({x=pos.x-shift_x+x,y=pos.y-shift_y+y,z=pos.z+z}, {name=nodename}) + count = count + 1 + 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) @@ -476,4 +497,4 @@ worldedit.deserialize_old = function(originpos, value) count = count + 1 end return count -end \ No newline at end of file +end diff --git a/init.lua b/init.lua index 10d03b8..cef7e53 100644 --- a/init.lua +++ b/init.lua @@ -216,6 +216,36 @@ minetest.register_chatcommand("/hollowcylinder", { end, }) + +minetest.register_chatcommand("/spiral", { + params = " ", + description = "Add Spiral at WorldEdit position 1 with size , composed of ", + 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, _, size, nodename = param:find("(%d+)%s+([^%s]+)$") + if found == nil then + minetest.chat_send_player(name, "Invalid usage: " .. param) + return + end + if axis == "?" then + axis = worldedit.player_axis(name) + end + if not worldedit.node_is_valid(pos, nodename) then + minetest.chat_send_player(name, "Invalid node name: " .. param) + return + end + + local count = worldedit.spiral(pos, tonumber(size), nodename) + minetest.chat_send_player(name, count .. " nodes changed") + end, +}) + minetest.register_chatcommand("/cylinder", { params = "x/y/z/? ", description = "Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length and radius , composed of ", @@ -486,4 +516,4 @@ minetest.register_chatcommand("/load", { minetest.chat_send_player(name, count .. " nodes loaded") end, -}) \ No newline at end of file +}) diff --git a/spirals.lua b/spirals.lua new file mode 100644 index 0000000..0a8dea1 --- /dev/null +++ b/spirals.lua @@ -0,0 +1,17 @@ +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