425 lines
10 KiB
Lua
Raw Permalink Normal View History

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()
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()
2023-05-28 14:07:39 +02:00
end
-- helper functions for movement
function forward()
xRelPos = xRelPos + facing.x
yRelPos = yRelPos + facing.y
writeState()
2023-05-28 14:07:39 +02:00
if turtle.forward() then
return true
2023-05-28 14:07:39 +02:00
end
xRelPos = xRelPos - facing.x
yRelPos = yRelPos - facing.y
writeState()
turtle.dig()
turtle.attack()
return false
2023-05-28 14:07:39 +02:00
end
2023-05-29 02:39:58 +02:00
function upwards()
zRelPos = zRelPos + 1
writeState()
2023-05-29 02:39:58 +02:00
if turtle.up() then
return true
end
zRelPos = zRelPos - 1
writeState()
turtle.digUp()
turtle.attackUp()
2023-05-29 02:39:58 +02:00
return false
end
function downwards()
zRelPos = zRelPos - 1
writeState()
2023-05-29 02:39:58 +02:00
if turtle.down() then
return true
end
zRelPos = zRelPos + 1
writeState()
turtle.digDown()
turtle.attackDown()
2023-05-29 02:39:58 +02:00
return false
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
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
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
-- 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()
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
-- 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
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()
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
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
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
2023-05-28 14:07:39 +02:00
function returnItems()
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)
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
2023-05-28 14:07:39 +02:00
end
-- 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()
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
setupResume()
readState()
2023-05-28 14:07:39 +02:00
while true do
moveToNext()
digHole()
print("Returning to chest")
2023-05-28 14:07:39 +02:00
returnItems()
end