55
66-- Load support for MT game translation.
77local S = minetest .get_translator (" bones" )
8- -- bones are supposed to hold up to 4*8+6+4*3*8+4+3*3 item slots:
9- -- 4*8 for the main inventory
10- -- 6 for the 3d_armor
11- -- (at most) 4*3*8 for 4 backpack worth of items (unified inventory)
12- -- 4 more for the actual backpacks
13- -- 3*3 more for the crafting grid
14- -- that adds up to 147, so 150 slots would be sufficient
15- local cols = 15
16- local rows = 10
17-
18- bones = {
19- private = {
20- dead_player_callbacks = {}
21- },
22- public = {}
23- }
8+
9+ local theoretical_max_slots = minetest .settings :get (" bones_max_slots" ) or ( 15 * 10 )
10+ local dead_player_callbacks = {}
11+
12+ bones = {}
13+
2414
2515local function is_owner (pos , name )
2616 local owner = minetest .get_meta (pos ):get_string (" owner" )
@@ -30,6 +20,7 @@ local function is_owner(pos, name)
3020 return false
3121end
3222
23+
3324local function drop (pos , itemstack )
3425 local obj = minetest .add_item (pos , itemstack :take_item (itemstack :get_count ()))
3526 if obj then
@@ -41,6 +32,7 @@ local function drop(pos, itemstack)
4132 end
4233end
4334
35+
4436local function drop_contents (pos )
4537 local inv = minetest .get_meta (pos ):get_inventory ()
4638
@@ -51,14 +43,32 @@ local function drop_contents(pos)
5143 minetest .remove_node (pos )
5244end
5345
54- local bones_formspec =
55- " size[" .. cols .. " ," .. (rows + 5 ).. " ]" ..
56- " list[current_name;main;0,0.3;" .. cols .. " ," .. rows .. " ;]" ..
57- " list[current_player;main;" .. ((cols - 8 )/ 2 ).. " ," .. rows .. " .85;8,1;]" ..
58- " list[current_player;main;" .. ((cols - 8 )/ 2 ).. " ," .. (rows + 2 ).. " .08;8,3;8]" ..
59- " listring[current_name;main]" ..
60- " listring[current_player;main]" ..
61- default .get_hotbar_bg (0 ,4.85 )
46+
47+ local function get_bones_formspec_wh (cols ,rows )
48+ return
49+ " size[" .. cols .. " ," .. ( rows + 5 ) .. " ]" ..
50+ " list[current_name;main;0,0.3;" .. cols .. " ," .. rows .. " ;]" ..
51+ " list[current_player;main;" .. ( ( cols - 8 ) / 2 ) .. " ," .. rows .. " .85;8,1;]" ..
52+ " list[current_player;main;" .. ( ( cols - 8 ) / 2 ) .. " ," .. ( rows + 2 ) .. " .08;8,3;8]" ..
53+ " listring[current_name;main]" ..
54+ " listring[current_player;main]" ..
55+ default .get_hotbar_bg (0 ,4.85 )
56+ end
57+
58+
59+ local function get_bones_formspec_for_size (numitems )
60+ -- the absolute minimum is 4*8
61+ if numitems <= 4 * 8 then
62+ return get_bones_formspec_wh (8 , 4 )
63+ end
64+ -- if we're over 4*8, but below 4*15 we make it 4 rows and adjust the column count to make everything fit
65+ if numitems <= 4 * 15 then
66+ return get_bones_formspec_wh ( math.floor ( ( numitems + 3 ) / 4 ), 4 )
67+ end
68+ -- if we're over 4*15 we'll make 15 columns and adjust the row count to make everything fit
69+ return get_bones_formspec_wh (15 , math.floor ( ( numitems + 14 ) / 15 ) )
70+ end
71+
6272
6373local share_bones_time = tonumber (minetest .settings :get (" share_bones_time" )) or 1200
6474local share_bones_time_early = tonumber (minetest .settings :get (" share_bones_time_early" )) or share_bones_time / 4
@@ -214,66 +224,58 @@ end
214224local player_inventory_lists = { " main" , " craft" }
215225bones .player_inventory_lists = player_inventory_lists
216226
217- local function is_all_empty (player_inv )
218- for _ , list_name in ipairs (player_inventory_lists ) do
219- if not player_inv :is_empty (list_name ) then
220- return false
221- end
222- end
223- return true
224- end
225-
226227-- functions registered this way won't becalled if bones_mode is keep
227- function bones .public . register_transfer_inventory_to_bones_on_player_death (func )
228- bones . private . dead_player_callbacks [ # ( bones . private . dead_player_callbacks )] = func
228+ function bones .register_dead_player_inv_management (func )
229+ table.insert ( dead_player_callbacks , func )
229230end
230231
231- -- drop or put into bones based on config and free slots in the bones
232- -- supposed to be called from functions registered to bones.public.register_transfer_inventory_to_bones_on_player_death
233- function bones .public .transfer_stack_to_bones (stk )
232+ local function transfer_stack_to_bones (stk ,current_dead_player )
234233 -- check if it's possible to place bones, if not find space near player
235- if ( ( bones .private .current_dead_player .bones_mode == " bones" ) and ( bones .private .current_dead_player .bones_pos == nil ) ) then
236- bones .private .current_dead_player .bones_pos = bones .private .current_dead_player .player_pos
234+ if ( current_dead_player .bones_mode == " bones" ) and
235+ ( current_dead_player .bones_pos == nil ) then
236+ current_dead_player .bones_pos = current_dead_player .player_pos
237237 local air
238- if ( may_replace (bones . private . current_dead_player .bones_pos , bones . private . current_dead_player .player ) ) then
239- air = bones . private . current_dead_player .bones_pos
238+ if may_replace (current_dead_player .bones_pos , current_dead_player .player ) then
239+ air = current_dead_player .bones_pos
240240 else
241- air = minetest .find_node_near (bones . private . current_dead_player .bones_pos , 1 , {" air" })
241+ air = minetest .find_node_near (current_dead_player .bones_pos , 1 , {" air" })
242242 end
243243
244- if air and not minetest .is_protected (air , bones .private .current_dead_player .player_name ) then
245- bones .private .current_dead_player .bones_pos = air
246- local param2 = minetest .dir_to_facedir (bones .private .current_dead_player .player :get_look_dir ())
247- minetest .set_node (bones .private .current_dead_player .bones_pos , {name = " bones:bones" , param2 = param2 })
248- local meta = minetest .get_meta (bones .private .current_dead_player .bones_pos )
249- bones .private .current_dead_player .bones_inv = meta :get_inventory ()
250- bones .private .current_dead_player .bones_inv :set_size (" main" , cols * rows )
244+ if air and not minetest .is_protected (air , current_dead_player .player_name ) then
245+ current_dead_player .bones_pos = air
246+ local param2 = minetest .dir_to_facedir (current_dead_player .player :get_look_dir ())
247+ minetest .set_node (current_dead_player .bones_pos , {name = " bones:bones" , param2 = param2 })
248+ local meta = minetest .get_meta (current_dead_player .bones_pos )
249+ current_dead_player .bones_inv = meta :get_inventory ()
250+ -- make it so big that anything reasonable will for sure fit inside
251+ current_dead_player .bones_inv :set_size (" main" , theoretical_max_slots )
251252 else
252- bones . private . current_dead_player .bones_mode = " drop"
253- bones . private . current_dead_player .bones_pos = nil
253+ current_dead_player .bones_mode = " drop"
254+ current_dead_player .bones_pos = nil
254255 end
255256 end
256257
257- if ( ( bones .private .current_dead_player .bones_mode == " bones" ) and ( bones .private .current_dead_player .bones_inv :room_for_item (" main" , stk ) ) ) then
258- bones .private .current_dead_player .bones_inv :add_item (" main" , stk )
258+ if ( current_dead_player .bones_mode == " bones" ) and
259+ ( current_dead_player .bones_inv :room_for_item (" main" , stk ) ) then
260+ current_dead_player .bones_inv :add_item (" main" , stk )
259261 else
260- drop (bones . private . current_dead_player .player_pos , stk )
261- bones . private . current_dead_player .dropped = true
262+ drop (current_dead_player .player_pos , stk )
263+ current_dead_player .dropped = true
262264 end
263265end
264266
265- local function player_dies_transfer_inventory (player )
267+ local function player_dies_transfer_inventory (player , transfer_stack )
266268 local player_inv = player :get_inventory ()
267269 for _ , list_name in ipairs (player_inventory_lists ) do
268270 for i = 1 , player_inv :get_size (list_name ) do
269271 local stack = player_inv :get_stack (list_name , i )
270- bones . public . transfer_stack_to_bones (stack )
272+ transfer_stack (stack )
271273 end
272274 player_inv :set_list (list_name , {})
273275 end
274276end
275277
276- bones .public . register_transfer_inventory_to_bones_on_player_death (player_dies_transfer_inventory )
278+ bones .register_dead_player_inv_management (player_dies_transfer_inventory )
277279
278280minetest .register_on_dieplayer (function (player )
279281 local pos = vector .round (player :get_pos ())
@@ -282,7 +284,8 @@ minetest.register_on_dieplayer(function(player)
282284 bones_mode = " bones"
283285 end
284286 local player_name = player :get_player_name ()
285- 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 }
287+ local current_dead_player = {player = player , player_name = player_name , bones_inv = nil , bones_pos = nil ,
288+ bones_mode = bones_mode , player_pos = pos , dropped = false }
286289
287290 local bones_position_message = minetest .settings :get_bool (" bones_position_message" ) == true
288291 local pos_string = minetest .pos_to_string (pos )
@@ -297,58 +300,73 @@ minetest.register_on_dieplayer(function(player)
297300 return
298301 end
299302
300- for i = 0 ,# bones .private .dead_player_callbacks do
301- local fun = bones .private .dead_player_callbacks [i ]
302- fun (player )
303+ local callback = function (stk )
304+ transfer_stack_to_bones (stk ,current_dead_player )
305+ end
306+
307+ for i = 1 ,# dead_player_callbacks do
308+ local fun = dead_player_callbacks [i ]
309+ fun (player ,callback )
303310 end
304311
305- local bones_conclusion = " "
306- local public_conclusion = " "
312+ local bones_conclusion
307313
308- if ( not ( bones . private . current_dead_player .bones_pos )) then
309- drop (bones . private . current_dead_player .player_pos , ItemStack (" bones:bones" ))
310- if ( not ( bones . private . current_dead_player .dropped )) then
314+ if not ( current_dead_player .bones_pos ) then
315+ drop (current_dead_player .player_pos , ItemStack (" bones:bones" ))
316+ if not ( current_dead_player .dropped ) then
311317 bones_conclusion = " No bones placed"
318+ if bones_position_message then
319+ minetest .chat_send_player (player_name , S (" @1 died at @2." , player_name , pos_string ))
320+ end
312321 else
313322 bones_conclusion = " Inventory dropped"
314- public_conclusion = " dropped their inventory"
323+ if bones_position_message then
324+ minetest .chat_send_player (player_name , S (" @1 died at @2, and dropped their inventory." , player_name , pos_string , public_conclusion ))
325+ end
315326 end
316327 else
317- if ( not ( bones . private . current_dead_player .dropped )) then
328+ if not ( current_dead_player .dropped ) then
318329 bones_conclusion = " Bones placed"
319- public_conclusion = " bones were placed"
330+ if bones_position_message then
331+ minetest .chat_send_player (player_name , S (" @1 died at @2, and bones were placed." , player_name , pos_string , public_conclusion ))
332+ end
320333 else
321334 bones_conclusion = " Inventory partially dropped"
322- public_conclusion = " partially dropped their inventory"
335+ if bones_position_message then
336+ minetest .chat_send_player (player_name , S (" @1 died at @2, and partially dropped their inventory." , player_name , pos_string , public_conclusion ))
337+ end
323338 end
324339 end
325340
326341 minetest .log (" action" , player_name .. " dies at " .. pos_string ..
327342 " . " .. bones_conclusion )
328343
329- if bones_position_message then
330- if (public_conclusion ~= " " )then
331- public_conclusion = " , and " .. public_conclusion
344+ local inv = current_dead_player .bones_inv
345+ local inv_size = theoretical_max_slots
346+ if inv then
347+ for i = 1 , theoretical_max_slots do
348+ local stack = inv :get_stack (" main" , i )
349+ if stack :get_count () == 0 then
350+ inv_size = i - 1
351+ break
352+ end
332353 end
333- minetest .chat_send_player (player_name , S (" @1 died at @2@3." , player_name , pos_string , public_conclusion ))
334- end
354+ local meta = minetest .get_meta (current_dead_player .bones_pos )
355+ meta :set_string (" formspec" , get_bones_formspec_for_size (inv_size ))
356+ meta :set_string (" owner" , player_name )
335357
336- local meta = minetest .get_meta (bones .private .current_dead_player .bones_pos )
337- meta :set_string (" formspec" , bones_formspec )
338- meta :set_string (" owner" , player_name )
358+ if share_bones_time ~= 0 then
359+ meta :set_string (" infotext" , S (" @1's fresh bones" , player_name ))
339360
340- if share_bones_time ~= 0 then
341- meta :set_string (" infotext" , S (" @1's fresh bones" , player_name ))
361+ if share_bones_time_early == 0 or not minetest .is_protected (pos , player_name ) then
362+ meta :set_int (" time" , 0 )
363+ else
364+ meta :set_int (" time" , (share_bones_time - share_bones_time_early ))
365+ end
342366
343- if share_bones_time_early == 0 or not minetest .is_protected (pos , player_name ) then
344- meta :set_int (" time" , 0 )
367+ minetest .get_node_timer (pos ):start (10 )
345368 else
346- meta :set_int ( " time " , ( share_bones_time - share_bones_time_early ))
369+ meta :set_string ( " infotext " , S ( " @1's bones " , player_name ))
347370 end
348-
349- minetest .get_node_timer (pos ):start (10 )
350- else
351- meta :set_string (" infotext" , S (" @1's bones" , player_name ))
352371 end
353- bones .private .current_dead_player = nil
354372end )
0 commit comments