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 |