From 6d3389c9c6939199cf6447c21f1a2aeb495c0c39 Mon Sep 17 00:00:00 2001 From: kepler155c Date: Fri, 26 Oct 2018 00:30:37 -0400 Subject: [PATCH] milo wip --- milo/Milo.lua | 10 +- milo/apis/milo.lua | 10 +- milo/apis/networkedAdapter18.lua | 13 +- milo/apis/turtle/craft.lua | 212 ++++++++++++++++--------------- milo/plugins/craftTask.lua | 23 +--- milo/plugins/jobList.lua | 18 ++- milo/plugins/machineLearn.lua | 5 +- 7 files changed, 147 insertions(+), 144 deletions(-) diff --git a/milo/Milo.lua b/milo/Milo.lua index 1f1e736..603d5c8 100644 --- a/milo/Milo.lua +++ b/milo/Milo.lua @@ -113,6 +113,8 @@ local context = { craftingQueue = { }, } +_G._p = context--debug + local function initStorage(detachedDevice) debug('Initializing storage') local storage = { } @@ -142,7 +144,9 @@ debug(storage) debug('resuming') Milo:resumeCrafting() end - +--TODO: cannot do this, must be able to add and mark inactive +-- due to activity table +-- add an networkAdapter:scan() context.inventoryAdapter = InventoryAdapter.wrap({ remoteDefaults = storage }) if not context.inventoryAdapter then @@ -151,7 +155,7 @@ debug(storage) end Event.on({ 'device_attach' }, function(_, dev) - debug('attach: ' .. dev) + --debug('attach: ' .. dev) if config.remoteDefaults[dev] and config.remoteDefaults[dev].mtype == 'storage' then initStorage() @@ -159,7 +163,7 @@ Event.on({ 'device_attach' }, function(_, dev) end) Event.on({ 'device_detach' }, function(_, dev) - debug('detach: ' .. dev) + --debug('detach: ' .. dev) if config.remoteDefaults[dev] and config.remoteDefaults[dev].mtype == 'storage' then initStorage(dev) diff --git a/milo/apis/milo.lua b/milo/apis/milo.lua index c8c5b4f..9bd90fb 100644 --- a/milo/apis/milo.lua +++ b/milo/apis/milo.lua @@ -22,13 +22,11 @@ function Milo:requestCrafting(item) local key = Milo:uniqueKey(item) if not self.context.craftingQueue[key] then - item.ingredients = { } - --[[ - count = requested amount, - crafted = amount that has been crafted - ]] + item.ingredients = { + [ key ] = item + } +-- item.ingredients[key] = item item.crafted = 0 - self.context.craftingQueue[key] = item end end diff --git a/milo/apis/networkedAdapter18.lua b/milo/apis/networkedAdapter18.lua index a3d3897..2f1295f 100644 --- a/milo/apis/networkedAdapter18.lua +++ b/milo/apis/networkedAdapter18.lua @@ -115,9 +115,9 @@ function NetworkedAdapter:provide(item, qty, slot, direction) for _, remote in ipairs(self.remotes) do local amount = remote:provide(item, qty, slot, direction) if amount > 0 then -debug('EXT: %s(%d): %s -> %s%s', - item.name, amount, remote.side, direction or self.localName, - slot and string.format('[%d]', slot) or '') +--debug('EXT: %s(%d): %s -> %s%s', +-- item.name, amount, remote.side, direction or self.localName, +-- slot and string.format('[%d]', slot) or '') self.dirty = true remote.dirty = true end @@ -165,12 +165,11 @@ function NetworkedAdapter:insert(slot, qty, toSlot, item, source) local function insert(remote) local amount = remote:insert(slot, qty, toSlot, source or self.direction) if amount > 0 then -debug('INS: %s(%d): %s[%d] -> %s', - item.name, amount, - source or self.localName, slot, remote.side) +--debug('INS: %s(%d): %s[%d] -> %s', +-- item.name, amount, +-- source or self.localName, slot, remote.side) self.dirty = true remote.dirty = true -debug('insert: ' .. (source or self.localName)) local entry = self.activity[key] or 0 self.activity[key] = entry + amount end diff --git a/milo/apis/turtle/craft.lua b/milo/apis/turtle/craft.lua index a2c1746..be62582 100644 --- a/milo/apis/turtle/craft.lua +++ b/milo/apis/turtle/craft.lua @@ -41,6 +41,13 @@ local function splitKey(key) return item end +local function makeRecipeKey(item) + if type(item) == 'string' then + item = splitKey(item) + end + return table.concat({ item.name, item.damage or 0, item.nbtHash }, ':') +end + function Craft.getItemCount(items, item) if type(item) == 'string' then item = splitKey(item) @@ -60,25 +67,25 @@ function Craft.getItemCount(items, item) return count end -local function machineCraft(recipe, qty, inventoryAdapter, machineName, oitem) - local key = recipe.result - local request = oitem.ingredients[key] - - if not request then - request = { - count = qty, - crafted = 0, - } - oitem.ingredients[recipe.result] = request +function Craft.sumIngredients(recipe) + -- produces { ['minecraft:planks:0'] = 8 } + local t = { } + 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 - request.crafted = request.crafted + (inventoryAdapter.activity[key] or 0) - if request.crafted >= request.count then - request.pending = nil -- TODO: check... - request.statusCode = Craft.STATUS_SUCCESS + 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 - return true end return end @@ -99,7 +106,7 @@ local function machineCraft(recipe, qty, inventoryAdapter, machineName, oitem) end for k,v in pairs(recipe.ingredients) do - if inventoryAdapter:provide(splitKey(v), qty, k, machineName) ~= qty then + if inventoryAdapter:provide(splitKey(v), count, k, machineName) ~= count then -- TODO: suck em back out request.status = 'unknown error' request.statusCode = Craft.STATUS_ERROR @@ -108,21 +115,10 @@ local function machineCraft(recipe, qty, inventoryAdapter, machineName, oitem) end request.status = 'processing' request.statusCode = Craft.STATUS_INFO - request.pending = true + request.pending = count * recipe.count end -local function turtleCraft(recipe, qty, inventoryAdapter, oitem) - local key = recipe.result - local request = oitem.ingredients[key] - - if not request then - request = { - count = qty, - crafted = 0, - } - oitem.ingredients[recipe.result] = request - end - +local function turtleCraft(recipe, inventoryAdapter, request, count) if not clearGrid(inventoryAdapter) then request.status = 'grid in use' request.statusCode = Craft.STATUS_ERROR @@ -131,92 +127,84 @@ local function turtleCraft(recipe, qty, inventoryAdapter, oitem) for k,v in pairs(recipe.ingredients) do local item = splitKey(v) - local provideQty = qty - --[[ - Turtles can only craft 1 item at a time when using a tool. - - if recipe.craftingTools and recipe.craftingTools[k] then - provideQty = 1 - end - ]]-- - if inventoryAdapter:provide(item, provideQty, k) ~= provideQty then + if inventoryAdapter:provide(item, count, k) ~= count then -- FIX: ingredients cannot be stacked ---debug('failed ' .. v .. ' - ' .. provideQty) request.status = 'unknown error' request.statusCode = Craft.STATUS_ERROR return end end + turtle.select(1) if turtle.craft() then request.status = nil request.statusCode = Craft.STATUS_SUCCESS + request.crafted = request.crafted + count * recipe.count return true end - request.status = 'failed to craft' + request.status = 'Failed to craft' request.statusCode = Craft.STATUS_ERROR end -function Craft.loadRecipes() - Craft.recipes = { } - - Util.merge(Craft.recipes, (Util.readTable(fs.combine(RECIPES_DIR, 'minecraft.db')) or { }).recipes) - - local config = Util.readTable('usr/config/recipeBooks.db') or { } - for _, book in pairs(config) do - local recipeFile = Util.readTable(book) - Util.merge(Craft.recipes, recipeFile.recipes) - end - - local recipes = Util.readTable(USER_RECIPES) or { } - Util.merge(Craft.recipes, recipes) - - for k,v in pairs(Craft.recipes) do - v.result = k - end - - Craft.machineLookup = Util.readTable(MACHINE_LOOKUP) or { } -end - -function Craft.sumIngredients(recipe) - -- produces { ['minecraft:planks:0'] = 8 } - local t = { } - 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 makeRecipeKey(item) - if type(item) == 'string' then - item = splitKey(item) - end - return table.concat({ item.name, item.damage or 0, item.nbtHash }, ':') -end - function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem) if type(recipe) == 'string' then recipe = Craft.recipes[recipe] if not recipe then - origItem.ingredients[recipe.result] = { - status = 'no recipe', - statusCode = Craft.STATUS_ERROR, - } return 0, 'No recipe' end end + 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 + return Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem) +end + +function Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem) local items = inventoryAdapter:listItems() if not items then - origItem.ingredients[recipe.result] = { - status = 'Inventory changed', - statusCode = Craft.STATUS_ERROR, - } return 0, 'Inventory changed' end - count = math.ceil(count / recipe.count) + 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) + return 0 + end + + local canCraft = Craft.getCraftableAmount(recipe, count, items, { }) + if canCraft == 0 then + + local resourceList = Craft.getResourceList(recipe, items, count) + 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 + 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 @@ -228,36 +216,33 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem) maxCount = math.min(maxCount, itemDB:getMaxCount(key)) if itemCount < need then local irecipe = Craft.findRecipe(key) - if irecipe then - local iqty = need - itemCount - local crafted = Craft.craftRecipe(irecipe, iqty, inventoryAdapter, origItem) - if crafted ~= iqty then - turtle.select(1) - return 0 - end + if not irecipe then + return 0 + end + local iqty = need - itemCount + local crafted = Craft.craftRecipeInternal(irecipe, iqty, inventoryAdapter, origItem) + if crafted ~= iqty then + return 0 end end end local crafted = 0 repeat - local requested = math.min(count, maxCount) - + local batch = math.min(count, maxCount) if Craft.machineLookup[recipe.result] then - if not machineCraft(recipe, requested, inventoryAdapter, Craft.machineLookup[recipe.result], origItem) then - break - end - else - if not turtleCraft(recipe, requested, inventoryAdapter, origItem) then + if not machineCraft(recipe, inventoryAdapter, + Craft.machineLookup[recipe.result], request, batch) then break end + elseif not turtleCraft(recipe, inventoryAdapter, request, batch) then + break end - crafted = crafted + requested + crafted = crafted + batch count = count - maxCount until count <= 0 - turtle.select(1) return crafted * recipe.count end @@ -378,6 +363,27 @@ function Craft.getCraftableAmount(inRecipe, count, items, missing) return sumItems(inRecipe, { }, math.ceil(count / inRecipe.count)) end +function Craft.loadRecipes() + Craft.recipes = { } + + Util.merge(Craft.recipes, (Util.readTable(fs.combine(RECIPES_DIR, 'minecraft.db')) or { }).recipes) + + local config = Util.readTable('usr/config/recipeBooks.db') or { } + for _, book in pairs(config) do + local recipeFile = Util.readTable(book) + Util.merge(Craft.recipes, recipeFile.recipes) + end + + local recipes = Util.readTable(USER_RECIPES) or { } + Util.merge(Craft.recipes, recipes) + + for k,v in pairs(Craft.recipes) do + v.result = k + end + + Craft.machineLookup = Util.readTable(MACHINE_LOOKUP) or { } +end + function Craft.canCraft(item, count, items) return Craft.getCraftableAmount(Craft.recipes[item], count, items) == count end diff --git a/milo/plugins/craftTask.lua b/milo/plugins/craftTask.lua index 44e413d..7cd499a 100644 --- a/milo/plugins/craftTask.lua +++ b/milo/plugins/craftTask.lua @@ -10,17 +10,9 @@ local craftTask = { priority = 70, } --- Craft -function craftTask:craftItem(recipe, originalItem, count) - local toCraft = Craft.getCraftableAmount(recipe, count, Milo:listItems(), { }) - local crafted = 0 - - if toCraft > 0 then - crafted = Craft.craftRecipe(recipe, toCraft, context.inventoryAdapter, originalItem) - Milo:clearGrid() - end - - return crafted +function craftTask:craftItem(recipe, item, count) + Craft.craftRecipe(recipe, count, context.inventoryAdapter, item) + Milo:clearGrid() end -- Craft as much as possible regardless if all ingredients are available @@ -91,24 +83,21 @@ function craftTask:forceCraftItem(inRecipe, originalItem, inCount) end function craftTask:craft(recipe, item) - item.status = nil - item.statusCode = nil - if Milo:isCraftingPaused() then return end if item.forceCrafting then - item.crafted = item.crafted + self:forceCraftItem(recipe, item, item.count - item.crafted) + self:forceCraftItem(recipe, item, item.count - item.crafted) else - item.crafted = item.crafted + self:craftItem(recipe, item, item.count - item.crafted) + self:craftItem(recipe, item, item.count - item.crafted) end end function craftTask:cycle() for _,key in pairs(Util.keys(context.craftingQueue)) do local item = context.craftingQueue[key] - if item.count > 0 then + if item.count - item.crafted > 0 then local recipe = Craft.recipes[key] if recipe then self:craft(recipe, item) diff --git a/milo/plugins/jobList.lua b/milo/plugins/jobList.lua index 4132abf..93ed3a8 100644 --- a/milo/plugins/jobList.lua +++ b/milo/plugins/jobList.lua @@ -20,7 +20,7 @@ local jobList = UI.Page { sortColumn = 'index', backgroundFocusColor = colors.black, columns = { - { heading = 'Qty', key = 'remaining', width = 6 }, + { heading = 'Qty', key = 'remaining', width = 4 }, { heading = 'Crafting', key = 'displayName', }, { heading = 'Status', key = 'status', }, { heading = 'Req', key = 'count', width = 3 }, @@ -41,13 +41,15 @@ function jobList:updateList(craftList) for _,v in pairs(craftList) do table.insert(t, v) v.index = #t - v.showRemining = true + v.showRemaining = true for k2,v2 in pairs(v.ingredients) do - table.insert(t, v2) - if not v2.displayName then - v2.displayName = itemDB:getName(k2) + if v2 ~= v then + table.insert(t, v2) + if not v2.displayName then + v2.displayName = itemDB:getName(k2) + end + v2.index = #t end - v2.index = #t end end self.grid:setValues(t) @@ -59,8 +61,10 @@ end function jobList.grid:getDisplayValues(row) row = Util.shallowCopy(row) - if row.showRemining then + if row.showRemaining then row.remaining = row.count - row.crafted + else + row.displayName = ' ' .. row.displayName end return row end diff --git a/milo/plugins/machineLearn.lua b/milo/plugins/machineLearn.lua index 36e35df..d005c92 100644 --- a/milo/plugins/machineLearn.lua +++ b/milo/plugins/machineLearn.lua @@ -116,6 +116,8 @@ function pages.confirmation:validate() end end + -- TODO: maxCount needs to be entered by user ? ie. brewing station can only do 1 at a time + local recipe = { count = result.count, ingredients = { }, @@ -131,12 +133,13 @@ function pages.confirmation:validate() -- save the recipe context.userRecipes[key] = recipe Util.writeTable(Milo.RECIPES_FILE, context.userRecipes) - Craft.loadRecipes() -- save the machine association Craft.machineLookup[key] = machine.name Util.writeTable(MACHINE_LOOKUP, Craft.machineLookup) + Craft.loadRecipes() + local listingPage = UI:getPage('listing') local displayName = itemDB:getName(result)