forked from nalc/areas
Use smallest area at given position (#79)
When checking for permission to interact, currently the smallest id takes precedence in a situation where areas enclose other areas. This makes it complicated to set up private areas within faction areas and vice versa. Same applies for open areas within a bigger private area. When multiple areas have the same volume, players seem to agree that the most recently protected area should also take precedence. Since we can't guarantee that the largest id is the most recent, we still use that info as we have no other way to determine age.
This commit is contained in:
parent
9a5cdb2822
commit
c2e3d073be
58
api.lua
58
api.lua
@ -95,36 +95,56 @@ function areas:getAreasIntersectingArea(pos1, pos2)
|
|||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Checks if the area is unprotected or owned by you
|
-- Returns smallest area at position and its id or nil.
|
||||||
|
-- If multiple areas have the same volume, larger id takes precedence.
|
||||||
|
function areas:getSmallestAreaAtPos(pos)
|
||||||
|
local smallest_area, smallest_id, volume
|
||||||
|
local smallest_volume = math.huge
|
||||||
|
for id, area in pairs(self:getAreasAtPos(pos)) do
|
||||||
|
volume = (area.pos2.x - area.pos1.x + 1)
|
||||||
|
* (area.pos2.y - area.pos1.y + 1)
|
||||||
|
* (area.pos2.z - area.pos1.z + 1)
|
||||||
|
if smallest_volume >= volume then
|
||||||
|
smallest_area = area
|
||||||
|
smallest_id = id
|
||||||
|
smallest_volume = volume
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return smallest_area, smallest_id
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks if the area is unprotected, open, owned by player
|
||||||
|
-- or player is part of faction of smallest area at position.
|
||||||
function areas:canInteract(pos, name)
|
function areas:canInteract(pos, name)
|
||||||
if minetest.check_player_privs(name, self.adminPrivs) then
|
if minetest.check_player_privs(name, self.adminPrivs) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
local owned = false
|
local area = self:getSmallestAreaAtPos(pos)
|
||||||
for _, area in pairs(self:getAreasAtPos(pos)) do
|
-- No area, player owns it or area is open
|
||||||
if area.owner == name or area.open then
|
if not area
|
||||||
return true
|
or area.owner == name
|
||||||
elseif areas.factions_available and area.faction_open then
|
or area.open
|
||||||
if (factions.version or 0) < 2 then
|
then
|
||||||
local faction_name = factions.get_player_faction(name)
|
return true
|
||||||
if faction_name then
|
elseif areas.factions_available and area.faction_open then
|
||||||
for _, fname in ipairs(area.faction_open or {}) do
|
if (factions.version or 0) < 2 then
|
||||||
if faction_name == fname then
|
local faction_name = factions.get_player_faction(name)
|
||||||
return true
|
if faction_name then
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for _, fname in ipairs(area.faction_open or {}) do
|
for _, fname in ipairs(area.faction_open or {}) do
|
||||||
if factions.player_is_in_faction(fname, name) then
|
if faction_name == fname then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
for _, fname in ipairs(area.faction_open or {}) do
|
||||||
|
if factions.player_is_in_faction(fname, name) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
owned = true
|
|
||||||
end
|
end
|
||||||
return not owned
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a table (list) of all players that own an area
|
-- Returns a table (list) of all players that own an area
|
||||||
|
Loading…
Reference in New Issue
Block a user