mirror of
https://github.com/sys4-fr/server-nalc.git
synced 2024-12-25 18:20:36 +01:00
Optimize areas with AreaStore (by est31)
This commit is contained in:
parent
1e49bd6d20
commit
6cb835f75e
@ -10,6 +10,13 @@ local plants = { ["farming:blueberries"]=1, ["farming:carrot"]=1, ["farming:coff
|
|||||||
function areas:getAreasAtPos(pos)
|
function areas:getAreasAtPos(pos)
|
||||||
local a = {}
|
local a = {}
|
||||||
local px, py, pz = pos.x, pos.y, pos.z
|
local px, py, pz = pos.x, pos.y, pos.z
|
||||||
|
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
|
for id, area in pairs(self.areas) do
|
||||||
local ap1, ap2 = area.pos1, area.pos2
|
local ap1, ap2 = area.pos1, area.pos2
|
||||||
if px >= ap1.x and px <= ap2.x and
|
if px >= ap1.x and px <= ap2.x and
|
||||||
@ -18,9 +25,33 @@ function areas:getAreasAtPos(pos)
|
|||||||
a[id] = area
|
a[id] = area
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return a
|
return a
|
||||||
end
|
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
|
-- Checks if the area is unprotected or owned by you
|
||||||
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
|
||||||
@ -80,32 +111,25 @@ function areas:canInteractInArea(pos1, pos2, name, allow_open)
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
areas:sortPos(pos1, pos2)
|
areas:sortPos(pos1, pos2)
|
||||||
|
|
||||||
|
local areas = self:getAreasForArea(pos1, pos2)
|
||||||
|
for id, area in pairs(areas) do
|
||||||
-- 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
|
-- A little optimization: isAreaOwner isn't necessary
|
||||||
-- here since we're iterating through all areas.
|
-- here since we're iterating through all relevant areas.
|
||||||
if area.owner == name and
|
if area.owner == name and
|
||||||
self:isSubarea(pos1, pos2, id) then
|
self:isSubarea(pos1, pos2, id) then
|
||||||
return true
|
return true
|
||||||
end
|
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.
|
|
||||||
-- Return if the area is closed or open areas aren't
|
-- Return if the area is closed or open areas aren't
|
||||||
-- allowed, and the area isn't owned.
|
-- allowed, and the area isn't owned.
|
||||||
if (not allow_open or not area.open) and
|
if (not allow_open or not area.open) and
|
||||||
(not name or not areas:isAreaOwner(id, name)) then
|
(not name or not self:isAreaOwner(id, name)) then
|
||||||
return false, id
|
return false, id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,6 +20,23 @@ function areas:save()
|
|||||||
file:close()
|
file:close()
|
||||||
end
|
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
|
-- Load the areas table from the save file
|
||||||
function areas:load()
|
function areas:load()
|
||||||
local file, err = io.open(self.config.filename, "r")
|
local file, err = io.open(self.config.filename, "r")
|
||||||
@ -31,6 +48,7 @@ function areas:load()
|
|||||||
if type(self.areas) ~= "table" then
|
if type(self.areas) ~= "table" then
|
||||||
self.areas = {}
|
self.areas = {}
|
||||||
end
|
end
|
||||||
|
populateStore(self)
|
||||||
file:close()
|
file:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -48,6 +66,12 @@ function areas:add(owner, name, pos1, pos2, parent)
|
|||||||
local id = findFirstUnusedIndex(self.areas)
|
local id = findFirstUnusedIndex(self.areas)
|
||||||
self.areas[id] = {name=name, pos1=pos1, pos2=pos2, owner=owner,
|
self.areas[id] = {name=name, pos1=pos1, pos2=pos2, owner=owner,
|
||||||
parent=parent}
|
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
|
return id
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -75,6 +99,13 @@ function areas:remove(id, recurse)
|
|||||||
|
|
||||||
-- Remove main entry
|
-- Remove main entry
|
||||||
self.areas[id] = nil
|
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
|
end
|
||||||
|
|
||||||
-- Checks if a area between two points is entirely contained by another area
|
-- Checks if a area between two points is entirely contained by another area
|
||||||
|
Loading…
Reference in New Issue
Block a user