From 4a3c3085062e2e0efdad64410cd4dbc07cdd9ca5 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Wed, 27 Aug 2014 15:01:05 +0100 Subject: [PATCH] Initial Commit --- .gitignore | 2 + README.md | 9 ++ init.lua | 159 ++++++++++++++++++++++++++++++++++ textures/forceload_anchor.png | Bin 0 -> 463 bytes 4 files changed, 170 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 init.lua create mode 100644 textures/forceload_anchor.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96728cd --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~* + diff --git a/README.md b/README.md new file mode 100644 index 0000000..1bb39b8 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +Forceload Mod +============= + +This mod allows areas in the map to be keep loaded. +Use the forceload:anchor block. + +Created by rubenwardy + +License: LGPL 3.0 or later \ No newline at end of file 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) + diff --git a/textures/forceload_anchor.png b/textures/forceload_anchor.png new file mode 100644 index 0000000000000000000000000000000000000000..2a5f46c0caf0f84e9e5da67b09d2c81984cf9507 GIT binary patch literal 463 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfxXNX$C5WSLllI>BT^B9x7-CYx@)^uQtbZig@l%+Qac`*Z0sh zQ?>bv&i0f&-`SX$(|j+$=!UCv^D$njSoRwcNB>%`D&6GNWxPZA5Z{$IcJc=UPSoOL(RbDPOBSrLyY~Nr_uRVw{%YS#KJU%nJ?G;^(~>Q+O~I#*`yJjFFXsAu zbK$3>G1|`#B}N`A)V1^QWL)B$laUm}{{N4Vzx{0+vFwA!O`SmBFnGH9xvX