local _ = require "moses" local util = require "util" local conf = util.conf rednet.open(conf.modem) local patterns = loadfile "patterns.lua"() local function descend(intermediateFn, terminalFn, i) local pattern = patterns[i] if pattern then intermediateFn(pattern) local pqty = pattern.qty -- Qty keys must be removed from the pattern for collation -- Otherwise, it shows up as a number stuck in the items needed table, which is bad. pattern.qty = nil local needs = util.collate(pattern) pattern.qty = pqty local has = {} for slot, item in pairs(pattern) do if util.satisfied(needs, has) then break end if patterns[item] then descend(intermediateFn, terminalFn, item) has[item] = (has[item] or 0) + (patterns[item].qty or 1) end end else terminalFn(i) end end local function cost(i) local items = {} descend(function() end, function(i) table.insert(items, i) end, i) return collate(items) end local function tasks(i) local t = {} descend(function(pat) table.insert(t, pat) end, function() end, i) return t end -- Splits "mod:item:meta" into {"mod:item", "meta"} local function splitItemString(is) local parts = util.split(is, ":") return {parts[1] .. parts[2], tonumber(parts[3]) or 0} end local function craftOne(pat) for slot, itemName in pairs(pat) do local ispl = splitItemString(itemName) util.query { cmd = "extract", meta = ispl[2], name = ispl[1], destInv = conf.name, destSlot = slot } end turtle.craft() util.query { cmd = "insert", fromInv = conf.name, fromSlot = 16 } end local function craft(i) turtle.select(16) -- so that crafting outputs go here local stored = utils.query { cmd = "list" } local reqs = cost(i) if util.satisfied(reqs, stored) then local tsks = _.reverse(tasks(i)) -- tasks returns the highest level/most complex/most subtask-requring tasks first. for _, tsk in pairs(tsks) do craftOne(tsk) end else return "ERROR" end end while true do local id, msg = rednet.receive "dragon" if msg and msg.cmd and msg.cmd == "craft" and msg.item then craft(msg.item) end end