forked from mtcontrib/pipeworks
Fix autocrafter not taking enough items if number of needed items of a kind > stack max for that item.
This commit is contained in:
parent
7887d28e08
commit
dc1ef38a58
@ -1,51 +1,59 @@
|
|||||||
local autocrafterCache = {} -- caches some recipe data to avoid to call the slow function minetest.get_craft_result() every second
|
local autocrafterCache = {} -- caches some recipe data to avoid to call the slow function minetest.get_craft_result() every second
|
||||||
|
|
||||||
|
local function make_inventory_cache(invlist)
|
||||||
|
local l = {}
|
||||||
|
for _, stack in ipairs(invlist) do
|
||||||
|
l[stack:get_name()] = (l[stack:get_name()] or 0) + stack:get_count()
|
||||||
|
end
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
function autocraft(inventory, pos)
|
function autocraft(inventory, pos)
|
||||||
local recipe = inventory:get_list("recipe")
|
local recipe = inventory:get_list("recipe")
|
||||||
local recipe_last
|
local recipe_last
|
||||||
local result
|
local result
|
||||||
local new
|
local new
|
||||||
|
|
||||||
if autocrafterCache[minetest.hash_node_position(pos)] == nil then
|
if autocrafterCache[minetest.hash_node_position(pos)] == nil then
|
||||||
--print("first call for this autocrafter at pos("..pos.x..","..pos.y..","..pos.z..")")
|
--print("first call for this autocrafter at pos("..pos.x..","..pos.y..","..pos.z..")")
|
||||||
recipe_last = {}
|
recipe_last = {}
|
||||||
|
for i = 1, 9 do
|
||||||
|
recipe_last[i] = recipe[i]
|
||||||
|
--print (recipe_last[i]:get_name())
|
||||||
|
recipe[i] = ItemStack({name = recipe[i]:get_name(), count = 1})
|
||||||
|
end
|
||||||
|
result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe})
|
||||||
|
autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new}
|
||||||
|
else
|
||||||
|
local autocrafterCacheEntry = autocrafterCache[minetest.hash_node_position(pos)]
|
||||||
|
recipe_last = autocrafterCacheEntry["recipe"]
|
||||||
|
result = autocrafterCacheEntry["result"]
|
||||||
|
new = autocrafterCacheEntry["new"]
|
||||||
|
local recipeUnchanged = true
|
||||||
|
for i = 1, 9 do
|
||||||
|
if recipe[i]:get_name() ~= recipe_last[i]:get_name() then
|
||||||
|
recipeUnchanged = False
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if recipe[i]:get_count() ~= recipe_last[i]:get_count() then
|
||||||
|
recipeUnchanged = False
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if recipeUnchanged then
|
||||||
|
--print("autocrafter recipe unchanged")
|
||||||
|
else
|
||||||
|
--print("autocrafter recipe changed at pos("..pos.x..","..pos.y..","..pos.z..")")
|
||||||
for i = 1, 9 do
|
for i = 1, 9 do
|
||||||
recipe_last[i] = recipe[i]
|
recipe_last[i] = recipe[i]
|
||||||
--print (recipe_last[i]:get_name())
|
recipe[i] = ItemStack({name = recipe[i]:get_name(), count = 1})
|
||||||
recipe[i] = ItemStack({name = recipe[i]:get_name(), count = 1})
|
|
||||||
end
|
end
|
||||||
result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe})
|
result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe})
|
||||||
autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new}
|
autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new}
|
||||||
else
|
|
||||||
local autocrafterCacheEntry = autocrafterCache[minetest.hash_node_position(pos)]
|
|
||||||
recipe_last = autocrafterCacheEntry["recipe"]
|
|
||||||
result = autocrafterCacheEntry["result"]
|
|
||||||
new = autocrafterCacheEntry["new"]
|
|
||||||
local recipeUnchanged = true
|
|
||||||
for i = 1, 9 do
|
|
||||||
if recipe[i]:get_name() ~= recipe_last[i]:get_name() then
|
|
||||||
recipeUnchanged = False
|
|
||||||
break
|
|
||||||
end
|
|
||||||
if recipe[i]:get_count() ~= recipe_last[i]:get_count() then
|
|
||||||
recipeUnchanged = False
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if recipeUnchanged then
|
|
||||||
--print("autocrafter recipe unchanged")
|
|
||||||
else
|
|
||||||
--print("autocrafter recipe changed at pos("..pos.x..","..pos.y..","..pos.z..")")
|
|
||||||
for i = 1, 9 do
|
|
||||||
recipe_last[i] = recipe[i]
|
|
||||||
recipe[i] = ItemStack({name = recipe[i]:get_name(), count = 1})
|
|
||||||
end
|
|
||||||
result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe})
|
|
||||||
autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local input = inventory:get_list("input")
|
local input = inventory:get_list("input")
|
||||||
if result.item:is_empty() then return end
|
if result.item:is_empty() then return end
|
||||||
result = result.item
|
result = result.item
|
||||||
if not inventory:room_for_item("dst", result) then return end
|
if not inventory:room_for_item("dst", result) then return end
|
||||||
@ -59,14 +67,14 @@ function autocraft(inventory, pos)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local stack
|
local invcache = make_inventory_cache(inventory:get_list("src"))
|
||||||
for itemname, number in pairs(to_use) do
|
for itemname, number in pairs(to_use) do
|
||||||
stack = ItemStack({name = itemname, count = number})
|
if (not invcache[itemname]) or invcache[itemname] < number then return end
|
||||||
if not inventory:contains_item("src", stack) then return end
|
|
||||||
end
|
end
|
||||||
for itemname, number in pairs(to_use) do
|
for itemname, number in pairs(to_use) do
|
||||||
stack = ItemStack({name = itemname, count = number})
|
for i = 1, number do -- We have to do that since remove_item does not work if count > stack_max
|
||||||
inventory:remove_item("src", stack)
|
inventory:remove_item("src", ItemStack(itemname))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
inventory:add_item("dst", result)
|
inventory:add_item("dst", result)
|
||||||
for i = 1, 9 do
|
for i = 1, 9 do
|
||||||
|
Loading…
Reference in New Issue
Block a user