Skip to content
Snippets Groups Projects
Commit 84b94eb1 authored by Nathanaëlle Courant's avatar Nathanaëlle Courant
Browse files

Add forceloading

parent e21b29f4
No related branches found
No related tags found
No related merge requests found
......@@ -34,3 +34,4 @@ dofile(modpath.."/falling.lua")
dofile(modpath.."/features.lua")
dofile(modpath.."/voxelarea.lua")
dofile(modpath.."/vector.lua")
dofile(modpath.."/forceloading.lua")
-- Prevent anyone else accessing those functions
local forceload_block = minetest.forceload_block
local forceload_free_block = minetest.forceload_free_block
minetest.forceload_block = nil
minetest.forceload_free_block = nil
local blocks_forceloaded
local total_forceloaded = 0
local BLOCKSIZE = 16
local function get_blockpos(pos)
return {
x = math.floor(pos.x/BLOCKSIZE),
y = math.floor(pos.y/BLOCKSIZE),
z = math.floor(pos.z/BLOCKSIZE)}
end
function minetest.forceload_block(pos)
local blockpos = get_blockpos(pos)
local hash = minetest.hash_node_position(blockpos)
if blocks_forceloaded[hash] ~= nil then
blocks_forceloaded[hash] = blocks_forceloaded[hash] + 1
return true
else
if total_forceloaded >= (minetest.setting_get("max_forceloaded_blocks") or 16) then
return false
end
total_forceloaded = total_forceloaded+1
blocks_forceloaded[hash] = 1
forceload_block(blockpos)
return true
end
end
function minetest.forceload_free_block(pos)
local blockpos = get_blockpos(pos)
local hash = minetest.hash_node_position(blockpos)
if blocks_forceloaded[hash] == nil then return end
if blocks_forceloaded[hash] > 1 then
blocks_forceloaded[hash] = blocks_forceloaded[hash] - 1
else
total_forceloaded = total_forceloaded-1
blocks_forceloaded[hash] = nil
forceload_free_block(blockpos)
end
end
-- Keep the forceloaded areas after restart
local wpath = minetest.get_worldpath()
local function read_file(filename)
local f = io.open(filename, "r")
if f==nil then return {} end
local t = f:read("*all")
f:close()
if t=="" or t==nil then return {} end
return minetest.deserialize(t)
end
local function write_file(filename, table)
local f = io.open(filename, "w")
f:write(minetest.serialize(table))
f:close()
end
blocks_forceloaded = read_file(wpath.."/force_loaded.txt")
for _, __ in pairs(blocks_forceloaded) do
total_forceloaded = total_forceloaded + 1
end
minetest.after(5, function()
for hash, _ in pairs(blocks_forceloaded) do
local blockpos = minetest.get_position_from_hash(hash)
forceload_block(blockpos)
end
end)
minetest.register_on_shutdown(function()
write_file(wpath.."/force_loaded.txt", blocks_forceloaded)
end)
......@@ -64,6 +64,16 @@ function minetest.hash_node_position(pos)
return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768
end
function minetest.get_position_from_hash(hash)
local pos = {}
pos.x = (hash%65536) - 32768
hash = math.floor(hash/65536)
pos.y = (hash%65536) - 32768
hash = math.floor(hash/65536)
pos.z = (hash%65536) - 32768
return pos
end
function minetest.get_item_group(name, group)
if not minetest.registered_items[name] or not
minetest.registered_items[name].groups[group] then
......
......@@ -1590,6 +1590,15 @@ minetest.rotate_node(itemstack, placer, pointed_thing)
the creative mode setting, and checks for "sneak" to set the invert_wall
parameter.
minetest.forceload_block(pos)
^ forceloads the position pos.
^ returns true if area could be forceloaded
minetest.forceload_free_block(pos)
^ stops forceloading the position pos.
Please note that forceloaded areas are saved when the server restarts.
Global objects:
minetest.env - EnvRef of the server environment and world.
^ Any function in the minetest namespace can be called using the syntax
......
......@@ -301,6 +301,8 @@
# This is a trade-off between sqlite transaction overhead and
# memory consumption (4096=100MB, as a rule of thumb)
#max_clearobjects_extra_loaded_blocks = 4096
# Maximum number of forceloaded blocks
#max_forceloaded_blocks = 16
# Interval of sending time of day to clients
#time_send_interval = 5
# Length of day/night cycle. 72=20min, 360=4min, 1=24hour, 0=day/night/whatever stays unchanged
......
......@@ -258,7 +258,7 @@ void ActiveBlockList::update(std::list<v3s16> &active_positions,
/*
Create the new list
*/
std::set<v3s16> newlist;
std::set<v3s16> newlist = m_forceloaded_list;
for(std::list<v3s16>::iterator i = active_positions.begin();
i != active_positions.end(); ++i)
{
......
......@@ -170,6 +170,7 @@ class ActiveBlockList
}
std::set<v3s16> m_list;
std::set<v3s16> m_forceloaded_list;
private:
};
......@@ -305,6 +306,8 @@ class ServerEnvironment : public Environment
// is weather active in this environment?
bool m_use_weather;
std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; };
private:
/*
......
......@@ -798,6 +798,27 @@ int ModApiEnvMod::l_get_humidity(lua_State *L)
return 1;
}
// minetest.forceload_block(blockpos)
// blockpos = {x=num, y=num, z=num}
int ModApiEnvMod::l_forceload_block(lua_State *L)
{
GET_ENV_PTR;
v3s16 blockpos = read_v3s16(L, 1);
env->getForceloadedBlocks()->insert(blockpos);
return 0;
}
// minetest.forceload_free_block(blockpos)
// blockpos = {x=num, y=num, z=num}
int ModApiEnvMod::l_forceload_free_block(lua_State *L)
{
GET_ENV_PTR;
v3s16 blockpos = read_v3s16(L, 1);
env->getForceloadedBlocks()->erase(blockpos);
return 0;
}
void ModApiEnvMod::Initialize(lua_State *L, int top)
{
......@@ -836,4 +857,6 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
API_FCT(transforming_liquid_add);
API_FCT(get_heat);
API_FCT(get_humidity);
API_FCT(forceload_block);
API_FCT(forceload_free_block);
}
......@@ -151,6 +151,14 @@ class ModApiEnvMod : public ModApiBase {
static int l_get_heat(lua_State *L);
static int l_get_humidity(lua_State *L);
// minetest.forceload_block(blockpos)
// forceloads a block
static int l_forceload_block(lua_State *L);
// minetest.forceload_free_block(blockpos)
// stops forceloading a position
static int l_forceload_free_block(lua_State *L);
public:
static void Initialize(lua_State *L, int top);
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment