Possibility to store inventories when keep_inventory is false

master
Zughy 2021-01-23 17:59:02 +00:00
parent 3b6ba272e4
commit c4fa1e3979
4 changed files with 80 additions and 7 deletions

View File

@ -63,7 +63,7 @@ The second field, on the contrary, is a table of optional parameters: they defin
* `selected_image =`: (string) the image to show when a slot is selected
If a field is not declared, it'll keep the server defaults
* `join_while_in_progress`: (bool) whether the minigame allows to join an ongoing match. Default is `false`
* `keep_inventory`: (bool) whether to keep players inventories when joining an arena. Default is `false`
* `keep_inventory`: (bool) whether to keep players inventories when joining an arena. Default is `false`. Check out also `STORE_INVENTORY_MODE` in `SETTINGS.lua`, to choose whether and how to store players' inventory
* `show_nametags`: (bool) whether to show the players nametags while in game. Default is `false`
* `show_minimap`: (bool) whether to allow players to use the builtin minimap function. Default is `false`
* `time_mode`: (int) whether arenas will keep track of the time or not.

View File

@ -11,3 +11,12 @@ arena_lib.SERVER_PHYSICS = {
sneak_glitch = false,
new_move = true
}
-- for mods where `keep_inventory = false`.
-- It determines whether the inventory before entering an arena should be stored
-- and where. When stored, players will get it back either when the match ends or,
-- if they disconnect/the server crashes, next time they log in.
-- "none" = don't store
-- "mod_db" = store in the arena_lib mod database
-- "external_db" = store in an external database -TODO: NOT YET IMPLEMENTED
arena_lib.STORE_INVENTORY_MODE = "mod_db"

72
api.lua
View File

@ -1106,8 +1106,6 @@ end
-- winner_name può essere stringa (no team) o tabella di nomi (team)
function arena_lib.load_celebration(mod, arena, winner_name)
local mod_ref = arena_lib.mods[mod]
arena.in_celebration = true
arena_lib.update_sign(arena)
@ -1128,6 +1126,8 @@ function arena_lib.load_celebration(mod, arena, winner_name)
winning_message = S("Team @1 wins the game", arena.teams[winner_team_ID].name)
end
local mod_ref = arena_lib.mods[mod]
arena_lib.HUD_send_msg_all("title", arena, winning_message, mod_ref.celebration_time)
-- eventuale codice aggiuntivo
@ -1241,7 +1241,6 @@ function arena_lib.is_player_in_arena(p_name, mod)
end
return true
end
end
@ -1261,7 +1260,6 @@ function arena_lib.is_player_in_queue(p_name, mod)
end
return true
end
end
@ -1497,6 +1495,44 @@ end
--WARNING: internal use only
function arena_lib.restore_inventory(p_name)
if arena_lib.STORE_INVENTORY_MODE == "mod_db" and storage:get_string(p_name .. ".INVENTORY") ~= "" then
local stored_inv = minetest.deserialize(storage:get_string(p_name .. ".INVENTORY"))
local current_inv = minetest.get_player_by_name(p_name):get_inventory()
-- ripristino l'inventario
for listname, content in pairs(stored_inv) do
-- se una lista non esiste più (es. son cambiate le mod), la rimuovo
if not current_inv:get_list(listname) then
stored_inv[listname] = nil
else
for i_name, i_def in pairs(content) do
stored_inv[listname][i_name] = ItemStack(i_def)
end
end
end
-- quando una lista viene salvata, la sua grandezza equivarrà all'ultimo slot contenente
-- un oggetto. Per evitare quindi che reimpostando la lista, l'inventario si rimpicciolisca,
-- salvo prima la grandezza dell'inventario immacolato, applico la lista e poi reimposto la grandezza.
-- Questo mi evita di dover salvare nel database la grandezza di ogni lista.
for listname, _ in pairs (current_inv:get_lists()) do
local list_size = current_inv:get_size(listname)
current_inv:set_list(listname, stored_inv[listname])
current_inv:set_size(listname, list_size)
end
storage:set_string(p_name .. ".INVENTORY", "")
-- TODO: storaggio database esterno
--elseif arena_lib.STORE_INVENTORY_MODE == "external_db" then
end
end
function arena_lib.send_message_players_in_arena(arena, msg, teamID, except_teamID)
if teamID then
@ -2081,8 +2117,28 @@ function operations_before_entering_arena(mod_ref, mod, arena, arena_ID, p_name)
-- chiudo eventuali formspec
minetest.close_formspec(p_name, "")
-- svuoto eventualmente l'inventario
-- svuoto eventualmente l'inventario, decidendo se e come salvarlo
if not mod_ref.keep_inventory then
if arena_lib.STORE_INVENTORY_MODE == "mod_db" then
local p_inv = player:get_inventory()
local stored_inv = {}
-- itero ogni lista non vuota per convertire tutti gli itemstack in tabelle (sennò non li serializza)
for listname, content in pairs(p_inv:get_lists()) do
if not p_inv:is_empty(listname) then
stored_inv[listname] = {}
for i_name, i_def in pairs(content) do
stored_inv[listname][i_name] = i_def:to_table()
end
end
end
storage:set_string(p_name .. ".INVENTORY", minetest.serialize(stored_inv))
-- TODO: storaggio database esterno
--elseif arena_lib.STORE_INVENTORY_MODE == "external_db" then
end
player:get_inventory():set_list("main",{})
player:get_inventory():set_list("craft",{})
end
@ -2101,10 +2157,14 @@ function operations_before_leaving_arena(mod_ref, arena, p_name)
local player = minetest.get_player_by_name(p_name)
-- svuoto eventualmente l'inventario
-- svuoto eventualmente l'inventario e ripristino gli oggetti
if not mod_ref.keep_inventory then
player:get_inventory():set_list("main", {})
player:get_inventory():set_list("craft",{})
if arena_lib.STORE_INVENTORY_MODE ~= "none" then
arena_lib.restore_inventory(p_name)
end
end
-- resetto eventuali texture

View File

@ -2,6 +2,10 @@ minetest.register_on_joinplayer(function(player)
arena_lib.HUD_add(player)
if arena_lib.STORE_INVENTORY_MODE ~= "none" then
arena_lib.restore_inventory(player:get_player_name())
end
-- nel caso qualcuno si fosse disconnesso da dentro all'editor o fosse crashato il server con qualcuno nell'editor
if player:get_inventory():contains_item("main", "arena_lib:editor_quit") then