2017-02-26 05:47:16 +01:00
|
|
|
-- A simple special-purpose class, this is used for building up sets of three-dimensional points for fast reference
|
2016-12-31 07:38:18 +01:00
|
|
|
|
|
|
|
Pointset = {}
|
|
|
|
Pointset.__index = Pointset
|
|
|
|
|
2019-01-05 06:06:12 +01:00
|
|
|
-- from builtin\game\misc.lua, modified to take values directly to avoid creating an intermediate vector
|
|
|
|
local hash_node_position_values = function(x, y, z)
|
|
|
|
return (z + 32768) * 65536 * 65536
|
|
|
|
+ (y + 32768) * 65536
|
|
|
|
+ x + 32768
|
|
|
|
end
|
|
|
|
|
2016-12-31 07:38:18 +01:00
|
|
|
function Pointset.create()
|
|
|
|
local set = {}
|
|
|
|
setmetatable(set,Pointset)
|
|
|
|
set.points = {}
|
|
|
|
return set
|
|
|
|
end
|
|
|
|
|
2019-01-09 08:20:02 +01:00
|
|
|
function Pointset:clear()
|
|
|
|
local points = self.points
|
|
|
|
for k, v in pairs(points) do
|
|
|
|
points[k] = nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-12-31 07:38:18 +01:00
|
|
|
function Pointset:set(x, y, z, value)
|
|
|
|
-- sets a value in the 3D array "points".
|
2019-01-05 06:06:12 +01:00
|
|
|
self.points[hash_node_position_values(x,y,z)] = value
|
2016-12-31 07:38:18 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function Pointset:set_if_not_in(excluded, x, y, z, value)
|
|
|
|
-- If a value is not already set for this point in the 3D array "excluded", set it in "points"
|
|
|
|
if excluded:get(x, y, z) ~= nil then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
self:set(x, y, z, value)
|
|
|
|
end
|
|
|
|
|
|
|
|
function Pointset:get(x, y, z)
|
|
|
|
-- return a value from the 3D array "points"
|
2019-01-05 06:06:12 +01:00
|
|
|
return self.points[hash_node_position_values(x,y,z)]
|
2016-12-31 07:38:18 +01:00
|
|
|
end
|
|
|
|
|
2017-02-26 05:47:16 +01:00
|
|
|
function Pointset:set_pos(pos, value)
|
|
|
|
self:set(pos.x, pos.y, pos.z, value)
|
|
|
|
end
|
|
|
|
|
|
|
|
function Pointset:set_pos_if_not_in(excluded, pos, value)
|
|
|
|
self:set_if_not_in(excluded, pos.x, pos.y, pos.z, value)
|
|
|
|
end
|
|
|
|
|
|
|
|
function Pointset:get_pos(pos)
|
|
|
|
return self:get(pos.x, pos.y, pos.z)
|
|
|
|
end
|
|
|
|
|
2016-12-31 07:38:18 +01:00
|
|
|
function Pointset:pop()
|
|
|
|
-- returns a point that's in the 3D array, and then removes it.
|
2019-01-05 06:06:12 +01:00
|
|
|
local hash, value = next(self.points)
|
|
|
|
if hash == nil then return nil end
|
|
|
|
local pos = minetest.get_position_from_hash(hash)
|
|
|
|
self.points[hash] = nil
|
|
|
|
return pos, value
|
2017-02-26 05:47:16 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function Pointset:get_pos_list(value)
|
|
|
|
-- Returns a list of all points with the given value in standard Minetest vector format. If no value is provided, returns all points
|
|
|
|
local outlist = {}
|
2019-01-05 06:06:12 +01:00
|
|
|
for hash, pointsval in pairs(self.points) do
|
|
|
|
if value == nil or pointsval == value then
|
|
|
|
table.insert(outlist, minetest.get_position_from_hash(hash))
|
2017-02-26 05:47:16 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
return outlist
|
|
|
|
end
|
|
|
|
|
|
|
|
|