milo wip
This commit is contained in:
@@ -8,10 +8,6 @@ local turtle = _G.turtle
|
||||
local Milo = {
|
||||
RECIPES_FILE = 'usr/config/recipes.db',
|
||||
RESOURCE_FILE = 'usr/config/resources.db',
|
||||
|
||||
STATUS_INFO = 'info',
|
||||
STATUS_WARNING = 'warning',
|
||||
STATUS_ERROR = 'error',
|
||||
}
|
||||
|
||||
function Milo:init(context)
|
||||
@@ -26,8 +22,11 @@ function Milo:requestCrafting(item)
|
||||
local key = Milo:uniqueKey(item)
|
||||
|
||||
if not self.context.craftingQueue[key] then
|
||||
item.processing = { }
|
||||
item.requested = item.count
|
||||
item.ingredients = { }
|
||||
--[[
|
||||
count = requested amount,
|
||||
crafted = amount that has been crafted
|
||||
]]
|
||||
item.crafted = 0
|
||||
|
||||
self.context.craftingQueue[key] = item
|
||||
@@ -77,7 +76,7 @@ function Milo:resetCraftingStatus()
|
||||
|
||||
for _,key in pairs(Util.keys(self.context.craftingQueue)) do
|
||||
local item = self.context.craftingQueue[key]
|
||||
if item.crafted >= item.requested then
|
||||
if item.crafted >= item.count then
|
||||
debug('removing:')
|
||||
debug(item)
|
||||
self.context.craftingQueue[key] = nil
|
||||
|
||||
@@ -13,6 +13,7 @@ function NetworkedAdapter:init(args)
|
||||
dirty = true,
|
||||
listCount = 0,
|
||||
activity = { },
|
||||
nameArray = { },
|
||||
}
|
||||
Util.merge(self, defaults)
|
||||
Util.merge(self, args)
|
||||
@@ -29,6 +30,7 @@ listCount = 0,
|
||||
local adapter = InventoryAdapter.wrap({ side = k, direction = self.localName })
|
||||
if adapter then
|
||||
table.insert(self.remotes, adapter)
|
||||
self.nameArray[adapter.direction] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -47,6 +49,7 @@ listCount = 0,
|
||||
return a.priority > b.priority
|
||||
end)
|
||||
end
|
||||
debug(self.nameArray)
|
||||
end
|
||||
|
||||
function NetworkedAdapter:isValid()
|
||||
@@ -116,13 +119,15 @@ 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('%s(%d): %s -> %s%s',
|
||||
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
|
||||
local entry = self.activity[key] or 0
|
||||
self.activity[key] = entry + amount
|
||||
--if self.nameArray[direction or self.localName] then
|
||||
-- local entry = self.activity[key] or 0
|
||||
-- self.activity[key] = entry + amount
|
||||
--end
|
||||
end
|
||||
qty = qty - amount
|
||||
total = total + amount
|
||||
@@ -168,13 +173,16 @@ 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('%s(%d): %s[%d] -> %s',
|
||||
debug('INS: %s(%d): %s[%d] -> %s',
|
||||
item.name, amount,
|
||||
source or self.localName, slot, remote.side)
|
||||
self.dirty = true
|
||||
remote.dirty = true
|
||||
local entry = self.activity[key] or 0
|
||||
self.activity[key] = entry + amount
|
||||
debug('insert: ' .. (source or self.localName))
|
||||
--if self.nameArray[source or self.localName] then
|
||||
local entry = self.activity[key] or 0
|
||||
self.activity[key] = entry + amount
|
||||
--end
|
||||
end
|
||||
qty = qty - amount
|
||||
total = total + amount
|
||||
|
||||
@@ -9,7 +9,12 @@ local RECIPES_DIR = 'usr/etc/recipes'
|
||||
local USER_RECIPES = 'usr/config/recipes.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)
|
||||
turtle.eachFilledSlot(function(slot)
|
||||
@@ -57,11 +62,24 @@ end
|
||||
|
||||
local function machineCraft(recipe, qty, inventoryAdapter, machineName, oitem)
|
||||
local key = recipe.result
|
||||
local request = oitem.processing[key]
|
||||
if request then
|
||||
local request = oitem.ingredients[key]
|
||||
|
||||
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)
|
||||
if request.crafted >= request.requested then
|
||||
oitem.processing[key] = nil -- TODO: check...
|
||||
debug({ request.crafted, request.count })
|
||||
if request.crafted >= request.count then
|
||||
request.pending = nil -- TODO: check...
|
||||
request.statusCode = Craft.STATUS_SUCCESS
|
||||
request.status = nil
|
||||
return true
|
||||
end
|
||||
return
|
||||
@@ -69,42 +87,50 @@ local function machineCraft(recipe, qty, inventoryAdapter, machineName, oitem)
|
||||
|
||||
local machine = device[machineName]
|
||||
if not machine then
|
||||
debug('machine not found')
|
||||
oitem.processing[recipe.result] = {
|
||||
status = 'machine not found'
|
||||
}
|
||||
else
|
||||
for k in pairs(recipe.ingredients) do
|
||||
if machine.getItemMeta(k) then
|
||||
oitem.processing[recipe.result] = {
|
||||
status = 'machine in use'
|
||||
}
|
||||
debug('machine in use: ' .. k)
|
||||
end
|
||||
end
|
||||
|
||||
debug('processing ' .. recipe.result)
|
||||
for k,v in pairs(recipe.ingredients) do
|
||||
if inventoryAdapter:provide(splitKey(v), qty, k, machineName) ~= qty then
|
||||
-- TODO: suck em back out
|
||||
oitem.processing[recipe.result] = {
|
||||
status = 'unknown error'
|
||||
}
|
||||
end
|
||||
end
|
||||
oitem.processing[recipe.result] = {
|
||||
status = 'processing',
|
||||
requested = qty,
|
||||
crafted = 0,
|
||||
}
|
||||
request.status = 'machine not found'
|
||||
request.statusCode = Craft.STATUS_ERROR
|
||||
return
|
||||
end
|
||||
|
||||
for k in pairs(recipe.ingredients) do
|
||||
if machine.getItemMeta(k) then
|
||||
request.status = 'machine in use'
|
||||
request.statusCode = Craft.STATUS_WARNING
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
debug('processing %s %d', key, qty)
|
||||
|
||||
for k,v in pairs(recipe.ingredients) do
|
||||
if inventoryAdapter:provide(splitKey(v), qty, k, machineName) ~= qty then
|
||||
-- TODO: suck em back out
|
||||
request.status = 'unknown error'
|
||||
request.statusCode = Craft.STATUS_ERROR
|
||||
return
|
||||
end
|
||||
end
|
||||
request.status = 'processing'
|
||||
request.statusCode = Craft.STATUS_INFO
|
||||
request.pending = true
|
||||
end
|
||||
|
||||
local function turtleCraft(recipe, qty, inventoryAdapter, oitem)
|
||||
if not clearGrid(inventoryAdapter) then
|
||||
oitem.processing[recipe.result] = {
|
||||
status = 'grid in use',
|
||||
local key = recipe.result
|
||||
local request = oitem.ingredients[key]
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
@@ -121,19 +147,19 @@ local function turtleCraft(recipe, qty, inventoryAdapter, oitem)
|
||||
if inventoryAdapter:provide(item, provideQty, k) ~= provideQty then
|
||||
-- FIX: ingredients cannot be stacked
|
||||
--debug('failed ' .. v .. ' - ' .. provideQty)
|
||||
oitem.processing[recipe.result] = {
|
||||
status = 'unknown error',
|
||||
}
|
||||
request.status = 'unknown error'
|
||||
request.statusCode = Craft.STATUS_ERROR
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if turtle.craft() then
|
||||
request.status = nil
|
||||
request.statusCode = Craft.STATUS_SUCCESS
|
||||
return true
|
||||
end
|
||||
oitem.processing[recipe.result] = {
|
||||
status = 'processing',
|
||||
}
|
||||
request.status = 'failed to craft'
|
||||
request.statusCode = Craft.STATUS_ERROR
|
||||
end
|
||||
|
||||
function Craft.loadRecipes()
|
||||
@@ -178,8 +204,9 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem)
|
||||
if type(recipe) == 'string' then
|
||||
recipe = Craft.recipes[recipe]
|
||||
if not recipe then
|
||||
origItem.processing[recipe.result] = {
|
||||
origItem.ingredients[recipe.result] = {
|
||||
status = 'no recipe',
|
||||
statusCode = Craft.STATUS_ERROR,
|
||||
}
|
||||
return 0, 'No recipe'
|
||||
end
|
||||
@@ -187,8 +214,9 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem)
|
||||
|
||||
local items = inventoryAdapter:listItems()
|
||||
if not items then
|
||||
origItem.processing[recipe.result] = {
|
||||
origItem.ingredients[recipe.result] = {
|
||||
status = 'Inventory changed',
|
||||
statusCode = Craft.STATUS_ERROR,
|
||||
}
|
||||
return 0, 'Inventory changed'
|
||||
end
|
||||
@@ -225,7 +253,7 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem)
|
||||
break
|
||||
end
|
||||
else
|
||||
if not turtleCraft(recipe, requested, inventoryAdapter) then
|
||||
if not turtleCraft(recipe, requested, inventoryAdapter, origItem) then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,13 +12,7 @@ local craftTask = {
|
||||
|
||||
-- Craft
|
||||
function craftTask:craftItem(recipe, originalItem, count)
|
||||
local missing = { }
|
||||
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 toCraft = Craft.getCraftableAmount(recipe, count, Milo:listItems(), { })
|
||||
local crafted = 0
|
||||
|
||||
if toCraft > 0 then
|
||||
@@ -99,23 +93,15 @@ end
|
||||
function craftTask:craft(recipe, item)
|
||||
item.status = nil
|
||||
item.statusCode = nil
|
||||
item.crafted = 0
|
||||
|
||||
if Milo:isCraftingPaused() then
|
||||
return
|
||||
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
|
||||
item.crafted = self:forceCraftItem(recipe, item, item.count)
|
||||
item.crafted = item.crafted + self:forceCraftItem(recipe, item, item.count - item.crafted)
|
||||
else
|
||||
item.crafted = self:craftItem(recipe, item, item.count)
|
||||
item.crafted = item.crafted + self:craftItem(recipe, item, item.count - item.crafted)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -126,12 +112,12 @@ function craftTask:cycle()
|
||||
local recipe = Craft.recipes[key]
|
||||
if recipe then
|
||||
self:craft(recipe, item)
|
||||
if item.eject and item.crafted >= item.requested then
|
||||
Milo:eject(item, item.requested)
|
||||
if item.eject and item.crafted >= item.count then
|
||||
Milo:eject(item, item.count)
|
||||
end
|
||||
elseif not context.controllerAdapter then
|
||||
item.status = '(no recipe)'
|
||||
item.statusCode = Milo.STATUS_ERROR
|
||||
item.statusCode = Craft.STATUS_ERROR
|
||||
item.crafted = 0
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
local Craft = require('turtle.craft')
|
||||
local itemDB = require('itemDB')
|
||||
local Milo = require('milo')
|
||||
local Peripheral = require('peripheral')
|
||||
local UI = require('ui')
|
||||
local Util = require('util')
|
||||
|
||||
local colors = _G.colors
|
||||
|
||||
local context = Milo:getContext()
|
||||
local mon = Peripheral.lookup(context.config.monitor) or
|
||||
error('Monitor is not attached')
|
||||
local display = UI.Device {
|
||||
device = mon,
|
||||
textScale = .5,
|
||||
}
|
||||
|
||||
local jobList = UI.Page {
|
||||
parent = display,
|
||||
parent = UI.Device {
|
||||
device = mon,
|
||||
textScale = .5,
|
||||
},
|
||||
grid = UI.Grid {
|
||||
sortColumn = 'index',
|
||||
backgroundFocusColor = colors.black,
|
||||
columns = {
|
||||
{ heading = 'Qty', key = 'count', width = 6 },
|
||||
{ heading = 'Crafting', key = 'displayName', }, -- width = display.width / 2 - 10 },
|
||||
{ heading = 'Status', key = 'status', }, -- width = display.width - 10 },
|
||||
{ heading = 'Req', key = 'requested', width = 6 },
|
||||
{ heading = 'Cra', key = 'crafted', width = 6 },
|
||||
{ heading = 'Qty', key = 'remaining', width = 6 },
|
||||
{ heading = 'Crafting', key = 'displayName', },
|
||||
{ heading = 'Status', key = 'status', },
|
||||
{ heading = 'Req', key = 'count', width = 3 },
|
||||
{ heading = 'Cra', key = 'crafted', width = 3 },
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -36,16 +38,16 @@ end
|
||||
function jobList:updateList(craftList)
|
||||
if not Milo:isCraftingPaused() then
|
||||
local t = { }
|
||||
local index = 1
|
||||
for k,v in pairs(craftList) do
|
||||
t[k] = v
|
||||
v.index = index
|
||||
index = index + 1
|
||||
for k2,v2 in pairs(v.processing) do
|
||||
t[k2] = v2
|
||||
v2.displayName = k2
|
||||
v2.index = index
|
||||
index = index + 1
|
||||
for _,v in pairs(craftList) do
|
||||
table.insert(t, v)
|
||||
v.index = #t
|
||||
v.showRemining = true
|
||||
for k2,v2 in pairs(v.ingredients) do
|
||||
table.insert(t, v2)
|
||||
if not v2.displayName then
|
||||
v2.displayName = itemDB:getName(k2)
|
||||
end
|
||||
v2.index = #t
|
||||
end
|
||||
end
|
||||
self.grid:setValues(t)
|
||||
@@ -55,15 +57,23 @@ function jobList:updateList(craftList)
|
||||
end
|
||||
end
|
||||
|
||||
function jobList.grid:getRowTextColor(row, selected)
|
||||
if row.statusCode == Milo.STATUS_ERROR then
|
||||
return colors.red
|
||||
elseif row.statusCode == Milo.STATUS_WARNING then
|
||||
return colors.yellow
|
||||
elseif row.statusCode == Milo.STATUS_INFO then
|
||||
return colors.lime
|
||||
function jobList.grid:getDisplayValues(row)
|
||||
row = Util.shallowCopy(row)
|
||||
if row.showRemining then
|
||||
row.remaining = row.count - row.crafted
|
||||
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
|
||||
|
||||
jobList:enable()
|
||||
|
||||
Reference in New Issue
Block a user