Use AreaStore

This commit is contained in:
est31 2015-07-09 11:42:13 +02:00
parent 177f659f4e
commit fe932b6ea6
2 changed files with 84 additions and 29 deletions

82
api.lua
View File

@ -3,17 +3,48 @@
function areas:getAreasAtPos(pos)
local a = {}
local px, py, pz = pos.x, pos.y, pos.z
for id, area in pairs(self.areas) do
local ap1, ap2 = area.pos1, area.pos2
if px >= ap1.x and px <= ap2.x and
py >= ap1.y and py <= ap2.y and
pz >= ap1.z and pz <= ap2.z then
a[id] = area
if self.store then
local areas = self.store:get_areas_for_pos(pos, false, true)
for store_id, store_area in pairs(areas) do
local id = tonumber(store_area.data)
a[id] = self.areas[id]
end
else
for id, area in pairs(self.areas) do
local ap1, ap2 = area.pos1, area.pos2
if px >= ap1.x and px <= ap2.x and
py >= ap1.y and py <= ap2.y and
pz >= ap1.z and pz <= ap2.z then
a[id] = area
end
end
end
return a
end
function areas:getAreasForArea(pos1, pos2)
local res = {}
if self.store then
local areas = self.store:get_areas_in_area(pos1,
pos2, true, false, true)
for store_id, store_area in pairs(areas) do
local id = tonumber(store_area.data)
res[id] = self.areas[id]
end
else
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.
res[id] = area
end
end
end
return res
end
-- Checks if the area is unprotected or owned by you
function areas:canInteract(pos, name)
if minetest.check_player_privs(name, self.adminPrivs) then
@ -52,30 +83,23 @@ function areas:canInteractInArea(pos1, pos2, name, allow_open)
return true
end
areas:sortPos(pos1, pos2)
-- 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
-- here since we're iterating through all areas.
if area.owner == name and
self:isSubarea(pos1, pos2, id) then
return true
end
local areas = self:getAreasForArea(pos1, pos2)
for id, area in pairs(areas) do
-- First check for a fully enclosing owned area.
-- A little optimization: isAreaOwner isn't necessary
-- here since we're iterating through all relevant 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.
-- 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
-- Then check for intersecting (non-owned) areas.
-- 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 self:isAreaOwner(id, name)) then
return false, id
end
end
return true

View File

@ -18,6 +18,23 @@ function areas:save()
file:close()
end
local function populateStore(self)
if not rawget(_G, "AreaStore") then
return
end
local store = AreaStore()
local store_ids = {}
store:reserve(#self.areas)
for id, area in pairs(areas.areas) do
local sid = store:insert_area(area.pos1,
area.pos2, tostring(id))
assert(sid ~= nil) -- if its nil, no id could be found
store_ids[id] = sid
end
self.store = store
self.store_ids = store_ids
end
-- Load the areas table from the save file
function areas:load()
local file, err = io.open(self.config.filename, "r")
@ -29,6 +46,7 @@ function areas:load()
if type(self.areas) ~= "table" then
self.areas = {}
end
populateStore(self)
file:close()
end
@ -46,6 +64,12 @@ function areas:add(owner, name, pos1, pos2, parent)
local id = findFirstUnusedIndex(self.areas)
self.areas[id] = {name=name, pos1=pos1, pos2=pos2, owner=owner,
parent=parent}
-- add to AreaStore
if self.store then
local sid = self.store:insert_area(pos1, pos2, dump(id))
assert(sid ~= nil) -- if its nil, no id could be found
self.store_ids[id] = sid
end
return id
end
@ -73,6 +97,13 @@ function areas:remove(id, recurse)
-- Remove main entry
self.areas[id] = nil
-- remove from AreaStore
if self.store then
local sid = self.store_ids[id]
self.store_ids[id] = nil
self.store:remove_area(sid)
end
end
-- Checks if a area between two points is entirely contained by another area