diff --git a/api.lua b/api.lua index 7b10a87..1a4026b 100644 --- a/api.lua +++ b/api.lua @@ -41,17 +41,18 @@ end --- Checks if the area intersects with an area that the player can't interact in. -- Note that this fails and returns false when the specified area is fully --- owned by the player, but with miltiple protection zones, none of which +-- owned by the player, but with multiple protection zones, none of which -- cover the entire checked area. -- @param name (optional) player name. If not specified checks for any intersecting areas. +-- @param allow_open Whether open areas should be counted as is they didn't exist. -- @return Boolean indicating whether the player can interact in that area. -- @return Un-owned intersecting area id, if found. -function areas:canInteractInArea(pos1, pos2, name) +function areas:canInteractInArea(pos1, pos2, name, allow_open) if name and minetest.check_player_privs(name, self.adminPrivs) then return true end areas:sortPos(pos1, pos2) - -- First check for a fully enclosing owned area + -- First check for a fully enclosing owned area. if name then for id, area in pairs(self.areas) do -- A little optimization: isAreaOwner isn't necessary @@ -62,14 +63,17 @@ function areas:canInteractInArea(pos1, pos2, name) end end end - -- Then check for intersecting (non-owned) areas + -- Then check for intersecting (non-owned) areas. for id, area in pairs(self.areas) do local p1, p2 = area.pos1, area.pos2 if (p1.x <= pos2.x and p2.x >= pos1.x) and (p1.y <= pos2.y and p2.y >= pos1.y) and (p1.z <= pos2.z and p2.z >= pos1.z) then - -- Found an intersecting area - if not name or not areas:isAreaOwner(id, name) then + -- Found an intersecting area. + -- Return if the area is closed or open areas aren't + -- allowed, and the area isn't owned. + if (not allow_open or not area.open) and + (not name or not areas:isAreaOwner(id, name)) then return false, id end end diff --git a/init.lua b/init.lua index 1e85a5a..37cf58d 100644 --- a/init.lua +++ b/init.lua @@ -19,11 +19,16 @@ dofile(areas.modpath.."/hud.lua") areas:load() -minetest.register_privilege("areas", {description = "Can administer areas"}) +minetest.register_privilege("areas", { + description = "Can administer areas." +}) +minetest.register_privilege("areas_high_limit", { + description = "Can can more, bigger areas." +}) if not minetest.registered_privileges[areas.self_protection_privilege] then minetest.register_privilege(areas.self_protection_privilege, { - description = "Can protect areas", + description = "Can protect areas.", }) end diff --git a/internal.lua b/internal.lua index e06b99d..96f9456 100644 --- a/internal.lua +++ b/internal.lua @@ -52,12 +52,12 @@ end -- Remove a area, and optionally it's children recursively. -- If a area is deleted non-recursively the children will -- have the removed area's parent as their new parent. -function areas:remove(id, recurse, secondrun) +function areas:remove(id, recurse) if recurse then -- Recursively find child entries and remove them local cids = self:getChildren(id) for _, cid in pairs(cids) do - self:remove(cid, true, true) + self:remove(cid, true) end else -- Update parents @@ -109,22 +109,26 @@ end -- Also checks the size of the area and if the user already -- has more than max_areas. function areas:canPlayerAddArea(pos1, pos2, name) - if minetest.check_player_privs(name, self.adminPrivs) then + local privs = minetest.get_player_privs(name) + if privs.areas then return true end -- Check self protection privilege, if it is enabled, -- and if the area is too big. - if (not self.self_protection) or - (not minetest.check_player_privs(name, - {[areas.self_protection_privilege]=true})) then + if not self.self_protection or + not privs[areas.self_protection_privilege] then return false, "Self protection is disabled or you do not have" .." the necessary privilege." end - if (pos2.x - pos1.x) > self.self_protection_max_size.x or - (pos2.y - pos1.y) > self.self_protection_max_size.y or - (pos2.z - pos1.z) > self.self_protection_max_size.z then + local max_size = privs.areas_high_limit and + self.self_protection_max_size_high or + self.self_protection_max_size + if + (pos2.x - pos1.x) > max_size.x or + (pos2.y - pos1.y) > max_size.y or + (pos2.z - pos1.z) > max_size.z then return false, "Area is too big." end @@ -135,7 +139,10 @@ function areas:canPlayerAddArea(pos1, pos2, name) count = count + 1 end end - if count >= self.self_protection_max_areas then + local max_areas = privs.areas_high_limit and + self.self_protection_max_areas_high or + self.self_protection_max_areas + if count >= max_areas then return false, "You have reached the maximum amount of" .." areas that you are allowed to protect." end @@ -144,7 +151,7 @@ function areas:canPlayerAddArea(pos1, pos2, name) local can, id = self:canInteractInArea(pos1, pos2, name) if not can then local area = self.areas[id] - return false, ("The area intersects with %s [%u] owned by %s.") + return false, ("The area intersects with %s [%u] (%s).") :format(area.name, id, area.owner) end diff --git a/settings.lua b/settings.lua index d126c83..c9ed9a0 100644 --- a/settings.lua +++ b/settings.lua @@ -12,16 +12,21 @@ areas.filename = minetest.setting_get("areas.filename") or worldpath.."/areas.dat" -- Allow players with a privilege create their own areas --- within the max_size and number +-- within the maximum size and number areas.self_protection = setting_getbool_default("areas.self_protection", false) areas.self_protection_privilege = minetest.setting_get("areas.self_protection_privilege") or "interact" areas.self_protection_max_size = minetest.setting_get_pos("areas.self_protection_max_size") or - {x=50, y=100, z=50} + {x=64, y=128, z=64} +areas.self_protection_max_size_high = + minetest.setting_get_pos("areas.self_protection_max_size_high") or + {x=512, y=512, z=512} areas.self_protection_max_areas = - tonumber(minetest.setting_get("areas.self_protection_max_areas")) or 3 + tonumber(minetest.setting_get("areas.self_protection_max_areas")) or 4 +areas.self_protection_max_areas_high = + tonumber(minetest.setting_get("areas.self_protection_max_areas_high")) or 32 -- Register compatability functions for node_ownership. -- legacy_table (owner_defs) compatibility is untested