fixes as per code review completed

This commit is contained in:
Imre Péntek 2023-05-05 17:50:43 +02:00
parent b0545dc5c2
commit 3dad8a530d
2 changed files with 104 additions and 92 deletions

View File

@ -85,11 +85,11 @@ e.g. `table.insert(bones.player_inventory_lists, "backpack")`
Additionally, callbacks can be registered to transfer items into the bones on death: Additionally, callbacks can be registered to transfer items into the bones on death:
`bones.public.register_transfer_inventory_to_bones_on_player_death(function(player){})` `bones.register_dead_player_inv_management(function(player,callback){})`
In the above functions this routine should be used to add itmes to the bones inventory: In the above functions the provided callback should be used to add items to the bones inventory:
`bones.public.transfer_stack_to_bones(stack)` `callback(stack)`
please note that the inventory these items were taken from still need to be disposed of. please note that the inventory these items were taken from still need to be disposed of.

View File

@ -5,22 +5,11 @@
-- Load support for MT game translation. -- Load support for MT game translation.
local S = minetest.get_translator("bones") local S = minetest.get_translator("bones")
-- bones are supposed to hold up to 4*8+6+4*3*8+4+3*3 item slots:
-- 4*8 for the main inventory
-- 6 for the 3d_armor
-- (at most) 4*3*8 for 4 backpack worth of items (unified inventory)
-- 4 more for the actual backpacks
-- 3*3 more for the crafting grid
-- that adds up to 147, so 150 slots would be sufficient
local cols=15
local rows=10
bones = { local theoretical_max_slots = minetest.settings:get("bones_max_slots") or ( 15 * 10 )
private={ local dead_player_callbacks={}
dead_player_callbacks={}
}, bones = {}
public={}
}
local function is_owner(pos, name) local function is_owner(pos, name)
local owner = minetest.get_meta(pos):get_string("owner") local owner = minetest.get_meta(pos):get_string("owner")
@ -30,14 +19,29 @@ local function is_owner(pos, name)
return false return false
end end
local bones_formspec = local function get_bones_formspec_wh(cols,rows)
"size["..cols..","..(rows+5).."]" .. return
"list[current_name;main;0,0.3;"..cols..","..rows..";]" .. "size[" .. cols .. "," .. ( rows + 5 ) .. "]" ..
"list[current_player;main;"..((cols-8)/2)..","..rows..".85;8,1;]" .. "list[current_name;main;0,0.3;" .. cols .. "," .. rows .. ";]" ..
"list[current_player;main;"..((cols-8)/2)..","..(rows+2)..".08;8,3;8]" .. "list[current_player;main;" .. ( ( cols - 8 ) / 2 ) .. "," .. rows .. ".85;8,1;]" ..
"listring[current_name;main]" .. "list[current_player;main;".. ( ( cols - 8 ) / 2 ) .. "," .. ( rows + 2 ) .. ".08;8,3;8]" ..
"listring[current_player;main]" .. "listring[current_name;main]" ..
default.get_hotbar_bg(0,4.85) "listring[current_player;main]" ..
default.get_hotbar_bg(0,4.85)
end
local function get_bones_formspec_for_size(numitems)
--the absolute minimum is 4*8
if numitems <= 4 * 8 then
return get_bones_formspec_wh(8, 4)
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)
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 ) )
end
local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or 1200 local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or 1200
local share_bones_time_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4 local share_bones_time_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4
@ -199,66 +203,58 @@ end
local player_inventory_lists = { "main", "craft" } local player_inventory_lists = { "main", "craft" }
bones.player_inventory_lists = player_inventory_lists bones.player_inventory_lists = player_inventory_lists
local function is_all_empty(player_inv)
for _, list_name in ipairs(player_inventory_lists) do
if not player_inv:is_empty(list_name) then
return false
end
end
return true
end
--functions registered this way won't becalled if bones_mode is keep --functions registered this way won't becalled if bones_mode is keep
function bones.public.register_transfer_inventory_to_bones_on_player_death(func) function bones.register_dead_player_inv_management(func)
bones.private.dead_player_callbacks[#(bones.private.dead_player_callbacks)]=func table.insert(dead_player_callbacks, func)
end end
--drop or put into bones based on config and free slots in the bones local function transfer_stack_to_bones(stk,current_dead_player)
--supposed to be called from functions registered to bones.public.register_transfer_inventory_to_bones_on_player_death
function bones.public.transfer_stack_to_bones(stk)
-- check if it's possible to place bones, if not find space near player -- check if it's possible to place bones, if not find space near player
if ( ( bones.private.current_dead_player.bones_mode == "bones" ) and ( bones.private.current_dead_player.bones_pos == nil ) ) then if ( current_dead_player.bones_mode == "bones" ) and
bones.private.current_dead_player.bones_pos = bones.private.current_dead_player.player_pos ( current_dead_player.bones_pos == nil ) then
current_dead_player.bones_pos = current_dead_player.player_pos
local air local air
if ( may_replace(bones.private.current_dead_player.bones_pos, bones.private.current_dead_player.player) ) then if may_replace(current_dead_player.bones_pos, current_dead_player.player) then
air = bones.private.current_dead_player.bones_pos air = current_dead_player.bones_pos
else else
air = minetest.find_node_near(bones.private.current_dead_player.bones_pos, 1, {"air"}) air = minetest.find_node_near(current_dead_player.bones_pos, 1, {"air"})
end end
if air and not minetest.is_protected(air, bones.private.current_dead_player.player_name) then if air and not minetest.is_protected(air, current_dead_player.player_name) then
bones.private.current_dead_player.bones_pos = air current_dead_player.bones_pos = air
local param2 = minetest.dir_to_facedir(bones.private.current_dead_player.player:get_look_dir()) local param2 = minetest.dir_to_facedir(current_dead_player.player:get_look_dir())
minetest.set_node(bones.private.current_dead_player.bones_pos, {name = "bones:bones", param2 = param2}) minetest.set_node(current_dead_player.bones_pos, {name = "bones:bones", param2 = param2})
local meta = minetest.get_meta(bones.private.current_dead_player.bones_pos) local meta = minetest.get_meta(current_dead_player.bones_pos)
bones.private.current_dead_player.bones_inv = meta:get_inventory() current_dead_player.bones_inv = meta:get_inventory()
bones.private.current_dead_player.bones_inv:set_size("main", cols * rows) --make it so big that anything reasonable will for sure fit inside
current_dead_player.bones_inv:set_size("main", theoretical_max_slots)
else else
bones.private.current_dead_player.bones_mode = "drop" current_dead_player.bones_mode = "drop"
bones.private.current_dead_player.bones_pos = nil current_dead_player.bones_pos = nil
end end
end end
if ( ( bones.private.current_dead_player.bones_mode == "bones" ) and ( bones.private.current_dead_player.bones_inv:room_for_item("main", stk) ) ) then if ( current_dead_player.bones_mode == "bones" ) and
bones.private.current_dead_player.bones_inv:add_item("main", stk) ( current_dead_player.bones_inv:room_for_item("main", stk) ) then
current_dead_player.bones_inv:add_item("main", stk)
else else
drop(bones.private.current_dead_player.player_pos, stk) drop(current_dead_player.player_pos, stk)
bones.private.current_dead_player.dropped=true current_dead_player.dropped=true
end end
end end
local function player_dies_transfer_inventory(player) local function player_dies_transfer_inventory(player,transfer_stack)
local player_inv = player:get_inventory() local player_inv = player:get_inventory()
for _, list_name in ipairs(player_inventory_lists) do for _, list_name in ipairs(player_inventory_lists) do
for i = 1, player_inv:get_size(list_name) do for i = 1, player_inv:get_size(list_name) do
local stack = player_inv:get_stack(list_name, i) local stack = player_inv:get_stack(list_name, i)
bones.public.transfer_stack_to_bones(stack) transfer_stack(stack)
end end
player_inv:set_list(list_name, {}) player_inv:set_list(list_name, {})
end end
end end
bones.public.register_transfer_inventory_to_bones_on_player_death(player_dies_transfer_inventory) bones.register_dead_player_inv_management(player_dies_transfer_inventory)
minetest.register_on_dieplayer(function(player) minetest.register_on_dieplayer(function(player)
local pos = vector.round(player:get_pos()) local pos = vector.round(player:get_pos())
@ -267,7 +263,8 @@ minetest.register_on_dieplayer(function(player)
bones_mode = "bones" bones_mode = "bones"
end end
local player_name = player:get_player_name() local player_name = player:get_player_name()
bones.private.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 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_position_message = minetest.settings:get_bool("bones_position_message") == true 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(pos)
@ -282,58 +279,73 @@ minetest.register_on_dieplayer(function(player)
return return
end end
for i=0,#bones.private.dead_player_callbacks do local callback=function(stk)
local fun=bones.private.dead_player_callbacks[i] transfer_stack_to_bones(stk,current_dead_player)
fun(player)
end end
local bones_conclusion="" for i=1,#dead_player_callbacks do
local public_conclusion="" local fun=dead_player_callbacks[i]
fun(player,callback)
end
if(not(bones.private.current_dead_player.bones_pos))then local bones_conclusion
drop(bones.private.current_dead_player.player_pos, ItemStack("bones:bones"))
if(not(bones.private.current_dead_player.dropped))then 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" 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
else else
bones_conclusion="Inventory dropped" bones_conclusion="Inventory dropped"
public_conclusion="dropped their inventory" 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
end end
else else
if(not(bones.private.current_dead_player.dropped))then if not ( current_dead_player.dropped ) then
bones_conclusion="Bones placed" bones_conclusion="Bones placed"
public_conclusion="bones were 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
else else
bones_conclusion="Inventory partially dropped" bones_conclusion="Inventory partially dropped"
public_conclusion="partially dropped their inventory" 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
end end
end end
minetest.log("action", player_name .. " dies at " .. pos_string .. minetest.log("action", player_name .. " dies at " .. pos_string ..
". " .. bones_conclusion) ". " .. bones_conclusion)
if bones_position_message then local inv = current_dead_player.bones_inv
if(public_conclusion~="")then local inv_size = theoretical_max_slots
public_conclusion=", and "..public_conclusion if inv then
for i = 1, theoretical_max_slots do
local stack = inv:get_stack("main", i)
if stack:get_count() == 0 then
inv_size = i - 1
break
end
end end
minetest.chat_send_player(player_name, S("@1 died at @2@3.", player_name, pos_string, public_conclusion)) local meta = minetest.get_meta(current_dead_player.bones_pos)
end meta:set_string("formspec", get_bones_formspec_for_size(inv_size))
meta:set_string("owner", player_name)
local meta = minetest.get_meta(bones.private.current_dead_player.bones_pos) if share_bones_time ~= 0 then
meta:set_string("formspec", bones_formspec) meta:set_string("infotext", S("@1's fresh bones", player_name))
meta:set_string("owner", player_name)
if share_bones_time ~= 0 then if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then
meta:set_string("infotext", S("@1's fresh bones", player_name)) meta:set_int("time", 0)
else
meta:set_int("time", (share_bones_time - share_bones_time_early))
end
if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then minetest.get_node_timer(pos):start(10)
meta:set_int("time", 0)
else else
meta:set_int("time", (share_bones_time - share_bones_time_early)) meta:set_string("infotext", S("@1's bones", player_name))
end end
minetest.get_node_timer(pos):start(10)
else
meta:set_string("infotext", S("@1's bones", player_name))
end end
bones.private.current_dead_player=nil
end) end)