turtles/dominic/canemine.lua
2020-07-05 12:56:24 +02:00

356 lines
9.4 KiB
Lua

args = {...}
function noop() end
function pair(x, y)
return math.floor((x + y) * (x + y + 1)/2 + y)
end
function unpairX(z)
local j = math.floor(math.sqrt(0.25 + 2*z) - 0.5)
return j - (z - j*(j+1)/2)
end
function unpairZ(z)
local j = math.floor(math.sqrt(0.25 + 2*z) - 0.5)
return z - j * (j+1)/2;
end
lookup = {4, 1, 3, 0, 2}
local function isDiggingSpot(x, y)
local val = lookup[(y % 5) + 1]
return (x % 5) == val
end
offset = 10
function ithSpot(i)
j = offset
while true do
x, z = unpairX(j), unpairZ(j)
if isDiggingSpot(x, z) then
if i <= 1 then
return x, z
else
i = i - 1
end
end
j = j + 1
end
end
-- move safely into the direction, not hurting other turtles, but freeing the path if needed.
function moveSafe(moveAction, inspectAction, digAction)
while true do
local status, block = inspectAction()
if status then
if block["name"]:lower():find("turtle") then
-- turtle in front of me. lets wait for it to move
sleep(0.6)
else
digAction()
end
else
-- nothing in the way, try to move
if moveAction() then
break
end
end
end
end
-- If the block in front of the turtle is desired, take it.
function grabOres()
local status, block = turtle.inspect()
if status and block["name"]:lower():find("ore") then
turtle.dig()
end
end
-- dig all the way down to bedrock, collect ores
-- Parameters:
-- * moveAction: the **vertical** move action, eg turtle.down
-- * digAction: the **vertical** dig action, eg turtle.digDown
-- * inpectAction: the **vertical** inspect action, eg turtle.inspectDown
-- * limit: if >= 0 * the number of blocks to dig
-- * dig until bedrock is hit
--
--
-- Returns: the depth dug
function digDeep(moveAction, digAction, inspectAction, limit)
local depth = 0
grabOres()
while true do
-- termination condition:
-- * if limit != -1: limit > 0
-- * otherwise : bedrock beneath
if limit < 0 then
local status, nextblock = inspectAction()
if status and nextblock["name"] == "minecraft:bedrock" then
return depth
end
else
if limit == 0 then
return depth
end
end
-- Limit not reached: keep digging
depth = depth + 1
limit = limit - 1
digAction()
moveAction()
grabOres() -- inspect block in front of turtle, take if neccessary
end
end
function selectCobble()
for i = 1,16 do
turtle.select(i)
item = turtle.getItemDetail()
if item and item["name"] == "minecraft:cobblestone" then
break
end
end
end
function selectFuel()
for i = 1,16 do
turtle.select(i)
item = turtle.getItemDetail()
if item and (item["name"] == "minecraft:coal" or item["name"] == "minecraft:charcoal") then
break
end
end
end
function digShaft()
turtle.digDown()
selectCobble()
turtle.placeUp()
turtle.down()
depth = digDeep(turtle.down, turtle.digDown, turtle.inspectDown, -1)
turtle.turnLeft()
digDeep(turtle.up, noop, noop, depth)
turtle.turnLeft()
digDeep(turtle.down, noop, noop, depth)
turtle.turnLeft()
digDeep(turtle.up, noop, noop, depth)
selectCobble()
turtle.placeDown()
turtle.up()
turtle.digUp()
turtle.up()
end
function digTo(x, z)
print("Digging to rel. coord ("..tostring(x)..", "..tostring(z)..")")
while z > 0 do
moveSafe(turtle.forward, turtle.inspect, turtle.dig)
z = z - 1
repeat sleep(0.6)
until (not turtle.digUp())
end
turtle.turnRight()
while x > 0 do
moveSafe(turtle.forward, turtle.inspect, turtle.dig)
x = x - 1
repeat sleep(0.6)
until (not turtle.digUp())
end
end
function goToSpawn(x, z)
moveSafe(turtle.up, turtle.inspectUp, turtle.digUp)
while z > 0 do
moveSafe(turtle.forward, turtle.inspect, turtle.dig)
z = z - 1
end
turtle.turnRight()
while x > 0 do
moveSafe(turtle.forward, turtle.inspect, turtle.dig)
x = x - 1
end
end
function moveSafeForward()
moveSafe(turtle.forward, turtle.inspect, noop)
end
function goToBarrel(path)
if path == 0 then
turtle.turnLeft()
moveSafe(turtle.forward, turtle.inspect, noop)
turtle.turnRight()
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
turtle.turnRight()
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.down, turtle.inspectDown, noop)
else
moveSafe(turtle.forward, turtle.inspect, noop)
turtle.turnRight()
moveSafe(turtle.forward, turtle.inspect, noop)
turtle.turnLeft()
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.down, turtle.inspectDown, noop)
turtle.turnRight()
end
end
function leaveBarrel(path)
if path == 0 then
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
turtle.turnRight()
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
turtle.turnRight()
else
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
moveSafe(turtle.forward, turtle.inspect, noop)
turtle.turnRight()
moveSafe(turtle.forward, turtle.inspect, noop)
turtle.turnRight()
end
end
function reportDuty(id, fuelconsumed)
moveSafe(turtle.down, turtle.inspectDown, noop)
moveSafe(turtle.down, turtle.inspectDown, noop)
moveSafe(turtle.down, turtle.inspectDown, noop)
moveSafeForward()
moveSafeForward()
moveSafeForward()
moveSafeForward()
moveSafeForward()
moveSafeForward()
moveSafeForward()
moveSafeForward()
rednet.open("bottom")
--print("Proto: Sending completed Job id")
rednet.broadcast(tostring(id), "jobs")
sleep(0.6)
--print("Proto: Sending fuel status")
rednet.broadcast(tostring(fuelconsumed), "fuel")
while true do
--print("Proto: Awaiting thanks")
sender, message, proto = rednet.receive("jobcomplete")
if message == "thanks" then
break
else
sleep(1)
end
end
--print("Proto: Received thanks")
end
function enqueueTurtle()
moveSafe(turtle.up, turtle.inspectUp, noop)
moveSafe(turtle.up, turtle.inspectUp, noop)
moveSafe(turtle.up, turtle.inspectUp, noop)
turtle.turnLeft()
moveSafeForward()
moveSafeForward()
moveSafeForward()
turtle.turnRight()
while true do
local status, block = turtle.inspectDown()
if not status then
if turtle.down() then
break -- we moved in line
end
else
if turtle.forward() then
-- pass, thats ok
else
local status, block = turtle.inspect()
if status and not block["name"]:lower():find("turtle") then
turtle.dig()
turtle.forward()
turtle.digUp()
turtle.digDown()
end
end
end
end
-- we moved into line
turtle.turnLeft()
turtle.turnLeft()
end
function doRefuel()
moveSafeForward()
turtle.turnRight()
while turtle.getFuelLevel() < 1500 do
turtle.suck(4)
selectFuel()
turtle.refuel()
end
turtle.turnLeft()
end
function goToJob()
moveSafeForward()
moveSafeForward()
moveSafeForward()
end
function waitForJob()
print("Waiting for job...")
while true do
status, block = turtle.inspectDown()
if status and block["name"] == "computercraft:wired_modem_full" then
break
else
moveSafeForward()
end
end
rednet.open("bottom")
rednet.broadcast("gibjob", "jobs")
while true do
sender, message, proto = rednet.receive("newjob", 1)
if message then
job = tonumber(message)
print("Received job "..tostring(job))
return job
end
end
end
function emptyToBarrel()
sleep(0.4)
for i = 1,16 do
turtle.select(i)
sleep(0.1)
turtle.dropDown()
end
end
while true do
thejob = waitForJob()
doRefuel()
fuel = turtle.getFuelLevel()
goToJob()
x, z = ithSpot(thejob)
digTo(x,z)
digShaft()
goToSpawn(x, z)
path = math.floor(math.random() + 0.5)
goToBarrel(path)
emptyToBarrel()
leaveBarrel(path)
fuelconsumed = fuel - turtle.getFuelLevel()
print("I consumed "..tostring(fuelconsumed).." fuel")
print("Reporting Duty")
reportDuty(thejob, fuelconsumed)
enqueueTurtle()
end