forceloading.lua 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. -- Prevent anyone else accessing those functions
  2. local forceload_block = minetest.forceload_block
  3. local forceload_free_block = minetest.forceload_free_block
  4. minetest.forceload_block = nil
  5. minetest.forceload_free_block = nil
  6. local blocks_forceloaded
  7. local total_forceloaded = 0
  8. local BLOCKSIZE = 16
  9. local function get_blockpos(pos)
  10. return {
  11. x = math.floor(pos.x/BLOCKSIZE),
  12. y = math.floor(pos.y/BLOCKSIZE),
  13. z = math.floor(pos.z/BLOCKSIZE)}
  14. end
  15. function minetest.forceload_block(pos)
  16. local blockpos = get_blockpos(pos)
  17. local hash = minetest.hash_node_position(blockpos)
  18. if blocks_forceloaded[hash] ~= nil then
  19. blocks_forceloaded[hash] = blocks_forceloaded[hash] + 1
  20. return true
  21. else
  22. if total_forceloaded >= (tonumber(minetest.setting_get("max_forceloaded_blocks")) or 16) then
  23. return false
  24. end
  25. total_forceloaded = total_forceloaded+1
  26. blocks_forceloaded[hash] = 1
  27. forceload_block(blockpos)
  28. return true
  29. end
  30. end
  31. function minetest.forceload_free_block(pos)
  32. local blockpos = get_blockpos(pos)
  33. local hash = minetest.hash_node_position(blockpos)
  34. if blocks_forceloaded[hash] == nil then return end
  35. if blocks_forceloaded[hash] > 1 then
  36. blocks_forceloaded[hash] = blocks_forceloaded[hash] - 1
  37. else
  38. total_forceloaded = total_forceloaded-1
  39. blocks_forceloaded[hash] = nil
  40. forceload_free_block(blockpos)
  41. end
  42. end
  43. -- Keep the forceloaded areas after restart
  44. local wpath = minetest.get_worldpath()
  45. local function read_file(filename)
  46. local f = io.open(filename, "r")
  47. if f==nil then return {} end
  48. local t = f:read("*all")
  49. f:close()
  50. if t=="" or t==nil then return {} end
  51. return minetest.deserialize(t)
  52. end
  53. local function write_file(filename, table)
  54. local f = io.open(filename, "w")
  55. f:write(minetest.serialize(table))
  56. f:close()
  57. end
  58. blocks_forceloaded = read_file(wpath.."/force_loaded.txt")
  59. for _, __ in pairs(blocks_forceloaded) do
  60. total_forceloaded = total_forceloaded + 1
  61. end
  62. minetest.after(5, function()
  63. for hash, _ in pairs(blocks_forceloaded) do
  64. local blockpos = minetest.get_position_from_hash(hash)
  65. forceload_block(blockpos)
  66. end
  67. end)
  68. minetest.register_on_shutdown(function()
  69. write_file(wpath.."/force_loaded.txt", blocks_forceloaded)
  70. end)