diff --git a/milo/MiloRemote.lua b/milo/MiloRemote.lua index 9d8642b..0251bd0 100644 --- a/milo/MiloRemote.lua +++ b/milo/MiloRemote.lua @@ -12,8 +12,6 @@ local fs = _G.fs local shell = _ENV.shell local string = _G.string -local STARTUP_FILE = 'usr/autorun/miloRemote.lua' - local context = { state = Config.load('miloRemote', { displayMode = 0, deposit = true }), responseHandlers = { }, @@ -107,51 +105,6 @@ local page = UI.Page { q = 'quit', }, - setup = UI.SlideOut { - backgroundColor = colors.cyan, - titleBar = UI.TitleBar { - title = 'Remote Setup', - }, - form = UI.Form { - x = 2, ex = -2, y = 2, ey = -1, - [1] = UI.TextEntry { - formLabel = 'Server', formKey = 'server', - help = 'ID for the server', - shadowText = 'Milo server ID', - limit = 6, - validate = 'numeric', - required = true, - }, - [2] = UI.TextEntry { - formLabel = 'Return Slot', formKey = 'slot', - help = 'Use a slot for sending to storage', - shadowText = 'Inventory slot #', - limit = 5, - validate = 'numeric', - required = false, - }, - [3] = UI.Checkbox { - formLabel = 'Shield Slot', formKey = 'useShield', - help = 'Or, use the shield slot for sending' - }, - [4] = UI.Checkbox { - formLabel = 'Run on startup', formKey = 'runOnStartup', - help = 'Run this program on startup' - }, - info = UI.TextArea { - x = 1, ex = -1, y = 6, ey = -4, - textColor = colors.yellow, - marginLeft = 0, - marginRight = 0, - value = [[The Milo turtle must connect to a manipulator with a ]] .. - [[bound introspection module. The neural interface must ]] .. - [[also have an introspection module.]], - }, - }, - statusBar = UI.StatusBar { - backgroundColor = colors.cyan, - }, - }, items = { }, } @@ -211,13 +164,6 @@ function page:transfer(item, count, msg) context:sendRequest({ request = 'transfer', item = item, count = count }, msg) end -function page.setup:eventHandler(event) - if event.type == 'focus_change' then - self.statusBar:setStatus(event.focused.help) - end - return UI.SlideOut.eventHandler(self, event) -end - function page:eventHandler(event) if event.type == 'quit' then UI:exitPullEvents() @@ -233,27 +179,6 @@ function page:eventHandler(event) context:setStatus(depositMode[context.state.deposit].help) Config.update('miloRemote', context.state) - elseif event.type == 'form_complete' then - Config.update('miloRemote', context.state) - self.setup:hide() - self:refresh('list') - self.grid:draw() - self:setFocus(self.statusBar.filter) - - if context.state.runOnStartup then - if not fs.exists(STARTUP_FILE) then - Util.writeFile(STARTUP_FILE, - [[os.sleep(1) -shell.openForegroundTab('packages/milo/MiloRemote')]]) - end - elseif fs.exists(STARTUP_FILE) then - fs.delete(STARTUP_FILE) - end - - elseif event.type == 'form_cancel' then - self.setup:hide() - self:setFocus(self.statusBar.filter) - elseif event.type == 'focus_change' then context:setStatus(event.focused.help) @@ -399,8 +324,11 @@ end context.page = page function context:setStatus(status) - page.menuBar.infoBar:setStatus(status) - page:sync() + page.menuBar.infoBar.values = status + if page.menuBar.infoBar.enabled then + page.menuBar.infoBar:draw() + page:sync() + end end local function processMessages(s) diff --git a/milo/apis/milo.lua b/milo/apis/milo.lua index 8e17c98..724ce29 100644 --- a/milo/apis/milo.lua +++ b/milo/apis/milo.lua @@ -216,10 +216,20 @@ function Milo:makeRequest(item, count, callback) end function Milo:eject(item, count) - count = self.context.storage:export(self.context.turtleInventory, nil, count, item) - Sound.play('entity.experience_bottle.throw') - turtle.emptyInventory() - return count + local total = 0 + while count > 0 do + local amount = math.min(count, 16*(item.maxCount or 64)) + amount = self.context.storage:export(self.context.turtleInventory, nil, amount, item) + if amount == 0 then + break + end + total = total + amount + count = count - amount + + Sound.play('ui.button.click') + turtle.emptyInventory() + end + return total end function Milo:learnRecipe() diff --git a/milo/plugins/remote.lua b/milo/plugins/remote.lua index 937feba..9a2ddc0 100644 --- a/milo/plugins/remote.lua +++ b/milo/plugins/remote.lua @@ -75,7 +75,7 @@ local function client(socket) if not data then break end -_G._debug(data) + socket.co = coroutine.running() if data.request == 'scan' then -- full scan of all inventories @@ -94,18 +94,11 @@ _G._debug(data) elseif data.request == 'deposit' then local function deposit() - local devType = 'inventory' - local slotNo = data.slot - if data.slot == 'shield' then - slotNo = SHIELD_SLOT - devType = 'equipment' - end - - local node = makeNode(devType) + local node = makeNode(data.source or 'inventory') if node then - local slot = node.adapter.getItemMeta(slotNo) + local slot = node.adapter.getItemMeta(data.slot) if slot then - if context.storage:import(node, slotNo, slot.count, slot) > 0 then + if context.storage:import(node, data.slot, slot.count, slot) > 0 then local item = Milo:getItem(slot) if item then socket:write({ diff --git a/milo/plugins/remote/autostore.lua b/milo/plugins/remote/autostore.lua index 8fd0309..1dba7a3 100644 --- a/milo/plugins/remote/autostore.lua +++ b/milo/plugins/remote/autostore.lua @@ -8,6 +8,7 @@ local colors = _G.colors local device = _G.device local ni = device.neuralInterface +local SHIELD_SLOT = 2 local context = args[1] if not context.state.autostore then @@ -21,7 +22,7 @@ local page = UI.Page { previousPage = true, }, tabs = UI.Tabs { - y = 2, + y = 2, ey = -2, inventory = UI.Window { tabTitle = 'Inventory', grid = UI.ScrollingGrid { @@ -43,6 +44,9 @@ local page = UI.Page { }, }, }, + statusBar = UI.StatusBar { + values = 'Double-click to toggle auto-deposit' + }, } local function makeKey(item) @@ -55,13 +59,12 @@ function page.tabs.inventory:enable() local list = { } for k, item in pairs(inv) do - local key = itemDB:makeKey(item) + item = itemDB:get(item, function() return ni.getInventory().getItemMeta(k) end) + local key = makeKey(item) if not list[key] then - local cItem = itemDB:get(item, function() return ni.getInventory().getItemMeta(k) end) - if cItem then - cItem.key = makeKey(cItem) - list[key] = cItem - end + item.key = key + item.displayName = item.displayName:match('(.+) %(damage:.+%)') or item.displayName + list[key] = item end end @@ -120,31 +123,26 @@ function page.tabs.autostore:eventHandler(event) end Event.onInterval(5, function() - if context.state.deposit and (context.state.useShield or context.state.slot) then - local inv = ni.getInventory().list() - local slot = context.state.slot - local target = 'inventory' - local empty = not inv[slot] + if context.socket and + context.state.deposit and + (context.state.useShield or context.state.slot) and + not Util.empty(context.state.autostore) then - if context.state.useShield then - slot = 2 - target = 'equipment' - empty = not ni.getEquipment().list()[slot] - end - - if empty then - pcall(function() -- prevent errors from some mod items - for k,v in pairs(inv) do - local item = itemDB:get(v, function() ni.getInventory().getItemMeta(k) end) - if item then - if context.state.autostore[makeKey(item)] then - ni.getInventory().pushItems(target, k, v.count, slot) - break - end + pcall(function() -- prevent errors from some mod items + for slot,v in pairs(ni.getInventory().list()) do + local item = itemDB:get(v, function() ni.getInventory().getItemMeta(slot) end) + if item then + if context.state.autostore[makeKey(item)] then + context:sendRequest({ + request = 'deposit', + source = 'inventory', + slot = slot, + count = item.count, + }) end end - end) - end + end + end) end end) diff --git a/milo/plugins/remote/deposit.lua b/milo/plugins/remote/deposit.lua index bd0efdc..7493ee0 100644 --- a/milo/plugins/remote/deposit.lua +++ b/milo/plugins/remote/deposit.lua @@ -17,19 +17,18 @@ Event.addRoutine(function() end os.sleep(context.socket and sleepTime or 5) - if context.state.deposit then + if context.state.deposit and context.state.server and (context.state.useShield or context.state.slot) then local neural = device.neuralInterface local inv = context.state.useShield and 'getEquipment' or 'getInventory' - if not neural or not neural[inv] then - _G._debug('missing Introspection module') - elseif context.state.server and (context.state.useShield or context.state.slot) then + if neural and neural[inv] then local s, m = pcall(function() local method = neural[inv] local item = method and method().list()[context.state.useShield and SHIELD_SLOT or context.state.slot] if item then if context:sendRequest({ request = 'deposit', - slot = context.state.useShield and 'shield' or context.state.slot, + source = context.state.useShield and 'equipment' or 'inventory', + slot = context.state.useShield and SHIELD_SLOT or context.state.slot, count = item.count, }) then lastTransfer = os.clock() diff --git a/milo/plugins/remote/depositAll.lua b/milo/plugins/remote/depositAll.lua index 6ead2a8..d2b9347 100644 --- a/milo/plugins/remote/depositAll.lua +++ b/milo/plugins/remote/depositAll.lua @@ -35,28 +35,26 @@ local page = UI.Page { formLabel = 'Include hotbar', formKey = 'includeHotbar', help = 'Also send the contents of the hotbar to Milo (excluding the neural connector)' } - }, + }, notification = UI.Notification(), } -local function makeKey(item) +local function makeKey(item) -- group items regardless of damage local damage = item.maxDamage == 0 and item.damage return itemDB:makeKey({ name = item.name, damage = damage }) end -function page:updateInventoryList() +function page:updateInventoryList() local inv = ni.getInventory().list() local list = { } for slot, item in pairs(inv) do if (context.state.depositAll.includeHotbar or slot > 9) and item.name ~= 'plethora:neuralconnector' then - local key = itemDB:makeKey(item) + item = itemDB:get(item, function() return ni.getInventory().getItemMeta(slot) end) + local key = makeKey(item) if not list[key] then - local cItem = itemDB:get(item, function() return ni.getInventory().getItemMeta(slot) end) - if cItem then - cItem.key = makeKey(cItem) - list[key] = cItem - end + item.displayName = item.displayName:match('(.+) %(damage:.+%)') or item.displayName + list[key] = item else list[key].count = list[key].count + item.count end @@ -83,6 +81,7 @@ function page:depositAll() if (context.state.depositAll.includeHotbar or slot > 9) and item.name ~= 'plethora:neuralconnector' then context:sendRequest({ request = 'deposit', + source = 'inventory', slot = slot, count = item.count, }) diff --git a/milo/plugins/remote/setup.lua b/milo/plugins/remote/setup.lua new file mode 100644 index 0000000..1c08f9e --- /dev/null +++ b/milo/plugins/remote/setup.lua @@ -0,0 +1,87 @@ +local Config = require('config') +local UI = require('ui') +local Util = require('util') + +local colors = _G.colors +local fs = _G.fs + +local STARTUP_FILE = 'usr/autorun/miloRemote.lua' + +local context = ({ ... })[1] + +local setup = UI.SlideOut { + backgroundColor = colors.cyan, + titleBar = UI.TitleBar { + title = 'Remote Setup', + }, + form = UI.Form { + x = 2, ex = -2, y = 2, ey = -1, + [1] = UI.TextEntry { + formLabel = 'Server', formKey = 'server', + help = 'ID for the server', + shadowText = 'Milo server ID', + limit = 6, + validate = 'numeric', + required = true, + }, + [2] = UI.TextEntry { + formLabel = 'Return Slot', formKey = 'slot', + help = 'Use a slot for sending to storage', + shadowText = 'Inventory slot #', + limit = 5, + validate = 'numeric', + required = false, + }, + [3] = UI.Checkbox { + formLabel = 'Shield Slot', formKey = 'useShield', + help = 'Or, use the shield slot for sending' + }, + [4] = UI.Checkbox { + formLabel = 'Run on startup', formKey = 'runOnStartup', + help = 'Run this program on startup' + }, + info = UI.TextArea { + x = 1, ex = -1, y = 6, ey = -4, + textColor = colors.yellow, + marginLeft = 0, + marginRight = 0, + value = [[The Milo turtle must connect to a manipulator with a ]] .. + [[bound introspection module. The neural interface must ]] .. + [[also have an introspection module.]], + }, + }, + statusBar = UI.StatusBar { + backgroundColor = colors.cyan, + }, +} + +function setup:eventHandler(event) + if event.type == 'focus_change' then + self.statusBar:setStatus(event.focused.help) + + elseif event.type == 'form_complete' then + Config.update('miloRemote', context.state) + self:hide() + context.page:refresh('list') + context.page.grid:draw() + context.page:setFocus(context.page.statusBar.filter) + + if context.state.runOnStartup then + if not fs.exists(STARTUP_FILE) then + Util.writeFile(STARTUP_FILE, + [[os.sleep(1) +shell.openForegroundTab('packages/milo/MiloRemote')]]) + end + elseif fs.exists(STARTUP_FILE) then + fs.delete(STARTUP_FILE) + end + + elseif event.type == 'form_cancel' then + self:hide() + context.page:setFocus(context.page.statusBar.filter) + end + + return UI.SlideOut.eventHandler(self, event) +end + +context.page:add({ setup = setup })