diff --git a/Chat Commands.md b/Chat Commands.md index 861f4ae..bfca8bf 100644 --- a/Chat Commands.md +++ b/Chat Commands.md @@ -155,18 +155,27 @@ Flip the current WorldEdit region along the x/y/z/? axis. ### //rotate x/y/z/? -Rotate the current WorldEdit positions and region along the x/y/z/? axis by angle (integer multiple of 90 degrees). +Rotate the current WorldEdit positions and region along the x/y/z/? axis by angle (90 degree increment). //rotate x 90 //rotate y 180 //rotate z 270 //rotate ? -90 +### //orient + +Rotate oriented nodes in the current WorldEdit region around the Y axis by angle (90 degree increment) + + //orient 90 + //orient 180 + //orient 270 + //orient -90 + ### //fixlight Fixes the lighting in the current WorldEdit region. - //dig + //fixlight ## //hide diff --git a/WorldEdit API.md b/WorldEdit API.md index be2270d..a0a1a60 100644 --- a/WorldEdit API.md +++ b/WorldEdit API.md @@ -56,6 +56,12 @@ Rotates a region defined by the positions `pos1` and `pos2` by `angle` degrees c Returns the number of nodes rotated, the new position 1, and the new position 2. +### count = worldedit.orient(pos1, pos2, angle) + +Rotates all oriented nodes in a region defined by the positions `pos1` and `pos2` by `angle` degrees clockwise (90 degree increment) around the Y axis. + +Returns the number of nodes oriented. + ### count = worldedit.fixlight(pos1, pos2) Fixes the lighting in a region defined by positions `pos1` and `pos2`. diff --git a/worldedit/manipulations.lua b/worldedit/manipulations.lua index 1903084..253456c 100644 --- a/worldedit/manipulations.lua +++ b/worldedit/manipulations.lua @@ -304,6 +304,62 @@ worldedit.rotate = function(pos1, pos2, axis, angle) return count, pos1, pos2 end +--rotates all oriented nodes in a region defined by the positions `pos1` and `pos2` by `angle` degrees clockwise (90 degree increment) around the Y axis, returning the number of nodes oriented +worldedit.orient = function(pos1, pos2, angle) + local pos1, pos2 = worldedit.sort_pos(pos1, pos2) + local nodes = minetest.registered_nodes + local env = minetest.env + local wallmounted = { + [90]={[0]=0, [1]=1, [2]=5, [3]=4, [4]=2, [5]=3}, + [180]={[0]=0, [1]=1, [2]=3, [3]=2, [4]=5, [5]=4}, + [270]={[0]=0, [1]=1, [2]=4, [3]=5, [4]=3, [5]=2} + } + local facedir = { + [90]={[0]=1, [1]=2, [2]=3, [3]=0}, + [180]={[0]=2, [1]=3, [2]=0, [3]=1}, + [270]={[0]=3, [1]=0, [2]=1, [3]=2} + } + + angle = angle % 360 + if angle == 0 then + return 0 + end + local wallmounted_substitution = wallmounted[angle] + local facedir_substitution = facedir[angle] + + local count = 0 + local pos = {x=pos1.x, y=0, z=0} + while pos.x <= pos2.x do + pos.y = pos1.y + while pos.y <= pos2.y do + pos.z = pos1.z + while pos.z <= pos2.z do + local node = env:get_node(pos) + local def = nodes[node.name] + if def then + if def.paramtype2 == "wallmounted" then + node.param2 = wallmounted_substitution[node.param2] + local meta = env:get_meta(pos):to_table() + env:add_node(pos, node) + env:get_meta(pos):from_table(meta) + count = count + 1 + elseif def.paramtype2 == "facedir" then + node.param2 = facedir_substitution[node.param2] + local meta = env:get_meta(pos):to_table() + env:add_node(pos, node) + env:get_meta(pos):from_table(meta) + count = count + 1 + end + end + pos.z = pos.z + 1 + end + pos.y = pos.y + 1 + end + pos.x = pos.x + 1 + end + return count +end + --fixes the lighting in a region defined by positions `pos1` and `pos2`, returning the number of nodes updated worldedit.fixlight = function(pos1, pos2) local pos1, pos2 = worldedit.sort_pos(pos1, pos2) diff --git a/worldedit_commands/init.lua b/worldedit_commands/init.lua index b0e15b3..15220c6 100644 --- a/worldedit_commands/init.lua +++ b/worldedit_commands/init.lua @@ -544,6 +544,33 @@ minetest.register_chatcommand("/rotate", { end, }) +minetest.register_chatcommand("/orient", { + params = "", + description = "Rotate oriented nodes in the current WorldEdit region around the Y axis by angle (90 degree increment)", + privs = {worldedit=true}, + func = function(name, param) + local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name] + if pos1 == nil or pos2 == nil then + minetest.chat_send_player(name, "No WorldEdit region selected") + return + end + + local found, _, angle = param:find("^([+-]?%d+)$") + if found == nil then + minetest.chat_send_player(name, "Invalid usage: " .. param) + return + end + if angle % 90 ~= 0 then + minetest.chat_send_player(name, "Invalid usage: angle must be multiple of 90") + return + end + + local count = worldedit.orient(pos1, pos2, angle) + + minetest.chat_send_player(name, count .. " nodes oriented") + end, +}) + minetest.register_chatcommand("/fixlight", { params = "", description = "Fix the lighting in the current WorldEdit region",