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

@@ -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