+ Using hashes as keys to save changed nodes positions instead of serialized tables in the maps metadata

master
Giov4 2021-02-13 16:35:08 +01:00
parent 3e16ffb923
commit c924247079
5 changed files with 59 additions and 26 deletions

View File

@ -1,6 +1,8 @@
local function delete_drops() end
local function async_reset_map() end
local function reset_node_inventory() end
local get_position_from_hash = minetest.get_position_from_hash
local hash_node_position = minetest.hash_node_position
local deserialize = minetest.deserialize
local add_node = minetest.add_node
local get_node = minetest.get_node
@ -61,9 +63,10 @@ function async_reset_map(arena, debug, recursive_data)
-- Resets a node if it hasn't been reset yet and if it resets more than "nodes_per_tick"
-- nodes it invokes this function again after one step.
arena.is_resetting = true
for serialized_pos, node in pairs(original_nodes_to_reset) do
for hash_pos, node in pairs(original_nodes_to_reset) do
if current_index > last_index then
local pos = deserialize(serialized_pos)
local pos = get_position_from_hash(hash_pos)
add_node(pos, node)
reset_node_inventory(pos)
end
@ -92,21 +95,22 @@ function async_reset_map(arena, debug, recursive_data)
end
local current_nodes_to_reset = current_maps[arena.name].changed_nodes
for serialized_pos, node in pairs(current_nodes_to_reset) do
local always_to_be_reset = original_maps[arena.name].always_to_be_reset_nodes[serialized_pos]
if not original_nodes_to_reset[serialized_pos] or always_to_be_reset then
for hash_pos, node in pairs(current_nodes_to_reset) do
local always_to_be_reset = original_maps[arena.name].always_to_be_reset_nodes[hash_pos]
if not original_nodes_to_reset[hash_pos] or always_to_be_reset then
goto continue
end
local old_node = original_nodes_to_reset[serialized_pos]
local pos = deserialize(serialized_pos)
local old_node = original_nodes_to_reset[hash_pos]
local pos = get_position_from_hash(hash_pos)
local current_node = get_node(pos)
local is_old_node_still_reset = (current_node.name == old_node.name)
-- Checking if the node was modified again DURING the reset process but
-- AFTER being reset already.
if is_old_node_still_reset then
current_nodes_to_reset[serialized_pos] = nil
current_nodes_to_reset[hash_pos] = nil
end
::continue::

View File

@ -1,5 +1,6 @@
local function save_node() end
local get_inventory = minetest.get_inventory
local hash_node_position = minetest.hash_node_position
minetest.register_on_placenode(function(pos, newnode, player, oldnode, itemstack, pointed_thing)
@ -37,9 +38,10 @@ end)
-- Minetest functions overrides.
local set_node = minetest.set_node
local get_node = minetest.get_node
function minetest.set_node(pos, node)
local arena = skywars.get_arena_by_pos(pos)
local oldnode = minetest.get_node(pos)
local oldnode = get_node(pos)
if arena and arena.enabled then
save_node(arena, pos, oldnode)
@ -76,26 +78,26 @@ function skywars.save_nodes_with_inventories(arena)
local emerged_pos1, emerged_pos2 = manip:read_from_map(arena.min_pos, arena.max_pos)
local emerged_area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
local original_area = VoxelArea:new({MinEdge=arena.min_pos, MaxEdge=arena.max_pos})
local nodes = manip:get_data()
local get_inventory = minetest.get_inventory
local get_name_from_content_id = minetest.get_name_from_content_id
local serialize = minetest.serialize
local hash_node_position = minetest.hash_node_position
local get_node = minetest.get_node
initialize_map_data(maps, arena)
maps[arena.name].always_to_be_reset_nodes = {}
local map = maps[arena.name]
map.always_to_be_reset_nodes = {}
map.changed_nodes = {}
-- Saving every node with an inventory.
for i in emerged_area:iterp(emerged_pos1, emerged_pos2) do
local node_pos = emerged_area:position(i)
local hash_pos = hash_node_position(node_pos)
local location = {type = "node", pos = node_pos}
if original_area:containsp(node_pos) and get_inventory(location) then
local node = get_node(node_pos)
local serialized_pos = serialize(node_pos)
maps[arena.name].always_to_be_reset_nodes[serialized_pos] = true
maps[arena.name].changed_nodes[serialized_pos] = node
map.always_to_be_reset_nodes[hash_pos] = true
map.changed_nodes[hash_pos] = node
end
end
@ -106,14 +108,14 @@ end
function save_node(arena, pos, node)
local maps = skywars.load_table("maps")
local serialized_pos = minetest.serialize(pos)
local hash_pos = hash_node_position(vector.round(pos))
if not arena then return end
initialize_map_data(maps, arena)
-- If this block has not been changed yet then save it.
if maps[arena.name].changed_nodes[serialized_pos] == nil then
maps[arena.name].changed_nodes[serialized_pos] = node
if not maps[arena.name].changed_nodes[hash_pos] then
maps[arena.name].changed_nodes[hash_pos] = node
skywars.overwrite_table("maps", maps)
end
end
@ -125,4 +127,34 @@ function initialize_map_data(maps, arena)
if not maps[arena.name] then maps[arena.name] = {} end
if not maps[arena.name].changed_nodes then maps[arena.name].changed_nodes = {} end
if not maps[arena.name].always_to_be_reset_nodes then maps[arena.name].always_to_be_reset_nodes = {} end
end
end
--
-- ! LEGACY SUPPORT FOR SERIALIZED POSITIONS.
-- Converting all the serialized positions into
-- hashes.
--
local maps = skywars.load_table("maps")
for arena_name, map in pairs(maps) do
initialize_map_data(maps, {name = arena_name})
for pos, node in pairs(map.changed_nodes) do
if minetest.deserialize(pos) then
local hash_pos = minetest.hash_node_position()
map.changed_nodes[pos] = nil
map.changed_nodes[hash_pos] = node
end
end
for pos, bool in pairs(map.always_to_be_reset_nodes) do
if type(pos) == "string" then
local hash_pos = minetest.hash_node_position(minetest.deserialize(pos))
map.always_to_be_reset_nodes[pos] = nilf
map.always_to_be_reset_nodes[hash_pos] = bool
end
end
end
skywars.overwrite_table("maps", maps)

View File

@ -74,9 +74,6 @@ function place_nodes_at_arena_edges(arena)
minetest.set_node(arena.min_pos, {name="skywars:test_node"})
minetest.set_node(arena.max_pos, {name="skywars:test_node"})
node1 = minetest.get_node(arena.min_pos)
node2 = minetest.get_node(arena.max_pos)
end

View File

@ -955,7 +955,7 @@ end, {
- pos2 <arena name>
- reset <arena name>
TREASURES:
- addtreasure <arena name> <item> <count> <preciousness>

View File

@ -32,6 +32,7 @@ arena_lib.register_minigame("skywars", {
dofile(minetest.get_modpath("skywars") .. "/chatcmdbuilder.lua")
dofile(minetest.get_modpath("skywars") .. "/_storage/storage_manager.lua")
dofile(minetest.get_modpath("skywars") .. "/nodes.lua")
dofile(minetest.get_modpath("skywars") .. "/utils.lua")
dofile(minetest.get_modpath("skywars") .. "/_map_handler/map_utils.lua")
@ -42,7 +43,6 @@ dofile(minetest.get_modpath("skywars") .. "/_map_handler/chests/treasures.lua")
dofile(minetest.get_modpath("skywars") .. "/_tests/map_reset.lua")
dofile(minetest.get_modpath("skywars") .. "/_compatible_mods/enderpearl/init_enderpearl.lua")
dofile(minetest.get_modpath("skywars") .. "/_compatible_mods/3d_armor/init_3d_armor.lua")
dofile(minetest.get_modpath("skywars") .. "/_storage/storage_manager.lua")
dofile(minetest.get_modpath("skywars") .. "/_hud/hud_manager.lua")
dofile(minetest.get_modpath("skywars") .. "/commands.lua")
dofile(minetest.get_modpath("skywars") .. "/_arena_lib/arena_callbacks.lua")