Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Position tracking
- local currentX = 0
- local currentY = 0
- local currentZ = 0
- local facing = 0 -- 0=forward(away from chest), 1=right, 2=back(toward chest), 3=left
- local startRow = true -- Track if we're starting from the front or back of the row
- local miningLength = 0 -- Store length as a module-level variable
- local forward = true -- Moved to module-level to preserve state between layers
- local resumePos = {x=0, y=0, z=0, facing=0}
- -- Add this at the top with other variables
- local ESSENTIAL_ITEMS = {
- ["minecraft:torch"] = 64,
- ["minecraft:cobblestone"] = 128,
- ["minecraft:dirt"] = 128,
- ["minecraft:cobbled_deepslate"] = 128
- }
- local function setMiningLength(len)
- miningLength = len
- end
- -- Utility functions
- local function findItem(itemName)
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item and item.name == itemName then
- turtle.select(slot)
- return true
- end
- end
- return false
- end
- local function hasInventorySpace()
- for slot = 1, 16 do
- if turtle.getItemCount(slot) == 0 then
- return true
- end
- end
- return false
- end
- local function handleLiquid(direction)
- if findItem("minecraft:cobblestone") or findItem("minecraft:dirt") or findItem("minecraft:cobbled_deepslate") then
- if direction == "up" then
- turtle.placeUp()
- elseif direction == "down" then
- turtle.placeDown()
- else
- turtle.place()
- end
- sleep(0.5)
- return true
- end
- return false
- end
- local function turnToFacing(targetFacing)
- while facing ~= targetFacing do
- turtle.turnRight()
- facing = (facing + 1) % 4
- end
- end
- -- Optimized turning function that takes shortest path
- local function turnToFacingOptimal(targetFacing)
- local currentFacing = facing
- local rightTurns = (targetFacing - currentFacing) % 4
- local leftTurns = (currentFacing - targetFacing) % 4
- if rightTurns <= leftTurns then
- -- Turn right is shorter or equal
- for i = 1, rightTurns do
- turtle.turnRight()
- facing = (facing + 1) % 4
- end
- else
- -- Turn left is shorter
- for i = 1, leftTurns do
- turtle.turnLeft()
- facing = (facing - 1) % 4
- end
- end
- end
- local function tryMove(moveFunc, digFunc, direction)
- -- First check if there's a liquid
- local detectFunc
- if direction == "up" then
- detectFunc = turtle.detectUp
- elseif direction == "down" then
- detectFunc = turtle.detectDown
- else
- detectFunc = turtle.detect
- end
- -- Maximum attempts to handle falling blocks
- local maxAttempts = 10
- local attempts = 0
- while attempts < maxAttempts do
- attempts = attempts + 1
- if detectFunc() then
- -- Handle liquid first
- if handleLiquid(direction) then
- digFunc()
- if moveFunc() then
- break
- end
- else
- digFunc()
- if moveFunc() then
- break
- end
- end
- else
- if moveFunc() then
- break
- else
- -- If movement failed but no block detected, try handling liquid
- if handleLiquid(direction) then
- if moveFunc() then
- break
- end
- end
- end
- end
- -- If we're still here after an attempt, brief pause before next try
- -- This helps with falling blocks settling
- sleep(0.2)
- -- If we've tried several times and still can't move, it might be an infinite fall
- if attempts == maxAttempts then
- print("Warning: Possible falling blocks causing obstruction")
- return false
- end
- end
- -- Update position after successful move
- if attempts < maxAttempts then -- Only update if we actually moved
- if moveFunc == turtle.forward then
- if facing == 0 then currentY = currentY - 1
- elseif facing == 1 then currentX = currentX + 1
- elseif facing == 2 then currentY = currentY + 1
- else currentX = currentX - 1 end
- elseif moveFunc == turtle.up then
- currentZ = currentZ + 1
- elseif moveFunc == turtle.down then
- currentZ = currentZ - 1
- end
- return true
- end
- return false
- end
- -- Optimized turning function that takes shortest path
- local function turnToFacingOptimal(targetFacing)
- local currentFacing = facing
- local rightTurns = (targetFacing - currentFacing) % 4
- local leftTurns = (currentFacing - targetFacing) % 4
- if rightTurns <= leftTurns then
- -- Turn right is shorter or equal
- for i = 1, rightTurns do
- turtle.turnRight()
- facing = (facing + 1) % 4
- end
- else
- -- Turn left is shorter
- for i = 1, leftTurns do
- turtle.turnLeft()
- facing = (facing - 1) % 4
- end
- end
- end
- local function returnToChest()
- local returnFacing = facing
- local pathFound = false
- -- Try multiple vertical levels to find an open path
- local function tryPathAtLevel(targetZ)
- -- Move to target Z level first
- while currentZ > targetZ do
- if not turtle.down() then return false end
- currentZ = currentZ - 1
- end
- while currentZ < targetZ do
- if not turtle.up() then return false end
- currentZ = currentZ + 1
- end
- -- Face toward chest (facing 2)
- turnToFacingOptimal(2)
- -- Try Y movement without digging
- local initialY = currentY
- while currentY < 0 do
- if not turtle.forward() then
- -- If blocked, restore position and return false
- while currentY < initialY do
- turtle.back()
- currentY = currentY + 1
- end
- return false
- end
- currentY = currentY + 1
- end
- -- Try X movement without digging
- if currentX ~= 0 then
- if currentX > 0 then
- turnToFacingOptimal(3) -- face left
- else
- turnToFacingOptimal(1) -- face right
- end
- local initialX = currentX
- while currentX ~= 0 do
- if not turtle.forward() then
- -- If blocked, restore position and return false
- while currentX ~= initialX do
- turtle.back()
- currentX = currentX + (currentX > 0 and 1 or -1)
- end
- return false
- end
- currentX = currentX + (currentX > 0 and -1 or 1)
- end
- end
- return true
- end
- -- Try paths at different levels, starting with levels we expect to be clear
- local levelsToTry = {
- 0, -- Ground level (where chest is)
- -1, -- One below ground
- 1, -- One above ground
- currentZ, -- Current level
- }
- -- Add intermediate levels if we're far from 0
- if math.abs(currentZ) > 1 then
- table.insert(levelsToTry, math.floor(currentZ/2))
- end
- -- Try each level until we find a clear path
- for _, targetZ in ipairs(levelsToTry) do
- if tryPathAtLevel(targetZ) then
- pathFound = true
- break
- end
- end
- -- If no clear path found, fall back to original digging behavior
- if not pathFound then
- -- Original digging behavior
- while currentZ > 0 do
- if not tryMove(turtle.down, turtle.digDown, "down") then
- print("Can't move down to Z=0")
- return false
- end
- end
- while currentZ < 0 do
- if not tryMove(turtle.up, turtle.digUp, "up") then
- print("Can't move up to Z=0")
- return false
- end
- end
- turnToFacingOptimal(2)
- while currentY < 0 do
- if not tryMove(turtle.forward, turtle.dig, "forward") then
- print("Obstruction while returning on Y axis")
- return false
- end
- end
- if currentX ~= 0 then
- if currentX > 0 then
- turnToFacingOptimal(3)
- else
- turnToFacingOptimal(1)
- end
- while currentX ~= 0 do
- if not tryMove(turtle.forward, turtle.dig, "forward") then
- print("Obstruction while returning on X axis")
- return false
- end
- end
- end
- end
- -- Final position verification and facing correction
- if currentX ~= 0 or currentY ~= 0 or currentZ ~= 0 then
- print("Failed to reach chest position!")
- return false
- end
- -- Ensure we're facing the chest (facing 2) at the end
- turnToFacingOptimal(2)
- return true
- end
- local function hasEssentialItems()
- local hasTorches = false
- local hasBlocks = false
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item then
- if item.name == "minecraft:torch" then
- hasTorches = true
- elseif item.name == "minecraft:cobblestone"
- or item.name == "minecraft:dirt"
- or item.name == "minecraft:cobbled_deepslate" then
- hasBlocks = true
- end
- end
- end
- return hasTorches and hasBlocks
- end
- -- Modified hasOperationalInventory
- local function hasOperationalInventory()
- -- Check if we have at least 1 free slot AND essential items
- local hasSpace = false
- local preservedItems = {}
- -- First check for space
- for slot = 1, 16 do
- if turtle.getItemCount(slot) == 0 then
- hasSpace = true
- break
- end
- end
- -- Then check essential items
- for itemName in pairs(ESSENTIAL_ITEMS) do
- local found = false
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item and item.name == itemName then
- found = true
- break
- end
- end
- if not found then
- return false
- end
- end
- return hasSpace
- end
- local function dumpInventory()
- -- Store current position
- resumePos.x = currentX
- resumePos.y = currentY
- resumePos.z = currentZ
- resumePos.facing = facing
- -- Return to chest
- print("Inventory full! Returning to chest...")
- if not returnToChest() then return false end
- -- Track preserved quantities
- local preserved = {
- ["minecraft:torch"] = 0,
- ["minecraft:cobblestone"] = 0,
- ["minecraft:dirt"] = 0,
- ["minecraft:cobbled_deepslate"] = 0
- }
- -- First pass: Calculate total preserved items
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item and ESSENTIAL_ITEMS[item.name] then
- preserved[item.name] = preserved[item.name] + item.count
- end
- end
- -- Second pass: Drop excess items
- for slot = 1, 16 do
- turtle.select(slot)
- local item = turtle.getItemDetail(slot)
- if item then
- local itemName = item.name
- if ESSENTIAL_ITEMS[itemName] then
- local maxKeep = ESSENTIAL_ITEMS[itemName]
- local alreadyPreserved = preserved[itemName]
- if alreadyPreserved > maxKeep then
- -- Drop excess from this slot
- local toDrop = math.min(alreadyPreserved - maxKeep, item.count)
- turtle.drop(toDrop)
- preserved[itemName] = preserved[itemName] - toDrop
- end
- else
- -- Drop all non-essential items
- turtle.drop()
- end
- end
- end
- -- Return to mining position with optimized movement
- -- Move vertically first
- while currentZ ~= resumePos.z do
- if currentZ < resumePos.z then
- tryMove(turtle.up, turtle.digUp, "up")
- else
- tryMove(turtle.down, turtle.digDown, "down")
- end
- end
- -- Optimize Y movement
- if currentY ~= resumePos.y then
- if currentY > resumePos.y then
- turnToFacingOptimal(0) -- Face mining direction
- else
- turnToFacingOptimal(2) -- Face chest direction
- end
- while currentY ~= resumePos.y do
- tryMove(turtle.forward, turtle.dig, "forward")
- end
- end
- -- Optimize X movement
- if currentX ~= resumePos.x then
- if currentX < resumePos.x then
- turnToFacingOptimal(1) -- Face right
- else
- turnToFacingOptimal(3) -- Face left
- end
- while currentX ~= resumePos.x do
- tryMove(turtle.forward, turtle.dig, "forward")
- end
- end
- -- Return to original facing
- turnToFacingOptimal(resumePos.facing)
- return true
- end
- local function dumpAllInventory()
- -- Return to chest if not already there
- if currentX ~= 0 or currentY ~= 0 or currentZ ~= 0 then
- if not returnToChest() then
- print("Failed to return to chest!")
- return false
- end
- end
- -- Ensure facing chest
- turnToFacingOptimal(2)
- -- Small delay to ensure stable chest interaction
- sleep(0.5)
- -- Dump everything from inventory
- for slot = 1, 16 do
- turtle.select(slot)
- -- Drop entire stack, regardless of item type
- turtle.drop()
- end
- return true
- end
- local function calculateTorches(length, width)
- return math.ceil(length/4) * math.ceil(width/4)
- end
- -- Main Program
- local args = {...}
- if #args < 3 then
- print("Usage: digRoom <length> <width> <height> [horizontal] [vertical]")
- print("horizontal: left/right (default: right)")
- print("vertical: up/down (default: up)")
- return
- end
- local length = tonumber(args[1])
- local width = tonumber(args[2])
- local height = tonumber(args[3])
- local horizontalDir = args[4] or "right"
- local verticalDir = args[5] or "up"
- setMiningLength(length)
- if not (length and width and height) or length < 1 or width < 1 or height < 1 then
- print("Invalid dimensions!")
- return
- end
- if horizontalDir ~= "left" and horizontalDir ~= "right" then
- print("Invalid horizontal direction! Use 'left' or 'right'")
- return
- end
- if verticalDir ~= "up" and verticalDir ~= "down" then
- print("Invalid vertical direction! Use 'up' or 'down'")
- return
- end
- -- Calculate required resources
- local totalBlocks = length * width * height
- local fuelNeeded = totalBlocks + height + math.ceil(width/2) * 2
- local requiredTorches = height > 1 and calculateTorches(length, width) or 0
- -- Check fuel
- if turtle.getFuelLevel() < fuelNeeded then
- print(string.format("Need %d fuel, have %d", fuelNeeded, turtle.getFuelLevel()))
- return
- end
- -- Check torches if needed
- if requiredTorches > 0 then
- local torchCount = 0
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item and item.name == "minecraft:torch" then
- torchCount = torchCount + turtle.getItemCount(slot)
- end
- end
- if torchCount < requiredTorches then
- print(string.format("Need %d torches, have %d", requiredTorches, torchCount))
- return
- end
- end
- -- Check for blocking material
- local hasBlockingMaterial = false
- for slot = 1, 16 do
- local item = turtle.getItemDetail(slot)
- if item and (item.name == "minecraft:cobblestone" or item.name == "minecraft:dirt" or item.name == "minecraft:cobbled_deepslate") then
- hasBlockingMaterial = true
- break
- end
- end
- if not hasBlockingMaterial then
- print("Warning: No blocks available for liquid handling")
- print("Recommend having cobblestone, dirt, or cobbled deepslate")
- print("Continue anyway? (y/n)")
- local response = read():lower()
- if response ~= "y" then
- return
- end
- end
- local function turnToDir(targetDir)
- if horizontalDir == "left" then
- if targetDir == "right" then
- turtle.turnLeft()
- facing = (facing - 1) % 4
- else
- turtle.turnRight()
- facing = (facing + 1) % 4
- end
- else
- if targetDir == "right" then
- turtle.turnRight()
- facing = (facing + 1) % 4
- else
- turtle.turnLeft()
- facing = (facing - 1) % 4
- end
- end
- end
- local function moveVertical()
- if verticalDir == "up" then
- return turtle.up, turtle.digUp, "up"
- else
- return turtle.down, turtle.digDown, "down"
- end
- end
- -- Modified inventory check in mining loop
- local function mineLayer()
- for row = 1, width do
- for col = 1, length - 1 do
- -- New inventory check logic
- local hasSpace = false
- for slot = 1, 16 do
- if turtle.getItemCount(slot) == 0 then
- hasSpace = true
- break
- end
- end
- if not hasSpace then
- if not dumpInventory() then
- print("Aborting mining operation")
- return false
- end
- end
- -- Only place torches in larger rooms or narrow corridors with enough length
- if (row == 2 and col % 4 == 0) and
- ((width > 2) or (width <= 2 and col >= math.ceil(length / 2))) then
- if findItem("minecraft:torch") then
- turtle.placeDown()
- end
- end
- if not tryMove(turtle.forward, turtle.dig, "forward") then
- print("Obstruction detected")
- return false
- end
- end
- if row < width then
- if forward then
- turnToDir("right")
- if not tryMove(turtle.forward, turtle.dig, "forward") then return false end
- turnToDir("right")
- startRow = false
- else
- turnToDir("left")
- if not tryMove(turtle.forward, turtle.dig, "forward") then return false end
- turnToDir("left")
- startRow = true
- end
- forward = not forward -- Toggle direction for next row
- end
- end
- return true
- end
- -- Modified end of main program
- for layer = 1, height do
- if width % 2 == 0 then
- forward = (layer % 2 == 1)
- else
- forward = true
- end
- if not mineLayer() then break end
- if layer < height then
- -- Move up/down
- local moveFunc, digFunc, direction = moveVertical()
- if not tryMove(moveFunc, digFunc, direction) then
- print("Warning: Unable to move " .. verticalDir .. " (possible liquid)")
- print("Try again? (y/n)")
- local response = read():lower()
- if response ~= "y" then
- break
- end
- end
- -- Turn around for next layer
- turtle.turnRight()
- turtle.turnRight()
- facing = (facing + 2) % 4
- end
- end
- -- Final return and dump all inventory
- print("Mining complete! Returning to chest...")
- if dumpAllInventory() then
- print("All items deposited in chest.")
- turnToFacingOptimal(0)
- else
- print("Failed to deposit all items!")
- end
Add Comment
Please, Sign In to add comment