milo: simplify learn types + monitor resize

This commit is contained in:
kepler155c@gmail.com
2018-12-04 18:49:01 -05:00
parent e90e6cebdd
commit fff04ec01a
18 changed files with 225 additions and 305 deletions

View File

@@ -112,7 +112,6 @@ local context = {
state = { }, state = { },
craftingQueue = { }, craftingQueue = { },
learnTypes = { },
tasks = { }, tasks = { },
queue = { }, queue = { },

View File

@@ -1,7 +1,6 @@
local itemDB = require('itemDB') local itemDB = require('itemDB')
local Util = require('util') local Util = require('util')
local device = _G.device
local fs = _G.fs local fs = _G.fs
local turtle = _G.turtle local turtle = _G.turtle
@@ -81,8 +80,15 @@ local function machineCraft(recipe, storage, machineName, request, count, item)
return return
end end
if not machine.adapter or not machine.adapter.online then
request.status = 'machine offline'
request.statusCode = Craft.STATUS_ERROR
return
end
local list = machine.adapter.list()
for k in pairs(recipe.ingredients) do for k in pairs(recipe.ingredients) do
if machine.adapter.getItemMeta(k) then if list[k] then
request.status = 'machine in use' request.status = 'machine in use'
request.statusCode = Craft.STATUS_WARNING request.statusCode = Craft.STATUS_WARNING
return return

View File

@@ -27,4 +27,4 @@ while true do
end end
print('digging') print('digging')
turtle.digDown() turtle.digDown()
end end

90
milo/core/learnWizard.lua Normal file
View File

@@ -0,0 +1,90 @@
local Milo = require('milo')
local UI = require('ui')
local turtle = _G.turtle
local learnPage = UI.Page {
titleBar = UI.TitleBar { title = 'Learn Recipe' },
wizard = UI.Wizard {
y = 2, ey = -2,
pages = {
general = UI.Window {
index = 1,
grid = UI.ScrollingGrid {
x = 2, ex = -2, y = 2, ey = -2,
disableHeader = true,
columns = {
{ heading = 'Name', key = 'name'},
},
sortColumn = 'name',
},
},
},
},
notification = UI.Notification { },
}
local general = learnPage.wizard.pages.general
function general:validate()
Milo:setState('learnType', self.grid:getSelected().value)
return true
end
function learnPage:enable()
local t = { }
for _, page in pairs(self.wizard.pages) do
if page.validFor then
t[page.validFor] = {
name = page.validFor,
value = page.validFor,
}
end
end
general.grid:setValues(t)
general.grid:setSelected('name', Milo:getState('learnType') or '')
Milo:pauseCrafting({ key = 'gridInUse', msg = 'Crafting paused' })
self:focusFirst()
UI.Page.enable(self)
end
function learnPage:disable()
Milo:resumeCrafting({ key = 'gridInUse' })
return UI.Page.disable(self)
end
function learnPage.wizard:getPage(index)
local pages = { }
table.insert(pages, general)
local selected = general.grid:getSelected()
for _, page in pairs(self.pages) do
if page.validFor and (not selected or selected.value == page.validFor) then
table.insert(pages, page)
end
end
table.sort(pages, function(a, b)
return a.index < b.index
end)
return pages[index]
end
function learnPage:eventHandler(event)
if event.type == 'cancel' then
turtle.emptyInventory()
UI:setPreviousPage()
elseif event.type == 'form_invalid' or event.type == 'general_error' then
self.notification:error(event.message)
self:setFocus(event.field)
else
return UI.Page.eventHandler(self, event)
end
return true
end
UI:addPage('learnWizard', learnPage)

View File

@@ -234,7 +234,7 @@ function page:eventHandler(event)
Milo:setState('displayMode', displayMode) Milo:setState('displayMode', displayMode)
elseif event.type == 'learn' then elseif event.type == 'learn' then
UI:setPage('learn') UI:setPage('learnWizard')
elseif event.type == 'craft' then elseif event.type == 'craft' then
local item = self.grid:getSelected() local item = self.grid:getSelected()
@@ -242,7 +242,6 @@ function page:eventHandler(event)
if Craft.findRecipe(item) then -- or item.is_craftable then if Craft.findRecipe(item) then -- or item.is_craftable then
UI:setPage('craft', self.grid:getSelected()) UI:setPage('craft', self.grid:getSelected())
else else
Sound.play('entity.villager.no')
self.notification:error('No recipe defined') self.notification:error('No recipe defined')
end end
end end

View File

@@ -395,6 +395,10 @@ function nodeWizard.wizard.pages.general:enable()
self:focusFirst() self:focusFirst()
end end
function nodeWizard.wizard.pages.general:isValidFor()
return false
end
function nodeWizard.wizard.pages.general:showInventory(node) function nodeWizard.wizard.pages.general:showInventory(node)
local inventory local inventory
@@ -418,31 +422,28 @@ end
function nodeWizard.wizard.pages.general:validate() function nodeWizard.wizard.pages.general:validate()
if self.form:save() then if self.form:save() then
_G._p3 = nodeWizard.choices
_G._p4 = nodeWizard.node
nodeWizard.node.category = Util.find(nodeWizard.choices, 'value', nodeWizard.node.mtype).category nodeWizard.node.category = Util.find(nodeWizard.choices, 'value', nodeWizard.node.mtype).category
nodeWizard.nodePages = { }
table.insert(nodeWizard.nodePages, nodeWizard.wizard.pages.general)
for _, page in pairs(nodeWizard.wizard.pages) do for _, page in pairs(nodeWizard.wizard.pages) do
page.index = nil if not page.isValidFor or page:isValidFor(nodeWizard.node) then
end table.insert(nodeWizard.nodePages, page)
local index = 2 if page.setNode then
nodeWizard.wizard.pages.general.index = 1 page:setNode(nodeWizard.node)
nodeWizard.wizard.pages.confirmation.index = 2
for _, page in pairs(nodeWizard.wizard.pages) do
if not page.index then
if not page.isValidFor or page:isValidFor(nodeWizard.node) then
page.index = index
index = index + 1
if page.setNode then
page:setNode(nodeWizard.node)
end
end end
end end
end end
nodeWizard.wizard.pages.confirmation.index = index table.insert(nodeWizard.nodePages, nodeWizard.wizard.pages.confirmation)
return true return true
end end
end end
--[[ Confirmation ]]--
function nodeWizard.wizard.pages.confirmation:isValidFor()
return false
end
--[[ Wizard ]] -- --[[ Wizard ]] --
function nodeWizard:enable(node) function nodeWizard:enable(node)
local adapter = node.adapter local adapter = node.adapter
@@ -469,17 +470,17 @@ function nodeWizard:enable(node)
self.wizard.pages.general:showInventory(self.node) self.wizard.pages.general:showInventory(self.node)
-- restore indices self.nodePages = { }
for _, page in pairs(self.wizard.pages) do table.insert(self.nodePages, self.wizard.pages.general)
if not page.oindex then table.insert(self.nodePages, self.wizard.pages.confirmation)
page.oindex = page.index
end
page.index = page.oindex
end
UI.Page.enable(self) UI.Page.enable(self)
end end
function nodeWizard.wizard:getPage(index)
return nodeWizard.nodePages[index]
end
function nodeWizard:eventHandler(event) function nodeWizard:eventHandler(event)
if event.type == 'cancel' then if event.type == 'cancel' then
UI:setPreviousPage() UI:setPreviousPage()
@@ -500,6 +501,12 @@ function nodeWizard:eventHandler(event)
return true return true
end) end)
for _, page in pairs(self.nodePages) do
if page.saveNode then
page:saveNode(self.node)
end
end
Util.clear(context.storage.nodes[self.node.name]) Util.clear(context.storage.nodes[self.node.name])
Util.merge(context.storage.nodes[self.node.name], self.node) Util.merge(context.storage.nodes[self.node.name], self.node)
context.storage.nodes[self.node.name].adapter = adapter context.storage.nodes[self.node.name].adapter = adapter

View File

@@ -7,6 +7,7 @@ local Util = require('util')
local colors = _G.colors local colors = _G.colors
local context = Milo:getContext() local context = Milo:getContext()
local device = _G.device local device = _G.device
local os = _G.os
--[[ Configuration Page ]]-- --[[ Configuration Page ]]--
local template = local template =
@@ -30,10 +31,10 @@ local wizardPage = UI.Window {
formLabel = 'Font Size', formKey = 'textScale', formLabel = 'Font Size', formKey = 'textScale',
nochoice = 'Small', nochoice = 'Small',
choices = { choices = {
{ name = 'Small', value = .5, help = '(requires restart)', }, { name = 'Small', value = .5 },
{ name = 'Large', value = 1, help = '(requires restart)', }, { name = 'Large', value = 1 },
}, },
help = 'Adjust text scaling (requires restart)', help = 'Adjust text scaling',
}, },
}, },
} }
@@ -46,6 +47,10 @@ function wizardPage:validate()
return self.form:save() return self.form:save()
end end
function wizardPage:saveNode(node)
os.queueEvent('monitor_resize', node.name)
end
function wizardPage:isValidType(node) function wizardPage:isValidType(node)
local m = device[node.name] local m = device[node.name]
return m and m.type == 'monitor' and { return m and m.type == 'monitor' and {
@@ -71,8 +76,8 @@ local function createPage(node)
}, },
grid = UI.Grid { grid = UI.Grid {
columns = { columns = {
{ heading = 'Qty', key = 'count', width = 6 }, { heading = 'Qty', key = 'count', width = 5 },
{ heading = 'Change', key = 'change', width = 6 }, { heading = 'Change', key = 'change', width = 5 },
{ heading = 'Rate', key = 'rate', width = 6 }, { heading = 'Rate', key = 'rate', width = 6 },
{ heading = 'Name', key = 'displayName' }, { heading = 'Name', key = 'displayName' },
}, },
@@ -106,7 +111,6 @@ local function createPage(node)
function page:reset() function page:reset()
self.lastItems = nil self.lastItems = nil
self.grid:setValues({ }) self.grid:setValues({ })
self.grid:clear()
self.grid:draw() self.grid:draw()
end end
@@ -176,6 +180,20 @@ end
local pages = { } local pages = { }
Event.on('monitor_resize', function(_, side)
for node in context.storage:filterActive('activity') do
if node.name == side and pages[node.name] then
local p = pages[node.name]
p.parent:setTextScale(node.textScale or .5)
p.parent:resize()
p:resize()
p:draw()
p:sync()
break
end
end
end)
Event.on('monitor_touch', function(_, side) Event.on('monitor_touch', function(_, side)
local function filter(node) local function filter(node)
return node.adapter.name == side and pages[node.name] return node.adapter.name == side and pages[node.name]

View File

@@ -8,8 +8,8 @@ local template =
[[%sBrewing stands have the ability to automatically learn recipes.%s [[%sBrewing stands have the ability to automatically learn recipes.%s
Simply craft potions in the brewing stand as normal except for these conditions. Simply craft potions in the brewing stand as normal except for these conditions.
1. Place item in top slot first. 1. Place item in top slot FIRST.
2. At least 1 bottle must be placed in the first slot. 2. Place all 3 bottles.
When finished brewing, the recipe will be available upon refreshing. When finished brewing, the recipe will be available upon refreshing.

View File

@@ -3,7 +3,6 @@ local Milo = require('milo')
local Util = require('util') local Util = require('util')
local context = Milo:getContext() local context = Milo:getContext()
local turtle = _G.turtle
local craftTask = { local craftTask = {
name = 'crafting', name = 'crafting',

View File

@@ -63,10 +63,7 @@ end
function craftPage.wizard.pages.resources.grid:getDisplayValues(row) function craftPage.wizard.pages.resources.grid:getDisplayValues(row)
local function dv(v) local function dv(v)
if v == 0 then return v == 0 and '' or Util.toBytes(v)
return ''
end
return Util.toBytes(v)
end end
row = Util.shallowCopy(row) row = Util.shallowCopy(row)
row.total = Util.toBytes(row.total) row.total = Util.toBytes(row.total)

View File

@@ -8,6 +8,7 @@ local Util = require('util')
local colors = _G.colors local colors = _G.colors
local context = Milo:getContext() local context = Milo:getContext()
local device = _G.device local device = _G.device
local os = _G.os
--[[ Configuration Screen ]] --[[ Configuration Screen ]]
local wizardPage = UI.Window { local wizardPage = UI.Window {
@@ -28,10 +29,10 @@ local wizardPage = UI.Window {
formLabel = 'Font Size', formKey = 'textScale', formLabel = 'Font Size', formKey = 'textScale',
nochoice = 'Small', nochoice = 'Small',
choices = { choices = {
{ name = 'Small', value = .5, help = '(requires restart)', }, { name = 'Small', value = .5 },
{ name = 'Large', value = 1, help = '(requires restart)', }, { name = 'Large', value = 1 },
}, },
help = 'Adjust text scaling (requires restart)', help = 'Adjust text scaling',
}, },
}, },
} }
@@ -40,6 +41,10 @@ function wizardPage:setNode(node)
self.form:setValues(node) self.form:setValues(node)
end end
function wizardPage:saveNode(node)
os.queueEvent('monitor_resize', node.name)
end
function wizardPage:validate() function wizardPage:validate()
return self.form:save() return self.form:save()
end end
@@ -70,7 +75,6 @@ local function createPage(node)
}, },
grid = UI.Grid { grid = UI.Grid {
sortColumn = 'index', sortColumn = 'index',
backgroundFocusColor = colors.black,
columns = { columns = {
{ heading = 'Qty', key = 'remaining', width = 4 }, { heading = 'Qty', key = 'remaining', width = 4 },
{ heading = 'Crafting', key = 'displayName', }, { heading = 'Crafting', key = 'displayName', },
@@ -142,6 +146,20 @@ end
local pages = { } local pages = { }
Event.on('monitor_resize', function(_, side)
for node in context.storage:filterActive('jobs') do
if node.name == side and pages[node.name] then
local p = pages[node.name]
p.parent:setTextScale(node.textScale or .5)
p.parent:resize()
p:resize()
p:draw()
p:sync()
break
end
end
end)
Event.on({ 'milo_resume', 'milo_pause' }, function(_, reason) Event.on({ 'milo_resume', 'milo_pause' }, function(_, reason)
for node in context.storage:filterActive('jobs') do for node in context.storage:filterActive('jobs') do
local page = pages[node.name] local page = pages[node.name]

View File

@@ -1,67 +1 @@
local Milo = require('milo') -- moved
local UI = require('ui')
local context = Milo:getContext()
local turtle = _G.turtle
local learnPage = UI.Dialog {
height = 9, width = UI.term.width - 6,
title = 'Learn Recipe',
grid = UI.ScrollingGrid {
x = 2, ex = -2, y = 3, height = 4,
disableHeader = true,
columns = {
{ heading = 'Name', key = 'name'},
},
sortColumn = 'name',
},
cancel = UI.Button {
x = 3, y = -2,
text = 'Cancel', event = 'cancel'
},
accept = UI.Button {
ex = -3, y = -2,
width = 8,
text = 'Ok', event = 'accept',
},
}
function learnPage:enable()
local t = { }
for k in pairs(context.learnTypes) do
table.insert(t, {
name = k,
value = k,
})
end
self.grid:setValues(t)
self.grid:setSelected('name', Milo:getState('learnType') or '')
Milo:pauseCrafting({ key = 'gridInUse', msg = 'Crafting paused' })
self:focusFirst()
UI.Dialog.enable(self)
end
function learnPage:disable()
UI.Dialog.disable(self)
end
function learnPage:eventHandler(event)
if event.type == 'cancel' then
Milo:resumeCrafting({ key = 'gridInUse' })
turtle.emptyInventory()
UI:setPreviousPage()
elseif event.type == 'accept' or event.type == 'grid_select' then
local choice = self.grid:getSelected().value
Milo:setState('learnType', choice)
UI:setPage(context.learnTypes[choice])
else
return UI.Dialog.eventHandler(self, event)
end
return true
end
UI:addPage('learn', learnPage)

View File

@@ -5,46 +5,38 @@ local Util = require('util')
local colors = _G.colors local colors = _G.colors
local device = _G.device local device = _G.device
local turtle = _G.turtle
local context = Milo:getContext() local context = Milo:getContext()
local machine
local machineLearnWizard = UI.Page { local pages = {
titleBar = UI.TitleBar { title = 'Select machine' }, machines = UI.Window {
wizard = UI.Wizard { index = 2,
y = 2, ey = -2, validFor = 'Machine Processing',
pages = { grid = UI.ScrollingGrid {
machines = UI.Window { y = 2, ey = -2,
index = 1, columns = {
grid = UI.ScrollingGrid { { heading = 'Name', key = 'displayName' },
y = 2, ey = -2,
columns = {
{ heading = 'Name', key = 'displayName' },
},
sortColumn = 'displayName',
},
}, },
confirmation = UI.Window { sortColumn = 'displayName',
index = 2, },
notice = UI.TextArea { },
x = 2, ex = -2, y = 2, ey = -2, confirmation = UI.Window {
backgroundColor = colors.black, index = 3,
value = validFor = 'Machine Processing',
notice = UI.TextArea {
x = 2, ex = -2, y = 2, ey = -2,
backgroundColor = colors.black,
value =
[[Place items in slots according to the machine's inventory. [[Place items in slots according to the machine's inventory.
Place the result in the last slot of the turtle. Place the result in the last slot of the turtle.
Example: Slot 1 is the top slot in a furnace.]], Example: Slot 1 is the top slot in a furnace.]],
},
},
}, },
}, },
notification = UI.Notification { },
} }
local pages = machineLearnWizard.wizard.pages
local machine
function pages.machines.grid:getDisplayValues(row) function pages.machines.grid:getDisplayValues(row)
row = Util.shallowCopy(row) row = Util.shallowCopy(row)
row.displayName = row.displayName or row.name row.displayName = row.displayName or row.name
@@ -64,18 +56,18 @@ end
function pages.machines:validate() function pages.machines:validate()
local selected = self.grid:getSelected() local selected = self.grid:getSelected()
if not selected then if not selected then
machineLearnWizard.notification:error('No machines configured') self:emit({ type = 'general_error', message = 'No machines configured' })
return return
end end
machine = device[selected.name] machine = device[selected.name]
if not machine then if not machine then
machineLearnWizard.notification:error('Machine not found') self:emit({type = 'general_error', message = 'Machine not found' })
return return
end end
if not machine.size then if not machine.size then
machineLearnWizard.notification:error('Invalid machine') self:emit({ type = 'general_error', message = 'Invalid machine' })
return return
end end
@@ -90,19 +82,21 @@ function pages.confirmation:validate()
inventory[16] = nil inventory[16] = nil
if not result then if not result then
machineLearnWizard.notification:error('Result must be placed in last slot') self:emit({ type = 'general_error', message = 'Result must be placed in last slot' })
return return
end end
if Util.empty(inventory) then if Util.empty(inventory) then
machineLearnWizard.notification:error('Ingredients not present') self:emit({ type = 'general_error', message = 'Ingredients not present' })
return return
end end
for k in pairs(inventory) do for k in pairs(inventory) do
if k > slotCount then if k > slotCount then
machineLearnWizard.notification:error( self:emit({
'Slot ' .. k .. ' is not valid\nThe valid slots are 1 - ' .. machine.size()) type = 'general_error',
message = 'Slot ' .. k .. ' is not valid\nThe valid slots are 1 - ' .. machine.size()
})
return return
end end
end end
@@ -130,19 +124,4 @@ function pages.confirmation:validate()
return true return true
end end
function machineLearnWizard:disable() UI:getPage('learnWizard').wizard:add(pages)
Milo:resumeCrafting({ key = 'gridInUse' })
UI.Page.disable(self)
end
function machineLearnWizard:eventHandler(event)
if event.type == 'cancel' then
turtle.emptyInventory()
UI:setPage('listing')
else
return UI.Page.eventHandler(self, event)
end
return true
end
context.learnTypes['Machine processing'] = machineLearnWizard

View File

@@ -1,32 +0,0 @@
local Event = require('event')
local Milo = require('milo')
local device = _G.device
local RedstoneTask = {
name = 'redstone',
priority = 40,
}
function RedstoneTask:cycle(context)
for v in context.storage:filterActive({ 'mtype', 'machine' }) do
if v.redstone then
local ri = device[v.redstone.integrator]
if not ri or not v.adapter then
_debug(v.redstone)
else
local function conditionsSatisfied()
return not not next(v.adapter.list())
end
if conditionsSatisfied() then
ri.setOutput(v.redstone.side, true)
Event.onTimeout(.25, function()
ri.setOutput(v.redstone.side, false)
end)
end
end
end
end
end
Milo:registerTask(RedstoneTask)

View File

@@ -1,73 +0,0 @@
local UI = require('ui')
local colors = _G.colors
local device = _G.device
local dispenserView = UI.Window {
index = 10,
title = 'Redstone Control',
backgroundColor = colors.cyan,
form = UI.Form {
x = 1, y = 2, ex = -1, ey = -2,
manualControls = true,
[1] = UI.TextEntry {
formLabel = 'Interval', formKey = 'interval',
help = 'Pulse redstone if items are present',
limit = 6,
validate = 'numeric',
},
[2] = UI.Chooser {
formLabel = 'Integrator', formKey = 'integrator',
nochoice = 'disable',
help = 'Control via redstone',
},
[3] = UI.Chooser {
width = 10,
formLabel = 'Side', formKey = 'side',
choices = {
{ name = 'up', value = 'up' },
{ name = 'down', value = 'down' },
{ name = 'east', value = 'east' },
{ name = 'north', value = 'north' },
{ name = 'west', value = 'west' },
{ name = 'south', value = 'south' },
},
help = 'Output side',
},
},
}
function dispenserView:isValidFor(node)
if node.mtype == 'machine' then
local m = device[node.name]
--return m and m.type == 'minecraft:dispenser'
end
end
function dispenserView:enable()
UI.Window.enable(self)
self:focusFirst()
self.form[2].choices = { }
for _,m in pairs(device) do
if m.type == 'redstone_integrator' then
table.insert(self.form[2].choices, {
name = m.name,
value = m.name,
})
end
end
end
function dispenserView:validate()
return self.form:save()
end
function dispenserView:setNode(node)
if not node.redstone then
node.redstone = { }
end
self.form:setValues(node.redstone)
end
--UI:getPage('nodeWizard').wizard:add({ dispenser = dispenserView })

View File

@@ -75,7 +75,7 @@ local function client(socket)
if not data then if not data then
break break
end end
_G._debug(data) --_G._debug(data)
socket.co = coroutine.running() socket.co = coroutine.running()
if data.request == 'scan' then -- full scan of all inventories if data.request == 'scan' then -- full scan of all inventories

View File

@@ -38,15 +38,15 @@ local wizardPage = UI.Window {
} }
function wizardPage:setNode(node) function wizardPage:setNode(node)
self.node = node
self.form:setValues(node) self.form:setValues(node)
end end
function wizardPage:saveNode(node)
Sound.setVolume(node.volume)
end
function wizardPage:validate() function wizardPage:validate()
if self.form:save() then return self.form:save()
Sound.setVolume(self.node.volume)
return true
end
end end
function wizardPage:isValidType(node) function wizardPage:isValidType(node)

View File

@@ -104,30 +104,19 @@ local function learnRecipe()
return recipe return recipe
end end
local turtleLearnWizard = UI.Page { local pages = {
titleBar = UI.TitleBar { title = 'Learn a crafting recipe' }, turtleCraft = UI.Window {
wizard = UI.Wizard { index = 2,
y = 2, ey = -3, validFor = 'Turtle Crafting',
pages = { notice = UI.TextArea {
confirmation = UI.Window { x = 2, ex = -2, y = 2, ey = -2,
index = 1, value =
notice = UI.TextArea {
x = 2, ex = -2, y = 2, ey = -2,
value =
[[Place recipe in turtle!]], [[Place recipe in turtle!]],
},
},
}, },
}, },
notification = UI.Notification { },
} }
function turtleLearnWizard:disable() function pages.turtleCraft:validate()
Milo:resumeCrafting({ key = 'gridInUse' })
UI.Page.disable(self)
end
function turtleLearnWizard.wizard.pages.confirmation:validate()
local recipe, msg = learnRecipe(self) local recipe, msg = learnRecipe(self)
if recipe then if recipe then
@@ -139,18 +128,8 @@ function turtleLearnWizard.wizard.pages.confirmation:validate()
}) })
return true return true
else else
turtleLearnWizard.notification:error(msg) self:emit({ type = 'general_error', message = msg })
end end
end end
function turtleLearnWizard:eventHandler(event) UI:getPage('learnWizard').wizard:add(pages)
if event.type == 'cancel' then
turtle.emptyInventory()
UI:setPage('listing')
else
return UI.Page.eventHandler(self, event)
end
return true
end
context.learnTypes['Turtle crafting'] = turtleLearnWizard