SomeoneNew666

Minecraft ComputerCraft Room Mining Program2

Feb 17th, 2025 (edited)
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Position tracking
  2. local currentX = 0
  3. local currentY = 0
  4. local currentZ = 0
  5. local facing = 0 -- 0=forward(away from chest), 1=right, 2=back(toward chest), 3=left
  6. local startRow = true -- Track if we're starting from the front or back of the row
  7. local miningLength = 0  -- Store length as a module-level variable
  8. local forward = true -- Moved to module-level to preserve state between layers
  9. local resumePos = {x=0, y=0, z=0, facing=0}
  10.  
  11. -- Add this at the top with other variables
  12. local ESSENTIAL_ITEMS = {
  13.     ["minecraft:torch"] = 64,
  14.     ["minecraft:cobblestone"] = 128,
  15.     ["minecraft:dirt"] = 128,
  16.     ["minecraft:cobbled_deepslate"] = 128
  17. }
  18.  
  19. local function setMiningLength(len)
  20.   miningLength = len
  21. end
  22.  
  23. -- Utility functions
  24. local function findItem(itemName)
  25.   for slot = 1, 16 do
  26.     local item = turtle.getItemDetail(slot)
  27.     if item and item.name == itemName then
  28.       turtle.select(slot)
  29.       return true
  30.     end
  31.   end
  32.   return false
  33. end
  34.  
  35. local function hasInventorySpace()
  36.   for slot = 1, 16 do
  37.     if turtle.getItemCount(slot) == 0 then
  38.       return true
  39.     end
  40.   end
  41.   return false
  42. end
  43.  
  44. local function handleLiquid(direction)
  45.   if findItem("minecraft:cobblestone") or findItem("minecraft:dirt") or findItem("minecraft:cobbled_deepslate") then
  46.     if direction == "up" then
  47.       turtle.placeUp()
  48.     elseif direction == "down" then
  49.       turtle.placeDown()
  50.     else
  51.       turtle.place()
  52.     end
  53.     sleep(0.5)
  54.     return true
  55.   end
  56.   return false
  57. end
  58.  
  59. local function turnToFacing(targetFacing)
  60.   while facing ~= targetFacing do
  61.     turtle.turnRight()
  62.     facing = (facing + 1) % 4
  63.   end
  64. end
  65.  
  66. -- Optimized turning function that takes shortest path
  67. local function turnToFacingOptimal(targetFacing)
  68.   local currentFacing = facing
  69.   local rightTurns = (targetFacing - currentFacing) % 4
  70.   local leftTurns = (currentFacing - targetFacing) % 4
  71.  
  72.   if rightTurns <= leftTurns then
  73.       -- Turn right is shorter or equal
  74.       for i = 1, rightTurns do
  75.           turtle.turnRight()
  76.           facing = (facing + 1) % 4
  77.       end
  78.   else
  79.       -- Turn left is shorter
  80.       for i = 1, leftTurns do
  81.           turtle.turnLeft()
  82.           facing = (facing - 1) % 4
  83.       end
  84.   end
  85. end
  86.  
  87. local function tryMove(moveFunc, digFunc, direction)
  88.     -- First check if there's a liquid
  89.     local detectFunc
  90.     if direction == "up" then
  91.         detectFunc = turtle.detectUp
  92.     elseif direction == "down" then
  93.         detectFunc = turtle.detectDown
  94.     else
  95.         detectFunc = turtle.detect
  96.     end
  97.  
  98.     -- Maximum attempts to handle falling blocks
  99.     local maxAttempts = 10
  100.     local attempts = 0
  101.  
  102.     while attempts < maxAttempts do
  103.         attempts = attempts + 1
  104.        
  105.         if detectFunc() then
  106.             -- Handle liquid first
  107.             if handleLiquid(direction) then
  108.                 digFunc()
  109.                 if moveFunc() then
  110.                     break
  111.                 end
  112.             else
  113.                 digFunc()
  114.                 if moveFunc() then
  115.                     break
  116.                 end
  117.             end
  118.         else
  119.             if moveFunc() then
  120.                 break
  121.             else
  122.                 -- If movement failed but no block detected, try handling liquid
  123.                 if handleLiquid(direction) then
  124.                     if moveFunc() then
  125.                         break
  126.                     end
  127.                 end
  128.             end
  129.         end
  130.  
  131.         -- If we're still here after an attempt, brief pause before next try
  132.         -- This helps with falling blocks settling
  133.         sleep(0.2)
  134.        
  135.         -- If we've tried several times and still can't move, it might be an infinite fall
  136.         if attempts == maxAttempts then
  137.             print("Warning: Possible falling blocks causing obstruction")
  138.             return false
  139.         end
  140.     end
  141.    
  142.     -- Update position after successful move
  143.     if attempts < maxAttempts then  -- Only update if we actually moved
  144.         if moveFunc == turtle.forward then
  145.             if facing == 0 then currentY = currentY - 1
  146.             elseif facing == 1 then currentX = currentX + 1
  147.             elseif facing == 2 then currentY = currentY + 1
  148.             else currentX = currentX - 1 end
  149.         elseif moveFunc == turtle.up then
  150.             currentZ = currentZ + 1
  151.         elseif moveFunc == turtle.down then
  152.             currentZ = currentZ - 1
  153.         end
  154.         return true
  155.     end
  156.    
  157.     return false
  158. end
  159.  
  160. -- Optimized turning function that takes shortest path
  161. local function turnToFacingOptimal(targetFacing)
  162.   local currentFacing = facing
  163.   local rightTurns = (targetFacing - currentFacing) % 4
  164.   local leftTurns = (currentFacing - targetFacing) % 4
  165.  
  166.   if rightTurns <= leftTurns then
  167.       -- Turn right is shorter or equal
  168.       for i = 1, rightTurns do
  169.           turtle.turnRight()
  170.           facing = (facing + 1) % 4
  171.       end
  172.   else
  173.       -- Turn left is shorter
  174.       for i = 1, leftTurns do
  175.           turtle.turnLeft()
  176.           facing = (facing - 1) % 4
  177.       end
  178.   end
  179. end
  180.  
  181. local function returnToChest()
  182.   local returnFacing = facing
  183.   local pathFound = false
  184.  
  185.   -- Try multiple vertical levels to find an open path
  186.   local function tryPathAtLevel(targetZ)
  187.       -- Move to target Z level first
  188.       while currentZ > targetZ do
  189.           if not turtle.down() then return false end
  190.           currentZ = currentZ - 1
  191.       end
  192.       while currentZ < targetZ do
  193.           if not turtle.up() then return false end
  194.           currentZ = currentZ + 1
  195.       end
  196.      
  197.       -- Face toward chest (facing 2)
  198.       turnToFacingOptimal(2)
  199.      
  200.       -- Try Y movement without digging
  201.       local initialY = currentY
  202.       while currentY < 0 do
  203.           if not turtle.forward() then
  204.               -- If blocked, restore position and return false
  205.               while currentY < initialY do
  206.                   turtle.back()
  207.                   currentY = currentY + 1
  208.               end
  209.               return false
  210.           end
  211.           currentY = currentY + 1
  212.       end
  213.      
  214.       -- Try X movement without digging
  215.       if currentX ~= 0 then
  216.           if currentX > 0 then
  217.               turnToFacingOptimal(3) -- face left
  218.           else
  219.               turnToFacingOptimal(1) -- face right
  220.           end
  221.          
  222.           local initialX = currentX
  223.           while currentX ~= 0 do
  224.               if not turtle.forward() then
  225.                   -- If blocked, restore position and return false
  226.                   while currentX ~= initialX do
  227.                       turtle.back()
  228.                       currentX = currentX + (currentX > 0 and 1 or -1)
  229.                   end
  230.                   return false
  231.               end
  232.               currentX = currentX + (currentX > 0 and -1 or 1)
  233.           end
  234.       end
  235.      
  236.       return true
  237.   end
  238.  
  239.   -- Try paths at different levels, starting with levels we expect to be clear
  240.   local levelsToTry = {
  241.       0,           -- Ground level (where chest is)
  242.       -1,          -- One below ground
  243.       1,           -- One above ground
  244.       currentZ,    -- Current level
  245.   }
  246.  
  247.   -- Add intermediate levels if we're far from 0
  248.   if math.abs(currentZ) > 1 then
  249.       table.insert(levelsToTry, math.floor(currentZ/2))
  250.   end
  251.  
  252.   -- Try each level until we find a clear path
  253.   for _, targetZ in ipairs(levelsToTry) do
  254.       if tryPathAtLevel(targetZ) then
  255.           pathFound = true
  256.           break
  257.       end
  258.   end
  259.  
  260.   -- If no clear path found, fall back to original digging behavior
  261.   if not pathFound then
  262.       -- Original digging behavior
  263.       while currentZ > 0 do
  264.           if not tryMove(turtle.down, turtle.digDown, "down") then
  265.               print("Can't move down to Z=0")
  266.               return false
  267.           end
  268.       end
  269.       while currentZ < 0 do
  270.           if not tryMove(turtle.up, turtle.digUp, "up") then
  271.               print("Can't move up to Z=0")
  272.               return false
  273.           end
  274.       end
  275.      
  276.       turnToFacingOptimal(2)
  277.       while currentY < 0 do
  278.           if not tryMove(turtle.forward, turtle.dig, "forward") then
  279.               print("Obstruction while returning on Y axis")
  280.               return false
  281.           end
  282.       end
  283.      
  284.       if currentX ~= 0 then
  285.           if currentX > 0 then
  286.               turnToFacingOptimal(3)
  287.           else
  288.               turnToFacingOptimal(1)
  289.           end
  290.          
  291.           while currentX ~= 0 do
  292.               if not tryMove(turtle.forward, turtle.dig, "forward") then
  293.                   print("Obstruction while returning on X axis")
  294.                   return false
  295.               end
  296.           end
  297.       end
  298.   end
  299.  
  300.   -- Final position verification and facing correction
  301.   if currentX ~= 0 or currentY ~= 0 or currentZ ~= 0 then
  302.       print("Failed to reach chest position!")
  303.       return false
  304.   end
  305.  
  306.   -- Ensure we're facing the chest (facing 2) at the end
  307.   turnToFacingOptimal(2)
  308.  
  309.   return true
  310. end
  311.  
  312. local function hasEssentialItems()
  313.     local hasTorches = false
  314.     local hasBlocks = false
  315.    
  316.     for slot = 1, 16 do
  317.         local item = turtle.getItemDetail(slot)
  318.         if item then
  319.             if item.name == "minecraft:torch" then
  320.                 hasTorches = true
  321.             elseif item.name == "minecraft:cobblestone"
  322.                 or item.name == "minecraft:dirt"
  323.                 or item.name == "minecraft:cobbled_deepslate" then
  324.                 hasBlocks = true
  325.             end
  326.         end
  327.     end
  328.    
  329.     return hasTorches and hasBlocks
  330. end
  331.  
  332. -- Modified hasOperationalInventory
  333. local function hasOperationalInventory()
  334.     -- Check if we have at least 1 free slot AND essential items
  335.     local hasSpace = false
  336.     local preservedItems = {}
  337.    
  338.     -- First check for space
  339.     for slot = 1, 16 do
  340.         if turtle.getItemCount(slot) == 0 then
  341.             hasSpace = true
  342.             break
  343.         end
  344.     end
  345.    
  346.     -- Then check essential items
  347.     for itemName in pairs(ESSENTIAL_ITEMS) do
  348.         local found = false
  349.         for slot = 1, 16 do
  350.             local item = turtle.getItemDetail(slot)
  351.             if item and item.name == itemName then
  352.                 found = true
  353.                 break
  354.             end
  355.         end
  356.         if not found then
  357.             return false
  358.         end
  359.     end
  360.    
  361.     return hasSpace
  362. end
  363.  
  364.  
  365. local function dumpInventory()
  366.     -- Store current position
  367.     resumePos.x = currentX
  368.     resumePos.y = currentY
  369.     resumePos.z = currentZ
  370.     resumePos.facing = facing
  371.  
  372.     -- Return to chest
  373.     print("Inventory full! Returning to chest...")
  374.     if not returnToChest() then return false end
  375.    
  376.     -- Track preserved quantities
  377.     local preserved = {
  378.         ["minecraft:torch"] = 0,
  379.         ["minecraft:cobblestone"] = 0,
  380.         ["minecraft:dirt"] = 0,
  381.         ["minecraft:cobbled_deepslate"] = 0
  382.     }
  383.  
  384.     -- First pass: Calculate total preserved items
  385.     for slot = 1, 16 do
  386.         local item = turtle.getItemDetail(slot)
  387.         if item and ESSENTIAL_ITEMS[item.name] then
  388.             preserved[item.name] = preserved[item.name] + item.count
  389.         end
  390.     end
  391.  
  392.     -- Second pass: Drop excess items
  393.     for slot = 1, 16 do
  394.         turtle.select(slot)
  395.         local item = turtle.getItemDetail(slot)
  396.        
  397.         if item then
  398.             local itemName = item.name
  399.             if ESSENTIAL_ITEMS[itemName] then
  400.                 local maxKeep = ESSENTIAL_ITEMS[itemName]
  401.                 local alreadyPreserved = preserved[itemName]
  402.                
  403.                 if alreadyPreserved > maxKeep then
  404.                     -- Drop excess from this slot
  405.                     local toDrop = math.min(alreadyPreserved - maxKeep, item.count)
  406.                     turtle.drop(toDrop)
  407.                     preserved[itemName] = preserved[itemName] - toDrop
  408.                 end
  409.             else
  410.                 -- Drop all non-essential items
  411.                 turtle.drop()
  412.             end
  413.         end
  414.     end
  415.  
  416.     -- Return to mining position with optimized movement
  417.     -- Move vertically first
  418.     while currentZ ~= resumePos.z do
  419.         if currentZ < resumePos.z then
  420.             tryMove(turtle.up, turtle.digUp, "up")
  421.         else
  422.             tryMove(turtle.down, turtle.digDown, "down")
  423.         end
  424.     end
  425.  
  426.     -- Optimize Y movement
  427.     if currentY ~= resumePos.y then
  428.         if currentY > resumePos.y then
  429.             turnToFacingOptimal(0)  -- Face mining direction
  430.         else
  431.             turnToFacingOptimal(2)  -- Face chest direction
  432.         end
  433.         while currentY ~= resumePos.y do
  434.             tryMove(turtle.forward, turtle.dig, "forward")
  435.         end
  436.     end
  437.  
  438.     -- Optimize X movement
  439.     if currentX ~= resumePos.x then
  440.         if currentX < resumePos.x then
  441.             turnToFacingOptimal(1)  -- Face right
  442.         else
  443.             turnToFacingOptimal(3)  -- Face left
  444.         end
  445.         while currentX ~= resumePos.x do
  446.             tryMove(turtle.forward, turtle.dig, "forward")
  447.         end
  448.     end
  449.  
  450.     -- Return to original facing
  451.     turnToFacingOptimal(resumePos.facing)
  452.     return true
  453. end
  454.  
  455. local function dumpAllInventory()
  456.     -- Return to chest if not already there
  457.     if currentX ~= 0 or currentY ~= 0 or currentZ ~= 0 then
  458.         if not returnToChest() then
  459.             print("Failed to return to chest!")
  460.             return false
  461.         end
  462.     end
  463.    
  464.     -- Ensure facing chest
  465.     turnToFacingOptimal(2)
  466.    
  467.     -- Small delay to ensure stable chest interaction
  468.     sleep(0.5)
  469.    
  470.     -- Dump everything from inventory
  471.     for slot = 1, 16 do
  472.         turtle.select(slot)
  473.         -- Drop entire stack, regardless of item type
  474.         turtle.drop()
  475.     end
  476.    
  477.     return true
  478. end
  479.  
  480. local function calculateTorches(length, width)
  481.   return math.ceil(length/4) * math.ceil(width/4)
  482. end
  483.  
  484. -- Main Program
  485. local args = {...}
  486. if #args < 3 then
  487.   print("Usage: digRoom <length> <width> <height> [horizontal] [vertical]")
  488.   print("horizontal: left/right (default: right)")
  489.   print("vertical: up/down (default: up)")
  490.   return
  491. end
  492.  
  493. local length = tonumber(args[1])
  494. local width = tonumber(args[2])
  495. local height = tonumber(args[3])
  496. local horizontalDir = args[4] or "right"
  497. local verticalDir = args[5] or "up"
  498.  
  499. setMiningLength(length)
  500.  
  501. if not (length and width and height) or length < 1 or width < 1 or height < 1 then
  502.   print("Invalid dimensions!")
  503.   return
  504. end
  505.  
  506. if horizontalDir ~= "left" and horizontalDir ~= "right" then
  507.   print("Invalid horizontal direction! Use 'left' or 'right'")
  508.   return
  509. end
  510.  
  511. if verticalDir ~= "up" and verticalDir ~= "down" then
  512.   print("Invalid vertical direction! Use 'up' or 'down'")
  513.   return
  514. end
  515.  
  516. -- Calculate required resources
  517. local totalBlocks = length * width * height
  518. local fuelNeeded = totalBlocks + height + math.ceil(width/2) * 2
  519. local requiredTorches = height > 1 and calculateTorches(length, width) or 0
  520.  
  521. -- Check fuel
  522. if turtle.getFuelLevel() < fuelNeeded then
  523.   print(string.format("Need %d fuel, have %d", fuelNeeded, turtle.getFuelLevel()))
  524.   return
  525. end
  526.  
  527. -- Check torches if needed
  528. if requiredTorches > 0 then
  529.   local torchCount = 0
  530.   for slot = 1, 16 do
  531.     local item = turtle.getItemDetail(slot)
  532.     if item and item.name == "minecraft:torch" then
  533.       torchCount = torchCount + turtle.getItemCount(slot)
  534.     end
  535.   end
  536.   if torchCount < requiredTorches then
  537.     print(string.format("Need %d torches, have %d", requiredTorches, torchCount))
  538.     return
  539.   end
  540. end
  541.  
  542. -- Check for blocking material
  543. local hasBlockingMaterial = false
  544. for slot = 1, 16 do
  545.   local item = turtle.getItemDetail(slot)
  546.   if item and (item.name == "minecraft:cobblestone" or item.name == "minecraft:dirt" or item.name == "minecraft:cobbled_deepslate") then
  547.     hasBlockingMaterial = true
  548.     break
  549.   end
  550. end
  551.  
  552. if not hasBlockingMaterial then
  553.   print("Warning: No blocks available for liquid handling")
  554.   print("Recommend having cobblestone, dirt, or cobbled deepslate")
  555.   print("Continue anyway? (y/n)")
  556.   local response = read():lower()
  557.   if response ~= "y" then
  558.     return
  559.   end
  560. end
  561.  
  562. local function turnToDir(targetDir)
  563.   if horizontalDir == "left" then
  564.     if targetDir == "right" then
  565.       turtle.turnLeft()
  566.       facing = (facing - 1) % 4
  567.     else
  568.       turtle.turnRight()
  569.       facing = (facing + 1) % 4
  570.     end
  571.   else
  572.     if targetDir == "right" then
  573.       turtle.turnRight()
  574.       facing = (facing + 1) % 4
  575.     else
  576.       turtle.turnLeft()
  577.       facing = (facing - 1) % 4
  578.     end
  579.   end
  580. end
  581.  
  582. local function moveVertical()
  583.   if verticalDir == "up" then
  584.     return turtle.up, turtle.digUp, "up"
  585.   else
  586.     return turtle.down, turtle.digDown, "down"
  587.   end
  588. end
  589.  
  590. -- Modified inventory check in mining loop
  591. local function mineLayer()
  592.     for row = 1, width do
  593.         for col = 1, length - 1 do
  594.             -- New inventory check logic
  595.             local hasSpace = false
  596.             for slot = 1, 16 do
  597.                 if turtle.getItemCount(slot) == 0 then
  598.                     hasSpace = true
  599.                     break
  600.                 end
  601.             end
  602.            
  603.             if not hasSpace then
  604.                 if not dumpInventory() then
  605.                     print("Aborting mining operation")
  606.                     return false
  607.                 end
  608.             end
  609.      
  610.           -- Only place torches in larger rooms or narrow corridors with enough length
  611.           if (row == 2 and col % 4 == 0) and
  612.              ((width > 2) or (width <= 2 and col >= math.ceil(length / 2))) then
  613.             if findItem("minecraft:torch") then
  614.               turtle.placeDown()
  615.             end
  616.           end
  617.      
  618.           if not tryMove(turtle.forward, turtle.dig, "forward") then
  619.                     print("Obstruction detected")
  620.                     return false
  621.           end
  622.         end
  623.    
  624.     if row < width then
  625.       if forward then
  626.         turnToDir("right")
  627.         if not tryMove(turtle.forward, turtle.dig, "forward") then return false end
  628.         turnToDir("right")
  629.         startRow = false
  630.       else
  631.         turnToDir("left")
  632.         if not tryMove(turtle.forward, turtle.dig, "forward") then return false end
  633.         turnToDir("left")
  634.         startRow = true
  635.       end
  636.       forward = not forward -- Toggle direction for next row
  637.     end
  638.   end
  639.  
  640.   return true
  641. end
  642.  
  643. -- Modified end of main program
  644. for layer = 1, height do
  645.     if width % 2 == 0 then
  646.         forward = (layer % 2 == 1)
  647.     else
  648.         forward = true
  649.     end
  650.  
  651.     if not mineLayer() then break end
  652.  
  653.     if layer < height then
  654.         -- Move up/down
  655.         local moveFunc, digFunc, direction = moveVertical()
  656.         if not tryMove(moveFunc, digFunc, direction) then
  657.             print("Warning: Unable to move " .. verticalDir .. " (possible liquid)")
  658.             print("Try again? (y/n)")
  659.             local response = read():lower()
  660.             if response ~= "y" then
  661.                 break
  662.             end
  663.         end
  664.  
  665.         -- Turn around for next layer
  666.         turtle.turnRight()
  667.         turtle.turnRight()
  668.         facing = (facing + 2) % 4
  669.     end
  670. end
  671.  
  672. -- Final return and dump all inventory
  673. print("Mining complete! Returning to chest...")
  674. if dumpAllInventory() then
  675.     print("All items deposited in chest.")
  676.     turnToFacingOptimal(0)
  677. else
  678.     print("Failed to deposit all items!")
  679. end
Add Comment
Please, Sign In to add comment