From 7ce365f4e4d551b076332a7faf3c161844caaab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Fri, 5 May 2023 07:31:06 +0200 Subject: [PATCH 01/30] bones: bones are now holding 150 item slots and register_transfer_inventory_to_bones_on_player_death callback --- game_api.txt | 10 +++ mods/bones/init.lua | 158 ++++++++++++++++++++++++++++---------------- 2 files changed, 111 insertions(+), 57 deletions(-) diff --git a/game_api.txt b/game_api.txt index c4250d50..25d592a9 100644 --- a/game_api.txt +++ b/game_api.txt @@ -83,6 +83,16 @@ in `bones.player_inventory_lists`. e.g. `table.insert(bones.player_inventory_lists, "backpack")` +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){})` + +In the above functions this routine should be used to add itmes to the bones inventory: + +`bones.public.transfer_stack_to_bones(stack)` + +please note that the inventory these items were taken from still need to be disposed of. + Creative API ------------ diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 797224c8..0fe11874 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -5,8 +5,22 @@ -- Load support for MT game translation. 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 = {} +bones = { + private={ + dead_player_callbacks={} + }, + public={} +} local function is_owner(pos, name) local owner = minetest.get_meta(pos):get_string("owner") @@ -38,10 +52,10 @@ local function drop_contents(pos) end local bones_formspec = - "size[8,9]" .. - "list[current_name;main;0,0.3;8,4;]" .. - "list[current_player;main;0,4.85;8,1;]" .. - "list[current_player;main;0,6.08;8,3;8]" .. + "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]" .. "listring[current_name;main]" .. "listring[current_player;main]" .. default.get_hotbar_bg(0,4.85) @@ -209,15 +223,68 @@ local function is_all_empty(player_inv) return true end +--functions registered this way won't becalled if bones_mode is keep +function bones.public.register_transfer_inventory_to_bones_on_player_death(func) + bones.private.dead_player_callbacks[#(bones.private.dead_player_callbacks)]=func +end + +--drop or put into bones based on config and free slots in the bones +--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 + if ( ( bones.private.current_dead_player.bones_mode == "bones" ) and ( bones.private.current_dead_player.bones_pos == nil ) ) then + bones.private.current_dead_player.bones_pos = bones.private.current_dead_player.player_pos + local air + if ( may_replace(bones.private.current_dead_player.bones_pos, bones.private.current_dead_player.player) ) then + air = bones.private.current_dead_player.bones_pos + else + air = minetest.find_node_near(bones.private.current_dead_player.bones_pos, 1, {"air"}) + end + + if air and not minetest.is_protected(air, bones.private.current_dead_player.player_name) then + bones.private.current_dead_player.bones_pos = air + local param2 = minetest.dir_to_facedir(bones.private.current_dead_player.player:get_look_dir()) + minetest.set_node(bones.private.current_dead_player.bones_pos, {name = "bones:bones", param2 = param2}) + local meta = minetest.get_meta(bones.private.current_dead_player.bones_pos) + bones.private.current_dead_player.bones_inv = meta:get_inventory() + bones.private.current_dead_player.bones_inv:set_size("main", cols * rows) + else + bones.private.current_dead_player.bones_mode = "drop" + bones.private.current_dead_player.bones_pos = nil + 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 + bones.private.current_dead_player.bones_inv:add_item("main", stk) + else + drop(bones.private.current_dead_player.player_pos, stk) + bones.private.current_dead_player.dropped=true + end +end + +local function player_dies_transfer_inventory(player) + 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) + bones.public.transfer_stack_to_bones(stack) + end + player_inv:set_list(list_name, {}) + end +end + +bones.public.register_transfer_inventory_to_bones_on_player_death(player_dies_transfer_inventory) + minetest.register_on_dieplayer(function(player) + local 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() + 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 bones_position_message = minetest.settings:get_bool("bones_position_message") == true - local player_name = player:get_player_name() - local pos = vector.round(player:get_pos()) local pos_string = minetest.pos_to_string(pos) -- return if keep inventory set or in creative mode @@ -230,67 +297,43 @@ minetest.register_on_dieplayer(function(player) return end - local player_inv = player:get_inventory() - if is_all_empty(player_inv) then - minetest.log("action", player_name .. " dies at " .. pos_string .. - ". No bones placed") - if bones_position_message then - minetest.chat_send_player(player_name, S("@1 died at @2.", player_name, pos_string)) - end - return + for i=0,#bones.private.dead_player_callbacks do + local fun=bones.private.dead_player_callbacks[i] + fun(player) end - -- check if it's possible to place bones, if not find space near player - if bones_mode == "bones" and not may_replace(pos, player) then - local air = minetest.find_node_near(pos, 1, {"air"}) - if air then - pos = air + local bones_conclusion="" + local public_conclusion="" + + if(not(bones.private.current_dead_player.bones_pos))then + drop(bones.private.current_dead_player.player_pos, ItemStack("bones:bones")) + if(not(bones.private.current_dead_player.dropped))then + bones_conclusion="No bones placed" else - bones_mode = "drop" + bones_conclusion="Inventory dropped" + public_conclusion="dropped their inventory" + end + else + if(not(bones.private.current_dead_player.dropped))then + bones_conclusion="Bones placed" + public_conclusion="bones were placed" + else + bones_conclusion="Inventory partially dropped" + public_conclusion="partially dropped their inventory" end end - if bones_mode == "drop" then - for _, list_name in ipairs(player_inventory_lists) do - for i = 1, player_inv:get_size(list_name) do - drop(pos, player_inv:get_stack(list_name, i)) - end - player_inv:set_list(list_name, {}) - end - drop(pos, ItemStack("bones:bones")) - minetest.log("action", player_name .. " dies at " .. pos_string .. - ". 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)) - end - return - end - - local param2 = minetest.dir_to_facedir(player:get_look_dir()) - minetest.set_node(pos, {name = "bones:bones", param2 = param2}) - minetest.log("action", player_name .. " dies at " .. pos_string .. - ". Bones placed") + ". " .. bones_conclusion) + if bones_position_message then - minetest.chat_send_player(player_name, S("@1 died at @2, and bones were placed.", player_name, pos_string)) - end - - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - inv:set_size("main", 8 * 4) - - 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) - if inv:room_for_item("main", stack) then - inv:add_item("main", stack) - else -- no space left - drop(pos, stack) - end + if(public_conclusion~="")then + public_conclusion=", and "..public_conclusion end - player_inv:set_list(list_name, {}) + minetest.chat_send_player(player_name, S("@1 died at @2@3.", player_name, pos_string, public_conclusion)) end + local meta = minetest.get_meta(bones.private.current_dead_player.bones_pos) meta:set_string("formspec", bones_formspec) meta:set_string("owner", player_name) @@ -307,4 +350,5 @@ minetest.register_on_dieplayer(function(player) else meta:set_string("infotext", S("@1's bones", player_name)) end + bones.private.current_dead_player=nil end) From 63f6abe52fbb0941cd6ad7b62cd4cde1cb9a7167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Fri, 5 May 2023 17:50:43 +0200 Subject: [PATCH 02/30] fixes as per code review completed --- game_api.txt | 6 +- mods/bones/init.lua | 196 ++++++++++++++++++++++++-------------------- 2 files changed, 110 insertions(+), 92 deletions(-) diff --git a/game_api.txt b/game_api.txt index 25d592a9..55d2011e 100644 --- a/game_api.txt +++ b/game_api.txt @@ -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: -`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. diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 0fe11874..9ce41702 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -5,22 +5,12 @@ -- Load support for MT game translation. 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 = { - private={ - dead_player_callbacks={} - }, - public={} -} +local theoretical_max_slots = minetest.settings:get("bones_max_slots") or ( 15 * 10 ) +local dead_player_callbacks={} + +bones = {} + local function is_owner(pos, name) local owner = minetest.get_meta(pos):get_string("owner") @@ -30,6 +20,7 @@ local function is_owner(pos, name) return false end + local function drop(pos, itemstack) local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) if obj then @@ -41,6 +32,7 @@ local function drop(pos, itemstack) end end + local function drop_contents(pos) local inv = minetest.get_meta(pos):get_inventory() @@ -51,14 +43,32 @@ local function drop_contents(pos) minetest.remove_node(pos) end -local bones_formspec = - "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]" .. - "listring[current_name;main]" .. - "listring[current_player;main]" .. - default.get_hotbar_bg(0,4.85) + +local function get_bones_formspec_wh(cols,rows) + return + "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]" .. + "listring[current_name;main]" .. + "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_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4 @@ -214,66 +224,58 @@ end local player_inventory_lists = { "main", "craft" } 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 -function bones.public.register_transfer_inventory_to_bones_on_player_death(func) - bones.private.dead_player_callbacks[#(bones.private.dead_player_callbacks)]=func +function bones.register_dead_player_inv_management(func) + table.insert(dead_player_callbacks, func) end ---drop or put into bones based on config and free slots in the bones ---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) +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 ( ( bones.private.current_dead_player.bones_mode == "bones" ) and ( bones.private.current_dead_player.bones_pos == nil ) ) then - bones.private.current_dead_player.bones_pos = bones.private.current_dead_player.player_pos + 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(bones.private.current_dead_player.bones_pos, bones.private.current_dead_player.player) ) then - air = bones.private.current_dead_player.bones_pos + 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(bones.private.current_dead_player.bones_pos, 1, {"air"}) + air = minetest.find_node_near(current_dead_player.bones_pos, 1, {"air"}) end - if air and not minetest.is_protected(air, bones.private.current_dead_player.player_name) then - bones.private.current_dead_player.bones_pos = air - local param2 = minetest.dir_to_facedir(bones.private.current_dead_player.player:get_look_dir()) - minetest.set_node(bones.private.current_dead_player.bones_pos, {name = "bones:bones", param2 = param2}) - local meta = minetest.get_meta(bones.private.current_dead_player.bones_pos) - bones.private.current_dead_player.bones_inv = meta:get_inventory() - bones.private.current_dead_player.bones_inv:set_size("main", cols * rows) + 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 - bones.private.current_dead_player.bones_mode = "drop" - bones.private.current_dead_player.bones_pos = nil + current_dead_player.bones_mode = "drop" + current_dead_player.bones_pos = nil 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 - bones.private.current_dead_player.bones_inv:add_item("main", stk) + 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(bones.private.current_dead_player.player_pos, stk) - bones.private.current_dead_player.dropped=true + drop(current_dead_player.player_pos, stk) + current_dead_player.dropped=true end end -local function player_dies_transfer_inventory(player) +local function player_dies_transfer_inventory(player,transfer_stack) 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) - bones.public.transfer_stack_to_bones(stack) + transfer_stack(stack) end player_inv:set_list(list_name, {}) 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) local pos = vector.round(player:get_pos()) @@ -282,7 +284,8 @@ minetest.register_on_dieplayer(function(player) bones_mode = "bones" end 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 pos_string = minetest.pos_to_string(pos) @@ -297,58 +300,73 @@ minetest.register_on_dieplayer(function(player) return end - for i=0,#bones.private.dead_player_callbacks do - local fun=bones.private.dead_player_callbacks[i] - fun(player) + local callback=function(stk) + transfer_stack_to_bones(stk,current_dead_player) end - local bones_conclusion="" - local public_conclusion="" + for i=1,#dead_player_callbacks do + local fun=dead_player_callbacks[i] + fun(player,callback) + end - if(not(bones.private.current_dead_player.bones_pos))then - drop(bones.private.current_dead_player.player_pos, ItemStack("bones:bones")) - if(not(bones.private.current_dead_player.dropped))then + local bones_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 else 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 else - if(not(bones.private.current_dead_player.dropped))then + if not ( current_dead_player.dropped ) then 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 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 minetest.log("action", player_name .. " dies at " .. pos_string .. ". " .. bones_conclusion) - if bones_position_message then - if(public_conclusion~="")then - public_conclusion=", and "..public_conclusion + local inv = current_dead_player.bones_inv + local inv_size = theoretical_max_slots + 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 - minetest.chat_send_player(player_name, S("@1 died at @2@3.", player_name, pos_string, public_conclusion)) - 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) - local meta = minetest.get_meta(bones.private.current_dead_player.bones_pos) - meta:set_string("formspec", bones_formspec) - meta:set_string("owner", player_name) + if share_bones_time ~= 0 then + meta:set_string("infotext", S("@1's fresh bones", player_name)) - if share_bones_time ~= 0 then - 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) + 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 - meta:set_int("time", 0) + minetest.get_node_timer(pos):start(10) else - meta:set_int("time", (share_bones_time - share_bones_time_early)) + meta:set_string("infotext", S("@1's bones", player_name)) end - - minetest.get_node_timer(pos):start(10) - else - meta:set_string("infotext", S("@1's bones", player_name)) end - bones.private.current_dead_player=nil end) From 54539fb05c095ebe933b44877beacd3c6897f64d 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 03/30] 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 55d2011e..3d2d5849 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 9ce41702..6cc122fe 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 = {} @@ -46,10 +46,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) @@ -63,10 +63,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 @@ -224,71 +224,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 @@ -300,73 +268,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) From 5c9ae2911c5b88e2907d8b57ac94919556ce18ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Fri, 12 May 2023 09:37:26 +0200 Subject: [PATCH 04/30] fixes as per code review completed (3) --- mods/bones/init.lua | 53 ++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 6cc122fe..97664358 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -6,8 +6,10 @@ -- 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 bones_max_slots = minetest.settings:get("bones_max_slots") or 15 * 10 local dead_player_callbacks={} +-- we're going to display no less than 4*8 slots, we'll also provide at least 4*8 slots in bones +local min_inv_size = 4 * 8 bones = {} @@ -58,15 +60,15 @@ end local function get_bones_formspec_for_size(numitems) --the absolute minimum is 4*8 - if numitems <= 4 * 8 then + if numitems <= min_inv_size 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) + return get_bones_formspec_wh(math.ceil(numitems / 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.ceil(numitems / 15)) end @@ -288,7 +290,7 @@ minetest.register_on_dieplayer(function(player) 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) + bones_inv:set_size("main", bones_max_slots) else bones_mode = "drop" bones_pos = nil @@ -304,45 +306,46 @@ minetest.register_on_dieplayer(function(player) end end - local bones_conclusion - local public_conclusion + local log_message + local chat_message - 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) + if bones_pos then + if dropped then + log_message = "Inventory partially dropped" + chat_message = "@1 died at @2, and partially dropped their inventory." else - bones_conclusion = "Inventory dropped" - public_conclusion = S("@1 died at @2, and dropped their inventory.", player_name, pos_string) + log_message = "Bones placed" + chat_message = "@1 died at @2, and bones were placed." end else - if not dropped then - bones_conclusion = "Bones placed" - public_conclusion = S("@1 died at @2, and bones were placed.", player_name, pos_string) + drop(player_pos, ItemStack("bones:bones")) + if dropped then + log_message = "Inventory dropped" + chat_message = "@1 died at @2, and dropped their inventory." else - bones_conclusion = "Inventory partially dropped" - public_conclusion = S("@1 died at @2, and partially dropped their inventory.", player_name, pos_string) + log_message = "No bones placed" + chat_message = "@1 died at @2." end end if bones_position_message then - minetest.chat_send_player(player_name, public_conclusion) + chat_message = S(chat_message, player_name, pos_string) + minetest.chat_send_player(player_name, chat_message) end - minetest.log("action", player_name .. " dies at " .. pos_string .. ". " .. bones_conclusion) + minetest.log("action", player_name .. " dies at " .. pos_string .. ". " .. log_message) if bones_inv then - local inv_size = theoretical_max_slots - for i = 1, theoretical_max_slots do + local inv_size = bones_max_slots + for i = 1, bones_max_slots do local stack = bones_inv:get_stack("main", i) if stack:get_count() == 0 then inv_size = i - 1 break end end - if inv_size <= 4 * 8 then - bones_inv:set_size("main", 4 * 8) + if inv_size <= min_inv_size then + bones_inv:set_size("main", min_inv_size) else bones_inv:set_size("main", inv_size) end From 93637aab706f82b76414f37e525157115add910b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Mon, 29 May 2023 19:01:11 +0200 Subject: [PATCH 05/30] fixes as per code review completed (4) --- mods/bones/init.lua | 94 ++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 35 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 97664358..780a3d47 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -245,6 +245,58 @@ end bones.register_dead_player_inv_management(player_dies_transfer_inventory) +local function collect_all_items(player) + local all_inventory = {} + for _, fun in ipairs(dead_player_callbacks) do + local items = fun(player) + -- https://www.programming-idioms.org/idiom/166/concatenate-two-lists/3812/lua + table.move(items, 1, #items, #all_inventory + 1, all_inventory) + end + return all_inventory +end + +-- check if it's possible to place bones, if not find space near player +local function find_node_for_bones_on_player_death(player, player_pos) + local bones_pos = nil + local bones_inv = nil + local bones_meta = nil + local bones_mode = "bones" + 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 + + 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", bones_max_slots) + else + bones_mode = "drop" + bones_pos = nil + end + return bones_mode, bones_pos, bones_inv, bones_meta +end + +local function dump_into(bones_mode, bones_inv, bones_pos, all_inventory) + local dropped = false + for _, item in ipairs(all_inventory) do + 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 + return dropped +end + minetest.register_on_dieplayer(function(player) local player_pos = vector.round(player:get_pos()) local bones_mode = minetest.settings:get("bones_mode") or "bones" @@ -254,7 +306,6 @@ minetest.register_on_dieplayer(function(player) local player_name = player:get_player_name() 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 @@ -270,41 +321,14 @@ minetest.register_on_dieplayer(function(player) return 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 - - 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", bones_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 + local all_inventory = collect_all_items(player) + if bones_mode == "bones" and #all_inventory > 0 then + bones_mode, bones_pos, bones_inv, bones_meta = find_node_for_bones_on_player_death(player, player_pos) end + if bones_mode == "drop" and #all_inventory > 0 then + all_inventory.insert(all_inventory,ItemStack("bones:bones")) + end + local dropped = dump_into(bones_mode, bones_inv, bones_pos, all_inventory) local log_message local chat_message From bfa75a2a83fc79f86c0cf142bf8adbd88a095537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Mon, 29 May 2023 20:16:01 +0200 Subject: [PATCH 06/30] Use Minetest's `table.insert_all` --- mods/bones/init.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 780a3d47..0a9e8419 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -246,13 +246,12 @@ end bones.register_dead_player_inv_management(player_dies_transfer_inventory) local function collect_all_items(player) - local all_inventory = {} + local all_items = {} for _, fun in ipairs(dead_player_callbacks) do local items = fun(player) - -- https://www.programming-idioms.org/idiom/166/concatenate-two-lists/3812/lua - table.move(items, 1, #items, #all_inventory + 1, all_inventory) + table.insert_all(all_items, items) end - return all_inventory + return all_items end -- check if it's possible to place bones, if not find space near player From 0b484fd5a67884098306ade0589c73cb2a27eefd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Mon, 29 May 2023 21:47:56 +0200 Subject: [PATCH 07/30] Fix `table.insert` usage --- mods/bones/init.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 0a9e8419..cae75847 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -320,14 +320,14 @@ minetest.register_on_dieplayer(function(player) return end - local all_inventory = collect_all_items(player) - if bones_mode == "bones" and #all_inventory > 0 then + local all_items = collect_all_items(player) + if bones_mode == "bones" and #all_items > 0 then bones_mode, bones_pos, bones_inv, bones_meta = find_node_for_bones_on_player_death(player, player_pos) end - if bones_mode == "drop" and #all_inventory > 0 then - all_inventory.insert(all_inventory,ItemStack("bones:bones")) + if bones_mode == "drop" and #all_items > 0 then + table.insert(all_items, ItemStack("bones:bones")) end - local dropped = dump_into(bones_mode, bones_inv, bones_pos, all_inventory) + local dropped = dump_into(bones_mode, bones_inv, bones_pos, all_items) local log_message local chat_message From f963ab2a8e8834823b8529ccd63f4acd8ca4c4df Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Tue, 30 May 2023 10:26:17 +0200 Subject: [PATCH 08/30] Refactor --- game_api.txt | 11 ++- mods/bones/init.lua | 213 +++++++++++++++++++++----------------------- 2 files changed, 109 insertions(+), 115 deletions(-) diff --git a/game_api.txt b/game_api.txt index 3d2d5849..6b4222ff 100644 --- a/game_api.txt +++ b/game_api.txt @@ -83,13 +83,16 @@ in `bones.player_inventory_lists`. 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 to the bones on death: -`bones.register_dead_player_inv_management(function(player){})` +`bones.register_collect_items(callback)` -the registered function is supposed to return with a table of items to be transferred. +Functions registered this way won't be called if `bones_mode` is `keep`. -please note that the inventory these items were taken from still need to be disposed of. +`callback` is a `function(player)` which `return`s a table of items to be transferred. + +Please note that this does not remove the items from the inventory they were taken of. +Disposing of the items in this inventory is the `callback`'s responsibility. Creative API diff --git a/mods/bones/init.lua b/mods/bones/init.lua index cae75847..b7029a4d 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -7,9 +7,7 @@ local S = minetest.get_translator("bones") local bones_max_slots = minetest.settings:get("bones_max_slots") or 15 * 10 -local dead_player_callbacks={} --- we're going to display no less than 4*8 slots, we'll also provide at least 4*8 slots in bones -local min_inv_size = 4 * 8 +local min_inv_size = 4 * 8 -- display and provide at least this many slots bones = {} @@ -59,16 +57,23 @@ end local function get_bones_formspec_for_size(numitems) - --the absolute minimum is 4*8 + local cols, rows if numitems <= min_inv_size then - return get_bones_formspec_wh(8, 4) + cols, rows = 8, 4 + elseif numitems <= 4 * 15 then + cols, rows = math.ceil(numitems / 4), 4 + else + cols, rows = 15, math.ceil(numitems / 15) 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.ceil(numitems / 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.ceil(numitems / 15)) + return table.concat{ + "size[", cols, ",", rows + 5, "]", + "list[current_name;main;0,0.3;", cols, ",", rows, ";]", + "list[current_player;main;", (cols - 8) / 2, ",", rows + 0.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) + } end @@ -226,92 +231,99 @@ end local player_inventory_lists = { "main", "craft" } bones.player_inventory_lists = player_inventory_lists ---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) +local collect_items_callbacks = {} + +function bones.register_collect_items(func) + table.insert(collect_items_callbacks, func) end -local function player_dies_transfer_inventory(player) - local result = {} +bones.register_collect_items(function(player) + local items = {} 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 - table.insert(result, player_inv:get_stack(list_name, i)) - end + for _, list_name in ipairs(bones.player_inventory_lists) do + table.insert_all(items, player_inv:get_list(list_name) or {}) player_inv:set_list(list_name, {}) end - return result + return items +end) + +local function collect_items(player) + local items = {} + for _, cb in ipairs(collect_items_callbacks) do + table.insert_all(items, cb(player)) + end + return items end -bones.register_dead_player_inv_management(player_dies_transfer_inventory) - -local function collect_all_items(player) - local all_items = {} - for _, fun in ipairs(dead_player_callbacks) do - local items = fun(player) - table.insert_all(all_items, items) - end - return all_items -end - --- check if it's possible to place bones, if not find space near player -local function find_node_for_bones_on_player_death(player, player_pos) - local bones_pos = nil - local bones_inv = nil - local bones_meta = nil - local bones_mode = "bones" - bones_pos = player_pos - local air - if may_replace(bones_pos, player) then - air = bones_pos +-- Try to find the closest space near the player to place bones +local function find_bones_pos(player) + local rounded_player_pos = vector.round(player:get_pos()) + local bones_pos + if may_replace(rounded_player_pos, player) then + bones_pos = rounded_player_pos else - air = minetest.find_node_near(bones_pos, 1, {"air"}) + bones_pos = minetest.find_node_near(rounded_player_pos, 1, {"air"}) end - - 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", bones_max_slots) - else - bones_mode = "drop" + if minetest.is_protected(bones_pos, player:get_player_name()) then bones_pos = nil end - return bones_mode, bones_pos, bones_inv, bones_meta + return bones_pos end -local function dump_into(bones_mode, bones_inv, bones_pos, all_inventory) - local dropped = false - for _, item in ipairs(all_inventory) do - if bones_mode == "bones" and bones_inv:room_for_item("main", item) then +local function place_bones(player, bones_pos, items) + local param2 = minetest.dir_to_facedir(player:get_look_dir()) + minetest.set_node(bones_pos, {name = "bones:bones", param2 = param2}) + local bones_meta = minetest.get_meta(bones_pos) + local bones_inv = bones_meta:get_inventory() + -- Make it big enough that anything reasonable will fit + bones_inv:set_size("main", bones_max_slots) + local leftover_items = {} + for _, item in ipairs(items) do + if bones_inv:room_for_item("main", item) then bones_inv:add_item("main", item) else - drop(player_pos, item) - dropped = true + table.insert(leftover_items, item) end end - return dropped + local inv_size = bones_max_slots + for i = 1, bones_max_slots do + if bones_inv:get_stack("main", i):get_count() == 0 then + inv_size = i - 1 + break + end + end + bones_inv:set_size("main", math.max(inv_size, min_inv_size)) + bones_meta:set_string("formspec", get_bones_formspec_for_size(inv_size)) + -- "Ownership" + local player_name = player:get_player_name() + bones_meta:set_string("owner", player_name) + if share_bones_time ~= 0 then + bones_meta:set_string("infotext", S("@1's fresh bones", player_name)) + if share_bones_time_early == 0 or not minetest.is_protected(bones_pos, player_name) then + bones_meta:set_int("time", 0) + else + bones_meta:set_int("time", share_bones_time - share_bones_time_early) + end + minetest.get_node_timer(bones_pos):start(10) + else + bones_meta:set_string("infotext", S("@1's bones", player_name)) + end + return leftover_items end minetest.register_on_dieplayer(function(player) - 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 bones_inv = nil - local bones_pos = nil - local bones_meta = nil local bones_position_message = minetest.settings:get_bool("bones_position_message") == true - local pos_string = minetest.pos_to_string(player_pos) + local pos_string = minetest.pos_to_string(player:get_pos()) - -- return if keep inventory set or in creative mode - if bones_mode == "keep" or minetest.is_creative_enabled(player_name) then + local items = collect_items(player) + + if bones_mode == "keep" or minetest.is_creative_enabled(player_name) or #items == 0 then minetest.log("action", player_name .. " dies at " .. pos_string .. ". No bones placed") if bones_position_message then @@ -320,20 +332,32 @@ minetest.register_on_dieplayer(function(player) return end - local all_items = collect_all_items(player) - if bones_mode == "bones" and #all_items > 0 then - bones_mode, bones_pos, bones_inv, bones_meta = find_node_for_bones_on_player_death(player, player_pos) + local bones_placed, drop_bones = false, false + if bones_mode == "bones" then + local bones_pos = find_bones_pos(player) + if bones_pos then + items = place_bones(player, bones_pos, items) + bones_placed, drop_bones = true, #items ~= 0 + else + drop_bones = true + end + elseif bones_mode == "drop" then + drop_bones = true end - if bones_mode == "drop" and #all_items > 0 then - table.insert(all_items, ItemStack("bones:bones")) + if drop_bones then + if not bones_placed then + table.insert(items, ItemStack("bones:bones")) + end + for _, item in ipairs(items) do + drop(player:get_pos(), item) + end end - local dropped = dump_into(bones_mode, bones_inv, bones_pos, all_items) local log_message local chat_message - if bones_pos then - if dropped then + if bones_placed then + if drop_bones then log_message = "Inventory partially dropped" chat_message = "@1 died at @2, and partially dropped their inventory." else @@ -341,8 +365,7 @@ minetest.register_on_dieplayer(function(player) chat_message = "@1 died at @2, and bones were placed." end else - drop(player_pos, ItemStack("bones:bones")) - if dropped then + if drop_bones then log_message = "Inventory dropped" chat_message = "@1 died at @2, and dropped their inventory." else @@ -357,36 +380,4 @@ minetest.register_on_dieplayer(function(player) end minetest.log("action", player_name .. " dies at " .. pos_string .. ". " .. log_message) - - if bones_inv then - local inv_size = bones_max_slots - for i = 1, bones_max_slots do - local stack = bones_inv:get_stack("main", i) - if stack:get_count() == 0 then - inv_size = i - 1 - break - end - end - if inv_size <= min_inv_size then - bones_inv:set_size("main", min_inv_size) - 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 - bones_meta:set_string("infotext", S("@1's fresh bones", player_name)) - - if share_bones_time_early == 0 or not minetest.is_protected(bones_pos, player_name) then - bones_meta:set_int("time", 0) - else - bones_meta:set_int("time", (share_bones_time - share_bones_time_early)) - end - - minetest.get_node_timer(bones_pos):start(10) - else - bones_meta:set_string("infotext", S("@1's bones", player_name)) - end - end end) From abdd3f12df4918d01942ebf2c9f669c4d6eeb559 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Tue, 30 May 2023 10:33:07 +0200 Subject: [PATCH 09/30] Make Luacheck happy --- .luacheckrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.luacheckrc b/.luacheckrc index b8388982..a10f6087 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -17,7 +17,7 @@ read_globals = { "Settings", "unpack", -- Silence errors about custom table methods. - table = { fields = { "copy", "indexof" } }, + table = { fields = { "copy", "indexof", "insert_all" } }, -- Silence warnings about accessing undefined fields of global 'math' math = { fields = { "sign" } } } From 5208139538812f74f9881d0bbdc463800c362712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 24 Feb 2024 14:51:17 +0100 Subject: [PATCH 10/30] PR #3030 fix --- mods/bones/init.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index b7029a4d..fa91344a 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -264,9 +264,6 @@ local function find_bones_pos(player) else bones_pos = minetest.find_node_near(rounded_player_pos, 1, {"air"}) end - if minetest.is_protected(bones_pos, player:get_player_name()) then - bones_pos = nil - end return bones_pos end From 76dcf7256cc2bcefb54aedba7d38a6f54b97b91d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 24 Feb 2024 15:05:59 +0100 Subject: [PATCH 11/30] as per https://github.com/minetest/minetest_game/pull/3030#pullrequestreview-1899419816 --- mods/bones/init.lua | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index fa91344a..e7c2d2bd 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -11,6 +11,9 @@ local min_inv_size = 4 * 8 -- display and provide at least this many slots bones = {} +local function TRANSLATEMEPLEASE(s) + return s +end local function is_owner(pos, name) local owner = minetest.get_meta(pos):get_string("owner") @@ -356,18 +359,18 @@ minetest.register_on_dieplayer(function(player) if bones_placed then if drop_bones then log_message = "Inventory partially dropped" - chat_message = "@1 died at @2, and partially dropped their inventory." + chat_message = TRANSLATEMEPLEASE("@1 died at @2, and partially dropped their inventory.") else log_message = "Bones placed" - chat_message = "@1 died at @2, and bones were placed." + chat_message = TRANSLATEMEPLEASE("@1 died at @2, and bones were placed.") end else if drop_bones then log_message = "Inventory dropped" - chat_message = "@1 died at @2, and dropped their inventory." + chat_message = TRANSLATEMEPLEASE("@1 died at @2, and dropped their inventory.") else log_message = "No bones placed" - chat_message = "@1 died at @2." + chat_message = TRANSLATEMEPLEASE("@1 died at @2.") end end From d20c1e2dcf05d8237492d44c136140c539bb6d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Tue, 27 Feb 2024 12:50:26 +0100 Subject: [PATCH 12/30] NS routine as per code review --- mods/bones/init.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index e7c2d2bd..16b7a9be 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -11,7 +11,7 @@ local min_inv_size = 4 * 8 -- display and provide at least this many slots bones = {} -local function TRANSLATEMEPLEASE(s) +local function NS(s) return s end @@ -359,18 +359,18 @@ minetest.register_on_dieplayer(function(player) if bones_placed then if drop_bones then log_message = "Inventory partially dropped" - chat_message = TRANSLATEMEPLEASE("@1 died at @2, and partially dropped their inventory.") + chat_message = NS("@1 died at @2, and partially dropped their inventory.") else log_message = "Bones placed" - chat_message = TRANSLATEMEPLEASE("@1 died at @2, and bones were placed.") + chat_message = NS("@1 died at @2, and bones were placed.") end else if drop_bones then log_message = "Inventory dropped" - chat_message = TRANSLATEMEPLEASE("@1 died at @2, and dropped their inventory.") + chat_message = NS("@1 died at @2, and dropped their inventory.") else log_message = "No bones placed" - chat_message = TRANSLATEMEPLEASE("@1 died at @2.") + chat_message = NS("@1 died at @2.") end end From 21ad20d631782beae5dcda9b4532c2f0d7f3b669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 23 Mar 2024 15:10:48 +0100 Subject: [PATCH 13/30] fix for https://github.com/minetest/minetest_game/pull/3030#pullrequestreview-1912657094 --- mods/bones/init.lua | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 16b7a9be..fce649d9 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -244,13 +244,23 @@ bones.register_collect_items(function(player) local items = {} local player_inv = player:get_inventory() for _, list_name in ipairs(bones.player_inventory_lists) do - table.insert_all(items, player_inv:get_list(list_name) or {}) + local inv_list=player_inv:get_list(list_name) or {} + for _, inv_slot in ipairs(inv_list) do + if inv_slot:get_count() > 0 then + table.insert(items, inv_slot) + end + end + player_inv:set_list(list_name, {}) end return items end) -local function collect_items(player) +local function collect_items(player, player_name) + if minetest.is_creative_enabled(player_name) then + return {} + end + local items = {} for _, cb in ipairs(collect_items_callbacks) do table.insert_all(items, cb(player)) @@ -321,9 +331,9 @@ minetest.register_on_dieplayer(function(player) local bones_position_message = minetest.settings:get_bool("bones_position_message") == true local pos_string = minetest.pos_to_string(player:get_pos()) - local items = collect_items(player) + local items = collect_items(player, player_name) - if bones_mode == "keep" or minetest.is_creative_enabled(player_name) or #items == 0 then + if bones_mode == "keep" or #items == 0 then minetest.log("action", player_name .. " dies at " .. pos_string .. ". No bones placed") if bones_position_message then From 2f29afddcdc51ec1d1d69d67bcfb2b3a87a6e36f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 23 Mar 2024 16:43:06 +0100 Subject: [PATCH 14/30] doc clarification --- game_api.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game_api.txt b/game_api.txt index 6b4222ff..17d8eaa9 100644 --- a/game_api.txt +++ b/game_api.txt @@ -87,7 +87,7 @@ Additionally, callbacks can be registered to transfer items to the bones on deat `bones.register_collect_items(callback)` -Functions registered this way won't be called if `bones_mode` is `keep`. +Functions registered this way won't be called if `bones_mode` is `keep` or in case of the death of a creative player. `callback` is a `function(player)` which `return`s a table of items to be transferred. From f970fc8537e72c52609a00d8e4e081fd797f1f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Thu, 28 Mar 2024 11:29:07 +0100 Subject: [PATCH 15/30] as per https://github.com/minetest/minetest_game/pull/3030#discussion_r1538212559 --- mods/bones/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index fce649d9..c385f859 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 bones_max_slots = minetest.settings:get("bones_max_slots") or 15 * 10 +local bones_max_slots = tonumber(minetest.settings:get("bones_max_slots")) or 15 * 10 local min_inv_size = 4 * 8 -- display and provide at least this many slots bones = {} From fa791eab1d79e64cda573336b7d2115fa77a6143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Thu, 28 Mar 2024 16:46:22 +0100 Subject: [PATCH 16/30] scrollbar vs bones formspec --- mods/bones/init.lua | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index c385f859..fd1fc79d 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -23,6 +23,12 @@ local function is_owner(pos, name) return false end +local function appendmulti(tbl,...) + for _, v in pairs({...}) do + table.insert(tbl, v) + end +end + local function drop(pos, itemstack) local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) @@ -61,22 +67,30 @@ end local function get_bones_formspec_for_size(numitems) local cols, rows + local scroll=false if numitems <= min_inv_size then cols, rows = 8, 4 - elseif numitems <= 4 * 15 then - cols, rows = math.ceil(numitems / 4), 4 else - cols, rows = 15, math.ceil(numitems / 15) + cols, rows = 8, math.ceil(numitems / 8) + scroll=true end - return table.concat{ - "size[", cols, ",", rows + 5, "]", - "list[current_name;main;0,0.3;", cols, ",", rows, ";]", - "list[current_player;main;", (cols - 8) / 2, ",", rows + 0.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) - } + local output={} + appendmulti(output, "size[", 8.5, ",", 9, "]") + if scroll then + appendmulti(output, "scrollbaroptions[max=",rows*9.3,"]") + appendmulti(output, "scrollbar[8,0;0.3,4.5;vertical;bones_scroll;0]") + appendmulti(output, "scroll_container[0,0.3;10.3,4.95;bones_scroll;vertical;0.1]") + end + appendmulti(output, "list[current_name;main;0,0;", cols, ",", rows, ";]") + if scroll then + appendmulti(output, "scroll_container_end[]") + end + appendmulti(output, "list[current_player;main;", 0, ",", 4.75, ";8,1;]") + appendmulti(output, "list[current_player;main;", 0, ",", 5.98, ";8,3;8]") + appendmulti(output, "listring[current_name;main]") + appendmulti(output, "listring[current_player;main]") + appendmulti(output, default.get_hotbar_bg(0, 4.85)) + return table.concat(output) end @@ -253,6 +267,11 @@ bones.register_collect_items(function(player) player_inv:set_list(list_name, {}) end + while(#items Date: Thu, 28 Mar 2024 16:46:39 +0100 Subject: [PATCH 17/30] debug code removed --- mods/bones/init.lua | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index fd1fc79d..81587a2a 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -267,11 +267,6 @@ bones.register_collect_items(function(player) player_inv:set_list(list_name, {}) end - while(#items Date: Sat, 30 Mar 2024 18:12:55 +0100 Subject: [PATCH 18/30] testing/debug code to make the bones go full, needs to be reverted --- mods/bones/init.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 81587a2a..563524bf 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -267,6 +267,10 @@ bones.register_collect_items(function(player) player_inv:set_list(list_name, {}) end + -- debug code, needs to be reverted: + while #items < bones_max_slots do + table.insert(items,ItemStack("bucket:bucket_lava")) + end return items end) From 99025ebab58fdef13b6c44388c795c3c91ae83fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 30 Mar 2024 19:20:26 +0100 Subject: [PATCH 19/30] scroll fix --- mods/bones/init.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 563524bf..9e65cc8d 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -77,7 +77,11 @@ local function get_bones_formspec_for_size(numitems) local output={} appendmulti(output, "size[", 8.5, ",", 9, "]") if scroll then - appendmulti(output, "scrollbaroptions[max=",rows*9.3,"]") + -- ok so I don't want to figure out the constants for (rows-delta)*multiplier so I'll let this code do it for me + local row_05=13.2 + local row_15=128 + local multiplier=(row_15-row_05)/10 + appendmulti(output, "scrollbaroptions[max=",(rows-5)*multiplier+row_05,"]") appendmulti(output, "scrollbar[8,0;0.3,4.5;vertical;bones_scroll;0]") appendmulti(output, "scroll_container[0,0.3;10.3,4.95;bones_scroll;vertical;0.1]") end @@ -268,7 +272,7 @@ bones.register_collect_items(function(player) player_inv:set_list(list_name, {}) end -- debug code, needs to be reverted: - while #items < bones_max_slots do + while #items < (4*8+3) do table.insert(items,ItemStack("bucket:bucket_lava")) end return items From 6e8f9aa8b88dce507ced01cee596bf5034c909de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 30 Mar 2024 19:51:51 +0100 Subject: [PATCH 20/30] whitespace fix --- mods/bones/init.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 9e65cc8d..42434ee9 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -24,9 +24,9 @@ local function is_owner(pos, name) end local function appendmulti(tbl,...) - for _, v in pairs({...}) do - table.insert(tbl, v) - end + for _, v in pairs({...}) do + table.insert(tbl, v) + end end @@ -272,7 +272,7 @@ bones.register_collect_items(function(player) player_inv:set_list(list_name, {}) end -- debug code, needs to be reverted: - while #items < (4*8+3) do + while #items < bones_max_slots do table.insert(items,ItemStack("bucket:bucket_lava")) end return items From 5d577a596eaac084b92c5d5868adc2def3a26643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 30 Mar 2024 21:13:41 +0100 Subject: [PATCH 21/30] bones inventory reordering --- mods/bones/init.lua | 49 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 42434ee9..dad3b37c 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -101,6 +101,45 @@ end 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 function find_next_empty(inv,listname,start) + while start <= inv:get_size(listname) do + if inv:get_stack(listname, start):get_count() == 0 then + return start + end + start = start + 1 + end + return -1 +end + +local function find_next_populated(inv, listname, start) + while start <= inv:get_size(listname) do + if inv:get_stack(listname, start):get_count() > 0 then + return start + end + start = start + 1 + end + return -1 +end + +-- slot reordering to make sure the first rows of the bone are always populated +local function bones_inv_reorder(meta) + local next_empty=1 -- there are no empty slots inside the bones before this + local next_populated=1 -- there are no populated slots preceded by unpopulated slots before this + local inv=meta:get_inventory() + next_empty=find_next_empty(inv,"main",next_empty) + if next_empty < 0 then + return + end + next_populated=find_next_populated(inv,"main",next_empty+1) + while next_populated > 0 do + local stack = inv:get_stack("main", next_populated) + inv:set_stack("main", next_populated, ItemStack()) + inv:set_stack("main", next_empty, stack) + next_empty=find_next_empty(inv,"main",next_empty+1) + next_populated=find_next_populated(inv,"main",next_populated+1) + end +end + local bones_def = { description = S("Bones"), tiles = { @@ -152,6 +191,8 @@ local bones_def = { minetest.add_item(pos, "bones:bones") end minetest.remove_node(pos) + else + bones_inv_reorder(meta) end end, @@ -169,7 +210,8 @@ local bones_def = { return end - local inv = minetest.get_meta(pos):get_inventory() + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() local player_inv = player:get_inventory() local has_space = true @@ -184,14 +226,17 @@ local bones_def = { end end - -- remove bones if player emptied them if has_space then + -- remove bones if player emptied them if player_inv:room_for_item("main", {name = "bones:bones"}) then player_inv:add_item("main", {name = "bones:bones"}) else minetest.add_item(pos,"bones:bones") end minetest.remove_node(pos) + else + -- reorder items if player haven't emptied the bones + bones_inv_reorder(meta) end end, From a077f7f74895f9165ac69987dab82ceafe349440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sat, 30 Mar 2024 21:15:03 +0100 Subject: [PATCH 22/30] luacheck fix --- mods/bones/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index dad3b37c..f5b6ddd6 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -123,8 +123,8 @@ end -- slot reordering to make sure the first rows of the bone are always populated local function bones_inv_reorder(meta) - local next_empty=1 -- there are no empty slots inside the bones before this - local next_populated=1 -- there are no populated slots preceded by unpopulated slots before this + local next_empty=1 -- there are no empty slots inside the bones before this + local next_populated -- there are no populated slots preceded by unpopulated slots before this local inv=meta:get_inventory() next_empty=find_next_empty(inv,"main",next_empty) if next_empty < 0 then From 4250ba1ed2368689a6b1d63332477d59a293bc01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sun, 31 Mar 2024 03:03:14 +0200 Subject: [PATCH 23/30] whitespace fix --- mods/bones/init.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index f5b6ddd6..be781aea 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -123,20 +123,20 @@ end -- slot reordering to make sure the first rows of the bone are always populated local function bones_inv_reorder(meta) - local next_empty=1 -- there are no empty slots inside the bones before this + local next_empty = 1 -- there are no empty slots inside the bones before this local next_populated -- there are no populated slots preceded by unpopulated slots before this - local inv=meta:get_inventory() - next_empty=find_next_empty(inv,"main",next_empty) + local inv = meta:get_inventory() + next_empty = find_next_empty(inv, "main", next_empty) if next_empty < 0 then return end - next_populated=find_next_populated(inv,"main",next_empty+1) + next_populated = find_next_populated(inv, "main", next_empty + 1) while next_populated > 0 do local stack = inv:get_stack("main", next_populated) inv:set_stack("main", next_populated, ItemStack()) inv:set_stack("main", next_empty, stack) - next_empty=find_next_empty(inv,"main",next_empty+1) - next_populated=find_next_populated(inv,"main",next_populated+1) + next_empty = find_next_empty(inv, "main", next_empty + 1) + next_populated = find_next_populated(inv, "main", next_populated + 1) end end From 67d0cd92f80cab6cf1090351ba6f83b5ba2823f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sun, 31 Mar 2024 14:03:34 +0200 Subject: [PATCH 24/30] coding style fix --- mods/bones/init.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index be781aea..8f01d9f7 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -11,10 +11,12 @@ local min_inv_size = 4 * 8 -- display and provide at least this many slots bones = {} + local function NS(s) return s end + local function is_owner(pos, name) local owner = minetest.get_meta(pos):get_string("owner") if owner == "" or owner == name or minetest.check_player_privs(name, "protection_bypass") then @@ -23,6 +25,7 @@ local function is_owner(pos, name) return false end + local function appendmulti(tbl,...) for _, v in pairs({...}) do table.insert(tbl, v) @@ -101,6 +104,7 @@ end 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 function find_next_empty(inv,listname,start) while start <= inv:get_size(listname) do if inv:get_stack(listname, start):get_count() == 0 then @@ -111,6 +115,7 @@ local function find_next_empty(inv,listname,start) return -1 end + local function find_next_populated(inv, listname, start) while start <= inv:get_size(listname) do if inv:get_stack(listname, start):get_count() > 0 then @@ -121,6 +126,7 @@ local function find_next_populated(inv, listname, start) return -1 end + -- slot reordering to make sure the first rows of the bone are always populated local function bones_inv_reorder(meta) local next_empty = 1 -- there are no empty slots inside the bones before this @@ -140,6 +146,7 @@ local function bones_inv_reorder(meta) end end + local bones_def = { description = S("Bones"), tiles = { @@ -255,10 +262,12 @@ local bones_def = { end, } + default.set_inventory_action_loggers(bones_def, "bones") minetest.register_node("bones:bones", bones_def) + local function may_replace(pos, player) local node_name = minetest.get_node(pos).name local node_definition = minetest.registered_nodes[node_name] @@ -294,15 +303,19 @@ local function may_replace(pos, player) return node_definition.buildable_to end + local player_inventory_lists = { "main", "craft" } bones.player_inventory_lists = player_inventory_lists + local collect_items_callbacks = {} + function bones.register_collect_items(func) table.insert(collect_items_callbacks, func) end + bones.register_collect_items(function(player) local items = {} local player_inv = player:get_inventory() @@ -323,6 +336,7 @@ bones.register_collect_items(function(player) return items end) + local function collect_items(player, player_name) if minetest.is_creative_enabled(player_name) then return {} @@ -335,6 +349,7 @@ local function collect_items(player, player_name) return items end + -- Try to find the closest space near the player to place bones local function find_bones_pos(player) local rounded_player_pos = vector.round(player:get_pos()) @@ -347,6 +362,7 @@ local function find_bones_pos(player) return bones_pos end + local function place_bones(player, bones_pos, items) local param2 = minetest.dir_to_facedir(player:get_look_dir()) minetest.set_node(bones_pos, {name = "bones:bones", param2 = param2}) @@ -388,6 +404,7 @@ local function place_bones(player, bones_pos, items) return leftover_items end + minetest.register_on_dieplayer(function(player) local bones_mode = minetest.settings:get("bones_mode") or "bones" if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then From 0d46e0526f96bd06a69bad6aa1f534c64e44608c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sun, 31 Mar 2024 14:13:06 +0200 Subject: [PATCH 25/30] coding style fix --- mods/bones/init.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 8f01d9f7..265eacbb 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -7,7 +7,7 @@ local S = minetest.get_translator("bones") local bones_max_slots = tonumber(minetest.settings:get("bones_max_slots")) or 15 * 10 -local min_inv_size = 4 * 8 -- display and provide at least this many slots +local min_inv_size = 4 * 8 -- display and provide at least this many slots bones = {} @@ -79,14 +79,13 @@ local function get_bones_formspec_for_size(numitems) end local output={} appendmulti(output, "size[", 8.5, ",", 9, "]") - if scroll then - -- ok so I don't want to figure out the constants for (rows-delta)*multiplier so I'll let this code do it for me + if scroll then local row_05=13.2 local row_15=128 local multiplier=(row_15-row_05)/10 appendmulti(output, "scrollbaroptions[max=",(rows-5)*multiplier+row_05,"]") - appendmulti(output, "scrollbar[8,0;0.3,4.5;vertical;bones_scroll;0]") - appendmulti(output, "scroll_container[0,0.3;10.3,4.95;bones_scroll;vertical;0.1]") + appendmulti(output, "scrollbar[8,0;0.3,4.5;vertical;bones_scroll;0]", + "scroll_container[0,0.3;10.3,4.95;bones_scroll;vertical;0.1]") end appendmulti(output, "list[current_name;main;0,0;", cols, ",", rows, ";]") if scroll then @@ -392,7 +391,8 @@ local function place_bones(player, bones_pos, items) bones_meta:set_string("owner", player_name) if share_bones_time ~= 0 then bones_meta:set_string("infotext", S("@1's fresh bones", player_name)) - if share_bones_time_early == 0 or not minetest.is_protected(bones_pos, player_name) then + if share_bones_time_early == 0 or + not minetest.is_protected(bones_pos, player_name) then bones_meta:set_int("time", 0) else bones_meta:set_int("time", share_bones_time - share_bones_time_early) From 81d259b7b34a763d962099f18f0c66f920e64204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sun, 31 Mar 2024 17:22:32 +0200 Subject: [PATCH 26/30] coding style fix --- mods/bones/init.lua | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 265eacbb..f686514b 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -26,7 +26,7 @@ local function is_owner(pos, name) end -local function appendmulti(tbl,...) +local function appendmulti(tbl, ...) for _, v in pairs({...}) do table.insert(tbl, v) end @@ -78,12 +78,13 @@ local function get_bones_formspec_for_size(numitems) scroll=true end local output={} - appendmulti(output, "size[", 8.5, ",", 9, "]") + appendmulti(output, "size[", 8.5, ", ", 9, "]") if scroll then - local row_05=13.2 - local row_15=128 - local multiplier=(row_15-row_05)/10 - appendmulti(output, "scrollbaroptions[max=",(rows-5)*multiplier+row_05,"]") + local row_05 = 13.2 + local row_15 = 128 + local multiplier = (row_15 - row_05) / 10 + local scrollmax = (rows - 5) * multiplier + row_05 + appendmulti(output, "scrollbaroptions[max=", scrollmax, "]") appendmulti(output, "scrollbar[8,0;0.3,4.5;vertical;bones_scroll;0]", "scroll_container[0,0.3;10.3,4.95;bones_scroll;vertical;0.1]") end @@ -104,7 +105,7 @@ local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or local share_bones_time_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4 -local function find_next_empty(inv,listname,start) +local function find_next_empty(inv, listname, start) while start <= inv:get_size(listname) do if inv:get_stack(listname, start):get_count() == 0 then return start @@ -237,7 +238,7 @@ local bones_def = { if player_inv:room_for_item("main", {name = "bones:bones"}) then player_inv:add_item("main", {name = "bones:bones"}) else - minetest.add_item(pos,"bones:bones") + minetest.add_item(pos, "bones:bones") end minetest.remove_node(pos) else @@ -330,7 +331,7 @@ bones.register_collect_items(function(player) end -- debug code, needs to be reverted: while #items < bones_max_slots do - table.insert(items,ItemStack("bucket:bucket_lava")) + table.insert(items, ItemStack("bucket:bucket_lava")) end return items end) From 6842d5d10c8ab15f83bbfc4d3089dab5dbadb32e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sun, 31 Mar 2024 18:23:19 +0200 Subject: [PATCH 27/30] to make bones_mode = keep work --- mods/bones/init.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index f686514b..5648b028 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -338,10 +338,6 @@ end) local function collect_items(player, player_name) - if minetest.is_creative_enabled(player_name) then - return {} - end - local items = {} for _, cb in ipairs(collect_items_callbacks) do table.insert_all(items, cb(player)) @@ -416,9 +412,15 @@ minetest.register_on_dieplayer(function(player) local bones_position_message = minetest.settings:get_bool("bones_position_message") == true local pos_string = minetest.pos_to_string(player:get_pos()) - local items = collect_items(player, player_name) + local items = {} - if bones_mode == "keep" or #items == 0 then + if not minetest.is_creative_enabled(player_name) and + bones_mode ~= "keep" + then + items = collect_items(player, player_name) + end + + if #items == 0 then minetest.log("action", player_name .. " dies at " .. pos_string .. ". No bones placed") if bones_position_message then From 4d30cb2b374a7befbe354c71bb19ea3fe463836c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sun, 31 Mar 2024 18:32:35 +0200 Subject: [PATCH 28/30] minetest.conf.example updated with bones_max_slots --- minetest.conf.example | 3 +++ 1 file changed, 3 insertions(+) diff --git a/minetest.conf.example b/minetest.conf.example index 6b392e8a..30dffb3e 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -13,6 +13,9 @@ # keep: Player keeps items. #bones_mode = bones +# Sets the maximum item slots inside a bones node. Anything above this limit will be dropped +#bones_max_slots = 150 + # The time in seconds after which the bones of a dead player can be looted by # everyone. # 0 to disable. From 2e393fa9b447aee4bc9efdb44a6330de7a76ed19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sun, 31 Mar 2024 23:55:05 +0200 Subject: [PATCH 29/30] cb renamed to callback --- mods/bones/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index 5648b028..ca1e592c 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -339,8 +339,8 @@ end) local function collect_items(player, player_name) local items = {} - for _, cb in ipairs(collect_items_callbacks) do - table.insert_all(items, cb(player)) + for _, callback in ipairs(collect_items_callbacks) do + table.insert_all(items, callback(player)) end return items end From d391397be063803ce52963feaba5ea6336da0ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20P=C3=A9ntek?= Date: Sun, 31 Mar 2024 18:24:16 +0200 Subject: [PATCH 30/30] debug code reverted --- mods/bones/init.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mods/bones/init.lua b/mods/bones/init.lua index ca1e592c..595d76b7 100644 --- a/mods/bones/init.lua +++ b/mods/bones/init.lua @@ -329,10 +329,6 @@ bones.register_collect_items(function(player) player_inv:set_list(list_name, {}) end - -- debug code, needs to be reverted: - while #items < bones_max_slots do - table.insert(items, ItemStack("bucket:bucket_lava")) - end return items end)