Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Strip mining turtle program with save-state, vein mining, and inventory management
- -- Fixed: robust vein mining (stack-based) and branch resumption
- -- CONFIGURATION
- local MAIN_LENGTH = 1500
- local BRANCH_EVERY = 3
- local BRANCH_LENGTH = 5
- local ORE_WHITELIST = {
- ["minecraft:coal_ore"] = true,
- ["minecraft:iron_ore"] = true,
- ["minecraft:gold_ore"] = true,
- ["minecraft:redstone_ore"] = true,
- ["minecraft:lapis_ore"] = true,
- ["minecraft:diamond_ore"] = true,
- ["minecraft:emerald_ore"] = true,
- }
- local DROP_BLACKLIST = {
- ["minecraft:cobblestone"] = true,
- ["minecraft:dirt"] = true,
- }
- -- STATE
- local state = {
- x=0,y=0,z=0,
- facing=0, -- 0=north,1=east,2=south,3=west
- mode="main",
- mainProgress=0,
- branchSide="left",
- branchProgress=0,
- nextBranchAt=BRANCH_EVERY,
- branchMainDir=0,
- -- Branch resumption fields
- branchReturning=false,
- branchBackLeft=0,
- -- Vein mining resumption stack: holds reverse-move directions to backtrack (e.g., "b","l","r","u","d")
- veinStack={},
- }
- -- HELPERS
- local function saveState()
- local f = fs.open("resume.dat","w")
- f.write(textutils.serialize(state))
- f.close()
- end
- local function loadState()
- if fs.exists("resume.dat") then
- local f = fs.open("resume.dat","r")
- state = textutils.unserialize(f.readAll())
- f.close()
- end
- end
- local function turnLeft() turtle.turnLeft(); state.facing=(state.facing+3)%4 end
- local function turnRight() turtle.turnRight(); state.facing=(state.facing+1)%4 end
- local function face(dir)
- while state.facing~=dir do turnRight() end
- end
- local function forward()
- while not turtle.forward() do turtle.dig(); sleep(0.5) end
- if state.facing==0 then state.z=state.z-1
- elseif state.facing==1 then state.x=state.x+1
- elseif state.facing==2 then state.z=state.z+1
- elseif state.facing==3 then state.x=state.x-1 end
- end
- -- ORE DETECTION / VEIN MINING (resumable)
- local function inspectDir(direction)
- if direction == "forward" then return turtle.inspect()
- elseif direction == "up" then return turtle.inspectUp()
- elseif direction == "down" then return turtle.inspectDown()
- elseif direction == "left" then
- turtle.turnLeft()
- local ok, data = turtle.inspect()
- turtle.turnRight()
- return ok, data
- elseif direction == "right" then
- turtle.turnRight()
- local ok, data = turtle.inspect()
- turtle.turnLeft()
- return ok, data
- elseif direction == "back" then
- turtle.turnLeft(); turtle.turnLeft()
- local ok, data = turtle.inspect()
- turtle.turnRight(); turtle.turnRight()
- return ok, data
- end
- end
- local function moveDir(dir)
- if dir=="f" then turtle.dig(); forward()
- elseif dir=="b" then turtle.back(); if state.facing==0 then state.z=state.z+1 elseif state.facing==1 then state.x=state.x-1 elseif state.facing==2 then state.z=state.z-1 elseif state.facing==3 then state.x=state.x+1 end
- elseif dir=="l" then turtle.turnLeft(); turtle.dig(); forward(); turtle.turnRight()
- elseif dir=="r" then turtle.turnRight(); turtle.dig(); forward(); turtle.turnLeft()
- elseif dir=="u" then while not turtle.up() do turtle.digUp(); sleep(0.2) end; state.y=state.y+1
- elseif dir=="d" then while not turtle.down() do turtle.digDown(); sleep(0.2) end; state.y=state.y-1 end
- end
- local function reverseDir(dir)
- if dir=="f" then return "b" elseif dir=="b" then return "f" elseif dir=="l" then return "r" elseif dir=="r" then return "l" elseif dir=="u" then return "d" else return "u" end
- end
- local function tryFindOreDir()
- -- Prefer lateral/forward first; we intentionally skip checking "back" to avoid thrashing
- for _,probe in ipairs({"forward","left","right","up","down"}) do
- local ok, data = inspectDir(probe)
- if ok and data and ORE_WHITELIST[data.name] then
- if probe=="forward" then return "f"
- elseif probe=="left" then return "l"
- elseif probe=="right" then return "r"
- elseif probe=="up" then return "u"
- elseif probe=="down" then return "d" end
- end
- end
- return nil
- end
- local function continueVein()
- state.mode="vein"; saveState()
- while true do
- local dir = tryFindOreDir()
- if dir then
- -- Move into the ore block and push the reverse move for backtracking
- moveDir(dir)
- table.insert(state.veinStack, reverseDir(dir))
- saveState()
- else
- -- No adjacent ore; backtrack one step if we have a path
- if #state.veinStack == 0 then
- -- Vein complete
- state.mode = "main"; saveState()
- return
- end
- local back = table.remove(state.veinStack)
- moveDir(back)
- saveState()
- end
- end
- end
- local function maybeVeinMine()
- if tryFindOreDir() then
- -- Start/resume a vein
- if state.mode ~= "vein" then state.veinStack = {} end
- continueVein()
- end
- end
- end
- end
- -- INVENTORY
- local function dropInventory()
- for slot=2,16 do
- turtle.select(slot)
- turtle.dropDown()
- end
- turtle.select(1)
- end
- local function isInventoryFull()
- for slot=2,16 do
- if turtle.getItemCount(slot)==0 then return false end
- end
- return true
- end
- -- BRANCHING
- local function resumeBranch()
- local branchDir = (state.branchSide=="left") and (state.branchMainDir+3)%4 or (state.branchMainDir+1)%4
- face(branchDir)
- for i=state.branchProgress+1,BRANCH_LENGTH do
- turtle.dig(); forward()
- state.branchProgress=i
- maybeVeinMine()
- saveState()
- end
- -- return to tunnel
- face((branchDir+2)%4)
- for i=1,BRANCH_LENGTH do forward() end
- face(state.branchMainDir)
- state.mode="main"
- saveState()
- end
- local function doOneBranch(side)
- -- Initialize branch state if starting fresh
- if state.mode ~= "branch" then
- state.mode="branch"
- state.branchSide=side
- state.branchProgress=state.branchProgress or 0
- state.branchMainDir=state.facing
- state.branchReturning=false
- state.branchBackLeft=BRANCH_LENGTH
- saveState()
- end
- local branchDir = (state.branchSide=="left") and (state.branchMainDir+3)%4 or (state.branchMainDir+1)%4
- -- Forward leg
- if not state.branchReturning then
- face(branchDir)
- for i=state.branchProgress+1,BRANCH_LENGTH do
- turtle.dig(); forward()
- state.branchProgress=i
- saveState()
- maybeVeinMine()
- end
- -- Switch to return leg
- state.branchReturning=true
- state.branchBackLeft=BRANCH_LENGTH
- saveState()
- end
- -- Return leg
- face((branchDir+2)%4)
- while state.branchBackLeft>0 do
- forward()
- state.branchBackLeft=state.branchBackLeft-1
- saveState()
- end
- -- Finish: restore facing and clear branch state
- face(state.branchMainDir)
- state.mode="main"
- state.branchProgress=0
- state.branchBackLeft=0
- state.branchReturning=false
- saveState()
- end
- -- MAIN MINING
- local function mineMain()
- state.mode="main"
- while state.mainProgress<MAIN_LENGTH do
- turtle.dig(); forward()
- state.mainProgress=state.mainProgress+1
- saveState()
- maybeVeinMine()
- if state.mainProgress==state.nextBranchAt then
- -- Left branch (resumable)
- if state.mode=="main" then doOneBranch("left") end
- -- Right branch (resumable)
- if state.mode=="main" then doOneBranch("right") end
- state.nextBranchAt=state.nextBranchAt+BRANCH_EVERY
- if isInventoryFull() then
- local stepsBack=state.mainProgress
- face((state.facing+2)%4)
- for i=1,stepsBack do forward() end
- dropInventory()
- -- go forward again to resume
- face((state.facing+2)%4)
- for i=1,stepsBack do forward() end
- face((state.facing+2)%4)
- end
- end
- end
- end
- dropInventory()
- face((state.facing+2)%4)
- for i=1,stepsBack do forward() end
- face((state.facing+2)%4)
- end
- end
- saveState()
- end
- end
- -- MAIN
- local function main()
- loadState()
- -- If we crashed mid-vein or mid-branch, resume that first
- if state.mode=="vein" then
- continueVein()
- end
- if state.mode=="branch" then
- doOneBranch(state.branchSide)
- end
- -- Continue main plan
- mineMain()
- print("Mining complete.")
- end
- print("Mining complete.")
- end
- main()
Advertisement
Add Comment
Please, Sign In to add comment