diff --git a/recipe.lua b/recipe.lua index 6d0210a..bcce899 100644 --- a/recipe.lua +++ b/recipe.lua @@ -18,20 +18,20 @@ function prototype:getCost() return costs end --- Returns table of item -> missing-count mappings. Empty table if recipe can be afforded +-- Returns table of insufficient items. Empty table if recipe can be afforded function prototype:canAfford(chests) local storage = stackgroup.fromChests(table.unpack(chests)) local costs = self:getCost() local missing = {} for item,cost in pairs(costs) do - local group = storage:findGroup(item) - if group == nil or group.total < cost then + local group = storage:findAllGroups({ item = item, total = function(checkTotal) return checkTotal >= cost end }) + if #group == 0 then local totalMissing = cost if group ~= nil then totalMissing = totalMissing - group.total end - missing[item] = totalMissing + table.insert(missing, item) end end @@ -42,7 +42,7 @@ function prototype:beginCrafting(chests) local storage = stackgroup.fromChests(table.unpack(chests)) for _,input in pairs(self.inputs) do - local group = storage:findGroup(input.item) + local group = storage:findAllGroups({ item = input.item, total = function(checkTotal) return checkTotal >= input.cost end })[1] group:moveItemsToPeripheral(chests, input.count, input.machine, input.slot) end @@ -51,7 +51,7 @@ function prototype:beginCrafting(chests) for _,output in pairs(self.outputs) do local stackdata = itemstack.fromSlot(output.machine, output.slot) - if output.item ~= stackdata.item or output.count > stackdata.count then + if util.fuzzyEquals(stackdata.item, output.item) or output.count > stackdata.count then return false end end diff --git a/stackgroup.lua b/stackgroup.lua index edea9ee..2edae92 100644 --- a/stackgroup.lua +++ b/stackgroup.lua @@ -93,6 +93,10 @@ function stackgroupSetPrototype:findGroup(item) return util.find(self, function(group) return group.item == item end) end +function stackgroupSetPrototype:findAllGroups(groupPattern) + return util.findAll(self, function(group) return util.fuzzyEquals(group, groupPattern) end) +end + function stackgroup.fromChests(...) local chests = { ... } local groups = {} diff --git a/util.lua b/util.lua index 7074a45..064f194 100644 --- a/util.lua +++ b/util.lua @@ -34,9 +34,54 @@ function util.find(array, f) return nil end +function util.findAll(array, f) + local matches = {} + for k,v in pairs(array) do + if f(v, k) then + table.insert(matches, v) + end + end + return matches +end + function util.isEmpty(tbl) local next, t = pairs(tbl) return next(t) == nil end +function util.fuzzyEquals(value, pattern) + local valueType = type(value) + local patternType = type(pattern) + + if patternType == "nil" then + return true + end + + if patternType == "function" then + return pattern(value) + end + + if valueType ~= patternType then + return false + end + + if valueType == "table" then + for k,_ in pairs(pattern) do + if value[k] == nil then + return false + end + end + + for k,v in pairs(value) do + if not util.compareValue(v, pattern[k]) then + return false + end + end + + return true + end + + return value == pattern +end + return util \ No newline at end of file