If cycle fails due to out-of-inventory failure, reports first item that was out of stock

This commit is contained in:
FaceDeer 2017-01-01 00:53:40 -07:00
parent 6c7842d92c
commit c6d715d887
2 changed files with 21 additions and 13 deletions

@ -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. -- 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 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." -- 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) test_build = function(pos, test_pos, inventory_positions, protected_nodes, nodes_dug, controlling_coordinate, controller_pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local facing = minetest.get_node(pos).param2 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 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. --It's not the builder's turn to build right now.
return 0 return 0, nil
end end
if not digtron.can_move_to(buildpos, protected_nodes, nodes_dug) then 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. --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. --The player should be thanking me for all the error-checking I *do* do, really.
--Ungrateful wretch. --Ungrateful wretch.
return 0 return 0, nil
end end
local inv = minetest.get_inventory({type="node", pos=pos}) local inv = minetest.get_inventory({type="node", pos=pos})
@ -136,11 +142,11 @@ minetest.register_node("digtron:builder", {
end end
local source_location = digtron.take_from_inventory(item_stack:get_name(), inventory_positions) local source_location = digtron.take_from_inventory(item_stack:get_name(), inventory_positions)
if source_location ~= nil then if source_location ~= nil then
return {item=item_stack, location=source_location} return 1, {item=item_stack, location=source_location}
end 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 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
end, end,

@ -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 -- 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. -- need from inventory, and then we put it all back afterward.
local can_build = true local can_build = true
local test_build_return = nil local test_build_return_code = nil
local test_build_return_item = nil
local test_items = {} local test_items = {}
for k, location in pairs(layout.builders) do for k, location in pairs(layout.builders) do
local target = minetest.get_node(location) local target = minetest.get_node(location)
local targetdef = minetest.registered_nodes[target.name] local targetdef = minetest.registered_nodes[target.name]
local test_location = digtron.find_new_pos(location, facing) local test_location = digtron.find_new_pos(location, facing)
if targetdef.test_build ~= nil then 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) 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 == 1 or test_build_return == 2 then if test_build_return_code > 1 then
can_build = false can_build = false
break break
end end
if test_build_return ~= 0 then if test_build_return_code == 1 then
table.insert(test_items, test_build_return) table.insert(test_items, test_build_return_item)
end end
else 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)) 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) minetest.get_meta(pos):set_string("waiting", nil)
end, pos 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 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.") 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 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 end
return --Abort, don't dig and don't build. return --Abort, don't dig and don't build.
end end