This commit is contained in:
kepler155c
2018-10-27 21:35:21 -04:00
parent d227d6ebb7
commit 57e7a574c4
16 changed files with 518 additions and 288 deletions

View File

@@ -85,6 +85,9 @@ if not modem or not modem.getNameLocal then
error('Wired modem is not connected')
end
local introspectionModule = Peripheral.get('plethora:introspection') or
error('Introspection module not found')
local function loadResources()
local resources = Util.readTable(Milo.RESOURCE_FILE) or { }
for k,v in pairs(resources) do
@@ -98,12 +101,15 @@ local context = {
config = config,
resources = loadResources(),
userRecipes = Util.readTable(Milo.RECIPES_FILE) or { },
learnTypes = { },
machineTypes = { },
localName = modem.getNameLocal(),
tasks = { },
craftingQueue = { },
learnTypes = { },
tasks = { },
localName = modem.getNameLocal(),
storage = Storage(config),
introspectionModule = introspectionModule,
}
_G._p = context --debug

View File

@@ -9,7 +9,6 @@ local Util = require('util')
local colors = _G.colors
local device = _G.device
local socket
local neural = device.neuralInterface
local options = {
user = { arg = 'u', type = 'string',
@@ -34,6 +33,11 @@ if not options.user.value or not options.server.value then
error('Invalid arguments')
end
if options.slot.value and
not (device.neuralInterface and device.neuralInterface.getInventory) then
error('Introspection module is required for transferring items')
end
local page = UI.Page {
menuBar = UI.MenuBar {
buttons = {
@@ -240,14 +244,21 @@ function page:applyFilter()
self.grid:setValues(t)
end
if neural and options.slot.value and neural.getInventory then
if options.slot.value then
debug('Transfer items initialized')
Event.onInterval(1, function()
local inv = neural.getInventory()
if inv and inv.getItem(options.slot.value) then
page:sendRequest({ request = 'deposit', slot = options.slot.value })
-- local item =
-- TODO: update count for this one item
-- page.grid:draw() page:sync()
local neural = device.neuralInterface
if neural and neural.getInventory then
local item = neural.getInventory().getItem(options.slot.value)
if item then
debug('depositing')
page:sendRequest({ request = 'deposit', slot = options.slot.value })
-- local item =
-- TODO: update count for this one item
-- page.grid:draw() page:sync()
end
else
debug('missing Introspection module')
end
end)
end

View File

@@ -129,6 +129,20 @@ function Milo:clearGrid()
return clear() or clear()
end
function Milo:getTurtleInventory()
local list = { }
for i = 1,16 do
-- TODO: update item db
local item = self.context.introspectionModule.getInventory().getItemMeta(i)
if item then
itemDB:add(item)
list[i] = item
end
end
itemDB:flush()
return list
end
function Milo:eject(item, qty)
local s, m = pcall(function()
self.context.storage:provide(item, qty)

View File

@@ -23,17 +23,24 @@ listCount = 0,
local modem = Peripheral.get('wired_modem') or error('Wired modem not attached')
self.localName = modem.getNameLocal()
Event.on({ 'device_attach' }, function(_, dev)
debug('attach: ' .. dev)
Event.on({ 'device_attach', 'device_detach' }, function(e, dev)
debug('%s: %s', e, tostring(dev))
self:initStorage()
end)
Event.on({ 'device_detach' }, function(_, dev)
debug('detach: ' .. dev)
self:initStorage(dev)
Event.onInterval(15, function()
self:showStorage()
end)
end
function NetworkedAdapter:showStorage()
debug('Storage:')
for k,v in pairs(self.remoteDefaults) do
local online = v.adapter and v.adapter.online
debug(' %s: %s', online and ' online' or 'offline', k)
end
debug('')
end
function NetworkedAdapter:setOnline(online)
if online ~= self.storageOnline then
self.storageOnline = online
@@ -59,7 +66,6 @@ function NetworkedAdapter:initStorage()
end
if v.mtype == 'storage' then
online = online and not not (v.adapter and v.adapter.online)
debug(' %s: %s', v.adapter and v.adapter.online and ' online' or 'offline', k)
end
end

View File

@@ -51,6 +51,22 @@ local machinesPage = UI.Page {
},
}
function machinesPage.grid:getDisplayValues(row)
row = Util.shallowCopy(row)
row.displayName = row.displayName or row.name
return row
end
function machinesPage.grid:getRowTextColor(row, selected)
if not device[row.name] then
return colors.red
end
if row.mtype == 'ignore' then
return colors.lightGray
end
return UI.Grid:getRowTextColor(row, selected)
end
function machinesPage:getList()
-- TODO: remove dedupe naming in perf code ?
for _, v in pairs(device) do
@@ -82,22 +98,6 @@ function machinesPage:disable()
Event.off(self.handler)
end
function machinesPage.grid:getDisplayValues(row)
row = Util.shallowCopy(row)
row.displayName = row.displayName or row.name
return row
end
function machinesPage.grid:getRowTextColor(row, selected)
if not device[row.name] then
return colors.red
end
if row.mtype == 'ignore' then
return colors.lightGray
end
return UI.Grid:getRowTextColor(row, selected)
end
function machinesPage:eventHandler(event)
if event.type == 'grid_select' then
UI:setPage('machineWizard', event.selected)
@@ -178,8 +178,146 @@ The settings will take effect immediately!]],
backgroundColor = colors.cyan,
},
notification = UI.Notification { },
filter = UI.SlideOut {
backgroundColor = colors.cyan,
menuBar = UI.MenuBar {
buttons = {
{ text = 'Save', event = 'save' },
{ text = 'Cancel', event = 'cancel' },
},
},
grid = UI.ScrollingGrid {
x = 2, ex = -6, y = 2, ey = -6,
columns = {
{ heading = 'Name', key = 'displayName' },
},
sortColumn = 'displayName',
help = 'Select item to export',
},
remove = UI.Button {
x = -4, y = 4,
text = '-', event = 'remove_entry', help = 'Remove',
},
form = UI.Form {
x = 2, y = -4, height = 3,
margin = 1,
manualControls = true,
[1] = UI.Chooser {
width = 7,
formLabel = 'Ignore Dmg', formKey = 'ignoreDamage',
pruneEmpty = true,
nochoice = 'No',
choices = {
{ name = 'Yes', value = true },
{ name = 'No', value = false },
},
help = 'Ignore damage of item when exporting'
},
[2] = UI.Chooser {
width = 7,
formLabel = 'Ignore NBT', formKey = 'ignoreNbtHash',
pruneEmpty = true,
nochoice = 'No',
choices = {
{ name = 'Yes', value = true },
{ name = 'No', value = false },
},
help = 'Ignore NBT of item when exporting'
},
[3] = UI.Chooser {
width = 13,
formLabel = 'Mode', formKey = 'blacklist',
nochoice = 'whitelist',
choices = {
{ name = 'whitelist', value = false },
{ name = 'blacklist', value = true },
},
help = 'Ignore damage of item when exporting'
},
scan = UI.Button {
x = -11, y = 1,
text = 'Scan', event = 'scan_turtle',
help = 'Add items to turtle to add to filter',
},
},
statusBar = UI.StatusBar {
backgroundColor = colors.cyan,
},
},
}
--[[ Filter slide out ]] --
function machineWizard.filter:show(entry, callback, whitelistOnly)
self.entry = entry
self.callback = callback
if not self.entry.filter then
self.entry.filter = { }
end
self.form:setValues(entry)
self:resetGrid()
self.form[3].inactive = whitelistOnly
UI.SlideOut.show(self)
-- self:setFocus(self.filter)
end
function machineWizard.filter:resetGrid()
local t = { }
for k in pairs(self.entry.filter) do
table.insert(t, itemDB:splitKey(k))
end
self.grid:setValues(t)
end
function machineWizard.filter.grid:getDisplayValues(row)
row = Util.shallowCopy(row)
row.displayName = itemDB:getName(row)
return row
end
function machineWizard.filter:eventHandler(event)
if event.type == 'focus_change' then
self.statusBar:setStatus(event.focused.help)
elseif event.type == 'scan_turtle' then
local inventory = Milo:getTurtleInventory()
for _,item in pairs(inventory) do
self.entry.filter[Milo:uniqueKey(item)] = true
end
self:resetGrid()
self.grid:update()
self.grid:draw()
elseif event.type == 'remove_entry' then
local row = self.grid:getSelected()
if row then
Util.removeByValue(self.grid.values, row)
self.grid:update()
self.grid:draw()
end
elseif event.type == 'save' then
self.form:save()
self.entry.filter = { }
for _,v in pairs(self.grid.values) do
self.entry.filter[Milo:uniqueKey(v)] = true
end
self:hide()
self.callback()
elseif event.type == 'cancel' then
self:hide()
else
return UI.SlideOut.eventHandler(self, event)
end
return true
end
--[[ General Page ]] --
function machineWizard.wizard.pages.general:enable()
UI.Window.enable(self)
self:focusFirst()
@@ -208,6 +346,7 @@ function machineWizard.wizard.pages.general:validate()
return self.form:save()
end
--[[ Wizard ]] --
function machineWizard.wizard:eventHandler(event)
if event.type == 'nextView' and
Util.find(self.pages, 'enabled', true) == self.pages.general then
@@ -215,11 +354,16 @@ function machineWizard.wizard:eventHandler(event)
if self.pages.general.form:save() then
local index = 2
for _, page in pairs(self.pages) do
if page.mtype == machineWizard.machine.mtype then
page.index = nil
end
self.pages.general.index = 1
self.pages.confirmation.index = 2
for k, page in pairs(self.pages) do
debug(k)
if not page.index and page:isValidFor(self.parent.machine) then
page.index = index
index = index + 1
elseif page.index ~= 1 then
page.index = nil
end
end
self.pages.confirmation.index = index
@@ -237,6 +381,7 @@ function machineWizard:enable(machine)
self.machine.adapter = adapter
machine.adapter = adapter
_G._p2 = self.machine
self.wizard.pages.general.form:setValues(self.machine)
self.wizard.pages.general.form[1].shadowText = self.machine.name
@@ -286,6 +431,9 @@ function machineWizard:eventHandler(event)
UI:setPreviousPage()
elseif event.type == 'edit_filter' then
self.filter:show(event.entry, event.callback, event.whitelistOnly)
elseif event.type == 'enable_view' then
local current = event.next or event.prev
self.titleBar.title = current.title or 'Machine'

View File

@@ -14,22 +14,30 @@ function ExportTask:cycle(context)
local machine = device[target]
if machine and machine.getItemMeta then
for _, entry in pairs(v.exports) do
local slot = machine.getItemMeta(entry.slot) or { count = 0 }
local item = itemDB:splitKey(entry.name)
local slotNo = type(entry.slot) == 'number' and entry.slot or nil -- '*' indicates any slot
-- is something else is in this slot
if not slot.name or slot.name == item.name then
local maxCount = slot.maxCount or itemDB:getMaxCount(item)
local count = maxCount - slot.count
local slot = (slotNo and machine.getItemMeta(slotNo)) or { count = 0 }
for key in pairs(entry.filter) do
local item = itemDB:splitKey(key)
if count > 0 then
item = Milo:getItemWithQty(item)
if item and count > 0 then
context.storage:export(
target,
entry.slot,
math.min(count, item.count),
item)
-- is something else is in this slot
if not slot.name or slot.name == item.name then
local maxCount = slot.maxCount or itemDB:getMaxCount(item)
local count = maxCount - slot.count
if not slotNo then
-- TODO: should we just execute export -
-- or scan all slots for space ??
count = machine.size() * maxCount - slot.count
end
if count > 0 then
item = Milo:getItemWithQty(item)
if item and count > 0 then
context.storage:export(
target,
slotNo,
math.min(count, item.count),
item)
end
end
end
end

View File

@@ -1,181 +1,43 @@
local itemDB = require('itemDB')
local Milo = require('milo')
local UI = require('ui')
local Util = require('util')
local colors = _G.colors
local device = _G.device
local itemSlideout = UI.SlideOut {
backgroundColor = colors.cyan,
menuBar = UI.MenuBar {
buttons = {
{ text = 'Save', event = 'save' },
{ text = 'Cancel', event = 'cancel' },
{ text = 'Refresh', event = 'refresh', x = -9 },
},
},
grid = UI.ScrollingGrid {
y = 2, ey = -6,
columns = {
{ heading = 'Name', key = 'displayName', width = 31 },
{ heading = 'Qty', key = 'count' , width = 5 },
},
sortColumn = 'displayName',
help = 'Select item to export',
},
filter = UI.TextEntry {
x = 2, ex = 18, y = -3,
limit = 50,
shadowText = 'filter',
backgroundColor = colors.lightGray,
backgroundFocusColor = colors.lightGray,
},
form = UI.Form {
x = 21, y = -4, height = 3,
margin = 1,
manualControls = true,
[1] = UI.Chooser {
width = 7,
formLabel = 'Slot', formKey = 'slot',
nochoice = 1,
help = 'Export into this slot',
},
[2] = UI.Chooser {
width = 7,
formLabel = 'Ignore Dmg', formKey = 'ignoreDamage',
pruneEmpty = true,
nochoice = 'No',
choices = {
{ name = 'Yes', value = true },
{ name = 'No', value = false },
},
help = 'Ignore damage of item when exporting'
},
[3] = UI.Chooser {
width = 7,
formLabel = 'Ignore NBT', formKey = 'ignoreNbtHash',
pruneEmpty = true,
nochoice = 'No',
choices = {
{ name = 'Yes', value = true },
{ name = 'No', value = false },
},
help = 'Ignore NBT of item when exporting'
},
},
statusBar = UI.StatusBar {
backgroundColor = colors.cyan,
},
}
function itemSlideout:filterItems(t, filter)
if filter and #filter > 0 then
local r = {}
filter = filter:lower()
for _,v in pairs(t) do
if string.find(v.lname, filter) then
table.insert(r, v)
end
end
return r
end
return t
end
function itemSlideout.grid:enable()
if not self.allItems then
self.allItems = Milo:listItems()
Milo:mergeResources(self.allItems)
self:setValues(self.allItems)
end
UI.Grid.enable(self)
end
function itemSlideout:show(machine, entry, callback)
self.entry = entry
self.callback = callback
self.form.choices = { }
local m = device[machine.name]
for k = 1, m.size() do
table.insert(self.form[1].choices, {
name = k,
value = k,
})
end
if not entry.slot then
entry.slot = 1
end
self.form:setValues(entry)
UI.SlideOut.show(self)
self:setFocus(self.filter)
--self.filter:focus()
end
function itemSlideout:eventHandler(event)
if event.type == 'text_change' then
local t = self:filterItems(self.grid.allItems, event.text)
self.grid:setValues(t)
self.grid:draw()
elseif event.type == 'focus_change' then
self.statusBar:setStatus(event.focused.help)
elseif event.type == 'save' then
local selected = self.grid:getSelected()
if not selected then
self.statusBar:setStatus('Select an item to export')
else
self.form:save()
self.form.values.name = itemDB:makeKey(selected)
self:hide()
self.callback()
end
elseif event.type == 'cancel' then
self:hide()
elseif event.type == 'refresh' then
self.allItems = Milo:listItems()
Milo:mergeResources(self.allItems)
local t = self:filterItems(self.allItems, self.filter.value)
self.grid:setValues(t)
self.grid:draw()
self.filter:focus()
else
return UI.SlideOut.eventHandler(self, event)
end
return true
end
local exportView = UI.Window {
mtype = 'machine',
title = 'Export item into machine',
index = 3,
grid = UI.ScrollingGrid {
x = 2, ex = -6, y = 2, ey = -2,
x = 2, ex = -6, y = 2, ey = -4,
columns = {
{ heading = 'Slot', key = 'slot', width = 4 },
{ heading = 'Item', key = 'displayName' },
{ heading = 'Slot', key = 'slot', width = 4 },
{ heading = 'Filter', key = 'filter' },
},
sortColumn = 'slot',
help = 'Edit this entry',
},
text = UI.Text {
x = 2, y = -2,
value = 'Slot',
},
slots = UI.Chooser {
x = 7, y = -2,
width = 7,
nochoice = 'All',
help = 'Export to this slot',
},
add = UI.Button {
x = -4, y = 4,
text = '+', event = 'add_export', help = '...',
x = 15, y = -2,
text = '+', event = 'add_entry', help = 'Add',
},
remove = UI.Button {
x = -4, y = 6,
text = '-', event = 'remove_export', help = '...',
x = -4, y = 4,
text = '-', event = 'remove_entry', help = 'Remove',
},
}
function exportView:save(machine)
machine.exports = not Util.empty(self.grid.values) and self.grid.values or nil
return true
function exportView:isValidFor(machine)
return machine.mtype == 'machine'
end
function exportView:setMachine(machine)
@@ -184,30 +46,53 @@ function exportView:setMachine(machine)
self.machine.exports = { }
end
self.grid:setValues(machine.exports)
self.slots.choices = {
{ name = 'All', value = '*' }
}
-- TODO: what if device is dettached ?
local m = device[machine.name]
for k = 1, m.size() do
table.insert(self.slots.choices, { name = k, value = k })
end
end
function exportView.grid:getDisplayValues(row)
row = Util.shallowCopy(row)
row.displayName = itemDB:getName(row.name)
if not row.filter or Util.empty(row.filter) then
row.filter = 'none'
else
local t = { }
for key in pairs(row.filter) do
table.insert(t, itemDB:getName(key))
end
row.filter = table.concat(t, ', ')
end
return row
end
function exportView:eventHandler(event)
if event.type == 'grid_select' then
itemSlideout:show(self.machine, self.grid:getSelected(), function()
self.grid:update()
self.grid:draw()
end)
self:emit({
type = 'edit_filter',
entry = self.grid:getSelected(),
whitelistOnly = true,
callback = function()
self.grid:update()
self.grid:draw()
end,
})
elseif event.type == 'add_export' then
local export = { }
itemSlideout:show(self.machine, export, function()
table.insert(self.machine.exports, export)
self.grid:update()
self.grid:draw()
end)
elseif event.type == 'add_entry' then
table.insert(self.machine.exports, {
slot = self.slots.value or '*',
filter = { },
})
self.grid:update()
self.grid:draw()
elseif event.type == 'remove_export' then
elseif event.type == 'remove_entry' then
local row = self.grid:getSelected()
if row then
Util.removeByValue(self.grid.values, row)
@@ -217,5 +102,4 @@ function exportView:eventHandler(event)
end
end
UI:getPage('machineWizard'):add({ items = itemSlideout })
UI:getPage('machineWizard').wizard:add({ export = exportView })

View File

@@ -11,11 +11,34 @@ function ImportTask:cycle(context)
for source, v in pairs(context.config.remoteDefaults) do
if v.imports then
local inventory = device[source]
if inventory and inventory.getItemMeta then
for slot in pairs(v.imports) do
local item = inventory.getItemMeta(slot)
if item then
context.storage:import(source, slot, item.count, item)
if inventory then
for _, entry in pairs(v.imports) do
local function matchesFilter(item)
if not entry.filter then
return true
end
local key = Milo:uniqueKey(item)
if entry.blacklist then
return not entry.filter[key]
end
return entry.filter[key]
end
local function importSlot(slotNo)
local item = inventory.getItemMeta(slotNo)
if item and matchesFilter(item) then
context.storage:import(source, slotNo, item.count, item)
end
end
if type(entry.slot) == 'number' then
importSlot(entry.slot)
else
for i = 1, inventory.size() do
importSlot(i)
end
end
end
else

View File

@@ -1,55 +1,103 @@
local UI = require('ui')
local Util = require('util')
local itemDB = require('itemDB')
local UI = require('ui')
local Util = require('util')
local device = _G.device
local importView = UI.Window {
mtype = 'machine',
title = 'Import item from machine',
index = 4,
grid = UI.ScrollingGrid {
y = 2, ey = -2,
x = 2, ex = -6, y = 2, ey = -4,
columns = {
{ heading = 'Slot', key = 'slot', width = 4 },
{ heading = 'Import', key = 'import' },
{ heading = 'Filter', key = 'filter' },
},
sortColumn = 'slot',
help = 'Double-click to toggle'
help = 'Edit this entry',
},
text = UI.Text {
x = 2, y = -2,
value = 'Slot',
},
slots = UI.Chooser {
x = 7, y = -2,
width = 7,
nochoice = 'All',
help = 'Import from this slot',
},
add = UI.Button {
x = 15, y = -2,
text = '+', event = 'add_entry', help = 'Add',
},
remove = UI.Button {
x = -4, y = 4,
text = '-', event = 'remove_entry', help = 'Remove',
},
}
function importView:setMachine(machine)
local m = device[machine.name]
local t = { }
for k = 1, m.size() do
t[k] = { slot = k }
end
if machine.imports then
for k,v in pairs(machine.imports) do
t[k] = { slot = k, import = v }
end
end
self.grid:setValues(t)
function importView:isValidFor(machine)
return machine.mtype == 'machine'
end
function importView:save(machine)
local t = { }
for k,v in pairs(self.grid.values) do
if v.import then
t[k] = true
end
function importView:setMachine(machine)
self.machine = machine
if not self.machine.imports then
self.machine.imports = { }
end
machine.imports = not Util.empty(t) and t or nil
return true
self.grid:setValues(machine.imports)
self.slots.choices = {
{ name = 'All', value = '*' }
}
-- TODO: what if device is dettached ?
local m = device[machine.name]
for k = 1, m.size() do
table.insert(self.slots.choices, { name = k, value = k })
end
end
function importView.grid:getDisplayValues(row)
row = Util.shallowCopy(row)
if not row.filter or Util.empty(row.filter) then
row.filter = 'none'
else
local t = { }
for key in pairs(row.filter) do
table.insert(t, itemDB:getName(key))
end
row.filter = table.concat(t, ', ')
end
return row
end
function importView:eventHandler(event)
if event.type == 'grid_select' then
event.selected.import = not event.selected.import
self:emit({
type = 'edit_filter',
entry = self.grid:getSelected(),
callback = function()
self.grid:update()
self.grid:draw()
end,
})
elseif event.type == 'add_entry' then
table.insert(self.machine.imports, {
slot = self.slots.value or '*',
filter = { },
})
self.grid:update()
self.grid:draw()
elseif event.type == 'remove_entry' then
local row = self.grid:getSelected()
if row then
Util.removeByValue(self.grid.values, row)
self.grid:update()
self.grid:draw()
end
end
end

View File

@@ -61,7 +61,7 @@ end
function jobList.grid:getDisplayValues(row)
row = Util.shallowCopy(row)
if row.showRemaining then
row.remaining = row.count - row.crafted
row.remaining = math.max(0, row.count - row.crafted)
else
row.displayName = ' ' .. row.displayName
end

View File

@@ -12,17 +12,6 @@ local MACHINE_LOOKUP = 'usr/config/machine_crafting.db'
local context = Milo:getContext()
local function getTurtleInventory()
local introspectionModule = device['plethora:introspection'] or
error('Introspection module not found')
local list = { }
for i = 1,16 do
list[i] = introspectionModule.getInventory().getItemMeta(i)
end
return list
end
local machineLearnWizard = UI.Page {
titleBar = UI.TitleBar { title = 'Learn a crafting recipe' },
wizard = UI.Wizard {
@@ -92,7 +81,7 @@ function pages.machine:validate()
end
function pages.confirmation:validate()
local inventory = getTurtleInventory()
local inventory = Milo:getTurtleInventory()
local result = inventory[16]
local slotCount = machine.size()

View File

@@ -0,0 +1,28 @@
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 pairs(context.config.remoteDefaults) do
if v.redstone then
local ri = device[v.redstone.integrator]
local function conditionsSatisfied()
return not not next(ri.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
Milo:registerTask(RedstoneTask)

View File

@@ -0,0 +1,73 @@
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(machine)
if machine.mtype == 'machine' then
local m = device[machine.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:setMachine(machine)
if not machine.redstone then
machine.redstone = { }
end
self.form:setValues(machine.redstone)
end
UI:getPage('machineWizard').wizard:add({ dispenser = dispenserView })

View File

@@ -33,6 +33,7 @@ local function client(socket)
if not data then
break
end
debug('remote: ' .. data.request)
if data.request == 'list' then
local items = Milo:refreshItems()
Milo:mergeResources(items)

View File

@@ -1,11 +1,10 @@
local itemDB = require('itemDB')
local UI = require('ui')
local UI = require('ui')
local colors = _G.colors
local device = _G.device
local storageView = UI.Window {
mtype = 'storage',
title = 'Storage Options',
index = 2,
backgroundColor = colors.cyan,
@@ -49,6 +48,10 @@ function storageView:validate()
return self.form:save()
end
function storageView:isValidFor(machine)
return machine.mtype == 'storage'
end
function storageView:setMachine(machine)
self.machine = machine
self.form:setValues(machine)

View File

@@ -4,24 +4,12 @@ local Milo = require('milo')
local UI = require('ui')
local Util = require('util')
local device = _G.device
local turtle = _G.turtle
local context = Milo:getContext()
local function getTurtleInventory()
local introspectionModule = device['plethora:introspection'] or
error('Introspection module not found')
local list = { }
for i = 1,16 do
list[i] = introspectionModule.getInventory().getItemMeta(i)
end
return list
end
local function learnRecipe()
local ingredients = getTurtleInventory()
local ingredients = Milo:getTurtleInventory()
if not ingredients then
return false, 'No recipe defined'
@@ -32,7 +20,7 @@ local function learnRecipe()
return false, 'Failed to craft'
end
local results = getTurtleInventory()
local results = Milo:getTurtleInventory()
if not results or not results[1] then
return false, 'Failed to craft'
end