mirror of
https://github.com/kepler155c/opus
synced 2025-02-03 02:49:09 +00:00
bit of everything
This commit is contained in:
parent
027f386ed1
commit
f8bcf90a6b
@ -14,7 +14,6 @@ local keys = Util.transpose({
|
||||
})
|
||||
|
||||
function ChestProvider:init(args)
|
||||
|
||||
local defaults = {
|
||||
items = { },
|
||||
name = 'chest',
|
||||
@ -43,12 +42,10 @@ function ChestProvider:getCachedItemDetails(item, k)
|
||||
if not detail then
|
||||
return
|
||||
end
|
||||
-- NOT SUFFICIENT
|
||||
if detail.name ~= item.name then
|
||||
return
|
||||
end
|
||||
if detail.maxDamage and detail.maxDamage > 0 and detail.damage > 0 then
|
||||
detail.displayName = detail.displayName .. ' (damaged)'
|
||||
end
|
||||
|
||||
for _,k in ipairs(Util.keys(detail)) do
|
||||
if not keys[k] then
|
||||
@ -135,8 +132,8 @@ function ChestProvider:provide(item, qty, slot, direction)
|
||||
end
|
||||
end
|
||||
|
||||
function ChestProvider:extract(slot, qty)
|
||||
self.pushItems(self.direction, slot, qty)
|
||||
function ChestProvider:extract(slot, qty, toSlot)
|
||||
self.pushItems(self.direction, slot, qty, toSlot)
|
||||
end
|
||||
|
||||
function ChestProvider:insert(slot, qty)
|
||||
|
@ -1,25 +1,17 @@
|
||||
local Util = require('util')
|
||||
local Process = require('process')
|
||||
|
||||
local Event = {
|
||||
uid = 1, -- unique id for handlers
|
||||
routines = { },
|
||||
handlers = { namedTimers = { } },
|
||||
terminate = false,
|
||||
}
|
||||
|
||||
local eventHandlers = {
|
||||
namedTimers = {}
|
||||
}
|
||||
|
||||
-- debug purposes
|
||||
function Event.getHandlers()
|
||||
return eventHandlers
|
||||
end
|
||||
|
||||
function Event.addHandler(type, f)
|
||||
local event = eventHandlers[type]
|
||||
local event = Event.handlers[type]
|
||||
if not event then
|
||||
event = {}
|
||||
event.handlers = {}
|
||||
eventHandlers[type] = event
|
||||
event = { handlers = { } }
|
||||
Event.handlers[type] = event
|
||||
end
|
||||
|
||||
local handler = {
|
||||
@ -35,7 +27,7 @@ end
|
||||
|
||||
function Event.removeHandler(h)
|
||||
if h and h.event then
|
||||
eventHandlers[h.event].handlers[h.uid] = nil
|
||||
Event.handlers[h.event].handlers[h.uid] = nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -49,11 +41,11 @@ end
|
||||
|
||||
function Event.addNamedTimer(name, interval, recurring, f)
|
||||
Event.cancelNamedTimer(name)
|
||||
eventHandlers.namedTimers[name] = Event.addTimer(interval, recurring, f)
|
||||
Event.handlers.namedTimers[name] = Event.addTimer(interval, recurring, f)
|
||||
end
|
||||
|
||||
function Event.getNamedTimer(name)
|
||||
return eventHandlers.namedTimers[name]
|
||||
return Event.handlers.namedTimers[name]
|
||||
end
|
||||
|
||||
function Event.cancelNamedTimer(name)
|
||||
@ -64,11 +56,6 @@ function Event.cancelNamedTimer(name)
|
||||
end
|
||||
end
|
||||
|
||||
function Event.isTimerActive(timer)
|
||||
return timer.enabled and
|
||||
os.clock() < timer.start + timer.interval
|
||||
end
|
||||
|
||||
function Event.addTimer(interval, recurring, f)
|
||||
local timer = Event.addHandler('timer',
|
||||
function(t, id)
|
||||
@ -81,7 +68,6 @@ function Event.addTimer(interval, recurring, f)
|
||||
end
|
||||
if t.recurring then
|
||||
t.fired = false
|
||||
t.start = os.clock()
|
||||
t.timerId = os.startTimer(t.interval)
|
||||
else
|
||||
Event.removeHandler(t)
|
||||
@ -91,103 +77,121 @@ function Event.addTimer(interval, recurring, f)
|
||||
timer.cf = f
|
||||
timer.interval = interval
|
||||
timer.recurring = recurring
|
||||
timer.start = os.clock()
|
||||
timer.enabled = true
|
||||
timer.timerId = os.startTimer(interval)
|
||||
|
||||
return timer
|
||||
end
|
||||
|
||||
function Event.removeTimer(h)
|
||||
Event.removeHandler(h)
|
||||
function Event.onInterval(interval, f)
|
||||
return Event.addTimer(interval, true, f)
|
||||
end
|
||||
|
||||
function Event.blockUntilEvent(event, timeout)
|
||||
return Event.waitForEvent(event, timeout, os.pullEvent)
|
||||
function Event.onTimeout(timeout, f)
|
||||
return Event.addTimer(timeout, false, f)
|
||||
end
|
||||
|
||||
function Event.waitForEvent(event, timeout, pullEvent)
|
||||
pullEvent = pullEvent or Event.pullEvent
|
||||
|
||||
function Event.waitForEvent(event, timeout)
|
||||
local timerId = os.startTimer(timeout)
|
||||
repeat
|
||||
local e, p1, p2, p3, p4 = pullEvent()
|
||||
local e, p1, p2, p3, p4 = os.pullEvent()
|
||||
if e == event then
|
||||
return e, p1, p2, p3, p4
|
||||
end
|
||||
until e == 'timer' and p1 == timerId
|
||||
end
|
||||
|
||||
local exitPullEvents = false
|
||||
|
||||
local function _pullEvents()
|
||||
while true do
|
||||
local e = { os.pullEvent() }
|
||||
Event.processEvent(e)
|
||||
function Event.addRoutine(routine)
|
||||
local r = { co = coroutine.create(routine) }
|
||||
local s, m = coroutine.resume(r.co)
|
||||
if not s then
|
||||
error(m or 'Error processing routine')
|
||||
end
|
||||
end
|
||||
|
||||
function Event.sleep(t)
|
||||
local timerId = os.startTimer(t or 0)
|
||||
repeat
|
||||
local event, id = Event.pullEvent()
|
||||
until event == 'timer' and id == timerId
|
||||
end
|
||||
|
||||
function Event.addThread(fn)
|
||||
return Process:addThread(fn)
|
||||
Event.routines[r] = true
|
||||
r.filter = m
|
||||
return r
|
||||
end
|
||||
|
||||
function Event.pullEvents(...)
|
||||
local routines = { ... }
|
||||
if #routines > 0 then
|
||||
Process:addThread(_pullEvents)
|
||||
for _, routine in ipairs(routines) do
|
||||
Process:addThread(routine)
|
||||
end
|
||||
while true do
|
||||
local e = Process:pullEvent()
|
||||
if exitPullEvents or e == 'terminate' then
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
while true do
|
||||
local e = { os.pullEventRaw() }
|
||||
Event.processEvent(e)
|
||||
if exitPullEvents or e[1] == 'terminate' then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for _, r in ipairs({ ... }) do
|
||||
Event.addRoutine(r)
|
||||
end
|
||||
|
||||
repeat
|
||||
local e = Event.pullEvent()
|
||||
until e[1] == 'terminate'
|
||||
end
|
||||
|
||||
function Event.exitPullEvents()
|
||||
exitPullEvents = true
|
||||
Event.terminate = true
|
||||
os.sleep(0)
|
||||
end
|
||||
|
||||
function Event.pullEvent(eventType)
|
||||
local e = { os.pullEventRaw(eventType) }
|
||||
return Event.processEvent(e)
|
||||
|
||||
while true do
|
||||
local e = { os.pullEventRaw() }
|
||||
local routines = Util.keys(Event.routines)
|
||||
for _, r in ipairs(routines) do
|
||||
if not r.filter or r.filter == e[1] then
|
||||
local s, m = coroutine.resume(r.co, table.unpack(e))
|
||||
if not s and e[1] ~= 'terminate' then
|
||||
debug({s, m})
|
||||
debug(r)
|
||||
error(m or 'Error processing event')
|
||||
end
|
||||
if coroutine.status(r.co) == 'dead' then
|
||||
r.co = nil
|
||||
Event.routines[r] = nil
|
||||
else
|
||||
r.filter = m
|
||||
end
|
||||
end
|
||||
end
|
||||
Event.processEvent(e)
|
||||
if Event.terminate or e[1] == 'terminate' then
|
||||
Event.terminate = false
|
||||
return { 'terminate' }
|
||||
end
|
||||
|
||||
if not eventType or e[1] == eventType then
|
||||
return e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Event.processEvent(pe)
|
||||
|
||||
local e, p1, p2, p3, p4, p5 = unpack(pe)
|
||||
|
||||
local event = eventHandlers[e]
|
||||
local event = Event.handlers[e]
|
||||
if event then
|
||||
local keys = Util.keys(event.handlers)
|
||||
for _,key in pairs(keys) do
|
||||
local h = event.handlers[key]
|
||||
if h then
|
||||
h.f(h, p1, p2, p3, p4, p5)
|
||||
if h and not h.co then
|
||||
local co = coroutine.create(function()
|
||||
h.f(h, p1, p2, p3, p4, p5)
|
||||
end)
|
||||
local s, m = coroutine.resume(co)
|
||||
if not s then
|
||||
debug({s, m})
|
||||
debug(h)
|
||||
error(m or 'Error processing ' .. e)
|
||||
elseif coroutine.status(co) ~= 'dead' then
|
||||
h.co = co
|
||||
h.filter = m
|
||||
Event.routines[h] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return e, p1, p2, p3, p4, p5
|
||||
end
|
||||
|
||||
Event.on = Event.addHandler
|
||||
Event.off = Event.removeHandler
|
||||
|
||||
return Event
|
||||
|
@ -12,9 +12,9 @@ local PASTEBIN_URL = 'http://pastebin.com/raw'
|
||||
local GIT_URL = 'https://raw.githubusercontent.com'
|
||||
|
||||
local function standardSearcher(modname, env, shell)
|
||||
if package.loaded[modname] then
|
||||
if _G.package.loaded[modname] then
|
||||
return function()
|
||||
return package.loaded[modname]
|
||||
return _G.package.loaded[modname]
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -33,7 +33,7 @@ end
|
||||
local function pathSearcher(modname, env, shell)
|
||||
local fname = modname:gsub('%.', '/') .. '.lua'
|
||||
|
||||
for dir in string.gmatch(package.path, "[^:]+") do
|
||||
for dir in string.gmatch(_G.package.path, "[^:]+") do
|
||||
local path = fs.combine(dir, fname)
|
||||
if fs.exists(path) and not fs.isDir(path) then
|
||||
return loadfile(path, env)
|
||||
@ -109,7 +109,7 @@ local function urlSearcher(modname, env, shell)
|
||||
local fname = modname:gsub('%.', '/') .. '.lua'
|
||||
|
||||
if fname:sub(1, 1) ~= '/' then
|
||||
for entry in string.gmatch(package.upath, "[^;]+") do
|
||||
for entry in string.gmatch(_G.package.upath, "[^;]+") do
|
||||
local url = entry .. '/' .. fname
|
||||
local c = loadUrl(url)
|
||||
if c then
|
||||
@ -150,7 +150,7 @@ local function requireWrapper(env)
|
||||
return loaded[modname]
|
||||
end
|
||||
|
||||
for _,searcher in ipairs(package.loaders) do
|
||||
for _,searcher in ipairs(_G.package.loaders) do
|
||||
local fn, msg = searcher(modname, env, shell)
|
||||
if fn then
|
||||
local module, msg = fn(modname, env)
|
||||
|
@ -1,6 +1,6 @@
|
||||
local TableDB = require('tableDB')
|
||||
|
||||
local itemDB = TableDB({ fileName = 'usr/config/items.db' })
|
||||
local itemDB = TableDB({ fileName = 'usr/etc/items.db' })
|
||||
|
||||
function itemDB:get(key)
|
||||
|
||||
@ -13,6 +13,9 @@ function itemDB:get(key)
|
||||
if key[2] ~= 0 then
|
||||
item = TableDB.get(self, { key[1], 0, key[3] })
|
||||
if item and item.maxDamage > 0 then
|
||||
item = Util.shallowCopy(item)
|
||||
item.damage = key[2]
|
||||
item.displayName = string.format('%s (damage: %d)', item.displayName, item.damage)
|
||||
return item
|
||||
end
|
||||
end
|
||||
|
@ -50,7 +50,12 @@ function Peripheral.addDevice(deviceList, side)
|
||||
name = uniqueName
|
||||
end
|
||||
|
||||
deviceList[name] = peripheral.wrap(side)
|
||||
local s, m pcall(function() deviceList[name] = peripheral.wrap(side) end)
|
||||
if not s and m then
|
||||
printError('wrap failed')
|
||||
printError(m)
|
||||
end
|
||||
|
||||
if deviceList[name] then
|
||||
Util.merge(deviceList[name], {
|
||||
name = name,
|
||||
|
@ -4,13 +4,19 @@ function Point.copy(pt)
|
||||
return { x = pt.x, y = pt.y, z = pt.z }
|
||||
end
|
||||
|
||||
function Point.same(pta, ptb)
|
||||
return pta.x == ptb.x and
|
||||
pta.y == ptb.y and
|
||||
pta.z == ptb.z
|
||||
end
|
||||
|
||||
function Point.subtract(a, b)
|
||||
a.x = a.x - b.x
|
||||
a.y = a.y - b.y
|
||||
a.z = a.z - b.z
|
||||
end
|
||||
|
||||
-- real distance
|
||||
-- Euclidian distance
|
||||
function Point.pythagoreanDistance(a, b)
|
||||
return math.sqrt(
|
||||
math.pow(a.x - b.x, 2) +
|
||||
@ -18,7 +24,7 @@ function Point.pythagoreanDistance(a, b)
|
||||
math.pow(a.z - b.z, 2))
|
||||
end
|
||||
|
||||
-- turtle distance
|
||||
-- turtle distance (manhattan)
|
||||
function Point.turtleDistance(a, b)
|
||||
if a.y and b.y then
|
||||
return math.abs(a.x - b.x) +
|
||||
@ -40,6 +46,35 @@ function Point.calculateTurns(ih, oh)
|
||||
return 1
|
||||
end
|
||||
|
||||
function Point.calculateHeading(pta, ptb)
|
||||
|
||||
local heading
|
||||
|
||||
if (pta.heading % 2) == 0 and pta.z ~= ptb.z then
|
||||
if ptb.z > pta.z then
|
||||
heading = 1
|
||||
else
|
||||
heading = 3
|
||||
end
|
||||
elseif (pta.heading % 2) == 1 and pta.x ~= ptb.x then
|
||||
if ptb.x > pta.x then
|
||||
heading = 0
|
||||
else
|
||||
heading = 2
|
||||
end
|
||||
elseif pta.heading == 0 and pta.x > ptb.x then
|
||||
heading = 2
|
||||
elseif pta.heading == 2 and pta.x < ptb.x then
|
||||
heading = 0
|
||||
elseif pta.heading == 1 and pta.z > ptb.z then
|
||||
heading = 3
|
||||
elseif pta.heading == 3 and pta.z < ptb.z then
|
||||
heading = 1
|
||||
end
|
||||
|
||||
return heading or pta.heading
|
||||
end
|
||||
|
||||
-- Calculate distance to location including turns
|
||||
-- also returns the resulting heading
|
||||
function Point.calculateMoves(pta, ptb, distance)
|
||||
@ -88,6 +123,32 @@ function Point.closest(reference, pts)
|
||||
return lpt
|
||||
end
|
||||
|
||||
-- find the closest block
|
||||
-- * favor same plane
|
||||
-- * going backwards only if the dest is above or below
|
||||
function Point.closest2(reference, pts)
|
||||
local lpt, lm -- lowest
|
||||
for _,pt in pairs(pts) do
|
||||
local m = Point.turtleDistance(reference, pt)
|
||||
local h = Point.calculateHeading(reference, pt)
|
||||
local t = Point.calculateTurns(reference.heading, h)
|
||||
if pt.y ~= reference.y then -- try and stay on same plane
|
||||
m = m + .01
|
||||
end
|
||||
if t ~= 2 or pt.y == reference.y then
|
||||
m = m + t
|
||||
if t > 0 then
|
||||
m = m + .01
|
||||
end
|
||||
end
|
||||
if not lm or m < lm then
|
||||
lpt = pt
|
||||
lm = m
|
||||
end
|
||||
end
|
||||
return lpt
|
||||
end
|
||||
|
||||
function Point.adjacentPoints(pt)
|
||||
local pts = { }
|
||||
|
||||
|
@ -48,9 +48,6 @@ function RefinedProvider:getCachedItemDetails(item)
|
||||
return
|
||||
end
|
||||
Util.merge(detail, meta)
|
||||
if detail.maxDamage and detail.maxDamage > 0 and detail.damage > 0 then
|
||||
detail.displayName = detail.displayName .. ' (damaged)'
|
||||
end
|
||||
detail.lname = detail.displayName:lower()
|
||||
|
||||
local t = { }
|
||||
|
@ -100,15 +100,15 @@ function Schematic:parse(a, h, containsName, spinner)
|
||||
local i4 = h:readbyte(h)
|
||||
local i = bit.blshift(i1, 24) + bit.blshift(i2, 16) + bit.blshift(i3, 8) + i4
|
||||
|
||||
if not self.length or not self.width then
|
||||
|
||||
self:discardBytes(h,i, spinner)
|
||||
self.twopass = true
|
||||
|
||||
elseif name == "Blocks" then
|
||||
if name == "Blocks" then
|
||||
for i = 1, i do
|
||||
local id = h:readbyte(h)
|
||||
self:assignCoord(i, id)
|
||||
if id > 0 then
|
||||
table.insert(self.blocks, {
|
||||
id = id,
|
||||
index = i,
|
||||
})
|
||||
end
|
||||
if (i % 1000) == 0 then
|
||||
spinner:spin()
|
||||
end
|
||||
@ -269,15 +269,36 @@ function Schematic:loadpass(fh, spinner)
|
||||
break
|
||||
end
|
||||
self:parse(a, fh, true, spinner)
|
||||
if self.twopass and self.width and self.length then
|
||||
break
|
||||
end
|
||||
|
||||
spinner:spin()
|
||||
end
|
||||
|
||||
fh:close()
|
||||
|
||||
print('Assigning coords ')
|
||||
local index = 1
|
||||
for _, b in ipairs(self.blocks) do
|
||||
while index < b.index do
|
||||
self.x = self.x + 1
|
||||
if self.x >= self.width then
|
||||
self.x = 0
|
||||
self.z = self.z + 1
|
||||
end
|
||||
if self.z >= self.length then
|
||||
self.z = 0
|
||||
self.y = self.y + 1
|
||||
end
|
||||
if self.y >= self.height then
|
||||
self.height = self.y + 1
|
||||
end
|
||||
index = index + 1
|
||||
end
|
||||
b.x = self.x
|
||||
b.y = self.y
|
||||
b.z = self.z
|
||||
spinner:spin()
|
||||
end
|
||||
|
||||
self:assignDamages(spinner)
|
||||
self.damages = nil
|
||||
|
||||
@ -313,22 +334,9 @@ function Schematic:load(filename)
|
||||
|
||||
self:checkFileType(f)
|
||||
|
||||
print('Initial pass ')
|
||||
print('Loading blocks ')
|
||||
self:loadpass(f, spinner)
|
||||
|
||||
if self.twopass then
|
||||
self.twopass = nil
|
||||
self.blocks = { }
|
||||
self.damages = { }
|
||||
self.originalBlocks = { }
|
||||
self.x, self.y, self.z = 0, 0, 0
|
||||
self.height = 0
|
||||
self.index = 1
|
||||
|
||||
print('Second pass ')
|
||||
self:loadpass(f, spinner)
|
||||
end
|
||||
|
||||
self.rowIndex = { }
|
||||
for k,b in ipairs(self.blocks) do
|
||||
local ri = self.rowIndex[b.y]
|
||||
@ -342,42 +350,12 @@ function Schematic:load(filename)
|
||||
self.cache = Util.readTable('usr/builder/' .. self.filename .. '.cache') or { }
|
||||
end
|
||||
|
||||
function Schematic:assignCoord(i, id)
|
||||
|
||||
if id > 0 then
|
||||
table.insert(self.blocks, {
|
||||
id = id,
|
||||
index = i,
|
||||
x = self.x,
|
||||
z = self.z,
|
||||
y = self.y,
|
||||
})
|
||||
end
|
||||
|
||||
self.x = self.x + 1
|
||||
if self.x >= self.width then
|
||||
self.x = 0
|
||||
self.z = self.z + 1
|
||||
end
|
||||
if self.z >= self.length then
|
||||
self.z = 0
|
||||
self.y = self.y + 1
|
||||
end
|
||||
if self.y >= self.height then
|
||||
self.height = self.y + 1
|
||||
end
|
||||
end
|
||||
|
||||
function Schematic:assignDamages(spinner)
|
||||
print('Assigning damages')
|
||||
|
||||
local i = 0
|
||||
for _,b in pairs(self.blocks) do
|
||||
b.dmg = self.damages[b.index] or 0
|
||||
i = i + 1
|
||||
if (i % 1000) == 0 then
|
||||
spinner:spin()
|
||||
end
|
||||
spinner:spin()
|
||||
end
|
||||
end
|
||||
|
||||
@ -849,6 +827,7 @@ function Schematic:getComputedBlock(i)
|
||||
-- has this level been computed ?
|
||||
if not self.rowIndex[b.y].loaded then
|
||||
-- compute each level up til this one (unless saved in cache)
|
||||
|
||||
for y = 0, b.y - 1 do
|
||||
if not self.cache[y] then
|
||||
self:determineBlockPlacement(y)
|
||||
@ -858,7 +837,6 @@ function Schematic:getComputedBlock(i)
|
||||
-- get the block now at the computed location
|
||||
b = self.blocks[i]
|
||||
end
|
||||
|
||||
return b
|
||||
end
|
||||
|
||||
|
@ -67,7 +67,7 @@ function Manager:init(args)
|
||||
local mouseDragged = false
|
||||
local pages = { }
|
||||
|
||||
Event.addHandler('term_resize', function(h, side)
|
||||
Event.on('term_resize', function(h, side)
|
||||
if self.currentPage then
|
||||
-- the parent doesn't have any children set...
|
||||
-- that's why we have to resize both the parent and the current page
|
||||
@ -81,7 +81,7 @@ function Manager:init(args)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('mouse_scroll', function(h, direction, x, y)
|
||||
Event.on('mouse_scroll', function(h, direction, x, y)
|
||||
if self.target then
|
||||
local event = self:pointToChild(self.target, x, y)
|
||||
local directions = {
|
||||
@ -97,7 +97,7 @@ function Manager:init(args)
|
||||
end)
|
||||
|
||||
-- this should be moved to the device !
|
||||
Event.addHandler('monitor_touch', function(h, side, x, y)
|
||||
Event.on('monitor_touch', function(h, side, x, y)
|
||||
if self.currentPage then
|
||||
if self.currentPage.parent.device.side == side then
|
||||
self:click(1, x, y)
|
||||
@ -105,7 +105,7 @@ function Manager:init(args)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('mouse_click', function(h, button, x, y)
|
||||
Event.on('mouse_click', function(h, button, x, y)
|
||||
|
||||
mouseDragged = false
|
||||
if button == 1 and shift and control then -- debug hack
|
||||
@ -123,7 +123,7 @@ function Manager:init(args)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('mouse_up', function(h, button, x, y)
|
||||
Event.on('mouse_up', function(h, button, x, y)
|
||||
|
||||
if self.currentPage and not mouseDragged then
|
||||
if not self.currentPage.parent.device.side then
|
||||
@ -132,7 +132,7 @@ function Manager:init(args)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('mouse_drag', function(h, button, x, y)
|
||||
Event.on('mouse_drag', function(h, button, x, y)
|
||||
|
||||
mouseDragged = true
|
||||
if self.target then
|
||||
@ -146,7 +146,7 @@ function Manager:init(args)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('paste', function(h, text)
|
||||
Event.on('paste', function(h, text)
|
||||
if clipboard.isInternal() then
|
||||
text = clipboard.getData()
|
||||
end
|
||||
@ -156,7 +156,7 @@ function Manager:init(args)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('char', function(h, ch)
|
||||
Event.on('char', function(h, ch)
|
||||
control = false
|
||||
if self.currentPage then
|
||||
self:inputEvent(self.currentPage.focused, { type = 'key', key = ch })
|
||||
@ -164,7 +164,7 @@ function Manager:init(args)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('key_up', function(h, code)
|
||||
Event.on('key_up', function(h, code)
|
||||
if code == keys.leftCtrl or code == keys.rightCtrl then
|
||||
control = false
|
||||
elseif code == keys.leftShift or code == keys.rightShift then
|
||||
@ -172,7 +172,7 @@ function Manager:init(args)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('key', function(h, code)
|
||||
Event.on('key', function(h, code)
|
||||
local ch = keys.getName(code)
|
||||
if not ch then
|
||||
return
|
||||
@ -1282,6 +1282,8 @@ function UI.Device:runTransitions(transitions, canvas)
|
||||
if Util.empty(transitions) then
|
||||
break
|
||||
end
|
||||
os.sleep(0)
|
||||
--[[
|
||||
local timerId = os.startTimer(0)
|
||||
while true do
|
||||
local e = { os.pullEvent() }
|
||||
@ -1290,10 +1292,11 @@ function UI.Device:runTransitions(transitions, canvas)
|
||||
end
|
||||
table.insert(queue, e)
|
||||
end
|
||||
--]]
|
||||
end
|
||||
for _, e in ipairs(queue) do
|
||||
Event.processEvent(e)
|
||||
end
|
||||
-- for _, e in ipairs(queue) do
|
||||
-- Event.processEvent(e)
|
||||
-- end
|
||||
end
|
||||
|
||||
function UI.Device:sync()
|
||||
|
@ -116,23 +116,20 @@ function page.grid:getDisplayValues(row)
|
||||
return row
|
||||
end
|
||||
|
||||
Event.addThread(function()
|
||||
while true do
|
||||
page.grid:update()
|
||||
page.grid:draw()
|
||||
page:sync()
|
||||
os.sleep(1)
|
||||
end
|
||||
Event.onInterval(1, function()
|
||||
page.grid:update()
|
||||
page.grid:draw()
|
||||
page:sync()
|
||||
end)
|
||||
|
||||
Event.addHandler('device_attach', function(h, deviceName)
|
||||
Event.on('device_attach', function(h, deviceName)
|
||||
if deviceName == 'wireless_modem' then
|
||||
page.notification:success('Modem connected')
|
||||
page:sync()
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('device_detach', function(h, deviceName)
|
||||
Event.on('device_detach', function(h, deviceName)
|
||||
if deviceName == 'wireless_modem' then
|
||||
page.notification:error('Wireless modem not attached')
|
||||
page:sync()
|
||||
|
@ -532,34 +532,30 @@ if not fs.exists(GROUPS_PATH) then
|
||||
fs.makeDir(GROUPS_PATH)
|
||||
end
|
||||
|
||||
Event.addHandler('network_attach', function()
|
||||
Event.on('network_attach', function()
|
||||
if mainPage.enabled then
|
||||
mainPage:draw()
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('network_detach', function()
|
||||
Event.on('network_detach', function()
|
||||
if mainPage.enabled then
|
||||
mainPage:draw()
|
||||
end
|
||||
end)
|
||||
|
||||
function statusUpdate()
|
||||
while true do
|
||||
if mainPage.enabled then
|
||||
local selected = mainPage.computers:getSelected()
|
||||
if selected then
|
||||
local computer = _G.network[selected.id]
|
||||
mainPage.statusBar.values = { computer }
|
||||
mainPage.statusBar:draw()
|
||||
mainPage:sync()
|
||||
end
|
||||
Event.onInterval(1, function()
|
||||
if mainPage.enabled then
|
||||
local selected = mainPage.computers:getSelected()
|
||||
if selected then
|
||||
local computer = _G.network[selected.id]
|
||||
mainPage.statusBar.values = { computer }
|
||||
mainPage.statusBar:draw()
|
||||
mainPage:sync()
|
||||
end
|
||||
os.sleep(1)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
UI:setPage(mainPage)
|
||||
|
||||
Event.pullEvents(statusUpdate)
|
||||
UI:pullEvents()
|
||||
UI.term:reset()
|
||||
|
@ -52,7 +52,7 @@ function page.grid:getDisplayValues(row)
|
||||
if elapsed < 60 then
|
||||
row.timestamp = string.format("%ds", math.floor(elapsed))
|
||||
else
|
||||
row.timestamp = string.format("%fm", math.floor(elapsed/6)/10)
|
||||
row.timestamp = string.format("%sm", math.floor(elapsed/6)/10)
|
||||
end
|
||||
if row.isDead then
|
||||
row.status = 'error'
|
||||
|
@ -2,7 +2,7 @@ require = requireInjector(getfenv(1))
|
||||
local UI = require('ui')
|
||||
local Socket = require('socket')
|
||||
local Terminal = require('terminal')
|
||||
local TableDB = require('tableDB')
|
||||
local itemDB = require('itemDB')
|
||||
|
||||
multishell.setTitle(multishell.getCurrent(), 'Turtles')
|
||||
UI.Button.defaults.focusIndicator = ' '
|
||||
@ -31,12 +31,6 @@ local policies = {
|
||||
{ label = 'turtleSafe' },
|
||||
}
|
||||
|
||||
local itemInfoDB = TableDB({
|
||||
fileName = 'items.db'
|
||||
})
|
||||
|
||||
itemInfoDB:load()
|
||||
|
||||
local page = UI.Page {
|
||||
--[[
|
||||
policy = UI.Chooser {
|
||||
@ -177,7 +171,7 @@ function page.coords:draw()
|
||||
self:clear()
|
||||
self:setCursorPos(1, 1)
|
||||
local ind = 'GPS'
|
||||
if t.coordSystem ~= 'GPS' then
|
||||
if not t.point.gps then
|
||||
ind = 'REL'
|
||||
end
|
||||
self:print(string.format('%s : %d,%d,%d\nFuel: %s\n',
|
||||
@ -204,7 +198,7 @@ function page.tabs.inventory:draw()
|
||||
v.selected = true
|
||||
end
|
||||
if v.id then
|
||||
local item = itemInfoDB:get({ v.id, v.dmg })
|
||||
local item = itemDB:get({ v.id, v.dmg })
|
||||
if item then
|
||||
v.id = item.displayName
|
||||
else
|
||||
|
@ -41,6 +41,7 @@ local Builder = {
|
||||
resourceSlots = 14,
|
||||
facing = 'south',
|
||||
confirmFacing = false,
|
||||
wrenchSucks = false,
|
||||
}
|
||||
|
||||
local pistonFacings
|
||||
@ -95,6 +96,7 @@ function subDB:seedDB()
|
||||
[ "minecraft:wall_banner:0" ] = "minecraft:banner:0",
|
||||
[ "minecraft:standing_banner:0" ] = "minecraft:banner:0",
|
||||
[ "minecraft:tripwire:0" ] = "minecraft:string:0",
|
||||
[ "minecraft:pumpkin_stem:0" ] = "minecraft:pumpkin_seeds:0",
|
||||
}
|
||||
self.dirty = true
|
||||
self:flush()
|
||||
@ -266,7 +268,7 @@ function Builder:getAirResupplyList(blockIndex)
|
||||
local fuel = subDB:getSubstitutedItem(Builder.fuelItem.id, Builder.fuelItem.dmg)
|
||||
|
||||
slots[15] = {
|
||||
id = 'ironchest:BlockIronChest', -- 'minecraft:chest',
|
||||
id = 'minecraft:chest', --'ironchest:BlockIronChest', --
|
||||
dmg = 0,
|
||||
qty = 0,
|
||||
need = 1,
|
||||
@ -821,6 +823,14 @@ function Builder:placePiston(b)
|
||||
return
|
||||
end
|
||||
|
||||
if self.wrenchSucks then
|
||||
turtle.turnRight()
|
||||
turtle.forward()
|
||||
turtle.turnLeft()
|
||||
turtle.forward()
|
||||
turtle.turnLeft()
|
||||
end
|
||||
|
||||
local success = self:wrenchBlock('forward', 'down', pistonFacings) --wrench piston to point downwards
|
||||
|
||||
rs.setOutput('front', true)
|
||||
@ -830,6 +840,11 @@ function Builder:placePiston(b)
|
||||
turtle.select(ps.index)
|
||||
turtle.dig()
|
||||
|
||||
if not success and not self.wrenchSucks then
|
||||
self.wrenchSucks = true
|
||||
success = self:placePiston(b)
|
||||
end
|
||||
|
||||
return success
|
||||
end
|
||||
|
||||
@ -2029,12 +2044,9 @@ UI:setPages({
|
||||
|
||||
UI:setPage('start')
|
||||
|
||||
turtle.run(function()
|
||||
local s, m = turtle.run(function()
|
||||
turtle.setPolicy(turtle.policies.digAttack)
|
||||
turtle.setPoint({ x = -1, z = -1, y = 0, heading = 0 })
|
||||
turtle.getState().coordSystem = 'relative'
|
||||
turtle.saveLocation('supplies')
|
||||
Event.pullEvents()
|
||||
UI:pullEvents()
|
||||
end)
|
||||
|
||||
UI.term:reset()
|
||||
|
@ -5,16 +5,18 @@ local ChestProvider = require('chestProvider18')
|
||||
local RefinedProvider = require('refinedProvider')
|
||||
local itemDB = require('itemDB')
|
||||
local Terminal = require('terminal')
|
||||
local Peripheral = require('peripheral')
|
||||
|
||||
multishell.setTitle(multishell.getCurrent(), 'Resource Manager')
|
||||
|
||||
-- 3 wide monitor (any side of turtle)
|
||||
|
||||
-- Config location is /sys/config/chestManager
|
||||
-- Config location is /sys/config/resourceManager
|
||||
-- adjust directions in that file if needed
|
||||
|
||||
local config = {
|
||||
trashDirection = 'up', -- trash /chest in relation to interface
|
||||
turtleDirection = 'down', -- turtle in relation to interface
|
||||
noCraftingStorage = 'false' -- no ME crafting (or ability to tell if powered - use with caution)
|
||||
trashDirection = 'up', -- trash /chest in relation to chest
|
||||
turtleDirection = 'down', -- turtle in relation to chest
|
||||
}
|
||||
|
||||
Config.load('resourceManager', config)
|
||||
@ -26,14 +28,34 @@ if not controller:isValid() then
|
||||
end
|
||||
|
||||
local chestProvider = ChestProvider({ direction = 'west', wrapSide = 'back' })
|
||||
local turtleChestProvider = ChestProvider({ direction = 'up', wrapSide = 'bottom' })
|
||||
|
||||
local RESOURCE_FILE = 'usr/etc/resources.db'
|
||||
local RECIPES_FILE = 'usr/etc/recipes.db'
|
||||
|
||||
local jobListGrid
|
||||
local craftingPaused = false
|
||||
local recipes = Util.readTable('recipes') or { }
|
||||
local recipes = Util.readTable(RECIPES_FILE) or { }
|
||||
local resources = Util.readTable(RESOURCE_FILE) or { }
|
||||
|
||||
multishell.setTitle(multishell.getCurrent(), 'Resource Manager')
|
||||
for _,r in pairs(resources) do
|
||||
r.maxDamage = nil
|
||||
r.displayName = nil
|
||||
r.count = nil
|
||||
r.lname = nil
|
||||
r.has_recipe = nil
|
||||
|
||||
function getItem(items, inItem, ignoreDamage)
|
||||
if not r.ignoreDamage then
|
||||
r.ignoreDamage = nil
|
||||
end
|
||||
|
||||
if not r.auto then
|
||||
r.auto = nil
|
||||
end
|
||||
end
|
||||
Util.writeTable(RESOURCE_FILE, resources)
|
||||
|
||||
local function getItem(items, inItem, ignoreDamage)
|
||||
for _,item in pairs(items) do
|
||||
if item.name == inItem.name then
|
||||
if ignoreDamage then
|
||||
@ -61,7 +83,7 @@ local function getItemDetails(items, item)
|
||||
cItem = itemDB:get(itemDB:makeKey(item))
|
||||
if cItem then
|
||||
return { count = 0, maxCount = cItem.maxCount }
|
||||
enditemDB:makeKey
|
||||
end
|
||||
return { count = 0, maxCount = 64 }
|
||||
end
|
||||
|
||||
@ -69,7 +91,7 @@ local function uniqueKey(item)
|
||||
return table.concat({ item.name, item.damage, item.nbtHash }, ':')
|
||||
end
|
||||
|
||||
function getName(item)
|
||||
local function getName(item)
|
||||
local detail = itemDB:get(itemDB:makeKey(item))
|
||||
if detail then
|
||||
return detail.displayName
|
||||
@ -77,60 +99,51 @@ function getName(item)
|
||||
return item.name .. ':' .. item.damage
|
||||
end
|
||||
|
||||
function mergeResources(t)
|
||||
local resources = Util.readTable('resource.limits') or { }
|
||||
|
||||
local function mergeResources(t)
|
||||
for _,v in pairs(resources) do
|
||||
v.low = tonumber(v.low) -- backwards compatibility
|
||||
local item = getItem(t, v)
|
||||
if item then
|
||||
item.low = v.low
|
||||
item.limit = v.limit
|
||||
item.auto = v.auto
|
||||
item.ignoreDamage = v.ignoreDamage
|
||||
item.rsControl = v.rsControl
|
||||
item.rsDevice = v.rsDevice
|
||||
item.rsSide = v.rsSide
|
||||
Util.merge(item, v)
|
||||
else
|
||||
v.count = 0
|
||||
table.insert(t, v)
|
||||
item = Util.shallowCopy(v)
|
||||
item.count = 0
|
||||
table.insert(t, item)
|
||||
end
|
||||
end
|
||||
|
||||
for _,v in pairs(recipes) do
|
||||
local item = getItem(t, v)
|
||||
if item then
|
||||
item.has_recipe = true
|
||||
else
|
||||
if not item then
|
||||
item = Util.shallowCopy(v)
|
||||
item.displayName = getName(item)
|
||||
item.count = 0
|
||||
item.has_recipe = true
|
||||
table.insert(t, item)
|
||||
end
|
||||
item.has_recipe = true
|
||||
end
|
||||
|
||||
for _,v in pairs(t) do
|
||||
if not v.displayName then
|
||||
v.displayName = getName(v)
|
||||
end
|
||||
v.lname = v.displayName:lower()
|
||||
end
|
||||
end
|
||||
|
||||
function filterItems(t, filter)
|
||||
local r = {}
|
||||
local function filterItems(t, filter)
|
||||
if filter then
|
||||
local r = {}
|
||||
filter = filter:lower()
|
||||
for k,v in pairs(t) do
|
||||
if string.find(v.lname, filter) then
|
||||
if string.find(v.lname, filter) then
|
||||
table.insert(r, v)
|
||||
end
|
||||
end
|
||||
else
|
||||
return t
|
||||
return r
|
||||
end
|
||||
return r
|
||||
return t
|
||||
end
|
||||
|
||||
function sumItems3(ingredients, items, summedItems, count)
|
||||
local function sumItems3(ingredients, items, summedItems, count)
|
||||
|
||||
local canCraft = 0
|
||||
for _,item in pairs(ingredients) do
|
||||
@ -179,7 +192,7 @@ local function sumItems2(ingredients, items, summedItems, count)
|
||||
return canCraft
|
||||
end
|
||||
|
||||
function sumItems(items)
|
||||
local function sumItems(items)
|
||||
local t = {}
|
||||
|
||||
for _,item in pairs(items) do
|
||||
@ -197,7 +210,7 @@ function sumItems(items)
|
||||
return t
|
||||
end
|
||||
|
||||
function isGridClear()
|
||||
local function isGridClear()
|
||||
for i = 1, 16 do
|
||||
if turtle.getItemCount(i) ~= 0 then
|
||||
return false
|
||||
@ -219,22 +232,11 @@ local function clearGrid()
|
||||
return true
|
||||
end
|
||||
|
||||
function turtleCraft(recipe, originalItem, qty)
|
||||
local function turtleCraft(recipe, originalItem, qty)
|
||||
|
||||
for k,v in pairs(recipe.ingredients) do
|
||||
|
||||
-- ugh
|
||||
local dmg = v.damage
|
||||
|
||||
--FIX - LOOKUP IN ITEMS
|
||||
if v.max_dmg and v.max_dmg > 0 then
|
||||
local item = ME.getItemDetail({ id = v.id, nbt_hash = v.nbt_hash }, false)
|
||||
if item then
|
||||
dmg = item.dmg
|
||||
end
|
||||
end
|
||||
|
||||
chestProvider:provide({ id = v.name, dmg = dmg, nbt_hash = v.nbtHash }, v.count * qty, k)
|
||||
chestProvider:provide({ id = v.name, dmg = v.damage, nbt_hash = v.nbtHash }, v.count * qty, k)
|
||||
if turtle.getItemCount(k) ~= v.count * qty then
|
||||
clearGrid()
|
||||
originalItem.status = v.name .. ' (extract failed)'
|
||||
@ -256,7 +258,7 @@ function turtleCraft(recipe, originalItem, qty)
|
||||
return true
|
||||
end
|
||||
|
||||
function addCraftingRequest(item, craftList, count)
|
||||
local function addCraftingRequest(item, craftList, count)
|
||||
local key = uniqueKey(item)
|
||||
local request = craftList[key]
|
||||
if not craftList[key] then
|
||||
@ -267,9 +269,18 @@ function addCraftingRequest(item, craftList, count)
|
||||
request.count = request.count + count
|
||||
end
|
||||
|
||||
function craftRecipe(recipe, items, originalItem, count)
|
||||
local function craftRecipe(recipe, items, originalItem, count)
|
||||
|
||||
local maxCount = 64
|
||||
local maxCount = recipe.maxCount
|
||||
|
||||
if not maxCount then -- temporary
|
||||
local cItem = itemDB:get(itemDB:makeKey(recipe))
|
||||
if cItem then
|
||||
maxCount = cItem.maxCount
|
||||
else
|
||||
maxCount = 1
|
||||
end
|
||||
end
|
||||
|
||||
local summedItems = sumItems(recipe.ingredients)
|
||||
for key,ingredient in pairs(summedItems) do
|
||||
@ -293,7 +304,7 @@ function craftRecipe(recipe, items, originalItem, count)
|
||||
return true
|
||||
end
|
||||
|
||||
function craftItem(recipe, items, originalItem, craftList, count)
|
||||
local function craftItem(recipe, items, originalItem, craftList, count)
|
||||
|
||||
if craftingPaused or not device.workbench or not isGridClear() then
|
||||
return
|
||||
@ -305,12 +316,11 @@ function craftItem(recipe, items, originalItem, craftList, count)
|
||||
|
||||
if toCraft > 0 then
|
||||
craftRecipe(recipe, items, originalItem, toCraft)
|
||||
items = chestProvider:listItems()
|
||||
end
|
||||
|
||||
count = count - toCraft
|
||||
|
||||
items = chestProvider:listItems()
|
||||
|
||||
local summedItems = { }
|
||||
sumItems3(recipe.ingredients, items, summedItems, count)
|
||||
|
||||
@ -321,7 +331,7 @@ function craftItem(recipe, items, originalItem, craftList, count)
|
||||
end
|
||||
end
|
||||
|
||||
function craftItems(craftList, allItems)
|
||||
local function craftItems(craftList, allItems)
|
||||
|
||||
for _,key in pairs(Util.keys(craftList)) do
|
||||
local item = craftList[key]
|
||||
@ -336,25 +346,29 @@ function craftItems(craftList, allItems)
|
||||
|
||||
for key,item in pairs(craftList) do
|
||||
|
||||
if controller and not recipes[key] then
|
||||
if controller:isCrafting(item) then
|
||||
item.status = '(crafting)'
|
||||
if not recipes[key] then
|
||||
if not controller then
|
||||
item.status = '(no recipe)'
|
||||
else
|
||||
if controller:isCrafting(item) then
|
||||
item.status = '(crafting)'
|
||||
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 controller:craft(item, count) then
|
||||
item.status = '(missing ingredients)'
|
||||
error('failed')
|
||||
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 controller:craft(item, count) then
|
||||
item.status = '(missing ingredients)'
|
||||
error('failed')
|
||||
end
|
||||
item.status = '(crafting)'
|
||||
end)
|
||||
if s then
|
||||
break -- successfully requested crafting
|
||||
end
|
||||
item.status = '(crafting)'
|
||||
end)
|
||||
if s then
|
||||
break -- successfully requested crafting
|
||||
count = math.floor(count / 2)
|
||||
end
|
||||
count = math.floor(count / 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -363,11 +377,11 @@ end
|
||||
|
||||
local function jobMonitor(jobList)
|
||||
|
||||
local mon
|
||||
local mon = Peripheral.getByType('monitor')
|
||||
|
||||
if device.monitor then
|
||||
if mon then
|
||||
mon = UI.Device({
|
||||
deviceType = 'monitor',
|
||||
device = mon,
|
||||
textScale = .5,
|
||||
})
|
||||
else
|
||||
@ -387,11 +401,10 @@ local function jobMonitor(jobList)
|
||||
})
|
||||
end
|
||||
|
||||
function getAutocraftItems()
|
||||
local t = Util.readTable('resource.limits') or { }
|
||||
local function getAutocraftItems()
|
||||
local craftList = { }
|
||||
|
||||
for _,res in pairs(t) do
|
||||
for _,res in pairs(resources) do
|
||||
|
||||
if res.auto then
|
||||
res.count = 4 -- this could be higher to increase autocrafting speed
|
||||
@ -426,19 +439,18 @@ local function getItemWithQty(items, res, ignoreDamage)
|
||||
return item
|
||||
end
|
||||
|
||||
function watchResources(items)
|
||||
local function watchResources(items)
|
||||
|
||||
local craftList = { }
|
||||
|
||||
local t = Util.readTable('resource.limits') or { }
|
||||
for k, res in pairs(t) do
|
||||
for k, res in pairs(resources) do
|
||||
local item = getItemWithQty(items, res, res.ignoreDamage)
|
||||
if not item then
|
||||
item = {
|
||||
damage = res.damage,
|
||||
nbtHash = res.nbtHash,
|
||||
name = res.name,
|
||||
displayName = res.displayName,
|
||||
displayName = getName(res),
|
||||
count = 0
|
||||
}
|
||||
end
|
||||
@ -472,7 +484,7 @@ function watchResources(items)
|
||||
return craftList
|
||||
end
|
||||
|
||||
itemPage = UI.Page {
|
||||
local itemPage = UI.Page {
|
||||
backgroundColor = colors.lightGray,
|
||||
titleBar = UI.TitleBar {
|
||||
title = 'Limit Resource',
|
||||
@ -481,10 +493,10 @@ itemPage = UI.Page {
|
||||
backgroundColor = colors.green
|
||||
},
|
||||
displayName = UI.Window {
|
||||
x = 5, y = 2, width = UI.term.width - 10, height = 3,
|
||||
x = 2, y = 2, width = UI.term.width - 4, height = 3,
|
||||
},
|
||||
form = UI.Form {
|
||||
x = 4, y = 4, height = 8, rex = -4,
|
||||
x = 4, y = 5, height = 8, rex = -4,
|
||||
[1] = UI.TextEntry {
|
||||
width = 7,
|
||||
backgroundColor = colors.gray,
|
||||
@ -555,7 +567,7 @@ 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)
|
||||
str = str .. string.format('\n%s', item.nbtHash)
|
||||
end
|
||||
self:setCursorPos(1, 1)
|
||||
self:print(str)
|
||||
@ -593,9 +605,8 @@ function itemPage:eventHandler(event)
|
||||
|
||||
elseif event.type == 'form_complete' then
|
||||
local values = self.form.values
|
||||
local t = Util.readTable('resource.limits') or { }
|
||||
local keys = { 'name', 'displayName', 'auto', 'low', 'limit', 'damage',
|
||||
'maxDamage', 'nbtHash', 'ignoreDamage',
|
||||
local keys = { 'name', 'auto', 'low', 'limit', 'damage',
|
||||
'nbtHash', 'ignoreDamage',
|
||||
'rsControl', 'rsDevice', 'rsSide', }
|
||||
|
||||
local filtered = { }
|
||||
@ -605,16 +616,26 @@ function itemPage:eventHandler(event)
|
||||
filtered.low = tonumber(filtered.low)
|
||||
filtered.limit = tonumber(filtered.limit)
|
||||
|
||||
filtered.ignoreDamage = filtered.ignoreDamage == true
|
||||
filtered.auto = filtered.auto == true
|
||||
filtered.rsControl = filtered.rsControl == true
|
||||
--filtered.ignoreDamage = filtered.ignoreDamage == true
|
||||
--filtered.auto = filtered.auto == true
|
||||
--filtered.rsControl = filtered.rsControl == true
|
||||
|
||||
if filtered.ignoreDamage then
|
||||
if filtered.auto ~= true then
|
||||
filtered.auto = nil
|
||||
end
|
||||
|
||||
if filtered.rsControl ~= true then
|
||||
filtered.rsControl = nil
|
||||
filtered.rsSide = nil
|
||||
filtered.rsDevice = nil
|
||||
end
|
||||
|
||||
if values.ignoreDamage == true then
|
||||
filtered.damage = 0
|
||||
end
|
||||
|
||||
t[uniqueKey(filtered)] = filtered
|
||||
Util.writeTable('resource.limits', t)
|
||||
resources[uniqueKey(filtered)] = filtered
|
||||
Util.writeTable(RESOURCE_FILE, resources)
|
||||
|
||||
UI:setPreviousPage()
|
||||
|
||||
@ -624,11 +645,12 @@ function itemPage:eventHandler(event)
|
||||
return true
|
||||
end
|
||||
|
||||
listingPage = UI.Page {
|
||||
local listingPage = UI.Page {
|
||||
menuBar = UI.MenuBar {
|
||||
buttons = {
|
||||
{ text = 'Learn', event = 'learn' },
|
||||
{ text = 'Forget', event = 'forget' },
|
||||
{ text = 'Craft', event = 'craft' },
|
||||
},
|
||||
},
|
||||
grid = UI.Grid {
|
||||
@ -720,6 +742,9 @@ function listingPage:eventHandler(event)
|
||||
self.statusBar.filter:focus()
|
||||
|
||||
elseif event.type == 'learn' then
|
||||
UI:setPage('learn')
|
||||
|
||||
elseif event.type == 'craft' then
|
||||
UI:setPage('craft')
|
||||
|
||||
elseif event.type == 'forget' then
|
||||
@ -729,16 +754,12 @@ function listingPage:eventHandler(event)
|
||||
|
||||
if recipes[key] then
|
||||
recipes[key] = nil
|
||||
Util.writeTable('recipes', recipes)
|
||||
Util.writeTable(RECIPES_FILE, recipes)
|
||||
end
|
||||
|
||||
local resources = Util.readTable('resource.limits') or { }
|
||||
for k,v in pairs(resources) do
|
||||
if v.name == item.name and v.damage == item.damage then
|
||||
resources[k] = nil
|
||||
Util.writeTable('resource.limits', resources)
|
||||
break
|
||||
end
|
||||
if resources[key] then
|
||||
resources[key] = nil
|
||||
Util.writeTable(RESOURCE_FILE, resources)
|
||||
end
|
||||
|
||||
self.statusBar:timedStatus('Forgot: ' .. item.name, 3)
|
||||
@ -779,7 +800,7 @@ function listingPage:applyFilter()
|
||||
end
|
||||
|
||||
-- without duck antenna
|
||||
local function getTurtleInventory()
|
||||
local function getTurtleInventoryOld()
|
||||
local inventory = { }
|
||||
for i = 1,16 do
|
||||
if turtle.getItemCount(i) > 0 then
|
||||
@ -795,6 +816,20 @@ local function getTurtleInventory()
|
||||
return inventory
|
||||
end
|
||||
|
||||
local function getTurtleInventory()
|
||||
local inventory = { }
|
||||
for i = 1,16 do
|
||||
local qty = turtle.getItemCount(i)
|
||||
if qty > 0 then
|
||||
turtleChestProvider:insert(i, qty)
|
||||
local items = turtleChestProvider:listItems()
|
||||
_, inventory[i] = next(items)
|
||||
turtleChestProvider:extract(1, qty, i)
|
||||
end
|
||||
end
|
||||
return inventory
|
||||
end
|
||||
|
||||
local function filter(t, filter)
|
||||
local keys = Util.keys(t)
|
||||
for _,key in pairs(keys) do
|
||||
@ -817,10 +852,10 @@ local function learnRecipe(page)
|
||||
|
||||
clearGrid()
|
||||
|
||||
filter(recipe, { 'name', 'damage', 'nbtHash', 'count' })
|
||||
filter(recipe, { 'name', 'damage', 'nbtHash', 'count', 'maxCount' })
|
||||
|
||||
for _,ingredient in pairs(ingredients) do
|
||||
filter(ingredient, { 'name', 'damage', 'nbtHash', 'count' })
|
||||
filter(ingredient, { 'name', 'damage', 'nbtHash', 'count', 'maxCount' })
|
||||
--if ingredient.max_dmg > 0 then -- let's try this...
|
||||
-- ingredient.dmg = 0
|
||||
--end
|
||||
@ -829,7 +864,7 @@ local function learnRecipe(page)
|
||||
|
||||
recipes[key] = recipe
|
||||
|
||||
Util.writeTable('recipes', recipes)
|
||||
Util.writeTable(RECIPES_FILE, recipes)
|
||||
|
||||
local displayName = getName(recipe)
|
||||
|
||||
@ -849,13 +884,10 @@ local function learnRecipe(page)
|
||||
end
|
||||
end
|
||||
|
||||
craftPage = UI.Dialog {
|
||||
local learnPage = UI.Dialog {
|
||||
height = 7, width = UI.term.width - 6,
|
||||
backgroundColor = colors.lightGray,
|
||||
titleBar = UI.TitleBar {
|
||||
title = 'Learn Recipe',
|
||||
previousPage = true,
|
||||
},
|
||||
title = 'Learn Recipe',
|
||||
idField = UI.Text {
|
||||
x = 5,
|
||||
y = 3,
|
||||
@ -875,6 +907,61 @@ craftPage = UI.Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
function learnPage:enable()
|
||||
craftingPaused = true
|
||||
self:focusFirst()
|
||||
UI.Dialog.enable(self)
|
||||
end
|
||||
|
||||
function learnPage:disable()
|
||||
craftingPaused = false
|
||||
UI.Dialog.disable(self)
|
||||
end
|
||||
|
||||
function learnPage:eventHandler(event)
|
||||
if event.type == 'cancel' then
|
||||
UI:setPreviousPage()
|
||||
elseif event.type == 'accept' then
|
||||
if learnRecipe(self) then
|
||||
UI:setPreviousPage()
|
||||
end
|
||||
else
|
||||
return UI.Dialog.eventHandler(self, event)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local craftPage = UI.Dialog {
|
||||
height = 6, width = UI.term.width - 10,
|
||||
backgroundColor = colors.lightGray,
|
||||
title = 'Enter amount to craft',
|
||||
idField = UI.TextEntry {
|
||||
x = 15,
|
||||
y = 3,
|
||||
width = 10,
|
||||
limit = 6,
|
||||
value = '1',
|
||||
backgroundColor = colors.black,
|
||||
backgroundFocusColor = colors.black,
|
||||
},
|
||||
accept = UI.Button {
|
||||
rx = -7, ry = -1,
|
||||
backgroundColor = colors.green,
|
||||
text = '+', event = 'accept',
|
||||
},
|
||||
cancel = UI.Button {
|
||||
rx = -3, ry = -1,
|
||||
backgroundColor = colors.red,
|
||||
backgroundFocusColor = colors.red,
|
||||
text = '\215', event = 'cancel'
|
||||
},
|
||||
}
|
||||
|
||||
function craftPage:draw()
|
||||
UI.Dialog.draw(self)
|
||||
self:write(6, 3, 'Quantity')
|
||||
end
|
||||
|
||||
function craftPage:enable()
|
||||
craftingPaused = true
|
||||
self:focusFirst()
|
||||
@ -890,9 +977,7 @@ function craftPage:eventHandler(event)
|
||||
if event.type == 'cancel' then
|
||||
UI:setPreviousPage()
|
||||
elseif event.type == 'accept' then
|
||||
if learnRecipe(self) then
|
||||
UI:setPreviousPage()
|
||||
end
|
||||
|
||||
else
|
||||
return UI.Dialog.eventHandler(self, event)
|
||||
end
|
||||
@ -902,6 +987,7 @@ end
|
||||
UI:setPages({
|
||||
listing = listingPage,
|
||||
item = itemPage,
|
||||
learn = learnPage,
|
||||
craft = craftPage,
|
||||
})
|
||||
|
||||
@ -913,15 +999,12 @@ jobMonitor()
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
|
||||
function craftingThread()
|
||||
local function craftingThread()
|
||||
|
||||
while true do
|
||||
os.sleep(5)
|
||||
|
||||
if not craftingPaused then
|
||||
|
||||
local items = chestProvider:listItems()
|
||||
|
||||
if Util.size(items) == 0 then
|
||||
jobListGrid.parent:clear()
|
||||
jobListGrid.parent:centeredWrite(math.ceil(jobListGrid.parent.height/2), 'No items in system')
|
||||
@ -942,8 +1025,6 @@ function craftingThread()
|
||||
end
|
||||
end
|
||||
end
|
||||
--craftingThread()
|
||||
UI:pullEvents(craftingThread)
|
||||
|
||||
UI.term:reset()
|
||||
UI:pullEvents(craftingThread)
|
||||
jobListGrid.parent:reset()
|
||||
|
@ -61,40 +61,37 @@ function getClient(id)
|
||||
return ids[id]
|
||||
end
|
||||
|
||||
local function logWriter()
|
||||
while true do
|
||||
os.pullEvent('logMessage')
|
||||
local t = { }
|
||||
while #messages > 0 do
|
||||
local msg = messages[1]
|
||||
table.remove(messages, 1)
|
||||
local client = getClient(msg.id)
|
||||
client.scrollingText:appendLine(string.format('%d %s', math.floor(os.clock()), msg.text))
|
||||
t[msg.id] = client
|
||||
end
|
||||
for _,client in pairs(t) do
|
||||
client.scrollingText:draw()
|
||||
end
|
||||
terminal:sync()
|
||||
Event.on('logMessage', function()
|
||||
local t = { }
|
||||
while #messages > 0 do
|
||||
local msg = messages[1]
|
||||
table.remove(messages, 1)
|
||||
local client = getClient(msg.id)
|
||||
client.scrollingText:appendLine(string.format('%d %s', math.floor(os.clock()), msg.text))
|
||||
t[msg.id] = client
|
||||
end
|
||||
end
|
||||
for _,client in pairs(t) do
|
||||
client.scrollingText:draw()
|
||||
end
|
||||
terminal:sync()
|
||||
end)
|
||||
|
||||
Message.addHandler('log', function(h, id, msg)
|
||||
table.insert(messages, { id = id, text = msg.contents })
|
||||
os.queueEvent('logMessage')
|
||||
end)
|
||||
|
||||
Event.addHandler('monitor_touch', function()
|
||||
Event.on('monitor_touch', function()
|
||||
terminal:reset()
|
||||
ids = { }
|
||||
end)
|
||||
|
||||
Event.addHandler('mouse_click', function()
|
||||
Event.on('mouse_click', function()
|
||||
terminal:reset()
|
||||
ids = { }
|
||||
end)
|
||||
|
||||
Event.addHandler('char', function()
|
||||
Event.on('char', function()
|
||||
Event.exitPullEvents()
|
||||
end)
|
||||
|
||||
|
@ -2,7 +2,7 @@ require = requireInjector(getfenv(1))
|
||||
local Socket = require('socket')
|
||||
local Terminal = require('terminal')
|
||||
local Logger = require('logger')
|
||||
local process = require('process')
|
||||
local Event = require('event')
|
||||
|
||||
Logger.setScreenLogging()
|
||||
|
||||
@ -31,7 +31,12 @@ local function wrapTerm(socket)
|
||||
socket.term[k] = function(...)
|
||||
if not socket.queue then
|
||||
socket.queue = { }
|
||||
os.queueEvent('mirror_flush')
|
||||
Event.onTimeout(0, function()
|
||||
if socket.queue then
|
||||
socket:write(socket.queue)
|
||||
socket.queue = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
table.insert(socket.queue, {
|
||||
f = k,
|
||||
@ -61,17 +66,13 @@ while true do
|
||||
os.queueEvent('term_resize')
|
||||
|
||||
while true do
|
||||
local e = process:pullEvent('mirror_flush')
|
||||
local e = Event.pullEvent()
|
||||
if e == 'terminate' then
|
||||
break
|
||||
end
|
||||
if not socket.connected then
|
||||
break
|
||||
end
|
||||
if socket.queue then
|
||||
socket:write(socket.queue)
|
||||
socket.queue = nil
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(socket.oldTerm) do
|
||||
|
@ -1,7 +1,7 @@
|
||||
require = requireInjector(getfenv(1))
|
||||
local Event = require('event')
|
||||
local Socket = require('socket')
|
||||
local Logger = require('logger')
|
||||
local process = require('process')
|
||||
|
||||
Logger.setScreenLogging()
|
||||
|
||||
@ -20,7 +20,7 @@ while true do
|
||||
|
||||
print('mirror: connection from ' .. socket.dhost)
|
||||
|
||||
local updateThread = process:newThread('updateThread', function()
|
||||
Event.addRoutine(function()
|
||||
while true do
|
||||
local data = socket:read()
|
||||
if not data then
|
||||
@ -33,18 +33,15 @@ while true do
|
||||
end)
|
||||
|
||||
-- ensure socket is connected
|
||||
process:newThread('pinger', function()
|
||||
while true do
|
||||
os.sleep(3)
|
||||
if not socket:ping() then
|
||||
break
|
||||
end
|
||||
Event.onInterval(3, function(h)
|
||||
if not socket:ping() then
|
||||
Event.off(h)
|
||||
end
|
||||
end)
|
||||
|
||||
while true do
|
||||
process:pullEvent('modem_message')
|
||||
if updateThread:isDead() then
|
||||
Event.pullEvent()
|
||||
if not socket.connected then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -243,6 +243,159 @@ turtle.run(function()
|
||||
end)
|
||||
]]
|
||||
|
||||
local levelScript = [[
|
||||
|
||||
require = requireInjector(getfenv(1))
|
||||
local Point = require('point')
|
||||
|
||||
local checkedNodes = { }
|
||||
local nodes = { }
|
||||
local box = { }
|
||||
|
||||
local function inBox(pt, box)
|
||||
return pt.x >= box.x and
|
||||
pt.y >= box.y and
|
||||
pt.z >= box.z and
|
||||
pt.x <= box.ex and
|
||||
pt.y <= box.ey and
|
||||
pt.z <= box.ez
|
||||
end
|
||||
|
||||
local function toKey(pt)
|
||||
return table.concat({ pt.x, pt.y, pt.z }, ':')
|
||||
end
|
||||
|
||||
local function addNode(node)
|
||||
|
||||
for i = 0, 5 do
|
||||
local hi = turtle.getHeadingInfo(i)
|
||||
local testNode = { x = node.x + hi.xd, y = node.y + hi.yd, z = node.z + hi.zd }
|
||||
|
||||
if inBox(testNode, box) then
|
||||
local key = toKey(testNode)
|
||||
if not checkedNodes[key] then
|
||||
nodes[key] = testNode
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dig(action)
|
||||
|
||||
local directions = {
|
||||
top = 'up',
|
||||
bottom = 'down',
|
||||
}
|
||||
|
||||
-- convert to up, down, north, south, east, west
|
||||
local direction = directions[action.side] or
|
||||
turtle.getHeadingInfo(turtle.point.heading).direction
|
||||
|
||||
local hi = turtle.getHeadingInfo(direction)
|
||||
local node = { x = turtle.point.x + hi.xd, y = turtle.point.y + hi.yd, z = turtle.point.z + hi.zd }
|
||||
if inBox(node, box) then
|
||||
|
||||
local key = toKey(node)
|
||||
checkedNodes[key] = true
|
||||
nodes[key] = nil
|
||||
|
||||
if action.dig() then
|
||||
addNode(node)
|
||||
repeat until not action.dig() -- sand, etc
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function move(action)
|
||||
if action == 'turn' then
|
||||
dig(turtle.getAction('forward'))
|
||||
elseif action == 'up' then
|
||||
dig(turtle.getAction('up'))
|
||||
elseif action == 'down' then
|
||||
dig(turtle.getAction('down'))
|
||||
elseif action == 'back' then
|
||||
dig(turtle.getAction('up'))
|
||||
dig(turtle.getAction('down'))
|
||||
end
|
||||
end
|
||||
|
||||
local function getAdjacentPoint(pt)
|
||||
local t = { }
|
||||
table.insert(t, pt)
|
||||
for i = 0, 5 do
|
||||
local hi = turtle.getHeadingInfo(i)
|
||||
local heading
|
||||
if i < 4 then
|
||||
heading = (hi.heading + 2) % 4
|
||||
end
|
||||
table.insert(t, { x = pt.x + hi.xd, z = pt.z + hi.zd, y = pt.y + hi.yd, heading = heading })
|
||||
end
|
||||
|
||||
return Point.closest2(turtle.getPoint(), t)
|
||||
end
|
||||
|
||||
local function level()
|
||||
|
||||
box.x = math.min(data.startPt.x, data.endPt.x)
|
||||
box.y = math.min(data.startPt.y, data.endPt.y)
|
||||
box.z = math.min(data.startPt.z, data.endPt.z)
|
||||
box.ex = math.max(data.startPt.x, data.endPt.x)
|
||||
box.ey = math.max(data.startPt.y, data.endPt.y)
|
||||
box.ez = math.max(data.startPt.z, data.endPt.z)
|
||||
|
||||
turtle.pathfind(data.firstPt)
|
||||
|
||||
turtle.setPolicy("attack", { dig = dig }, "assuredMove")
|
||||
turtle.setMoveCallback(move)
|
||||
|
||||
repeat
|
||||
local key = toKey(turtle.point)
|
||||
|
||||
checkedNodes[key] = true
|
||||
nodes[key] = nil
|
||||
|
||||
dig(turtle.getAction('down'))
|
||||
dig(turtle.getAction('up'))
|
||||
dig(turtle.getAction('forward'))
|
||||
|
||||
print(string.format('%d nodes remaining', Util.size(nodes)))
|
||||
|
||||
if Util.size(nodes) == 0 then
|
||||
break
|
||||
end
|
||||
|
||||
local node = Point.closest2(turtle.point, nodes)
|
||||
node = getAdjacentPoint(node)
|
||||
if not turtle.gotoPoint(node) then
|
||||
break
|
||||
end
|
||||
until turtle.abort
|
||||
|
||||
turtle.resetState()
|
||||
end
|
||||
|
||||
local s, m = turtle.run(function()
|
||||
turtle.status = 'Leveling'
|
||||
|
||||
if turtle.enableGPS() then
|
||||
|
||||
local pt = Util.shallowCopy(turtle.point)
|
||||
local s, m = pcall(level)
|
||||
turtle.pathfind(pt)
|
||||
|
||||
if not s and m then
|
||||
error(m)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if not s then
|
||||
error(m)
|
||||
end
|
||||
]]
|
||||
|
||||
|
||||
local data = Util.readTable('/usr/config/shapes') or { }
|
||||
|
||||
local page = UI.Page {
|
||||
@ -251,6 +404,7 @@ local page = UI.Page {
|
||||
startCoord = UI.Button { x = 2, y = 6, text = 'Start ', event = 'startCoord' },
|
||||
endCoord = UI.Button { x = 2, y = 8, text = 'End ', event = 'endCoord' },
|
||||
supplies = UI.Button { x = 2, y = 10, text = 'Supplies', event = 'supplies' },
|
||||
first = UI.Button { x = 2, y = 11, text = 'First', event = 'firstCoord' },
|
||||
cancel = UI.Button { rx = 2, ry = -2, text = 'Abort', event = 'cancel' },
|
||||
begin = UI.Button { rx = -7, ry = -2, text = 'Begin', event = 'begin' },
|
||||
accelerators = { q = 'quit' },
|
||||
@ -286,6 +440,7 @@ end
|
||||
|
||||
function page:runFunction(id, script)
|
||||
|
||||
Util.writeFile('script.tmp', script)
|
||||
self.notification:info('Connecting')
|
||||
local fn, msg = loadstring(script, 'script')
|
||||
if not fn then
|
||||
@ -299,7 +454,6 @@ function page:runFunction(id, script)
|
||||
self.notification:error('Unable to connect')
|
||||
return
|
||||
end
|
||||
|
||||
socket:write({ type = 'script', args = script })
|
||||
socket:close()
|
||||
|
||||
@ -321,6 +475,13 @@ function page:eventHandler(event)
|
||||
Util.writeTable('/usr/config/shapes', data)
|
||||
end
|
||||
self:draw()
|
||||
elseif event.type == 'firstCoord' then
|
||||
data.firstPt = self:getPoint()
|
||||
if data.firstPt then
|
||||
self.statusBar:setStatus('first point set')
|
||||
Util.writeTable('/usr/config/shapes', data)
|
||||
end
|
||||
self:draw()
|
||||
elseif event.type == 'supplies' then
|
||||
data.suppliesPt = self:getPoint()
|
||||
if data.suppliesPt then
|
||||
@ -329,7 +490,7 @@ function page:eventHandler(event)
|
||||
end
|
||||
elseif event.type == 'begin' then
|
||||
if data.startPt and data.endPt then
|
||||
local s = 'local data = ' .. textutils.serialize(data) .. script
|
||||
local s = 'local data = ' .. textutils.serialize(data) .. levelScript
|
||||
self:runFunction(turtleId, s)
|
||||
else
|
||||
self.notification:error('Corners not set')
|
||||
|
@ -863,43 +863,37 @@ jobMonitor()
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
|
||||
function craftingThread()
|
||||
Event.onInterval(5, function()
|
||||
|
||||
while true do
|
||||
os.sleep(5)
|
||||
if not craftingPaused then
|
||||
|
||||
if not craftingPaused then
|
||||
local items = ME.getAvailableItems()
|
||||
|
||||
if Util.size(items) == 0 then
|
||||
jobListGrid.parent:clear()
|
||||
jobListGrid.parent:centeredWrite(math.ceil(jobListGrid.parent.height/2), 'No items in system')
|
||||
jobListGrid:sync()
|
||||
|
||||
elseif config.noCraftingStorage ~= 'true' and #ME.getCraftingCPUs() <= 0 then -- only way to determine if AE is online
|
||||
jobListGrid.parent:clear()
|
||||
jobListGrid.parent:centeredWrite(math.ceil(jobListGrid.parent.height/2), 'Power failure')
|
||||
jobListGrid:sync()
|
||||
|
||||
local items = ME.getAvailableItems()
|
||||
|
||||
if Util.size(items) == 0 then
|
||||
jobListGrid.parent:clear()
|
||||
jobListGrid.parent:centeredWrite(math.ceil(jobListGrid.parent.height/2), 'No items in system')
|
||||
jobListGrid:sync()
|
||||
|
||||
elseif config.noCraftingStorage ~= 'true' and #ME.getCraftingCPUs() <= 0 then -- only way to determine if AE is online
|
||||
jobListGrid.parent:clear()
|
||||
jobListGrid.parent:centeredWrite(math.ceil(jobListGrid.parent.height/2), 'Power failure')
|
||||
jobListGrid:sync()
|
||||
else
|
||||
local itemList = watchResources(items)
|
||||
jobListGrid:setValues(itemList)
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
craftItems(itemList)
|
||||
jobListGrid:update()
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
|
||||
else
|
||||
local itemList = watchResources(items)
|
||||
jobListGrid:setValues(itemList)
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
craftItems(itemList)
|
||||
jobListGrid:update()
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
|
||||
itemList = getAutocraftItems(items) -- autocrafted items don't show on job monitor
|
||||
craftItems(itemList)
|
||||
end
|
||||
itemList = getAutocraftItems(items) -- autocrafted items don't show on job monitor
|
||||
craftItems(itemList)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
Event.pullEvents(craftingThread)
|
||||
|
||||
UI.term:reset()
|
||||
UI:pullEvents()
|
||||
jobListGrid.parent:reset()
|
@ -429,7 +429,6 @@ end
|
||||
|
||||
turtle.run(function()
|
||||
turtle.setPoint({ x = -1, z = -2, y = -1, heading = 1 })
|
||||
turtle.getState().coordSystem = 'relative'
|
||||
|
||||
turtle.saveLocation('supplies')
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
require = requireInjector(getfenv(1))
|
||||
local process = require('process')
|
||||
local Event = require('event')
|
||||
local Socket = require('socket')
|
||||
local Terminal = require('terminal')
|
||||
|
||||
@ -36,7 +36,7 @@ socket:write({
|
||||
isColor = ct.isColor(),
|
||||
})
|
||||
|
||||
process:newThread('telnet_read', function()
|
||||
Event.addRoutine(function()
|
||||
while true do
|
||||
local data = socket:read()
|
||||
if not data then
|
||||
@ -57,7 +57,7 @@ local filter = Util.transpose({
|
||||
})
|
||||
|
||||
while true do
|
||||
local e = { process:pullEvent() }
|
||||
local e = Event.pullEvent()
|
||||
local event = e[1]
|
||||
|
||||
if not socket.connected then
|
||||
|
@ -1,5 +1,5 @@
|
||||
require = requireInjector(getfenv(1))
|
||||
local process = require('process')
|
||||
local Event = require('event')
|
||||
local Socket = require('socket')
|
||||
local Terminal = require('terminal')
|
||||
|
||||
@ -39,7 +39,7 @@ if not ct.isColor() then
|
||||
Terminal.toGrayscale(ct)
|
||||
end
|
||||
|
||||
process:newThread('vnc_read', function()
|
||||
Event.addRoutine(function()
|
||||
while true do
|
||||
local data = socket:read()
|
||||
if not data then
|
||||
@ -60,7 +60,7 @@ local filter = Util.transpose({
|
||||
})
|
||||
|
||||
while true do
|
||||
local e = { process:pullEvent() }
|
||||
local e = Event.pullEvent()
|
||||
local event = e[1]
|
||||
|
||||
if not socket.connected then
|
||||
|
83
sys/etc/scripts/level
Normal file
83
sys/etc/scripts/level
Normal file
@ -0,0 +1,83 @@
|
||||
require = requireInjector(getfenv(1))
|
||||
local Point = require('point')
|
||||
|
||||
local checkedNodes = { }
|
||||
local nodes = { }
|
||||
local box = { x = 65, ex = 69, y = 65, ey = 70, z = -23, ez = -19 }
|
||||
|
||||
local function inBox(pt, box)
|
||||
return pt.x >= box.x and
|
||||
pt.y >= box.y and
|
||||
pt.z >= box.z and
|
||||
pt.x <= box.ex and
|
||||
pt.y <= box.ey and
|
||||
pt.z <= box.ez
|
||||
end
|
||||
|
||||
local function toKey(pt)
|
||||
return table.concat({ pt.x, pt.y, pt.z }, ':')
|
||||
end
|
||||
|
||||
local function addNode(node)
|
||||
|
||||
for i = 0, 5 do
|
||||
local hi = turtle.getHeadingInfo(i)
|
||||
local testNode = { x = node.x + hi.xd, y = node.y + hi.yd, z = node.z + hi.zd }
|
||||
|
||||
if inBox(testNode, box) then
|
||||
local key = toKey(testNode)
|
||||
if not checkedNodes[key] then
|
||||
nodes[key] = testNode
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dig(facing)
|
||||
local direction = facing
|
||||
if direction == 'forward' then
|
||||
direction = turtle.getHeadingInfo(turtle.point.heading).direction
|
||||
end
|
||||
local hi = turtle.getHeadingInfo(direction)
|
||||
local node = { x = turtle.point.x + hi.xd, y = turtle.point.y + hi.yd, z = turtle.point.z + hi.zd }
|
||||
if inBox(node, box) then
|
||||
if turtle.getAction(facing).dig() then
|
||||
addNode(node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function level()
|
||||
repeat
|
||||
local node = { x = turtle.point.x, y = turtle.point.y, z = turtle.point.z }
|
||||
local key = toKey(node)
|
||||
|
||||
checkedNodes[key] = true
|
||||
nodes[key] = nil
|
||||
|
||||
dig('down')
|
||||
dig('up')
|
||||
dig('forward')
|
||||
|
||||
print(string.format('%d nodes remaining', Util.size(nodes)))
|
||||
|
||||
if Util.size(nodes) == 0 then
|
||||
break
|
||||
end
|
||||
|
||||
local node = Point.closest(turtle.point, nodes)
|
||||
if not turtle.gotoPoint(node) then
|
||||
break
|
||||
end
|
||||
until turtle.abort
|
||||
end
|
||||
|
||||
local pt = Util.shallowCopy(turtle.point)
|
||||
turtle.setPolicy(turtle.policies.none)
|
||||
if turtle.pathfind({ x = 65, y = 70, z = -23 }) then
|
||||
--turtle.reset()
|
||||
turtle.setPolicy(turtle.policies.digOnly)
|
||||
level()
|
||||
end
|
||||
turtle.pathfind(pt)
|
||||
--local s, m = turtle.run(level)
|
@ -7,7 +7,6 @@ local function summon(id)
|
||||
|
||||
turtle.status = 'GPSing'
|
||||
turtle.setPoint({ x = 0, y = 0, z = 0, heading = 0 })
|
||||
turtle.getState().coordSystem = 'relative'
|
||||
|
||||
local pts = {
|
||||
[ 1 ] = { x = 0, z = 0, y = 0 },
|
||||
|
@ -6,15 +6,14 @@ require = requireInjector(getfenv(1))
|
||||
local GPS = require('gps')
|
||||
|
||||
function turtle.enableGPS(timeout)
|
||||
if turtle.getState().coordSystem == 'GPS' then
|
||||
if turtle.point.gps == 'GPS' then
|
||||
return turtle.point
|
||||
end
|
||||
|
||||
local pt = GPS.getPointAndHeading(timeout)
|
||||
if pt then
|
||||
turtle.setPoint(pt)
|
||||
turtle.getState().coordSystem = 'GPS'
|
||||
return true
|
||||
turtle.setPoint(pt, true)
|
||||
return turtle.point
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -7,30 +7,40 @@ local function noop() end
|
||||
turtle.point = { x = 0, y = 0, z = 0, heading = 0 }
|
||||
turtle.status = 'idle'
|
||||
turtle.abort = false
|
||||
local state = { }
|
||||
|
||||
function turtle.getPoint()
|
||||
return turtle.point
|
||||
function turtle.getPoint() return turtle.point end
|
||||
function turtle.getState() return state end
|
||||
|
||||
local function _defaultMove(action)
|
||||
while not action.move() do
|
||||
if not state.digPolicy(action) and not state.attackPolicy(action) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local state = {
|
||||
moveAttack = noop,
|
||||
moveDig = noop,
|
||||
moveCallback = noop,
|
||||
locations = {},
|
||||
coordSystem = 'relative', -- type of coordinate system being used
|
||||
}
|
||||
|
||||
function turtle.getState()
|
||||
return state
|
||||
end
|
||||
|
||||
function turtle.setPoint(pt)
|
||||
function turtle.setPoint(pt, isGPS)
|
||||
turtle.point.x = pt.x
|
||||
turtle.point.y = pt.y
|
||||
turtle.point.z = pt.z
|
||||
if pt.heading then
|
||||
turtle.point.heading = pt.heading
|
||||
end
|
||||
turtle.point.gps = isGPS
|
||||
return true
|
||||
end
|
||||
|
||||
function turtle.resetState()
|
||||
--turtle.abort = false -- should be part of state
|
||||
--turtle.status = 'idle' -- should be part of state
|
||||
state.attackPolicy = noop
|
||||
state.digPolicy = noop
|
||||
state.movePolicy = _defaultMove
|
||||
state.moveCallback = noop
|
||||
state.locations = { }
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
@ -39,27 +49,16 @@ function turtle.reset()
|
||||
turtle.point.y = 0
|
||||
turtle.point.z = 0
|
||||
turtle.point.heading = 0
|
||||
turtle.point.gps = false
|
||||
turtle.abort = false -- should be part of state
|
||||
--turtle.status = 'idle' -- should be part of state
|
||||
state.moveAttack = noop
|
||||
state.moveDig = noop
|
||||
state.moveCallback = noop
|
||||
state.locations = {}
|
||||
state.coordSystem = 'relative'
|
||||
|
||||
turtle.resetState()
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function turtle.resetState()
|
||||
--turtle.abort = false -- should be part of state
|
||||
--turtle.status = 'idle' -- should be part of state
|
||||
state.moveAttack = noop
|
||||
state.moveDig = noop
|
||||
state.moveCallback = noop
|
||||
state.locations = {}
|
||||
|
||||
return true
|
||||
end
|
||||
turtle.reset()
|
||||
|
||||
local actions = {
|
||||
up = {
|
||||
@ -116,12 +115,12 @@ end
|
||||
|
||||
-- [[ Heading data ]] --
|
||||
local headings = {
|
||||
[ 0 ] = { xd = 1, zd = 0, yd = 0, heading = 0, direction = 'east' },
|
||||
[ 0 ] = { xd = 1, zd = 0, yd = 0, heading = 0, direction = 'east' },
|
||||
[ 1 ] = { xd = 0, zd = 1, yd = 0, heading = 1, direction = 'south' },
|
||||
[ 2 ] = { xd = -1, zd = 0, yd = 0, heading = 2, direction = 'west' },
|
||||
[ 2 ] = { xd = -1, zd = 0, yd = 0, heading = 2, direction = 'west' },
|
||||
[ 3 ] = { xd = 0, zd = -1, yd = 0, heading = 3, direction = 'north' },
|
||||
[ 4 ] = { xd = 0, zd = 0, yd = 1, heading = 4, direction = 'up' },
|
||||
[ 5 ] = { xd = 0, zd = 0, yd = -1, heading = 5, direction = 'down' }
|
||||
[ 4 ] = { xd = 0, zd = 0, yd = 1, heading = 4, direction = 'up' },
|
||||
[ 5 ] = { xd = 0, zd = 0, yd = -1, heading = 5, direction = 'down' }
|
||||
}
|
||||
|
||||
local namedHeadings = {
|
||||
@ -133,9 +132,7 @@ local namedHeadings = {
|
||||
down = headings[5]
|
||||
}
|
||||
|
||||
function turtle.getHeadings()
|
||||
return headings
|
||||
end
|
||||
function turtle.getHeadings() return headings end
|
||||
|
||||
function turtle.getHeadingInfo(heading)
|
||||
if heading and type(heading) == 'string' then
|
||||
@ -181,8 +178,8 @@ local function _place(action, indexOrId)
|
||||
if result[1] then
|
||||
return true
|
||||
end
|
||||
if not state.moveDig(action) then
|
||||
state.moveAttack(action)
|
||||
if not state.digPolicy(action) then
|
||||
state.attackPolicy(action)
|
||||
end
|
||||
return unpack(result)
|
||||
end)
|
||||
@ -267,48 +264,66 @@ turtle.digPolicies = {
|
||||
end
|
||||
}
|
||||
|
||||
turtle.policies = {
|
||||
none = { dig = turtle.digPolicies.none, attack = turtle.attackPolicies.none },
|
||||
digOnly = { dig = turtle.digPolicies.dig, attack = turtle.attackPolicies.none },
|
||||
attackOnly = { dig = turtle.digPolicies.none, attack = turtle.attackPolicies.attack },
|
||||
digAttack = { dig = turtle.digPolicies.dig, attack = turtle.attackPolicies.attack },
|
||||
turtleSafe = { dig = turtle.digPolicies.turtleSafe, attack = turtle.attackPolicies.attack },
|
||||
turtle.movePolicies = {
|
||||
none = noop,
|
||||
default = _defaultMove,
|
||||
assured = function(action)
|
||||
if not _defaultMove(action) then
|
||||
if action.side == 'back' then
|
||||
return false
|
||||
end
|
||||
local oldStatus = turtle.status
|
||||
print('stuck')
|
||||
turtle.status = 'stuck'
|
||||
repeat
|
||||
os.sleep(1)
|
||||
until _defaultMove(action)
|
||||
turtle.status = oldStatus
|
||||
end
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
||||
function turtle.setPolicy(policy)
|
||||
if type(policy) == 'string' then
|
||||
policy = turtle.policies[policy]
|
||||
turtle.policies = {
|
||||
none = { dig = turtle.digPolicies.none, attack = turtle.attackPolicies.none },
|
||||
digOnly = { dig = turtle.digPolicies.dig, attack = turtle.attackPolicies.none },
|
||||
attackOnly = { dig = turtle.digPolicies.none, attack = turtle.attackPolicies.attack },
|
||||
digAttack = { dig = turtle.digPolicies.dig, attack = turtle.attackPolicies.attack },
|
||||
turtleSafe = { dig = turtle.digPolicies.turtleSafe, attack = turtle.attackPolicies.attack },
|
||||
|
||||
attack = { attack = turtle.attackPolicies.attack },
|
||||
|
||||
defaultMove = { move = turtle.movePolicies.default },
|
||||
assuredMove = { move = turtle.movePolicies.assured },
|
||||
}
|
||||
|
||||
function turtle.setPolicy(...)
|
||||
local args = { ... }
|
||||
for _, policy in pairs(args) do
|
||||
if type(policy) == 'string' then
|
||||
policy = turtle.policies[policy]
|
||||
end
|
||||
if not policy then
|
||||
error('Invalid policy')
|
||||
-- return false, 'Invalid policy'
|
||||
end
|
||||
if policy.dig then
|
||||
state.digPolicy = policy.dig
|
||||
end
|
||||
if policy.attack then
|
||||
state.attackPolicy = policy.attack
|
||||
end
|
||||
if policy.move then
|
||||
state.movePolicy = policy.move
|
||||
end
|
||||
end
|
||||
if not policy then
|
||||
return false, 'Invalid policy'
|
||||
end
|
||||
state.moveDig = policy.dig
|
||||
state.moveAttack = policy.attack
|
||||
return true
|
||||
end
|
||||
|
||||
function turtle.setDigPolicy(policy)
|
||||
state.moveDig = policy
|
||||
end
|
||||
|
||||
function turtle.setAttackPolicy(policy)
|
||||
state.moveAttack = policy
|
||||
end
|
||||
|
||||
function turtle.setMoveCallback(cb)
|
||||
state.moveCallback = cb
|
||||
end
|
||||
|
||||
function turtle.clearMoveCallback()
|
||||
state.moveCallback = noop
|
||||
end
|
||||
|
||||
local function infoMoveCallback()
|
||||
local pt = turtle.point
|
||||
print(string.format('x:%d y:%d z:%d heading:%d', pt.x, pt.y, pt.z, pt.heading))
|
||||
end
|
||||
-- TESTING
|
||||
--turtle.setMoveCallback(infoMoveCallback)
|
||||
function turtle.setDigPolicy(policy) state.digPolicy = policy end
|
||||
function turtle.setAttackPolicy(policy) state.attackPolicy = policy end
|
||||
function turtle.setMoveCallback(cb) state.moveCallback = cb end
|
||||
function turtle.clearMoveCallback() state.moveCallback = noop end
|
||||
|
||||
-- [[ Locations ]] --
|
||||
function turtle.getLocation(name)
|
||||
@ -364,6 +379,7 @@ function turtle.turnAround()
|
||||
return turtle.point
|
||||
end
|
||||
|
||||
-- combine with setHeading
|
||||
function turtle.setNamedHeading(headingName)
|
||||
local headingInfo = namedHeadings[headingName]
|
||||
if headingInfo then
|
||||
@ -432,17 +448,8 @@ function turtle.headTowards(pt)
|
||||
end
|
||||
|
||||
-- [[ move ]] --
|
||||
local function _move(action)
|
||||
while not action.move() do
|
||||
if not state.moveDig(action) and not state.moveAttack(action) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function turtle.up()
|
||||
if _move(actions.up) then
|
||||
if state.movePolicy(actions.up) then
|
||||
turtle.point.y = turtle.point.y + 1
|
||||
state.moveCallback('up', turtle.point)
|
||||
return true, turtle.point
|
||||
@ -450,7 +457,7 @@ function turtle.up()
|
||||
end
|
||||
|
||||
function turtle.down()
|
||||
if _move(actions.down) then
|
||||
if state.movePolicy(actions.down) then
|
||||
turtle.point.y = turtle.point.y - 1
|
||||
state.moveCallback('down', turtle.point)
|
||||
return true, turtle.point
|
||||
@ -458,7 +465,7 @@ function turtle.down()
|
||||
end
|
||||
|
||||
function turtle.forward()
|
||||
if _move(actions.forward) then
|
||||
if state.movePolicy(actions.forward) then
|
||||
turtle.point.x = turtle.point.x + headings[turtle.point.heading].xd
|
||||
turtle.point.z = turtle.point.z + headings[turtle.point.heading].zd
|
||||
state.moveCallback('forward', turtle.point)
|
||||
@ -467,7 +474,7 @@ function turtle.forward()
|
||||
end
|
||||
|
||||
function turtle.back()
|
||||
if _move(actions.back) then
|
||||
if state.movePolicy(actions.back) then
|
||||
turtle.point.x = turtle.point.x - headings[turtle.point.heading].xd
|
||||
turtle.point.z = turtle.point.z - headings[turtle.point.heading].zd
|
||||
state.moveCallback('back', turtle.point)
|
||||
|
@ -129,7 +129,6 @@ local function sendInfo()
|
||||
info.status = turtle.status
|
||||
info.point = turtle.point
|
||||
info.inventory = turtle.getInventory()
|
||||
info.coordSystem = turtle.getState().coordSystem
|
||||
info.slotIndex = turtle.getSelectedSlot()
|
||||
end
|
||||
device.wireless_modem.transmit(999, os.getComputerID(), info)
|
||||
|
@ -75,9 +75,9 @@ process:newThread('vnc_server', function()
|
||||
|
||||
local termInfo = socket:read(5)
|
||||
if termInfo then
|
||||
-- no new process - only 1 connection allowed
|
||||
-- due to term size issues
|
||||
vncHost(socket, termInfo)
|
||||
-- no new process - only 1 connection allowed
|
||||
-- due to term size issues
|
||||
vncHost(socket, termInfo)
|
||||
else
|
||||
socket:close()
|
||||
end
|
||||
|
@ -12,7 +12,7 @@ if not term.isColor() then
|
||||
detachColor = colors.lightGray
|
||||
end
|
||||
|
||||
Event.addHandler('peripheral', function(event, side)
|
||||
Event.on('peripheral', function(event, side)
|
||||
if side then
|
||||
local dev = Peripheral.addDevice(device, side)
|
||||
if dev then
|
||||
@ -23,7 +23,7 @@ Event.addHandler('peripheral', function(event, side)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.addHandler('peripheral_detach', function(event, side)
|
||||
Event.on('peripheral_detach', function(event, side)
|
||||
if side then
|
||||
local dev = Util.find(device, 'side', side)
|
||||
if dev then
|
||||
|
Loading…
Reference in New Issue
Block a user