425 lines
10 KiB
Lua
425 lines
10 KiB
Lua
maxCompareSlot = 0 -- all slots up to this one are used for comparing, initialized in initCompareSlots
|
|
currentCompareSlot = 1 -- current compare slot (does not have to be saved)
|
|
|
|
startupWait = 5 -- time in seconds to wait after reading state before resuming
|
|
|
|
xRelPos = 0 -- "positive = forward"
|
|
yRelPos = 0 -- "positive = right"
|
|
zRelPos = 0 -- "positive = upwards"
|
|
|
|
facing = {
|
|
x = 1,
|
|
y = 0
|
|
}
|
|
|
|
holeCounter = {
|
|
line = 0,
|
|
hole = 0
|
|
}
|
|
|
|
function printPos()
|
|
print("At (", xRelPos, ", ", yRelPos, ", ", zRelPos, ") facing (", facing.x, ", ", facing.y, ")")
|
|
end
|
|
|
|
function startupTimer()
|
|
print("Waiting ", startupWait, "s before starting... ")
|
|
sleep(startupWait)
|
|
print("Starting!")
|
|
end
|
|
|
|
function setupResume()
|
|
if fs.exists("startup") then
|
|
return
|
|
end
|
|
local file = fs.open("startup", "w") --Startup File
|
|
file.writeLine( --The below is on the left because spacing
|
|
[[
|
|
print("Resuming Miner")
|
|
local event
|
|
if fs.exists("state") then
|
|
os.run({},"]]..shell.getRunningProgram()..[[")
|
|
else
|
|
print("Never mind, no save file found")
|
|
fs.delete("startup")
|
|
end
|
|
]])
|
|
file.close()
|
|
end
|
|
|
|
-- get all lines from a file, returns an empty
|
|
-- list/table if the file does not exist
|
|
function lines_from(file)
|
|
local lines = {}
|
|
for line in io.lines(file) do
|
|
lines[#lines + 1] = line
|
|
end
|
|
return lines
|
|
end
|
|
|
|
function readState()
|
|
if not fs.exists("state") then
|
|
initCompareSlots()
|
|
return
|
|
end
|
|
print("Reading state after restart")
|
|
local file = fs.open("state", "r")
|
|
|
|
xRelPos = tonumber(file.readLine())
|
|
yRelPos = tonumber(file.readLine())
|
|
zRelPos = tonumber(file.readLine())
|
|
facing.x = tonumber(file.readLine())
|
|
facing.y = tonumber(file.readLine())
|
|
holeCounter.line = tonumber(file.readLine())
|
|
holeCounter.hole = tonumber(file.readLine())
|
|
maxCompareSlot = tonumber(file.readLine())
|
|
|
|
file.close()
|
|
print("Read state:")
|
|
printPos()
|
|
|
|
startupTimer()
|
|
end
|
|
|
|
function writeState()
|
|
if fs.exists("state") then
|
|
fs.delete("state")
|
|
end
|
|
file = fs.open("state", "w")
|
|
|
|
file.writeLine(tostring(xRelPos))
|
|
file.writeLine(tostring(yRelPos))
|
|
file.writeLine(tostring(zRelPos))
|
|
file.writeLine(tostring(facing.x))
|
|
file.writeLine(tostring(facing.y))
|
|
file.writeLine(tostring(holeCounter.line))
|
|
file.writeLine(tostring(holeCounter.hole))
|
|
file.writeLine(tostring(maxCompareSlot))
|
|
|
|
file.close()
|
|
end
|
|
|
|
-- helper functions for movement
|
|
function forward()
|
|
xRelPos = xRelPos + facing.x
|
|
yRelPos = yRelPos + facing.y
|
|
writeState()
|
|
|
|
if turtle.forward() then
|
|
return true
|
|
end
|
|
|
|
xRelPos = xRelPos - facing.x
|
|
yRelPos = yRelPos - facing.y
|
|
writeState()
|
|
|
|
turtle.dig()
|
|
turtle.attack()
|
|
return false
|
|
end
|
|
|
|
function upwards()
|
|
zRelPos = zRelPos + 1
|
|
writeState()
|
|
if turtle.up() then
|
|
return true
|
|
end
|
|
zRelPos = zRelPos - 1
|
|
writeState()
|
|
turtle.digUp()
|
|
turtle.attackUp()
|
|
return false
|
|
end
|
|
|
|
function downwards()
|
|
zRelPos = zRelPos - 1
|
|
writeState()
|
|
if turtle.down() then
|
|
return true
|
|
end
|
|
zRelPos = zRelPos + 1
|
|
writeState()
|
|
turtle.digDown()
|
|
turtle.attackDown()
|
|
return false
|
|
end
|
|
|
|
function turnRight()
|
|
if facing.x == 1 and facing.y == 0 then -- facing forward
|
|
facing.x = 0
|
|
facing.y = 1
|
|
elseif facing.x == 0 and facing.y == 1 then -- facing right
|
|
facing.x = -1
|
|
facing.y = 0
|
|
elseif facing.x == -1 and facing.y == 0 then -- facing backward
|
|
facing.x = 0
|
|
facing.y = -1
|
|
elseif facing.x == 0 and facing.y == -1 then -- facing left
|
|
facing.x = 1
|
|
facing.y = 0
|
|
else
|
|
print("turnRight: This should never happen")
|
|
end
|
|
writeState()
|
|
turtle.turnRight()
|
|
end
|
|
|
|
function turnLeft()
|
|
if facing.x == 1 and facing.y == 0 then -- facing forward
|
|
facing.x = 0
|
|
facing.y = -1
|
|
elseif facing.x == 0 and facing.y == 1 then -- facing right
|
|
facing.x = 1
|
|
facing.y = 0
|
|
elseif facing.x == -1 and facing.y == 0 then -- facing backward
|
|
facing.x = 0
|
|
facing.y = 1
|
|
elseif facing.x == 0 and facing.y == -1 then -- facing left
|
|
facing.x = -1
|
|
facing.y = 0
|
|
else
|
|
print("turnLeft: This should never happen")
|
|
end
|
|
writeState()
|
|
turtle.turnLeft()
|
|
end
|
|
|
|
function faceTo(x, y)
|
|
if (x == facing.x) and (y == facing.y) then
|
|
return
|
|
end
|
|
if (x == 1 and facing.x == -1) or (x == -1 and facing.x == 1) or (y == 1 and facing.y == -1) or (y == -1 and facing.y == 1) then
|
|
turnRight()
|
|
turnRight()
|
|
elseif (facing.y == -1 and x == 1) or (facing.y == 1 and x == -1) or (facing.x == 1 and y == 1) or (facing.x == -1 and y == -1) then
|
|
turnRight()
|
|
elseif (facing.y == -1 and x == -1) or (facing.y == 1 and x == 1) or (facing.x == 1 and y == -1) or (facing.x == -1 and y == 1) then
|
|
turnLeft()
|
|
else
|
|
print("faceTo: This should never happen")
|
|
end
|
|
end
|
|
|
|
function moveTo(x, y)
|
|
if (yRelPos > y) then
|
|
faceTo(0, -1)
|
|
while yRelPos > y do
|
|
forward()
|
|
end
|
|
elseif (yRelPos < y) then
|
|
faceTo(0, 1)
|
|
while yRelPos < y do
|
|
forward()
|
|
end
|
|
end
|
|
|
|
if (xRelPos > x) then
|
|
faceTo(-1, 0)
|
|
while xRelPos > x do
|
|
forward()
|
|
end
|
|
elseif (xRelPos < x) then
|
|
faceTo(1, 0)
|
|
while xRelPos < x do
|
|
forward()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- should only be called once when manually starting, not when restarting
|
|
function initCompareSlots()
|
|
print("Setting up compare slots...")
|
|
|
|
while true do
|
|
if (turtle.getItemCount(maxCompareSlot + 1) == 0) then
|
|
break
|
|
end
|
|
maxCompareSlot = maxCompareSlot + 1
|
|
end
|
|
|
|
print("Found ", maxCompareSlot, " compare slots!")
|
|
end
|
|
|
|
-- checks slots 1..maxCompareSlot against currently looked at block
|
|
-- make sure that the selected slot == currentCompareSlot at all times
|
|
function blockIsWorth()
|
|
if (maxCompareSlot <= 0) then
|
|
-- special case
|
|
return true
|
|
end
|
|
|
|
lastCompareSlot = currentCompareSlot
|
|
while true do
|
|
if turtle.compare() then
|
|
return false
|
|
end
|
|
|
|
-- cycle currentCompareSlot, fmod would work perfectly if indices started at 0 -_-
|
|
nextCompareSlot = currentCompareSlot + 1
|
|
if nextCompareSlot > maxCompareSlot then
|
|
nextCompareSlot = 1
|
|
end
|
|
|
|
if (nextCompareSlot == lastCompareSlot) then
|
|
break
|
|
end
|
|
|
|
currentCompareSlot = nextCompareSlot
|
|
turtle.select(currentCompareSlot)
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
function checkForItems()
|
|
dir = math.fmod(zRelPos, 2)
|
|
|
|
-- alternatingly check relative facing (left, forward, right) and (right, forward, left) blocks, so at the end we can face backwards when going up and check without turning at all
|
|
-- -> two turns per mined level
|
|
if (dir == 0) then
|
|
faceTo(0, -1) -- just to be safe, but this should never really do anything except for the first level
|
|
if blockIsWorth() then
|
|
turtle.dig()
|
|
end
|
|
turnRight()
|
|
if blockIsWorth() then
|
|
turtle.dig()
|
|
end
|
|
turnRight()
|
|
if blockIsWorth() then
|
|
turtle.dig()
|
|
end
|
|
else
|
|
faceTo(0, 1)
|
|
if blockIsWorth() then
|
|
turtle.dig()
|
|
end
|
|
turnLeft()
|
|
if blockIsWorth() then
|
|
turtle.dig()
|
|
end
|
|
turnLeft()
|
|
if blockIsWorth() then
|
|
turtle.dig()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Digs straight down right where it is, taking resources with it
|
|
function digHole()
|
|
print("Digging Hole (", holeCounter.line, ", ", holeCounter.hole, ")")
|
|
|
|
-- go down
|
|
turtle.digDown()
|
|
while downwards() do
|
|
checkForItems()
|
|
turtle.digDown()
|
|
end
|
|
|
|
-- go back up
|
|
-- look at the remaining direction (-1, 0) and check blocks
|
|
faceTo(-1, 0)
|
|
while zRelPos < 0 do
|
|
if blockIsWorth() then
|
|
turtle.dig()
|
|
end
|
|
upwards()
|
|
end
|
|
end
|
|
|
|
function shouldReturnItems()
|
|
if turtle.getItemCount(11) == 0 then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- moves to the chest and deposits items, but only when deemed necessary by shouldReturnItems
|
|
function returnItems()
|
|
if not shouldReturnItems() then
|
|
return
|
|
end
|
|
|
|
-- chest coordinates are -1, 0, so go to 0, 0 facing "backwards"
|
|
moveTo(0, 0)
|
|
|
|
faceTo(-1, 0)
|
|
|
|
local droppedAll = true
|
|
|
|
while true do
|
|
droppedAll = true
|
|
-- already facing right direction, put items
|
|
for slot = 1, maxCompareSlot do
|
|
-- put away compare slots' items except one
|
|
turtle.select(slot)
|
|
turtle.drop(turtle.getItemCount(slot) - 1)
|
|
if (turtle.getItemCount(slot) ~= 1) then
|
|
droppedAll = false
|
|
end
|
|
end
|
|
for slot = maxCompareSlot + 1, 16 do
|
|
-- then drop everything else
|
|
turtle.select(slot)
|
|
turtle.drop()
|
|
if (turtle.getItemCount(slot) ~= 0) then
|
|
droppedAll = false
|
|
end
|
|
end
|
|
if (droppedAll) then
|
|
break
|
|
end
|
|
end
|
|
|
|
-- necessary so the next mined block doesn't go in random places
|
|
turtle.select(currentCompareSlot)
|
|
end
|
|
|
|
function moveToNext()
|
|
if not (zRelPos == 0) then
|
|
return -- we're resuming, don't move, don't increase hole
|
|
end
|
|
|
|
print("Moving to the next hole")
|
|
|
|
xPos = 1
|
|
yPos = 1
|
|
|
|
-- find out where the next hole should be
|
|
for i = 1, holeCounter.line do
|
|
if math.fmod(i, 2) == 0 then
|
|
xPos = xPos + 2
|
|
yPos = 1
|
|
else
|
|
xPos = xPos + 3
|
|
yPos = 0
|
|
end
|
|
end
|
|
|
|
for i = 1, holeCounter.hole do
|
|
xPos = xPos - 1
|
|
yPos = yPos + 2
|
|
end
|
|
|
|
moveTo(xPos, yPos)
|
|
|
|
-- update holeCounter
|
|
-- if the xPos we calculated is 1 that means we need to start the next line
|
|
if xPos == 0 then
|
|
holeCounter.line = holeCounter.line + 1
|
|
holeCounter.hole = 0
|
|
else
|
|
holeCounter.hole = holeCounter.hole + 1
|
|
end
|
|
|
|
end
|
|
|
|
setupResume()
|
|
readState()
|
|
|
|
while true do
|
|
moveToNext()
|
|
digHole()
|
|
print("Returning to chest")
|
|
returnItems()
|
|
end
|