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 = {}
2413
2514local function is_owner (pos , name )
2615 local owner = minetest .get_meta (pos ):get_string (" owner" )
@@ -30,14 +19,29 @@ local function is_owner(pos, name)
3019 return false
3120end
3221
33- local bones_formspec =
34- " size[" .. cols .. " ," .. (rows + 5 ).. " ]" ..
35- " list[current_name;main;0,0.3;" .. cols .. " ," .. rows .. " ;]" ..
36- " list[current_player;main;" .. ((cols - 8 )/ 2 ).. " ," .. rows .. " .85;8,1;]" ..
37- " list[current_player;main;" .. ((cols - 8 )/ 2 ).. " ," .. (rows + 2 ).. " .08;8,3;8]" ..
38- " listring[current_name;main]" ..
39- " listring[current_player;main]" ..
40- default .get_hotbar_bg (0 ,4.85 )
22+ local function get_bones_formspec_wh (cols ,rows )
23+ return
24+ " size[" .. cols .. " ," .. ( rows + 5 ) .. " ]" ..
25+ " list[current_name;main;0,0.3;" .. cols .. " ," .. rows .. " ;]" ..
26+ " list[current_player;main;" .. ( ( cols - 8 ) / 2 ) .. " ," .. rows .. " .85;8,1;]" ..
27+ " list[current_player;main;" .. ( ( cols - 8 ) / 2 ) .. " ," .. ( rows + 2 ) .. " .08;8,3;8]" ..
28+ " listring[current_name;main]" ..
29+ " listring[current_player;main]" ..
30+ default .get_hotbar_bg (0 ,4.85 )
31+ end
32+
33+ local function get_bones_formspec_for_size (numitems )
34+ -- the absolute minimum is 4*8
35+ if numitems <= 4 * 8 then
36+ return get_bones_formspec_wh (8 , 4 )
37+ end
38+ -- if we're over 4*8, but below 4*15 we make it 4 rows and adjust the column count to make everything fit
39+ if numitems <= 4 * 15 then
40+ return get_bones_formspec_wh ( math.floor ( ( numitems + 3 ) / 4 ), 4 )
41+ end
42+ -- if we're over 4*15 we'll make 15 columns and adjust the row count to make everything fit
43+ return get_bones_formspec_wh (15 , math.floor ( ( numitems + 14 ) / 15 ) )
44+ end
4145
4246local share_bones_time = tonumber (minetest .settings :get (" share_bones_time" )) or 1200
4347local share_bones_time_early = tonumber (minetest .settings :get (" share_bones_time_early" )) or share_bones_time / 4
@@ -195,66 +199,58 @@ end
195199local player_inventory_lists = { " main" , " craft" }
196200bones .player_inventory_lists = player_inventory_lists
197201
198- local function is_all_empty (player_inv )
199- for _ , list_name in ipairs (player_inventory_lists ) do
200- if not player_inv :is_empty (list_name ) then
201- return false
202- end
203- end
204- return true
205- end
206-
207202-- functions registered this way won't becalled if bones_mode is keep
208- function bones .public . register_transfer_inventory_to_bones_on_player_death (func )
209- bones . private . dead_player_callbacks [ # ( bones . private . dead_player_callbacks )] = func
203+ function bones .register_dead_player_inv_management (func )
204+ table.insert ( dead_player_callbacks , func )
210205end
211206
212- -- drop or put into bones based on config and free slots in the bones
213- -- supposed to be called from functions registered to bones.public.register_transfer_inventory_to_bones_on_player_death
214- function bones .public .transfer_stack_to_bones (stk )
207+ local function transfer_stack_to_bones (stk ,current_dead_player )
215208 -- check if it's possible to place bones, if not find space near player
216- if ( ( bones .private .current_dead_player .bones_mode == " bones" ) and ( bones .private .current_dead_player .bones_pos == nil ) ) then
217- bones .private .current_dead_player .bones_pos = bones .private .current_dead_player .player_pos
209+ if ( current_dead_player .bones_mode == " bones" ) and
210+ ( current_dead_player .bones_pos == nil ) then
211+ current_dead_player .bones_pos = current_dead_player .player_pos
218212 local air
219- if ( may_replace (bones . private . current_dead_player .bones_pos , bones . private . current_dead_player .player ) ) then
220- air = bones . private . current_dead_player .bones_pos
213+ if may_replace (current_dead_player .bones_pos , current_dead_player .player ) then
214+ air = current_dead_player .bones_pos
221215 else
222- air = minetest .find_node_near (bones . private . current_dead_player .bones_pos , 1 , {" air" })
216+ air = minetest .find_node_near (current_dead_player .bones_pos , 1 , {" air" })
223217 end
224218
225- if air and not minetest .is_protected (air , bones .private .current_dead_player .player_name ) then
226- bones .private .current_dead_player .bones_pos = air
227- local param2 = minetest .dir_to_facedir (bones .private .current_dead_player .player :get_look_dir ())
228- minetest .set_node (bones .private .current_dead_player .bones_pos , {name = " bones:bones" , param2 = param2 })
229- local meta = minetest .get_meta (bones .private .current_dead_player .bones_pos )
230- bones .private .current_dead_player .bones_inv = meta :get_inventory ()
231- bones .private .current_dead_player .bones_inv :set_size (" main" , cols * rows )
219+ if air and not minetest .is_protected (air , current_dead_player .player_name ) then
220+ current_dead_player .bones_pos = air
221+ local param2 = minetest .dir_to_facedir (current_dead_player .player :get_look_dir ())
222+ minetest .set_node (current_dead_player .bones_pos , {name = " bones:bones" , param2 = param2 })
223+ local meta = minetest .get_meta (current_dead_player .bones_pos )
224+ current_dead_player .bones_inv = meta :get_inventory ()
225+ -- make it so big that anything reasonable will for sure fit inside
226+ current_dead_player .bones_inv :set_size (" main" , theoretical_max_slots )
232227 else
233- bones . private . current_dead_player .bones_mode = " drop"
234- bones . private . current_dead_player .bones_pos = nil
228+ current_dead_player .bones_mode = " drop"
229+ current_dead_player .bones_pos = nil
235230 end
236231 end
237232
238- if ( ( bones .private .current_dead_player .bones_mode == " bones" ) and ( bones .private .current_dead_player .bones_inv :room_for_item (" main" , stk ) ) ) then
239- bones .private .current_dead_player .bones_inv :add_item (" main" , stk )
233+ if ( current_dead_player .bones_mode == " bones" ) and
234+ ( current_dead_player .bones_inv :room_for_item (" main" , stk ) ) then
235+ current_dead_player .bones_inv :add_item (" main" , stk )
240236 else
241- drop (bones . private . current_dead_player .player_pos , stk )
242- bones . private . current_dead_player .dropped = true
237+ drop (current_dead_player .player_pos , stk )
238+ current_dead_player .dropped = true
243239 end
244240end
245241
246- local function player_dies_transfer_inventory (player )
242+ local function player_dies_transfer_inventory (player , transfer_stack )
247243 local player_inv = player :get_inventory ()
248244 for _ , list_name in ipairs (player_inventory_lists ) do
249245 for i = 1 , player_inv :get_size (list_name ) do
250246 local stack = player_inv :get_stack (list_name , i )
251- bones . public . transfer_stack_to_bones (stack )
247+ transfer_stack (stack )
252248 end
253249 player_inv :set_list (list_name , {})
254250 end
255251end
256252
257- bones .public . register_transfer_inventory_to_bones_on_player_death (player_dies_transfer_inventory )
253+ bones .register_dead_player_inv_management (player_dies_transfer_inventory )
258254
259255minetest .register_on_dieplayer (function (player )
260256 local pos = vector .round (player :get_pos ())
@@ -263,7 +259,8 @@ minetest.register_on_dieplayer(function(player)
263259 bones_mode = " bones"
264260 end
265261 local player_name = player :get_player_name ()
266- 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 }
262+ local current_dead_player = {player = player , player_name = player_name , bones_inv = nil , bones_pos = nil ,
263+ bones_mode = bones_mode , player_pos = pos , dropped = false }
267264
268265 local bones_position_message = minetest .settings :get_bool (" bones_position_message" ) == true
269266 local pos_string = minetest .pos_to_string (pos )
@@ -278,58 +275,73 @@ minetest.register_on_dieplayer(function(player)
278275 return
279276 end
280277
281- for i = 0 ,# bones .private .dead_player_callbacks do
282- local fun = bones .private .dead_player_callbacks [i ]
283- fun (player )
278+ local callback = function (stk )
279+ transfer_stack_to_bones (stk ,current_dead_player )
284280 end
285281
286- local bones_conclusion = " "
287- local public_conclusion = " "
282+ for i = 1 ,# dead_player_callbacks do
283+ local fun = dead_player_callbacks [i ]
284+ fun (player ,callback )
285+ end
286+
287+ local bones_conclusion
288288
289- if ( not ( bones . private . current_dead_player .bones_pos )) then
290- drop (bones . private . current_dead_player .player_pos , ItemStack (" bones:bones" ))
291- if ( not ( bones . private . current_dead_player .dropped )) then
289+ if not ( current_dead_player .bones_pos ) then
290+ drop (current_dead_player .player_pos , ItemStack (" bones:bones" ))
291+ if not ( current_dead_player .dropped ) then
292292 bones_conclusion = " No bones placed"
293+ if bones_position_message then
294+ minetest .chat_send_player (player_name , S (" @1 died at @2." , player_name , pos_string ))
295+ end
293296 else
294297 bones_conclusion = " Inventory dropped"
295- public_conclusion = " dropped their inventory"
298+ if bones_position_message then
299+ minetest .chat_send_player (player_name , S (" @1 died at @2, and dropped their inventory." , player_name , pos_string , public_conclusion ))
300+ end
296301 end
297302 else
298- if ( not ( bones . private . current_dead_player .dropped )) then
303+ if not ( current_dead_player .dropped ) then
299304 bones_conclusion = " Bones placed"
300- public_conclusion = " bones were placed"
305+ if bones_position_message then
306+ minetest .chat_send_player (player_name , S (" @1 died at @2, and bones were placed." , player_name , pos_string , public_conclusion ))
307+ end
301308 else
302309 bones_conclusion = " Inventory partially dropped"
303- public_conclusion = " partially dropped their inventory"
310+ if bones_position_message then
311+ minetest .chat_send_player (player_name , S (" @1 died at @2, and partially dropped their inventory." , player_name , pos_string , public_conclusion ))
312+ end
304313 end
305314 end
306315
307316 minetest .log (" action" , player_name .. " dies at " .. pos_string ..
308317 " . " .. bones_conclusion )
309318
310- if bones_position_message then
311- if (public_conclusion ~= " " )then
312- public_conclusion = " , and " .. public_conclusion
319+ local inv = current_dead_player .bones_inv
320+ local inv_size = theoretical_max_slots
321+ if inv then
322+ for i = 1 , theoretical_max_slots do
323+ local stack = inv :get_stack (" main" , i )
324+ if stack :get_count () == 0 then
325+ inv_size = i - 1
326+ break
327+ end
313328 end
314- minetest .chat_send_player (player_name , S (" @1 died at @2@3." , player_name , pos_string , public_conclusion ))
315- end
329+ local meta = minetest .get_meta (current_dead_player .bones_pos )
330+ meta :set_string (" formspec" , get_bones_formspec_for_size (inv_size ))
331+ meta :set_string (" owner" , player_name )
316332
317- local meta = minetest .get_meta (bones .private .current_dead_player .bones_pos )
318- meta :set_string (" formspec" , bones_formspec )
319- meta :set_string (" owner" , player_name )
333+ if share_bones_time ~= 0 then
334+ meta :set_string (" infotext" , S (" @1's fresh bones" , player_name ))
320335
321- if share_bones_time ~= 0 then
322- meta :set_string (" infotext" , S (" @1's fresh bones" , player_name ))
336+ if share_bones_time_early == 0 or not minetest .is_protected (pos , player_name ) then
337+ meta :set_int (" time" , 0 )
338+ else
339+ meta :set_int (" time" , (share_bones_time - share_bones_time_early ))
340+ end
323341
324- if share_bones_time_early == 0 or not minetest .is_protected (pos , player_name ) then
325- meta :set_int (" time" , 0 )
342+ minetest .get_node_timer (pos ):start (10 )
326343 else
327- meta :set_int ( " time " , ( share_bones_time - share_bones_time_early ))
344+ meta :set_string ( " infotext " , S ( " @1's bones " , player_name ))
328345 end
329-
330- minetest .get_node_timer (pos ):start (10 )
331- else
332- meta :set_string (" infotext" , S (" @1's bones" , player_name ))
333346 end
334- bones .private .current_dead_player = nil
335347end )
0 commit comments