362 lines
7.9 KiB
Lua
362 lines
7.9 KiB
Lua
-- SPDX-FileCopyrightText: 2017 Daniel Ratcliffe
|
|
--
|
|
-- SPDX-License-Identifier: LicenseRef-CCPL
|
|
|
|
if not turtle then
|
|
printError("Requires a Turtle")
|
|
return
|
|
end
|
|
|
|
local tArgs = { ... }
|
|
if #tArgs ~= 1 then
|
|
local programName = arg[0] or fs.getName(shell.getRunningProgram())
|
|
print("Usage: " .. programName .. " <diameter>")
|
|
return
|
|
end
|
|
|
|
-- Mine in a quarry pattern until we hit something we can't dig
|
|
local size = tonumber(tArgs[1])
|
|
if size < 1 then
|
|
print("Excavate diameter must be positive")
|
|
return
|
|
end
|
|
|
|
local depth = 0
|
|
local unloaded = 0
|
|
local collected = 0
|
|
|
|
local xPos, zPos = 0, 0
|
|
local xDir, zDir = 0, 1
|
|
|
|
local goTo -- Filled in further down
|
|
local refuel -- Filled in further down
|
|
|
|
local function unload(_bKeepOneFuelStack)
|
|
print("Unloading items...")
|
|
for n = 1, 16 do
|
|
local nCount = turtle.getItemCount(n)
|
|
if nCount > 0 then
|
|
turtle.select(n)
|
|
local bDrop = true
|
|
if _bKeepOneFuelStack and turtle.refuel(0) then
|
|
bDrop = false
|
|
_bKeepOneFuelStack = false
|
|
end
|
|
if bDrop then
|
|
turtle.drop()
|
|
unloaded = unloaded + nCount
|
|
end
|
|
end
|
|
end
|
|
collected = 0
|
|
turtle.select(1)
|
|
end
|
|
|
|
local function returnSupplies()
|
|
local x, y, z, xd, zd = xPos, depth, zPos, xDir, zDir
|
|
print("Returning to surface...")
|
|
goTo(0, 0, 0, 0, -1)
|
|
|
|
local fuelNeeded = 2 * (x + y + z) + 1
|
|
if not refuel(fuelNeeded) then
|
|
unload(true)
|
|
print("Waiting for fuel")
|
|
while not refuel(fuelNeeded) do
|
|
os.pullEvent("turtle_inventory")
|
|
end
|
|
else
|
|
unload(true)
|
|
end
|
|
|
|
print("Resuming mining...")
|
|
goTo(x, y, z, xd, zd)
|
|
end
|
|
|
|
local function collect()
|
|
local bFull = true
|
|
local nTotalItems = 0
|
|
for n = 1, 16 do
|
|
local nCount = turtle.getItemCount(n)
|
|
if nCount == 0 then
|
|
bFull = false
|
|
end
|
|
nTotalItems = nTotalItems + nCount
|
|
end
|
|
|
|
if nTotalItems > collected then
|
|
collected = nTotalItems
|
|
if math.fmod(collected + unloaded, 50) == 0 then
|
|
print("Mined " .. collected + unloaded .. " items.")
|
|
end
|
|
end
|
|
|
|
if bFull then
|
|
print("No empty slots left.")
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
function refuel(amount)
|
|
local fuelLevel = turtle.getFuelLevel()
|
|
if fuelLevel == "unlimited" then
|
|
return true
|
|
end
|
|
|
|
local needed = amount or xPos + zPos + depth + 2
|
|
if turtle.getFuelLevel() < needed then
|
|
for n = 1, 16 do
|
|
if turtle.getItemCount(n) > 0 then
|
|
turtle.select(n)
|
|
if turtle.refuel(1) then
|
|
while turtle.getItemCount(n) > 0 and turtle.getFuelLevel() < needed do
|
|
turtle.refuel(1)
|
|
end
|
|
if turtle.getFuelLevel() >= needed then
|
|
turtle.select(1)
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
turtle.select(1)
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local function tryForwards()
|
|
if not refuel() then
|
|
print("Not enough Fuel")
|
|
returnSupplies()
|
|
end
|
|
|
|
while not turtle.forward() do
|
|
if turtle.detect() then
|
|
if turtle.dig() then
|
|
if not collect() then
|
|
returnSupplies()
|
|
end
|
|
else
|
|
return false
|
|
end
|
|
elseif turtle.attack() then
|
|
if not collect() then
|
|
returnSupplies()
|
|
end
|
|
else
|
|
sleep(0.5)
|
|
end
|
|
end
|
|
|
|
xPos = xPos + xDir
|
|
zPos = zPos + zDir
|
|
return true
|
|
end
|
|
|
|
local function tryDown()
|
|
if not refuel() then
|
|
print("Not enough Fuel")
|
|
returnSupplies()
|
|
end
|
|
|
|
while not turtle.down() do
|
|
if turtle.detectDown() then
|
|
if turtle.digDown() then
|
|
if not collect() then
|
|
returnSupplies()
|
|
end
|
|
else
|
|
return false
|
|
end
|
|
elseif turtle.attackDown() then
|
|
if not collect() then
|
|
returnSupplies()
|
|
end
|
|
else
|
|
sleep(0.5)
|
|
end
|
|
end
|
|
|
|
depth = depth + 1
|
|
if math.fmod(depth, 10) == 0 then
|
|
print("Descended " .. depth .. " metres.")
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local function turnLeft()
|
|
turtle.turnLeft()
|
|
xDir, zDir = -zDir, xDir
|
|
end
|
|
|
|
local function turnRight()
|
|
turtle.turnRight()
|
|
xDir, zDir = zDir, -xDir
|
|
end
|
|
|
|
function goTo(x, y, z, xd, zd)
|
|
while depth > y do
|
|
if turtle.up() then
|
|
depth = depth - 1
|
|
elseif turtle.digUp() or turtle.attackUp() then
|
|
collect()
|
|
else
|
|
sleep(0.5)
|
|
end
|
|
end
|
|
|
|
if xPos > x then
|
|
while xDir ~= -1 do
|
|
turnLeft()
|
|
end
|
|
while xPos > x do
|
|
if turtle.forward() then
|
|
xPos = xPos - 1
|
|
elseif turtle.dig() or turtle.attack() then
|
|
collect()
|
|
else
|
|
sleep(0.5)
|
|
end
|
|
end
|
|
elseif xPos < x then
|
|
while xDir ~= 1 do
|
|
turnLeft()
|
|
end
|
|
while xPos < x do
|
|
if turtle.forward() then
|
|
xPos = xPos + 1
|
|
elseif turtle.dig() or turtle.attack() then
|
|
collect()
|
|
else
|
|
sleep(0.5)
|
|
end
|
|
end
|
|
end
|
|
|
|
if zPos > z then
|
|
while zDir ~= -1 do
|
|
turnLeft()
|
|
end
|
|
while zPos > z do
|
|
if turtle.forward() then
|
|
zPos = zPos - 1
|
|
elseif turtle.dig() or turtle.attack() then
|
|
collect()
|
|
else
|
|
sleep(0.5)
|
|
end
|
|
end
|
|
elseif zPos < z then
|
|
while zDir ~= 1 do
|
|
turnLeft()
|
|
end
|
|
while zPos < z do
|
|
if turtle.forward() then
|
|
zPos = zPos + 1
|
|
elseif turtle.dig() or turtle.attack() then
|
|
collect()
|
|
else
|
|
sleep(0.5)
|
|
end
|
|
end
|
|
end
|
|
|
|
while depth < y do
|
|
if turtle.down() then
|
|
depth = depth + 1
|
|
elseif turtle.digDown() or turtle.attackDown() then
|
|
collect()
|
|
else
|
|
sleep(0.5)
|
|
end
|
|
end
|
|
|
|
while zDir ~= zd or xDir ~= xd do
|
|
turnLeft()
|
|
end
|
|
end
|
|
|
|
if not refuel() then
|
|
print("Out of Fuel")
|
|
return
|
|
end
|
|
|
|
print("Excavating...")
|
|
|
|
local reseal = false
|
|
turtle.select(1)
|
|
if turtle.digDown() then
|
|
reseal = true
|
|
end
|
|
|
|
local alternate = 0
|
|
local done = false
|
|
while not done do
|
|
for n = 1, size do
|
|
for _ = 1, size - 1 do
|
|
if not tryForwards() then
|
|
done = true
|
|
break
|
|
end
|
|
end
|
|
if done then
|
|
break
|
|
end
|
|
if n < size then
|
|
if math.fmod(n + alternate, 2) == 0 then
|
|
turnLeft()
|
|
if not tryForwards() then
|
|
done = true
|
|
break
|
|
end
|
|
turnLeft()
|
|
else
|
|
turnRight()
|
|
if not tryForwards() then
|
|
done = true
|
|
break
|
|
end
|
|
turnRight()
|
|
end
|
|
end
|
|
end
|
|
if done then
|
|
break
|
|
end
|
|
|
|
if size > 1 then
|
|
if math.fmod(size, 2) == 0 then
|
|
turnRight()
|
|
else
|
|
if alternate == 0 then
|
|
turnLeft()
|
|
else
|
|
turnRight()
|
|
end
|
|
alternate = 1 - alternate
|
|
end
|
|
end
|
|
|
|
if not tryDown() then
|
|
done = true
|
|
break
|
|
end
|
|
end
|
|
|
|
print("Returning to surface...")
|
|
|
|
-- Return to where we started
|
|
goTo(0, 0, 0, 0, -1)
|
|
unload(false)
|
|
goTo(0, 0, 0, 0, 1)
|
|
|
|
-- Seal the hole
|
|
if reseal then
|
|
turtle.placeDown()
|
|
end
|
|
|
|
print("Mined " .. collected + unloaded .. " items total.")
|