api cleanup

This commit is contained in:
kepler155c
2017-11-15 00:09:29 -05:00
parent 2526308eb6
commit f6fb6a4433
12 changed files with 263 additions and 368 deletions

View File

@@ -440,7 +440,7 @@ function TurtleBuilder:inAirDropoff()
self:log('Received supply location')
os.sleep(0)
turtle._goto(pt.x, pt.z, pt.y)
turtle._goto(pt)
os.sleep(.1) -- random computer is not connected error
local chestAdapter = Adapter.wrap({ direction = 'down', wrapSide = 'top' })
@@ -502,7 +502,7 @@ function TurtleBuilder:inAirResupply()
self:log('Received supply location')
os.sleep(0)
turtle._goto(pt.x, pt.z, pt.y)
turtle._goto(pt)
os.sleep(.1) -- random computer is not connected error
local chestAdapter = Adapter.wrap({ direction = 'down', wrapSide = 'top' })
@@ -553,12 +553,11 @@ function TurtleBuilder:sendSupplyRequest(lastBlock)
if device.wireless_modem then
local slots = self:getAirResupplyList(lastBlock)
self.slotUid = os.clock()
Message.broadcast('supplyList', { uid = self.slotUid, slots = slots })
end
end
local function closestEdgePoint(pt, pts, rpt)
local function closestEdgePoint(pt, pts, rpt, y)
pt = Point.copy(pt)
pt.heading = rpt.heading
@@ -583,16 +582,18 @@ local function closestEdgePoint(pt, pts, rpt)
cpt.z = rpt.z
end
cpt.y = y
return cpt
end
function TurtleBuilder:getBuildingCorner(y)
local box = {
x = -1, ex = self.schematic.width,
y = y, ey = y,
z = -1, ez = self.schematic.length,
local pts = {
{ x = -1, z = -1, y = 0 },
{ x = -1, z = self.schematic.length, y = 0 },
{ x = self.schematic.width, z = -1, y = 0 },
{ x = self.schematic.width, z = self.schematic.length, y = 0 },
}
return Point.closestPointInBox(turtle.getPoint(), box)
return closestEdgePoint(self.supplyPoint, pts, turtle.getPoint(), y)
end
function TurtleBuilder:gotoSupplyPoint()
@@ -601,7 +602,7 @@ function TurtleBuilder:gotoSupplyPoint()
-- go to the corner closest to the supplies point
-- pathfind the rest of the way
local pt = self:getBuildingCorner(turtle.point.y)
turtle._goto(pt.x, pt.z)
turtle._goto({ x = pt.x, z = pt.z })
turtle.setPolicy('none')
turtle.pathfind(self.supplyPoint)
os.sleep(.1) -- random 'Computer is not connected' error...
@@ -809,7 +810,7 @@ function TurtleBuilder:placePiston(b)
end
function TurtleBuilder:_goto(x, z, y, heading)
if not turtle._goto(x, z, y, heading) then
if not turtle._goto({ x = x, z = z, y = y, heading = heading }) then
print('stuck')
print('Press enter to continue')
os.sleep(1)

42
apis/turtle/home.lua Normal file
View File

@@ -0,0 +1,42 @@
local Config = require('config')
local GPS = require('gps')
local turtle = _G.turtle
local Home = { }
function Home.go()
local config = { }
Config.load('gps', config)
if config.home then
if turtle.enableGPS() then
return turtle.pathfind(config.home)
end
end
end
function Home.set()
local config = { }
Config.load('gps', config)
local pt = GPS.getPoint()
if pt then
local originalHeading = turtle.point.heading
local heading = GPS.getHeading()
if heading then
local turns = (turtle.point.heading - originalHeading) % 4
pt.heading = (heading - turns) % 4
config.home = pt
Config.update('gps', config)
pt = GPS.getPoint()
pt.heading = heading
turtle.setPoint(pt, true)
turtle._goto(config.home)
return config.home
end
end
end
return Home

View File

@@ -158,7 +158,7 @@ function turtle.level(startPt, endPt, firstPt, verbose)
local node = closestPoint(turtle.point, nodes)
node = getAdjacentPoint(node)
if not turtle.gotoPoint(node) then
if not turtle._goto(node) then
break
end
until turtle.isAborted()

View File

@@ -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', },
},
})

View File

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

View File

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

View File

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

View File

@@ -412,6 +412,17 @@
[ 6 ] = "minecraft:iron_ingot:0",
},
},
[ "minecraft:brick_stairs:0" ] = {
count = 4,
ingredients = {
"minecraft:brick_block:0",
[ 9 ] = "minecraft:brick_block:0",
[ 10 ] = "minecraft:brick_block:0",
[ 11 ] = "minecraft:brick_block:0",
[ 5 ] = "minecraft:brick_block:0",
[ 6 ] = "minecraft:brick_block:0",
},
},
[ "minecraft:iron_block:0" ] = {
count = 1,
ingredients = {
@@ -514,20 +525,6 @@
[ 6 ] = "minecraft:planks:2",
},
},
[ "minecraft:gold_block:0" ] = {
count = 63,
ingredients = {
"minecraft:gold_block:0",
"minecraft:gold_block:0",
"minecraft:gold_block:0",
[ 9 ] = "minecraft:gold_block:0",
[ 10 ] = "minecraft:gold_block:0",
[ 11 ] = "minecraft:gold_block:0",
[ 5 ] = "minecraft:gold_block:0",
[ 6 ] = "minecraft:gold_block:0",
[ 7 ] = "minecraft:gold_block:0",
},
},
[ "minecraft:carpet:10" ] = {
count = 3,
ingredients = {
@@ -535,13 +532,6 @@
[ 6 ] = "minecraft:wool:10",
},
},
[ "minecraft:stone:5" ] = {
count = 2,
ingredients = {
"minecraft:stone:3",
"minecraft:cobblestone:0",
},
},
[ "minecraft:jungle_fence_gate:0" ] = {
count = 1,
ingredients = {
@@ -553,6 +543,24 @@
[ 7 ] = "minecraft:stick:0",
},
},
[ "minecraft:stone:5" ] = {
count = 2,
ingredients = {
"minecraft:stone:3",
"minecraft:cobblestone:0",
},
},
[ "minecraft:oak_stairs:0" ] = {
count = 8,
ingredients = {
"minecraft:planks:0",
[ 9 ] = "minecraft:planks:0",
[ 10 ] = "minecraft:planks:0",
[ 11 ] = "minecraft:planks:0",
[ 5 ] = "minecraft:planks:0",
[ 6 ] = "minecraft:planks:0",
},
},
[ "minecraft:noteblock:0" ] = {
count = 1,
ingredients = {
@@ -567,15 +575,18 @@
[ 7 ] = "minecraft:planks:0",
},
},
[ "minecraft:oak_stairs:0" ] = {
count = 8,
[ "minecraft:gold_block:0" ] = {
count = 1,
ingredients = {
"minecraft:planks:0",
[ 9 ] = "minecraft:planks:0",
[ 10 ] = "minecraft:planks:0",
[ 11 ] = "minecraft:planks:0",
[ 5 ] = "minecraft:planks:0",
[ 6 ] = "minecraft:planks:0",
"minecraft:gold_ingot:0",
"minecraft:gold_ingot:0",
"minecraft:gold_ingot:0",
[ 5 ] = "minecraft:gold_ingot:0",
[ 6 ] = "minecraft:gold_ingot:0",
[ 7 ] = "minecraft:gold_ingot:0",
[ 9 ] = "minecraft:gold_ingot:0",
[ 10 ] = "minecraft:gold_ingot:0",
[ 11 ] = "minecraft:gold_ingot:0",
},
},
[ "minecraft:chest:0" ] = {
@@ -745,10 +756,12 @@
[ 6 ] = "minecraft:dye:10",
},
},
[ "minecraft:sugar:0" ] = {
count = 1,
[ "minecraft:tripwire_hook:0" ] = {
count = 2,
ingredients = {
[ 6 ] = "minecraft:reeds:0",
"minecraft:iron_ingot:0",
[ 9 ] = "minecraft:planks:0",
[ 5 ] = "minecraft:stick:0",
},
},
[ "minecraft:ladder:0" ] = {
@@ -824,6 +837,12 @@
[ 6 ] = "minecraft:iron_ingot:0",
},
},
[ "minecraft:sugar:0" ] = {
count = 1,
ingredients = {
[ 6 ] = "minecraft:reeds:0",
},
},
[ "minecraft:stained_glass:6" ] = {
count = 8,
ingredients = {
@@ -838,20 +857,6 @@
[ 7 ] = "minecraft:glass:0",
},
},
[ "minecraft:piston:0" ] = {
count = 1,
ingredients = {
"minecraft:planks:0",
"minecraft:planks:0",
"minecraft:planks:0",
[ 9 ] = "minecraft:cobblestone:0",
[ 10 ] = "minecraft:redstone:0",
[ 11 ] = "minecraft:cobblestone:0",
[ 5 ] = "minecraft:cobblestone:0",
[ 6 ] = "minecraft:iron_ingot:0",
[ 7 ] = "minecraft:cobblestone:0",
},
},
[ "minecraft:planks:0" ] = {
count = 4,
ingredients = {
@@ -895,12 +900,18 @@
[ 7 ] = "minecraft:hardened_clay:0",
},
},
[ "minecraft:tripwire_hook:0" ] = {
count = 2,
[ "minecraft:piston:0" ] = {
count = 1,
ingredients = {
"minecraft:iron_ingot:0",
[ 9 ] = "minecraft:planks:0",
[ 5 ] = "minecraft:stick:0",
"minecraft:planks:0",
"minecraft:planks:0",
"minecraft:planks:0",
[ 9 ] = "minecraft:cobblestone:0",
[ 10 ] = "minecraft:redstone:0",
[ 11 ] = "minecraft:cobblestone:0",
[ 5 ] = "minecraft:cobblestone:0",
[ 6 ] = "minecraft:iron_ingot:0",
[ 7 ] = "minecraft:cobblestone:0",
},
},
[ "minecraft:carpet:14" ] = {

View File

@@ -1 +1,2 @@
turtle.run(turtle.gotoGPSHome)
local Home = require('turtle.home')
turtle.run(Home.go)

View File

@@ -67,7 +67,7 @@ local function findObsidian()
end
node = Point.closest(turtle.point, nodes)
if not turtle.gotoPoint(node) then
if not turtle._goto(node) then
break
end
until turtle.isAborted()
@@ -91,7 +91,7 @@ turtle.run(function()
if not turtle.select('minecraft:water_bucket') then
break
end
turtle._goto(0, 0)
turtle._goto({ x = 0, z = 0 })
turtle.placeDown()
os.sleep(2)
turtle.placeDown()
@@ -104,5 +104,5 @@ turtle.run(function()
error(m)
end
turtle._goto(0, 0, 0, 0)
turtle._goto({ x = 0, y = 0, z = 0, heading = 0 })
end)

View File

@@ -1 +1,2 @@
turtle.run(turtle.setGPSHome)
local Home = require('turtle.home')
turtle.run(Home.set)

View File

@@ -32,7 +32,7 @@ local function summon(id)
local function doGPS()
tFixes = { }
for i = 1, 4 do
if not turtle.gotoPoint(pts[i]) then
if not turtle._goto(pts[i]) then
error('turtle: Unable to perform GPS maneuver')
end
local distance = getDistance()