Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- 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.")
Advertisement