-- quarry.lua (2025 optimized + fixed return logic)
-- Fully autonomous vertical quarry with resume, fuel, dump, trash filter
-- Author: ChatGPT (2025 edition, optimized & corrected)
-- === CONFIG ===
local STATE_FILE = "quarry_state.txt"
local FUEL_SLOT = 1
local SAFE_FUEL_MARGIN = 200
local SAVE_INTERVAL = 50
local STATUS_INTERVAL = 25
-- === Trash filter ===
local trashList = {
["minecraft:stone"]=true, ["minecraft:cobblestone"]=true,
["minecraft:andesite"]=true, ["minecraft:diorite"]=true,
["minecraft:granite"]=true, ["minecraft:dirt"]=true,
["minecraft:coarse_dirt"]=true, ["minecraft:gravel"]=true,
["minecraft:sand"]=true, ["minecraft:tuff"]=true,
["minecraft:deepslate"]=true, ["minecraft:cobbled_deepslate"]=true
}
-- === UTILITIES ===
local function saveState(s)
local f = fs.open(STATE_FILE, "w")
f.write(textutils.serialize(s))
f.close()
end
local function loadState()
if not fs.exists(STATE_FILE) then return nil end
local f = fs.open(STATE_FILE, "r")
local d = textutils.unserialize(f.readAll())
f.close()
return d
end
local function maxFuelLevel()
local limit = turtle.getFuelLimit()
return (limit == "unlimited") and math.huge or limit
end
-- === FUEL ===
local function refuelSlot()
if turtle.getFuelLevel() == "unlimited" then return end
turtle.select(FUEL_SLOT)
while turtle.getItemCount() > 0 and turtle.getFuelLevel() < maxFuelLevel() do
turtle.refuel(1)
end
end
local function autoRefuelFromChest()
turtle.turnRight(); turtle.turnRight()
turtle.select(FUEL_SLOT)
local found = false
while turtle.getFuelLevel() < maxFuelLevel() do
if not turtle.suck(64) then break end
found = true
refuelSlot()
end
turtle.turnRight(); turtle.turnRight()
if not found then
print("⚠️ Add fuel to chest behind and press Enter.")
read()
autoRefuelFromChest()
end
end
-- === INVENTORY ===
local function cleanTrash()
for i=2,16 do
local d = turtle.getItemDetail(i)
if d and trashList[d.name] then
turtle.select(i)
turtle.drop()
end
end
end
local function dumpInventory()
turtle.turnRight(); turtle.turnRight()
for i=2,16 do
turtle.select(i)
turtle.drop()
end
turtle.turnRight(); turtle.turnRight()
end
-- === HUD ===
local startTime = os.clock()
local movedBlocks = 0
local lastStatus = 0
local function formatTime(sec)
local m=math.floor(sec/60)
local s=math.floor(sec%60)
return string.format("%02d:%02d",m,s)
end
local function showStatus(state, totalLayers, totalBlocks)
term.clear()
term.setCursorPos(1,1)
local perc = math.min(100, (movedBlocks / totalBlocks) * 100)
local elapsed = os.clock() - startTime
local eta = (perc > 0) and (elapsed / perc) * (100 - perc) or 0
print("==============================")
print(" QUARRY STATUS ")
print("==============================")
print(string.format("Layer %d / %d", state.layer, totalLayers))
print(string.format("Fuel: %d", turtle.getFuelLevel()))
print(string.format("Progress: %.1f%% (%d/%d)", perc, movedBlocks, totalBlocks))
print(string.format("Time: %s | ETA: %s", formatTime(elapsed), formatTime(eta)))
print("==============================")
end
-- === SETUP ===
local args={...}
local length,width
if #args<2 then
if fs.exists(STATE_FILE) then
local s=loadState()
length=s.length; width=s.width
print(string.format("📁 Resuming quarry %dx%d",length,width))
else
print("📏 Enter quarry dimensions:")
io.write(" Length: "); length=tonumber(read())
io.write(" Width: "); width=tonumber(read())
end
else
length=tonumber(args[1]); width=tonumber(args[2])
end
if not length or not width or length<=0 or width<=0 then
print("❌ Invalid dimensions")
return
end
-- === DIRECTION + POSITION TRACKING ===
-- dir: 0=north, 1=east, 2=south, 3=west
local state = loadState() or {
x=1, z=1, y=0, dir=1, layer=0,
length=length, width=width, finished=false
}
local dir = state.dir or 1
local function turnRight()
turtle.turnRight()
dir = (dir + 1) % 4
state.dir = dir
end
local function turnLeft()
turtle.turnLeft()
dir = (dir + 3) % 4
state.dir = dir
end
local function forward()
while turtle.detect() do turtle.dig() end
while not turtle.forward() do turtle.dig(); sleep(0.1) end
if dir==0 then state.z = state.z - 1
elseif dir==1 then state.x = state.x + 1
elseif dir==2 then state.z = state.z + 1
elseif dir==3 then state.x = state.x - 1 end
end
local function back()
turtle.back()
if dir==0 then state.z = state.z + 1
elseif dir==1 then state.x = state.x - 1
elseif dir==2 then state.z = state.z - 1
elseif dir==3 then state.x = state.x + 1 end
end
local function down()
while turtle.detectDown() do turtle.digDown() end
turtle.down()
state.y = state.y - 1
end
-- === RETURN TO BASE ===
local function goHome()
-- Face west (reverse of start)
while dir ~= 3 do turnRight() end
while state.x > 1 do back() end
-- Face north
while dir ~= 0 do turnLeft() end
while state.z > 1 do back() end
-- Face east again (toward quarry)
while dir ~= 1 do turnRight() end
-- Now at (1,1), facing east, chest behind
end
local function resumePosition()
-- move from home to saved coords
while dir ~= 1 do turnRight() end
for z=2,state.z do forward() end
for x=2,state.x do forward() end
end
-- === INITIAL PREP ===
autoRefuelFromChest()
refuelSlot()
showStatus(state, 60, length*width*60) -- estimated start
local totalLayers = 60 -- adjust if desired
local totalBlocks = length*width*totalLayers
-- === MAIN LAYER MINING ===
local function mineLayer()
for z=1,state.width do
for x=1,state.length-1 do
forward()
movedBlocks=movedBlocks+1
if movedBlocks % SAVE_INTERVAL == 0 then saveState(state) end
if movedBlocks - lastStatus >= STATUS_INTERVAL then
showStatus(state,totalLayers,totalBlocks)
lastStatus = movedBlocks
end
-- Occasional maintenance
if movedBlocks % 128 == 0 then
if turtle.getFuelLevel() < SAFE_FUEL_MARGIN then
print("⛽ Refueling...")
goHome()
dumpInventory()
autoRefuelFromChest()
resumePosition()
end
local fullCount=0
for i=2,16 do if turtle.getItemCount(i)>0 then fullCount=fullCount+1 end end
if fullCount>=14 then
print("📦 Dumping inventory...")
goHome(); dumpInventory(); resumePosition()
else
cleanTrash()
end
end
end
if z < state.width then
if z % 2 == 1 then
turnRight(); forward(); turnRight()
else
turnLeft(); forward(); turnLeft()
end
end
end
-- Return to start of layer
goHome()
end
-- === MAIN LOOP ===
local function quarry()
while not state.finished do
mineLayer()
down()
state.layer = state.layer + 1
saveState(state)
showStatus(state, totalLayers, totalBlocks)
if state.layer >= totalLayers then state.finished = true end
end
end
-- === RUN ===
quarry()
goHome()
dumpInventory()
fs.delete(STATE_FILE)
print("✅ Quarry finished successfully.")
Comments
0 B
|👍
/👎
0 B
|0 👍
/0 👎
0 B
|👍
/👎