From e17cda925b7ab7d3d586ed1c40c591854704d770 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Sat, 12 Jul 2014 16:37:54 -0400 Subject: [PATCH] Add canInteractInArea --- api.lua | 31 +++++++++++++++++++++++++++++++ internal.lua | 18 ++++++------------ legacy.lua | 5 +++-- pos.lua | 2 +- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/api.lua b/api.lua index d6a2cfd..bdb886a 100644 --- a/api.lua +++ b/api.lua @@ -39,3 +39,34 @@ function areas:getNodeOwners(pos) return owners 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 +-- cover the entire checked area. +-- @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) + areas:sortPos(pos1, pos2) + -- First check for a fully enclosing owned area + for id, area in pairs(self.areas) do + -- A little optimization: isAreaOwner isn't necessary here + -- since we're iterating through all areas. + if area.owner == name and self:isSubarea(pos1, pos2, id) then + return true + end + end + -- 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 areas:isAreaOwner(id, name) then + return false, id + end + end + end + return true +end + diff --git a/internal.lua b/internal.lua index 93b873f..f032b1b 100644 --- a/internal.lua +++ b/internal.lua @@ -81,7 +81,7 @@ function areas:isSubarea(pos1, pos2, id) if not area then return false end - p1, p2 = area.pos1, area.pos2 + local p1, p2 = area.pos1, area.pos2 if (pos1.x >= p1.x and pos1.x <= p2.x) and (pos2.x >= p1.x and pos2.x <= p2.x) and (pos1.y >= p1.y and pos1.y <= p2.y) and @@ -141,17 +141,11 @@ function areas:canPlayerAddArea(pos1, pos2, name) end -- Check intersecting areas - for id, area in pairs(self.areas) do - if (area.pos1.x <= pos2.x and area.pos2.x >= pos1.x) and - (area.pos1.y <= pos2.y and area.pos2.y >= pos1.y) and - (area.pos1.z <= pos2.z and area.pos2.z >= pos1.z) then - -- Found an area intersecting with the suplied area - if not areas:isAreaOwner(id, name) then - return false, ("The area intersects with" - .." %s [%u] owned by %s.") - :format(area.name, id, area.owner) - end - end + 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.") + :format(area.name, id, area.owner) end return true diff --git a/legacy.lua b/legacy.lua index 7eabf90..b689cc0 100644 --- a/legacy.lua +++ b/legacy.lua @@ -31,7 +31,7 @@ minetest.register_chatcommand("legacy_load_areas", { nil, nil, nil, nil, nil, nil -- Area positions sorting - area.pos1, area.pos2 = areas:sortPos(area.pos1, area.pos2) + areas:sortPos(area.pos1, area.pos2) -- Add name area.name = "unnamed" @@ -43,7 +43,8 @@ minetest.register_chatcommand("legacy_load_areas", { areas:save() minetest.chat_send_player(name, "Converted areas saved. Done.") -end}) + end +}) function areas:node_ownership_load() local filename = minetest.get_worldpath().."/owners.tbl" diff --git a/pos.lua b/pos.lua index e4f2d25..40f8360 100644 --- a/pos.lua +++ b/pos.lua @@ -168,7 +168,7 @@ end) -- Modifies positions `pos1` and `pos2` so that each component of `pos1` -- is less than or equal to its corresponding component of `pos2`, --- returning two new positions +-- returning the two positions. function areas:sortPos(pos1, pos2) if pos1.x > pos2.x then pos2.x, pos1.x = pos1.x, pos2.x