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 = { },
craftingQueue = { },
learnTypes = { },
tasks = { },
queue = { },

View File

@@ -1,7 +1,6 @@
local itemDB = require('itemDB')
local Util = require('util')
local device = _G.device
local fs = _G.fs
local turtle = _G.turtle
@@ -81,8 +80,15 @@ local function machineCraft(recipe, storage, machineName, request, count, item)
return
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
if machine.adapter.getItemMeta(k) then
if list[k] then
request.status = 'machine in use'
request.statusCode = Craft.STATUS_WARNING
return

View File

@@ -27,4 +27,4 @@ while true do
end
print('digging')
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)
elseif event.type == 'learn' then
UI:setPage('learn')
UI:setPage('learnWizard')
elseif event.type == 'craft' then
local item = self.grid:getSelected()
@@ -242,7 +242,6 @@ function page:eventHandler(event)
if Craft.findRecipe(item) then -- or item.is_craftable then
UI:setPage('craft', self.grid:getSelected())
else
Sound.play('entity.villager.no')
self.notification:error('No recipe defined')
end
end

View File

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

View File

@@ -7,6 +7,7 @@ local Util = require('util')
local colors = _G.colors
local context = Milo:getContext()
local device = _G.device
local os = _G.os
--[[ Configuration Page ]]--
local template =
@@ -30,10 +31,10 @@ local wizardPage = UI.Window {
formLabel = 'Font Size', formKey = 'textScale',
nochoice = 'Small',
choices = {
{ name = 'Small', value = .5, help = '(requires restart)', },
{ name = 'Large', value = 1, help = '(requires restart)', },
{ name = 'Small', value = .5 },
{ 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()
end
function wizardPage:saveNode(node)
os.queueEvent('monitor_resize', node.name)
end
function wizardPage:isValidType(node)
local m = device[node.name]
return m and m.type == 'monitor' and {
@@ -71,8 +76,8 @@ local function createPage(node)
},
grid = UI.Grid {
columns = {
{ heading = 'Qty', key = 'count', width = 6 },
{ heading = 'Change', key = 'change', width = 6 },
{ heading = 'Qty', key = 'count', width = 5 },
{ heading = 'Change', key = 'change', width = 5 },
{ heading = 'Rate', key = 'rate', width = 6 },
{ heading = 'Name', key = 'displayName' },
},
@@ -106,7 +111,6 @@ local function createPage(node)
function page:reset()
self.lastItems = nil
self.grid:setValues({ })
self.grid:clear()
self.grid:draw()
end
@@ -176,6 +180,20 @@ end
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)
local function filter(node)
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
Simply craft potions in the brewing stand as normal except for these conditions.
1. Place item in top slot first.
2. At least 1 bottle must be placed in the first slot.
1. Place item in top slot FIRST.
2. Place all 3 bottles.
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 context = Milo:getContext()
local turtle = _G.turtle
local craftTask = {
name = 'crafting',

View File

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

View File

@@ -8,6 +8,7 @@ local Util = require('util')
local colors = _G.colors
local context = Milo:getContext()
local device = _G.device
local os = _G.os
--[[ Configuration Screen ]]
local wizardPage = UI.Window {
@@ -28,10 +29,10 @@ local wizardPage = UI.Window {
formLabel = 'Font Size', formKey = 'textScale',
nochoice = 'Small',
choices = {
{ name = 'Small', value = .5, help = '(requires restart)', },
{ name = 'Large', value = 1, help = '(requires restart)', },
{ name = 'Small', value = .5 },
{ 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)
end
function wizardPage:saveNode(node)
os.queueEvent('monitor_resize', node.name)
end
function wizardPage:validate()
return self.form:save()
end
@@ -70,7 +75,6 @@ local function createPage(node)
},
grid = UI.Grid {
sortColumn = 'index',
backgroundFocusColor = colors.black,
columns = {
{ heading = 'Qty', key = 'remaining', width = 4 },
{ heading = 'Crafting', key = 'displayName', },
@@ -142,6 +146,20 @@ end
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)
for node in context.storage:filterActive('jobs') do
local page = pages[node.name]

View File

@@ -1,67 +1 @@
local Milo = require('milo')
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)
-- moved

View File

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

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
break
end
_G._debug(data)
--_G._debug(data)
socket.co = coroutine.running()
if data.request == 'scan' then -- full scan of all inventories

View File

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

View File

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