rahk

Quarry

May 2nd, 2013
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2.  
  3.   Rectangular Quarry Program 1.2b
  4.   by Adam Smith "shiphorns"
  5.   March 7 2013
  6.  
  7.   1.0b -    Original public release
  8.   1.1b -    Fixes bug with turtle using the wrong axis order when trying to return home after hitting
  9.             and undiggable block. I erroneously had it trying to do moveTo(0,0,0) instead of goHome()
  10.             which would result in the turtle trying to move in the x-direction first, and possibly
  11.             getting blocked by bedrock when trying to move home.
  12.   1.2b -    Fix for turtle getting stuck if turtle simultaneous encounters bedrock in front and above it.
  13.  
  14. --]]
  15. local tArgs = { ... }
  16. local sizeZ -- Quarry is this long in direction turtle is initially facing, including block turtle is on
  17. local sizeX -- Quarry is this wide to the right of where turtle is facing, including block turtle is on
  18. local sizeY -- Quarry removes this many layers of blocks including layer where turtle starts
  19. local bDebug= false
  20.  
  21. local goUnload  -- Forward declaration
  22.  
  23. if (#tArgs == 1) then
  24.     sizeZ,sizeX,sizeY = tonumber(tArgs[1]),tonumber(tArgs[1]),256
  25. elseif (#tArgs == 2) then
  26.     sizeZ,sizeX,sizeY = tonumber(tArgs[1]),tonumber(tArgs[2]),256
  27. elseif (#tArgs >= 3) then
  28.     sizeZ,sizeX,sizeY = tonumber(tArgs[1]),tonumber(tArgs[2]),tonumber(tArgs[3])
  29.     if (#tArgs > 3) then
  30.         bDebug = (tonumber(tArgs[4])==1)
  31.     end
  32. else
  33.     print( "Usage: quarry <sq. size> <optional width > <optional fixed depth> <optional 1 for debug mode>" )
  34.     return
  35. end
  36.  
  37. -- Validate dimensions
  38. if (sizeX<2 or sizeZ<2 or sizeY<1) then
  39.   print( "Dimensions given must be at least 2L x 2W x 1D. Efficiency is optimal if fixed depth is a multiple of 3." )
  40.   return
  41. end
  42.  
  43. local minFuel = math.ceil((math.ceil(sizeY/3)*(sizeX*sizeY)+(2*sizeY))/1200)
  44. local maxFuel = "TBD"
  45.  
  46. if not (turtle.getFuelLevel()=="unlimited") then
  47.   print("Place fuel reserves in slot 1 (upper left) if desired and hit any key to start.")
  48.   os.pullEvent("key")
  49. end
  50.  
  51. local tX,tZ,tY = 0,0,0    -- Place the turtle starts is considered block 0,0,0 in the turtle's local coordinate system
  52. local xDir,zDir = 0,1     -- Turtle is considered as initially facing positive z direction, regardless of global world facing direction
  53. local refuelSlot = 1      -- Turtle can fuel from any slot, but it will never dump this slot's contents so this is where fuel should be placed
  54.  
  55. -- Notice that all coordinates formated as 0,0,0 are in X,Z,Y order, NOT alphabetical X,Y,Z order, where Y is up/down axis
  56. -- Y axis is always the minecraft world Y-axis, but X and Z in this turtle's local coordinate system won't necessarily match his
  57. -- orientation in the global world system (turtle's system is relative to how he is initially facing, +Z is his facing direction)
  58.  
  59. local function checkFuel(bMovingAwayFromOrigin)
  60.     if bDebug then print("checkFuel()") end
  61.     -- This function returns true only if there is enough fuel left to move 1 block in any direction,
  62.     -- and still have enough left over for a return trip to 0,0,0 that might be needed for refuel or at
  63.     -- the end of the quarrying. This ensures the turtle is never stranded in the quarry.
  64.     local fuelLevel = turtle.getFuelLevel()
  65.    
  66.     if (fuelLevel == "unlimited") then
  67.         -- Server has fuel requirement turned off in configs
  68.         return true
  69.     end
  70.    
  71.     -- If the turtle is attempting to move away from its starting location, it is going to
  72.     -- consume the normal 1 fuel cost to move, but it will also add +1 to the cost of the
  73.     -- trip to return home to dump/refuel/finish. If we know the turtle is moving closer to
  74.     -- home, there is no extra cost since it is effectively part of the return trip.
  75.     local fuelNeeded = math.abs(tX)+math.abs(tY)+math.abs(tZ)
  76.     if (bMovingAwayFromOrigin == nil or bMovingAwayFromOrigin == true) then
  77.         -- Turtle is moving away from 0,0,0 or direction is unspecified (assume worst case), add 2 fuel
  78.         fuelNeeded = fuelNeeded + 2
  79.     end
  80.  
  81.     if (fuelLevel >= fuelNeeded) then
  82.         -- Turtle has enough fuel to do the next 1-block movement, plus enough to
  83.         -- return home from there.
  84.         return true
  85.     end
  86.  
  87.     -- If we get here, turtle does not have enough fuel for the move plus a return to base
  88.     -- First we will try to refuel from anything we find in the turtle's inventory. Failing that
  89.     -- We will return to home and prompt the user to add fuel
  90.    
  91.     local slot = 1
  92.     turtle.select(slot)
  93.    
  94.     if bDebug then print("Entering while true do in checkFuel") end
  95.     while true do
  96.         if turtle.refuel(1) then
  97.             -- Found fuel in current slot, consume 1, see if it's enough, if not loop again
  98.             if (turtle.getFuelLevel()>=fuelNeeded) then
  99.                 print("Refueled from inventory, resuming quarrying...")
  100.                 return true
  101.             end
  102.         else
  103.             -- Couldn't refuel from currently-selected slot, try next slot. If there are no more slots, ask for player help.
  104.             if (slot < 16) then
  105.                 slot = slot + 1
  106.                 turtle.select(slot)
  107.             else
  108.                 -- There are no more slots to look in, reset selection so that we're ready to loop over all slots again, and so that the
  109.                 -- player sees slot 1 highlighted (fastest for turtle to find fuel in). Return to 0,0,0 if we can (in case turtle is
  110.                 -- under lava or otherwise inaccessible), prompt player to add fuel.
  111.  
  112.                 return goUnload(true)
  113.             end
  114.         end
  115.     end
  116. end
  117.  
  118. local function turnLeft()
  119.   turtle.turnLeft()
  120.   xDir,zDir = -zDir,xDir
  121.   return true
  122. end
  123.  
  124. local function turnRight()
  125.   turtle.turnRight()
  126.   xDir,zDir = zDir,-xDir
  127.   return true
  128. end
  129.  
  130. local function goForward(bCheckFuel)
  131.     if bDebug then print("goForward()") end
  132.     -- Can't move without fuel. checkFuel() will wait on player if necessary.
  133.     if (bCheckFuel==true or bCheckFuel==nil) then
  134.     checkFuel((xDir>0 and tX>=0) or (xDir<0 and tX<=0) or (zDir>0 and tZ>=0) or (zDir<0 and tZ<=0)) -- Passes boolean true if moving away from 0,0,0
  135.   end
  136.  
  137.     local tries = 3
  138.     while not turtle.forward() do
  139.         if bDebug then print("goForward: while not turtle.forward() do tries="..tries) end
  140.         if turtle.detect() then
  141.             if bDebug then print("goForward: detect") end
  142.             if not turtle.dig() then
  143.                 print("Undiggable block encountered. Will retry in 5 seconds.")
  144.                 -- Turtle is blocked. In case this is a temporary glitch, we try 3 times before conceding hard failure
  145.                 tries = tries - 1
  146.                 if (tries <= 0) then
  147.                   return false
  148.                 else
  149.                     if bDebug then print("goForward: sleep(5)") end
  150.                     sleep(5) -- Wait 5 seconds, hope the problem resolves itself
  151.                 end
  152.             end
  153.         elseif turtle.attack() then
  154.             if bDebug then print("goForward: attack") end
  155.             -- Had to attack player or mob. You can add additional code here such
  156.             -- as turtle.suck() if you want to collect killed mob loot. This is a quarry program
  157.             -- to collect ores, not rotten flesh and bones, so this block is empty.
  158.         else
  159.             -- Unknown obstruction, possibly a player in
  160.             -- peaceful or creative mode. Try again in 0.5 seconds and hope it's gone.
  161.             if bDebug then
  162.                 print("goForward: sleep(0.5) else block")
  163.                 print("Turtle fuel="..turtle.getFuelLevel())
  164.             end
  165.             sleep(0.5)
  166.         end
  167.     end
  168.  
  169.     tX = tX + xDir  -- If we're moving in the xDir, this will change tX by + or - 1
  170.     tZ = tZ + zDir  -- If we're moving in the zDir, this will change tZ by + or - 1
  171.  
  172.     return true -- Turtle moved successfully
  173. end
  174.  
  175. local function goDown(bCheckFuel)
  176.     if bDebug then print("goDown()") end
  177.     -- Can't move without fuel. checkFuel() will wait on player if necessary.
  178.     if (bCheckFuel==true or bCheckFuel==nil) then
  179.     checkFuel(tY<=0)    -- Passes boolean true if moving away from 0,0,0
  180.   end
  181.  
  182.   local tries = 3
  183.     while not turtle.down() do
  184.         if bDebug then print("goDown: while not turtle.down() do tries="..tries) end
  185.         if turtle.detectDown() then
  186.             if bDebug then print("goDown: detectDown") end
  187.             if not turtle.digDown() then
  188.                 print("Undiggable block encountered. Will retry in 5 seconds")
  189.                 -- Turtle is blocked. In case this is a temporary glitch, we try 3 times before conceding hard failure
  190.                 tries = tries - 1
  191.                 if (tries <= 0) then
  192.                   return false
  193.                 else
  194.                     if bDebug then print("goDown: sleep(5)") end
  195.                   sleep(5) -- Wait 5 seconds, hope the problem resolves itself
  196.                 end
  197.             end
  198.         elseif turtle.attackDown() then
  199.             if bDebug then print("goDown: attack") end
  200.             -- Had to attack player or mob. You can add additional code here such
  201.             -- as turtle.suck() if you want to collect killed mob loot. This is a quarry program
  202.             -- to collect ores, not rotten flesh and bones, so this block is empty.
  203.         else
  204.             -- Unknown obstruction, possibly a player in
  205.             -- peaceful or creative mode. Try again in 0.5 seconds and hope it's gone.
  206.             if bDebug then print("goDown: sleep(0.5)") end
  207.             sleep(0.5)
  208.         end
  209.     end
  210.  
  211.     tY = tY - 1
  212.     return true -- Turtle moved successfully
  213. end
  214.  
  215. local function goUp(bCheckFuel)
  216.     if bDebug then print("goUp()") end
  217.    
  218.   -- Can't move without fuel. checkFuel() will wait on player if necessary.
  219.   if (bCheckFuel==true or bCheckFuel==nil) then
  220.     checkFuel(tY>=0)    -- Passes boolean true if moving away from 0,0,0
  221.   end
  222.  
  223.   local tries = 3
  224.     while not turtle.up() do
  225.         if bDebug then print("goUp: while not loop tries="..tries) end
  226.         if turtle.detectUp() then
  227.             if bDebug then print("goUp: detectUp") end
  228.               if not turtle.digUp() then
  229.                         print("Undiggable block encountered. Will retry in 5 seconds.")
  230.                         -- Turtle is blocked. In case this is a temporary glitch, we try 3 times before conceding hard failure
  231.                 tries = tries - 1
  232.                 if (tries <= 0) then
  233.                   return false
  234.                 else
  235.                   sleep(10) -- Wait 10 seconds, hope the problem resolves itself
  236.                 end
  237.             end
  238.         elseif turtle.attackUp() then
  239.             if bDebug then print("goUp: attack") end
  240.             -- Had to attack player or mob. You can add additional code here such
  241.             -- as turtle.suck() if you want to collect killed mob loot. This is a quarry program
  242.             -- to collect ores, not rotten flesh and bones, so this block is empty.
  243.         else
  244.             -- Unknown obstruction, possibly a player in
  245.             -- peaceful or creative mode. Try again in 0.5 seconds and hope it's gone.
  246.             if bDebug then print("goUp: sleep(0.5)") end
  247.             sleep(0.5)
  248.         end
  249.     end
  250.  
  251.     tY = tY + 1
  252.     return true -- Turtle moved successfully
  253. end
  254.  
  255. local function orient(targetXdir, targetZdir)
  256.     -- One of the supplied directions should be -1 or +1, the other should be 0.
  257.     if ((targetXdir ~= 0) and (targetZdir ~= 0)) or ((targetXdir==0) and (targetZdir==0)) then
  258.         print("orient() given mutually exclusive values: "..targetXdir..", "..targetZdir)
  259.         return false
  260.     end
  261.    
  262.     if (((targetXdir ~= 0) and (math.abs(targetXdir) ~= 1)) or ((targetZdir ~= 0) and (math.abs(targetZdir) ~= 1))) then
  263.         print("orient() given bad values: "..targetXdir..", "..targetZdir)
  264.         return false
  265.     end
  266.    
  267.     if (targetXdir ~= 0) and (targetXdir ~= xDir) then
  268.         -- x axis alignment requested, and differs from current alignment
  269.         if (xDir ~= 0) then
  270.             -- Turtle is x-axis aligned 180 from target
  271.             turnLeft()
  272.             turnLeft()
  273.         elseif (zDir == targetXdir) then
  274.             turnRight()
  275.         else
  276.             turnLeft()
  277.         end
  278.      elseif (targetZdir ~= 0) and (targetZdir ~= zDir) then
  279.          -- z axis alignment requested, and differs from current alignment
  280.         if (zDir ~= 0) then
  281.             -- Turtle is z-axis aligned 180 from target
  282.             turnLeft()
  283.             turnLeft()
  284.         elseif (xDir == targetZdir) then
  285.             turnLeft()
  286.         else
  287.             turnRight()
  288.         end
  289.     end
  290.    
  291.     return true
  292. end
  293.  
  294. local function goHome()
  295.   -- This is similar to moveTo(0,0,0) but axis ordering of movement is reversed, so that turtle takes
  296.   -- the same path to and from home location and where it left off. Also, this function passes false to
  297.   -- goDown, goUp and goForward to make them skip the per-move fuel check, because making that check
  298.   -- could result in circular function calling: goHome()->goFoward()->checkFuel()->goHome()->goFoward()->checkFuel().. etc.
  299.   -- This function is set up to move along Y-axis first, then X, then finally Z, unless bReverse is true
  300.   -- Note: The order doesn't matter much when digging out a space, but can matter when building something
  301.   -- so that you don't dig a tunnel through what you're building.
  302.  
  303.   local fuelNeeded = math.abs(tX)+math.abs(tY)+math.abs(tZ)
  304.   if not (turtle.getFuelLevel()=="unlimited") then
  305.     if not (turtle.getFuelLevel()>=fuelNeeded) then
  306.       print("Error: Turtle ended up in the unexpected state of not having enough fuel to return home.")
  307.       return false
  308.     end
  309.   end
  310.  
  311.     while (tY<0) do
  312.         if bDebug then print("goHome while tY<0 tY="..tY) end
  313.         if not goUp(false) then
  314.             -- Critical movement fail, bail
  315.             return false
  316.         end
  317.     end
  318.  
  319.     while (tY>0) do
  320.         if bDebug then print("goHome while tY>0 tY="..tY) end
  321.         if not goDown(false) then
  322.             -- Critical movement fail, bail
  323.             return false
  324.         end
  325.     end
  326.  
  327.     -- If not at tX==targetX, move the right direction until tX==targetX
  328.     if (tX>0) then orient(-1,0) end
  329.     if (tX<0) then orient(1,0) end
  330.     while (tX~=0) do
  331.         if bDebug then print("goHome while tX~=0 tX="..tX) end
  332.         if not goForward(false) then
  333.         -- Critical movement fail, bail
  334.         return false
  335.         end
  336.     end
  337.  
  338.     -- If not at tZ==targetZ, move the right direction until tZ==targetZ
  339.     if (tZ>0) then orient(0,-1) end
  340.     if (tZ<0) then orient(0,1) end
  341.     while (tZ~=0) do
  342.         if bDebug then print("goHome while tZ~=0 tZ="..tZ) end
  343.         if not goForward(false) then
  344.             -- Critical movement fail, bail
  345.             return false
  346.         end
  347.     end
  348.  
  349.     return true
  350. end
  351.  
  352. local function moveTo(targetX,targetZ,targetY)
  353.  
  354.     local fuelNeeded = math.abs(tX-targetX)+math.abs(tY-targetY)+math.abs(tZ-targetZ)
  355.   if not (turtle.getFuelLevel()=="unlimited") then
  356.     if not (turtle.getFuelLevel()>=fuelNeeded) then
  357.       print("Error: Turtle ended up in the unexpected state of not having enough fuel to return home.")
  358.       return false
  359.  
  360.     end
  361.   end
  362.  
  363.     -- If not at tZ==targetZ, move the right direction until tZ==targetZ
  364.     if (tZ>targetZ) then orient(0,-1) end
  365.     if (tZ<targetZ) then orient(0,1) end
  366.     while (tZ~=targetZ) do
  367.         if bDebug then print("moveTo while tZ~=targetZ tZ="..tZ.." targetZ="..targetZ) end
  368.         if not goForward(false) then
  369.             -- Critical movement fail, bail
  370.             return false
  371.         end
  372.     end
  373.  
  374.   -- If not at tX==targetX, move the right direction until tX==targetX
  375.     if (tX>targetX) then orient(-1,0) end
  376.     if (tX<targetX) then orient(1,0) end
  377.     while (tX~=targetX) do
  378.         if bDebug then print("moveTo while tX~=targetX tX="..tX.." targetX="..targetX) end
  379.         if not goForward(false) then
  380.             -- Critical movement fail, bail
  381.             return false
  382.         end
  383.     end
  384.  
  385.     while (tY<targetY) do
  386.         if bDebug then print("moveTo while tY<targetY tY="..tY.." targetY="..targetY) end
  387.         if not goUp(false) then
  388.             -- Critical movement fail, bail
  389.             return false
  390.         end
  391.     end
  392.  
  393.     while (tY>targetY) do
  394.         if bDebug then print("moveTo while tY>targetY tY="..tY.." targetY="..targetY) end
  395.         if not goDown(false) then
  396.             -- Critical movement fail, bail
  397.             return false
  398.         end
  399.     end
  400.  
  401.   return true
  402. end
  403.  
  404. function goUnload(bNeedsFuel)
  405.     if bDebug then print("goUnload()") end
  406.     -- Save position and orientation
  407.     local saveX = tX
  408.     local saveZ = tZ
  409.     local saveY = tY
  410.     local saveXdir = xDir
  411.     local saveZdir = zDir
  412.    
  413.     if not goHome() then
  414.     -- Critical failure to move
  415.         return false
  416.     end
  417.    
  418.     orient(0,-1)
  419.    
  420.     -- Drop items. Turtle will not empty the slot designated as the refuel slot.
  421.     for i=1,16 do
  422.         if (i ~= refuelSlot or turtle.getFuelLevel()=="unlimited") then
  423.           turtle.select(i)
  424.           turtle.drop()
  425.         end
  426.     end
  427.    
  428.     orient(0,1)
  429.    
  430.     -- Select first empty slot, might be a now-empty fuel slot, we don't really care
  431.     for i=1,16 do
  432.         if (turtle.getItemCount(i)==0) then
  433.           turtle.select(i)
  434.           break
  435.         end
  436.     end
  437.    
  438.    
  439.     -- Since we had to bring the turtle all the way home, calculate
  440.     -- the fuel needed to get back to where turtle left off mining, do at least one
  441.     -- full layer's worth of work, plus approximately enough to get back home again. It would be
  442.     -- silly to leave base with anything less than that, since the fuel would go nearly all to moving
  443.     -- the turtle through already-mined space doing no work...
  444.     local fuelNeeded = 2 * (math.abs(tX-saveX) + math.abs(tY-saveY) + math.abs(tZ-saveZ)) + (sizeX * sizeZ)
  445.     if not (turtle.getFuelLevel()=="unlimited") then
  446.       while (turtle.getFuelLevel() < fuelNeeded) do
  447.        
  448.         if bDebug then print("Entering while true do in goUnload fuel check stage") end
  449.        
  450.         -- Scan inventory for fuel
  451.         local slot = 1
  452.         turtle.select(slot)
  453.         local bRefueled = false
  454.        
  455.         while true do
  456.             if turtle.refuel(1) then
  457.                 -- Found fuel in current slot, consume 1, see if it's enough, if not loop again
  458.                 print("Consuming fuel item from slot "..slot)
  459.                 if (turtle.getFuelLevel()>=fuelNeeded) then
  460.                     print("Refueled from inventory, resuming quarrying...")
  461.                     bRefueled = true
  462.                     break
  463.                 end
  464.             else
  465.                 -- Couldn't refuel from currently-selected slot, try next slot. If there are no more slots, ask for player help.
  466.                 if (slot < 16) then
  467.                     slot = slot + 1
  468.                     turtle.select(slot)
  469.                 else
  470.                     -- There are no more slots to look in, reset selection so that we're ready to loop over all slots again, and so that the
  471.                     slot = 1
  472.                     break
  473.                 end
  474.             end
  475.         end
  476.        
  477.         if not bRefueled then
  478.             turtle.select(1)
  479.             print("Please add more fuel items to the turtle and press any key. Has:"..turtle.getFuelLevel().." Needs:"..fuelNeeded)
  480.             os.pullEvent("key")    -- suspend code execution awaiting user keypress
  481.         end
  482.       end
  483.     end
  484.     if not moveTo(saveX,saveZ,saveY) then
  485.         -- Critical failure to move
  486.         return false
  487.     end
  488.    
  489.     orient(saveXdir,saveZdir)
  490.    
  491.     return true
  492. end
  493.  
  494. local function checkFreeSlot()
  495.   -- This function will return true if the designated refuelSlot is empty, because if there is no fuel reserve there, there
  496.   -- is no reason not to allow item collection into this slot.
  497.     for i=1,16 do
  498.         if turtle.getItemCount(i)==0 then
  499.           return true
  500.         end
  501.     end
  502.  
  503.   -- Turtle does not have empty slot, goUnload
  504.     if not goUnload() then
  505.         return false
  506.     end
  507.  
  508.     return true
  509. end
  510.  
  511. --[[
  512.  
  513.   START OF THE MAIN PROGRAM
  514.  
  515. --]]
  516.  
  517. checkFreeSlot()
  518.  
  519. local abort = false
  520. local traversal = 1 -- Counts x-z layers we're rasterizing. Used to determine turning directions at end of columns and layers
  521. local lowestY = 1-sizeY
  522. local bDigBelow, bDigAbove = false, false -- initially false
  523. while true do -- This loops digging layers
  524.   print("Main loop traversal="..traversal.." tY="..tY.." lowestY="..lowestY)
  525.  
  526.   if (traversal==1) then --special case since turtle initially starts NOT on a layer that it just dug out.
  527.     if ((tY - lowestY) == 0) then
  528.         bDigBelow, bDigAbove = false, false
  529.     elseif ((tY - lowestY) == 1) then
  530.         bDigBelow, bDigAbove = true, false
  531.     elseif ((tY - lowestY) >= 2) then
  532.         bDigBelow, bDigAbove = true, true
  533.         if not goDown() then
  534.           -- Turtle can't dig down, adjust lowestY because we can't go as deep as planned
  535.           lowestY = tY - 1
  536.         end
  537.     else
  538.         -- Error: turtle is not in an expected place
  539.         print("Error: Turtle vertical position is not what we expect on 1st traversal. Aborting, please debug.")
  540.         abort = true
  541.         break
  542.     end
  543.   else
  544.     -- Not our first traversal, and turtle should now be on the last layer it dug out.
  545.     if ((tY - lowestY) == 1) then
  546.         bDigBelow, bDigAbove = true, false
  547.     elseif ((tY - lowestY) == 2) then
  548.         bDigBelow, bDigAbove = true, false
  549.         if not goDown() then
  550.           -- Turtle can't go down, adjust lowestY because we can't go as deep as planned
  551.           lowestY = tY - 1
  552.         end
  553.     elseif ((tY - lowestY) >= 3) then
  554.         bDigBelow, bDigAbove = true, true
  555.         -- Try to descend 2, if either fails, adjust lowestY to just below where turtle is able to get to, and
  556.         -- cancel the need to digAbove
  557.         for j=1,2 do
  558.             if not goDown() then
  559.               -- Turtle can't dig down, adjust lowestY because we can't go as deep as planned
  560.               lowestY = tY - 1
  561.               bDigAbove = false
  562.             end
  563.         end
  564.     else
  565.         -- Error: turtle is not in an expected place
  566.         print("Error: Turtle vertical position is not what we expect on traversal>1. Aborting, please debug.")
  567.         abort = true
  568.         break
  569.     end
  570.   end
  571.  
  572.  
  573.  
  574.   for column=1,sizeX  do  -- This loops sizeX times digging out columns
  575.     for block=1,(sizeZ-1) do -- this loops (sizeZ-1) times doing digDown and goForward to do all but the end of each column
  576.      
  577.       -- Since we're about to do a potentially ore-digging move, check for free space in inventory.
  578.       -- hasFreeSlot() calls goUnload if necessary
  579.       if not checkFreeSlot() then
  580.         print("Error: checkFreeSlot failure.")
  581.         abort = true
  582.         break
  583.       end
  584.      
  585.       if bDigBelow and turtle.detectDown() then
  586.         if not turtle.digDown() then
  587.           -- Turtle can't dig down, but we're not moving down so this is not a fatal error.
  588.           -- It might be bedrock below turtle, but that's not a concern until turtle is level with it.
  589.         end
  590.       end
  591.      
  592.       if bDigAbove and turtle.detectUp() then
  593.         if not turtle.digUp() then
  594.           -- Turtle can't dig up. This is actually concerning since we don't want to get him trapped under bedrock.
  595.           -- Because of the danger of entrapment, we're ending our quarrying here.
  596.           print("Turtle below undiggable block, backing out and returning home.")
  597.           turnRight()
  598.           turnRight()
  599.           if not goForward() then
  600.             -- This failure we care about, because there is something blocking us that we
  601.             -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
  602.             print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
  603.           end
  604.           abort = true
  605.           break
  606.         end
  607.         sleep(0.5) -- wait to see if anything falls on turtle from above (sand, gravel)
  608.        
  609.         -- First dig up was successful, so we haven't got an undiggable block above, and undiggables can't fall, so we can
  610.         -- safely loop trying to dig up as long as something is falling on us (gravel, sand)
  611.         while turtle.detectUp() do
  612.             if bDebug then print("in while turtrle.detectUp() loop.") end
  613.             if not turtle.digUp() then
  614.                 -- whatever is up there, we couldn't dig it, but it's not bedrock. Just move on...
  615.                 break
  616.             end
  617.             sleep(0.5)
  618.         end
  619.       end
  620.      
  621.       if not goForward() then
  622.         -- This failure we care about, because there is something blocking us that we
  623.         -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
  624.         -- after first checking to be sure the turtle is not under bedrock (if digging above)
  625.         print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
  626.         abort = true
  627.         break
  628.       end
  629.     end -- end of block loop
  630.    
  631.     -- If movement failed while traversing column, escape out, backing out from under bedrock if needed
  632.     if abort then
  633.       if bDigAbove and turtle.detectUp() then
  634.         if not turtle.digUp() then
  635.           -- Turtle can't dig up. This is actually concerning since we don't want to get him trapped under bedrock.
  636.           -- Because of the danger of entrapment, we're ending our quarrying here.
  637.           print("Turtle below undiggable block, backing out and returning home.")
  638.           turnRight()
  639.           turnRight()
  640.           if not goForward() then
  641.             -- This failure we care about, because there is something blocking us that we
  642.             -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
  643.             print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
  644.           end
  645.         end
  646.       end
  647.    
  648.       -- unwinding
  649.       break
  650.     end
  651.    
  652.     -- Dig out the last block of this column
  653.     if bDigBelow and turtle.detectDown() then
  654.       if not turtle.digDown() then
  655.         -- Turtle can't dig down, but we're not moving down so this is not a fatal error.
  656.         -- It might be bedrock below turtle, but that's not a concern until turtle is level with it.
  657.       end
  658.     end
  659.    
  660.     -- Do last digUp in this column, if required by bDigAbove
  661.     if bDigAbove and turtle.detectUp() then
  662.         if not turtle.digUp() then
  663.           -- Turtle can't dig up. This is actually concerning since we don't want to get him trapped under bedrock.
  664.           -- Because of the danger of entrapment, we're ending our quarrying here.
  665.           print("Turtle below undiggable block, backing out and returning home.")
  666.           turnRight()
  667.           turnRight()
  668.           if not goForward() then
  669.             -- This failure we care about, because there is something blocking us that we
  670.             -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
  671.             print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
  672.           end
  673.           abort = true
  674.           break
  675.         end
  676.         sleep(0.5) -- wait to see if anything falls on turtle from above (sand, gravel)
  677.        
  678.         -- First dig up was successful, so we haven't got an undiggable block above, and undiggables can't fall, so we can
  679.         -- safely loop trying to dig up as long as something is falling on us (gravel, sand)
  680.         while turtle.detectUp() do
  681.             if bDebug then print("in while turtrle.detectUp() loop.") end
  682.             if not turtle.digUp() then
  683.                 -- whatever is up there, we couldn't dig it, but it's not bedrock. Just move on...
  684.                 break
  685.             end
  686.             sleep(0.5)
  687.         end
  688.     end
  689.    
  690.     -- Turtle just finished the column, figure out if we need to advance to a new column, or
  691.     -- if we've finished the layer. If we need to turn to start a new column, we have to figure out which
  692.     -- direction to turn
  693.     if (column<sizeX) then
  694.       -- Turtle is at the end of a z column, but not the end of the whole x-z layer traversal
  695.      
  696.       -- FYI: These odd/even values are based on 1-based block, column, traversal numbers not 0-based tX, tZ, tY
  697.       -- sorry if that's confusing, but Lua convention is to start loop indicies at 1
  698.       local evenCol = ((column%2)==0)
  699.       local evenWidth = ((sizeX%2)==0)
  700.       local evenLayer = ((traversal%2)==0)
  701.       local backtrackingLayer = (evenWidth and evenLayer)
  702.      
  703.       if ((not evenCol and not backtrackingLayer) or (evenCol and backtrackingLayer)) then
  704.         turnRight() -- turn towards next row
  705.         if not goForward() then
  706.           print("Fatal Error during goForward from column "..column.." to column "..(column+1).." tX="..tX.." tZ="..tZ.." tY="..tY)
  707.           abort = true
  708.           break
  709.         end
  710.        
  711.         -- Danger check to see if we've moved under an undiggable block
  712.         if bDigAbove and turtle.detectUp() and not turtle.digUp() then
  713.           print("Turtle below undiggable block, backing out 1 and returning home.")
  714.           turnRight()
  715.           turnRight()
  716.           if not goForward() then
  717.             -- This failure we care about, because there is something blocking us that we
  718.             -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
  719.             print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
  720.           end
  721.           abort = true
  722.           break
  723.         end
  724.        
  725.         turnRight()
  726.       else
  727.         turnLeft()
  728.         if not goForward() then
  729.           print("Fatal Error during goForward from column "..column.." to column "..(column+1).." tX="..tX.." tZ="..tZ.." tY="..tY)
  730.           abort = true
  731.           break
  732.         end
  733.        
  734.         -- Danger check to see if we've moved under an undiggable block
  735.         if bDigAbove and turtle.detectUp() and not turtle.digUp() then
  736.           print("Turtle below undiggable block, backing out 1 and returning home.")
  737.           turnRight()
  738.           turnRight()
  739.           if not goForward() then
  740.             -- This failure we care about, because there is something blocking us that we
  741.             -- can't dig, attack or otherwise resolve. Bust out of our digging loops and attempt to return home
  742.             print("Fatal Error during column goForward tX="..tX.." tZ="..tZ.." tY="..tY)
  743.           end
  744.           abort = true
  745.           break
  746.         end
  747.        
  748.         turnLeft()
  749.       end
  750.       -- Turtle is now ready to start the next column
  751.     else
  752.       -- Turtle is at the end of the layer, rotate 180
  753.       turnRight()
  754.       turnRight()
  755.     end
  756.   end -- end of column loop
  757.  
  758.   if abort then
  759.     print("Abort breaking out of while true loop.")
  760.     -- abort in progress, unwinding out of loops
  761.     break
  762.   end
  763.  
  764.   -- See if we're done yet
  765.   if ((tY - lowestY) == 0) or (((tY - lowestY) == 1) and (bDigBelow == true)) then
  766.     -- We're done. We've finished digging our lowest layer either by digging forward or with digDown.
  767.     done = true
  768.     break
  769.   end
  770.  
  771.   -- If we got past the last if-then, we are not done, so we need to descend in preparation for next layer traversal
  772.   if bDigBelow then
  773.     -- We were digging below us on the traversal we just finished, so we need to drop down 2 levels to be on an undug layer
  774.     -- First we try to descend through the dug-down layer, but since that could have bedrock (we we skimming above it not caring)
  775.     -- we need to test to see if we can descend into that layer at our current tX,tZ location
  776.     if not goDown() then
  777.       print("Turtle finished a traversal and was digging below. Turtle can't go further down, we're done quarrying.")
  778.       abort = true
  779.       break
  780.     end
  781.   end
  782.  
  783.   traversal = traversal + 1
  784. end -- end of while not done loop
  785.  
  786. -- Quarrying ended, either normally or because of encountering undiggable block. Try to return to 0,0,0
  787. if not goHome(0,0,0) then
  788.   -- Can't even get back home :-( Notify the user
  789.   print("Turtle was not able to safely get back to starting location")
  790.   abort = true
  791. else
  792.     orient(0,-1)
  793.  
  794.     -- Drop everything
  795.     -- Drop items. Turtle will not empty the slot designated as the refuel slot.
  796.   print("Unloading all contents...")
  797.     for i=1,16 do
  798.         turtle.select(i)
  799.         turtle.drop()
  800.     end
  801.     orient(0,1)
  802. end
  803.  
  804. if abort then
  805.   print("Quarrying ended due to encounter with undiggable block.")
  806. else
  807.   print("Quarrying complete to desired depth.")
  808. end
Advertisement
Add Comment
Please, Sign In to add comment