local S = minetest.get_translator("chest_recovery") -- Récupérer le traducteur pour ce mod chest_positions = {} local function get_inventory_formspec(pos, player_name, owner) chest_positions[player_name] = minetest.pos_to_string(pos) return "size[9,11]".. -- Ligne 1 mcl_formspec.get_itemslot_bg_v4(0, 0, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(1, 0, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 0, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 0, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 0, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(5, 0, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 0, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(7, 0, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(8, 0, 1, 1) .. -- Ligne 2 mcl_formspec.get_itemslot_bg_v4(0, 1, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(1, 1, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 1, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 1, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 1, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(5, 1, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 1, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(7, 1, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(8, 1, 1, 1) .. -- Ligne 3 mcl_formspec.get_itemslot_bg_v4(0, 2, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(1, 2, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 2, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 2, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 2, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(5, 2, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 2, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(7, 2, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(8, 2, 1, 1) .. -- Ligne 4 mcl_formspec.get_itemslot_bg_v4(0, 3, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(1, 3, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 3, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 3, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 3, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(5, 3, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 3, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(7, 3, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(8, 3, 1, 1) .. -- Ligne 5 mcl_formspec.get_itemslot_bg_v4(1, 4, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 4, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 4, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 4, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 4, 1, 1) .. -- Ligne 6 -- Ligne 7 mcl_formspec.get_itemslot_bg_v4(1, 6, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 6, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 6, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 6, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 6, 1, 1) .. -- Ligne 8 mcl_formspec.get_itemslot_bg_v4(0, 7, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(1, 7, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 7, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 7, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 7, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(5, 7, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 7, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(7, 7, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(8, 7, 1, 1) .. -- Ligne 9 mcl_formspec.get_itemslot_bg_v4(0, 8, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(1, 8, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 8, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 8, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 8, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(5, 8, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 8, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(7, 8, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(8, 8, 1, 1) .. -- Ligne 10 mcl_formspec.get_itemslot_bg_v4(0, 9, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(1, 9, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 9, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 9, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 9, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(5, 9, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 9, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(7, 9, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(8, 9, 1, 1) .. -- Ligne 11 mcl_formspec.get_itemslot_bg_v4(0, 10, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(1, 10, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(2, 10, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(3, 10, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(4, 10, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(5, 10, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(6, 10, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(7, 10, 1, 1) .. mcl_formspec.get_itemslot_bg_v4(8, 10, 1, 1) .. --"field[100,0;1,1;chest_pos;;" .. minetest.pos_to_string(pos) .. "]".. "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main;0,0;9,4;]".. "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";armor;0,4;5,1;]".. "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";offhand;6,4;1,1;]" .. "label[0,5;Coffre de " .. owner .. "]".. "list[current_player;armor;0,6;9,1;]".. "list[current_player;main;0,7;9,4;]".. "listring[]".. "button[5,5;3,1;transfer;" .. S("Transfer All") .. "]" end local function show_error_formspec(player_name, message) local formspec = "size[8,3]".. "label[1,1.25;"..minetest.formspec_escape(message).."]".. "button_exit[3,2;2,1;close;"..S("OK").."]" minetest.show_formspec(player_name, "chest_recovery:error", formspec) end minetest.register_node("chest_recovery:chest", { drop = "", description = S("Recovery Chest") .. "\n" .. S("32 slots"), tiles = {"chest_chest.png^[sheet:2x2:0,0", "chest_chest.png^[sheet:2x2:0,0", "chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:1,0", "chest_chest.png^[sheet:2x2:1,1", "chest_chest.png^[sheet:2x2:1,1"}, paramtype2 = "facedir", groups = {creative_breakable=1, building_block=1, material_stone=1}, _mcl_blast_resistance = 3600000, _mcl_hardness = -1, is_ground_content = false, legacy_facedir_simple = true, -- sounds = default.node_sound_wood_defaults(), -- Cette ligne est commentée on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string("owner", "") meta:set_string("infotext", S("Recovery Chest")) local inv = meta:get_inventory() inv:set_size("main", 9*4) inv:set_size("armor", 5) inv:set_size("offhand", 1) end, can_dig = function(pos, player) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() return inv:is_empty("main") and inv:is_empty("armor") and inv:is_empty("offhand") end, on_rightclick = function(pos, node, player, itemstack, pointed_thing) local meta = minetest.get_meta(pos) local owner = meta:get_string("owner") local player_name = player:get_player_name() if owner == "" then meta:set_string("owner", player_name) -- si le coffre n'a pas de propriétaire, le joueur qui l'ouvre devient le propriétaire owner = player_name end --verifi si le joueur a la permission de bypasser la protection du coffre if minetest.check_player_privs(player_name, {chest_recovery_bypass=true}) then local formspec = get_inventory_formspec(pos, player_name, owner) -- Obtenir le formulaire de l'inventaire minetest.show_formspec(player_name, "chest_recovery:chest", formspec) -- Afficher le formulaire return end --verifie si le coffre a une date dans les metadonnées pour verifier si celle-ci date de 3 jours if meta:get_string("date") ~= "" then -- Si la date est définie --verifie si le coffre date de plus de 3 jours --recupere la date dans les metadonnées du coffre local date = meta:get_string("date") --recupere la date actuelle local current_date = os.date("%Y-%m-%d %H:%M:%S") -- Définition des dates local date1_str = date local date2_str = current_date -- Convertir les dates en timestamps (secondes depuis l'époque Unix) local date1 = os.time(os.date("*t", os.time({year=tonumber(date1_str:sub(1,4)), month=tonumber(date1_str:sub(6,7)), day=tonumber(date1_str:sub(9,10)), hour=tonumber(date1_str:sub(12,13)), min=tonumber(date1_str:sub(15,16)), sec=tonumber(date1_str:sub(18,19))}))) local date2 = os.time(os.date("*t", os.time({year=tonumber(date2_str:sub(1,4)), month=tonumber(date2_str:sub(6,7)), day=tonumber(date2_str:sub(9,10)), hour=tonumber(date2_str:sub(12,13)), min=tonumber(date2_str:sub(15,16)), sec=tonumber(date2_str:sub(18,19))}))) -- Calculer la différence en secondes entre les deux dates local difference_seconds = os.difftime(date2, date1) -- Convertir la différence en jours local difference_days = difference_seconds / (60 * 60 * 24) -- Si la différence est supérieure à 3 jours if difference_days > 3 then else --verifie si le joueur est le propriétaire du coffre if player_name ~= owner then -- Afficher un formulaire d'erreur si le joueur n'est pas le propriétaire du coffre et lui marque la date du coffre et le propriétaire du coffre show_error_formspec(player_name, S("You are not the owner of this chest.")) minetest.chat_send_player(player_name, S("This chest belongs to ") .. owner .. S(" and was created on ") .. date) return end end end local formspec = get_inventory_formspec(pos, player_name, owner) -- Obtenir le formulaire de l'inventaire minetest.show_formspec(player_name, "chest_recovery:chest", formspec) -- Afficher le formulaire end }) minetest.register_on_player_receive_fields(function(player, formname, fields) -- Debug: envoyer dans le chat tous les champs reçus --minetest.chat_send_all(player:get_player_name() .. " " .. formname .. " " .. dump(fields)) if formname == "chest_recovery:chest" then -- Récupérer la position du coffre à partir du champ caché --local pos_str = fields.chest_pos --recupere la position du joueur local pos_str = chest_positions[player:get_player_name()] if pos_str then local pos = minetest.string_to_pos(pos_str) if pos then local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local player_inv = player:get_inventory() -- Traitement du bouton de transfert if fields.transfer then -- Supprimer les éléments de récupération du joueur for i = 1, player_inv:get_size("main") do local stack = player_inv:get_stack("main", i) if stack:get_name():find("mcl_compass:.*_recovery") then player_inv:remove_item("main", stack) end end -- Transférer les éléments d'armure du coffre au joueur for i = 1, inv:get_size("armor") do local stack = inv:get_stack("armor", i) if i > 1 or not stack:is_empty() then local player_armor_stack = player_inv:get_stack("armor", i) if player_armor_stack:is_empty() then player_inv:set_stack("armor", i, stack) inv:set_stack("armor", i, ItemStack(nil)) end end end -- Mettre à jour les informations du joueur avec le mod mcl_armor if minetest.get_modpath("mcl_armor") then local player_name = player:get_player_name() local player = minetest.get_player_by_name(player_name) mcl_armor.update(player) end -- Transférer l'élément de l'offhand local offhand_stack = inv:get_stack("offhand", 1) local leftover_offhand = player_inv:add_item("offhand", offhand_stack) inv:set_stack("offhand", 1, leftover_offhand) -- Transférer les éléments principaux du coffre for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) local leftover = player_inv:add_item("main", stack) inv:set_stack("main", i, leftover) end -- Supprimer le coffre si tous les éléments sont transférés if inv:is_empty("main") and inv:is_empty("armor") and inv:is_empty("offhand") then -- Si l'inventaire du coffre est vide --ferme le formulaire du joueur minetest.close_formspec(player:get_player_name(), "chest_recovery:chest") minetest.remove_node(pos) end end else --minetest.chat_send_player(player:get_player_name(), "Invalid chest position.") end else --minetest.chat_send_player(player:get_player_name(), "No chest position provided.") end end end) --cree une permission pour bypasser la protection du coffre minetest.register_privilege("chest_recovery_bypass", { description = S("Allow to bypass the recovery chest protection"), give_to_singleplayer = false, on_grant = function(name) minetest.chat_send_all(name .. S(" has been granted the chest_recovery_bypass privilege.")) end, on_revoke = function(name) minetest.chat_send_all(name .. S(" has had the chest_recovery_bypass privilege revoked.")) end }) -- Fonction appelée lorsqu'un joueur meurt minetest.register_on_dieplayer(function(player) -- Récupérer l'inventaire du joueur local player_inv = player:get_inventory() local pos = player:get_pos() pos.y = pos.y -- Réglage de la coordonnée Y (elle semble inchangée) -- rendre les cordonner en entier pos.x = math.floor(pos.x) pos.y = math.floor(pos.y) backuppos = pos.y pos.z = math.floor(pos.z) -- Envoyer un message au joueur indiquant ses coordonnées après la mort minetest.chat_send_player(player:get_player_name(), S("You are dead, at the coordinates : ") .. minetest.pos_to_string(pos)) --si y estentre -27000 et -28000 alors on met la position a -27000 if pos.y < -27000 and pos.y > -28000 then pos.y = -27001 end --detecter si la postion du pos est dans un bloc vide local node = minetest.get_node(pos) --si le node name n'est pas air alors on marque le message -- Vérifie si le nom du nœud n'est pas "air" if node.name ~= "air" then -- Sauvegarde la position initiale de y local backuppos = pos.y -- Recherche de la position d'un bloc vide au-dessus de la position while node.name ~= "air" do pos.y = pos.y + 1 node = minetest.get_node(pos) if node.name == "mcl_core:bedrock" then pos.y = pos.y - 1 node = minetest.get_node(pos) if node.name == "mcl_nether:netherrack" or node.name == "mcl_blackstone:nether_gold" then minetest.remove_node(pos) pos.y = pos.y - 1 else pos.y = backuppos while node.name ~= "air" do -- tant que le nom du nœud n'est pas "air" pos.y = pos.y - 1 node = minetest.get_node(pos) if node.name == "mcl_core:bedrock" then pos.y = backuppos -- Casse le bloc pour poser le coffre minetest.remove_node(pos) pos.y = pos.y + 1 end end --pos.y = pos.y - 1 end end end -- On marque le message avec la nouvelle position end -- Placer un coffre de récupération à la position du joueur décédé minetest.set_node(pos, {name = "chest_recovery:chest"}) minetest.chat_send_player(player:get_player_name(), S("your recovery chest is in position: ") .. minetest.pos_to_string(pos)) -- Obtenir les métadonnées et l'inventaire du coffre de récupération local chest_meta = minetest.get_meta(pos) local chest_inv = chest_meta:get_inventory() local is_empty = true --met en metadonnée le nom du joueur chest_meta:set_string("owner", player:get_player_name()) --met en metadonnée la date de la mort chest_meta:set_string("date", os.date("%Y-%m-%d %H:%M:%S")) -- Transférer les objets de l'inventaire du joueur au coffre de récupération for _, listname in ipairs({"main", "armor", "offhand", "craft"}) do for i = 1, player_inv:get_size(listname) do local stack = player_inv:get_stack(listname, i) chest_inv:set_stack(listname, i, stack) player_inv:set_stack(listname, i, ItemStack(nil)) if not stack:is_empty() then is_empty = false end end end -- Si l'inventaire du joueur était vide, supprimer le coffre if is_empty then minetest.remove_node(pos) else -- Mettre à jour le formulaire du coffre avec les emplacements d'objets end end) -- Define compass_frames as a global variable compass_frames = 32 minetest.register_on_respawnplayer(function(player) -- Generate a new random frame for the recovery compass local random_frame = math.random(0, compass_frames - 1) -- Create the recovery compass item local recovery_compass = ItemStack("mcl_compass:" .. random_frame .. "_recovery") local player_inv_2 = player:get_inventory() if player_inv_2 then player_inv_2:add_item("main", recovery_compass) end end)