From 340416c789fc8a2e32ae39c28b0ea6eea403bb4d Mon Sep 17 00:00:00 2001 From: Anthony Zhang Date: Thu, 30 Aug 2012 16:17:15 -0400 Subject: [PATCH] Fix player axis detection, make spirals code a bit easier to read. --- README.md | 4 +-- functions.lua | 82 +++++++++++++++++++++++++++++++++++++++++---------- init.lua | 32 ++++++++++++-------- spirals.lua | 17 ----------- 4 files changed, 88 insertions(+), 47 deletions(-) delete mode 100644 spirals.lua diff --git a/README.md b/README.md index a83f2f4..676d425 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ Add cylinder at WorldEdit position 1 along the x/y/z/? axis with length ### //spiral -Add Spiral at WorldEdit position 1 with size , composed of . +Add spiral at WorldEdit position 1 with size , composed of . //spiral 8 dirt //spiral 5 default:glass @@ -227,7 +227,7 @@ Returns the number of nodes added. ### 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. diff --git a/functions.lua b/functions.lua index ee549de..f22e15d 100644 --- a/functions.lua +++ b/functions.lua @@ -1,4 +1,3 @@ -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} @@ -185,24 +184,77 @@ 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 + 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 - + shift_y = #sa -- "Height" of the Array + local fe = sa[1] + shift_x = #fe -- "Width" of the Array + fe = nil + + local count = 0 + local node = {name=nodename} + 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}, node) + count = count + 1 + end + end return count end +--wip: +sign = function(s) + if s > 0 then + return 1 + end + if s < 0 then + return -1 + end + return 0 +end + +--wip: needs to be faster +function spiral_index(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(math.abs(y), math.abs(x)) + local value + if math.abs(y) == l then + value = x + if y < 0 then + value = -value + end + else + value = y + if x < 0 then + value = -value + end + end + t1 = l * 2 + if x + y < 0 then + t1 = -t1 + end + t2 = y ^ 2 - x ^ 2 + if t2 < 0 then + t2 = -t2 + end + return ((2 * l - 1) ^ 2) + (l * 4) + t1 + (t2 * (l - value)) +end + +--wip: needs to be faster +function spiralt(side) + local spiral = {} + local start, stop = math.floor((-side+1)/2), math.floor((side-1)/2) + for i = 1, side do + spiral[i] = {} + for j = 1, side do + 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 + end + end + return spiral +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) diff --git a/init.lua b/init.lua index 7bd79be..1c3d323 100644 --- a/init.lua +++ b/init.lua @@ -16,16 +16,18 @@ worldedit.node_is_valid = function(temp_pos, nodename) or minetest.registered_nodes["default:" .. nodename] ~= nil end +--determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1) worldedit.player_axis = function(name) local dir = minetest.env:get_player_by_name(name):get_look_dir() - if dir.x > dir.y then - if dir.x > dir.z then - return "x" + local x, y, z = math.abs(dir.x), math.abs(dir.y), math.abs(dir.z) + if x > y then + if x > z then + return "x", dir.x > 0 and 1 or -1 end - elseif dir.y > dir.z then - return "y" + elseif y > z then + return "y", dir.y > 0 and 1 or -1 end - return "z" + return "z", dir.z > 0 and 1 or -1 end minetest.register_chatcommand("/reset", { @@ -204,7 +206,8 @@ minetest.register_chatcommand("/hollowcylinder", { return end if axis == "?" then - axis = worldedit.player_axis(name) + 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) @@ -216,10 +219,9 @@ minetest.register_chatcommand("/hollowcylinder", { end, }) - minetest.register_chatcommand("/spiral", { params = " ", - description = "Add Spiral at WorldEdit position 1 with size , composed of ", + description = "Add spiral at WorldEdit position 1 with size , composed of ", privs = {worldedit=true}, func = function(name, param) local pos = worldedit.pos1[name] @@ -260,7 +262,8 @@ minetest.register_chatcommand("/cylinder", { return end if axis == "?" then - axis = worldedit.player_axis(name) + 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) @@ -289,7 +292,8 @@ minetest.register_chatcommand("/copy", { return end if axis == "?" then - axis = worldedit.player_axis(name) + axis, sign = worldedit.player_axis(name) + amount = amount * sign end local count = worldedit.copy(pos1, pos2, axis, tonumber(amount)) @@ -314,7 +318,8 @@ minetest.register_chatcommand("/move", { return end if axis == "?" then - axis = worldedit.player_axis(name) + axis, sign = worldedit.player_axis(name) + amount = amount * sign end local count = worldedit.move(pos1, pos2, axis, tonumber(amount)) @@ -339,7 +344,8 @@ minetest.register_chatcommand("/stack", { return end if axis == "?" then - axis = worldedit.player_axis(name) + axis, sign = worldedit.player_axis(name) + count = count * sign end local count = worldedit.stack(pos1, pos2, axis, tonumber(count)) diff --git a/spirals.lua b/spirals.lua deleted file mode 100644 index 0a8dea1..0000000 --- a/spirals.lua +++ /dev/null @@ -1,17 +0,0 @@ -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