mirror of
https://github.com/kepler155c/opus
synced 2025-01-22 21:26:53 +00:00
builder upgrade
This commit is contained in:
parent
74e93068fb
commit
72bd16502b
10
apps/Lua.lua
10
apps/Lua.lua
@ -68,9 +68,6 @@ end
|
||||
function page:enable()
|
||||
self:setFocus(self.prompt)
|
||||
UI.Page.enable(self)
|
||||
if not device then
|
||||
self.menuBar.Device:disable()
|
||||
end
|
||||
end
|
||||
|
||||
local function autocomplete(env, oLine, x)
|
||||
@ -131,6 +128,13 @@ function page:eventHandler(event)
|
||||
self.prompt:updateCursor()
|
||||
|
||||
elseif event.type == 'device' then
|
||||
if not _G.device then
|
||||
sandboxEnv.device = { }
|
||||
for _,side in pairs(peripheral.getNames()) do
|
||||
local key = string.format('%s:%s', peripheral.getType(side), side)
|
||||
sandboxEnv.device[ key ] = peripheral.wrap(side)
|
||||
end
|
||||
end
|
||||
self:setPrompt('device', true)
|
||||
self:executeStatement('device')
|
||||
|
||||
|
@ -86,7 +86,7 @@ local systemPage = UI.Page {
|
||||
grid = UI.ScrollingGrid {
|
||||
y = 4,
|
||||
values = {
|
||||
{ name = 'CC version', value = os.version() },
|
||||
{ name = 'CC version', value = os.getVersion() },
|
||||
{ name = 'Lua version', value = _VERSION },
|
||||
{ name = 'MC version', value = _MC_VERSION or 'unknown' },
|
||||
{ name = 'Disk free', value = Util.toBytes(fs.getFreeSpace('/')) },
|
||||
|
261
apps/builder.lua
261
apps/builder.lua
@ -11,11 +11,15 @@ local UI = require('ui')
|
||||
local Schematic = require('schematic')
|
||||
local Profile = require('profile')
|
||||
local TableDB = require('tableDB')
|
||||
local ChestProvider = require('chestProvider')
|
||||
local MEProvider = require('meProvider')
|
||||
local Blocks = require('blocks')
|
||||
local Point = require('point')
|
||||
|
||||
local ChestProvider = require('chestProvider')
|
||||
if os.getVersion() == 1.8 then
|
||||
ChestProvider = require('chestProvider18')
|
||||
end
|
||||
|
||||
Logger.filter('modem_send', 'event', 'ui')
|
||||
|
||||
if device.wireless_modem then
|
||||
@ -38,24 +42,10 @@ local Builder = {
|
||||
fuelItem = { id = 'minecraft:coal', dmg = 0 },
|
||||
resourceSlots = 15,
|
||||
facing = 'south',
|
||||
confirmFacing = false,
|
||||
}
|
||||
|
||||
-- these wrenches work relative to the turtle
|
||||
local GoodWrenches = {
|
||||
[ 'appliedEnergistics2:item.ToolCertusQuartzWrench' ] = true,
|
||||
[ 'appliedEnergistics2:item.ToolNetherQuartzWrench' ] = true,
|
||||
[ 'EnderIO:itemYetaWrench' ] = true,
|
||||
}
|
||||
|
||||
--[[
|
||||
-- these wrenches work but take more hits to turn a piston
|
||||
|
||||
local BadButUsableWrenches = {
|
||||
[ 'ThermalExpansion:wrench' ] = true,
|
||||
[ 'MineFactoryReloaded:hammer' ] = true,
|
||||
[ 'ImmersiveEngineering:tool' ] = true,
|
||||
}
|
||||
--]]
|
||||
local pistonFacings
|
||||
|
||||
--[[-- SubDB --]]--
|
||||
subDB = TableDB({
|
||||
@ -359,7 +349,7 @@ function Builder:getBlockCounts()
|
||||
local blocks = { }
|
||||
|
||||
-- add a couple essential items to the supply list to allow replacements
|
||||
local wrench = subDB:getSubstitutedItem('ThermalExpansion:wrench', 0)
|
||||
local wrench = subDB:getSubstitutedItem('SubstituteAWrench', 0)
|
||||
wrench.qty = 0
|
||||
wrench.need = 1
|
||||
blocks[wrench.id .. ':' .. wrench.dmg] = wrench
|
||||
@ -461,7 +451,7 @@ function Builder:getSupplyList(blockIndex)
|
||||
index = 15,
|
||||
}
|
||||
|
||||
local wrench = subDB:getSubstitutedItem('ThermalExpansion:wrench', 0)
|
||||
local wrench = subDB:getSubstitutedItem('SubstituteAWrench', 0)
|
||||
slots[16] = {
|
||||
id = wrench.id,
|
||||
dmg = wrench.dmg,
|
||||
@ -612,9 +602,7 @@ function Builder:getSupplies()
|
||||
if s.need > 0 then
|
||||
local item = self.itemProvider:getItemInfo(s.id, s.dmg)
|
||||
if item then
|
||||
if item.name then
|
||||
s.name = item.name
|
||||
end
|
||||
|
||||
local qty = math.min(s.need - s.qty, item.qty)
|
||||
|
||||
@ -629,6 +617,8 @@ function Builder:getSupplies()
|
||||
self.itemProvider:provide(item, qty, s.index)
|
||||
s.qty = turtle.getItemCount(s.index)
|
||||
end
|
||||
else
|
||||
s.name = blocks.blockDB:getName(s.id, s.dmg)
|
||||
end
|
||||
end
|
||||
if s.qty < s.need then
|
||||
@ -855,26 +845,83 @@ end
|
||||
|
||||
function Builder:getWrenchSlot()
|
||||
|
||||
local wrench = subDB:getSubstitutedItem('ThermalExpansion:wrench', 0)
|
||||
local wrench = subDB:getSubstitutedItem('SubstituteAWrench', 0)
|
||||
|
||||
return Builder:selectItem(wrench.id, wrench.dmg)
|
||||
end
|
||||
|
||||
function Builder:wrenchBlock(side, count)
|
||||
function Builder:getTurtleFacing()
|
||||
|
||||
if os.getVersion() == 1.8 then
|
||||
|
||||
local directions = { -- reversed directions
|
||||
[5] = 'west',
|
||||
[3] = 'north',
|
||||
[4] = 'east',
|
||||
[2] = 'south',
|
||||
}
|
||||
|
||||
if self:selectItem('minecraft:piston', 0) then
|
||||
turtle.placeUp()
|
||||
local _, bi = turtle.inspectUp()
|
||||
turtle.digUp()
|
||||
return directions[bi.metadata]
|
||||
end
|
||||
return
|
||||
end
|
||||
return Builder.facing
|
||||
end
|
||||
|
||||
function Builder:wrenchBlock(side, facing)
|
||||
|
||||
local s = Builder:getWrenchSlot()
|
||||
|
||||
if not s then
|
||||
b.needResupply = true
|
||||
return
|
||||
return false
|
||||
end
|
||||
|
||||
local key = turtle.point.heading .. '-' .. facing
|
||||
local count = pistonFacings[side][key]
|
||||
|
||||
if count then
|
||||
turtle.select(s.index)
|
||||
for i = 1,count do
|
||||
turtle.getAction(side).place()
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local directions = {
|
||||
[5] = 'east',
|
||||
[3] = 'south',
|
||||
[4] = 'west',
|
||||
[2] = 'north',
|
||||
[0] = 'down',
|
||||
[1] = 'up',
|
||||
}
|
||||
|
||||
if turtle.getHeadingInfo(facing).heading < 4 then
|
||||
local offsetDirection = (turtle.getHeadingInfo(Builder.facing).heading +
|
||||
turtle.getHeadingInfo(facing).heading) % 4
|
||||
facing = turtle.getHeadingInfo(offsetDirection).direction
|
||||
end
|
||||
|
||||
count = 0
|
||||
print('determining wrench count')
|
||||
for i = 1, 6 do
|
||||
local _, bi = turtle.getAction(side).inspect()
|
||||
local pistonFacing = directions[bi.metadata]
|
||||
|
||||
if facing == pistonFacing then
|
||||
pistonFacings[side][key] = count
|
||||
return true
|
||||
end
|
||||
count = count + 1
|
||||
turtle.getAction(side).place()
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- place piston, wrench piston to face downward, extend, remove piston
|
||||
@ -890,15 +937,10 @@ function Builder:placePiston(b)
|
||||
end
|
||||
|
||||
if not turtle.place(ps.index) then
|
||||
return false
|
||||
return
|
||||
end
|
||||
|
||||
local wrenchCount = 5
|
||||
if GoodWrenches[ws.id] then
|
||||
wrenchCount = 2
|
||||
end
|
||||
|
||||
local success = self:wrenchBlock('forward', wrenchCount) --wrench piston to point downwards
|
||||
local success = self:wrenchBlock('forward', 'down') --wrench piston to point downwards
|
||||
|
||||
rs.setOutput('front', true)
|
||||
os.sleep(.25)
|
||||
@ -907,7 +949,7 @@ function Builder:placePiston(b)
|
||||
turtle.select(ps.index)
|
||||
turtle.dig()
|
||||
|
||||
return true
|
||||
return success
|
||||
end
|
||||
|
||||
function Builder:goto(x, z, y, heading)
|
||||
@ -1008,6 +1050,10 @@ function Builder:placeDirectionalBlock(b, slot, travelPlane)
|
||||
local isSouth = (turtle.getHeadingInfo(Builder.facing).heading +
|
||||
turtle.getHeadingInfo(stairUpDirections[d]).heading) % 4 == 1
|
||||
|
||||
if os.getVersion() == 1.8 then
|
||||
isSouth = false -- no stair bug in this version
|
||||
end
|
||||
|
||||
if isSouth then
|
||||
|
||||
-- for some reason, the south facing stair doesn't place correctly
|
||||
@ -1058,6 +1104,7 @@ function Builder:placeDirectionalBlock(b, slot, travelPlane)
|
||||
[ 'piston-west' ] = 'west',
|
||||
[ 'piston-east' ] = 'east',
|
||||
[ 'piston-down' ] = 'down',
|
||||
[ 'piston-up' ] = 'up',
|
||||
}
|
||||
|
||||
if pistonDirections[d] then
|
||||
@ -1071,55 +1118,23 @@ function Builder:placeDirectionalBlock(b, slot, travelPlane)
|
||||
return false
|
||||
end
|
||||
|
||||
if GoodWrenches[ws.id] then
|
||||
-- piston turns relative to turtle position :)
|
||||
local rotatedPistonDirections = {
|
||||
[ 'piston-east' ] = 'south',
|
||||
[ 'piston-south' ] = 'west',
|
||||
[ 'piston-west' ] = 'north',
|
||||
[ 'piston-north' ] = 'east',
|
||||
[ 'piston-down' ] = 'down',
|
||||
[ 'piston-east' ] = 0,
|
||||
[ 'piston-south' ] = 1,
|
||||
[ 'piston-west' ] = 2,
|
||||
[ 'piston-north' ] = 3,
|
||||
}
|
||||
|
||||
local wrenchCount
|
||||
self:gotoEx(b.x, b.z, b.y, nil, travelPlane)
|
||||
|
||||
if d == 'piston-down' then
|
||||
self:gotoEx(b.x -1, b.z, b.y, 0, travelPlane)
|
||||
wrenchCount = 2
|
||||
else
|
||||
local hi = turtle.getHeadingInfo(rotatedPistonDirections[d])
|
||||
self:gotoEx(b.x + hi.xd, b.z + hi.zd, b.y, (hi.heading + 2) % 4, travelPlane)
|
||||
wrenchCount = 1
|
||||
end
|
||||
|
||||
if self:place(slot) then
|
||||
self:wrenchBlock('forward', wrenchCount)
|
||||
turtle.up()
|
||||
b.placed = self:placePiston(b)
|
||||
end
|
||||
|
||||
else -- cresent wrench
|
||||
-- piston turns relative to the world :(
|
||||
local wrenchCounts = {
|
||||
[ 1 ] = 4, -- east
|
||||
[ 2 ] = 2, -- south
|
||||
[ 3 ] = 3, -- west
|
||||
[ 4 ] = 1, -- north
|
||||
}
|
||||
|
||||
self:goto(b.x, b.z, b.y, nil, travelPlane)
|
||||
|
||||
local wrenchCount = 5
|
||||
|
||||
if d ~= 'piston-down' then
|
||||
local offsetDirection = (turtle.getHeadingInfo(Builder.facing).heading +
|
||||
turtle.getHeadingInfo(pistonDirections[d]).heading) % 4
|
||||
wrenchCount = wrenchCounts[offsetDirection + 1]
|
||||
local heading = rotatedPistonDirections[d]
|
||||
if heading and turtle.point.heading % 2 ~= heading % 2 then
|
||||
turtle.setHeading(heading)
|
||||
end
|
||||
|
||||
if self:placeDown(slot) then
|
||||
b.placed = self:wrenchBlock('down', wrenchCount)
|
||||
end
|
||||
b.placed = self:wrenchBlock('down', pistonDirections[d])
|
||||
end
|
||||
end
|
||||
|
||||
@ -1254,6 +1269,13 @@ function Builder:build()
|
||||
else
|
||||
travelPlane = self:findTravelPlane(self.index)
|
||||
turtle.status = 'building'
|
||||
if not self.confirmFacing then
|
||||
local facing = self:getTurtleFacing()
|
||||
if facing then
|
||||
self.confirmFacing = true
|
||||
self.facing = facing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
UI:setPage('blank')
|
||||
@ -1366,6 +1388,11 @@ function blankPage:draw()
|
||||
self:setCursorPos(1, 1)
|
||||
end
|
||||
|
||||
function blankPage:enable()
|
||||
self:sync()
|
||||
UI.Page.enable(self)
|
||||
end
|
||||
|
||||
--[[-- selectSubstitutionPage --]]--
|
||||
selectSubstitutionPage = UI.Page({
|
||||
titleBar = UI.TitleBar({
|
||||
@ -1524,6 +1551,7 @@ function substitutionPage:eventHandler(event)
|
||||
elseif event.type == 'accept' or event.type == 'air' or event.type == 'revert' then
|
||||
self.statusBar:setStatus('Saving changes...')
|
||||
self.statusBar:draw()
|
||||
self:sync()
|
||||
|
||||
if event.type == 'air' then
|
||||
self:applySubstitute('minecraft:air', 0)
|
||||
@ -1674,8 +1702,8 @@ listingPage = UI.Page({
|
||||
grid = UI.ScrollingGrid({
|
||||
columns = {
|
||||
{ heading = 'Name', key = 'name', width = UI.term.width - 14 },
|
||||
{ heading = 'Need', key = 'fNeed', width = 5 },
|
||||
{ heading = 'Have', key = 'fQty', width = 5 },
|
||||
{ heading = 'Need', key = 'need', width = 5 },
|
||||
{ heading = 'Have', key = 'qty', width = 5 },
|
||||
},
|
||||
sortColumn = 'name',
|
||||
y = 3,
|
||||
@ -1743,6 +1771,13 @@ function listingPage:eventHandler(event)
|
||||
return UI.Page.eventHandler(self, event)
|
||||
end
|
||||
|
||||
function listingPage.grid:getDisplayValues(row)
|
||||
row = Util.shallowCopy(row)
|
||||
row.need = Util.toBytes(row.need)
|
||||
row.qty = Util.toBytes(row.qty)
|
||||
return row
|
||||
end
|
||||
|
||||
function listingPage.grid:getRowTextColor(row, selected)
|
||||
if row.is_craftable then
|
||||
return colors.yellow
|
||||
@ -1759,13 +1794,15 @@ function listingPage:refresh()
|
||||
for _,b in pairs(supplyList) do
|
||||
if b.need > 0 then
|
||||
local item = Builder.itemProvider:getItemInfo(b.id, b.dmg)
|
||||
|
||||
if item then
|
||||
local block = blocks.blockDB:lookup(b.id, b.dmg)
|
||||
if not block then
|
||||
blocks.blockDB:add(b.id, b.dmg, item.name)
|
||||
blocks.blockDB:add(b.id, b.dmg, item.name, b.id)
|
||||
elseif not blocks.name and item.name then
|
||||
blocks.blockDB:add(b.id, b.dmg, item.name)
|
||||
end
|
||||
b.name = item.name
|
||||
b.qty = item.qty
|
||||
b.is_craftable = item.is_craftable
|
||||
elseif not b.name then
|
||||
@ -1775,19 +1812,17 @@ function listingPage:refresh()
|
||||
end
|
||||
blocks.blockDB:flush()
|
||||
|
||||
if self.fullList then
|
||||
self.grid:setValues(supplyList)
|
||||
else
|
||||
local t = {}
|
||||
for _,b in pairs(supplyList) do
|
||||
local block = blocks.blockDB:lookup(b.id, b.dmg)
|
||||
if block then
|
||||
b.name = block.name
|
||||
end
|
||||
if self.fullList or b.qty < b.need then
|
||||
table.insert(t, b)
|
||||
end
|
||||
b.fNeed = Util.toBytes(b.need)
|
||||
b.fQty = Util.toBytes(b.qty)
|
||||
end
|
||||
self.grid:setValues(t)
|
||||
end
|
||||
self.grid:setIndex(1)
|
||||
end
|
||||
|
||||
@ -1882,13 +1917,19 @@ function startPage:eventHandler(event)
|
||||
|
||||
if event.type == 'startLevel' then
|
||||
local dialog = UI.Dialog({
|
||||
text = UI.Text({ x = 5, y = 3, value = '0 - ' .. schematic.height }),
|
||||
textEntry = UI.TextEntry({ x = 15, y = 3, '0 - 11' })
|
||||
title = 'Enter Starting Level',
|
||||
height = 7,
|
||||
form = UI.Form {
|
||||
y = 3, x = 2, height = 4,
|
||||
text = UI.Text({ x = 5, y = 1, textColor = colors.gray, value = '0 - ' .. schematic.height }),
|
||||
textEntry = UI.TextEntry({ x = 15, y = 1, '0 - 11', width = 7 }),
|
||||
},
|
||||
statusBar = UI.StatusBar(),
|
||||
})
|
||||
|
||||
dialog.eventHandler = function(self, event)
|
||||
if event.type == 'accept' then
|
||||
local l = tonumber(self.textEntry.value)
|
||||
if event.type == 'form_complete' then
|
||||
local l = tonumber(self.form.textEntry.value)
|
||||
if l and l < schematic.height and l >= 0 then
|
||||
for k,v in pairs(schematic.blocks) do
|
||||
if v.y >= l then
|
||||
@ -1901,25 +1942,32 @@ function startPage:eventHandler(event)
|
||||
else
|
||||
self.statusBar:timedStatus('Invalid Level', 3)
|
||||
end
|
||||
elseif event.type == 'form_cancel' or event.type == 'cancel' then
|
||||
UI:setPreviousPage()
|
||||
else
|
||||
return UI.Dialog.eventHandler(self, event)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return UI.Dialog.eventHandler(self, event)
|
||||
end
|
||||
|
||||
dialog.titleBar.title = 'Enter Starting Level'
|
||||
dialog:setFocus(dialog.textEntry)
|
||||
dialog:setFocus(dialog.form.textEntry)
|
||||
UI:setPage(dialog)
|
||||
|
||||
elseif event.type == 'startBlock' then
|
||||
local dialog = UI.Dialog({
|
||||
text = UI.Text({ x = 5, y = 3, value = '1 - ' .. #schematic.blocks }),
|
||||
textEntry = UI.TextEntry({ x = 15, y = 3, value = tostring(Builder.index) })
|
||||
})
|
||||
local dialog = UI.Dialog {
|
||||
title = 'Enter Block Number',
|
||||
height = 7,
|
||||
form = UI.Form {
|
||||
y = 3, x = 2, height = 4,
|
||||
text = UI.Text { x = 5, y = 1, value = '1 - ' .. #schematic.blocks, textColor = colors.gray },
|
||||
textEntry = UI.TextEntry { x = 15, y = 1, value = tostring(Builder.index), width = 7 }
|
||||
},
|
||||
statusBar = UI.StatusBar(),
|
||||
}
|
||||
|
||||
dialog.eventHandler = function(self, event)
|
||||
if event.type == 'accept' then
|
||||
local bn = tonumber(self.textEntry.value)
|
||||
if event.type == 'form_complete' then
|
||||
local bn = tonumber(self.form.textEntry.value)
|
||||
if bn and bn < #schematic.blocks and bn >= 0 then
|
||||
Builder.index = bn
|
||||
Builder:saveProgress(Builder.index)
|
||||
@ -1927,14 +1975,15 @@ function startPage:eventHandler(event)
|
||||
else
|
||||
self.statusBar:timedStatus('Invalid Block', 3)
|
||||
end
|
||||
elseif event.type == 'form_cancel' or event.type == 'cancel' then
|
||||
UI:setPreviousPage()
|
||||
else
|
||||
return UI.Dialog.eventHandler(self, event)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return UI.Dialog.eventHandler(self, event)
|
||||
end
|
||||
|
||||
dialog.titleBar.title = 'Enter Block Number'
|
||||
dialog:setFocus(dialog.textEntry)
|
||||
dialog:setFocus(dialog.form.textEntry)
|
||||
UI:setPage(dialog)
|
||||
|
||||
elseif event.type == 'assignBlocks' then
|
||||
@ -1992,6 +2041,12 @@ function startPage:eventHandler(event)
|
||||
print('Starting build')
|
||||
end
|
||||
|
||||
-- reset piston cache in case wrench was substituted
|
||||
pistonFacings = {
|
||||
down = { },
|
||||
forward = { },
|
||||
}
|
||||
|
||||
Builder:build()
|
||||
Profile.display()
|
||||
|
||||
|
603
apps/refinedManager.lua
Normal file
603
apps/refinedManager.lua
Normal file
@ -0,0 +1,603 @@
|
||||
local injector = requireInjector or load(http.get('http://pastebin.com/raw/c0TWsScv').readAll())()
|
||||
require = injector(getfenv(1))
|
||||
local Event = require('event')
|
||||
local UI = require('ui')
|
||||
local Peripheral = require('peripheral')
|
||||
|
||||
local controller = Peripheral.getByType('refinedstorage:controller')
|
||||
if not controller then
|
||||
error('Refined storage controller not found')
|
||||
end
|
||||
|
||||
multishell.setTitle(multishell.getCurrent(), 'Storage Manager')
|
||||
|
||||
-- Strip off color prefix
|
||||
local function safeString(text)
|
||||
|
||||
local val = text:byte(1)
|
||||
|
||||
if val < 32 or val > 128 then
|
||||
|
||||
local newText = {}
|
||||
for i = 4, #text do
|
||||
local val = text:byte(i)
|
||||
newText[i - 3] = (val > 31 and val < 127) and val or 63
|
||||
end
|
||||
return string.char(unpack(newText))
|
||||
end
|
||||
|
||||
return text
|
||||
end
|
||||
|
||||
function listItems()
|
||||
local items = { }
|
||||
local list
|
||||
|
||||
pcall(function()
|
||||
list = controller.listAvailableItems()
|
||||
end)
|
||||
|
||||
if list then
|
||||
for k,v in pairs(list) do
|
||||
local item = controller.findItem(v)
|
||||
|
||||
if item then
|
||||
Util.merge(item, item.getMetadata())
|
||||
item.displayName = safeString(item.displayName)
|
||||
if item.maxDamage and item.maxDamage > 0 and item.damage > 0 then
|
||||
item.displayName = item.displayName .. ' (damaged)'
|
||||
end
|
||||
item.lname = item.displayName:lower()
|
||||
|
||||
table.insert(items, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return items
|
||||
end
|
||||
|
||||
function getItem(items, inItem, ignoreDamage)
|
||||
for _,item in pairs(items) do
|
||||
if item.name == inItem.name then
|
||||
if ignoreDamage and ignoreDamage == 'yes' then
|
||||
return item
|
||||
elseif item.damage == inItem.damage and item.nbtHash == inItem.nbtHash then
|
||||
return item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function uniqueKey(item)
|
||||
local key = item.name .. ':' .. item.damage
|
||||
if item.nbtHash then
|
||||
key = key .. ':' .. item.nbtHash
|
||||
end
|
||||
return key
|
||||
end
|
||||
|
||||
function mergeResources(t)
|
||||
local resources = Util.readTable('resource.limits')
|
||||
resources = resources or { }
|
||||
|
||||
for _,v in pairs(resources) do
|
||||
local item = getItem(t, v)
|
||||
if item then
|
||||
item.limit = tonumber(v.limit)
|
||||
item.low = tonumber(v.low)
|
||||
item.auto = v.auto
|
||||
item.ignoreDamage = v.ignoreDamage
|
||||
else
|
||||
v.count = 0
|
||||
v.limit = tonumber(v.limit)
|
||||
v.low = tonumber(v.low)
|
||||
v.auto = v.auto
|
||||
v.ignoreDamage = v.ignoreDamage
|
||||
table.insert(t, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function filterItems(t, filter)
|
||||
local r = {}
|
||||
if filter then
|
||||
filter = filter:lower()
|
||||
for k,v in pairs(t) do
|
||||
if string.find(v.lname, filter) then
|
||||
table.insert(r, v)
|
||||
end
|
||||
end
|
||||
else
|
||||
return t
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
function getJobList()
|
||||
local list = { }
|
||||
|
||||
for _,task in pairs(controller.getCraftingTasks()) do
|
||||
table.insert(list, task.getPattern().outputs[1])
|
||||
end
|
||||
|
||||
return list
|
||||
end
|
||||
|
||||
function craftItems(itemList, allItems)
|
||||
|
||||
for _,item in pairs(itemList) do
|
||||
|
||||
local alreadyCrafting = false
|
||||
local jobList = getJobList()
|
||||
|
||||
for _,v in pairs(jobList) do
|
||||
if v.name == item.name and v.damage == item.damage and v.nbtHash == item.nbtHash then
|
||||
alreadyCrafting = true
|
||||
end
|
||||
end
|
||||
|
||||
local cItem = getItem(allItems, item)
|
||||
|
||||
if alreadyCrafting then
|
||||
item.status = '(crafting)'
|
||||
elseif not cItem then
|
||||
item.status = '(no recipe)'
|
||||
else
|
||||
|
||||
local count = item.count
|
||||
while count >= 1 do -- try to request smaller quantities until successful
|
||||
local s, m = pcall(function()
|
||||
item.status = '(no recipe)'
|
||||
if not cItem.craft(count) then
|
||||
item.status = '(missing ingredients)'
|
||||
error('failed')
|
||||
end
|
||||
item.status = '(crafting)'
|
||||
end)
|
||||
if s then
|
||||
break -- successfully requested crafting
|
||||
end
|
||||
count = math.floor(count / 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function getAutocraftItems(items)
|
||||
local t = Util.readTable('resource.limits') or { }
|
||||
local itemList = { }
|
||||
|
||||
for _,res in pairs(t) do
|
||||
|
||||
if res.auto and res.auto == 'yes' then
|
||||
res.count = 4 -- this could be higher to increase autocrafting speed
|
||||
table.insert(itemList, res)
|
||||
end
|
||||
end
|
||||
return itemList
|
||||
end
|
||||
|
||||
local function getItemWithQty(items, res, ignoreDamage)
|
||||
|
||||
local item = getItem(items, res, ignoreDamage)
|
||||
|
||||
if item then
|
||||
|
||||
if ignoreDamage and ignoreDamage == 'yes' then
|
||||
local count = 0
|
||||
|
||||
for _,v in pairs(items) do
|
||||
if item.name == v.name and item.nbtHash == v.nbtHash then
|
||||
if item.maxDamage > 0 or item.damage == v.damage then
|
||||
count = count + v.count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
item.count = count
|
||||
end
|
||||
end
|
||||
|
||||
return item
|
||||
end
|
||||
|
||||
function watchResources(items)
|
||||
|
||||
local itemList = { }
|
||||
|
||||
local t = Util.readTable('resource.limits') or { }
|
||||
for k, res in pairs(t) do
|
||||
local item = getItemWithQty(items, res, res.ignoreDamage)
|
||||
res.limit = tonumber(res.limit)
|
||||
res.low = tonumber(res.low)
|
||||
if not item then
|
||||
item = {
|
||||
damage = res.damage,
|
||||
nbtHash = res.nbtHash,
|
||||
name = res.name,
|
||||
displayName = res.displayName,
|
||||
count = 0
|
||||
}
|
||||
end
|
||||
|
||||
if res.low and item.count < res.low then
|
||||
if res.ignoreDamage and res.ignoreDamage == 'yes' then
|
||||
item.damage = 0
|
||||
end
|
||||
table.insert(itemList, {
|
||||
damage = item.damage,
|
||||
nbtHash = item.nbtHash,
|
||||
count = res.low - item.count,
|
||||
name = item.name,
|
||||
displayName = item.displayName,
|
||||
status = ''
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return itemList
|
||||
end
|
||||
|
||||
itemPage = UI.Page {
|
||||
backgroundColor = colors.lightGray,
|
||||
titleBar = UI.TitleBar {
|
||||
title = 'Limit Resource',
|
||||
previousPage = true,
|
||||
event = 'form_cancel',
|
||||
backgroundColor = colors.green
|
||||
},
|
||||
displayName = UI.Window {
|
||||
x = 5, y = 3, width = UI.term.width - 10, height = 3,
|
||||
},
|
||||
form = UI.Form {
|
||||
x = 4, y = 6, height = 8, rex = -4,
|
||||
[1] = UI.TextEntry {
|
||||
width = 7,
|
||||
backgroundColor = colors.gray,
|
||||
backgroundFocusColor = colors.gray,
|
||||
formLabel = 'Min', formKey = 'low', help = 'Craft if below min'
|
||||
},
|
||||
[2] = UI.Chooser {
|
||||
width = 7,
|
||||
formLabel = 'Autocraft', formKey = 'auto',
|
||||
nochoice = 'No',
|
||||
choices = {
|
||||
{ name = 'Yes', value = 'yes' },
|
||||
{ name = 'No', value = 'no' },
|
||||
},
|
||||
help = 'Craft until out of ingredients'
|
||||
},
|
||||
[3] = UI.Chooser {
|
||||
width = 7,
|
||||
formLabel = 'Ignore Dmg', formKey = 'ignoreDamage',
|
||||
nochoice = 'No',
|
||||
choices = {
|
||||
{ name = 'Yes', value = 'yes' },
|
||||
{ name = 'No', value = 'no' },
|
||||
},
|
||||
help = 'Ignore damage of item'
|
||||
},
|
||||
},
|
||||
statusBar = UI.StatusBar { }
|
||||
}
|
||||
|
||||
function itemPage.displayName:draw()
|
||||
local item = self.parent.item
|
||||
local str = string.format('Name: %s\nDamage: %d', item.displayName, item.damage)
|
||||
if item.nbtHash then
|
||||
str = str .. string.format('\nNBT: %s\n', item.nbtHash)
|
||||
end
|
||||
debug(str)
|
||||
self:setCursorPos(1, 1)
|
||||
self:print(str)
|
||||
end
|
||||
|
||||
function itemPage:enable(item)
|
||||
self.item = item
|
||||
|
||||
self.form:setValues(item)
|
||||
self.titleBar.title = item.name
|
||||
self.displayName.value = item.displayName
|
||||
|
||||
UI.Page.enable(self)
|
||||
self:focusFirst()
|
||||
end
|
||||
|
||||
function itemPage:eventHandler(event)
|
||||
if event.type == 'form_cancel' then
|
||||
UI:setPreviousPage()
|
||||
|
||||
elseif event.type == 'focus_change' then
|
||||
self.statusBar:setStatus(event.focused.help)
|
||||
self.statusBar:draw()
|
||||
|
||||
elseif event.type == 'form_complete' then
|
||||
local values = self.form.values
|
||||
local t = Util.readTable('resource.limits') or { }
|
||||
for k,v in pairs(t) do
|
||||
if v.name == values.name and v.damage == values.damage then
|
||||
t[k] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
local keys = { 'name', 'displayName', 'auto', 'low', 'damage', 'maxDamage', 'nbtHash', 'limit', 'ignoreDamage' }
|
||||
local filtered = { }
|
||||
for _,key in pairs(keys) do
|
||||
filtered[key] = values[key]
|
||||
end
|
||||
|
||||
if filtered.ignoreDamage and filtered.ignoreDamage == 'yes' then
|
||||
filtered.damage = 0
|
||||
end
|
||||
|
||||
t[uniqueKey(filtered)] = filtered
|
||||
--table.insert(t, filtered)
|
||||
Util.writeTable('resource.limits', t)
|
||||
UI:setPreviousPage()
|
||||
|
||||
else
|
||||
return UI.Page.eventHandler(self, event)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
listingPage = UI.Page {
|
||||
menuBar = UI.MenuBar {
|
||||
buttons = {
|
||||
{ text = 'Forget', event = 'forget' },
|
||||
},
|
||||
},
|
||||
grid = UI.Grid {
|
||||
y = 2, height = UI.term.height - 2,
|
||||
columns = {
|
||||
{ heading = 'Name', key = 'displayName', width = UI.term.width - 14 },
|
||||
{ heading = 'Qty', key = 'count', width = 5 },
|
||||
{ heading = 'Min', key = 'low', width = 4 },
|
||||
},
|
||||
sortColumn = 'lname',
|
||||
},
|
||||
statusBar = UI.StatusBar {
|
||||
backgroundColor = colors.gray,
|
||||
width = UI.term.width,
|
||||
filterText = UI.Text {
|
||||
x = 2, width = 6,
|
||||
value = 'Filter',
|
||||
},
|
||||
filter = UI.TextEntry {
|
||||
x = 9, rex = -12,
|
||||
limit = 50,
|
||||
},
|
||||
refresh = UI.Button {
|
||||
rx = -9, width = 8,
|
||||
text = 'Refresh',
|
||||
event = 'refresh',
|
||||
},
|
||||
},
|
||||
accelerators = {
|
||||
r = 'refresh',
|
||||
q = 'quit',
|
||||
}
|
||||
}
|
||||
|
||||
function listingPage.grid:getRowTextColor(row, selected)
|
||||
if row.is_craftable then -- not implemented
|
||||
return colors.yellow
|
||||
end
|
||||
return UI.Grid:getRowTextColor(row, selected)
|
||||
end
|
||||
|
||||
function listingPage.grid:getDisplayValues(row)
|
||||
row = Util.shallowCopy(row)
|
||||
row.count = Util.toBytes(row.count)
|
||||
if row.low then
|
||||
row.low = Util.toBytes(row.low)
|
||||
end
|
||||
if row.limit then
|
||||
row.limit = Util.toBytes(row.limit)
|
||||
end
|
||||
return row
|
||||
end
|
||||
|
||||
function listingPage.statusBar:draw()
|
||||
return UI.Window.draw(self)
|
||||
end
|
||||
|
||||
function listingPage.statusBar.filter:eventHandler(event)
|
||||
if event.type == 'mouse_rightclick' then
|
||||
self.value = ''
|
||||
self:draw()
|
||||
local page = UI:getCurrentPage()
|
||||
page.filter = nil
|
||||
page:applyFilter()
|
||||
page.grid:draw()
|
||||
page:setFocus(self)
|
||||
end
|
||||
return UI.TextEntry.eventHandler(self, event)
|
||||
end
|
||||
|
||||
function listingPage:eventHandler(event)
|
||||
if event.type == 'quit' then
|
||||
Event.exitPullEvents()
|
||||
|
||||
elseif event.type == 'grid_select' then
|
||||
local selected = event.selected
|
||||
UI:setPage('item', selected)
|
||||
|
||||
elseif event.type == 'refresh' then
|
||||
self:refresh()
|
||||
self.grid:draw()
|
||||
|
||||
elseif event.type == 'forget' then
|
||||
local item = self.grid:getSelected()
|
||||
if item then
|
||||
|
||||
local resources = Util.readTable('resource.limits') or { }
|
||||
resources[uniqueKey(item)] = nil
|
||||
Util.writeTable('resource.limits', resources)
|
||||
|
||||
self.statusBar:timedStatus('Forgot: ' .. item.name, 3)
|
||||
self:refresh()
|
||||
self.grid:draw()
|
||||
end
|
||||
|
||||
elseif event.type == 'text_change' then
|
||||
self.filter = event.text
|
||||
if #self.filter == 0 then
|
||||
self.filter = nil
|
||||
end
|
||||
self:applyFilter()
|
||||
self.grid:draw()
|
||||
self.statusBar.filter:focus()
|
||||
|
||||
else
|
||||
UI.Page.eventHandler(self, event)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function listingPage:enable()
|
||||
self:refresh()
|
||||
self:setFocus(self.statusBar.filter)
|
||||
UI.Page.enable(self)
|
||||
end
|
||||
|
||||
function listingPage:refresh()
|
||||
self.allItems = listItems()
|
||||
mergeResources(self.allItems)
|
||||
self:applyFilter()
|
||||
end
|
||||
|
||||
function listingPage:applyFilter()
|
||||
local t = filterItems(self.allItems, self.filter)
|
||||
self.grid:setValues(t)
|
||||
end
|
||||
|
||||
local nullDevice = {
|
||||
setCursorPos = function(...) end,
|
||||
write = function(...) end,
|
||||
getSize = function() return 13, 20 end,
|
||||
isColor = function() return false end,
|
||||
setBackgroundColor = function(...) end,
|
||||
setTextColor = function(...) end,
|
||||
clear = function(...) end,
|
||||
sync = function(...) end,
|
||||
}
|
||||
|
||||
local function jobMonitor(jobList)
|
||||
|
||||
local mon = Peripheral.getByType('monitor')
|
||||
|
||||
if mon then
|
||||
mon = UI.Device({
|
||||
device = mon,
|
||||
textScale = .5,
|
||||
})
|
||||
else
|
||||
mon = UI.Device({
|
||||
device = nullDevice
|
||||
})
|
||||
end
|
||||
|
||||
jobListGrid = UI.Grid {
|
||||
parent = mon,
|
||||
sortColumn = 'displayName',
|
||||
columns = {
|
||||
{ heading = 'Qty', key = 'count', width = 6 },
|
||||
{ heading = 'Crafting', key = 'displayName', width = mon.width / 2 - 10 },
|
||||
{ heading = 'Status', key = 'status', width = mon.width - 10 },
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
local function jobMonitor(jobList)
|
||||
|
||||
local mon = Peripheral.getByType('monitor')
|
||||
local nullDevice = {
|
||||
setCursorPos = function(...) end,
|
||||
write = function(...) end,
|
||||
getSize = function() return 13, 20 end,
|
||||
isColor = function() return false end,
|
||||
setBackgroundColor = function(...) end,
|
||||
setTextColor = function(...) end,
|
||||
clear = function(...) end,
|
||||
sync = function(...) end,
|
||||
blit = function(...) end,
|
||||
}
|
||||
|
||||
if mon then
|
||||
mon = UI.Device({
|
||||
device = mon,
|
||||
textScale = .5,
|
||||
})
|
||||
else
|
||||
mon = UI.Device({
|
||||
device = nullDevice
|
||||
})
|
||||
end
|
||||
|
||||
jobListGrid = UI.Grid {
|
||||
parent = mon,
|
||||
sortColumn = 'displayName',
|
||||
columns = {
|
||||
{ heading = 'Qty', key = 'count', width = 6 },
|
||||
{ heading = 'Crafting', key = 'displayName', width = mon.width / 2 - 10 },
|
||||
{ heading = 'Status', key = 'status', width = mon.width - 10 },
|
||||
},
|
||||
}
|
||||
|
||||
return jobListGrid
|
||||
end
|
||||
|
||||
UI:setPages({
|
||||
listing = listingPage,
|
||||
item = itemPage,
|
||||
})
|
||||
|
||||
UI:setPage(listingPage)
|
||||
listingPage:setFocus(listingPage.statusBar.filter)
|
||||
|
||||
local jobListGrid = jobMonitor()
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
|
||||
function craftingThread()
|
||||
|
||||
while true do
|
||||
os.sleep(5)
|
||||
|
||||
pcall(function()
|
||||
|
||||
local items = listItems()
|
||||
|
||||
if controller.getNetworkEnergyStored() == 0 then
|
||||
jobListGrid.parent:clear()
|
||||
jobListGrid.parent:centeredWrite(math.ceil(jobListGrid.parent.height/2), 'Power failure')
|
||||
jobListGrid:sync()
|
||||
|
||||
elseif Util.size(items) == 0 then
|
||||
jobListGrid.parent:clear()
|
||||
jobListGrid.parent:centeredWrite(math.ceil(jobListGrid.parent.height/2), 'No items in system')
|
||||
jobListGrid:sync()
|
||||
|
||||
else
|
||||
local itemList = watchResources(items)
|
||||
jobListGrid:setValues(itemList)
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
craftItems(itemList, items)
|
||||
jobListGrid:update()
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
|
||||
itemList = getAutocraftItems(items) -- autocrafted items don't show on job monitor
|
||||
craftItems(itemList, items)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
Event.pullEvents(craftingThread)
|
||||
|
||||
UI.term:reset()
|
||||
jobListGrid.parent:reset()
|
@ -24,6 +24,11 @@ local options = {
|
||||
|
||||
local MIN_FUEL = 7500
|
||||
local LOW_FUEL = 1500
|
||||
local MAX_FUEL = 100000
|
||||
|
||||
if not term.isColor() then
|
||||
MAX_FUEL = 20000
|
||||
end
|
||||
|
||||
local mining = {
|
||||
diameter = 1,
|
||||
@ -175,6 +180,7 @@ end
|
||||
|
||||
function refuel()
|
||||
if turtle.getFuelLevel() < MIN_FUEL then
|
||||
local oldStatus = turtle.status
|
||||
status('refueling')
|
||||
|
||||
if turtle.selectSlot('minecraft:coal:0') then
|
||||
@ -193,7 +199,7 @@ function refuel()
|
||||
end)
|
||||
end
|
||||
log('Fuel: ' .. turtle.getFuelLevel())
|
||||
status('boring')
|
||||
status(oldStatus)
|
||||
end
|
||||
|
||||
turtle.select(1)
|
||||
@ -315,7 +321,7 @@ function mineable(action)
|
||||
collectDrops(action.suck)
|
||||
end
|
||||
|
||||
if turtle.getFuelLevel() < 99000 then
|
||||
if turtle.getFuelLevel() < (MAX_FUEL - 1000) then
|
||||
if block.name == 'minecraft:lava' or block.name == 'minecraft:flowing_lava' then
|
||||
if turtle.selectSlot('minecraft:bucket:0') then
|
||||
if action.place() then
|
||||
@ -546,6 +552,7 @@ end
|
||||
local function main()
|
||||
repeat
|
||||
while #mining.locations > 0 do
|
||||
status('searching')
|
||||
if not boreCommand() then
|
||||
return
|
||||
end
|
||||
|
@ -6,6 +6,11 @@ local Point = require('point')
|
||||
local TableDB = require('tableDB')
|
||||
local MEProvider = require('meProvider')
|
||||
|
||||
local ChestProvider = require('chestProvider')
|
||||
if os.getVersion() == 1.8 then
|
||||
ChestProvider = require('chestProvider18')
|
||||
end
|
||||
|
||||
if not device.wireless_modem then
|
||||
error('No wireless modem detected')
|
||||
end
|
||||
@ -324,9 +329,9 @@ Message.addHandler('needSupplies',
|
||||
turtle.select(15)
|
||||
turtle.placeDown()
|
||||
os.sleep(.1) -- random computer not connected error
|
||||
local p = peripheral.wrap('bottom')
|
||||
local p = ChestProvider({ direction = 'up', wrapSide = 'bottom' })
|
||||
for i = 1, 16 do
|
||||
p.pullItem('up', i, 64)
|
||||
p:insert(i, 64)
|
||||
end
|
||||
|
||||
Message.send(__BUILDER_ID, 'gotSupplies', { supplies = true, point = pt })
|
||||
@ -334,9 +339,9 @@ Message.addHandler('needSupplies',
|
||||
Message.waitForMessage('thanks', 5, __BUILDER_ID)
|
||||
--os.sleep(0)
|
||||
|
||||
p.condenseItems()
|
||||
--p.condenseItems()
|
||||
for i = 1, 16 do
|
||||
p.pushItem('up', i, 64)
|
||||
p:extract(i, 64)
|
||||
end
|
||||
turtle.digDown()
|
||||
turtle.status = 'waiting'
|
||||
@ -386,6 +391,12 @@ turtle.setPoint({ x = -1, z = -2, y = 0, heading = 0 })
|
||||
turtle.saveLocation('supplies')
|
||||
|
||||
Builder.itemProvider = MEProvider()
|
||||
if not Builder.itemProvider:isValid() then
|
||||
Builder.itemProvider = ChestProvider()
|
||||
if not Builder.itemProvider:isValid() then
|
||||
error('A chest or ME interface must be below turtle')
|
||||
end
|
||||
end
|
||||
|
||||
turtle.run(function()
|
||||
Event.pullEvents(onTheWay)
|
||||
|
@ -96,15 +96,13 @@ function blockDB:seedDB(dir)
|
||||
end
|
||||
lastID = strId
|
||||
|
||||
local sep = string.find(line[2], ':')
|
||||
if not sep then
|
||||
nid = tonumber(line[2])
|
||||
local t = { }
|
||||
string.gsub(line[2], '(%d+)', function(d) table.insert(t, d) end)
|
||||
nid = tonumber(t[1])
|
||||
dmg = 0
|
||||
else
|
||||
nid = tonumber(string.sub(line[2], 1, sep - 1))
|
||||
dmg = tonumber(string.sub(line[2], sep + 1, #line[2]))
|
||||
if t[2] then
|
||||
dmg = tonumber(t[2])
|
||||
end
|
||||
|
||||
self:add(nid, dmg, name, strId)
|
||||
end
|
||||
|
||||
@ -653,13 +651,13 @@ function blockTypeDB:seedDB()
|
||||
})
|
||||
blockTypeDB:addTemp('piston', { -- piston placement is broken in 1.7 -- need to add work around
|
||||
{ 0, nil, 0, 'piston-down' },
|
||||
{ 1, nil, 0 },
|
||||
{ 1, nil, 0, 'piston-up' },
|
||||
{ 2, nil, 0, 'piston-north' },
|
||||
{ 3, nil, 0, 'piston-south' },
|
||||
{ 4, nil, 0, 'piston-west' },
|
||||
{ 5, nil, 0, 'piston-east' },
|
||||
{ 8, nil, 0, 'piston-down' },
|
||||
{ 9, nil, 0 },
|
||||
{ 9, nil, 0, 'piston-up' },
|
||||
{ 10, nil, 0, 'piston-north' },
|
||||
{ 11, nil, 0, 'piston-south' },
|
||||
{ 12, nil, 0, 'piston-west' },
|
||||
|
@ -54,7 +54,9 @@ function ChestProvider:getItemInfo(id, dmg)
|
||||
item.max_size = stack.max_size
|
||||
end
|
||||
end
|
||||
if item.name then
|
||||
return item
|
||||
end
|
||||
end
|
||||
|
||||
function ChestProvider:craft(id, dmg, qty)
|
||||
@ -80,6 +82,12 @@ function ChestProvider:provide(item, qty, slot)
|
||||
end
|
||||
end
|
||||
|
||||
function ChestProvider:extract(slot, qty)
|
||||
if self.p then
|
||||
self.p.pushItem(self.direction, slot, qty)
|
||||
end
|
||||
end
|
||||
|
||||
function ChestProvider:insert(slot, qty)
|
||||
if self.p then
|
||||
local s, m = pcall(function() self.p.pullItem(self.direction, slot, qty) end)
|
||||
|
103
sys/apis/chestProvider18.lua
Normal file
103
sys/apis/chestProvider18.lua
Normal file
@ -0,0 +1,103 @@
|
||||
local class = require('class')
|
||||
local Logger = require('logger')
|
||||
|
||||
local ChestProvider = class()
|
||||
|
||||
function ChestProvider:init(args)
|
||||
|
||||
args = args or { }
|
||||
|
||||
self.stacks = {}
|
||||
self.name = 'chest'
|
||||
self.direction = args.direction or 'up'
|
||||
self.wrapSide = args.wrapSide or 'bottom'
|
||||
self.p = peripheral.wrap(self.wrapSide)
|
||||
end
|
||||
|
||||
function ChestProvider:isValid()
|
||||
return self.p and self.p.list
|
||||
end
|
||||
|
||||
function ChestProvider:refresh()
|
||||
if self.p then
|
||||
--self.p.condenseItems()
|
||||
self.stacks = self.p.list()
|
||||
local t = { }
|
||||
for _,s in pairs(self.stacks) do
|
||||
s.id = s.name
|
||||
s.dmg = s.damage
|
||||
s.qty = s.count
|
||||
local key = s.id .. ':' .. s.dmg
|
||||
if t[key] and t[key].qty < 64 then
|
||||
t[key].max_size = t[key].qty
|
||||
else
|
||||
t[key] = {
|
||||
qty = s.qty
|
||||
}
|
||||
end
|
||||
end
|
||||
for _,s in ipairs(self.stacks) do
|
||||
local key = s.id .. ':' .. s.dmg
|
||||
if t[key].max_size then
|
||||
s.max_size = t[key].qty
|
||||
else
|
||||
s.max_size = 64
|
||||
end
|
||||
end
|
||||
end
|
||||
return self.stacks
|
||||
end
|
||||
|
||||
function ChestProvider:getItemInfo(id, dmg)
|
||||
local item = { id = id, dmg = dmg, qty = 0, max_size = 64 }
|
||||
for k,stack in pairs(self.stacks) do
|
||||
if stack.id == id and stack.dmg == dmg then
|
||||
local meta = self.p.getItemMeta(k)
|
||||
if meta then
|
||||
item.name = meta.displayName
|
||||
item.qty = item.qty + meta.count
|
||||
item.max_size = meta.maxCount
|
||||
end
|
||||
end
|
||||
end
|
||||
if item.name then
|
||||
return item
|
||||
end
|
||||
end
|
||||
|
||||
function ChestProvider:craft(id, dmg, qty)
|
||||
return false
|
||||
end
|
||||
|
||||
function ChestProvider:craftItems(items)
|
||||
end
|
||||
|
||||
function ChestProvider:provide(item, qty, slot)
|
||||
if self.p then
|
||||
self:refresh()
|
||||
for key,stack in pairs(self.stacks) do
|
||||
if stack.id == item.id and stack.dmg == item.dmg then
|
||||
local amount = math.min(qty, stack.qty)
|
||||
self.p.pushItems(self.direction, key, amount, slot)
|
||||
qty = qty - amount
|
||||
if qty <= 0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ChestProvider:extract(slot, qty)
|
||||
if self.p then
|
||||
self.p.pushItems(self.direction, slot, qty)
|
||||
end
|
||||
end
|
||||
|
||||
function ChestProvider:insert(slot, qty)
|
||||
if self.p then
|
||||
self.p.pullItems(self.direction, slot, qty)
|
||||
end
|
||||
end
|
||||
|
||||
return ChestProvider
|
@ -1,6 +1,21 @@
|
||||
local Peripheral = { }
|
||||
|
||||
function Peripheral.addDevice(side)
|
||||
local function getDeviceList()
|
||||
|
||||
if _G.device then
|
||||
return _G.device
|
||||
end
|
||||
|
||||
local deviceList = { }
|
||||
|
||||
for _,side in pairs(peripheral.getNames()) do
|
||||
Peripheral.addDevice(deviceList, side)
|
||||
end
|
||||
|
||||
return deviceList
|
||||
end
|
||||
|
||||
function Peripheral.addDevice(deviceList, side)
|
||||
local name = side
|
||||
local ptype = peripheral.getType(side)
|
||||
|
||||
@ -28,33 +43,33 @@ function Peripheral.addDevice(side)
|
||||
if sides[name] then
|
||||
local i = 1
|
||||
local uniqueName = ptype
|
||||
while device[uniqueName] do
|
||||
while deviceList[uniqueName] do
|
||||
uniqueName = ptype .. '_' .. i
|
||||
i = i + 1
|
||||
end
|
||||
name = uniqueName
|
||||
end
|
||||
|
||||
device[name] = peripheral.wrap(side)
|
||||
Util.merge(device[name], {
|
||||
deviceList[name] = peripheral.wrap(side)
|
||||
Util.merge(deviceList[name], {
|
||||
name = name,
|
||||
type = ptype,
|
||||
side = side,
|
||||
})
|
||||
|
||||
return device[name]
|
||||
return deviceList[name]
|
||||
end
|
||||
|
||||
function Peripheral.getBySide(side)
|
||||
return Util.find(device, 'side', side)
|
||||
return Util.find(getDeviceList(), 'side', side)
|
||||
end
|
||||
|
||||
function Peripheral.getByType(typeName)
|
||||
return Util.find(device, 'type', typeName)
|
||||
return Util.find(getDeviceList(), 'type', typeName)
|
||||
end
|
||||
|
||||
function Peripheral.getByMethod(method)
|
||||
for _,p in pairs(device) do
|
||||
for _,p in pairs(getDeviceList()) do
|
||||
if p[method] then
|
||||
return p
|
||||
end
|
||||
|
@ -438,6 +438,7 @@ end
|
||||
|
||||
function Manager:pullEvents(...)
|
||||
Event.pullEvents(...)
|
||||
self.term:reset()
|
||||
end
|
||||
|
||||
function Manager:exitPullEvents()
|
||||
@ -1075,7 +1076,7 @@ function UI.TransitionSlideLeft:update(device)
|
||||
self.canvas:blit(device, {
|
||||
x = self.x,
|
||||
y = self.y,
|
||||
ex = self.ex - x + self.x + 1,
|
||||
ex = self.ex - x + self.x,
|
||||
ey = self.ey },
|
||||
{ x = x, y = self.y })
|
||||
end
|
||||
@ -1108,13 +1109,13 @@ function UI.TransitionSlideRight:update(device)
|
||||
self.lastScreen:blit(device, {
|
||||
x = self.x,
|
||||
y = self.y,
|
||||
ex = self.ex - x + self.x + 1,
|
||||
ex = self.ex - x + self.x,
|
||||
ey = self.ey },
|
||||
{ x = x, y = self.y })
|
||||
self.canvas:blit(device, {
|
||||
x = self.ex - x + self.x,
|
||||
y = self.y,
|
||||
ex = self.ex + 1,
|
||||
ex = self.ex,
|
||||
ey = self.ey },
|
||||
{ x = self.x, y = self.y })
|
||||
end
|
||||
@ -1431,8 +1432,6 @@ end
|
||||
UI.Grid = class(UI.Window)
|
||||
UI.Grid.defaults = {
|
||||
UIElement = 'Grid',
|
||||
x = 1,
|
||||
y = 1,
|
||||
index = 1,
|
||||
inverseSort = false,
|
||||
disableHeader = false,
|
||||
@ -2571,7 +2570,7 @@ UI.StatusBar.defaults = {
|
||||
function UI.StatusBar:init(args)
|
||||
local defaults = UI:getDefaults(UI.StatusBar, args)
|
||||
UI.GridLayout.init(self, defaults)
|
||||
self:setStatus(self.status)
|
||||
self:setStatus(self.status, true)
|
||||
end
|
||||
|
||||
function UI.StatusBar:setParent()
|
||||
@ -2583,12 +2582,15 @@ function UI.StatusBar:setParent()
|
||||
end
|
||||
end
|
||||
|
||||
function UI.StatusBar:setStatus(status)
|
||||
function UI.StatusBar:setStatus(status, noDraw)
|
||||
if type(status) == 'string' then
|
||||
self.values[1] = { status = status }
|
||||
else
|
||||
self.values[1] = status
|
||||
end
|
||||
if not noDraw then
|
||||
self:draw()
|
||||
end
|
||||
end
|
||||
|
||||
function UI.StatusBar:setValue(name, value)
|
||||
@ -2796,7 +2798,8 @@ function UI.TextEntry:updateScroll()
|
||||
elseif self.pos < self.scroll then
|
||||
self.scroll = self.pos
|
||||
end
|
||||
-- debug('p:%d s:%d w:%d l:%d', self.pos, self.scroll, self.width, self.limit)
|
||||
|
||||
--debug('p:%d s:%d w:%d l:%d', self.pos, self.scroll, self.width, self.limit)
|
||||
end
|
||||
|
||||
function UI.TextEntry:draw()
|
||||
@ -2910,7 +2913,7 @@ function UI.TextEntry:eventHandler(event)
|
||||
return true
|
||||
|
||||
elseif event.type == 'mouse_click' then
|
||||
if self.focused then
|
||||
if self.focused and event.x > 1 then
|
||||
self.pos = event.x + self.scroll - 2
|
||||
self:updateCursor()
|
||||
return true
|
||||
@ -3166,7 +3169,7 @@ function UI.Dialog:init(args)
|
||||
titleBar = UI.TitleBar({ previousPage = true, title = defaults.title }),
|
||||
})
|
||||
|
||||
UI.setProperties(defaults, args)
|
||||
--UI.setProperties(defaults, args)
|
||||
UI.Page.init(self, defaults)
|
||||
end
|
||||
|
||||
@ -3266,8 +3269,8 @@ function UI.NftImage:setImage(image)
|
||||
end
|
||||
|
||||
UI:loadTheme('config/ui.theme')
|
||||
if _HOST and string.find(_HOST, 'CCEmuRedux') then
|
||||
UI:loadTheme('config/ccemuredux.theme')
|
||||
if os.getVersion() >= 1.79 then
|
||||
UI:loadTheme('config/ext.theme')
|
||||
end
|
||||
|
||||
UI:setDefaultDevice(UI.Device({ device = term.current() }))
|
||||
|
@ -4,5 +4,5 @@ require = requireInjector(getfenv(1))
|
||||
local Peripheral = require('peripheral')
|
||||
|
||||
for _,side in pairs(peripheral.getNames()) do
|
||||
Peripheral.addDevice(side)
|
||||
Peripheral.addDevice(device, side)
|
||||
end
|
||||
|
@ -90,6 +90,16 @@ function os.isPocket()
|
||||
return not not pocket
|
||||
end
|
||||
|
||||
function os.getVersion()
|
||||
if _CC_VERSION then
|
||||
return tonumber(_CC_VERSION)
|
||||
end
|
||||
if _HOST then
|
||||
return tonumber(_HOST:gmatch('[%d]+%.?[%d][%d]', '%1')())
|
||||
end
|
||||
return 1.7
|
||||
end
|
||||
|
||||
function os.registerApp(entry)
|
||||
local apps = { }
|
||||
Config.load('apps', apps)
|
||||
|
@ -14,7 +14,7 @@ end
|
||||
|
||||
Event.addHandler('peripheral', function(event, side)
|
||||
if side then
|
||||
local dev = Peripheral.addDevice(side)
|
||||
local dev = Peripheral.addDevice(device, side)
|
||||
if dev then
|
||||
term.setTextColor(attachColor)
|
||||
Util.print('[%s] %s attached', dev.side, dev.name)
|
||||
|
Loading…
Reference in New Issue
Block a user