diff --git a/_arena_lib/arena_callbacks.lua b/_arena_lib/arena_callbacks.lua index 9d474bf..e33ec45 100644 --- a/_arena_lib/arena_callbacks.lua +++ b/_arena_lib/arena_callbacks.lua @@ -157,6 +157,8 @@ arena_lib.on_enable("skywars", function(arena, pl_name) skywars.print_error(pl_name, skywars.T("You didn't set the map corners!")) return false end + + skywars.save_nodes_with_inventories(arena) return true end) diff --git a/_map_handler/map_manager.lua b/_map_handler/map_reset.lua similarity index 61% rename from _map_handler/map_manager.lua rename to _map_handler/map_reset.lua index 877ee8a..4e7149e 100644 --- a/_map_handler/map_manager.lua +++ b/_map_handler/map_reset.lua @@ -1,14 +1,7 @@ -local function save_node() end local function delete_drops() end local function async_reset_map() end local function reset_node_inventory() end -function skywars.load_mapblocks(arena) - minetest.load_area(arena.min_pos, arena.max_pos) - minetest.emerge_area(arena.min_pos, arena.max_pos) -end - - function skywars.reset_map(arena, debug, debug_data) if not arena.enabled or arena.is_resetting then return end @@ -20,100 +13,6 @@ end -function skywars.kill_players_out_map(arena) - for pl_name in pairs(arena.players) do - local player = minetest.get_player_by_name(pl_name) - local pl_pos = player:get_pos() - local map_area = VoxelArea:new{MinEdge = arena.min_pos, MaxEdge = arena.max_pos} - - if map_area:contains(pl_pos.x, pl_pos.y, pl_pos.z) == false then - player:set_hp(0) - end - end -end - - - -minetest.register_on_placenode(function(pos, newnode, player, oldnode, itemstack, pointed_thing) - local arena = arena_lib.get_arena_by_player(player:get_player_name()) - save_node(arena, pos, oldnode) - - if arena == nil then - arena = skywars.get_arena_by_pos(pos) - if arena and arena.enabled then - save_node(arena, pos, oldnode) - end - end -end) - - - -minetest.register_on_dignode(function(pos, oldnode, player) - local arena = arena_lib.get_arena_by_player(player:get_player_name()) - save_node(arena, pos, oldnode) - - if arena == nil then - arena = skywars.get_arena_by_pos(pos) - if arena and arena.enabled then - save_node(arena, pos, oldnode) - end - end -end) - - - --- Minetest functions overrides. - -local set_node = minetest.set_node -function minetest.set_node(pos, node) - local arena = skywars.get_arena_by_pos(pos) - local oldnode = minetest.get_node(pos) - - if arena and arena.enabled then - save_node(arena, pos, oldnode) - end - - return set_node(pos, node) -end -function minetest.add_node(pos, node) - minetest.set_node(pos, node) -end -function minetest.remove_node(pos) - minetest.set_node(pos, {name="air"}) -end - -local swap_node = minetest.swap_node -function minetest.swap_node(pos, node) - local arena = skywars.get_arena_by_pos(pos) - local oldnode = minetest.get_node(pos) - - if arena and arena.enabled then - save_node(arena, pos, oldnode) - end - - return swap_node(pos, node) -end - - - -function save_node(arena, pos, node) - local maps = skywars.load_table("maps") - local serialized_pos = minetest.serialize(pos) - - if not arena then return end - if not maps then maps = {} end - 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 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 - skywars.overwrite_table("maps", maps) - end -end - - - function delete_drops(arena) local min_pos, max_pos = skywars.reorder_positions(arena.min_pos, arena.max_pos) local distance_from_center = vector.distance(min_pos, max_pos) / 2 @@ -188,7 +87,10 @@ function async_reset_map(arena, debug, recursive_data) local current_nodes_to_reset = current_maps[arena.name].changed_nodes for serialized_pos, node in pairs(current_nodes_to_reset) do - if not original_nodes_to_reset[serialized_pos] then goto continue end + 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 + goto continue + end local old_node = original_nodes_to_reset[serialized_pos] local pos = minetest.deserialize(serialized_pos) diff --git a/_map_handler/map_saving.lua b/_map_handler/map_saving.lua new file mode 100644 index 0000000..5c0c760 --- /dev/null +++ b/_map_handler/map_saving.lua @@ -0,0 +1,100 @@ +local function save_node() end + + +minetest.register_on_placenode(function(pos, newnode, player, oldnode, itemstack, pointed_thing) + local arena = arena_lib.get_arena_by_player(player:get_player_name()) + save_node(arena, pos, oldnode) + + if arena == nil then + arena = skywars.get_arena_by_pos(pos) + if arena and arena.enabled then + save_node(arena, pos, oldnode) + end + end +end) + + + +minetest.register_on_dignode(function(pos, oldnode, player) + local arena = arena_lib.get_arena_by_player(player:get_player_name()) + save_node(arena, pos, oldnode) + + if arena == nil then + arena = skywars.get_arena_by_pos(pos) + if arena and arena.enabled then + save_node(arena, pos, oldnode) + end + end +end) + + + +-- Minetest functions overrides. + +local set_node = minetest.set_node +function minetest.set_node(pos, node) + local arena = skywars.get_arena_by_pos(pos) + local oldnode = minetest.get_node(pos) + + if arena and arena.enabled then + save_node(arena, pos, oldnode) + end + + return set_node(pos, node) +end +function minetest.add_node(pos, node) + minetest.set_node(pos, node) +end +function minetest.remove_node(pos) + minetest.set_node(pos, {name="air"}) +end + +local swap_node = minetest.swap_node +function minetest.swap_node(pos, node) + local arena = skywars.get_arena_by_pos(pos) + local oldnode = minetest.get_node(pos) + + if arena and arena.enabled then + save_node(arena, pos, oldnode) + end + + return swap_node(pos, node) +end + + + +function skywars.save_nodes_with_inventories(arena) + local maps = skywars.load_table("maps") + maps[arena.name].always_to_be_reset_nodes = {} + skywars.overwrite_table("maps", maps) + + skywars.iterate_area_nodes(arena.min_pos, arena.max_pos, function(node, node_pos) + local location = {type="node", pos=node_pos} + local node_inv = minetest.get_inventory(location) + + if node_inv then + save_node(arena, node_pos, node, "has_inventory") + end + end) +end + + + +function save_node(arena, pos, node, has_inventory) + local maps = skywars.load_table("maps") + local serialized_pos = minetest.serialize(pos) + + if not arena then return end + if not maps then maps = {} end + 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 this block has not been changed yet then save it. + if maps[arena.name].changed_nodes[serialized_pos] == nil then + if has_inventory then + maps[arena.name].always_to_be_reset_nodes[serialized_pos] = true + end + maps[arena.name].changed_nodes[serialized_pos] = node + skywars.overwrite_table("maps", maps) + end +end \ No newline at end of file diff --git a/_map_handler/map_utils.lua b/_map_handler/map_utils.lua new file mode 100644 index 0000000..9c3dde6 --- /dev/null +++ b/_map_handler/map_utils.lua @@ -0,0 +1,38 @@ +function skywars.kill_players_out_map(arena) + for pl_name in pairs(arena.players) do + local player = minetest.get_player_by_name(pl_name) + local pl_pos = player:get_pos() + local map_area = VoxelArea:new{MinEdge = arena.min_pos, MaxEdge = arena.max_pos} + + if map_area:contains(pl_pos.x, pl_pos.y, pl_pos.z) == false then + player:set_hp(0) + end + end +end + + + +function skywars.load_mapblocks(arena) + minetest.load_area(arena.min_pos, arena.max_pos) + minetest.emerge_area(arena.min_pos, arena.max_pos) +end + + + +function skywars.iterate_area_nodes(min_pos, max_pos, func) + for x = 1, max_pos.x - min_pos.x do + for y = 1, max_pos.y - min_pos.y do + for z = 1, max_pos.z - min_pos.z do + local node_pos = { + x = min_pos.x+x, + y = min_pos.y+y, + z = min_pos.z+z + } + local node = minetest.get_node(node_pos) + local func_result = func(node, node_pos) + + if func_result then return func_result end + end + end + end +end \ No newline at end of file diff --git a/_tests/map_reset.lua b/_tests/map_reset.lua index bda5440..448da50 100644 --- a/_tests/map_reset.lua +++ b/_tests/map_reset.lua @@ -14,23 +14,13 @@ function skywars.test_async_speed(arena) skywars.reorder_positions(arena.min_pos, arena.max_pos) skywars.load_mapblocks(arena) - local max_pos = arena.max_pos - local min_pos = arena.min_pos local area_size = 10 - max_pos = vector.add(min_pos, area_size) - - for x = 1, max_pos.x - min_pos.x do - for y = 1, max_pos.y - min_pos.y do - for z = 1, max_pos.z - min_pos.z do - local node_pos = { - x = min_pos.x+x, - y = min_pos.y+y, - z = min_pos.z+z - } - minetest.set_node(node_pos, {name="skywars:test_node"}) - end - end - end + local min_pos = arena.min_pos + local max_pos = vector.add(min_pos, area_size) + + skywars.iterate_area_nodes(min_pos, max_pos, function(node, node_pos) + minetest.set_node(node_pos, {name="skywars:test_node"}) + end) minetest.after(1, function() skywars.reset_map(arena, true) end) end diff --git a/init.lua b/init.lua index a8ba1f0..3df113c 100644 --- a/init.lua +++ b/init.lua @@ -32,6 +32,9 @@ arena_lib.register_minigame("skywars", { dofile(minetest.get_modpath("skywars") .. "/chatcmdbuilder.lua") dofile(minetest.get_modpath("skywars") .. "/utils.lua") +dofile(minetest.get_modpath("skywars") .. "/_map_handler/map_utils.lua") +dofile(minetest.get_modpath("skywars") .. "/_map_handler/map_reset.lua") +dofile(minetest.get_modpath("skywars") .. "/_map_handler/map_saving.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") @@ -40,7 +43,6 @@ dofile(minetest.get_modpath("skywars") .. "/_hud/hud_manager.lua") dofile(minetest.get_modpath("skywars") .. "/commands.lua") dofile(minetest.get_modpath("skywars") .. "/_chest_handler/chest_setter.lua") dofile(minetest.get_modpath("skywars") .. "/_chest_handler/treasures.lua") -dofile(minetest.get_modpath("skywars") .. "/_map_handler/map_manager.lua") dofile(minetest.get_modpath("skywars") .. "/_arena_lib/arena_callbacks.lua") dofile(minetest.get_modpath("skywars") .. "/_kits/formspec.lua") dofile(minetest.get_modpath("skywars") .. "/_kits/kit_items.lua")