diff --git a/worldedit_commands/depends.txt b/worldedit_commands/depends.txt index df8caff..d862cd8 100644 --- a/worldedit_commands/depends.txt +++ b/worldedit_commands/depends.txt @@ -1 +1,2 @@ -worldedit \ No newline at end of file +worldedit +areas? diff --git a/worldedit_commands/init.lua b/worldedit_commands/init.lua index 61aafc1..a2e4552 100644 --- a/worldedit_commands/init.lua +++ b/worldedit_commands/init.lua @@ -13,7 +13,7 @@ end dofile(minetest.get_modpath("worldedit_commands") .. "/cuboid.lua") dofile(minetest.get_modpath("worldedit_commands") .. "/mark.lua") dofile(minetest.get_modpath("worldedit_commands") .. "/wand.lua") -local safe_region, check_region, reset_pending = dofile(minetest.get_modpath("worldedit_commands") .. "/safe.lua") +local safe_region, check_region, reset_pending, area_protection = dofile(minetest.get_modpath("worldedit_commands") .. "/safe.lua") local function get_position(name) --position 1 retrieval function for when not using `safe_region` local pos1 = worldedit.pos1[name] @@ -545,6 +545,24 @@ local check_sphere = function(name, param) worldedit.player_notify(name, "invalid usage: " .. param) return nil end + local pos1 = worldedit.pos1[name] + local allowed = area_protection:interaction_allowed( + "sphere", + { + x = pos1.x - radius, + y = pos1.y - radius, + z = pos1.z - radius, + }, + { + x = pos1.x + radius, + y = pos1.y + radius, + z = pos1.z + radius, + }, + name + ) + if not allowed then + return nil + end local node = get_node(name, nodename) if not node then return nil end return math.ceil((4 * math.pi * (tonumber(radius) ^ 3)) / 3) --volume of sphere @@ -584,6 +602,24 @@ local check_dome = function(name, param) worldedit.player_notify(name, "invalid usage: " .. param) return nil end + local pos1 = worldedit.pos1[name] + local allowed = area_protection:interaction_allowed( + "dome", + { + x = pos1.x - radius, + y = pos1.y, + z = pos1.z - radius, + }, + { + x = pos1.x + radius, + y = pos1.y + radius, + z = pos1.z + radius, + }, + name + ) + if not allowed then + return nil + end local node = get_node(name, nodename) if not node then return nil end return math.ceil((2 * math.pi * (tonumber(radius) ^ 3)) / 3) --volume of dome @@ -629,6 +665,34 @@ local check_cylinder = function(name, param) worldedit.player_notify(name, "invalid usage: " .. param) return nil end + length = tonumber(length) + if axis == "?" then + local sign + axis, sign = worldedit.player_axis(name) + length = length * sign + end + local current_pos = vector.new(worldedit.pos1[name]) + if length < 0 then + length = -length + current_pos[axis] = current_pos[axis] - length + end + local other1, other2 = worldedit.get_axis_others(axis) + local interact_pos1 = vector.new(current_pos) + local interact_pos2 = vector.new(current_pos) + interact_pos1[other1] = interact_pos1[other1] - radius + interact_pos1[other2] = interact_pos1[other2] - radius + interact_pos2[other1] = interact_pos2[other1] + radius + interact_pos2[other2] = interact_pos2[other2] + radius + interact_pos2[axis] = interact_pos2[axis] + length + local allowed = area_protection:interaction_allowed( + "cylinder", + interact_pos1, + interact_pos2, + name + ) + if not allowed then + return nil + end local node = get_node(name, nodename) if not node then return nil end local radius = math.max(tonumber(radius1), tonumber(radius2)) @@ -693,6 +757,30 @@ local check_pyramid = function(name, param) worldedit.player_notify(name, "invalid usage: " .. param) return nil end + height = tonumber(height) + if axis == "?" then + local sign + axis, sign = worldedit.player_axis(name) + height = height * sign + end + local pos1 = worldedit.pos1[name] + local other1, other2 = worldedit.get_axis_others(axis) + local interact_pos1 = vector.new(pos1) + local interact_pos2 = vector.new(pos1) + interact_pos1[other1] = interact_pos1[other1] - height + interact_pos1[other2] = interact_pos1[other2] - height + interact_pos2[other1] = interact_pos2[other1] + height + interact_pos2[other2] = interact_pos2[other2] + height + interact_pos2[axis] = interact_pos2[axis] + height + local allowed = area_protection:interaction_allowed( + "pyramid", + interact_pos1, + interact_pos2, + name + ) + if not allowed then + return nil + end local node = get_node(name, nodename) if not node then return nil end height = tonumber(height) @@ -746,6 +834,13 @@ minetest.register_chatcommand("/spiral", { worldedit.player_notify(name, count .. " nodes added") end, function(name, param) + if area_protection:interaction_restrictions(name) then + worldedit.player_notify( + name, + "/spiral not yet supported with area protection" + ) + return nil + end if worldedit.pos1[name] == nil then worldedit.player_notify(name, "no position 1 selected") return nil @@ -872,6 +967,13 @@ minetest.register_chatcommand("/stack2", { worldedit.stack2(pos1, pos2, {x=x, y=y, z=z}, repetitions, function() worldedit.player_notify(name, count .. " nodes stacked") end) end, function() + if area_protection:interaction_restrictions(name) then + worldedit.player_notify( + name, + "/stack2 not yet supported with area protection" + ) + return nil + end return count end)(name,param) -- more hax --wip: clean this up a little bit end @@ -897,6 +999,13 @@ minetest.register_chatcommand("/stretch", { worldedit.player_notify(name, count .. " nodes stretched") end, function(name, param) + if area_protection:interaction_restrictions(name) then + worldedit.player_notify( + name, + "/stretch not yet supported with area protection" + ) + return nil + end local found, _, stretchx, stretchy, stretchz = param:find("^(%d+)%s+(%d+)%s+(%d+)$") if found == nil then worldedit.player_notify(name, "invalid usage: " .. param) @@ -1180,6 +1289,13 @@ minetest.register_chatcommand("/load", { description = "Load nodes from \"(world folder)/schems/[.we[m]]\" with position 1 of the current WorldEdit region as the origin", privs = {worldedit=true}, func = function(name, param) + if area_protection:interaction_restrictions(name) then + worldedit.player_notify( + name, + "/load not yet supported with area protection" + ) + return + end local pos = get_position(name) if pos == nil then return end @@ -1296,6 +1412,13 @@ minetest.register_chatcommand("/mtschemplace", { description = "Load nodes from \"(world folder)/schems/.mts\" with position 1 of the current WorldEdit region as the origin", privs = {worldedit=true}, func = function(name, param) + if area_protection:interaction_restrictions(name) then + worldedit.player_notify( + name, + "/mtschemplace not yet supported with area protection" + ) + return + end if param == "" then worldedit.player_notify(name, "no filename specified") return diff --git a/worldedit_commands/safe.lua b/worldedit_commands/safe.lua index 0bd30d7..9f9eb9e 100644 --- a/worldedit_commands/safe.lua +++ b/worldedit_commands/safe.lua @@ -1,3 +1,52 @@ +local area_protection = {} + +if minetest.get_modpath("areas") then + area_protection.areas = areas +end + +area_protection.interaction_restrictions = function( + area_protection, + player_name +) + if area_protection.areas then + if minetest.check_player_privs( + player_name, + { + areas = true + } + ) then + return false + end + return true + end + return false +end + +area_protection.interaction_allowed = function( + area_protection, + description, + pos1, + pos2, + player_name +) + if area_protection.areas then + local allowed, conflicting = area_protection.areas:canInteractInArea( + pos1, + pos2, + player_name, + false + ) + if not allowed then + worldedit.player_notify( + player_name, + description .. " conflicts with non-owned region " .. conflicting + ) + end + return allowed + end + return true +end + local safe_region_callback = {} local safe_region_param = {} @@ -9,6 +58,15 @@ local function check_region(name, param) worldedit.player_notify(name, "no region selected") return nil end + local allowed = area_protection:interaction_allowed( + "region", + pos1, + pos2, + name + ) + if not allowed then + return nil + end return worldedit.volume(pos1, pos2) end @@ -65,4 +123,4 @@ minetest.register_chatcommand("/n", { }) -return safe_region, check_region, reset_pending +return safe_region, check_region, reset_pending, area_protection