Browse Source

Bones: Iterate player inventory lists dynamically (#1229)

Avoid hard-coded player inventory lists.
Expose `bones.player_inventory_lists` for mods to look up or change,
which player inventory lists are being dropped or placed into bones.
Tim 6 years ago
parent
commit
283636bfdb
2 changed files with 38 additions and 25 deletions
  1. 9 0
      game_api.txt
  2. 29 25
      mods/bones/init.lua

+ 9 - 0
game_api.txt

@@ -67,6 +67,15 @@ Beds API
 		}
 	}
 
+Bones API
+---------
+
+An ordered list of listnames (default: "main", "craft") of the player inventory,
+that will be placed into bones or dropped on player death can be looked up or changed
+in `bones.player_inventory_lists`.
+
+e.g. `table.insert(bones.player_inventory_lists, "backpack")`
+
 Creative API
 ------------
 

+ 29 - 25
mods/bones/init.lua

@@ -1,6 +1,8 @@
 -- Minetest 0.4 mod: bones
 -- See README.txt for licensing and other information.
 
+bones = {}
+
 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
@@ -165,6 +167,18 @@ local drop = function(pos, itemstack)
 	end
 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
+
 minetest.register_on_dieplayer(function(player)
 
 	local bones_mode = minetest.settings:get("bones_mode") or "bones"
@@ -179,8 +193,7 @@ minetest.register_on_dieplayer(function(player)
 	end
 
 	local player_inv = player:get_inventory()
-	if player_inv:is_empty("main") and
-		player_inv:is_empty("craft") then
+	if is_all_empty(player_inv) then
 		return
 	end
 
@@ -198,19 +211,12 @@ minetest.register_on_dieplayer(function(player)
 	end
 
 	if bones_mode == "drop" then
-
-		-- drop inventory items
-		for i = 1, player_inv:get_size("main") do
-			drop(pos, player_inv:get_stack("main", i))
-		end
-		player_inv:set_list("main", {})
-
-		-- drop crafting grid items
-		for i = 1, player_inv:get_size("craft") do
-			drop(pos, player_inv:get_stack("craft", i))
+		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
-		player_inv:set_list("craft", {})
-
 		drop(pos, ItemStack("bones:bones"))
 		return
 	end
@@ -221,21 +227,19 @@ minetest.register_on_dieplayer(function(player)
 	local meta = minetest.get_meta(pos)
 	local inv = meta:get_inventory()
 	inv:set_size("main", 8 * 4)
-	inv:set_list("main", player_inv:get_list("main"))
 
-	for i = 1, player_inv:get_size("craft") do
-		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
-			drop(pos, stack)
+	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
 		end
+		player_inv:set_list(list_name, {})
 	end
 
-	player_inv:set_list("main", {})
-	player_inv:set_list("craft", {})
-
 	meta:set_string("formspec", bones_formspec)
 	meta:set_string("owner", player_name)