From eeec7d6be0c58092957eee4460a5f0a940b6e9cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 6 May 2023 10:24:22 +0200 Subject: [PATCH] fixes as per code review completed (2) --- game_api.txt | 6 +- mods/bones/init.lua | 174 +++++++++++++++++++++----------------------- 2 files changed, 86 insertions(+), 94 deletions(-) diff --git a/game_api.txt b/game_api.txt index 953f0e72..5b624131 100644 --- a/game_api.txt +++ b/game_api.txt @@ -85,11 +85,9 @@ e.g. `table.insert(bones.player_inventory_lists, "backpack")` Additionally, callbacks can be registered to transfer items into the bones on death: -`bones.register_dead_player_inv_management(function(player,callback){})` +`bones.register_dead_player_inv_management(function(player){})` -In the above functions the provided callback should be used to add items to the bones inventory: - -`callback(stack)` +the registered function is supposed to return with a table of items to be transferred. please note that the inventory these items were taken from still need to be disposed of. diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 060efebf..15efb958 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -6,7 +6,7 @@ -- Load support for MT game translation. local S = minetest.get_translator("bones") -local theoretical_max_slots = minetest.settings:get("bones_max_slots") or ( 15 * 10 ) +local theoretical_max_slots = minetest.settings:get("bones_max_slots") or 15 * 10 local dead_player_callbacks={} bones = {} @@ -21,10 +21,10 @@ end local function get_bones_formspec_wh(cols,rows) return - "size[" .. cols .. "," .. ( rows + 5 ) .. "]" .. + "size[" .. cols .. "," .. (rows + 5) .. "]" .. "list[current_name;main;0,0.3;" .. cols .. "," .. rows .. ";]" .. - "list[current_player;main;" .. ( ( cols - 8 ) / 2 ) .. "," .. rows .. ".85;8,1;]" .. - "list[current_player;main;".. ( ( cols - 8 ) / 2 ) .. "," .. ( rows + 2 ) .. ".08;8,3;8]" .. + "list[current_player;main;" .. ((cols - 8) / 2) .. "," .. rows .. ".85;8,1;]" .. + "list[current_player;main;".. ((cols - 8) / 2) .. "," .. (rows + 2) .. ".08;8,3;8]" .. "listring[current_name;main]" .. "listring[current_player;main]" .. default.get_hotbar_bg(0,4.85) @@ -37,10 +37,10 @@ local function get_bones_formspec_for_size(numitems) end --if we're over 4*8, but below 4*15 we make it 4 rows and adjust the column count to make everything fit if numitems <= 4 * 15 then - return get_bones_formspec_wh( math.floor ( ( numitems + 3 ) / 4 ), 4) + return get_bones_formspec_wh(math.floor((numitems + 3) / 4), 4) end --if we're over 4*15 we'll make 15 columns and adjust the row count to make everything fit - return get_bones_formspec_wh(15, math.floor ( ( numitems + 14 ) / 15 ) ) + return get_bones_formspec_wh(15, math.floor ((numitems + 14) / 15)) end local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or 1200 @@ -203,71 +203,39 @@ end local player_inventory_lists = { "main", "craft" } bones.player_inventory_lists = player_inventory_lists ---functions registered this way won't becalled if bones_mode is keep +--functions registered this way won't be called if bones_mode is keep function bones.register_dead_player_inv_management(func) table.insert(dead_player_callbacks, func) end -local function transfer_stack_to_bones(stk,current_dead_player) - -- check if it's possible to place bones, if not find space near player - if ( current_dead_player.bones_mode == "bones" ) and - ( current_dead_player.bones_pos == nil ) then - current_dead_player.bones_pos = current_dead_player.player_pos - local air - if may_replace(current_dead_player.bones_pos, current_dead_player.player) then - air = current_dead_player.bones_pos - else - air = minetest.find_node_near(current_dead_player.bones_pos, 1, {"air"}) - end - - if air and not minetest.is_protected(air, current_dead_player.player_name) then - current_dead_player.bones_pos = air - local param2 = minetest.dir_to_facedir(current_dead_player.player:get_look_dir()) - minetest.set_node(current_dead_player.bones_pos, {name = "bones:bones", param2 = param2}) - local meta = minetest.get_meta(current_dead_player.bones_pos) - current_dead_player.bones_inv = meta:get_inventory() - --make it so big that anything reasonable will for sure fit inside - current_dead_player.bones_inv:set_size("main", theoretical_max_slots) - else - current_dead_player.bones_mode = "drop" - current_dead_player.bones_pos = nil - end - end - - if ( current_dead_player.bones_mode == "bones" ) and - ( current_dead_player.bones_inv:room_for_item("main", stk) ) then - current_dead_player.bones_inv:add_item("main", stk) - else - drop(current_dead_player.player_pos, stk) - current_dead_player.dropped=true - end -end - -local function player_dies_transfer_inventory(player,transfer_stack) +local function player_dies_transfer_inventory(player) + local result = {} local player_inv = player:get_inventory() for _, list_name in ipairs(player_inventory_lists) do for i = 1, player_inv:get_size(list_name) do - local stack = player_inv:get_stack(list_name, i) - transfer_stack(stack) + table.insert(result, player_inv:get_stack(list_name, i)) end player_inv:set_list(list_name, {}) end + return result end bones.register_dead_player_inv_management(player_dies_transfer_inventory) minetest.register_on_dieplayer(function(player) - local pos = vector.round(player:get_pos()) + local player_pos = vector.round(player:get_pos()) local bones_mode = minetest.settings:get("bones_mode") or "bones" if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then bones_mode = "bones" end local player_name = player:get_player_name() - local current_dead_player={player=player, player_name=player_name, bones_inv=nil, bones_pos=nil, - bones_mode=bones_mode, player_pos=pos, dropped=false} + local bones_inv = nil + local bones_pos = nil + local dropped = false + local bones_meta = nil local bones_position_message = minetest.settings:get_bool("bones_position_message") == true - local pos_string = minetest.pos_to_string(pos) + local pos_string = minetest.pos_to_string(player_pos) -- return if keep inventory set or in creative mode if bones_mode == "keep" or minetest.is_creative_enabled(player_name) then @@ -279,73 +247,99 @@ minetest.register_on_dieplayer(function(player) return end - local callback=function(stk) - transfer_stack_to_bones(stk,current_dead_player) - end + for _, fun in ipairs(dead_player_callbacks) do + local items = fun(player) + for _, item in ipairs(items) do + -- check if it's possible to place bones, if not find space near player + if bones_mode == "bones" and bones_pos == nil then + bones_pos = player_pos + local air + if may_replace(bones_pos, player) then + air = bones_pos + else + air = minetest.find_node_near(bones_pos, 1, {"air"}) + end - for i=1,#dead_player_callbacks do - local fun=dead_player_callbacks[i] - fun(player,callback) + if air and not minetest.is_protected(air, player_name) then + bones_pos = air + local param2 = minetest.dir_to_facedir(player:get_look_dir()) + minetest.set_node(bones_pos, {name = "bones:bones", param2 = param2}) + bones_meta = minetest.get_meta(bones_pos) + bones_inv = bones_meta:get_inventory() + --make it so big that anything reasonable will for sure fit inside + bones_inv:set_size("main", theoretical_max_slots) + else + bones_mode = "drop" + bones_pos = nil + end + end + + if bones_mode == "bones" and bones_inv:room_for_item("main", item) then + bones_inv:add_item("main", item) + else + drop(player_pos, item) + dropped=true + end + end end local bones_conclusion + local public_conclusion - if not ( current_dead_player.bones_pos ) then - drop(current_dead_player.player_pos, ItemStack("bones:bones")) - if not ( current_dead_player.dropped ) then - bones_conclusion="No bones placed" - if bones_position_message then - minetest.chat_send_player(player_name, S("@1 died at @2.", player_name, pos_string)) - end + if not bones_pos then + drop(player_pos, ItemStack("bones:bones")) + if not dropped then + bones_conclusion = "No bones placed" + public_conclusion = S("@1 died at @2.", player_name, pos_string) else - bones_conclusion="Inventory dropped" - if bones_position_message then - minetest.chat_send_player(player_name, S("@1 died at @2, and dropped their inventory.", player_name, pos_string, public_conclusion)) - end + bones_conclusion = "Inventory dropped" + public_conclusion = S("@1 died at @2, and dropped their inventory.", player_name, pos_string) end else - if not ( current_dead_player.dropped ) then - bones_conclusion="Bones placed" - if bones_position_message then - minetest.chat_send_player(player_name, S("@1 died at @2, and bones were placed.", player_name, pos_string, public_conclusion)) - end + if not dropped then + bones_conclusion = "Bones placed" + public_conclusion = S("@1 died at @2, and bones were placed.", player_name, pos_string) else - bones_conclusion="Inventory partially dropped" - if bones_position_message then - minetest.chat_send_player(player_name, S("@1 died at @2, and partially dropped their inventory.", player_name, pos_string, public_conclusion)) - end + bones_conclusion = "Inventory partially dropped" + public_conclusion = S("@1 died at @2, and partially dropped their inventory.", player_name, pos_string) end end - minetest.log("action", player_name .. " dies at " .. pos_string .. - ". " .. bones_conclusion) + if bones_position_message then + minetest.chat_send_player(player_name, public_conclusion) + end - local inv = current_dead_player.bones_inv - local inv_size = theoretical_max_slots - if inv then + minetest.log("action", player_name .. " dies at " .. pos_string .. ". " .. bones_conclusion) + + if bones_inv then + local inv_size = theoretical_max_slots for i = 1, theoretical_max_slots do - local stack = inv:get_stack("main", i) + local stack = bones_inv:get_stack("main", i) if stack:get_count() == 0 then inv_size = i - 1 break end end - local meta = minetest.get_meta(current_dead_player.bones_pos) - meta:set_string("formspec", get_bones_formspec_for_size(inv_size)) - meta:set_string("owner", player_name) + if inv_size <= 4 * 8 then + bones_inv:set_size("main", 4 * 8) + else + bones_inv:set_size("main", inv_size) + end + bones_meta:set_string("formspec", get_bones_formspec_for_size(inv_size)) + bones_meta:set_string("owner", player_name) if share_bones_time ~= 0 then - meta:set_string("infotext", S("@1's fresh bones", player_name)) + bones_meta:set_string("infotext", S("@1's fresh bones", player_name)) - if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then - meta:set_int("time", 0) + if share_bones_time_early == 0 or not minetest.is_protected(bones_pos, player_name) then + bones_meta:set_int("time", 0) else - meta:set_int("time", (share_bones_time - share_bones_time_early)) + bones_meta:set_int("time", (share_bones_time - share_bones_time_early)) end - minetest.get_node_timer(pos):start(10) + minetest.get_node_timer(bones_pos):start(10) else - meta:set_string("infotext", S("@1's bones", player_name)) + bones_meta:set_string("infotext", S("@1's bones", player_name)) end end end)