Add areas mod
[minetest_tutorial_subgame.git] / mods / areas / api.lua
blob1a4026bae9abe6d53bc36e5fbb9a0fc3ed49e868
2 -- Returns a list of areas that include the provided position
3 function areas:getAreasAtPos(pos)
4 local a = {}
5 local px, py, pz = pos.x, pos.y, pos.z
6 for id, area in pairs(self.areas) do
7 local ap1, ap2 = area.pos1, area.pos2
8 if px >= ap1.x and px <= ap2.x and
9 py >= ap1.y and py <= ap2.y and
10 pz >= ap1.z and pz <= ap2.z then
11 a[id] = area
12 end
13 end
14 return a
15 end
17 -- Checks if the area is unprotected or owned by you
18 function areas:canInteract(pos, name)
19 if minetest.check_player_privs(name, self.adminPrivs) then
20 return true
21 end
22 local owned = false
23 for _, area in pairs(self:getAreasAtPos(pos)) do
24 if area.owner == name or area.open then
25 return true
26 else
27 owned = true
28 end
29 end
30 return not owned
31 end
33 -- Returns a table (list) of all players that own an area
34 function areas:getNodeOwners(pos)
35 local owners = {}
36 for _, area in pairs(self:getAreasAtPos(pos)) do
37 table.insert(owners, area.owner)
38 end
39 return owners
40 end
42 --- Checks if the area intersects with an area that the player can't interact in.
43 -- Note that this fails and returns false when the specified area is fully
44 -- owned by the player, but with multiple protection zones, none of which
45 -- cover the entire checked area.
46 -- @param name (optional) player name. If not specified checks for any intersecting areas.
47 -- @param allow_open Whether open areas should be counted as is they didn't exist.
48 -- @return Boolean indicating whether the player can interact in that area.
49 -- @return Un-owned intersecting area id, if found.
50 function areas:canInteractInArea(pos1, pos2, name, allow_open)
51 if name and minetest.check_player_privs(name, self.adminPrivs) then
52 return true
53 end
54 areas:sortPos(pos1, pos2)
55 -- First check for a fully enclosing owned area.
56 if name then
57 for id, area in pairs(self.areas) do
58 -- A little optimization: isAreaOwner isn't necessary
59 -- here since we're iterating through all areas.
60 if area.owner == name and
61 self:isSubarea(pos1, pos2, id) then
62 return true
63 end
64 end
65 end
66 -- Then check for intersecting (non-owned) areas.
67 for id, area in pairs(self.areas) do
68 local p1, p2 = area.pos1, area.pos2
69 if (p1.x <= pos2.x and p2.x >= pos1.x) and
70 (p1.y <= pos2.y and p2.y >= pos1.y) and
71 (p1.z <= pos2.z and p2.z >= pos1.z) then
72 -- Found an intersecting area.
73 -- Return if the area is closed or open areas aren't
74 -- allowed, and the area isn't owned.
75 if (not allow_open or not area.open) and
76 (not name or not areas:isAreaOwner(id, name)) then
77 return false, id
78 end
79 end
80 end
81 return true
82 end