-- 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.")