55
66-- Load support for MT game translation.
77local S = minetest .get_translator (" bones" )
8-
9- 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+ }
1024
1125local function is_owner (pos , name )
1226 local owner = minetest .get_meta (pos ):get_string (" owner" )
@@ -17,10 +31,10 @@ local function is_owner(pos, name)
1731end
1832
1933local bones_formspec =
20- " size[8,9 ]" ..
21- " list[current_name;main;0,0.3;8,4 ;]" ..
22- " list[current_player;main;0,4 .85;8,1;]" ..
23- " list[current_player;main;0,6 .08;8,3;8]" ..
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]" ..
2438 " listring[current_name;main]" ..
2539 " listring[current_player;main]" ..
2640 default .get_hotbar_bg (0 ,4.85 )
@@ -190,15 +204,68 @@ local function is_all_empty(player_inv)
190204 return true
191205end
192206
207+ -- 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
210+ end
211+
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 )
215+ -- 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
218+ 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
221+ else
222+ air = minetest .find_node_near (bones .private .current_dead_player .bones_pos , 1 , {" air" })
223+ end
224+
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 )
232+ else
233+ bones .private .current_dead_player .bones_mode = " drop"
234+ bones .private .current_dead_player .bones_pos = nil
235+ end
236+ end
237+
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 )
240+ else
241+ drop (bones .private .current_dead_player .player_pos , stk )
242+ bones .private .current_dead_player .dropped = true
243+ end
244+ end
245+
246+ local function player_dies_transfer_inventory (player )
247+ local player_inv = player :get_inventory ()
248+ for _ , list_name in ipairs (player_inventory_lists ) do
249+ for i = 1 , player_inv :get_size (list_name ) do
250+ local stack = player_inv :get_stack (list_name , i )
251+ bones .public .transfer_stack_to_bones (stack )
252+ end
253+ player_inv :set_list (list_name , {})
254+ end
255+ end
256+
257+ bones .public .register_transfer_inventory_to_bones_on_player_death (player_dies_transfer_inventory )
258+
193259minetest .register_on_dieplayer (function (player )
260+ local pos = vector .round (player :get_pos ())
194261 local bones_mode = minetest .settings :get (" bones_mode" ) or " bones"
195262 if bones_mode ~= " bones" and bones_mode ~= " drop" and bones_mode ~= " keep" then
196263 bones_mode = " bones"
197264 end
265+ 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 }
198267
199268 local bones_position_message = minetest .settings :get_bool (" bones_position_message" ) == true
200- local player_name = player :get_player_name ()
201- local pos = vector .round (player :get_pos ())
202269 local pos_string = minetest .pos_to_string (pos )
203270
204271 -- return if keep inventory set or in creative mode
@@ -211,67 +278,43 @@ minetest.register_on_dieplayer(function(player)
211278 return
212279 end
213280
214- local player_inv = player :get_inventory ()
215- if is_all_empty (player_inv ) then
216- minetest .log (" action" , player_name .. " dies at " .. pos_string ..
217- " . No bones placed" )
218- if bones_position_message then
219- minetest .chat_send_player (player_name , S (" @1 died at @2." , player_name , pos_string ))
220- end
221- return
281+ for i = 0 ,# bones .private .dead_player_callbacks do
282+ local fun = bones .private .dead_player_callbacks [i ]
283+ fun (player )
222284 end
223285
224- -- check if it's possible to place bones, if not find space near player
225- if bones_mode == " bones" and not may_replace (pos , player ) then
226- local air = minetest .find_node_near (pos , 1 , {" air" })
227- if air and not minetest .is_protected (air , player_name ) then
228- pos = air
229- else
230- bones_mode = " drop"
231- end
232- end
286+ local bones_conclusion = " "
287+ local public_conclusion = " "
233288
234- if bones_mode == " drop" then
235- for _ , list_name in ipairs (player_inventory_lists ) do
236- for i = 1 , player_inv :get_size (list_name ) do
237- drop (pos , player_inv :get_stack (list_name , i ))
238- end
239- player_inv :set_list (list_name , {})
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
292+ bones_conclusion = " No bones placed"
293+ else
294+ bones_conclusion = " Inventory dropped"
295+ public_conclusion = " dropped their inventory"
240296 end
241- drop (pos , ItemStack (" bones:bones" ))
242- minetest .log (" action" , player_name .. " dies at " .. pos_string ..
243- " . Inventory dropped" )
244- if bones_position_message then
245- minetest .chat_send_player (player_name , S (" @1 died at @2, and dropped their inventory." , player_name , pos_string ))
297+ else
298+ if (not (bones .private .current_dead_player .dropped ))then
299+ bones_conclusion = " Bones placed"
300+ public_conclusion = " bones were placed"
301+ else
302+ bones_conclusion = " Inventory partially dropped"
303+ public_conclusion = " partially dropped their inventory"
246304 end
247- return
248305 end
249306
250- local param2 = minetest .dir_to_facedir (player :get_look_dir ())
251- minetest .set_node (pos , {name = " bones:bones" , param2 = param2 })
252-
253307 minetest .log (" action" , player_name .. " dies at " .. pos_string ..
254- " . Bones placed" )
255- if bones_position_message then
256- minetest .chat_send_player (player_name , S (" @1 died at @2, and bones were placed." , player_name , pos_string ))
257- end
308+ " . " .. bones_conclusion )
258309
259- local meta = minetest .get_meta (pos )
260- local inv = meta :get_inventory ()
261- inv :set_size (" main" , 8 * 4 )
262-
263- for _ , list_name in ipairs (player_inventory_lists ) do
264- for i = 1 , player_inv :get_size (list_name ) do
265- local stack = player_inv :get_stack (list_name , i )
266- if inv :room_for_item (" main" , stack ) then
267- inv :add_item (" main" , stack )
268- else -- no space left
269- drop (pos , stack )
270- end
310+ if bones_position_message then
311+ if (public_conclusion ~= " " )then
312+ public_conclusion = " , and " .. public_conclusion
271313 end
272- player_inv : set_list ( list_name , {} )
314+ minetest . chat_send_player ( player_name , S ( " @1 died at @2@3. " , player_name , pos_string , public_conclusion ) )
273315 end
274316
317+ local meta = minetest .get_meta (bones .private .current_dead_player .bones_pos )
275318 meta :set_string (" formspec" , bones_formspec )
276319 meta :set_string (" owner" , player_name )
277320
@@ -288,4 +331,5 @@ minetest.register_on_dieplayer(function(player)
288331 else
289332 meta :set_string (" infotext" , S (" @1's bones" , player_name ))
290333 end
334+ bones .private .current_dead_player = nil
291335end )
0 commit comments