-- 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} local ESSENTIAL_ITEMS = { ["minecraft:torch"] = true -- or a very high number like 9999 } 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 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) -- Maximum attempts to handle falling blocks local maxAttempts = 10 local attempts = 0 while attempts < maxAttempts do attempts = attempts + 1 -- Check if there's a block in the way local detectFunc if direction == "up" then detectFunc = turtle.detectUp elseif direction == "down" then detectFunc = turtle.detectDown else detectFunc = turtle.detect end if detectFunc() then -- There's a block, dig it digFunc() if moveFunc() then break end else -- No block, try to move if moveFunc() then break end end -- If we're still here after an attempt, brief pause sleep(0.2) if attempts == maxAttempts then print("Warning: Unable to move after multiple attempts") return false end end -- Update position after successful move if attempts < maxAttempts then 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 for slot = 1, 16 do local item = turtle.getItemDetail(slot) if item and item.name == "minecraft:torch" then hasTorches = true break end end return hasTorches end local function hasOperationalInventory() -- Check if we have at least 1 free slot AND torches local hasSpace = false local hasTorches = false for slot = 1, 16 do if turtle.getItemCount(slot) == 0 then hasSpace = true else local item = turtle.getItemDetail(slot) if item and item.name == "minecraft:torch" then hasTorches = true end end end return hasSpace and hasTorches 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 -- Simply drop all non-torch items for slot = 1, 16 do turtle.select(slot) local item = turtle.getItemDetail(slot) if item and item.name ~= "minecraft:torch" then -- Drop all non-torch items turtle.drop() 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 -- Calculate torch positions for symmetric placement local function calculateTorchPositions(length, width) local positions = {} -- For very small rooms (less than 7x7), just place a torch in the center if length <= 7 and width <= 7 then table.insert(positions, {x = math.ceil(length/2), z = math.ceil(width/2)}) return positions end -- For larger rooms, create a grid of torches with optimal spacing -- In newer versions (1.18+), we can use spacing up to 13 blocks -- But we'll adjust for symmetry based on room dimensions -- Calculate spacing for symmetrical pattern local xSpacing = math.min(13, length) local zSpacing = math.min(13, width) -- Adjust spacing for larger rooms to maintain symmetry if length > 13 then -- Find the number of torches needed along length local numTorchesX = math.ceil(length / 13) -- Distribute evenly xSpacing = length / numTorchesX end if width > 13 then -- Find the number of torches needed along width local numTorchesZ = math.ceil(width / 13) -- Distribute evenly zSpacing = width / numTorchesZ end -- Calculate offsets to center the grid local xOffset = xSpacing / 2 local zOffset = zSpacing / 2 -- Create the grid of torch positions for x = xOffset, length, xSpacing do for z = zOffset, width, zSpacing do table.insert(positions, {x = math.floor(x), z = math.floor(z)}) end end return positions end -- Calculate the total number of torches needed local function calculateTorches(length, width) local positions = calculateTorchPositions(length, width) return #positions end -- Main Program local args = {...} if #args < 3 then print("Usage: digRoom [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 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 local function mineLayer() -- Calculate torch positions for this layer local torchPositions = calculateTorchPositions(length, width) -- Initialize room-relative coordinates local roomX = 0 local roomZ = 0 for row = 1, width do roomZ = row - 1 -- Z coordinate is the row (0-indexed) for col = 1, length - 1 do -- Update room X based on direction (serpentine pattern) if forward then roomX = col - 1 -- When mining forward, X increases else roomX = length - col -- When mining backward, X decreases end -- Check if current room position should have a torch with exact matching for _, pos in ipairs(torchPositions) do if pos.x - 1 == roomX and pos.z - 1 == roomZ then if findItem("minecraft:torch") then print("Placing torch at room position: " .. roomX .. "," .. roomZ) turtle.placeDown() break end end end -- Continue with inventory check and movement 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 -- Move forward if not tryMove(turtle.forward, turtle.dig, "forward") then print("Obstruction detected") return false end end -- Handle row changes if row < width then if forward then turnToDir("right") if not tryMove(turtle.forward, turtle.dig, "forward") then return false end turnToDir("right") else turnToDir("left") if not tryMove(turtle.forward, turtle.dig, "forward") then return false end turnToDir("left") end forward = not forward 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