api cleanup
This commit is contained in:
146
apps/crafter.lua
146
apps/crafter.lua
@@ -44,6 +44,16 @@ local function getItem(items, inItem, ignoreDamage)
|
||||
end
|
||||
end
|
||||
|
||||
local function getItemCount(items, inItem)
|
||||
inItem.count = 0
|
||||
for _,item in pairs(items) do
|
||||
if item.name == inItem.name and item.damage == inItem.damage and item.nbtHash == inItem.nbtHash then
|
||||
inItem.count = item.count
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function uniqueKey(item)
|
||||
return table.concat({ item.name, item.damage, item.nbtHash }, ':')
|
||||
end
|
||||
@@ -107,69 +117,138 @@ local function clearGrid()
|
||||
end
|
||||
|
||||
local function gotoMachine(machine)
|
||||
|
||||
local index
|
||||
if type(machine) == 'number' then
|
||||
index = machine
|
||||
else
|
||||
local _, k = Util.find(machines, 'name', machine)
|
||||
|
||||
if not k then
|
||||
error('Unable to locate machine: ' .. tostring(machine))
|
||||
for _ = 1, machine do
|
||||
if not turtle.back() then
|
||||
return
|
||||
end
|
||||
index = k - 1
|
||||
end
|
||||
|
||||
for _ = 1, index do
|
||||
turtle.back()
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function canCraft(recipe, items, count)
|
||||
count = math.ceil(count / recipe.count)
|
||||
|
||||
local icount = Util.size(recipe.ingredients)
|
||||
local maxSlots = math.floor(16 / icount)
|
||||
debug(maxSlots)
|
||||
for key,qty in pairs(recipe.ingredients) do
|
||||
local item = getItem(items, itemDB:splitKey(key))
|
||||
if not item then
|
||||
return 0, itemDB:getName(key)
|
||||
end
|
||||
local x = math.min(math.floor(item.count / qty), item.maxCount)
|
||||
local x = math.min(math.floor(item.count / qty), item.maxCount * maxSlots)
|
||||
count = math.min(x, count)
|
||||
debug(count)
|
||||
end
|
||||
|
||||
return count
|
||||
return count, ''
|
||||
end
|
||||
|
||||
local function craftItem(recipe, items, cItem, count)
|
||||
repeat until not turtle.forward()
|
||||
|
||||
local missing
|
||||
count, missing = canCraft(recipe, items, count)
|
||||
-- local missing
|
||||
-- count, missing = canCraft(recipe, items, count)
|
||||
-- if count == 0 then
|
||||
-- cItem.status = 'missing ' .. missing
|
||||
-- return false
|
||||
-- end
|
||||
if count == 0 then
|
||||
cItem.status = 'missing ' .. missing
|
||||
cItem.status = 'missing something'
|
||||
return false
|
||||
end
|
||||
|
||||
local slot = 1
|
||||
for key,qty in pairs(recipe.ingredients) do
|
||||
local item = itemDB:splitKey(key)
|
||||
inventoryAdapter:provide(item, count * qty, slot)
|
||||
if turtle.getItemCount(slot) ~= count * qty then
|
||||
cItem.status = 'failed'
|
||||
return false
|
||||
local item = itemDB:get(key)
|
||||
local c = count * qty
|
||||
while c > 0 do
|
||||
local maxCount = math.min(c, item.maxCount)
|
||||
inventoryAdapter:provide(item, maxCount, slot)
|
||||
if turtle.getItemCount(slot) == 0 then -- ~= maxCount then FIXXX !!!
|
||||
cItem.status = 'failed'
|
||||
debug(item)
|
||||
debug({ c, maxCount, count })
|
||||
read()
|
||||
return false
|
||||
end
|
||||
c = c - maxCount
|
||||
slot = slot + 1
|
||||
end
|
||||
slot = slot + 1
|
||||
end
|
||||
gotoMachine(recipe.machine)
|
||||
turtle.emptyInventory(turtle.dropDown)
|
||||
if #turtle.getFilledSlots() ~= 0 then
|
||||
cItem.status = 'machine busy'
|
||||
if not gotoMachine(recipe.machine) then
|
||||
cItem.status = 'failed to find machine'
|
||||
else
|
||||
cItem.status = 'crafting'
|
||||
turtle.emptyInventory(turtle.dropDown)
|
||||
if #turtle.getFilledSlots() ~= 0 then
|
||||
cItem.status = 'machine busy'
|
||||
else
|
||||
cItem.status = 'crafting'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function expandList(list)
|
||||
local items = lastItems
|
||||
|
||||
local function getCraftable(recipe, count)
|
||||
local maxSlots = math.floor(16 / Util.size(recipe.ingredients))
|
||||
|
||||
for key,qty in pairs(recipe.ingredients) do
|
||||
local item = getItem(items, itemDB:splitKey(key))
|
||||
if not item then
|
||||
item = itemDB:get(key)
|
||||
item.count = 0
|
||||
end
|
||||
local need = qty * count
|
||||
debug({ key, count, need })
|
||||
local irecipe = recipes[key]
|
||||
if item.count < need and irecipe then
|
||||
need = math.ceil((need - item.count) / irecipe.count)
|
||||
if not list[key] then
|
||||
list[key] = Util.shallowCopy(item)
|
||||
list[key].ocount = need
|
||||
list[key].count = 0
|
||||
else
|
||||
list[key].ocount = list[key].ocount + need
|
||||
end
|
||||
debug('adding ' .. key .. ' ' .. need)
|
||||
local icount = getCraftable(irecipe, need)
|
||||
|
||||
list[key].count = list[key].count + icount
|
||||
end
|
||||
local x = math.min(math.floor(item.count / qty), item.maxCount * maxSlots)
|
||||
count = math.min(x, count)
|
||||
item.count = math.max(0, item.count - (count * qty))
|
||||
end
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
--[[
|
||||
list = { }
|
||||
debug(getCraftable(recipes['minecraft:brick:0'], 512))
|
||||
for key, item in pairs(list) do
|
||||
debug(item.name .. ' : ' .. item.ocount .. ':' .. item.count)
|
||||
end
|
||||
read()
|
||||
]]
|
||||
|
||||
for key, item in pairs(Util.shallowCopy(list)) do
|
||||
local recipe = recipes[key]
|
||||
item.count = math.ceil(item.count / recipe.count)
|
||||
item.ocount = item.count
|
||||
if recipe then
|
||||
item.count = getCraftable(recipe, item.count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function craftItems(craftList)
|
||||
expandList(craftList)
|
||||
jobListGrid:update()
|
||||
jobListGrid:draw()
|
||||
jobListGrid:sync()
|
||||
for key, item in pairs(craftList) do
|
||||
local recipe = recipes[key]
|
||||
if recipe then
|
||||
@@ -304,9 +383,10 @@ local function jobMonitor()
|
||||
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 },
|
||||
{ heading = 'Qty', key = 'ocount', width = 6 },
|
||||
{ heading = 'Qty', key = 'count', width = 6 },
|
||||
{ heading = 'Crafting', key = 'displayName', width = (mon.width - 18) / 2 },
|
||||
{ heading = 'Status', key = 'status', },
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ local UID = 0
|
||||
local multishell = { }
|
||||
local processes = { }
|
||||
local parentTerm = term.current()
|
||||
local sessionFile = args[1] or syntax()
|
||||
local sessionFile = args[1] or 'config/mwm'
|
||||
local running
|
||||
local monitor
|
||||
|
||||
|
||||
287
apps/shapes.lua
287
apps/shapes.lua
@@ -1,284 +1,47 @@
|
||||
requireInjector(getfenv(1))
|
||||
_G.requireInjector()
|
||||
|
||||
local GPS = require('gps')
|
||||
local Socket = require('socket')
|
||||
local UI = require('ui')
|
||||
local Util = require('util')
|
||||
|
||||
local multishell = _ENV.multishell
|
||||
local textutils = _G.textutils
|
||||
|
||||
multishell.setTitle(multishell.getCurrent(), 'Shapes')
|
||||
|
||||
local args = { ... }
|
||||
local turtleId = args[1] or error('Supply turtle ID')
|
||||
turtleId = tonumber(turtleId)
|
||||
|
||||
local script = [[
|
||||
|
||||
requireInjector(getfenv(1))
|
||||
|
||||
local GPS = require('gps')
|
||||
local ChestAdapter = require('chestAdapter18')
|
||||
local Point = require('point')
|
||||
local Util = require('util')
|
||||
|
||||
local itemAdapter
|
||||
|
||||
function dumpInventory()
|
||||
|
||||
for i = 1, 16 do
|
||||
local qty = turtle.getItemCount(i)
|
||||
if qty > 0 then
|
||||
itemAdapter:insert(i, qty)
|
||||
end
|
||||
if turtle.getItemCount(i) ~= 0 then
|
||||
print('Adapter is full or missing - make space or replace')
|
||||
print('Press enter to continue')
|
||||
read()
|
||||
end
|
||||
end
|
||||
turtle.select(1)
|
||||
end
|
||||
|
||||
local function refuel()
|
||||
while turtle.getFuelLevel() < 4000 do
|
||||
print('Refueling')
|
||||
turtle.select(1)
|
||||
|
||||
itemAdapter:provide({ name = 'minecraft:coal', damage = 0 }, 64, 1)
|
||||
if turtle.getItemCount(1) == 0 then
|
||||
print('Out of fuel, add fuel to chest/ME system')
|
||||
turtle.setStatus('waiting')
|
||||
os.sleep(5)
|
||||
else
|
||||
turtle.refuel(64)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function goto(pt)
|
||||
while not turtle.gotoPoint(pt) do
|
||||
print('stuck')
|
||||
os.sleep(5)
|
||||
end
|
||||
end
|
||||
|
||||
local function pathTo(pt)
|
||||
while not turtle.pathfind(pt) do
|
||||
print('stuck')
|
||||
os.sleep(5)
|
||||
end
|
||||
end
|
||||
|
||||
local function resupply()
|
||||
|
||||
if data.suppliesPt then
|
||||
pathTo(data.suppliesPt)
|
||||
|
||||
itemAdapter = ChestAdapter({ direction = 'up', wrapSide = 'bottom' })
|
||||
dumpInventory()
|
||||
refuel()
|
||||
end
|
||||
end
|
||||
|
||||
local function makePlane(y)
|
||||
local pt = { x = math.min(data.startPt.x, data.endPt.x),
|
||||
ex = math.max(data.startPt.x, data.endPt.x),
|
||||
z = math.min(data.startPt.z, data.endPt.z),
|
||||
ez = math.max(data.startPt.z, data.endPt.z) }
|
||||
|
||||
local blocks = { }
|
||||
for z = pt.z, pt.ez do
|
||||
for x = pt.x, pt.ex do
|
||||
table.insert(blocks, { x = x, y = y, z = z })
|
||||
end
|
||||
end
|
||||
|
||||
return blocks
|
||||
end
|
||||
|
||||
local function optimizeRoute(plane, ptb)
|
||||
|
||||
local maxDistance = 99999999
|
||||
|
||||
local function getNearestNeighbor(p, pt, threshold)
|
||||
local key, block, heading
|
||||
local moves = maxDistance
|
||||
|
||||
local function getMoves(b, k)
|
||||
local distance = math.abs(pt.x - b.x) + math.abs(pt.z - b.z)
|
||||
|
||||
if distance < moves then
|
||||
-- this operation is expensive - only run if distance is close
|
||||
local c, h = Point.calculateMoves(pt, b, distance)
|
||||
if c < moves then
|
||||
block = b
|
||||
key = k
|
||||
moves = c
|
||||
heading = h
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function blockReady(b)
|
||||
return not b.u
|
||||
end
|
||||
|
||||
local mid = pt.index
|
||||
local forward = mid + 1
|
||||
local backward = mid - 1
|
||||
while forward <= #p or backward > 0 do
|
||||
if forward <= #p then
|
||||
local b = p[forward]
|
||||
if blockReady(b) then
|
||||
getMoves(b, forward)
|
||||
if moves <= threshold then
|
||||
break
|
||||
end
|
||||
if moves < maxDistance and math.abs(b.z - pt.z) > moves and pt.index > 0 then
|
||||
forward = #p
|
||||
end
|
||||
end
|
||||
forward = forward + 1
|
||||
end
|
||||
if backward > 0 then
|
||||
local b = p[backward]
|
||||
if blockReady(b) then
|
||||
getMoves(b, backward)
|
||||
if moves <= threshold then
|
||||
break
|
||||
end
|
||||
if moves < maxDistance and math.abs(pt.z - b.z) > moves then
|
||||
backward = 0
|
||||
end
|
||||
end
|
||||
backward = backward - 1
|
||||
end
|
||||
end
|
||||
pt.x = block.x
|
||||
pt.z = block.z
|
||||
pt.y = block.y
|
||||
pt.heading = heading
|
||||
pt.index = key
|
||||
block.u = true
|
||||
return block
|
||||
end
|
||||
|
||||
local throttle = Util.throttle()
|
||||
local t = { }
|
||||
ptb.index = 0
|
||||
local threshold = 0
|
||||
for i = 1, #plane do
|
||||
local b = getNearestNeighbor(plane, ptb, threshold)
|
||||
table.insert(t, b)
|
||||
throttle()
|
||||
threshold = 1
|
||||
end
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
local function clear()
|
||||
|
||||
local pt = Util.shallowCopy(data.startPt)
|
||||
pt.y = math.min(data.startPt.y, data.endPt.y)
|
||||
pt.heading = 0
|
||||
|
||||
local osy = pt.y
|
||||
local sy = osy + 1
|
||||
local ey = math.max(data.startPt.y, data.endPt.y)
|
||||
local firstPlane = true
|
||||
|
||||
resupply()
|
||||
|
||||
while true do
|
||||
|
||||
if sy > ey then
|
||||
sy = ey
|
||||
end
|
||||
|
||||
local plane = makePlane(sy)
|
||||
plane = optimizeRoute(plane, pt)
|
||||
|
||||
if firstPlane then
|
||||
turtle.pathfind(plane[1])
|
||||
turtle.setPolicy(turtle.policies.digAttack)
|
||||
firstPlane = false
|
||||
end
|
||||
|
||||
for _,b in ipairs(plane) do
|
||||
turtle.gotoPoint(b)
|
||||
if sy < ey then
|
||||
turtle.digUp()
|
||||
end
|
||||
if sy > osy then
|
||||
turtle.digDown()
|
||||
end
|
||||
if turtle.isAborted() then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if turtle.isAborted() then
|
||||
break
|
||||
end
|
||||
if sy + 1 >= ey then
|
||||
break
|
||||
end
|
||||
|
||||
sy = sy + 3
|
||||
end
|
||||
turtle.setPolicy(turtle.policies.none)
|
||||
resupply()
|
||||
end
|
||||
|
||||
turtle.run(function()
|
||||
turtle.setStatus('Clearing')
|
||||
|
||||
if turtle.enableGPS() then
|
||||
|
||||
local pt = Util.shallowCopy(turtle.point)
|
||||
local s, m = pcall(clear)
|
||||
pathTo(pt)
|
||||
|
||||
if not s and m then
|
||||
error(m)
|
||||
read()
|
||||
end
|
||||
end
|
||||
end)
|
||||
]]
|
||||
|
||||
local levelScript = [[
|
||||
requireInjector(getfenv(1))
|
||||
|
||||
requireInjector(getfenv(1))
|
||||
local Util = require('util')
|
||||
|
||||
local Util = require('util')
|
||||
local s, m = turtle.run(function()
|
||||
turtle.addFeatures('level')
|
||||
turtle.setStatus('Leveling')
|
||||
|
||||
local s, m = turtle.run(function()
|
||||
if turtle.enableGPS() then
|
||||
local pt = Util.shallowCopy(turtle.point)
|
||||
local s, m = pcall(function()
|
||||
turtle.level(data.startPt, data.endPt, data.firstPt)
|
||||
end)
|
||||
|
||||
turtle.addFeatures('level')
|
||||
turtle.setStatus('Leveling')
|
||||
turtle.pathfind(pt)
|
||||
|
||||
if turtle.enableGPS() then
|
||||
|
||||
local pt = Util.shallowCopy(turtle.point)
|
||||
local s, m = pcall(function()
|
||||
turtle.level(data.startPt, data.endPt, data.firstPt)
|
||||
end)
|
||||
|
||||
turtle.pathfind(pt)
|
||||
|
||||
if not s and m then
|
||||
error(m)
|
||||
if not s and m then
|
||||
error(m)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if not s then
|
||||
error(m)
|
||||
end
|
||||
end)
|
||||
|
||||
if not s then
|
||||
error(m)
|
||||
end
|
||||
]]
|
||||
|
||||
|
||||
local data = Util.readTable('/usr/config/shapes') or { }
|
||||
|
||||
local page = UI.Page {
|
||||
@@ -296,7 +59,6 @@ local page = UI.Page {
|
||||
}
|
||||
|
||||
function page.info:draw()
|
||||
|
||||
local function size(a, b)
|
||||
return (math.abs(a.x - b.x) + 1) *
|
||||
(math.abs(a.y - b.y) + 1) *
|
||||
@@ -322,13 +84,12 @@ function page:getPoint()
|
||||
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
|
||||
self.notification:error('Error in script')
|
||||
-- debug(msg)
|
||||
debug(msg)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -389,6 +150,4 @@ function page:eventHandler(event)
|
||||
end
|
||||
|
||||
UI:setPage(page)
|
||||
|
||||
UI:pullEvents()
|
||||
UI.term:reset()
|
||||
|
||||
@@ -268,7 +268,7 @@ local function getCobblestone(count)
|
||||
|
||||
until turtle.getItemCount(COBBLESTONE) >= count
|
||||
|
||||
turtle.gotoPoint(pt)
|
||||
turtle._goto(pt)
|
||||
turtle.placeDown(DIRT)
|
||||
|
||||
turtle.drop(DIRT)
|
||||
|
||||
Reference in New Issue
Block a user