From c6d715d8872eca52376089e99f7cd3e9d23dab58 Mon Sep 17 00:00:00 2001
From: FaceDeer <derksenmobile@gmail.com>
Date: Sun, 1 Jan 2017 00:53:40 -0700
Subject: If cycle fails due to out-of-inventory failure, reports first item
 that was out of stock

---
 node_builders.lua    | 16 +++++++++++-----
 node_controllers.lua | 18 ++++++++++--------
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/node_builders.lua b/node_builders.lua
index b8218b7..52fee0b 100644
--- a/node_builders.lua
+++ b/node_builders.lua
@@ -99,6 +99,12 @@ minetest.register_node("digtron:builder", {
 	-- return the item you took and the inventory location you took it from so it can be put back after all the other builders have been tested.
 	-- If you couldn't get the item from inventory, return an error code so we can abort the cycle.
 	-- If you're not supposed to build at all, or the location is obstructed, return 0 to let us know you're okay and we shouldn't abort."
+	
+	--return code and accompanying value:
+	-- 0, nil								-- not supposed to build, no error
+	-- 1, {itemstack, source inventory pos} -- can build, took an item from inventory
+	-- 2, itemstack 						-- was supposed to build, but couldn't get the item from inventory
+	-- 3, nil								-- builder configuration error
 	test_build = function(pos, test_pos, inventory_positions, protected_nodes, nodes_dug, controlling_coordinate, controller_pos)
 		local meta = minetest.get_meta(pos)
 		local facing = minetest.get_node(pos).param2
@@ -106,7 +112,7 @@ minetest.register_node("digtron:builder", {
 		
 		if (buildpos[controlling_coordinate] + meta:get_string("offset")) % meta:get_string("period") ~= 0 then
 			--It's not the builder's turn to build right now.
-			return 0
+			return 0, nil
 		end
 		
 		if not digtron.can_move_to(buildpos, protected_nodes, nodes_dug) then
@@ -120,7 +126,7 @@ minetest.register_node("digtron:builder", {
 			--managed one more cycle. That's not a bad outcome for a digtron array that was built stupidly to begin with.
 			--The player should be thanking me for all the error-checking I *do* do, really.
 			--Ungrateful wretch.
-			return 0
+			return 0, nil
 		end
 		
 		local inv = minetest.get_inventory({type="node", pos=pos})
@@ -136,11 +142,11 @@ minetest.register_node("digtron:builder", {
 			end
 			local source_location = digtron.take_from_inventory(item_stack:get_name(), inventory_positions)
 			if source_location ~= nil then
-				return {item=item_stack, location=source_location}
+				return 1, {item=item_stack, location=source_location}
 			end
-			return 2 -- error code for "needed an item but couldn't get it from inventory"
+			return 2, item_stack -- error code for "needed an item but couldn't get it from inventory"
 		else
-			return 1 -- error code for "this builder's item slot is unset"
+			return 3, nil -- error code for "this builder's item slot is unset"
 		end
 	end,
 	
diff --git a/node_controllers.lua b/node_controllers.lua
index fe0752c..07b84fb 100644
--- a/node_controllers.lua
+++ b/node_controllers.lua
@@ -115,20 +115,21 @@ minetest.register_node("digtron:controller", {
 		-- This is a complicated test because each builder needs to actually *take* the item it'll
 		-- need from inventory, and then we put it all back afterward.
 		local can_build = true
-		local test_build_return = nil
+		local test_build_return_code = nil
+		local test_build_return_item = nil
 		local test_items = {}
 		for k, location in pairs(layout.builders) do
 			local target = minetest.get_node(location)
 			local targetdef = minetest.registered_nodes[target.name]
 			local test_location = digtron.find_new_pos(location, facing)
 			if targetdef.test_build ~= nil then
-				test_build_return = targetdef.test_build(location, test_location, layout.inventories, layout.protected, nodes_dug, controlling_coordinate, layout.controller)
-				if test_build_return == 1 or test_build_return == 2 then
+				test_build_return_code, test_build_return_item = targetdef.test_build(location, test_location, layout.inventories, layout.protected, nodes_dug, controlling_coordinate, layout.controller)
+				if test_build_return_code > 1 then
 					can_build = false
 					break
 				end
-				if test_build_return ~= 0 then
-					table.insert(test_items, test_build_return)
+				if test_build_return_code == 1 then
+					table.insert(test_items, test_build_return_item)
 				end
 			else
 				minetest.log(string.format("%s has builder group but is missing test_build method! This is an error in mod programming, file a bug.", targetdef.name))
@@ -146,12 +147,13 @@ minetest.register_node("digtron:controller", {
 					minetest.get_meta(pos):set_string("waiting", nil)
 				end, pos
 			)
-			if test_build_return == 1 then
+			if test_build_return_code == 3 then
 				minetest.sound_play("honk", {gain=0.5, pos=pos}) -- A builder is not configured
 				meta:set_string("infotext", "Digtron connected to at least one builder node that hasn't had an output material assigned.")
-			elseif test_build_return == 2 then
+			elseif test_build_return_code == 2 then
 				minetest.sound_play("dingding", {gain=1.0, pos=pos}) -- Insufficient inventory
-				meta:set_string("infotext", "Digtron has insufficient materials in inventory to execute all build operations.")
+				meta:set_string("infotext", string.format("Digtron has insufficient materials in inventory to execute all build operations.\nNeeded: %s",
+					test_build_return_item:get_name()))
 			end
 			return --Abort, don't dig and don't build.
 		end	
-- 
cgit v1.2.3