Cristiano Magro
2024-08-27 535e04d542520f58a2db8d4d7a222b73e5c96ef1
commit | author | age
d78126 1 -- A simple special-purpose class, this is used for building up sets of three-dimensional points for fast reference
CM 2
3 Pointset = {}
4 Pointset.__index = Pointset
5
6 function Pointset.create()
7   local set = {}
8   setmetatable(set,Pointset)
9   set.points = {}
10   return set
11 end
12
13 function Pointset:set(x, y, z, value)
14   -- sets a value in the 3D array "points".
15   if self.points[x] == nil then
16     self.points[x] = {}
17   end
18   if self.points[x][y] == nil then
19     self.points[x][y] = {}
20   end
21   self.points[x][y][z] = value  
22 end
23
24 function Pointset:set_if_not_in(excluded, x, y, z, value)
25   -- If a value is not already set for this point in the 3D array "excluded", set it in "points"
26   if excluded:get(x, y, z) ~= nil then
27     return
28   end
29   self:set(x, y, z, value)
30 end
31
32 function Pointset:get(x, y, z)
33   -- return a value from the 3D array "points"
34   if self.points[x] == nil or self.points[x][y] == nil then
35     return nil
36   end
37   return self.points[x][y][z]
38 end
39
40 function Pointset:set_pos(pos, value)
41   self:set(pos.x, pos.y, pos.z, value)
42 end
43
44 function Pointset:set_pos_if_not_in(excluded, pos, value)
45   self:set_if_not_in(excluded, pos.x, pos.y, pos.z, value)
46 end
47
48 function Pointset:get_pos(pos)
49   return self:get(pos.x, pos.y, pos.z)
50 end
51
52 function Pointset:pop()
53   -- returns a point that's in the 3D array, and then removes it.
54   local pos = {}
55   local ytable
56   local ztable
57   local val
58
59   local count = 0
60   for _ in pairs(self.points) do count = count + 1 end
61   if count == 0 then
62     return nil
63   end
64   
65   pos.x, ytable = next(self.points)
66   pos.y, ztable = next(ytable)
67   pos.z, val = next(ztable)
68
69   self.points[pos.x][pos.y][pos.z] = nil
70   
71   count = 0
72   for _ in pairs(self.points[pos.x][pos.y]) do count = count + 1 end
73   if count == 0 then
74     self.points[pos.x][pos.y] = nil
75   end
76   
77   count = 0
78   for _ in pairs(self.points[pos.x]) do count = count + 1 end
79   if count == 0 then
80     self.points[pos.x] = nil
81   end
82   
83   return pos, val
84 end
85
86 function Pointset:get_pos_list(value)
87   -- Returns a list of all points with the given value in standard Minetest vector format. If no value is provided, returns all points
88   local outlist = {}
89   for x, ytable in ipairs(self.points) do
90     for y, ztable in ipairs(ytable) do
91       for z, val in ipairs(ztable) do
92         if (value == nil and val ~= nil ) or val == value then
93           table.insert(outlist, {x=x, y=y, z=z})
94         end
95       end
96     end
97   end
98   return outlist
99 end