Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- ComputerCraft Mining Turtle Quarry Program
- Final Working Version - All Functions in Correct Order
- ]]
- -- CONFIG --
- local TRASH = {
- ["minecraft:cobblestone"] = true,
- ["minecraft:dirt"] = true,
- ["minecraft:gravel"] = true,
- ["minecraft:stone"] = true,
- ["minecraft:sand"] = true,
- ["minecraft:netherrack"] = true
- }
- local INVENTORY_THRESHOLD = 15
- local MIN_FUEL_LEVEL = 500
- local PREFERRED_FUEL_ITEMS = {
- ["minecraft:coal"] = true,
- ["minecraft:coal_block"] = true,
- ["minecraft:lava_bucket"] = true
- }
- -- State Management
- local STATE_FILE = "quarry_state.dat"
- local width, length, depth
- local posX, posY, posZ = 0, 0, 0
- local dir = 0 -- 0=north,1=east,2=south,3=west
- local startX, startY, surfaceZ = 0, 0, 0
- local currentLayer = 1
- local goingForward = true
- local currentRow = 1
- local currentCol = 1
- -- Yielding Helper
- local function yield()
- os.queueEvent("yield")
- os.pullEvent("yield")
- end
- -- Movement Functions (MUST COME FIRST since others depend on them)
- local function right()
- turtle.turnRight()
- dir = (dir + 1) % 4
- return true
- end
- local function left()
- turtle.turnLeft()
- dir = (dir - 1) % 4
- if dir < 0 then dir = dir + 4 end
- return true
- end
- local function turnTo(targetDir)
- local diff = (targetDir - dir) % 4
- if diff == 3 then
- left()
- else
- for i = 1, diff do
- right()
- end
- end
- end
- local function tryDig(side)
- local attempts = 0
- while true do
- attempts = attempts + 1
- if attempts % 5 == 0 then yield() end
- local success, reason
- if side == "forward" then
- if not turtle.detect() then return true end
- success, reason = turtle.dig()
- elseif side == "up" then
- if not turtle.detectUp() then return true end
- success, reason = turtle.digUp()
- elseif side == "down" then
- if not turtle.detectDown() then return true end
- success, reason = turtle.digDown()
- end
- if not success then return false, reason end
- sleep(0.2)
- end
- end
- local function forward()
- local attempts = 0
- while not turtle.forward() do
- attempts = attempts + 1
- if attempts % 3 == 0 then yield() end
- local success, reason = tryDig("forward")
- if not success then return false, reason end
- sleep(0.2)
- end
- if dir == 0 then posY = posY + 1
- elseif dir == 1 then posX = posX + 1
- elseif dir == 2 then posY = posY - 1
- elseif dir == 3 then posX = posX - 1 end
- return true
- end
- local function up()
- local attempts = 0
- while not turtle.up() do
- attempts = attempts + 1
- if attempts % 3 == 0 then yield() end
- local success, reason = tryDig("up")
- if not success then return false, reason end
- sleep(0.2)
- end
- posZ = posZ - 1
- return true
- end
- local function down()
- local attempts = 0
- while not turtle.down() do
- attempts = attempts + 1
- if attempts % 3 == 0 then yield() end
- local success, reason = tryDig("down")
- if not success then return false, reason end
- sleep(0.2)
- end
- posZ = posZ + 1
- return true
- end
- local function moveForwardN(n)
- for i = 1, n do
- if not forward() then return false end
- end
- return true
- end
- -- Inventory Management
- local function compactInventory()
- for i = 1, 15 do
- local detail_i = turtle.getItemDetail(i)
- if detail_i then
- for j = i + 1, 16 do
- local detail_j = turtle.getItemDetail(j)
- if detail_j and detail_j.name == detail_i.name then
- turtle.select(j)
- turtle.transferTo(i)
- end
- end
- end
- end
- turtle.select(1)
- end
- local function shouldDumpTrash()
- local usedSlots = 0
- for i = 1, 16 do
- if turtle.getItemDetail(i) then usedSlots = usedSlots + 1 end
- if usedSlots >= INVENTORY_THRESHOLD then return true end
- end
- return false
- end
- local function dumpTrashNow()
- print("Disposing trash on ground...")
- local originalDir = dir
- turnTo(0) -- Face north to throw trash
- local trashFound = false
- for slot = 1, 16 do
- local detail = turtle.getItemDetail(slot)
- if detail and TRASH[detail.name] then
- turtle.select(slot)
- turtle.drop()
- trashFound = true
- end
- end
- turnTo(originalDir) -- Return to original facing
- turtle.select(1)
- return trashFound
- end
- local function depositItems()
- compactInventory()
- print("Depositing valuables in chest")
- for slot = 1, 16 do
- local detail = turtle.getItemDetail(slot)
- if detail and not TRASH[detail.name] then
- turtle.select(slot)
- turtle.drop()
- end
- end
- turtle.select(1)
- end
- -- Navigation
- local function returnToStartHorizontal()
- if posX > startX then
- turnTo(3)
- if not moveForwardN(posX - startX) then return false end
- elseif posX < startX then
- turnTo(1)
- if not moveForwardN(startX - posX) then return false end
- end
- if posY > startY then
- turnTo(2)
- if not moveForwardN(posY - startY) then return false end
- elseif posY < startY then
- turnTo(0)
- if not moveForwardN(startY - posY) then return false end
- end
- turnTo(2)
- return true
- end
- local function returnToChestSurface()
- if not returnToStartHorizontal() then return false end
- while posZ > surfaceZ do
- if not up() then return false end
- end
- while posZ < surfaceZ do
- if not down() then return false end
- end
- return true
- end
- -- Fuel System
- local FUEL_CHECK_ENABLED = nil
- local function checkAndRefuel()
- if not FUEL_CHECK_ENABLED then return true end
- if turtle.getFuelLevel() > MIN_FUEL_LEVEL then return true end
- print("Low fuel! Attempting to refuel...")
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item and PREFERRED_FUEL_ITEMS[item.name] then
- turtle.select(slot)
- if turtle.refuel(1) then
- print("Refueled with", item.name, "| New:", turtle.getFuelLevel())
- turtle.select(1)
- return true
- end
- end
- end
- print("No fuel found!")
- return false
- end
- local function initializeFuelSystem()
- local initialFuel = turtle.getFuelLevel()
- if initialFuel == "unlimited" then
- FUEL_CHECK_ENABLED = false
- print("Fuel checks disabled (unlimited fuel)")
- else
- FUEL_CHECK_ENABLED = true
- print("Fuel management enabled. Current:", initialFuel)
- if initialFuel < MIN_FUEL_LEVEL then checkAndRefuel() end
- end
- end
- -- State Saving/Loading
- local function saveState()
- local data = {
- width = width, length = length, depth = depth,
- posX = posX, posY = posY, posZ = posZ,
- dir = dir, startX = startX, startY = startY, startZ = surfaceZ,
- currentLayer = currentLayer, goingForward = goingForward,
- currentRow = currentRow, currentCol = currentCol
- }
- local file = fs.open(STATE_FILE, "w")
- file.write(textutils.serialize(data))
- file.close()
- end
- local function loadState()
- if fs.exists(STATE_FILE) then
- local file = fs.open(STATE_FILE, "r")
- local data = textutils.unserialize(file.readAll())
- file.close()
- if data then
- width, length, depth = data.width, data.length, data.depth
- posX, posY, posZ = data.posX, data.posY, data.posZ
- dir = data.dir
- startX, startY, surfaceZ = data.startX, data.startY, data.startZ
- currentLayer = data.currentLayer or 1
- goingForward = data.goingForward or true
- currentRow = data.currentRow or 1
- currentCol = data.currentCol or 1
- return true
- end
- end
- return false
- end
- -- Mining Functions
- local function mineColumn()
- if not tryDig("up") then return false end
- if currentCol < width and not tryDig("forward") then return false end
- if not tryDig("down") then return false end
- return true
- end
- -- Main Quarry Logic
- local function runQuarry()
- initializeFuelSystem()
- if not loadState() then
- width, length, depth = tonumber(arg[1]), tonumber(arg[2]), tonumber(arg[3])
- if not (width and length and depth) then
- print("Usage: quarry <width> <length> <depth>")
- return
- end
- startX, startY, surfaceZ = posX, posY, posZ
- saveState()
- end
- print("Starting quarry:", width, "x", length, "x", depth)
- for layer = currentLayer, depth do
- print("Mining layer", layer, "of", depth)
- currentLayer = layer
- turnTo(0) -- Face north at start of each layer
- for row = currentRow, length do
- currentRow = row
- yield()
- local rowDirection = goingForward and 0 or 2
- turnTo(rowDirection)
- for col = currentCol, width do
- currentCol = col
- if col % 3 == 0 and shouldDumpTrash() then
- dumpTrashNow()
- end
- if not mineColumn() then
- print("Stopping due to mining error")
- if returnToChestSurface() then depositItems() end
- return
- end
- if col < width then
- if not forward() then
- print("Failed to move forward in mining pattern")
- if returnToChestSurface() then depositItems() end
- return
- end
- end
- end
- currentCol = 1
- if row < length then
- if goingForward then
- right()
- if not forward() then
- print("Failed to move to next row (right turn)")
- if returnToChestSurface() then depositItems() end
- return
- end
- right()
- else
- left()
- if not forward() then
- print("Failed to move to next row (left turn)")
- if returnToChestSurface() then depositItems() end
- return
- end
- left()
- end
- goingForward = not goingForward
- end
- end
- currentRow = 1
- goingForward = true
- print("Completed layer", layer)
- dumpTrashNow() -- Force trash dump before ascending
- if returnToChestSurface() then
- depositItems()
- if layer < depth then
- right()
- right()
- local nextLayerZ = surfaceZ + layer * 3
- while posZ < nextLayerZ do
- if not down() then
- print("Failed to descend to next layer")
- return
- end
- end
- end
- else
- print("Failed to return to chest!")
- return
- end
- end
- print("Quarry complete!")
- fs.delete(STATE_FILE)
- end
- -- Start the program
- runQuarry()
Advertisement
Add Comment
Please, Sign In to add comment