storage manager improvements

This commit is contained in:
kepler155c
2017-12-27 23:56:14 -05:00
parent 85c5f542a8
commit aa50b55ab1
8 changed files with 280 additions and 218 deletions

View File

@@ -53,9 +53,10 @@ end
function ChestAdapter:getCachedItemDetails(item, k) function ChestAdapter:getCachedItemDetails(item, k)
local detail = itemDB:get(item) local detail = itemDB:get(item)
if not detail then if not detail then
pcall(function() detail = self.getItemMeta(k) end) local s, m = pcall(function() detail = self.getItemMeta(k) end)
if not detail then if not detail then
debug(item) debug(item)
debug(m)
debug('no details') debug('no details')
-- error('Inventory has changed') -- error('Inventory has changed')
return return
@@ -89,16 +90,16 @@ end
-- provide a consolidated list of items -- provide a consolidated list of items
function ChestAdapter:listItems(throttle) function ChestAdapter:listItems(throttle)
self.cache = { } local cache = { }
local items = { } local items = { }
debug('listing')
throttle = throttle or Util.throttle() throttle = throttle or Util.throttle()
for k,v in pairs(self.list()) do for k,v in pairs(self.list()) do
if v.count > 0 then if v.count > 0 then
local key = table.concat({ v.name, v.damage, v.nbtHash }, ':') local key = table.concat({ v.name, v.damage, v.nbtHash }, ':')
local entry = self.cache[key] local entry = cache[key]
if not entry then if not entry then
entry = self:getCachedItemDetails(v, k) entry = self:getCachedItemDetails(v, k)
if not entry then if not entry then
@@ -107,7 +108,7 @@ function ChestAdapter:listItems(throttle)
return -- Inventory has changed return -- Inventory has changed
end end
entry.count = 0 entry.count = 0
self.cache[key] = entry cache[key] = entry
table.insert(items, entry) table.insert(items, entry)
end end
@@ -120,8 +121,13 @@ function ChestAdapter:listItems(throttle)
--read() --read()
itemDB:flush() itemDB:flush()
debug('done listing')
if not Util.empty(items) then
self.cache = cache
return items return items
end end
debug('its empty')
end
function ChestAdapter:getItemInfo(item) function ChestAdapter:getItemInfo(item)
if not self.cache then if not self.cache then
@@ -137,6 +143,13 @@ end
function ChestAdapter:craftItems() function ChestAdapter:craftItems()
end end
function ChestAdapter:getPercentUsed()
if self.cache then
return math.floor(Util.size(self.cache) / self.getDrawerCount() * 100)
end
return 0
end
function ChestAdapter:provide(item, qty, slot, direction) function ChestAdapter:provide(item, qty, slot, direction)
local s, m = pcall(function() local s, m = pcall(function()
local stacks = self.list() local stacks = self.list()
@@ -161,6 +174,30 @@ function ChestAdapter:provide(item, qty, slot, direction)
return s, m return s, m
end end
function ChestAdapter:eject(item, qty, direction)
local s, m = pcall(function()
local stacks = self.list()
for key,stack in Util.rpairs(stacks) do
if stack.name == item.name and
(not item.damage or stack.damage == item.damage) and
(not item.nbtHash or stack.nbtHash == item.nbtHash) then
local amount = math.min(qty, stack.count)
if amount > 0 then
self.drop(key, amount, direction)
end
qty = qty - amount
if qty <= 0 then
break
end
end
end
end)
if not s then
debug(m)
end
return s, m
end
function ChestAdapter:extract(slot, qty, toSlot) function ChestAdapter:extract(slot, qty, toSlot)
self.pushItems(self.direction, slot, qty, toSlot) self.pushItems(self.direction, slot, qty, toSlot)
end end

View File

@@ -78,6 +78,7 @@ function itemDB:get(key)
if key.nbtHash then if key.nbtHash then
item = self:get({ name = key.name, damage = key.damage }) item = self:get({ name = key.name, damage = key.damage })
if item and (item.maxDamage > 0 or item.damage == key.damage) then if item and (item.maxDamage > 0 or item.damage == key.damage) then
item = Util.shallowCopy(item)
item.nbtHash = key.nbtHash item.nbtHash = key.nbtHash
return item return item
end end

View File

@@ -66,6 +66,7 @@ local function turtleCraft(recipe, qty, inventoryAdapter)
inventoryAdapter:provide(item, provideQty, k) inventoryAdapter:provide(item, provideQty, k)
if turtle.getItemCount(k) == 0 then -- ~= qty then if turtle.getItemCount(k) == 0 then -- ~= qty then
-- FIX: ingredients cannot be stacked -- FIX: ingredients cannot be stacked
debug('failed ' .. v .. ' - ' .. provideQty)
return false return false
end end
end end
@@ -176,7 +177,7 @@ function Craft.getResourceList(inRecipe, items, inCount)
return summed return summed
end end
function Craft.getResourceList3(inRecipe, items, inCount) function Craft.getResourceList3(inRecipe, items, inCount, inventoryAdapter)
local summed = { } local summed = { }
local throttle = Util.throttle() local throttle = Util.throttle()
@@ -192,38 +193,35 @@ function Craft.getResourceList3(inRecipe, items, inCount)
summedItem = Util.shallowCopy(item) summedItem = Util.shallowCopy(item)
summedItem.recipe = Craft.recipes[key] summedItem.recipe = Craft.recipes[key]
summedItem.count = Craft.getItemCount(items, key) summedItem.count = Craft.getItemCount(items, key)
summedItem.ocount = summedItem.count summedItem.total = 0
summedItem.need = 0 summedItem.need = 0
summedItem.used = 0 summedItem.used = 0
summedItem.missing = 0
summedItem.craftable = 0 summedItem.craftable = 0
summed[key] = summedItem summed[key] = summedItem
end end
debug(key)
local total = count * iqty -- 4 * 2 local total = count * iqty -- 4 * 2
local used = math.min(summedItem.count, total) -- 5 local used = math.min(summedItem.count, total) -- 5
local need = total - used -- 3 local need = total - used -- 3
if recipe.craftingTools and recipe.craftingTools[key] then if recipe.craftingTools and recipe.craftingTools[key] then
summedItem.total = 1
if summedItem.count > 0 then if summedItem.count > 0 then
summedItem.used = 1 summedItem.used = 1
need = 0 need = 0
else else
summedItem.need = 1
need = 1 need = 1
end end
else else
summedItem.total = summedItem.total + total
summedItem.count = summedItem.count - used summedItem.count = summedItem.count - used
summedItem.used = summedItem.used + used summedItem.used = summedItem.used + used
summedItem.need = summedItem.need + need
end end
if need > 0 then if need > 0 then
if not summedItem.recipe then if not summedItem.recipe then
debug(summedItem)
debug({ total, used, need })
summedItem.missing = summedItem.missing + need
craftable = math.min(craftable, math.floor(used / iqty)) craftable = math.min(craftable, math.floor(used / iqty))
summedItem.need = summedItem.need + need
else else
local c = sumItems(summedItem.recipe, need) -- 4 local c = sumItems(summedItem.recipe, need) -- 4
craftable = math.min(craftable, math.floor((used + c) / iqty)) craftable = math.min(craftable, math.floor((used + c) / iqty))
@@ -232,12 +230,17 @@ debug({ total, used, need })
end end
end end
--[[
if inventoryAdapter and craftable > 0 then
craftable = Craft.craftRecipe(recipe, craftable, inventoryAdapter)
clearGrid(inventoryAdapter)
end
]]
return craftable * recipe.count return craftable * recipe.count
end end
sumItems(inRecipe, inCount) return sumItems(inRecipe, inCount), summed
return summed
end end
-- given a certain quantity, return how many of those can be crafted -- given a certain quantity, return how many of those can be crafted

View File

@@ -17,6 +17,8 @@ local device = _G.device
local multishell = _ENV.multishell local multishell = _ENV.multishell
local peripheral = _G.peripheral local peripheral = _G.peripheral
local term = _G.term local term = _G.term
local colors = _G.colors
local turtle = _G.turtle
multishell.setTitle(multishell.getCurrent(), 'Resource Manager') multishell.setTitle(multishell.getCurrent(), 'Resource Manager')
@@ -64,13 +66,10 @@ end
local RESOURCE_FILE = 'usr/config/resources.db' local RESOURCE_FILE = 'usr/config/resources.db'
local RECIPES_FILE = 'usr/config/recipes.db' local RECIPES_FILE = 'usr/config/recipes.db'
local colors = _G.colors
local turtle = _G.turtle
local craftingPaused = false local craftingPaused = false
local canCraft = not not duckAntenna or turtleChestAdapter:isValid() local canCraft = not not duckAntenna or turtleChestAdapter:isValid()
local userRecipes = Util.readTable(RECIPES_FILE) or { } local userRecipes = Util.readTable(RECIPES_FILE) or { }
local jobListGrid local jobList
local resources local resources
local demandCrafting = { } local demandCrafting = { }
@@ -134,6 +133,26 @@ local function mergeResources(t)
end end
end end
local function listItems()
local items
for _ = 1, 5 do
items = inventoryAdapter:listItems()
if items then
break
end
os.sleep(.25)
end
if not items then
-- error('could not check inventory')
term.clear()
print('rebooting in 5 secs')
os.sleep(5)
os.reboot()
end
return items
end
local function filterItems(t, filter, displayMode) local function filterItems(t, filter, displayMode)
if filter or displayMode > 0 then if filter or displayMode > 0 then
local r = { } local r = { }
@@ -201,6 +220,7 @@ local function craftItem(recipe, items, originalItem, craftList, count)
if not isGridClear() then if not isGridClear() then
if not clearGrid() then if not clearGrid() then
originalItem.status = 'Grid obstructed' originalItem.status = 'Grid obstructed'
return 0
end end
end end
@@ -223,7 +243,7 @@ local function craftItem(recipe, items, originalItem, craftList, count)
--debug('crafting ' .. key .. ' - ' .. need - has) --debug('crafting ' .. key .. ' - ' .. need - has)
--read() --read()
craftItem(iRecipe, items, originalItem, { }, math.ceil((need - has) / iRecipe.count)) craftItem(iRecipe, items, originalItem, { }, math.ceil((need - has) / iRecipe.count))
items = inventoryAdapter:listItems() items = listItems()
if not items then if not items then
error('list failed') error('list failed')
--return 0 --return 0
@@ -238,11 +258,11 @@ local function craftItem(recipe, items, originalItem, craftList, count)
if toCraft > 0 then if toCraft > 0 then
crafted = Craft.craftRecipe(recipe, toCraft, inventoryAdapter) crafted = Craft.craftRecipe(recipe, toCraft, inventoryAdapter)
clearGrid() clearGrid()
items = inventoryAdapter:listItems() items = listItems()
count = count - crafted count = count - crafted
end end
if count > 0 then if count > 0 and items then
local ingredients = Craft.getResourceList(recipe, items, count) local ingredients = Craft.getResourceList(recipe, items, count)
for _,ingredient in pairs(ingredients) do for _,ingredient in pairs(ingredients) do
--if not ingredient.recipe and ingredient.count < 0 then --if not ingredient.recipe and ingredient.count < 0 then
@@ -269,15 +289,9 @@ local function forceCraftItem(inRecipe, items, originalItem, craftList, inCount)
if not summedItem then if not summedItem then
summedItem = Util.shallowCopy(item) summedItem = Util.shallowCopy(item)
summedItem.recipe = Craft.recipes[key] summedItem.recipe = Craft.recipes[key]
if summedItem.recipe then
summedItem.recipe.key = key
end
summedItem.count = Craft.getItemCount(items, key) summedItem.count = Craft.getItemCount(items, key)
summedItem.ocount = summedItem.count
summedItem.need = 0 summedItem.need = 0
summedItem.used = 0 summedItem.used = 0
summedItem.missing = 0
summedItem.craftable = 0 summedItem.craftable = 0
summed[key] = summedItem summed[key] = summedItem
end end
@@ -297,43 +311,34 @@ end
else else
summedItem.count = summedItem.count - used summedItem.count = summedItem.count - used
summedItem.used = summedItem.used + used summedItem.used = summedItem.used + used
summedItem.need = summedItem.need + need
end end
if need > 0 then if need > 0 then
if not summedItem.recipe then if not summedItem.recipe then
summedItem.missing = summedItem.missing + need
craftable = math.min(craftable, math.floor(used / iqty)) craftable = math.min(craftable, math.floor(used / iqty))
summedItem.need = summedItem.need + need
else else
local c = sumItems(summedItem.recipe, need) -- 4 local c = sumItems(summedItem.recipe, need) -- 4
debug({ 'summed', total, used, need, c })
craftable = math.min(craftable, math.floor((used + c) / iqty)) craftable = math.min(craftable, math.floor((used + c) / iqty))
summedItem.craftable = summedItem.craftable + c summedItem.craftable = summedItem.craftable + c
end end
end end
end end
if craftable > 0 then if craftable > 0 then
debug('crafting ' .. recipe.key) craftable = Craft.craftRecipe(recipe, craftable, inventoryAdapter) / recipe.count
debug({ count, craftable })
_G._p = summed
craftable = Craft.craftRecipe(recipe, craftable, inventoryAdapter)
clearGrid() clearGrid()
debug('got ' .. craftable)
end end
return craftable * recipe.count return craftable * recipe.count
end end
local count = sumItems(inRecipe, inCount) local count = sumItems(inRecipe, inCount)
debug({ 'final', inCount, count })
-- local count, summed = Craft.getResourceList3(inRecipe, items, inCount, inventoryAdapter)
if count < inCount then if count < inCount then
for _,ingredient in pairs(summed) do for _,ingredient in pairs(summed) do
--if not ingredient.recipe and ingredient.count < 0 then if ingredient.need > 0 then
if ingredient.missing > 0 then addCraftingRequest(ingredient, craftList, ingredient.need)
addCraftingRequest(ingredient, craftList, ingredient.missing)
originalItem.status = string.format('%s missing', itemDB:getName(ingredient)) originalItem.status = string.format('%s missing', itemDB:getName(ingredient))
originalItem.statusCode = 'missing' originalItem.statusCode = 'missing'
end end
@@ -351,12 +356,11 @@ local function craftItems(craftList, allItems)
item.status = nil item.status = nil
item.statusCode = nil item.statusCode = nil
if item.forceCrafting then if item.forceCrafting then
recipe.key = key
item.crafted = forceCraftItem(recipe, allItems, item, craftList, item.count) item.crafted = forceCraftItem(recipe, allItems, item, craftList, item.count)
else else
item.crafted = craftItem(recipe, allItems, item, craftList, item.count) item.crafted = craftItem(recipe, allItems, item, craftList, item.count)
end end
allItems = inventoryAdapter:listItems() -- refresh counts allItems = listItems() -- refresh counts
if not allItems then if not allItems then
break break
end end
@@ -408,29 +412,43 @@ local function jobMonitor()
}) })
end end
jobListGrid = UI.Grid({ jobList = UI.Page {
parent = mon, parent = mon,
grid = UI.Grid {
sortColumn = 'displayName', sortColumn = 'displayName',
columns = { columns = {
{ heading = 'Qty', key = 'count', width = 6 }, { heading = 'Qty', key = 'count', width = 6 },
{ heading = 'Crafting', key = 'displayName', width = mon.width / 2 - 10 }, { heading = 'Crafting', key = 'displayName', width = mon.width / 2 - 10 },
{ heading = 'Status', key = 'status', width = mon.width - 10 }, { heading = 'Status', key = 'status', width = mon.width - 10 },
}, },
}) },
}
function jobListGrid:getRowTextColor(row, selected) function jobList:showError(msg)
self.grid:clear()
self.grid:centeredWrite(math.ceil(self.grid.height / 2), msg)
self:sync()
end
function jobList:updateList(craftList)
self.grid:setValues(craftList)
self.grid:update()
self:draw()
self:sync()
end
function jobList.grid:getRowTextColor(row, selected)
if row.status == '(no recipe)' then if row.status == '(no recipe)' then
return colors.red return colors.red
elseif row.statusCode == 'missing' then elseif row.statusCode == 'missing' then
return colors.yellow return colors.yellow
end end
return UI.Grid:getRowTextColor(row, selected) return UI.Grid:getRowTextColor(row, selected)
end end
jobListGrid:draw() jobList:enable()
jobListGrid:sync() jobList:draw()
jobList:sync()
end end
local function getAutocraftItems() local function getAutocraftItems()
@@ -496,6 +514,12 @@ local function watchResources(items)
item.damage = 0 item.damage = 0
end end
local key = uniqueKey(res) local key = uniqueKey(res)
if res.name == 'harvestcraft:applesauceitem' then
_G._p = items
debug('applesause')
error('applesauce')
end
craftList[key] = { craftList[key] = {
damage = item.damage, damage = item.damage,
nbtHash = item.nbtHash, nbtHash = item.nbtHash,
@@ -532,12 +556,6 @@ local function loadResources()
for _,k in pairs(Util.keys(resources)) do for _,k in pairs(Util.keys(resources)) do
local v = resources[k] local v = resources[k]
Util.merge(v, itemDB:splitKey(k)) Util.merge(v, itemDB:splitKey(k))
if not v.damage then
v.damage = 0
v.ignoreDamage = true
resources[k] = nil
resources[uniqueKey(v)] = v
end
end end
end end
@@ -942,7 +960,7 @@ function listingPage:enable()
end end
function listingPage:refresh() function listingPage:refresh()
self.allItems = inventoryAdapter:listItems() self.allItems = listItems()
mergeResources(self.allItems) mergeResources(self.allItems)
self:applyFilter() self:applyFilter()
end end
@@ -1123,7 +1141,7 @@ local craftPage = UI.Page {
title = "Information", title = "Information",
}, },
wizard = UI.Wizard { wizard = UI.Wizard {
y = 2, y = 2, ey = -2,
pages = { pages = {
quantity = UI.Window { quantity = UI.Window {
index = 1, index = 1,
@@ -1132,37 +1150,37 @@ local craftPage = UI.Page {
value = 'Quantity', value = 'Quantity',
}, },
count = UI.TextEntry { count = UI.TextEntry {
x = 15, x = 15, y = 3, width = 10,
y = 3,
width = 10,
limit = 6, limit = 6,
value = 1, value = 1,
}, },
ejectText = UI.Text {
x = 6, y = 4,
value = 'Eject',
},
eject = UI.Chooser {
x = 15, y = 4, width = 7,
value = true,
nochoice = 'No',
choices = {
{ name = 'Yes', value = true },
{ name = 'No', value = false },
},
},
}, },
resources = UI.Window { resources = UI.Window {
index = 2, index = 2,
grid = UI.Grid { grid = UI.Grid {
y = 2, ey = -4, y = 2, ey = -2,
columns = { columns = {
{ heading = 'Name', key = 'displayName' }, { heading = 'Name', key = 'displayName' },
{ heading = 'Qty', key = 'ocount' , width = 5 }, { heading = 'Total', key = 'total' , width = 4 },
{ heading = 'Used', key = 'used' , width = 4 }, { heading = 'Used', key = 'used' , width = 4 },
{ heading = 'Craf', key = 'craftable' , width = 4 },
{ heading = 'Need', key = 'need' , width = 4 }, { heading = 'Need', key = 'need' , width = 4 },
{ heading = 'Miss', key = 'missing' , width = 4 },
{ heading = 'cra', key = 'craftable' , width = 4 },
}, },
sortColumn = 'displayName', sortColumn = 'displayName',
}, },
accept = UI.Button {
x = -8, y = -2,
backgroundColor = colors.green,
text = '+', event = 'accept',
},
cancel = UI.Button {
x = -4, y = -2,
backgroundColor = colors.red,
text = '\215', event = 'cancel'
},
}, },
}, },
}, },
@@ -1171,28 +1189,53 @@ local craftPage = UI.Page {
function craftPage:enable(item) function craftPage:enable(item)
self.item = item self.item = item
self:focusFirst() self:focusFirst()
-- self.wizard.pages.quantity.eject.value = true
UI.Page.enable(self) UI.Page.enable(self)
end end
function craftPage.wizard.pages.resources.grid:getDisplayValues(row)
local function dv(v)
if v == 0 then
return ''
end
return Util.toBytes(v)
end
row = Util.shallowCopy(row)
row.total = Util.toBytes(row.total)
row.used = dv(row.used)
row.craftable = dv(row.craftable)
row.need = dv(row.need)
return row
end
function craftPage.wizard.pages.resources.grid:getRowTextColor(row, selected)
if row.need - row.craftable > 0 then
return colors.orange
end
return UI.Grid:getRowTextColor(row, selected)
end
function craftPage:eventHandler(event) function craftPage:eventHandler(event)
if event.type == 'cancel' then if event.type == 'cancel' then
UI:setPreviousPage() UI:setPreviousPage()
elseif event.type == 'enable_view' and event.view == self.wizard.pages.resources then elseif event.type == 'enable_view' and event.view == self.wizard.pages.resources then
local items = inventoryAdapter:listItems() local items = listItems()
local count = self.wizard.pages.quantity.count.value local count = self.wizard.pages.quantity.count.value
local recipe = Craft.recipes[uniqueKey(self.item)] local recipe = Craft.recipes[uniqueKey(self.item)]
local ingredients = Craft.getResourceList3(recipe, items, count) local _, ingredients = Craft.getResourceList3(recipe, items, count)
self.wizard.pages.resources.grid:setValues(ingredients)
for _,v in pairs(ingredients) do for _,v in pairs(ingredients) do
v.displayName = itemDB:getName(v) v.displayName = itemDB:getName(v)
end end
self.wizard.pages.resources.grid:setValues(ingredients)
elseif event.type == 'accept' then elseif event.type == 'accept' then
local key = uniqueKey(self.item) local key = uniqueKey(self.item)
demandCrafting[key] = Util.shallowCopy(self.item) demandCrafting[key] = Util.shallowCopy(self.item)
demandCrafting[key].count = tonumber(self.wizard.pages.quantity.count.value) demandCrafting[key].count = tonumber(self.wizard.pages.quantity.count.value)
demandCrafting[key].ocount = demandCrafting[key].count
demandCrafting[key].forceCrafting = true demandCrafting[key].forceCrafting = true
demandCrafting[key].eject = self.wizard.pages.quantity.eject.value == true
UI:setPreviousPage() UI:setPreviousPage()
else else
return UI.Page.eventHandler(self, event) return UI.Page.eventHandler(self, event)
@@ -1218,41 +1261,46 @@ jobMonitor()
Event.onInterval(5, function() Event.onInterval(5, function()
if not craftingPaused then if not craftingPaused then
local items = inventoryAdapter:listItems() local items = listItems()
if not items or Util.size(items) == 0 then if not items or Util.size(items) == 0 then
jobListGrid.parent:clear() jobList:showError('No items in system')
jobListGrid.parent:centeredWrite(math.ceil(jobListGrid.parent.height/2), 'No items in system')
jobListGrid:sync()
else else
local craftList = watchResources(items) local demandCrafted
craftItems(craftList, items)
if Util.size(demandCrafting) > 0 then if Util.size(demandCrafting) > 0 then
items = inventoryAdapter:listItems() items = listItems()
if items then if items then
local list = Util.shallowCopy(demandCrafting) demandCrafted = Util.shallowCopy(demandCrafting)
craftItems(list, items) craftItems(demandCrafted, items)
for k,v in pairs(list) do end
end
items = listItems()
local craftList
if items then
craftList = watchResources(items)
craftItems(craftList, items)
end
if demandCrafted and craftList then
for k,v in pairs(demandCrafted) do
craftList[k] = v craftList[k] = v
end end
end end
end
jobListGrid:setValues(craftList)
jobListGrid:update()
jobListGrid:draw()
jobListGrid:sync()
for _,key in pairs(Util.keys(demandCrafting)) do for _,key in pairs(Util.keys(demandCrafting)) do
local item = demandCrafting[key] local item = demandCrafting[key]
if item.crafted then if item.crafted then
item.count = item.count - item.crafted item.count = item.count - item.crafted
if item.count <= 0 then -- should check statusCode if item.count <= 0 then
demandCrafting[key] = nil demandCrafting[key] = nil
if item.eject then
inventoryAdapter:eject(item, item.ocount, inventoryAdapter.getMetadata().state.facing)
end end
end end
end end
end
jobList:updateList(craftList)
craftList = getAutocraftItems(items) -- autocrafted items don't show on job monitor craftList = getAutocraftItems(items) -- autocrafted items don't show on job monitor
craftItems(craftList, items) craftItems(craftList, items)
@@ -1261,4 +1309,4 @@ Event.onInterval(5, function()
end) end)
UI:pullEvents() UI:pullEvents()
jobListGrid.parent:reset() jobList.parent:reset()

View File

@@ -11,6 +11,7 @@ local Util = require('util')
local colors = _G.colors local colors = _G.colors
local multishell = _ENV.multishell local multishell = _ENV.multishell
local os = _G.os
local term = _G.term local term = _G.term
local turtle = _G.turtle local turtle = _G.turtle
@@ -32,7 +33,7 @@ local recipes = Util.readTable(RECIPES_FILE) or { }
local resources local resources
local machines = { } local machines = { }
local jobListGrid local jobListGrid
local lastItems local listing, docked = false, false
local function getItem(items, inItem, ignoreDamage) local function getItem(items, inItem, ignoreDamage)
for _,item in pairs(items) do for _,item in pairs(items) do
@@ -67,12 +68,9 @@ local function getItemWithQty(items, res, ignoreNbtHash)
if res.name == v.name and if res.name == v.name and
((not res.damage and v.maxDamage > 0) or res.damage == v.damage) and ((not res.damage and v.maxDamage > 0) or res.damage == v.damage) and
((ignoreNbtHash and v.nbtHash) or res.nbtHash == v.nbtHash) then ((ignoreNbtHash and v.nbtHash) or res.nbtHash == v.nbtHash) then
debug('found')
debug(v)
return v return v
end end
end end
debug('nope:' .. uniqueKey(res))
local item = Util.shallowCopy(res) local item = Util.shallowCopy(res)
item.count = 0 item.count = 0
item.maxCount = 1 item.maxCount = 1
@@ -137,7 +135,15 @@ local function clearGrid()
return true return true
end end
local function undock()
while listing do
os.sleep(.5)
end
docked = false
end
local function gotoMachine(machine) local function gotoMachine(machine)
undock()
for _ = 1, machine.index do for _ = 1, machine.index do
if not turtle.back() then if not turtle.back() then
return return
@@ -147,8 +153,38 @@ local function gotoMachine(machine)
return true return true
end end
local function craftItem(recipe, recipeKey, items, cItem, count) local function dock()
if not docked then
repeat until not turtle.forward() repeat until not turtle.forward()
end
docked = true
end
local function getItems()
while not docked do
os.sleep(.5)
end
listing = true
local items
for _ = 1, 5 do
items = inventoryAdapter:listItems()
if items then
break
end
end
if not items then
error('could not check inventory')
end
listing = false
return items
end
local function craftItem(recipe, recipeKey, items, cItem, count)
dock()
local resource = resources[recipeKey] local resource = resources[recipeKey]
if not resource or not resource.machine then if not resource or not resource.machine then
@@ -222,8 +258,7 @@ debug(item)
end end
end end
local function expandList(list) local function expandList(list, items)
local items = lastItems
local function getCraftable(recipe, count) local function getCraftable(recipe, count)
local maxSlots = math.floor(16 / Util.size(recipe.ingredients)) local maxSlots = math.floor(16 / Util.size(recipe.ingredients))
@@ -259,15 +294,6 @@ local function expandList(list)
return count return count
end end
--[[
list = { }
debug(getCraftable(recipes['minecraft:brick:0'], 512))
for key, item in pairs(list) do
debug(item.name .. ' : ' .. item.ocount .. ':' .. item.count)
end
read()
]]
for key, item in pairs(Util.shallowCopy(list)) do for key, item in pairs(Util.shallowCopy(list)) do
local recipe = recipes[key] local recipe = recipes[key]
@@ -280,21 +306,21 @@ read()
end end
local function craftItems(craftList) local function craftItems(craftList)
expandList(craftList) local items = getItems()
lastItems = inventoryAdapter:listItems() -- refresh counts expandList(craftList, items)
jobListGrid:update() jobListGrid:update()
jobListGrid:draw() jobListGrid:draw()
jobListGrid:sync() jobListGrid:sync()
for key, item in pairs(craftList) do for key, item in pairs(craftList) do
local recipe = recipes[key] local recipe = recipes[key]
if recipe then if recipe then
craftItem(recipe, key, lastItems, item, item.count) craftItem(recipe, key, items, item, item.count)
repeat until not turtle.forward() dock()
jobListGrid:update() jobListGrid:update()
jobListGrid:draw() jobListGrid:draw()
jobListGrid:sync() jobListGrid:sync()
clearGrid() clearGrid()
lastItems = inventoryAdapter:listItems() -- refresh counts items = getItems()
end end
end end
end end
@@ -357,7 +383,7 @@ local function saveResources()
end end
local function findMachines() local function findMachines()
repeat until not turtle.forward() dock()
local function getName(side) local function getName(side)
local p = Peripheral.getBySide(side) local p = Peripheral.getBySide(side)
@@ -370,7 +396,6 @@ local function findMachines()
end end
local index = 0 local index = 0
local t = { }
local function getMachine(dir) local function getMachine(dir)
local side = turtle.getAction(dir).side local side = turtle.getAction(dir).side
@@ -383,17 +408,10 @@ local function findMachines()
end end
end end
if machine and type(machine) == 'table' then if machine and type(machine) == 'table' then
local rawName = getName(side) or machine.name local name = getName(side) or machine.name
local name = rawName
local i = 1
while t[name] do
name = rawName .. '_' .. i
i = i + 1
end
t[name] = true
table.insert(machines, { table.insert(machines, {
name = name, name = name,
rawName = name,
index = index, index = index,
dir = dir, dir = dir,
order = #machines + 1 order = #machines + 1
@@ -405,13 +423,19 @@ local function findMachines()
getMachine('down') getMachine('down')
getMachine('up') getMachine('up')
index = index + 1 index = index + 1
undock()
until not turtle.back() until not turtle.back()
local mf = Util.readTable(MACHINES_FILE) or { } local mf = Util.readTable(MACHINES_FILE) or { }
for _,m in pairs(machines) do for _,m in pairs(machines) do
local m2 = Util.find(mf, 'order', m.order) local m2 = Util.find(mf, 'order', m.order)
if m2 then if m2 then
if not m2.rawName then
m2.rawName = m.rawName
end
if m.rawName == m2.rawName then
m.name = m2.name or m.name m.name = m2.name or m.name
end
m.empty = m2.empty m.empty = m2.empty
m.ignore = m2.ignore m.ignore = m2.ignore
end end
@@ -483,6 +507,10 @@ local itemPage = UI.Page {
text = 'Select', event= 'selectMachine', text = 'Select', event= 'selectMachine',
formLabel = 'Machine' formLabel = 'Machine'
}, },
info = UI.TextArea {
x = 2, ex = -2, y = 6, height = 3,
textColor = colors.gray,
},
button = UI.Button { button = UI.Button {
x = 2, y = 9, x = 2, y = 9,
text = 'Recipe', event = 'learn', text = 'Recipe', event = 'learn',
@@ -526,6 +554,16 @@ function itemPage:enable(item)
self:focusFirst() self:focusFirst()
end end
function itemPage.form.info:draw()
local recipe = recipes[uniqueKey(itemPage.item)]
if recipe and itemPage.item.machine then
self.value = string.format('Crafts %d using the %s machine',
recipe.count,
machines[itemPage.item.machine].name)
end
UI.TextArea.draw(self)
end
--[[ --[[
function itemPage.machines:eventHandler(event) function itemPage.machines:eventHandler(event)
if event.type == 'grid_focus_row' then if event.type == 'grid_focus_row' then
@@ -638,7 +676,7 @@ local learnPage = UI.Page {
function learnPage:enable(target) function learnPage:enable(target)
self.target = target self.target = target
self.allItems = lastItems self.allItems = getItems()
mergeResources(self.allItems) mergeResources(self.allItems)
self.filter.value = '' self.filter.value = ''
@@ -950,7 +988,7 @@ function listingPage:enable()
end end
function listingPage:refresh() function listingPage:refresh()
self.allItems = lastItems self.allItems = getItems()
mergeResources(self.allItems) mergeResources(self.allItems)
self:applyFilter() self:applyFilter()
end end
@@ -962,10 +1000,9 @@ end
findMachines() findMachines()
loadResources() loadResources()
repeat until not turtle.forward() dock()
clearGrid() clearGrid()
jobMonitor() jobMonitor()
lastItems = inventoryAdapter:listItems()
UI:setPages({ UI:setPages({
listing = listingPage, listing = listingPage,
@@ -982,15 +1019,15 @@ Event.on('turtle_abort', function()
end) end)
Event.onInterval(30, function() Event.onInterval(30, function()
repeat until not turtle.forward() dock()
if turtle.getFuelLevel() < 100 then if turtle.getFuelLevel() < 100 then
turtle.select(1) turtle.select(1)
inventoryAdapter:provide({ name = 'minecraft:coal', damage = 1 }, 16, 1) inventoryAdapter:provide({ name = 'minecraft:coal', damage = 1 }, 16, 1)
turtle.refuel() turtle.refuel()
end end
lastItems = inventoryAdapter:listItems() local items = getItems()
if lastItems then if items then
local craftList = watchResources(lastItems) local craftList = watchResources(items)
jobListGrid:setValues(craftList) jobListGrid:setValues(craftList)
jobListGrid:update() jobListGrid:update()

View File

@@ -209,7 +209,8 @@ local listingPage = UI.Page {
columns = { columns = {
{ heading = 'Name', key = 'displayName' , width = 22 }, { heading = 'Name', key = 'displayName' , width = 22 },
{ heading = 'Qty', key = 'count' , width = 5 }, { heading = 'Qty', key = 'count' , width = 5 },
{ heading = 'Max', key = 'limit' , width = 4 }, { heading = 'Min', key = 'limit' , width = 4 },
{ heading = 'Max', key = 'low' , width = 4 },
}, },
sortColumn = 'displayName', sortColumn = 'displayName',
}, },

View File

@@ -150,6 +150,7 @@ function changedPage:refresh()
end end
self.grid:setValues(changedItems) self.grid:setValues(changedItems)
debug(storage:getPercentUsed())
end end
self.grid:draw() self.grid:draw()
end end

View File

@@ -19,20 +19,6 @@
}, },
count = 1, count = 1,
}, },
[ "mysticalagriculture:supremium_essence:0" ] = {
ingredients = {
[ 10 ] = "mysticalagriculture:superium_essence:0",
[ 2 ] = "mysticalagriculture:superium_essence:0",
[ 5 ] = "mysticalagriculture:superium_essence:0",
[ 6 ] = "mysticalagriculture:infusion_crystal:*",
[ 7 ] = "mysticalagriculture:superium_essence:0",
},
craftingTools = {
[ "mysticalagriculture:infusion_crystal:*" ] = true,
},
maxCount = 1,
count = 1,
},
[ "mysticalagriculture:intermedium_ingot:0" ] = { [ "mysticalagriculture:intermedium_ingot:0" ] = {
ingredients = { ingredients = {
[ 10 ] = "mysticalagriculture:intermedium_essence:0", [ 10 ] = "mysticalagriculture:intermedium_essence:0",
@@ -57,20 +43,6 @@
}, },
count = 1, count = 1,
}, },
[ "mysticalagriculture:intermedium_essence:0" ] = {
ingredients = {
[ 10 ] = "mysticalagriculture:prudentium_essence:0",
[ 2 ] = "mysticalagriculture:prudentium_essence:0",
[ 5 ] = "mysticalagriculture:prudentium_essence:0",
[ 6 ] = "mysticalagriculture:infusion_crystal:*",
[ 7 ] = "mysticalagriculture:prudentium_essence:0",
},
craftingTools = {
[ "mysticalagriculture:infusion_crystal:*" ] = true,
},
maxCount = 1,
count = 1,
},
[ "mysticalagriculture:inferium_ingot:0" ] = { [ "mysticalagriculture:inferium_ingot:0" ] = {
ingredients = { ingredients = {
[ 10 ] = "mysticalagriculture:inferium_essence:0", [ 10 ] = "mysticalagriculture:inferium_essence:0",
@@ -109,20 +81,6 @@
}, },
count = 1, count = 1,
}, },
[ "mysticalagriculture:superium_essence:0" ] = {
ingredients = {
[ 10 ] = "mysticalagriculture:intermedium_essence:0",
[ 2 ] = "mysticalagriculture:intermedium_essence:0",
[ 5 ] = "mysticalagriculture:intermedium_essence:0",
[ 6 ] = "mysticalagriculture:infusion_crystal:*",
[ 7 ] = "mysticalagriculture:intermedium_essence:0",
},
craftingTools = {
[ "mysticalagriculture:infusion_crystal:*" ] = true,
},
maxCount = 1,
count = 1,
},
[ "mysticalagriculture:supremium_armor_core:0" ] = { [ "mysticalagriculture:supremium_armor_core:0" ] = {
ingredients = { ingredients = {
"mysticalagriculture:supremium_essence:0", "mysticalagriculture:supremium_essence:0",
@@ -151,20 +109,6 @@
}, },
count = 1, count = 1,
}, },
[ "mysticalagriculture:prudentium_essence:0" ] = {
ingredients = {
[ 10 ] = "mysticalagriculture:inferium_essence:0",
[ 2 ] = "mysticalagriculture:inferium_essence:0",
[ 5 ] = "mysticalagriculture:inferium_essence:0",
[ 6 ] = "mysticalagriculture:infusion_crystal:*",
[ 7 ] = "mysticalagriculture:inferium_essence:0",
},
craftingTools = {
[ "mysticalagriculture:infusion_crystal:*" ] = true,
},
maxCount = 1,
count = 1,
},
[ "mysticalagriculture:base_essence_ingot:0" ] = { [ "mysticalagriculture:base_essence_ingot:0" ] = {
ingredients = { ingredients = {
[ 10 ] = "mysticalagriculture:prosperity_shard:0", [ 10 ] = "mysticalagriculture:prosperity_shard:0",
@@ -175,16 +119,6 @@
}, },
count = 1, count = 1,
}, },
[ "mysticalagriculture:superium_ingot:0" ] = {
ingredients = {
[ 10 ] = "mysticalagriculture:superium_essence:0",
[ 2 ] = "mysticalagriculture:superium_essence:0",
[ 5 ] = "mysticalagriculture:superium_essence:0",
[ 6 ] = "mysticalagriculture:intermedium_ingot:0",
[ 7 ] = "mysticalagriculture:superium_essence:0",
},
count = 1,
},
[ "mysticalagriculture:tier2_inferium_seeds:0" ] = { [ "mysticalagriculture:tier2_inferium_seeds:0" ] = {
count = 1, count = 1,
ingredients = { ingredients = {