diff --git a/milo/apis/milo.lua b/milo/apis/milo.lua index 87ae054..1025709 100644 --- a/milo/apis/milo.lua +++ b/milo/apis/milo.lua @@ -23,11 +23,11 @@ function Milo:requestCrafting(item) local key = Milo:uniqueKey(item) if not self.context.craftingQueue[key] then - item.ingredients = { - [ key ] = item - } item.crafted = 0 + item.pending = { } + item.key = key self.context.craftingQueue[key] = item + os.queueEvent('milo_cycle') end end diff --git a/milo/apis/storage.lua b/milo/apis/storage.lua index 2b22130..ce05b5d 100644 --- a/milo/apis/storage.lua +++ b/milo/apis/storage.lua @@ -27,12 +27,12 @@ listCount = 0, self.localName = modem.getNameLocal() Event.on({ 'device_attach', 'device_detach' }, function(e, dev) -_debug('%s: %s', e, tostring(dev)) +--_debug('%s: %s', e, tostring(dev)) self:initStorage() end) Event.onInterval(15, function() self:showStorage() - _debug('STORAGE: cache: %d/%d', self.hits, self.misses) +-- _debug('STORAGE: cache: %d/%d', self.hits, self.misses) end) end @@ -202,9 +202,9 @@ function Storage:provide(item, qty, slot, direction) local amount = adapter:provide(item, qty, slot, direction or self.localName) if amount > 0 then self.hits = self.hits + 1 - _debug('EXT: %s(%d): %s -> %s%s', - item.name, amount, adapter.name, direction or self.localName, - slot and string.format('[%d]', slot) or '') +-- _debug('EXT: %s(%d): %s -> %s%s', +-- item.name, amount, adapter.name, direction or self.localName, +-- slot and string.format('[%d]', slot) or '') self.dirty = true adapter.dirty = true end @@ -222,9 +222,9 @@ function Storage:provide(item, qty, slot, direction) for _, adapter in self:onlineAdapters() do local amount = adapter:provide(item, qty, slot, direction or self.localName) if amount > 0 then -_debug('EXT: %s(%d): %s -> %s%s', - item.name, amount, adapter.name, direction or self.localName, - slot and string.format('[%d]', slot) or '') +--_debug('EXT: %s(%d): %s -> %s%s', +-- item.name, amount, adapter.name, direction or self.localName, +-- slot and string.format('[%d]', slot) or '') self.dirty = true adapter.dirty = true end @@ -241,8 +241,8 @@ end function Storage:trash(source, slot, count) local trashcan = Util.find(self.remoteDefaults, 'mtype', 'trashcan') if trashcan and trashcan.adapter and trashcan.adapter.online then -_debug('TRA: %s[%d] (%d)', source or self.localName, slot, count or 64) - return trashcan.adapter.pullItems(source or self.localName, slot, count) +--_debug('TRA: %s[%d] (%d)', source or self.localName, slot, count or 64) +-- return trashcan.adapter.pullItems(source or self.localName, slot, count) end return 0 end diff --git a/milo/apis/turtle/craft.lua b/milo/apis/turtle/craft.lua index d05dd4a..8c2dea9 100644 --- a/milo/apis/turtle/craft.lua +++ b/milo/apis/turtle/craft.lua @@ -73,23 +73,10 @@ function Craft.sumIngredients(recipe) for _,item in pairs(recipe.ingredients) do t[item] = (t[item] or 0) + 1 end --- need a check for crafting tool return t end -local function machineCraft(recipe, inventoryAdapter, machineName, request, count) - if request.pending then - local imported = (inventoryAdapter.activity[recipe.result] or 0) - request.pending = request.pending - imported - request.crafted = request.crafted + imported - if request.pending <= 0 then - request.pending = nil - request.statusCode = nil - request.status = nil - end - return - end - +local function machineCraft(recipe, inventoryAdapter, machineName, request, count, item) local machine = device[machineName] if not machine then request.status = 'machine not found' @@ -126,7 +113,7 @@ local function machineCraft(recipe, inventoryAdapter, machineName, request, coun end request.status = 'processing' request.statusCode = Craft.STATUS_INFO - request.pending = count * recipe.count + item.pending[recipe.result] = count * recipe.count end local function turtleCraft(recipe, inventoryAdapter, request, count) @@ -149,12 +136,28 @@ local function turtleCraft(recipe, inventoryAdapter, request, count) turtle.select(1) if turtle.craft() then request.crafted = request.crafted + count * recipe.count + request.status = 'crafted' + request.statusCode = Craft.STATUS_INFO return true end request.status = 'Failed to craft' request.statusCode = Craft.STATUS_ERROR end +function Craft.processPending(item, inventoryAdapter) + for key, count in pairs(item.pending) do + local imported = inventoryAdapter.activity[key] + if imported then + local amount = math.min(imported, count) + inventoryAdapter.activity[key] = imported - amount + item.pending[key] = count - amount + if item.pending[key] <= 0 then + item.pending[key] = nil + end + end + end +end + function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem) if type(recipe) == 'string' then recipe = Craft.recipes[recipe] @@ -163,89 +166,43 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem) end end - -- wait til all requests have been completed - local isPending = false - for key, request in pairs(origItem.ingredients) do - if request.pending then - local irecipe = Craft.findRecipe(key) - machineCraft(irecipe, inventoryAdapter, - Craft.machineLookup[irecipe.result], request) - isPending = request.pending or isPending - end - end + local crafted = Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem) - local crafted = 0 - --if not isPending then - for _,key in pairs(Util.keys(origItem.ingredients)) do - local e = origItem.ingredients[key] - if e and e.transient then - origItem.ingredients[key] = nil - end - end - crafted = Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem) - --end - - for _, request in pairs(origItem.ingredients) do - if request.crafted >= request.count then -if request.pending then - _debug('??') - _debug(request) -end - request.status = nil - request.statusCode = Craft.STATUS_SUCCESS - end - end + origItem.crafted = math.min(origItem.count, origItem.crafted + crafted) return crafted end +local function adjustCounts(recipe, count, ingredients) + -- decrement ingredients used + for key,icount in pairs(Craft.sumIngredients(recipe)) do + ingredients[key].count = ingredients[key].count - (icount * count) + end + + -- increment crafted + local result = ingredients[recipe.result] + result.count = result.count + (count * recipe.count) +end + function Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem) - local items = inventoryAdapter:listItems() - if not items then - return 0, 'Inventory changed' - end - local request = origItem.ingredients[recipe.result] - if not request then - request = { - crafted = 0, - count = count, - } - origItem.ingredients[recipe.result] = request - end - if request.pending then - --machineCraft(recipe, inventoryAdapter, - -- Craft.machineLookup[recipe.result], request) + local canCraft = Craft.getCraftableAmount(recipe, count, origItem.ingredients) + if not origItem.forceCrafting and canCraft == 0 then return 0 end - local canCraft = Craft.getCraftableAmount(recipe, count, items, { }) - if canCraft == 0 then - - local resourceList = Craft.getResourceList(recipe, items, count) -_G._p2 = resourceList - for k,v in pairs(resourceList) do - if v.need > 0 then - if not origItem.ingredients[k] then - origItem.ingredients[k] = { - status = 'No recipe', - statusCode = Craft.STATUS_ERROR, - count = v.need, - crafted = 0, - transient = true, - } - end - end - end - return 0 + canCraft = math.ceil(canCraft / recipe.count) + if origItem.forceCrafting then + count = math.ceil(count / recipe.count) + else + count = canCraft end - count = math.ceil(canCraft / recipe.count) local maxCount = recipe.maxCount or math.floor(64 / recipe.count) for key,icount in pairs(Craft.sumIngredients(recipe)) do - local itemCount = Craft.getItemCount(items, key) + local itemCount = Craft.getItemCount(origItem.ingredients, key) local need = icount * count if recipe.craftingTools and recipe.craftingTools[key] then need = 1 @@ -258,27 +215,40 @@ _G._p2 = resourceList end local iqty = need - itemCount local crafted = Craft.craftRecipeInternal(irecipe, iqty, inventoryAdapter, origItem) - if crafted ~= iqty then + if not origItem.forceCrafting and crafted < iqty then return 0 end + if origItem.forceCrafting and crafted < iqty then + canCraft = math.floor((itemCount + crafted) / icount) + end end end + local crafted = 0 - repeat - local batch = math.min(count, maxCount) + while canCraft > 0 do + if origItem.pending[recipe.result] then + request.status = 'processing' + request.statusCode = Craft.STATUS_INFO + break + end + + local batch = math.min(canCraft, maxCount) + if Craft.machineLookup[recipe.result] then if not machineCraft(recipe, inventoryAdapter, - Craft.machineLookup[recipe.result], request, batch) then + Craft.machineLookup[recipe.result], request, batch, origItem) then break end elseif not turtleCraft(recipe, inventoryAdapter, request, batch) then break end + adjustCounts(recipe, batch, origItem.ingredients) + crafted = crafted + batch - count = count - maxCount - until count <= 0 + canCraft = canCraft - maxCount + end return crafted * recipe.count end diff --git a/milo/plugins/activityView.lua b/milo/plugins/activityView.lua index 259877e..44b420f 100644 --- a/milo/plugins/activityView.lua +++ b/milo/plugins/activityView.lua @@ -19,7 +19,6 @@ local page = UI.Window { textScale = .5, }, grid = UI.Grid { - ey = -6, columns = { { heading = 'Qty', key = 'count', width = 6 }, { heading = 'Change', key = 'change', width = 6 }, @@ -28,31 +27,6 @@ local page = UI.Window { }, sortColumn = 'displayName', }, - buttons = UI.Window { - y = -5, height = 5, - backgroundColor = colors.gray, - prevButton = UI.Button { - x = 2, y = 2, height = 3, width = 5, - event = 'previous', - backgroundColor = colors.lightGray, - text = ' < ' - }, - resetButton = UI.Button { - x = 8, y = 2, height = 3, ex = -8, - event = 'reset', - backgroundColor = colors.lightGray, - text = 'Reset' - }, - nextButton = UI.Button { - x = -6, y = 2, height = 3, width = 5, - event = 'next', - backgroundColor = colors.lightGray, - text = ' > ' - }, - }, - accelerators = { - q = 'quit', - } } function page.grid:getRowTextColor(row, selected) @@ -77,27 +51,11 @@ function page.grid:getDisplayValues(row) return row end -function page:eventHandler(event) - if event.type == 'reset' then - self.lastItems = nil - self.grid:setValues({ }) - self.grid:clear() - self.grid:draw() - - elseif event.type == 'next' then - self.grid:nextPage() - - elseif event.type == 'previous' then - self.grid:previousPage() - - elseif event.type == 'quit' then - Event.exitPullEvents() - - else - return UI.Window.eventHandler(self, event) - end - - return true +function page:reset() + self.lastItems = nil + self.grid:setValues({ }) + self.grid:clear() + self.grid:draw() end function page:refresh() @@ -165,7 +123,7 @@ end) Event.on('monitor_touch', function(_, side) if side == mon.side then - page:emit({ type = 'reset' }) + page:reset() page:sync() end end) diff --git a/milo/plugins/craftTask.lua b/milo/plugins/craftTask.lua index f0e59ee..ea01318 100644 --- a/milo/plugins/craftTask.lua +++ b/milo/plugins/craftTask.lua @@ -1,5 +1,4 @@ local Craft = require('turtle.craft') -local itemDB = require('itemDB') local Milo = require('milo') local sync = require('sync').sync local Util = require('util') @@ -12,89 +11,30 @@ local craftTask = { priority = 70, } -function craftTask:craftItem(recipe, item, count) - Craft.craftRecipe(recipe, count, context.storage, item) - Milo:clearGrid() -end - --- Craft as much as possible regardless if all ingredients are available -function craftTask:forceCraftItem(inRecipe, originalItem, inCount) - local summed = { } - local items = Milo:listItems() - local throttle = Util.throttle() - - local function sumItems(recipe, count) - count = math.ceil(count / recipe.count) - local craftable = count - - for key,iqty in pairs(Craft.sumIngredients(recipe)) do - throttle() - local item = itemDB:splitKey(key) - local summedItem = summed[key] - if not summedItem then - summedItem = Util.shallowCopy(item) - summedItem.recipe = Craft.findRecipe(item) - summedItem.count = Craft.getItemCount(items, key) - summedItem.need = 0 - summedItem.used = 0 - summedItem.craftable = 0 - summed[key] = summedItem - end - - local total = count * iqty -- 4 * 2 - local used = math.min(summedItem.count, total) -- 5 - local need = total - used -- 3 - - if recipe.craftingTools and recipe.craftingTools[key] then - if summedItem.count > 0 then - summedItem.used = 1 - summedItem.need = 0 - need = 0 - elseif not summedItem.recipe then - summedItem.need = 1 - need = 1 - else - need = 1 - end - else - summedItem.count = summedItem.count - used - summedItem.used = summedItem.used + used - end - - if need > 0 then - if not summedItem.recipe then - craftable = math.min(craftable, math.floor(used / iqty)) - summedItem.need = summedItem.need + need - else - local c = sumItems(summedItem.recipe, need) -- 4 - craftable = math.min(craftable, math.floor((used + c) / iqty)) - summedItem.craftable = summedItem.craftable + c - end - end - end - - if craftable > 0 then - craftable = Craft.craftRecipe(recipe, craftable * recipe.count, - context.storage, originalItem) / recipe.count - Milo:clearGrid() - end - - return craftable * recipe.count - end - - return sumItems(inRecipe, inCount) -end - function craftTask:craft(recipe, item) if Milo:isCraftingPaused() then return end - if item.forceCrafting then - self:forceCraftItem(recipe, item, item.count - item.crafted) - else - self:craftItem(recipe, item, item.count - item.crafted) + Craft.processPending(item, context.storage) + + item.ingredients = Craft.getResourceList(recipe, Milo:listItems(), item.count - item.crafted) + + for k, v in pairs(item.ingredients) do + v.crafted = v.used + v.count = v.used + v.key = k + if v.need > 0 then + v.status = 'No recipe' + v.statusCode = Craft.STATUS_ERROR + end end + item.ingredients[recipe.result] = Util.shallowCopy(item) + item.ingredients[recipe.result].total = item.count + item.ingredients[recipe.result].crafted = item.crafted + + Craft.craftRecipe(recipe, item.count - item.crafted, context.storage, item) + Milo:clearGrid() end function craftTask:cycle() diff --git a/milo/plugins/demandCraft.lua b/milo/plugins/demandCraft.lua index a1afa66..bc059dd 100644 --- a/milo/plugins/demandCraft.lua +++ b/milo/plugins/demandCraft.lua @@ -100,7 +100,7 @@ function craftPage.wizard.pages.resources:enable() local count = tonumber(self.parent.quantity.count.value) local recipe = Craft.findRecipe(craftPage.item) if recipe then - local ingredients = Craft.getResourceList4(recipe, items, count) + local ingredients = Craft.getResourceList(recipe, items, count) for _,v in pairs(ingredients) do v.displayName = itemDB:getName(v) end diff --git a/milo/plugins/jobMonitor.lua b/milo/plugins/jobMonitor.lua index 9d1a99e..da4fc30 100644 --- a/milo/plugins/jobMonitor.lua +++ b/milo/plugins/jobMonitor.lua @@ -25,7 +25,12 @@ local jobMonitor = UI.Page { { heading = 'Qty', key = 'remaining', width = 4 }, { heading = 'Crafting', key = 'displayName', }, { heading = 'Status', key = 'status', }, - { heading = 'Progress', key = 'progress', width = 8 }, + { heading = 'need', key = 'need', width = 4 }, + { heading = 'total', key = 'total', width = 4 }, + { heading = 'used', key = 'used', width = 4 }, + { heading = 'count', key = 'count', width = 4 }, + { heading = 'crafted', key = 'crafted', width = 4 }, +-- { heading = 'Progress', key = 'progress', width = 8 }, }, }, } @@ -44,7 +49,7 @@ function jobMonitor:updateList(craftList) v.index = #t v.showRemaining = true for k2,v2 in pairs(v.ingredients) do - if v2 ~= v then + if v2.key ~= v.key and v2.statusCode then table.insert(t, v2) if not v2.displayName then v2.displayName = itemDB:getName(k2) diff --git a/miners/scanningMiner.lua b/miners/scanningMiner.lua index 59175a3..1c3cbe4 100644 --- a/miners/scanningMiner.lua +++ b/miners/scanningMiner.lua @@ -425,10 +425,6 @@ local function scan() page.statusBar:setValue('status', b.name .. ' ' .. m) page.statusBar:draw() page:sync() - if debug and type(debug) == 'function' then - debug(b.name .. ' ' .. m) - end --- os.sleep(3) else page.statusBar:setValue('mining', m) end