Add canInteractInArea

This commit is contained in:
ShadowNinja 2014-07-12 16:37:54 -04:00
parent ee212466bf
commit e17cda925b
4 changed files with 41 additions and 15 deletions

31
api.lua

@ -39,3 +39,34 @@ function areas:getNodeOwners(pos)
return owners return owners
end 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

@ -81,7 +81,7 @@ function areas:isSubarea(pos1, pos2, id)
if not area then if not area then
return false return false
end 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 if (pos1.x >= p1.x and pos1.x <= p2.x) and
(pos2.x >= p1.x and pos2.x <= p2.x) and (pos2.x >= p1.x and pos2.x <= p2.x) and
(pos1.y >= p1.y and pos1.y <= p2.y) and (pos1.y >= p1.y and pos1.y <= p2.y) and
@ -141,17 +141,11 @@ function areas:canPlayerAddArea(pos1, pos2, name)
end end
-- Check intersecting areas -- Check intersecting areas
for id, area in pairs(self.areas) do local can, id = self:canInteractInArea(pos1, pos2, name)
if (area.pos1.x <= pos2.x and area.pos2.x >= pos1.x) and if not can then
(area.pos1.y <= pos2.y and area.pos2.y >= pos1.y) and local area = self.areas[id]
(area.pos1.z <= pos2.z and area.pos2.z >= pos1.z) then return false, ("The area intersects with %s [%u] owned by %s.")
-- Found an area intersecting with the suplied area :format(area.name, id, area.owner)
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
end end
return true return true

@ -31,7 +31,7 @@ minetest.register_chatcommand("legacy_load_areas", {
nil, nil, nil, nil, nil, nil nil, nil, nil, nil, nil, nil
-- Area positions sorting -- Area positions sorting
area.pos1, area.pos2 = areas:sortPos(area.pos1, area.pos2) areas:sortPos(area.pos1, area.pos2)
-- Add name -- Add name
area.name = "unnamed" area.name = "unnamed"
@ -43,7 +43,8 @@ minetest.register_chatcommand("legacy_load_areas", {
areas:save() areas:save()
minetest.chat_send_player(name, "Converted areas saved. Done.") minetest.chat_send_player(name, "Converted areas saved. Done.")
end}) end
})
function areas:node_ownership_load() function areas:node_ownership_load()
local filename = minetest.get_worldpath().."/owners.tbl" local filename = minetest.get_worldpath().."/owners.tbl"

@ -168,7 +168,7 @@ end)
-- Modifies positions `pos1` and `pos2` so that each component of `pos1` -- Modifies positions `pos1` and `pos2` so that each component of `pos1`
-- is less than or equal to its corresponding component of `pos2`, -- is less than or equal to its corresponding component of `pos2`,
-- returning two new positions -- returning the two positions.
function areas:sortPos(pos1, pos2) function areas:sortPos(pos1, pos2)
if pos1.x > pos2.x then if pos1.x > pos2.x then
pos2.x, pos1.x = pos1.x, pos2.x pos2.x, pos1.x = pos1.x, pos2.x