summaryrefslogtreecommitdiff
path: root/autocrafter.lua
diff options
context:
space:
mode:
authorNovatux <nathanael.courant@laposte.net>2013-10-30 08:33:09 +0100
committerNovatux <nathanael.courant@laposte.net>2013-10-30 08:33:34 +0100
commitdc1ef38a580406015ca18bd683615f27d9aabb50 (patch)
treeb4bfae5aab112113dfe5a6946db42cd5d408c87f /autocrafter.lua
parent7887d28e0816cb946ee73724545fad5ca1792203 (diff)
downloadpipeworks-dc1ef38a580406015ca18bd683615f27d9aabb50.tar
pipeworks-dc1ef38a580406015ca18bd683615f27d9aabb50.tar.gz
pipeworks-dc1ef38a580406015ca18bd683615f27d9aabb50.tar.bz2
pipeworks-dc1ef38a580406015ca18bd683615f27d9aabb50.tar.xz
pipeworks-dc1ef38a580406015ca18bd683615f27d9aabb50.zip
Fix autocrafter not taking enough items if number of needed items of a kind > stack max for that item.
Diffstat (limited to 'autocrafter.lua')
-rw-r--r--autocrafter.lua92
1 files changed, 50 insertions, 42 deletions
diff --git a/autocrafter.lua b/autocrafter.lua
index 164f6fe..1f2d9e5 100644
--- a/autocrafter.lua
+++ b/autocrafter.lua
@@ -1,51 +1,59 @@
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)
local recipe = inventory:get_list("recipe")
- local recipe_last
- local result
- local new
+ local recipe_last
+ local result
+ local new
- if autocrafterCache[minetest.hash_node_position(pos)] == nil then
- --print("first call for this autocrafter at pos("..pos.x..","..pos.y..","..pos.z..")")
- 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})
+ if autocrafterCache[minetest.hash_node_position(pos)] == nil then
+ --print("first call for this autocrafter at pos("..pos.x..","..pos.y..","..pos.z..")")
+ 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
- result, new = minetest.get_craft_result({method = "normal", width = 3, items = recipe})
- autocrafterCache[minetest.hash_node_position(pos)] = {["recipe"] = recipe, ["result"] = result, ["new"] = new}
+ if recipe[i]:get_count() ~= recipe_last[i]:get_count() then
+ recipeUnchanged = False
+ break
+ end
+ end
+ if recipeUnchanged then
+ --print("autocrafter recipe unchanged")
else
- local autocrafterCacheEntry = autocrafterCache[minetest.hash_node_position(pos)]
- recipe_last = autocrafterCacheEntry["recipe"]
- result = autocrafterCacheEntry["result"]
- new = autocrafterCacheEntry["new"]
- local recipeUnchanged = true
+ --print("autocrafter recipe changed at pos("..pos.x..","..pos.y..","..pos.z..")")
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}
+ 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
- local input = inventory:get_list("input")
+ local input = inventory:get_list("input")
if result.item:is_empty() then return end
result = result.item
if not inventory:room_for_item("dst", result) then return end
@@ -59,14 +67,14 @@ function autocraft(inventory, pos)
end
end
end
- local stack
+ local invcache = make_inventory_cache(inventory:get_list("src"))
for itemname, number in pairs(to_use) do
- stack = ItemStack({name = itemname, count = number})
- if not inventory:contains_item("src", stack) then return end
+ if (not invcache[itemname]) or invcache[itemname] < number then return end
end
for itemname, number in pairs(to_use) do
- stack = ItemStack({name = itemname, count = number})
- inventory:remove_item("src", stack)
+ for i = 1, number do -- We have to do that since remove_item does not work if count > stack_max
+ inventory:remove_item("src", ItemStack(itemname))
+ end
end
inventory:add_item("dst", result)
for i = 1, 9 do