summaryrefslogtreecommitdiff
path: root/digilines/util.lua
diff options
context:
space:
mode:
authorVanessa Ezekowitz <vanessaezekowitz@gmail.com>2017-03-04 23:58:38 -0500
committerVanessa Ezekowitz <vanessaezekowitz@gmail.com>2017-03-04 23:58:38 -0500
commita46f07cbfbd9ae59b7b1cc2fc32f68c39ae34de0 (patch)
tree5358ecc88cd634e7277bf04e51be8e9ddd37b2aa /digilines/util.lua
parent3eb0b959da58a153e4b9fc7f70eb513b1cf0e5fd (diff)
downloaddreambuilder_modpack-a46f07cbfbd9ae59b7b1cc2fc32f68c39ae34de0.tar
dreambuilder_modpack-a46f07cbfbd9ae59b7b1cc2fc32f68c39ae34de0.tar.gz
dreambuilder_modpack-a46f07cbfbd9ae59b7b1cc2fc32f68c39ae34de0.tar.bz2
dreambuilder_modpack-a46f07cbfbd9ae59b7b1cc2fc32f68c39ae34de0.tar.xz
dreambuilder_modpack-a46f07cbfbd9ae59b7b1cc2fc32f68c39ae34de0.zip
updated digilines, framedglass, mesecons, pipeworks, quartz
technic, unifiedinventory, and unifiedbricks
Diffstat (limited to 'digilines/util.lua')
-rw-r--r--digilines/util.lua89
1 files changed, 89 insertions, 0 deletions
diff --git a/digilines/util.lua b/digilines/util.lua
index d138d63..cec75be 100644
--- a/digilines/util.lua
+++ b/digilines/util.lua
@@ -65,3 +65,92 @@ function digiline:tablecopy(table) -- deep table copy
return newtable
end
+
+
+
+-- VoxelManipulator-based node access functions:
+
+-- Maps from a hashed mapblock position (as returned by hash_blockpos) to a
+-- table.
+--
+-- Contents of the table are:
+-- “va” → the VoxelArea
+-- “data” → the data array
+-- “param1” → the param1 array
+-- “param2” → the param2 array
+--
+-- Nil if no bulk-VM operation is in progress.
+local vm_cache = nil
+
+-- Starts a bulk-VoxelManipulator operation.
+--
+-- During a bulk-VoxelManipulator operation, calls to get_node_force operate
+-- directly on VM-loaded arrays, which should be faster for reading many nodes
+-- in rapid succession. However, the cache must be flushed with vm_end once the
+-- scan is finished, to avoid using stale data in future.
+function digiline:vm_begin()
+ vm_cache = {}
+end
+
+-- Ends a bulk-VoxelManipulator operation, freeing the cached data.
+function digiline:vm_end()
+ vm_cache = nil
+end
+
+-- The dimension of a mapblock in nodes.
+local MAPBLOCKSIZE = 16
+
+-- Converts a node position into a hash of a mapblock position.
+local function vm_hash_blockpos(pos)
+ return minetest.hash_node_position({
+ x = math.floor(pos.x / MAPBLOCKSIZE),
+ y = math.floor(pos.y / MAPBLOCKSIZE),
+ z = math.floor(pos.z / MAPBLOCKSIZE)
+ })
+end
+
+-- Gets the cache entry covering a position, populating it if necessary.
+local function vm_get_or_create_entry(pos)
+ local hash = vm_hash_blockpos(pos)
+ local tbl = vm_cache[hash]
+ if not tbl then
+ local vm = minetest.get_voxel_manip(pos, pos)
+ local min_pos, max_pos = vm:get_emerged_area()
+ local va = VoxelArea:new{MinEdge = min_pos, MaxEdge = max_pos}
+ tbl = {va = va, data = vm:get_data(), param1 = vm:get_light_data(), param2 = vm:get_param2_data()}
+ vm_cache[hash] = tbl
+ end
+ return tbl
+end
+
+-- Gets the node at a position during a bulk-VoxelManipulator operation.
+local function vm_get_node(pos)
+ local tbl = vm_get_or_create_entry(pos)
+ local index = tbl.va:indexp(pos)
+ local node_value = tbl.data[index]
+ local node_param1 = tbl.param1[index]
+ local node_param2 = tbl.param2[index]
+ return {name = minetest.get_name_from_content_id(node_value), param1 = node_param1, param2 = node_param2}
+end
+
+-- Gets the node at a given position, regardless of whether it is loaded or
+-- not.
+--
+-- Outside a bulk-VoxelManipulator operation, if the mapblock is not loaded, it
+-- is pulled into the server’s main map data cache and then accessed from
+-- there.
+--
+-- Inside a bulk-VoxelManipulator operation, the operation’s VM cache is used.
+function digiline:get_node_force(pos)
+ if vm_cache then
+ return vm_get_node(pos)
+ end
+ local node = minetest.get_node(pos)
+ if node.name == "ignore" then
+ -- Node is not currently loaded; use a VoxelManipulator to prime
+ -- the mapblock cache and try again.
+ minetest.get_voxel_manip(pos, pos)
+ node = minetest.get_node(pos)
+ end
+ return node
+end