This commit is contained in:
kepler155c
2017-10-18 19:54:28 -04:00
parent 1eb47cf3c8
commit 3622518b20
4 changed files with 162 additions and 139 deletions

View File

@@ -4,7 +4,11 @@ local Util = require('util')
local itemDB = TableDB({ fileName = 'usr/config/items.db' }) local itemDB = TableDB({ fileName = 'usr/config/items.db' })
local function splitKey(key, item) function itemDB:makeKey(item)
return { item.name, item.damage, item.nbtHash }
end
function itemDB:splitKey(key, item)
item = item or { } item = item or { }
@@ -45,15 +49,11 @@ function itemDB:add(key, item)
TableDB.add(self, key, item) TableDB.add(self, key, item)
end end
function itemDB:makeKey(item)
return { item.name, item.damage, item.nbtHash }
end
-- Accepts: "minecraft:stick:0" or { name = 'minecraft:stick', damage = 0 } -- Accepts: "minecraft:stick:0" or { name = 'minecraft:stick', damage = 0 }
function itemDB:getName(item) function itemDB:getName(item)
if type(item) == 'string' then if type(item) == 'string' then
item = splitKey(item) item = self:splitKey(item)
end end
local detail = self:get(self:makeKey(item)) local detail = self:get(self:makeKey(item))
@@ -70,7 +70,7 @@ function itemDB:load()
TableDB.load(self) TableDB.load(self)
for key,item in pairs(self.data) do for key,item in pairs(self.data) do
splitKey(key, item) self:splitKey(key, item)
item.maxDamage = item.maxDamage or 0 item.maxDamage = item.maxDamage or 0
item.maxCount = item.maxCount or 64 item.maxCount = item.maxCount or 64
end end

View File

@@ -298,14 +298,6 @@ function page.statusBar:draw()
UI.StatusBar.draw(self) UI.StatusBar.draw(self)
end end
function page.tabs.tabBar:selectTab(tabTitle)
if tabTitle then
config.tab = tabTitle
Config.update('Turtles', config)
return UI.TabBar.selectTab(self, tabTitle)
end
end
function page:showBlocks() function page:showBlocks()
local script = [[ local script = [[
@@ -328,6 +320,11 @@ end
function page:eventHandler(event) function page:eventHandler(event)
if event.type == 'quit' then if event.type == 'quit' then
UI:exitPullEvents() UI:exitPullEvents()
elseif event.type == 'tab_select' then
config.tab = event.button.text
Config.update('Turtles', config)
elseif event.type == 'button_press' then elseif event.type == 'button_press' then
if event.button.fn then if event.button.fn then
self:runFunction(event.button.fn, event.button.nowrap) self:runFunction(event.button.fn, event.button.nowrap)
@@ -369,18 +366,10 @@ Event.onInterval(1, function()
end end
end) end)
UI:setPage(page) if config.tab then
page.tabs.tabBar:selectTab(config.tab)
local lookup = {
Run = page.tabs.scripts,
Select = page.tabs.turtles,
Inv = page.tabs.inventory,
-- Mod = page.tabs.policy,
Action = page.tabs.action,
}
if lookup[options.tab.value] then
page.tabs:activateTab(lookup[options.tab.value].uid)
end end
UI:setPage(page)
UI:pullEvents() UI:pullEvents()

View File

@@ -644,7 +644,7 @@ end
function listingPage.statusBar:draw() function listingPage.statusBar:draw()
return UI.Window.draw(self) return UI.Window.draw(self)
end end
--[[
function listingPage.statusBar.filter:eventHandler(event) function listingPage.statusBar.filter:eventHandler(event)
if event.type == 'mouse_rightclick' then if event.type == 'mouse_rightclick' then
self.value = '' self.value = ''
@@ -657,6 +657,7 @@ function listingPage.statusBar.filter:eventHandler(event)
end end
return UI.TextEntry.eventHandler(self, event) return UI.TextEntry.eventHandler(self, event)
end end
]]
function listingPage:eventHandler(event) function listingPage:eventHandler(event)
if event.type == 'quit' then if event.type == 'quit' then

View File

@@ -5,6 +5,7 @@ local Event = require('event')
local itemDB = require('itemDB') local itemDB = require('itemDB')
local Peripheral = require('peripheral') local Peripheral = require('peripheral')
local UI = require('ui') local UI = require('ui')
local Terminal = require('terminal')
local Util = require('util') local Util = require('util')
local colors = _G.colors local colors = _G.colors
@@ -23,6 +24,7 @@ local craftingPaused = false
local recipes = Util.readTable(RECIPES_FILE) or { } local recipes = Util.readTable(RECIPES_FILE) or { }
local resources local resources
local machines = { } local machines = { }
local jobListGrid
local function getItem(items, inItem, ignoreDamage) local function getItem(items, inItem, ignoreDamage)
for _,item in pairs(items) do for _,item in pairs(items) do
@@ -36,17 +38,6 @@ local function getItem(items, inItem, ignoreDamage)
end end
end end
local function splitKey(key)
local t = Util.split(key, '(.-):')
local item = { }
if #t[#t] > 8 then
item.nbtHash = table.remove(t)
end
item.damage = tonumber(table.remove(t))
item.name = table.concat(t, ':')
return item
end
local function uniqueKey(item) local function uniqueKey(item)
return table.concat({ item.name, item.damage, item.nbtHash }, ':') return table.concat({ item.name, item.damage, item.nbtHash }, ':')
end end
@@ -64,7 +55,7 @@ local function mergeResources(t)
end end
for k in pairs(recipes) do for k in pairs(recipes) do
local v = splitKey(k) local v = itemDB:splitKey(k)
local item = getItem(t, v) local item = getItem(t, v)
if not item then if not item then
item = Util.shallowCopy(v) item = Util.shallowCopy(v)
@@ -110,13 +101,20 @@ local function clearGrid()
end end
local function gotoMachine(machine) local function gotoMachine(machine)
local _, k = Util.find(machines, 'name', machine)
if not k then local index
error('Unable to locate machine: ' .. tostring(machine)) if type(machine) == 'number' then
index = machine
else
local _, k = Util.find(machines, 'name', machine)
if not k then
error('Unable to locate machine: ' .. tostring(machine))
end
index = k - 1
end end
for _ = 1, k - 1 do for _ = 1, index do
turtle.back() turtle.back()
end end
end end
@@ -125,9 +123,9 @@ local function canCraft(recipe, items, count)
count = math.ceil(count / recipe.count) count = math.ceil(count / recipe.count)
for key,qty in pairs(recipe.ingredients) do for key,qty in pairs(recipe.ingredients) do
local item = getItem(items, splitKey(key)) local item = getItem(items, itemDB:splitKey(key))
if not item then if not item then
return 0 return 0, itemDB:getName(key)
end end
local x = math.min(math.floor(item.count / qty), item.maxCount) local x = math.min(math.floor(item.count / qty), item.maxCount)
count = math.min(x, count) count = math.min(x, count)
@@ -136,32 +134,44 @@ local function canCraft(recipe, items, count)
return count return count
end end
local function craftItem(recipe, items, count) local function craftItem(recipe, items, cItem, count)
repeat until not turtle.forward() repeat until not turtle.forward()
count = canCraft(recipe, items, count)
local missing
count, missing = canCraft(recipe, items, count)
if count == 0 then if count == 0 then
cItem.status = 'missing ' .. missing
return false return false
end end
local slot = 1 local slot = 1
for key,qty in pairs(recipe.ingredients) do for key,qty in pairs(recipe.ingredients) do
local item = splitKey(key) local item = itemDB:splitKey(key)
inventoryAdapter:provide(item, count * qty, slot) inventoryAdapter:provide(item, count * qty, slot)
if turtle.getItemCount(slot) ~= count then if turtle.getItemCount(slot) ~= count then
cItem.status = 'failed'
return false return false
end end
slot = slot + 1 slot = slot + 1
end end
gotoMachine(recipe.machine) gotoMachine(recipe.machine)
turtle.emptyInventory(turtle.dropDown) turtle.emptyInventory(turtle.dropDown)
if #turtle.getFilledSlots() ~= 0 then
cItem.status = 'machine busy'
else
cItem.status = 'crafting'
end
end end
local function craftItems(craftList, items) local function craftItems(craftList, items)
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, items, item.count) craftItem(recipe, items, item, item.count)
repeat until not turtle.forward() repeat until not turtle.forward()
jobListGrid:update()
jobListGrid:draw()
jobListGrid:sync()
clearGrid() clearGrid()
items = inventoryAdapter:listItems() -- refresh counts items = inventoryAdapter:listItems() -- refresh counts
end end
@@ -223,7 +233,7 @@ end
local function loadResources() local function loadResources()
resources = Util.readTable(RESOURCE_FILE) or { } resources = Util.readTable(RESOURCE_FILE) or { }
for k,v in pairs(resources) do for k,v in pairs(resources) do
Util.merge(v, splitKey(k)) Util.merge(v, itemDB:splitKey(k))
end end
end end
@@ -248,6 +258,10 @@ local function findMachines()
local t = { } local t = { }
repeat repeat
local machine = Peripheral.getBySide('bottom') local machine = Peripheral.getBySide('bottom')
if not machine then
local _
_, machine = turtle.inspectDown()
end
if machine then if machine then
local name = machine.name local name = machine.name
local i = 1 local i = 1
@@ -258,7 +272,6 @@ local function findMachines()
t[name] = true t[name] = true
table.insert(machines, { table.insert(machines, {
value = name,
name = name, name = name,
index = index, index = index,
}) })
@@ -267,6 +280,44 @@ local function findMachines()
until not turtle.back() until not turtle.back()
end end
local function jobMonitor()
local mon = Peripheral.getBySide('top')
if mon then
mon = UI.Device({
device = mon,
textScale = .5,
})
else
mon = UI.Device({
device = Terminal.getNullTerm(term.current())
})
end
jobListGrid = UI.Grid({
parent = mon,
sortColumn = 'displayName',
columns = {
{ heading = 'Qty', key = 'count', width = 6 },
{ heading = 'Crafting', key = 'displayName', width = mon.width / 2 - 10 },
{ heading = 'Status', key = 'status', width = mon.width - 10 },
},
})
function jobListGrid:getRowTextColor(row, selected)
if row.status == '(no recipe)'then
return colors.red
elseif row.statusCode == 'missing' then
return colors.yellow
end
return UI.Grid:getRowTextColor(row, selected)
end
jobListGrid:draw()
jobListGrid:sync()
end
local itemPage = UI.Page { local itemPage = UI.Page {
titleBar = UI.TitleBar { titleBar = UI.TitleBar {
title = 'Limit Resource', title = 'Limit Resource',
@@ -346,66 +397,54 @@ function itemPage:eventHandler(event)
end end
local learnPage = UI.Page { local learnPage = UI.Page {
scroller = UI.WindowScroller { wizard = UI.Wizard {
ey = -2, pages = {
[2] = UI.Window { screen1 = UI.Window {
ingredients = UI.ScrollingGrid { index = 1,
y = 2, height = 3, ingredients = UI.ScrollingGrid {
values = machines, y = 2, height = 3,
disableHeader = true, values = machines,
columns = { disableHeader = true,
{ heading = 'Name', key = 'displayName', width = 31 }, columns = {
{ heading = 'Qty', key = 'count' , width = 5 }, { heading = 'Name', key = 'displayName', width = 31 },
{ heading = 'Qty', key = 'count' , width = 5 },
},
sortColumn = 'displayName',
}, },
sortColumn = 'displayName', grid = UI.ScrollingGrid {
}, y = 6, height = 5,
grid = UI.ScrollingGrid { disableHeader = true,
y = 6, height = 5, columns = {
disableHeader = true, { heading = 'Name', key = 'displayName', width = 31 },
columns = { { heading = 'Qty', key = 'count' , width = 5 },
{ heading = 'Name', key = 'displayName', width = 31 }, },
{ heading = 'Qty', key = 'count' , width = 5 }, sortColumn = 'displayName',
},
filter = UI.TextEntry {
x = 20, ex = -2, y = 5,
limit = 50,
shadowText = 'filter',
backgroundColor = colors.lightGray,
backgroundFocusColor = colors.lightGray,
}, },
sortColumn = 'displayName',
}, },
filter = UI.TextEntry { screen2 = UI.Window {
x = 20, ex = -2, y = 5, index = 2,
limit = 50, machine = UI.ScrollingGrid {
shadowText = 'filter', y = 2, height = 7,
backgroundColor = colors.lightGray, values = machines,
backgroundFocusColor = colors.lightGray, disableHeader = true,
columns = {
{ heading = 'Name', key = 'name'},
},
sortColumn = 'index',
},
count = UI.TextEntry {
x = 11, y = -2, width = 5,
limit = 50,
},
}, },
}, },
[1] = UI.Window {
machine = UI.ScrollingGrid {
y = 2, height = 7,
values = machines,
disableHeader = true,
columns = {
{ heading = 'Name', key = 'name'},
},
sortColumn = 'index',
},
count = UI.TextEntry {
x = 11, y = -2, width = 5,
limit = 50,
},
},
},
cancelButton = UI.Button {
x = 2, y = -1,
text = ' Cancel ',
event = 'cancel',
},
previousButton = UI.Button {
x = -20, y = -1,
text = '<< Back',
event = 'previous',
},
nextButton = UI.Button {
x = -10, y = -1,
text = 'Next >>',
event = 'next',
}, },
} }
@@ -414,11 +453,8 @@ function learnPage:enable(target)
self.allItems = inventoryAdapter:listItems() self.allItems = inventoryAdapter:listItems()
mergeResources(self.allItems) mergeResources(self.allItems)
self.scroller.screen1 = self.scroller.children[2] local screen1 = self.wizard.screen1
self.scroller.screen2 = self.scroller.children[1] local screen2 = self.wizard.screen2
local screen1 = self.scroller.screen1
local screen2 = self.scroller.screen2
screen1.filter.value = '' screen1.filter.value = ''
screen1.grid.values = self.allItems screen1.grid.values = self.allItems
@@ -427,13 +463,14 @@ function learnPage:enable(target)
screen2.count.value = 1 screen2.count.value = 1
screen2.machine:update() screen2.machine:update()
self.nextButton.text = 'Next >>'
self.nextButton.event = 'next'
if target.has_recipe then if target.has_recipe then
local recipe = recipes[uniqueKey(target)] local recipe = recipes[uniqueKey(target)]
screen2.count.value = recipe.count screen2.count.value = recipe.count
screen2.machine:setIndex(select(2, Util.find(machines, 'name', recipe.machine))) if type(recipe.machine) == 'number' then
screen2.machine:setIndex(select(2, Util.find(machines, 'index', recipe.machine)))
else
screen2.machine:setIndex(select(2, Util.find(machines, 'name', recipe.machine)))
end
for k,v in pairs(recipe.ingredients) do for k,v in pairs(recipe.ingredients) do
screen1.ingredients.values[k] = screen1.ingredients.values[k] =
{ name = k, count = v, displayName = itemDB:getName(k) } { name = k, count = v, displayName = itemDB:getName(k) }
@@ -442,24 +479,20 @@ function learnPage:enable(target)
screen1.ingredients:update() screen1.ingredients:update()
UI.Page.enable(self) UI.Page.enable(self)
self.previousButton:disable()
end end
function learnPage.scroller.screen1:enable() function learnPage.wizard.screen1:enable()
UI.Window.enable(self) UI.Window.enable(self)
self.filter:focus() self:setFocus(self.filter)
learnPage.previousButton:enable()
learnPage.nextButton.text = 'Accept'
learnPage.nextButton.event = 'accept'
end end
function learnPage.scroller.screen1:draw() function learnPage.wizard.screen1:draw()
UI.Window.draw(self) UI.Window.draw(self)
self:write(2, 1, 'Ingredients', nil, colors.yellow) self:write(2, 1, 'Ingredients', nil, colors.yellow)
self:write(2, 5, 'Inventory', nil, colors.yellow) self:write(2, 5, 'Inventory', nil, colors.yellow)
end end
function learnPage.scroller.screen1:eventHandler(event) function learnPage.wizard.screen1:eventHandler(event)
if event.type == 'text_change' then if event.type == 'text_change' then
local t = filterItems(learnPage.allItems, event.text) local t = filterItems(learnPage.allItems, event.text)
self.grid:setValues(t) self.grid:setValues(t)
@@ -470,11 +503,12 @@ function learnPage.scroller.screen1:eventHandler(event)
return true return true
end end
function learnPage.scroller.screen2:enable() function learnPage.wizard.screen2:enable()
UI.Window.enable(self) UI.Window.enable(self)
end self:setFocus(self.count)
end
function learnPage.scroller.screen2:draw() function learnPage.wizard.screen2:draw()
UI.Window.draw(self) UI.Window.draw(self)
self:centeredWrite(1, 'Machine', nil, colors.yellow) self:centeredWrite(1, 'Machine', nil, colors.yellow)
self:write(2, 10, 'Produces') self:write(2, 10, 'Produces')
@@ -484,23 +518,15 @@ function learnPage:eventHandler(event)
if event.type == 'cancel' then if event.type == 'cancel' then
UI:setPreviousPage() UI:setPreviousPage()
elseif event.type == 'next' then
self.scroller:nextChild()
self:draw()
elseif event.type == 'previous' then
self.scroller:prevChild()
self:draw()
elseif event.type == 'accept' then elseif event.type == 'accept' then
local screen1 = self.scroller.screen1 local screen1 = self.wizard.screen1
local screen2 = self.scroller.screen2 local screen2 = self.wizard.screen2
local recipe = { local recipe = {
count = tonumber(screen2.count.value) or 1, count = tonumber(screen2.count.value) or 1,
ingredients = { }, ingredients = { },
machine = screen2.machine:getSelected().name, machine = screen2.machine:getSelected().index,
} }
for key, item in pairs(screen1.ingredients.values) do for key, item in pairs(screen1.ingredients.values) do
recipe.ingredients[key] = item.count recipe.ingredients[key] = item.count
@@ -511,7 +537,7 @@ function learnPage:eventHandler(event)
UI:setPreviousPage() UI:setPreviousPage()
elseif event.type == 'grid_select' then elseif event.type == 'grid_select' then
local screen1 = self.scroller.screen1 local screen1 = self.wizard.screen1
if event.element == screen1.grid then if event.element == screen1.grid then
local key = uniqueKey(event.selected) local key = uniqueKey(event.selected)
@@ -689,6 +715,7 @@ listingPage:setFocus(listingPage.statusBar.filter)
findMachines() findMachines()
repeat until not turtle.forward() repeat until not turtle.forward()
clearGrid() clearGrid()
jobMonitor()
Event.on('turtle_abort', function() Event.on('turtle_abort', function()
UI:exitPullEvents() UI:exitPullEvents()
@@ -704,6 +731,12 @@ Event.onInterval(30, function()
end end
local items = inventoryAdapter:listItems() local items = inventoryAdapter:listItems()
local craftList = watchResources(items) local craftList = watchResources(items)
jobListGrid:setValues(craftList)
jobListGrid:update()
jobListGrid:draw()
jobListGrid:sync()
craftItems(craftList, items) craftItems(craftList, items)
end end
end) end)