2023-09-30 13:20:05 +02:00
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
2023-05-28 14:07:39 +02:00
xRelPos = 0 -- "positive = forward"
yRelPos = 0 -- "positive = right"
2023-05-29 02:39:58 +02:00
zRelPos = 0 -- "positive = upwards"
2023-05-28 14:07:39 +02:00
facing = {
x = 1 ,
y = 0
}
holeCounter = {
line = 0 ,
hole = 0
}
function printPos ( )
2023-05-30 12:37:52 +02:00
print ( " At ( " , xRelPos , " , " , yRelPos , " , " , zRelPos , " ) facing ( " , facing.x , " , " , facing.y , " ) " )
end
2023-09-30 13:20:05 +02:00
function startupTimer ( )
print ( " Waiting " , startupWait , " s before starting... " )
sleep ( startupWait )
print ( " Starting! " )
end
2023-05-30 12:37:52 +02:00
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 " )
2023-09-30 13:20:05 +02:00
fs.delete ( " startup " )
2023-05-30 12:37:52 +02:00
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
2023-09-30 13:20:05 +02:00
initCompareSlots ( )
2023-05-30 12:37:52 +02:00
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 ( ) )
2023-09-30 13:20:05 +02:00
maxCompareSlot = tonumber ( file.readLine ( ) )
2023-05-30 12:37:52 +02:00
2023-09-30 13:20:05 +02:00
file.close ( )
print ( " Read state: " )
2023-05-30 12:37:52 +02:00
printPos ( )
2023-09-30 13:20:05 +02:00
startupTimer ( )
2023-05-30 12:37:52 +02:00
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 ) )
2023-09-30 13:20:05 +02:00
file.writeLine ( tostring ( maxCompareSlot ) )
2023-05-30 12:37:52 +02:00
file.close ( )
2023-05-28 14:07:39 +02:00
end
-- helper functions for movement
function forward ( )
2023-05-30 12:37:52 +02:00
xRelPos = xRelPos + facing.x
yRelPos = yRelPos + facing.y
writeState ( )
2023-05-28 14:07:39 +02:00
if turtle.forward ( ) then
2023-05-30 12:37:52 +02:00
return true
2023-05-28 14:07:39 +02:00
end
2023-05-30 12:37:52 +02:00
xRelPos = xRelPos - facing.x
yRelPos = yRelPos - facing.y
writeState ( )
turtle.dig ( )
2023-10-07 19:58:32 +02:00
turtle.attack ( )
2023-05-30 12:37:52 +02:00
return false
2023-05-28 14:07:39 +02:00
end
2023-05-29 02:39:58 +02:00
function upwards ( )
2023-05-30 12:37:52 +02:00
zRelPos = zRelPos + 1
writeState ( )
2023-05-29 02:39:58 +02:00
if turtle.up ( ) then
return true
end
2023-05-30 12:37:52 +02:00
zRelPos = zRelPos - 1
writeState ( )
turtle.digUp ( )
2023-10-07 19:58:32 +02:00
turtle.attackUp ( )
2023-05-29 02:39:58 +02:00
return false
end
function downwards ( )
2023-05-30 12:37:52 +02:00
zRelPos = zRelPos - 1
writeState ( )
2023-05-29 02:39:58 +02:00
if turtle.down ( ) then
return true
end
2023-05-30 12:37:52 +02:00
zRelPos = zRelPos + 1
writeState ( )
turtle.digDown ( )
2023-10-07 19:58:32 +02:00
turtle.attackDown ( )
2023-05-29 02:39:58 +02:00
return false
2023-05-30 12:37:52 +02:00
end
2023-05-29 02:39:58 +02:00
2023-05-28 14:07:39 +02:00
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
2023-05-30 12:37:52 +02:00
writeState ( )
turtle.turnRight ( )
2023-05-28 14:07:39 +02:00
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
2023-05-30 12:37:52 +02:00
writeState ( )
turtle.turnLeft ( )
2023-05-28 14:07:39 +02:00
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
2023-09-30 13:20:05 +02:00
-- 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
2023-05-28 14:07:39 +02:00
function blockIsWorth ( )
2023-09-30 13:20:05 +02:00
if ( maxCompareSlot <= 0 ) then
-- special case
return true
end
lastCompareSlot = currentCompareSlot
while true do
2023-05-28 14:07:39 +02:00
if turtle.compare ( ) then
return false
end
2023-09-30 13:20:05 +02:00
-- 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 )
2023-05-28 14:07:39 +02:00
end
2023-05-29 02:39:58 +02:00
return true
2023-05-28 14:07:39 +02:00
end
2023-05-30 12:37:52 +02:00
function checkForItems ( )
dir = math.fmod ( zRelPos , 2 )
2023-05-28 14:07:39 +02:00
-- 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 ( )
2023-05-30 12:37:52 +02:00
print ( " Digging Hole ( " , holeCounter.line , " , " , holeCounter.hole , " ) " )
2023-05-28 14:07:39 +02:00
-- go down
turtle.digDown ( )
2023-05-29 02:39:58 +02:00
while downwards ( ) do
2023-05-30 12:37:52 +02:00
checkForItems ( )
2023-05-28 14:07:39 +02:00
turtle.digDown ( )
end
-- go back up
-- look at the remaining direction (-1, 0) and check blocks
faceTo ( - 1 , 0 )
2023-05-29 02:39:58 +02:00
while zRelPos < 0 do
2023-05-28 14:07:39 +02:00
if blockIsWorth ( ) then
turtle.dig ( )
end
2023-05-29 02:39:58 +02:00
upwards ( )
2023-05-28 14:07:39 +02:00
end
end
2023-05-30 12:37:52 +02:00
function shouldReturnItems ( )
if turtle.getItemCount ( 11 ) == 0 then
return false
end
return true
end
2023-09-30 13:20:05 +02:00
-- moves to the chest and deposits items, but only when deemed necessary by shouldReturnItems
2023-05-28 14:07:39 +02:00
function returnItems ( )
2023-05-30 12:37:52 +02:00
if not shouldReturnItems ( ) then
return
end
2023-05-28 14:07:39 +02:00
-- chest coordinates are -1, 0, so go to 0, 0 facing "backwards"
moveTo ( 0 , 0 )
faceTo ( - 1 , 0 )
2023-09-30 13:54:43 +02:00
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
2023-09-30 13:20:05 +02:00
break
end
2023-05-28 14:07:39 +02:00
end
2023-05-30 12:37:52 +02:00
2023-09-30 13:20:05 +02:00
-- necessary so the next mined block doesn't go in random places
turtle.select ( currentCompareSlot )
2023-05-28 14:07:39 +02:00
end
function moveToNext ( )
2023-05-30 12:37:52 +02:00
if not ( zRelPos == 0 ) then
return -- we're resuming, don't move, don't increase hole
end
print ( " Moving to the next hole " )
2023-05-28 14:07:39 +02:00
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
2023-05-30 12:37:52 +02:00
setupResume ( )
readState ( )
2023-05-28 14:07:39 +02:00
while true do
moveToNext ( )
digHole ( )
2023-05-30 12:37:52 +02:00
print ( " Returning to chest " )
2023-05-28 14:07:39 +02:00
returnItems ( )
end