milo wip
This commit is contained in:
@@ -85,6 +85,9 @@ if not modem or not modem.getNameLocal then
|
|||||||
error('Wired modem is not connected')
|
error('Wired modem is not connected')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local introspectionModule = Peripheral.get('plethora:introspection') or
|
||||||
|
error('Introspection module not found')
|
||||||
|
|
||||||
local function loadResources()
|
local function loadResources()
|
||||||
local resources = Util.readTable(Milo.RESOURCE_FILE) or { }
|
local resources = Util.readTable(Milo.RESOURCE_FILE) or { }
|
||||||
for k,v in pairs(resources) do
|
for k,v in pairs(resources) do
|
||||||
@@ -98,12 +101,15 @@ local context = {
|
|||||||
config = config,
|
config = config,
|
||||||
resources = loadResources(),
|
resources = loadResources(),
|
||||||
userRecipes = Util.readTable(Milo.RECIPES_FILE) or { },
|
userRecipes = Util.readTable(Milo.RECIPES_FILE) or { },
|
||||||
learnTypes = { },
|
|
||||||
machineTypes = { },
|
|
||||||
localName = modem.getNameLocal(),
|
|
||||||
tasks = { },
|
|
||||||
craftingQueue = { },
|
craftingQueue = { },
|
||||||
|
|
||||||
|
learnTypes = { },
|
||||||
|
tasks = { },
|
||||||
|
|
||||||
|
localName = modem.getNameLocal(),
|
||||||
storage = Storage(config),
|
storage = Storage(config),
|
||||||
|
introspectionModule = introspectionModule,
|
||||||
}
|
}
|
||||||
|
|
||||||
_G._p = context --debug
|
_G._p = context --debug
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ local Util = require('util')
|
|||||||
local colors = _G.colors
|
local colors = _G.colors
|
||||||
local device = _G.device
|
local device = _G.device
|
||||||
local socket
|
local socket
|
||||||
local neural = device.neuralInterface
|
|
||||||
|
|
||||||
local options = {
|
local options = {
|
||||||
user = { arg = 'u', type = 'string',
|
user = { arg = 'u', type = 'string',
|
||||||
@@ -34,6 +33,11 @@ if not options.user.value or not options.server.value then
|
|||||||
error('Invalid arguments')
|
error('Invalid arguments')
|
||||||
end
|
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 {
|
local page = UI.Page {
|
||||||
menuBar = UI.MenuBar {
|
menuBar = UI.MenuBar {
|
||||||
buttons = {
|
buttons = {
|
||||||
@@ -240,14 +244,21 @@ function page:applyFilter()
|
|||||||
self.grid:setValues(t)
|
self.grid:setValues(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
if neural and options.slot.value and neural.getInventory then
|
if options.slot.value then
|
||||||
|
debug('Transfer items initialized')
|
||||||
Event.onInterval(1, function()
|
Event.onInterval(1, function()
|
||||||
local inv = neural.getInventory()
|
local neural = device.neuralInterface
|
||||||
if inv and inv.getItem(options.slot.value) then
|
if neural and neural.getInventory then
|
||||||
page:sendRequest({ request = 'deposit', slot = options.slot.value })
|
local item = neural.getInventory().getItem(options.slot.value)
|
||||||
-- local item =
|
if item then
|
||||||
-- TODO: update count for this one item
|
debug('depositing')
|
||||||
-- page.grid:draw() page:sync()
|
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)
|
end)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -129,6 +129,20 @@ function Milo:clearGrid()
|
|||||||
return clear() or clear()
|
return clear() or clear()
|
||||||
end
|
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)
|
function Milo:eject(item, qty)
|
||||||
local s, m = pcall(function()
|
local s, m = pcall(function()
|
||||||
self.context.storage:provide(item, qty)
|
self.context.storage:provide(item, qty)
|
||||||
|
|||||||
@@ -23,17 +23,24 @@ listCount = 0,
|
|||||||
local modem = Peripheral.get('wired_modem') or error('Wired modem not attached')
|
local modem = Peripheral.get('wired_modem') or error('Wired modem not attached')
|
||||||
self.localName = modem.getNameLocal()
|
self.localName = modem.getNameLocal()
|
||||||
|
|
||||||
Event.on({ 'device_attach' }, function(_, dev)
|
Event.on({ 'device_attach', 'device_detach' }, function(e, dev)
|
||||||
debug('attach: ' .. dev)
|
debug('%s: %s', e, tostring(dev))
|
||||||
self:initStorage()
|
self:initStorage()
|
||||||
end)
|
end)
|
||||||
|
Event.onInterval(15, function()
|
||||||
Event.on({ 'device_detach' }, function(_, dev)
|
self:showStorage()
|
||||||
debug('detach: ' .. dev)
|
|
||||||
self:initStorage(dev)
|
|
||||||
end)
|
end)
|
||||||
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)
|
function NetworkedAdapter:setOnline(online)
|
||||||
if online ~= self.storageOnline then
|
if online ~= self.storageOnline then
|
||||||
self.storageOnline = online
|
self.storageOnline = online
|
||||||
@@ -59,7 +66,6 @@ function NetworkedAdapter:initStorage()
|
|||||||
end
|
end
|
||||||
if v.mtype == 'storage' then
|
if v.mtype == 'storage' then
|
||||||
online = online and not not (v.adapter and v.adapter.online)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
function machinesPage:getList()
|
||||||
-- TODO: remove dedupe naming in perf code ?
|
-- TODO: remove dedupe naming in perf code ?
|
||||||
for _, v in pairs(device) do
|
for _, v in pairs(device) do
|
||||||
@@ -82,22 +98,6 @@ function machinesPage:disable()
|
|||||||
Event.off(self.handler)
|
Event.off(self.handler)
|
||||||
end
|
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)
|
function machinesPage:eventHandler(event)
|
||||||
if event.type == 'grid_select' then
|
if event.type == 'grid_select' then
|
||||||
UI:setPage('machineWizard', event.selected)
|
UI:setPage('machineWizard', event.selected)
|
||||||
@@ -178,8 +178,146 @@ The settings will take effect immediately!]],
|
|||||||
backgroundColor = colors.cyan,
|
backgroundColor = colors.cyan,
|
||||||
},
|
},
|
||||||
notification = UI.Notification { },
|
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()
|
function machineWizard.wizard.pages.general:enable()
|
||||||
UI.Window.enable(self)
|
UI.Window.enable(self)
|
||||||
self:focusFirst()
|
self:focusFirst()
|
||||||
@@ -208,6 +346,7 @@ function machineWizard.wizard.pages.general:validate()
|
|||||||
return self.form:save()
|
return self.form:save()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[ Wizard ]] --
|
||||||
function machineWizard.wizard:eventHandler(event)
|
function machineWizard.wizard:eventHandler(event)
|
||||||
if event.type == 'nextView' and
|
if event.type == 'nextView' and
|
||||||
Util.find(self.pages, 'enabled', true) == self.pages.general then
|
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
|
if self.pages.general.form:save() then
|
||||||
local index = 2
|
local index = 2
|
||||||
for _, page in pairs(self.pages) do
|
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
|
page.index = index
|
||||||
index = index + 1
|
index = index + 1
|
||||||
elseif page.index ~= 1 then
|
|
||||||
page.index = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.pages.confirmation.index = index
|
self.pages.confirmation.index = index
|
||||||
@@ -237,6 +381,7 @@ function machineWizard:enable(machine)
|
|||||||
self.machine.adapter = adapter
|
self.machine.adapter = adapter
|
||||||
machine.adapter = adapter
|
machine.adapter = adapter
|
||||||
|
|
||||||
|
_G._p2 = self.machine
|
||||||
self.wizard.pages.general.form:setValues(self.machine)
|
self.wizard.pages.general.form:setValues(self.machine)
|
||||||
self.wizard.pages.general.form[1].shadowText = self.machine.name
|
self.wizard.pages.general.form[1].shadowText = self.machine.name
|
||||||
|
|
||||||
@@ -286,6 +431,9 @@ function machineWizard:eventHandler(event)
|
|||||||
|
|
||||||
UI:setPreviousPage()
|
UI:setPreviousPage()
|
||||||
|
|
||||||
|
elseif event.type == 'edit_filter' then
|
||||||
|
self.filter:show(event.entry, event.callback, event.whitelistOnly)
|
||||||
|
|
||||||
elseif event.type == 'enable_view' then
|
elseif event.type == 'enable_view' then
|
||||||
local current = event.next or event.prev
|
local current = event.next or event.prev
|
||||||
self.titleBar.title = current.title or 'Machine'
|
self.titleBar.title = current.title or 'Machine'
|
||||||
|
|||||||
@@ -14,22 +14,30 @@ function ExportTask:cycle(context)
|
|||||||
local machine = device[target]
|
local machine = device[target]
|
||||||
if machine and machine.getItemMeta then
|
if machine and machine.getItemMeta then
|
||||||
for _, entry in pairs(v.exports) do
|
for _, entry in pairs(v.exports) do
|
||||||
local slot = machine.getItemMeta(entry.slot) or { count = 0 }
|
local slotNo = type(entry.slot) == 'number' and entry.slot or nil -- '*' indicates any slot
|
||||||
local item = itemDB:splitKey(entry.name)
|
|
||||||
|
|
||||||
-- is something else is in this slot
|
local slot = (slotNo and machine.getItemMeta(slotNo)) or { count = 0 }
|
||||||
if not slot.name or slot.name == item.name then
|
for key in pairs(entry.filter) do
|
||||||
local maxCount = slot.maxCount or itemDB:getMaxCount(item)
|
local item = itemDB:splitKey(key)
|
||||||
local count = maxCount - slot.count
|
|
||||||
|
|
||||||
if count > 0 then
|
-- is something else is in this slot
|
||||||
item = Milo:getItemWithQty(item)
|
if not slot.name or slot.name == item.name then
|
||||||
if item and count > 0 then
|
local maxCount = slot.maxCount or itemDB:getMaxCount(item)
|
||||||
context.storage:export(
|
local count = maxCount - slot.count
|
||||||
target,
|
if not slotNo then
|
||||||
entry.slot,
|
-- TODO: should we just execute export -
|
||||||
math.min(count, item.count),
|
-- or scan all slots for space ??
|
||||||
item)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,181 +1,43 @@
|
|||||||
local itemDB = require('itemDB')
|
local itemDB = require('itemDB')
|
||||||
local Milo = require('milo')
|
|
||||||
local UI = require('ui')
|
local UI = require('ui')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local colors = _G.colors
|
|
||||||
local device = _G.device
|
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 {
|
local exportView = UI.Window {
|
||||||
mtype = 'machine',
|
|
||||||
title = 'Export item into machine',
|
title = 'Export item into machine',
|
||||||
index = 3,
|
index = 3,
|
||||||
grid = UI.ScrollingGrid {
|
grid = UI.ScrollingGrid {
|
||||||
x = 2, ex = -6, y = 2, ey = -2,
|
x = 2, ex = -6, y = 2, ey = -4,
|
||||||
columns = {
|
columns = {
|
||||||
{ heading = 'Slot', key = 'slot', width = 4 },
|
{ heading = 'Slot', key = 'slot', width = 4 },
|
||||||
{ heading = 'Item', key = 'displayName' },
|
{ heading = 'Filter', key = 'filter' },
|
||||||
},
|
},
|
||||||
sortColumn = 'slot',
|
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 {
|
add = UI.Button {
|
||||||
x = -4, y = 4,
|
x = 15, y = -2,
|
||||||
text = '+', event = 'add_export', help = '...',
|
text = '+', event = 'add_entry', help = 'Add',
|
||||||
},
|
},
|
||||||
remove = UI.Button {
|
remove = UI.Button {
|
||||||
x = -4, y = 6,
|
x = -4, y = 4,
|
||||||
text = '-', event = 'remove_export', help = '...',
|
text = '-', event = 'remove_entry', help = 'Remove',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportView:save(machine)
|
function exportView:isValidFor(machine)
|
||||||
machine.exports = not Util.empty(self.grid.values) and self.grid.values or nil
|
return machine.mtype == 'machine'
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function exportView:setMachine(machine)
|
function exportView:setMachine(machine)
|
||||||
@@ -184,30 +46,53 @@ function exportView:setMachine(machine)
|
|||||||
self.machine.exports = { }
|
self.machine.exports = { }
|
||||||
end
|
end
|
||||||
self.grid:setValues(machine.exports)
|
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
|
end
|
||||||
|
|
||||||
function exportView.grid:getDisplayValues(row)
|
function exportView.grid:getDisplayValues(row)
|
||||||
row = Util.shallowCopy(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
|
return row
|
||||||
end
|
end
|
||||||
|
|
||||||
function exportView:eventHandler(event)
|
function exportView:eventHandler(event)
|
||||||
if event.type == 'grid_select' then
|
if event.type == 'grid_select' then
|
||||||
itemSlideout:show(self.machine, self.grid:getSelected(), function()
|
self:emit({
|
||||||
self.grid:update()
|
type = 'edit_filter',
|
||||||
self.grid:draw()
|
entry = self.grid:getSelected(),
|
||||||
end)
|
whitelistOnly = true,
|
||||||
|
callback = function()
|
||||||
|
self.grid:update()
|
||||||
|
self.grid:draw()
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
elseif event.type == 'add_export' then
|
elseif event.type == 'add_entry' then
|
||||||
local export = { }
|
table.insert(self.machine.exports, {
|
||||||
itemSlideout:show(self.machine, export, function()
|
slot = self.slots.value or '*',
|
||||||
table.insert(self.machine.exports, export)
|
filter = { },
|
||||||
self.grid:update()
|
})
|
||||||
self.grid:draw()
|
self.grid:update()
|
||||||
end)
|
self.grid:draw()
|
||||||
|
|
||||||
elseif event.type == 'remove_export' then
|
elseif event.type == 'remove_entry' then
|
||||||
local row = self.grid:getSelected()
|
local row = self.grid:getSelected()
|
||||||
if row then
|
if row then
|
||||||
Util.removeByValue(self.grid.values, row)
|
Util.removeByValue(self.grid.values, row)
|
||||||
@@ -217,5 +102,4 @@ function exportView:eventHandler(event)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
UI:getPage('machineWizard'):add({ items = itemSlideout })
|
|
||||||
UI:getPage('machineWizard').wizard:add({ export = exportView })
|
UI:getPage('machineWizard').wizard:add({ export = exportView })
|
||||||
|
|||||||
@@ -11,11 +11,34 @@ function ImportTask:cycle(context)
|
|||||||
for source, v in pairs(context.config.remoteDefaults) do
|
for source, v in pairs(context.config.remoteDefaults) do
|
||||||
if v.imports then
|
if v.imports then
|
||||||
local inventory = device[source]
|
local inventory = device[source]
|
||||||
if inventory and inventory.getItemMeta then
|
if inventory then
|
||||||
for slot in pairs(v.imports) do
|
for _, entry in pairs(v.imports) do
|
||||||
local item = inventory.getItemMeta(slot)
|
|
||||||
if item then
|
local function matchesFilter(item)
|
||||||
context.storage:import(source, slot, item.count, 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
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,55 +1,103 @@
|
|||||||
local UI = require('ui')
|
local itemDB = require('itemDB')
|
||||||
local Util = require('util')
|
local UI = require('ui')
|
||||||
|
local Util = require('util')
|
||||||
|
|
||||||
local device = _G.device
|
local device = _G.device
|
||||||
|
|
||||||
local importView = UI.Window {
|
local importView = UI.Window {
|
||||||
mtype = 'machine',
|
|
||||||
title = 'Import item from machine',
|
title = 'Import item from machine',
|
||||||
index = 4,
|
index = 4,
|
||||||
grid = UI.ScrollingGrid {
|
grid = UI.ScrollingGrid {
|
||||||
y = 2, ey = -2,
|
x = 2, ex = -6, y = 2, ey = -4,
|
||||||
columns = {
|
columns = {
|
||||||
{ heading = 'Slot', key = 'slot', width = 4 },
|
{ heading = 'Slot', key = 'slot', width = 4 },
|
||||||
{ heading = 'Import', key = 'import' },
|
{ heading = 'Filter', key = 'filter' },
|
||||||
},
|
},
|
||||||
sortColumn = 'slot',
|
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)
|
function importView:isValidFor(machine)
|
||||||
local m = device[machine.name]
|
return machine.mtype == 'machine'
|
||||||
|
|
||||||
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)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function importView:save(machine)
|
function importView:setMachine(machine)
|
||||||
local t = { }
|
self.machine = machine
|
||||||
for k,v in pairs(self.grid.values) do
|
if not self.machine.imports then
|
||||||
if v.import then
|
self.machine.imports = { }
|
||||||
t[k] = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
machine.imports = not Util.empty(t) and t or nil
|
self.grid:setValues(machine.imports)
|
||||||
return true
|
|
||||||
|
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
|
end
|
||||||
|
|
||||||
function importView:eventHandler(event)
|
function importView:eventHandler(event)
|
||||||
if event.type == 'grid_select' then
|
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()
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ end
|
|||||||
function jobList.grid:getDisplayValues(row)
|
function jobList.grid:getDisplayValues(row)
|
||||||
row = Util.shallowCopy(row)
|
row = Util.shallowCopy(row)
|
||||||
if row.showRemaining then
|
if row.showRemaining then
|
||||||
row.remaining = row.count - row.crafted
|
row.remaining = math.max(0, row.count - row.crafted)
|
||||||
else
|
else
|
||||||
row.displayName = ' ' .. row.displayName
|
row.displayName = ' ' .. row.displayName
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,17 +12,6 @@ local MACHINE_LOOKUP = 'usr/config/machine_crafting.db'
|
|||||||
|
|
||||||
local context = Milo:getContext()
|
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 {
|
local machineLearnWizard = UI.Page {
|
||||||
titleBar = UI.TitleBar { title = 'Learn a crafting recipe' },
|
titleBar = UI.TitleBar { title = 'Learn a crafting recipe' },
|
||||||
wizard = UI.Wizard {
|
wizard = UI.Wizard {
|
||||||
@@ -92,7 +81,7 @@ function pages.machine:validate()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function pages.confirmation:validate()
|
function pages.confirmation:validate()
|
||||||
local inventory = getTurtleInventory()
|
local inventory = Milo:getTurtleInventory()
|
||||||
local result = inventory[16]
|
local result = inventory[16]
|
||||||
local slotCount = machine.size()
|
local slotCount = machine.size()
|
||||||
|
|
||||||
|
|||||||
28
milo/plugins/redstoneTask.lua
Normal file
28
milo/plugins/redstoneTask.lua
Normal 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)
|
||||||
73
milo/plugins/redstoneView.lua
Normal file
73
milo/plugins/redstoneView.lua
Normal 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 })
|
||||||
@@ -33,6 +33,7 @@ local function client(socket)
|
|||||||
if not data then
|
if not data then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
debug('remote: ' .. data.request)
|
||||||
if data.request == 'list' then
|
if data.request == 'list' then
|
||||||
local items = Milo:refreshItems()
|
local items = Milo:refreshItems()
|
||||||
Milo:mergeResources(items)
|
Milo:mergeResources(items)
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
local itemDB = require('itemDB')
|
local itemDB = require('itemDB')
|
||||||
local UI = require('ui')
|
local UI = require('ui')
|
||||||
|
|
||||||
local colors = _G.colors
|
local colors = _G.colors
|
||||||
local device = _G.device
|
local device = _G.device
|
||||||
|
|
||||||
local storageView = UI.Window {
|
local storageView = UI.Window {
|
||||||
mtype = 'storage',
|
|
||||||
title = 'Storage Options',
|
title = 'Storage Options',
|
||||||
index = 2,
|
index = 2,
|
||||||
backgroundColor = colors.cyan,
|
backgroundColor = colors.cyan,
|
||||||
@@ -49,6 +48,10 @@ function storageView:validate()
|
|||||||
return self.form:save()
|
return self.form:save()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function storageView:isValidFor(machine)
|
||||||
|
return machine.mtype == 'storage'
|
||||||
|
end
|
||||||
|
|
||||||
function storageView:setMachine(machine)
|
function storageView:setMachine(machine)
|
||||||
self.machine = machine
|
self.machine = machine
|
||||||
self.form:setValues(machine)
|
self.form:setValues(machine)
|
||||||
|
|||||||
@@ -4,24 +4,12 @@ local Milo = require('milo')
|
|||||||
local UI = require('ui')
|
local UI = require('ui')
|
||||||
local Util = require('util')
|
local Util = require('util')
|
||||||
|
|
||||||
local device = _G.device
|
|
||||||
local turtle = _G.turtle
|
local turtle = _G.turtle
|
||||||
|
|
||||||
local context = Milo:getContext()
|
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 function learnRecipe()
|
||||||
local ingredients = getTurtleInventory()
|
local ingredients = Milo:getTurtleInventory()
|
||||||
|
|
||||||
if not ingredients then
|
if not ingredients then
|
||||||
return false, 'No recipe defined'
|
return false, 'No recipe defined'
|
||||||
@@ -32,7 +20,7 @@ local function learnRecipe()
|
|||||||
return false, 'Failed to craft'
|
return false, 'Failed to craft'
|
||||||
end
|
end
|
||||||
|
|
||||||
local results = getTurtleInventory()
|
local results = Milo:getTurtleInventory()
|
||||||
if not results or not results[1] then
|
if not results or not results[1] then
|
||||||
return false, 'Failed to craft'
|
return false, 'Failed to craft'
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user