summaryrefslogtreecommitdiff
path: root/init.lua
diff options
context:
space:
mode:
Diffstat (limited to 'init.lua')
-rw-r--r--init.lua159
1 files changed, 159 insertions, 0 deletions
diff --git a/init.lua b/init.lua
new file mode 100644
index 0000000..6e67515
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,159 @@
+local _pts = minetest.pos_to_string
+function minetest.pos_to_string(pos)
+ if not pos then
+ return "(-,-,-)"
+ end
+ return _pts(pos)
+end
+
+-- Makes sure that force load areas are handled correctly
+function ForceloadManager(filetoopen, hide_file_errors)
+ local blocks = {}
+ if filetoopen ~= nil then
+ local file = io.open(filetoopen, "r")
+ if file then
+ local table = minetest.deserialize(file:read("*all"))
+ file:close()
+ if type(table) == "table" then
+ blocks = table
+ end
+ elseif not hide_file_errors then
+ minetest.log("error", "File "..filetoopen.." does not exist!")
+ end
+ end
+ for i = 1, #blocks do
+ if not minetest.forceload_block(blocks[i]) then
+ minetest.log("error", "Failed to load block " .. minetest.pos_to_string(blocks[i]))
+ end
+ end
+ return {
+ _blocks = blocks,
+ load = function(self, pos)
+ if minetest.forceload_block(pos) then
+ table.insert(self._blocks, vector.new(pos))
+ return true
+ end
+ minetest.log("error", "Failed to load block " .. minetest.pos_to_string(pos))
+ return false
+ end,
+ unload = function(self, pos)
+ for i = 1, #self._blocks do
+ if vector.equals(pos, self._blocks[i]) then
+ minetest.forceload_block(pos)
+ table.remove(self._blocks, i)
+ return true
+ end
+ end
+ return false
+ end,
+ iter = function(self, func)
+ for i = 1, #self._blocks do
+ if func(i, self._blocks[i]) == true then
+ table.remove(self._blocks, i)
+ i = i - 1
+ end
+ end
+ end,
+ save = function(self, filename)
+ local file = io.open(filename, "w")
+ if file then
+ file:write(minetest.serialize(self._blocks))
+ file:close()
+ end
+ end,
+ verify = function(self)
+ return self:verify_each(function(pos, block)
+ local name = "ignore"
+ if block ~= nil then
+ name = block.name
+ end
+
+ if name == "ignore" then
+ if not pos.last or elapsed_time > pos.last + 15 then
+ pos.last = elapsed_time
+ if not minetest.forceload_block(pos) then
+ minetest.log("error", "Failed to force load " .. minetest.pos_to_string(pos))
+ pos.remove = true
+ end
+ end
+ return false
+ elseif name == "forceload:anchor" then
+ pos.last = elapsed_time
+ return true
+ else
+ minetest.log("error", minetest.pos_to_string(pos) .. " shouldn't be loaded")
+ pos.remove = true
+ return false
+ end
+ end)
+ end,
+ verify_each = function(self, func)
+ local not_loaded = {}
+ for i = 1, #self._blocks do
+ local res = minetest.get_node(self._blocks[i])
+ if not func(self._blocks[i], res) then
+ --[[table.insert(not_loaded, {
+ pos = self._blocks[i],
+ i = i,
+ b = res })]]--
+ end
+ end
+ return not_loaded
+ end,
+ clean = function(self)
+ local i = 1
+ while i <= #self._blocks do
+ if self._blocks[i].remove then
+ table.remove(self._blocks, i)
+ else
+ i = i + 1
+ end
+ end
+ end
+ }
+end
+
+local flm = ForceloadManager(minetest.get_worldpath().."/flm.json", true)
+
+minetest.register_privilege("forceload", "Allows players to use forceload block anchors")
+
+minetest.register_node("forceload:anchor",{
+ description = "Block Anchor",
+ walkable = false,
+ tiles = {"forceload_anchor.png"},
+ groups = {cracky = 3, oddly_breakable_by_hand = 2},
+ after_destruct = function(pos)
+ flm:unload(pos)
+ flm:save(minetest.get_worldpath().."/flm.json")
+ end,
+ after_place_node = function(pos, placer)
+ if not minetest.check_player_privs(placer:get_player_name(),
+ {forceload = true}) then
+ minetest.chat_send_player(placer:get_player_name(), "The forceload privilege is required to do that.")
+ elseif flm:load(pos) then
+ flm:save(minetest.get_worldpath().."/flm.json")
+ return
+ end
+ minetest.set_node(pos, {name="air"})
+ return true
+ end
+})
+
+minetest.register_chatcommand("a", {func = function(name)
+ flm:verify()
+ flm:clean()
+end})
+
+local elapsed_time = 0
+local count = 0
+minetest.register_globalstep(function(dtime)
+ count = count + dtime
+ elapsed_time = elapsed_time + dtime
+ if count > 5 then
+ count = 0
+ --print("Verifying...")
+ flm:verify()
+ flm:clean()
+ end
+end)
+