From d47201f8136a0fe588143a112ba2aa1c713620b1 Mon Sep 17 00:00:00 2001
From: SmallJoker <st.rentsch@hotmail.com>
Date: Tue, 15 Apr 2014 17:13:46 +0200
Subject: [PATCH] Add punch to pickup, drop instead of delete

These changes allow players to punch up old bones or their own.
If there is no area for bones, drop the items instead of delete.
Notify the player where he died, so he can find them again.
---
 mods/bones/init.lua | 58 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 49 insertions(+), 9 deletions(-)

diff --git a/mods/bones/init.lua b/mods/bones/init.lua
index 30ab06c..78121f7 100644
--- a/mods/bones/init.lua
+++ b/mods/bones/init.lua
@@ -56,6 +56,32 @@ minetest.register_node("bones:bones", {
 		end
 	end,
 	
+	on_punch = function(pos, node, player)
+		if(not is_owner(pos, player:get_player_name())) then
+			return
+		end
+		
+		local inv = minetest.get_meta(pos):get_inventory()
+		local player_inv = player:get_inventory()
+		local has_space = true
+		
+		for i=1,inv:get_size("main") do
+			local stk = inv:get_stack("main", i)
+			if player_inv:room_for_item("main", stk) then
+				inv:set_stack("main", i, nil)
+				player_inv:add_item("main", stk)
+			else
+				has_space = false
+				break
+			end
+		end
+		
+		-- remove bones if player emptied them
+		if has_space then
+			minetest.remove_node(pos)
+		end
+	end,
+	
 	on_timer = function(pos, elapsed)
 		local meta = minetest.get_meta(pos)
 		local time = meta:get_int("time")+elapsed
@@ -91,16 +117,25 @@ minetest.register_on_dieplayer(function(player)
 	pos.y = math.floor(pos.y+0.5)
 	pos.z = math.floor(pos.z+0.5)
 	local param2 = minetest.dir_to_facedir(player:get_look_dir())
+	local player_name = player:get_player_name()
+	local player_inv = player:get_inventory()
+	
+	minetest.chat_send_player(player_name, "You died at "..minetest.pos_to_string(pos))
 	
 	local nn = minetest.get_node(pos).name
 	if minetest.registered_nodes[nn].can_dig and
 		not minetest.registered_nodes[nn].can_dig(pos, player) then
+
+		-- drop items instead of delete
 		for i=1,player_inv:get_size("main") do
-			player_inv:set_stack("main", i, nil)
+			minetest.add_item(pos, player_inv:get_stack("main", i))
 		end
 		for i=1,player_inv:get_size("craft") do
-			player_inv:set_stack("craft", i, nil)
+			minetest.add_item(pos, player_inv:get_stack("craft", i))
 		end
+		-- empty lists main and craft
+		player_inv:set_list("main", {})
+		player_inv:set_list("craft", {})
 		return
 	end
 	
@@ -110,21 +145,26 @@ minetest.register_on_dieplayer(function(player)
 	local meta = minetest.get_meta(pos)
 	local inv = meta:get_inventory()
 	inv:set_size("main", 8*4)
-	
-	local empty_list = inv:get_list("main")
 	inv:set_list("main", player_inv:get_list("main"))
-	player_inv:set_list("main", empty_list)
 	
 	for i=1,player_inv:get_size("craft") do
-		inv:add_item("main", player_inv:get_stack("craft", i))
-		player_inv:set_stack("craft", i, nil)
+		local stack = player_inv:get_stack("craft", i)
+		if inv:room_for_item("main", stack) then
+			inv:add_item("main", stack)
+		else
+			--drop if no space left
+			minetest.add_item(pos, stack)
+		end
 	end
 	
+	player_inv:set_list("main", {})
+	player_inv:set_list("craft", {})
+	
 	meta:set_string("formspec", "size[8,9;]"..
 			"list[current_name;main;0,0;8,4;]"..
 			"list[current_player;main;0,5;8,4;]")
-	meta:set_string("infotext", player:get_player_name().."'s fresh bones")
-	meta:set_string("owner", player:get_player_name())
+	meta:set_string("infotext", player_name.."'s fresh bones")
+	meta:set_string("owner", player_name)
 	meta:set_int("time", 0)
 	
 	local timer  = minetest.get_node_timer(pos)