This commit is contained in:
kepler155c
2018-10-25 17:12:37 -04:00
parent 9f9dcafc60
commit ceb558dcff
5 changed files with 137 additions and 106 deletions

View File

@@ -8,10 +8,6 @@ local turtle = _G.turtle
local Milo = { local Milo = {
RECIPES_FILE = 'usr/config/recipes.db', RECIPES_FILE = 'usr/config/recipes.db',
RESOURCE_FILE = 'usr/config/resources.db', RESOURCE_FILE = 'usr/config/resources.db',
STATUS_INFO = 'info',
STATUS_WARNING = 'warning',
STATUS_ERROR = 'error',
} }
function Milo:init(context) function Milo:init(context)
@@ -26,8 +22,11 @@ function Milo:requestCrafting(item)
local key = Milo:uniqueKey(item) local key = Milo:uniqueKey(item)
if not self.context.craftingQueue[key] then if not self.context.craftingQueue[key] then
item.processing = { } item.ingredients = { }
item.requested = item.count --[[
count = requested amount,
crafted = amount that has been crafted
]]
item.crafted = 0 item.crafted = 0
self.context.craftingQueue[key] = item self.context.craftingQueue[key] = item
@@ -77,7 +76,7 @@ function Milo:resetCraftingStatus()
for _,key in pairs(Util.keys(self.context.craftingQueue)) do for _,key in pairs(Util.keys(self.context.craftingQueue)) do
local item = self.context.craftingQueue[key] local item = self.context.craftingQueue[key]
if item.crafted >= item.requested then if item.crafted >= item.count then
debug('removing:') debug('removing:')
debug(item) debug(item)
self.context.craftingQueue[key] = nil self.context.craftingQueue[key] = nil

View File

@@ -13,6 +13,7 @@ function NetworkedAdapter:init(args)
dirty = true, dirty = true,
listCount = 0, listCount = 0,
activity = { }, activity = { },
nameArray = { },
} }
Util.merge(self, defaults) Util.merge(self, defaults)
Util.merge(self, args) Util.merge(self, args)
@@ -29,6 +30,7 @@ listCount = 0,
local adapter = InventoryAdapter.wrap({ side = k, direction = self.localName }) local adapter = InventoryAdapter.wrap({ side = k, direction = self.localName })
if adapter then if adapter then
table.insert(self.remotes, adapter) table.insert(self.remotes, adapter)
self.nameArray[adapter.direction] = true
end end
end end
end end
@@ -47,6 +49,7 @@ listCount = 0,
return a.priority > b.priority return a.priority > b.priority
end) end)
end end
debug(self.nameArray)
end end
function NetworkedAdapter:isValid() function NetworkedAdapter:isValid()
@@ -116,13 +119,15 @@ function NetworkedAdapter:provide(item, qty, slot, direction)
for _, remote in ipairs(self.remotes) do for _, remote in ipairs(self.remotes) do
local amount = remote:provide(item, qty, slot, direction) local amount = remote:provide(item, qty, slot, direction)
if amount > 0 then if amount > 0 then
debug('%s(%d): %s -> %s%s', debug('EXT: %s(%d): %s -> %s%s',
item.name, amount, remote.side, direction or self.localName, item.name, amount, remote.side, direction or self.localName,
slot and string.format('[%d]', slot) or '') slot and string.format('[%d]', slot) or '')
self.dirty = true self.dirty = true
remote.dirty = true remote.dirty = true
local entry = self.activity[key] or 0 --if self.nameArray[direction or self.localName] then
self.activity[key] = entry + amount -- local entry = self.activity[key] or 0
-- self.activity[key] = entry + amount
--end
end end
qty = qty - amount qty = qty - amount
total = total + amount total = total + amount
@@ -168,13 +173,16 @@ function NetworkedAdapter:insert(slot, qty, toSlot, item, source)
local function insert(remote) local function insert(remote)
local amount = remote:insert(slot, qty, toSlot, source or self.direction) local amount = remote:insert(slot, qty, toSlot, source or self.direction)
if amount > 0 then if amount > 0 then
debug('%s(%d): %s[%d] -> %s', debug('INS: %s(%d): %s[%d] -> %s',
item.name, amount, item.name, amount,
source or self.localName, slot, remote.side) source or self.localName, slot, remote.side)
self.dirty = true self.dirty = true
remote.dirty = true remote.dirty = true
debug('insert: ' .. (source or self.localName))
--if self.nameArray[source or self.localName] then
local entry = self.activity[key] or 0 local entry = self.activity[key] or 0
self.activity[key] = entry + amount self.activity[key] = entry + amount
--end
end end
qty = qty - amount qty = qty - amount
total = total + amount total = total + amount

View File

@@ -9,7 +9,12 @@ local RECIPES_DIR = 'usr/etc/recipes'
local USER_RECIPES = 'usr/config/recipes.db' local USER_RECIPES = 'usr/config/recipes.db'
local MACHINE_LOOKUP = 'usr/config/machine_crafting.db' local MACHINE_LOOKUP = 'usr/config/machine_crafting.db'
local Craft = { } local Craft = {
STATUS_INFO = 'info',
STATUS_WARNING = 'warning',
STATUS_ERROR = 'error',
STATUS_SUCCESS = 'success',
}
local function clearGrid(inventoryAdapter) local function clearGrid(inventoryAdapter)
turtle.eachFilledSlot(function(slot) turtle.eachFilledSlot(function(slot)
@@ -57,11 +62,24 @@ end
local function machineCraft(recipe, qty, inventoryAdapter, machineName, oitem) local function machineCraft(recipe, qty, inventoryAdapter, machineName, oitem)
local key = recipe.result local key = recipe.result
local request = oitem.processing[key] local request = oitem.ingredients[key]
if request then
debug('requested: ' .. key)
if not request then
request = {
count = qty,
crafted = 0,
}
oitem.ingredients[recipe.result] = request
end
if request.pending then
request.crafted = request.crafted + (inventoryAdapter.activity[key] or 0) request.crafted = request.crafted + (inventoryAdapter.activity[key] or 0)
if request.crafted >= request.requested then debug({ request.crafted, request.count })
oitem.processing[key] = nil -- TODO: check... if request.crafted >= request.count then
request.pending = nil -- TODO: check...
request.statusCode = Craft.STATUS_SUCCESS
request.status = nil
return true return true
end end
return return
@@ -69,42 +87,50 @@ local function machineCraft(recipe, qty, inventoryAdapter, machineName, oitem)
local machine = device[machineName] local machine = device[machineName]
if not machine then if not machine then
debug('machine not found') request.status = 'machine not found'
oitem.processing[recipe.result] = { request.statusCode = Craft.STATUS_ERROR
status = 'machine not found' return
} end
else
for k in pairs(recipe.ingredients) do for k in pairs(recipe.ingredients) do
if machine.getItemMeta(k) then if machine.getItemMeta(k) then
oitem.processing[recipe.result] = { request.status = 'machine in use'
status = 'machine in use' request.statusCode = Craft.STATUS_WARNING
} return
debug('machine in use: ' .. k)
end end
end end
debug('processing ' .. recipe.result) debug('processing %s %d', key, qty)
for k,v in pairs(recipe.ingredients) do for k,v in pairs(recipe.ingredients) do
if inventoryAdapter:provide(splitKey(v), qty, k, machineName) ~= qty then if inventoryAdapter:provide(splitKey(v), qty, k, machineName) ~= qty then
-- TODO: suck em back out -- TODO: suck em back out
oitem.processing[recipe.result] = { request.status = 'unknown error'
status = 'unknown error' request.statusCode = Craft.STATUS_ERROR
} return
end end
end end
oitem.processing[recipe.result] = { request.status = 'processing'
status = 'processing', request.statusCode = Craft.STATUS_INFO
requested = qty, request.pending = true
crafted = 0,
}
end
end end
local function turtleCraft(recipe, qty, inventoryAdapter, oitem) local function turtleCraft(recipe, qty, inventoryAdapter, oitem)
if not clearGrid(inventoryAdapter) then local key = recipe.result
oitem.processing[recipe.result] = { local request = oitem.ingredients[key]
status = 'grid in use',
debug('requested: ' .. key)
if not request then
request = {
count = qty,
crafted = 0,
} }
oitem.ingredients[recipe.result] = request
end
if not clearGrid(inventoryAdapter) then
request.status = 'grid in use'
request.statusCode = Craft.STATUS_ERROR
return return
end end
@@ -121,19 +147,19 @@ local function turtleCraft(recipe, qty, inventoryAdapter, oitem)
if inventoryAdapter:provide(item, provideQty, k) ~= provideQty then if inventoryAdapter:provide(item, provideQty, k) ~= provideQty then
-- FIX: ingredients cannot be stacked -- FIX: ingredients cannot be stacked
--debug('failed ' .. v .. ' - ' .. provideQty) --debug('failed ' .. v .. ' - ' .. provideQty)
oitem.processing[recipe.result] = { request.status = 'unknown error'
status = 'unknown error', request.statusCode = Craft.STATUS_ERROR
}
return return
end end
end end
if turtle.craft() then if turtle.craft() then
request.status = nil
request.statusCode = Craft.STATUS_SUCCESS
return true return true
end end
oitem.processing[recipe.result] = { request.status = 'failed to craft'
status = 'processing', request.statusCode = Craft.STATUS_ERROR
}
end end
function Craft.loadRecipes() function Craft.loadRecipes()
@@ -178,8 +204,9 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem)
if type(recipe) == 'string' then if type(recipe) == 'string' then
recipe = Craft.recipes[recipe] recipe = Craft.recipes[recipe]
if not recipe then if not recipe then
origItem.processing[recipe.result] = { origItem.ingredients[recipe.result] = {
status = 'no recipe', status = 'no recipe',
statusCode = Craft.STATUS_ERROR,
} }
return 0, 'No recipe' return 0, 'No recipe'
end end
@@ -187,8 +214,9 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem)
local items = inventoryAdapter:listItems() local items = inventoryAdapter:listItems()
if not items then if not items then
origItem.processing[recipe.result] = { origItem.ingredients[recipe.result] = {
status = 'Inventory changed', status = 'Inventory changed',
statusCode = Craft.STATUS_ERROR,
} }
return 0, 'Inventory changed' return 0, 'Inventory changed'
end end
@@ -225,7 +253,7 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem)
break break
end end
else else
if not turtleCraft(recipe, requested, inventoryAdapter) then if not turtleCraft(recipe, requested, inventoryAdapter, origItem) then
break break
end end
end end

View File

@@ -12,13 +12,7 @@ local craftTask = {
-- Craft -- Craft
function craftTask:craftItem(recipe, originalItem, count) function craftTask:craftItem(recipe, originalItem, count)
local missing = { } local toCraft = Craft.getCraftableAmount(recipe, count, Milo:listItems(), { })
local toCraft = Craft.getCraftableAmount(recipe, count, Milo:listItems(), missing)
if missing.name then
originalItem.status = string.format('%s missing', itemDB:getName(missing.name))
originalItem.statusCode = Milo.STATUS_WARNING
end
local crafted = 0 local crafted = 0
if toCraft > 0 then if toCraft > 0 then
@@ -99,23 +93,15 @@ end
function craftTask:craft(recipe, item) function craftTask:craft(recipe, item)
item.status = nil item.status = nil
item.statusCode = nil item.statusCode = nil
item.crafted = 0
if Milo:isCraftingPaused() then if Milo:isCraftingPaused() then
return return
end end
-- todo: is this needed ?
if not Milo:clearGrid() then
item.status = 'Grid obstructed'
item.statusCode = Milo.STATUS_ERROR
return
end
if item.forceCrafting then if item.forceCrafting then
item.crafted = self:forceCraftItem(recipe, item, item.count) item.crafted = item.crafted + self:forceCraftItem(recipe, item, item.count - item.crafted)
else else
item.crafted = self:craftItem(recipe, item, item.count) item.crafted = item.crafted + self:craftItem(recipe, item, item.count - item.crafted)
end end
end end
@@ -126,12 +112,12 @@ function craftTask:cycle()
local recipe = Craft.recipes[key] local recipe = Craft.recipes[key]
if recipe then if recipe then
self:craft(recipe, item) self:craft(recipe, item)
if item.eject and item.crafted >= item.requested then if item.eject and item.crafted >= item.count then
Milo:eject(item, item.requested) Milo:eject(item, item.count)
end end
elseif not context.controllerAdapter then elseif not context.controllerAdapter then
item.status = '(no recipe)' item.status = '(no recipe)'
item.statusCode = Milo.STATUS_ERROR item.statusCode = Craft.STATUS_ERROR
item.crafted = 0 item.crafted = 0
end end
end end

View File

@@ -1,28 +1,30 @@
local Craft = require('turtle.craft')
local itemDB = require('itemDB')
local Milo = require('milo') local Milo = require('milo')
local Peripheral = require('peripheral') local Peripheral = require('peripheral')
local UI = require('ui') local UI = require('ui')
local Util = require('util')
local colors = _G.colors local colors = _G.colors
local context = Milo:getContext() local context = Milo:getContext()
local mon = Peripheral.lookup(context.config.monitor) or local mon = Peripheral.lookup(context.config.monitor) or
error('Monitor is not attached') error('Monitor is not attached')
local display = UI.Device {
device = mon,
textScale = .5,
}
local jobList = UI.Page { local jobList = UI.Page {
parent = display, parent = UI.Device {
device = mon,
textScale = .5,
},
grid = UI.Grid { grid = UI.Grid {
sortColumn = 'index', sortColumn = 'index',
backgroundFocusColor = colors.black, backgroundFocusColor = colors.black,
columns = { columns = {
{ heading = 'Qty', key = 'count', width = 6 }, { heading = 'Qty', key = 'remaining', width = 6 },
{ heading = 'Crafting', key = 'displayName', }, -- width = display.width / 2 - 10 }, { heading = 'Crafting', key = 'displayName', },
{ heading = 'Status', key = 'status', }, -- width = display.width - 10 }, { heading = 'Status', key = 'status', },
{ heading = 'Req', key = 'requested', width = 6 }, { heading = 'Req', key = 'count', width = 3 },
{ heading = 'Cra', key = 'crafted', width = 6 }, { heading = 'Cra', key = 'crafted', width = 3 },
}, },
}, },
} }
@@ -36,16 +38,16 @@ end
function jobList:updateList(craftList) function jobList:updateList(craftList)
if not Milo:isCraftingPaused() then if not Milo:isCraftingPaused() then
local t = { } local t = { }
local index = 1 for _,v in pairs(craftList) do
for k,v in pairs(craftList) do table.insert(t, v)
t[k] = v v.index = #t
v.index = index v.showRemining = true
index = index + 1 for k2,v2 in pairs(v.ingredients) do
for k2,v2 in pairs(v.processing) do table.insert(t, v2)
t[k2] = v2 if not v2.displayName then
v2.displayName = k2 v2.displayName = itemDB:getName(k2)
v2.index = index end
index = index + 1 v2.index = #t
end end
end end
self.grid:setValues(t) self.grid:setValues(t)
@@ -55,15 +57,23 @@ function jobList:updateList(craftList)
end end
end end
function jobList.grid:getRowTextColor(row, selected) function jobList.grid:getDisplayValues(row)
if row.statusCode == Milo.STATUS_ERROR then row = Util.shallowCopy(row)
return colors.red if row.showRemining then
elseif row.statusCode == Milo.STATUS_WARNING then row.remaining = row.count - row.crafted
return colors.yellow
elseif row.statusCode == Milo.STATUS_INFO then
return colors.lime
end end
return UI.Grid:getRowTextColor(row, selected) return row
end
function jobList.grid:getRowTextColor(row, selected)
local statusColor = {
[ Craft.STATUS_ERROR ] = colors.red,
[ Craft.STATUS_WARNING ] = colors.orange,
[ Craft.STATUS_INFO ] = colors.yellow,
[ Craft.STATUS_SUCCESS ] = colors.green,
}
return row.statusCode and statusColor[row.statusCode] or
UI.Grid:getRowTextColor(row, selected)
end end
jobList:enable() jobList:enable()