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