milo: crafting recursion fix

This commit is contained in:
kepler155c@gmail.com
2019-04-02 14:28:09 -04:00
parent 54ed32ecd9
commit 8f432c4638

View File

@@ -134,7 +134,7 @@ local function turtleCraft(recipe, storage, request, count)
for k,v in pairs(recipe.ingredients) do for k,v in pairs(recipe.ingredients) do
local item = splitKey(v) local item = splitKey(v)
if storage:export(storage.turtleInventory, k, count, item) ~= count then if storage:export(storage.turtleInventory, k, count, item) ~= count then
request.status = 'unknown error' request.status = 'rescan needed ?'
request.statusCode = Craft.STATUS_ERROR request.statusCode = Craft.STATUS_ERROR
_debug('failed to export: ' .. item.name) _debug('failed to export: ' .. item.name)
@@ -181,6 +181,20 @@ function Craft.processPending(item, storage)
end end
end end
-- return a recipe if the ingredients will not produce recursion
local function findValidRecipe(key, path)
local recipe = Craft.findRecipe(key)
if recipe then
for k in pairs(Craft.sumIngredients(recipe)) do
if path[k] then
return
end
end
return recipe
end
end
function Craft.craftRecipe(recipe, count, storage, origItem) function Craft.craftRecipe(recipe, count, storage, origItem)
if type(recipe) == 'string' then if type(recipe) == 'string' then
recipe = Craft.recipes[recipe] recipe = Craft.recipes[recipe]
@@ -189,7 +203,8 @@ function Craft.craftRecipe(recipe, count, storage, origItem)
end end
end end
return Craft.craftRecipeInternal(recipe, count, storage, origItem) local path = { [ recipe.result ] = true }
return Craft.craftRecipeInternal(recipe, count, storage, origItem, path)
end end
local function adjustCounts(recipe, count, ingredients, storage) local function adjustCounts(recipe, count, ingredients, storage)
@@ -203,7 +218,7 @@ local function adjustCounts(recipe, count, ingredients, storage)
result.count = result.count + (count * recipe.count) result.count = result.count + (count * recipe.count)
end end
function Craft.craftRecipeInternal(recipe, count, storage, origItem) function Craft.craftRecipeInternal(recipe, count, storage, origItem, path)
local request = origItem.ingredients[recipe.result] local request = origItem.ingredients[recipe.result]
--[[ --[[
@@ -239,13 +254,15 @@ function Craft.craftRecipeInternal(recipe, count, storage, origItem)
end end
maxCount = math.min(maxCount, itemDB:getMaxCount(key)) maxCount = math.min(maxCount, itemDB:getMaxCount(key))
if itemCount < need then if itemCount < need then
local irecipe = Craft.findRecipe(key) local irecipe = findValidRecipe(key, path)
if not irecipe then if not irecipe then
return 0 return 0
end end
local iqty = need - itemCount local iqty = need - itemCount
local crafted = Craft.craftRecipeInternal(irecipe, iqty, storage, origItem) local p = Util.shallowCopy(path)
p[irecipe.result] = true
local crafted = Craft.craftRecipeInternal(irecipe, iqty, storage, origItem, p)
if not origItem.forceCrafting and crafted < iqty then if not origItem.forceCrafting and crafted < iqty then
return 0 return 0
end end
@@ -311,18 +328,19 @@ end
function Craft.getResourceList(inRecipe, items, inCount, pending) function Craft.getResourceList(inRecipe, items, inCount, pending)
local summed = { } local summed = { }
local function sumItems(recipe, key, count) local function sumItems(recipe, key, count, path)
local item = itemDB:splitKey(key) local item = itemDB:splitKey(key)
local summedItem = summed[key] local summedItem = summed[key]
if not summedItem then if not summedItem then
summedItem = Util.shallowCopy(item) summedItem = Util.shallowCopy(item)
summedItem.recipe = Craft.findRecipe(key)
summedItem.count = Craft.getItemCount(items, item) summedItem.count = Craft.getItemCount(items, item)
summedItem.displayName = itemDB:getName(item) summedItem.displayName = itemDB:getName(item)
summedItem.total = 0 summedItem.total = 0
summedItem.need = 0 summedItem.need = 0
summedItem.used = 0 summedItem.used = 0
summed[key] = summedItem summed[key] = summedItem
summedItem.recipe = findValidRecipe(key, path)
end end
local total = count local total = count
local used = math.min(summedItem.count, total) local used = math.min(summedItem.count, total)
@@ -355,8 +373,10 @@ function Craft.getResourceList(inRecipe, items, inCount, pending)
if need > 0 and summedItem.recipe then if need > 0 and summedItem.recipe then
need = math.ceil(need / summedItem.recipe.count) need = math.ceil(need / summedItem.recipe.count)
local p = Util.shallowCopy(path)
p[summedItem.recipe.result] = true
for ikey,iqty in pairs(Craft.sumIngredients(summedItem.recipe)) do for ikey,iqty in pairs(Craft.sumIngredients(summedItem.recipe)) do
sumItems(summedItem.recipe, ikey, math.ceil(need * iqty)) sumItems(summedItem.recipe, ikey, math.ceil(need * iqty), p)
end end
end end
end end
@@ -366,8 +386,9 @@ function Craft.getResourceList(inRecipe, items, inCount, pending)
inCount = inCount - pending[inRecipe.result] inCount = inCount - pending[inRecipe.result]
end end
if inCount > 0 then if inCount > 0 then
local path = { [ inRecipe.result ] = true }
for ikey,iqty in pairs(Craft.sumIngredients(inRecipe)) do for ikey,iqty in pairs(Craft.sumIngredients(inRecipe)) do
sumItems(inRecipe, ikey, math.ceil(inCount * iqty)) sumItems(inRecipe, ikey, math.ceil(inCount * iqty), path)
end end
end end
@@ -376,22 +397,24 @@ end
function Craft.getResourceList4(inRecipe, items, count) function Craft.getResourceList4(inRecipe, items, count)
local summed = Craft.getResourceList(inRecipe, items, count) local summed = Craft.getResourceList(inRecipe, items, count)
-- filter down to just raw materials -- filter down to just raw materials
return Util.filter(summed, function(a) return a.used > 0 or a.need > 0 end) return Util.filter(summed, function(a) return a.used > 0 or a.need > 0 end)
end end
-- given a certain quantity, return how many of those can be crafted -- given a certain quantity, return how many of those can be crafted
function Craft.getCraftableAmount(inRecipe, inCount, items, missing) function Craft.getCraftableAmount(inRecipe, inCount, items, missing)
local function sumItems(recipe, summedItems, count) local function sumItems(recipe, summedItems, count, path)
local canCraft = 0 local canCraft = 0
for _ = 1, count do for _ = 1, count do
for _,item in pairs(recipe.ingredients) do for _,item in pairs(recipe.ingredients) do
local summedItem = summedItems[item] or Craft.getItemCount(items, item) local summedItem = summedItems[item] or Craft.getItemCount(items, item)
local irecipe = Craft.findRecipe(item) local irecipe = findValidRecipe(item, path)
if irecipe and summedItem <= 0 then if irecipe and summedItem <= 0 then
summedItem = summedItem + sumItems(irecipe, summedItems, 1) local p = Util.shallowCopy(path)
p[irecipe.result] = true
summedItem = summedItem + sumItems(irecipe, summedItems, 1, p)
end end
if summedItem <= 0 then if summedItem <= 0 then
if missing and not irecipe then if missing and not irecipe then
@@ -409,7 +432,8 @@ function Craft.getCraftableAmount(inRecipe, inCount, items, missing)
return canCraft return canCraft
end end
return sumItems(inRecipe, { }, math.ceil(inCount / inRecipe.count)) local path = { [ inRecipe.result ] = true }
return sumItems(inRecipe, { }, math.ceil(inCount / inRecipe.count), path)
end end
function Craft.loadRecipes() function Craft.loadRecipes()