Guest User

OreQuarry modifed

a guest
May 27th, 2013
980
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 66.79 KB | None | 0 0
  1. -- ********************************************************************************** --
  2. -- **                                                                              ** --
  3. -- **   Minecraft Mining Turtle Ore Quarry v0.7 by AustinKK                        ** --
  4. -- **   ---------------------------------------------------                        ** --
  5. -- **                                                                              ** --
  6. -- **   For instructions on how to use:                                            ** --
  7. -- **                                                                              ** --
  8. -- **     http://www.youtube.com/watch?v=PIugLVzUz3g                               ** --
  9. -- **                                                                              ** --
  10. -- **  Change Log:                                                                 ** --
  11. -- **    27th Dec 2012: [v0.2] Initial Draft Release                               ** --
  12. -- **    29th Dec 2012: [v0.3] Minor Performance Improvements                      ** --
  13. -- **    30th Dec 2012: [v0.4] Further Performance Improvements                    ** --
  14. -- **    9th  Jan 2013: [v0.5] Debug Version (dropping off chest)                  ** --
  15. -- **    10th Jan 2013: [v0.51] Further Debug (dropping off chest)                 ** --
  16. -- **    10th Jan 2013: [v0.52] Fix for dropping off chest bug                     ** --
  17. -- **    11th Jan 2013: [v0.53] Fix for dropping off chest bug (release)           ** --
  18. -- **    12th Jan 2013: [v0.6] Added support for resume                            ** --
  19. -- **    31st Mar 2013: [v0.7] Fixes for ComputerCraft v1.52                       ** --
  20. -- **    31st Mar 2013: [v0.7.1] add unlim.coal fuel, add RemoveNoisedBlocks,      ** --
  21. -- **                           add wait RS, GPS control                           ** --             ** --
  22. -- ********************************************************************************** --
  23.  
  24. -- Enumeration to store the the different types of message that can be written
  25. messageLevel = { DEBUG=0, INFO=1, WARNING=2, ERROR=3, FATAL=4 }
  26.  
  27. -- Enumeration to store names for the 6 directions
  28. direction = { FORWARD=0, RIGHT=1, BACK=2, LEFT=3, UP=4, DOWN=5 }
  29.  
  30. -- Enumeration of mining states
  31. miningState = { START=0, LAYER=1, EMPTYCHESTDOWN=2, EMPTYINVENTORY=3 }
  32.  
  33. local messageOutputLevel = messageLevel.INFO
  34. local messageOutputFileName
  35. local fuelLevelToRefuelAt = 5
  36. local refuelItemsToUseWhenRefuelling = 63
  37. local emergencyFuelToRetain = 0
  38. local maximumGravelStackSupported = 25 -- The number of stacked gravel or sand blocks supported
  39. local noiseBlocksCount
  40. local bottomLayer = 5 -- The y co-ords of the layer immediately above bedrock
  41. local returningToStart = false
  42. local lookForChests = false -- Determines if chests should be located as part of the quarrying
  43. local useEnderChest = false
  44. local miningOffset -- The offset to the mining layer. This is set depending on whether chests are being looked for or not
  45. local lastEmptySlot -- The last inventory slot that was empty when the program started (is either 15 if not looking for chests or 14 if we are)
  46. local turtleId
  47. local isWirelessTurtle
  48. local currentlySelectedSlot = 0 -- The slot that the last noise block was found in
  49. local lastMoveNeededDig = true -- Determines whether the last move needed a dig first
  50. local haveBeenAtZeroZeroOnLayer -- Determines whether the turtle has been at (0, 0) in this mining layer
  51. local orientationAtZeroZero -- The turtle's orientation when it was at (0, 0)
  52. local levelToReturnTo -- The level that the turtle should return to in order to head back to the start to unload
  53.  
  54. -- Variables used to support a resume
  55. local startupParamsFile = "OreQuarryParams.txt"
  56. local oreQuarryLocation = "OreQuarryLocation.txt"
  57. local returnToStartFile = "OreQuarryReturn.txt"
  58. local startupBackup = "startup_bak"
  59. local supportResume = false -- Determines whether the turtle is being run in the mode that supports resume
  60. local resuming = false -- Determines whether the turtle is currently in the process of resuming
  61. local resumeX
  62. local resumeY
  63. local resumeZ
  64. local resumeOrient
  65. local resumeMiningState
  66.  
  67. -- Variables to store the current location and orientation of the turtle. x is right, left, y is up, down and
  68. -- z is forward, back with relation to the starting orientation. Y is the actual turtle level, x and z are
  69. -- in relation to the starting point (i.e. the starting point is (0, 0))
  70. local currX
  71. local currY
  72. local currZ
  73. local currOrient
  74. local currMiningState = miningState.START
  75.  
  76. -- Command line parameters
  77. local startHeight -- Represents the height (y co-ord) that the turtle started at
  78. local quarryWidth -- Represents the length of the mines that the turtle will dig
  79.  
  80. function back()
  81.    if sw == true then
  82.    print("Back...")
  83.    local tidc
  84.    if os.getComputerLabel() == tidc then
  85.    tid = "nil"
  86.    else
  87.    tid = os.getComputerLabel()
  88.    end
  89.    rednet.broadcast(tid..": I am back!")
  90.    returnToStartAndUnload(true)
  91.    end
  92. end
  93.  
  94. function stop() --Ability to stop turtle mid-excavation. This will wait until current action is done, then exit the excavate function
  95.    local tidc
  96.    if os.getComputerLabel() == tidc then
  97.    tid = "nil"
  98.    else
  99.    tid = os.getComputerLabel()
  100.    end
  101.         while true do
  102.           id,m,dl = rednet.receive()
  103.           if m == "back" then
  104.           sw = true
  105.           end
  106.           if m == "fuel" then
  107.           fl = turtle.getFuelLevel()
  108.           flc = turtle.getItemCount(16)
  109.           rednet.broadcast(tid..": "..fl.."("..flc..")")
  110.           end
  111.         end
  112. end
  113. -- ********************************************************************************** --
  114. -- Writes an output message
  115. -- ********************************************************************************** --
  116. function writeMessage(message, msgLevel)
  117.   if msgLevel ~= nil and (msgLevel >= messageOutputLevel) then
  118.     print(message)
  119.  
  120.     -- If this turtle has a modem, then write the message to red net
  121.     if (isWirelessTurtle == true) then
  122.       if (turtleId == nil) then
  123.         rednet.broadcast(message)
  124.       else
  125.         -- Broadcast the message (prefixed with the turtle's id)
  126.         rednet.broadcast("[".. turtleId.."] "..message)
  127.       end
  128.     end
  129.  
  130.     if (messageOutputFileName ~= nil) then
  131.       -- Open file, write message and close file (flush doesn't seem to work!)
  132.       local outputFile = io.open(messageOutputFileName, "a")
  133.       outputFile:write(message)
  134.       outputFile:write("\n")
  135.       outputFile:close()
  136.     end
  137.   end
  138. end
  139.  
  140. -- ********************************************************************************** --
  141. -- Ensures that the turtle has fuel
  142. -- ********************************************************************************** --
  143. function getfuel()
  144. if turtle.getItemCount(16) < 30 then
  145.   turtle.select(16)
  146.   for gf=1,15 do
  147.     if turtle.compareTo(gf) then
  148.       turtle.select(gf)
  149.       turtle.transferTo(16,63)
  150.       turtle.select(16)
  151.     end
  152.   end
  153. end
  154. turtle.select(1)
  155. end
  156. function ensureFuel()
  157.  
  158.   -- Determine whether a refuel is required
  159.   local fuelLevel = turtle.getFuelLevel()
  160.   if (fuelLevel ~= "unlimited") then
  161.     if (fuelLevel < fuelLevelToRefuelAt) then
  162.       -- Need to refuel
  163.       turtle.select(16)
  164.       currentlySelectedSlot = 16
  165.       local fuelItems = turtle.getItemCount(16)
  166.  
  167.       -- Do we need to impact the emergency fuel to continue? (always  
  168.       -- keep one fuel item in slot 16)
  169.       if (fuelItems == 0) then
  170.         writeMessage("Completely out of fuel!", messageLevel.FATAL)
  171.       elseif (fuelItems == 1) then
  172.         writeMessage("Out of Fuel!", messageLevel.ERROR)
  173.         turtle.refuel()
  174.       elseif (fuelItems <= (emergencyFuelToRetain + 1)) then
  175.         writeMessage("Consuming emergency fuel supply. "..(fuelItems - 2).." emergency fuel items remain", messageLevel.WARNING)
  176.         turtle.refuel(1)
  177.       else
  178.         -- Refuel the lesser of the refuelItemsToUseWhenRefuelling and the number of items more than
  179.         -- the emergency fuel level
  180.         if (fuelItems - (emergencyFuelToRetain + 1) < refuelItemsToUseWhenRefuelling) then
  181.           turtle.refuel(fuelItems - (emergencyFuelToRetain + 1))
  182.         else
  183.           turtle.refuel(refuelItemsToUseWhenRefuelling)
  184.         end
  185.       end
  186.     end
  187.   end
  188. end        
  189.  
  190. -- ********************************************************************************** --
  191. -- Checks that the turtle has inventory space by checking for spare slots and returning
  192. -- to the starting point to empty out if it doesn't.
  193. --
  194. -- Takes the position required to move to in order to empty the turtle's inventory
  195. -- should it be full as arguments
  196. -- ********************************************************************************** --
  197. function clearNoiseBlocks(unl)
  198. if unl==false then
  199.   for noiseb=1,noiseBlocksCount do
  200.     if turtle.getItemCount(noiseb) >60 then
  201.       turtle.select(noiseb)
  202.       turtle.drop(turtle.getItemCount(noiseb)-1)
  203.     end
  204.   end
  205. else
  206.   for noiseb=1,noiseBlocksCount do
  207.     if turtle.getItemCount(noiseb) >1 then
  208.       turtle.select(noiseb)
  209.       turtle.dropUp(turtle.getItemCount(noiseb)-1)
  210.     end
  211.   end
  212. end
  213. end
  214. function ensureInventorySpace()
  215.  
  216.   -- If already returning to start, then don't need to do anything
  217.   if (returningToStart == false) then
  218.  
  219.     -- If the last inventory slot is full, then need to return to the start and empty
  220.     if (turtle.getItemCount(lastEmptySlot) > 0) then
  221.  
  222.       -- Return to the starting point and empty the inventory, then go back to mining
  223.     if useEnderChest == false then
  224.       returnToStartAndUnload(true)
  225.     else
  226.       emptyIntoEnderChest()
  227.     end
  228.   end
  229. end
  230. end
  231. function unloadInventory(dropFn,refuel)
  232.   -- Empty the inventory
  233.   local slotLoop = 1
  234.   local endSlot = 16
  235.   if useEnderChest then
  236.     endSlot = 15
  237.   end
  238.  
  239.   -- Loop over each of the slots (except the 16th one which stores fuel)
  240.   while (slotLoop < endSlot) do
  241.     -- If this is one of the slots that contains a noise block, empty all blocks except
  242.     -- one
  243.     turtle.select(slotLoop) -- Don't bother updating selected slot variable as it will set later in this function
  244.     if ((slotLoop <= noiseBlocksCount) or ((slotLoop == 15) and (lastEmptySlot == 14))) then
  245.       writeMessage("Dropping (n-1) from slot "..slotLoop.." ["..turtle.getItemCount(slotLoop).."]", messageLevel.DEBUG)  
  246.       if (turtle.getItemCount(slotLoop) > 0) then
  247.         dropFn(turtle.getItemCount(slotLoop) - 1)
  248.       end
  249.     else
  250.       -- Not a noise block, drop all of the items in this slot
  251.       writeMessage("Dropping (all) from slot "..slotLoop.." ["..turtle.getItemCount(slotLoop).."]", messageLevel.DEBUG)
  252.       if (turtle.getItemCount(slotLoop) > 0) then
  253.         dropFn()
  254.       end
  255.     end
  256.  
  257.     slotLoop = slotLoop + 1
  258.   end
  259.  
  260.   while (rs.getInput("front") == true) or (rs.getInput("left") == true) or (rs.getInput("right") == true) or (rs.getInput("back") == true) do
  261.   sleep(1)
  262.   end
  263.  
  264.   -- While we are here, refill the fuel items if there is capacity
  265.   if (turtle.getItemCount(16) < 64) and refuel then
  266.     turtleSetOrientation(direction.LEFT)
  267.     turtle.select(16) -- Don't bother updating selected slot variable as it will set later in this function
  268.     local currFuelItems = turtle.getItemCount(16)
  269.     turtle.suck()
  270.     while ((currFuelItems ~= turtle.getItemCount(16)) and (turtle.getItemCount(16) < 64)) do
  271.       currFuelItems = turtle.getItemCount(16)
  272.       turtle.suck()
  273.     end
  274.  
  275.     slotLoop = noiseBlocksCount + 1
  276.     -- Have now picked up all the items that we can. If we have also picked up some
  277.     -- additional fuel in some of the other slots, then drop it again
  278.     while (slotLoop <= lastEmptySlot) do
  279.       -- Drop any items found in this slot
  280.       if (turtle.getItemCount(slotLoop) > 0) then
  281.         turtle.select(slotLoop) -- Don't bother updating selected slot variable as it will set later in this function
  282.         turtle.drop()
  283.       end
  284.       slotLoop = slotLoop + 1
  285.     end
  286.   end
  287.  
  288.   -- Select the 1st slot because sometimes when leaving the 15th or 16th slots selected it can result
  289.   -- in that slot being immediately filled (resulting in the turtle returning to base again too soon)
  290.   turtle.select(1)
  291.   currentlySelectedSlot = 1
  292. end
  293.  
  294. -- ********************************************************************************** --
  295. -- Empties the turtle's inventory into an ender chest
  296. -- ********************************************************************************** --
  297. function emptyIntoEnderChest()
  298.   writeMessage("Emptying into ender chest...", messageLevel.DEBUG)
  299.  
  300.   -- select the slot containing the ender chest
  301.   turtle.select(15)
  302.   currentlySelectedSlot = 15
  303.   -- Make sure the block above us is empty
  304.   -- and place the ender chest
  305.   while not turtle.placeUp() do
  306.     turtle.digUp()
  307.     sleep(0.5)
  308.   end
  309.  
  310.   -- unload
  311.   getfuel()
  312.   clearNoiseBlocks(true)
  313.   unloadInventory(turtle.dropUp,false)
  314.  
  315.   -- break ender chest
  316.   turtle.select(15)
  317.   turtle.digUp()
  318.  
  319.   -- select slot 1 again
  320.   turtle.select(1)
  321.   currentlySelectedSlot = 1
  322. end
  323.  
  324. -- ********************************************************************************** --
  325. -- Function to move to the starting point, call a function that is passed in
  326. -- and return to the same location (if required)
  327. -- ********************************************************************************** --
  328. function returnToStartAndUnload(returnBackToMiningPoint)
  329.  
  330.   writeMessage("returnToStartAndUnload called", messageLevel.DEBUG)
  331.   returningToStart = true
  332.   local storedX, storedY, storedZ, storedOrient
  333.   local prevMiningState = currMiningState
  334.  
  335.   if (resuming == true) then
  336.     -- Get the stored parameters from the necessary file
  337.     local resumeFile = fs.open(returnToStartFile, "r")
  338.     if (resumeFile ~= nil) then
  339.       -- Restore the parameters from the file
  340.       local beenAtZero = resumeFile.readLine()
  341.       if (beenAtZero == "y") then
  342.         haveBeenAtZeroZeroOnLayer = true
  343.       else
  344.         haveBeenAtZeroZeroOnLayer = false
  345.       end
  346.  
  347.       local miningPointFlag = resumeFile.readLine()
  348.       if (miningPointFlag == "y") then
  349.         returnBackToMiningPoint = true
  350.       else
  351.         returnBackToMiningPoint = false
  352.       end
  353.  
  354.       currX = readNumber(resumeFile)
  355.       currY = readNumber(resumeFile)
  356.       currZ = readNumber(resumeFile)
  357.       currOrient = readNumber(resumeFile)
  358.       levelToReturnTo = readNumber(resumeFile)
  359.       prevMiningState = readNumber(resumeFile)
  360.       orientationAtZeroZero = readNumber(resumeFile)
  361.       resumeFile.close()
  362.  
  363.     else
  364.       writeMessage("Failed to read return to start file", messageLevel.ERROR)
  365.     end
  366.   elseif (supportResume == true) then
  367.  
  368.     local outputFile = io.open(returnToStartFile, "w")
  369.  
  370.     if (haveBeenAtZeroZeroOnLayer == true) then
  371.       outputFile:write("y\n")
  372.     else
  373.       outputFile:write("n\n")
  374.     end
  375.     if (returnBackToMiningPoint == true) then
  376.       outputFile:write("y\n")
  377.     else
  378.       outputFile:write("n\n")
  379.     end
  380.  
  381.     outputFile:write(currX)
  382.     outputFile:write("\n")
  383.     outputFile:write(currY)
  384.     outputFile:write("\n")
  385.     outputFile:write(currZ)
  386.     outputFile:write("\n")
  387.     outputFile:write(currOrient)
  388.     outputFile:write("\n")
  389.     outputFile:write(levelToReturnTo)
  390.     outputFile:write("\n")
  391.     outputFile:write(prevMiningState)
  392.     outputFile:write("\n")
  393.     outputFile:write(orientationAtZeroZero)
  394.     outputFile:write("\n")
  395.  
  396.     outputFile:close()
  397.   end
  398.    
  399.   storedX = currX
  400.   storedY = currY
  401.   storedZ = currZ
  402.   storedOrient = currOrient
  403.  
  404.   -- Store the current location and orientation so that it can be returned to
  405.   currMiningState = miningState.EMPTYINVENTORY
  406.   writeMessage("last item count = "..turtle.getItemCount(lastEmptySlot), messageLevel.DEBUG)
  407.  
  408.   if ((turtle.getItemCount(lastEmptySlot) > 0) or (returnBackToMiningPoint == false)) or (sw == true) then
  409.     if sw == true then sw = false end
  410.     writeMessage("Heading back to surface", messageLevel.DEBUG)
  411.  
  412.     -- Move down to the correct layer to return via
  413.     if (currY > levelToReturnTo) then
  414.       while (currY > levelToReturnTo) do
  415.         turtleDown()
  416.       end
  417.     elseif (currY < levelToReturnTo) then
  418.       while (currY < levelToReturnTo) do
  419.         turtleUp()
  420.       end
  421.     end
  422.  
  423.     if ((haveBeenAtZeroZeroOnLayer == false) or (orientationAtZeroZero == direction.FORWARD)) then
  424.       -- Move back to the correct X position first
  425.       if (currX > 0) then
  426.         turtleSetOrientation(direction.LEFT)
  427.         while (currX > 0) do
  428.           turtleForward()
  429.         end
  430.       elseif (currX < 0) then
  431.         -- This should never happen
  432.         writeMessage("Current x is less than 0 in returnToStartAndUnload", messageLevel.ERROR)
  433.       end
  434.  
  435.       -- Then move back to the correct Z position
  436.       if (currZ > 0) then
  437.         turtleSetOrientation(direction.BACK)
  438.         while (currZ > 0) do
  439.           turtleForward()
  440.         end
  441.       elseif (currZ < 0) then
  442.         -- This should never happen
  443.         writeMessage("Current z is less than 0 in returnToStartAndUnload", messageLevel.ERROR)
  444.       end
  445.     else
  446.       -- Move back to the correct Z position first
  447.       if (currZ > 0) then
  448.         turtleSetOrientation(direction.BACK)
  449.         while (currZ > 0) do
  450.           turtleForward()
  451.         end
  452.       elseif (currZ < 0) then
  453.         -- This should never happen
  454.         writeMessage("Current z is less than 0 in returnToStartAndUnload", messageLevel.ERROR)
  455.       end
  456.  
  457.       -- Then move back to the correct X position
  458.       if (currX > 0) then
  459.         turtleSetOrientation(direction.LEFT)
  460.         while (currX > 0) do
  461.           turtleForward()
  462.         end
  463.       elseif (currX < 0) then
  464.         -- This should never happen
  465.         writeMessage("Current x is less than 0 in returnToStartAndUnload", messageLevel.ERROR)
  466.       end
  467.     end
  468.  
  469.     -- Return to the starting layer
  470.     if (currY < startHeight) then
  471.       while (currY < startHeight) do
  472.         turtleUp()
  473.       end
  474.     elseif (currY > startHeight) then
  475.       -- This should never happen
  476.       writeMessage("Current height is greater than start height in returnToStartAndUnload", messageLevel.ERROR)
  477.     end
  478.  
  479.  
  480.     -- Face the chest
  481.     turtleSetOrientation(direction.BACK)
  482.    
  483.      -- Unload
  484.     getfuel()
  485.     clearNoiseBlocks(true)
  486.     unloadInventory(turtle.drop,true)
  487.   end
  488.  
  489.   -- If required, move back to the point that we were mining at before returning to the start
  490.   if (returnBackToMiningPoint == true) then
  491.  
  492.     -- If resuming, refresh the starting point to be the top of the return shaft
  493.     if (resuming == true) then
  494.       currX = 0
  495.       currY = startHeight
  496.       currZ = 0
  497.       currOrient = resumeOrient
  498.     end
  499.  
  500.     -- Return back to the required layer
  501.     while (currY > levelToReturnTo) do
  502.       turtleDown()
  503.     end
  504.  
  505.     if ((haveBeenAtZeroZeroOnLayer == false) or (orientationAtZeroZero == direction.FORWARD)) then
  506.       -- Move back to the correct Z position first
  507.       writeMessage("Stored Z: "..storedZ..", currZ: "..currZ, messageLevel.DEBUG)
  508.       if (storedZ > currZ) then
  509.         writeMessage("Orienting forward", messageLevel.DEBUG)
  510.         writeMessage("Moving in z direction", messageLevel.DEBUG)
  511.         turtleSetOrientation(direction.FORWARD)
  512.         while (storedZ > currZ) do
  513.           turtleForward()
  514.         end
  515.       elseif (storedZ < currZ) then
  516.         -- This should never happen
  517.         writeMessage("Stored z is less than current z in returnToStartAndUnload", messageLevel.ERROR)
  518.       end
  519.  
  520.       -- Then move back to the correct X position
  521.       if (storedX > currX) then
  522.         writeMessage("Stored X: "..storedX..", currX: "..currX, messageLevel.DEBUG)
  523.         writeMessage("Orienting right", messageLevel.DEBUG)
  524.         writeMessage("Moving in x direction", messageLevel.DEBUG)
  525.         turtleSetOrientation(direction.RIGHT)
  526.         while (storedX > currX) do
  527.           turtleForward()
  528.         end
  529.       elseif (storedX < currX) then
  530.         -- This should never happen
  531.         writeMessage("Stored x is less than current x in returnToStartAndUnload", messageLevel.ERROR)
  532.       end
  533.     else
  534.       -- Move back to the correct X position first
  535.       if (storedX > currX) then
  536.         writeMessage("Stored X: "..storedX..", currX: "..currX, messageLevel.DEBUG)
  537.         writeMessage("Orienting right", messageLevel.DEBUG)
  538.         writeMessage("Moving in x direction", messageLevel.DEBUG)
  539.         turtleSetOrientation(direction.RIGHT)
  540.         while (storedX > currX) do
  541.           turtleForward()
  542.         end
  543.       elseif (storedX < currX) then
  544.         -- This should never happen
  545.         writeMessage("Stored x is less than current x in returnToStartAndUnload", messageLevel.ERROR)
  546.       end
  547.  
  548.       -- Then move back to the correct Z position
  549.       writeMessage("Stored Z: "..storedZ..", currZ: "..currZ, messageLevel.DEBUG)
  550.       if (storedZ > currZ) then
  551.         writeMessage("Orienting forward", messageLevel.DEBUG)
  552.         writeMessage("Moving in z direction", messageLevel.DEBUG)
  553.         turtleSetOrientation(direction.FORWARD)
  554.         while (storedZ > currZ) do
  555.           turtleForward()
  556.         end
  557.       elseif (storedZ < currZ) then
  558.         -- This should never happen
  559.         writeMessage("Stored z is less than current z in returnToStartAndUnload", messageLevel.ERROR)
  560.       end
  561.     end
  562.  
  563.     -- Move back to the correct layer
  564.     if (storedY < currY) then
  565.       while (storedY < currY) do
  566.         turtleDown()
  567.       end
  568.     elseif (storedY > currY) then
  569.       while (storedY > currY) do
  570.         turtleUp()
  571.       end
  572.     end
  573.  
  574.     -- Finally, set the correct orientation
  575.     turtleSetOrientation(storedOrient)
  576.  
  577.     writeMessage("Have returned to the mining point", messageLevel.DEBUG)
  578.   end
  579.  
  580.   -- Store the current location and orientation so that it can be returned to
  581.   currMiningState = prevMiningState
  582.  
  583.   returningToStart = false
  584.  
  585. end
  586.  
  587. -- ********************************************************************************** --
  588. -- Empties a chest's contents
  589. -- ********************************************************************************** --
  590. function emptyChest(suckFn)
  591.  
  592.   local prevInventoryCount = {}
  593.   local inventoryLoop
  594.   local chestEmptied = false
  595.  
  596.   -- Record the number of items in each of the inventory slots
  597.   for inventoryLoop = 1, 16 do
  598.     prevInventoryCount[inventoryLoop] = turtle.getItemCount(inventoryLoop)
  599.   end
  600.  
  601.   while (chestEmptied == false) do
  602.     -- Pick up the next item
  603.     suckFn()
  604.  
  605.     -- Determine the number of items in each of the inventory slots now
  606.     local newInventoryCount = {}
  607.     for inventoryLoop = 1, 16 do
  608.       newInventoryCount[inventoryLoop] = turtle.getItemCount(inventoryLoop)
  609.     end
  610.  
  611.     -- Now, determine whether there have been any items taken from the chest
  612.     local foundDifferentItemCount = false
  613.     inventoryLoop = 1
  614.     while ((foundDifferentItemCount == false) and (inventoryLoop <= 16)) do
  615.       if (prevInventoryCount[inventoryLoop] ~= newInventoryCount[inventoryLoop]) then
  616.         foundDifferentItemCount = true
  617.       else
  618.         inventoryLoop = inventoryLoop + 1
  619.       end
  620.     end
  621.    
  622.     -- If no items have been found with a different item count, then the chest has been emptied
  623.     chestEmptied = not foundDifferentItemCount
  624.  
  625.     if (chestEmptied == false) then
  626.       prevInventoryCount = newInventoryCount
  627.       -- Check that there is sufficient inventory space as may have picked up a block
  628.       ensureInventorySpace()
  629.     end
  630.   end
  631.  
  632.   writeMessage("Finished emptying chest", messageLevel.DEBUG)
  633. end
  634.  
  635. -- ********************************************************************************** --
  636. -- Write the current location to a file
  637. -- ********************************************************************************** --
  638. function saveLocation()
  639.  
  640.   -- Write the x, y, z and orientation to the file
  641.   if ((supportResume == true) and (resuming == false)) then
  642.     local outputFile = io.open(oreQuarryLocation, "w")
  643.     outputFile:write(currMiningState)
  644.     outputFile:write("\n")
  645.     outputFile:write(currX)
  646.     outputFile:write("\n")
  647.     outputFile:write(currY)
  648.     outputFile:write("\n")
  649.     outputFile:write(currZ)
  650.     outputFile:write("\n")
  651.     outputFile:write(currOrient)
  652.     outputFile:write("\n")
  653.     outputFile:close()
  654.   end
  655.  
  656. end
  657.  
  658. -- ********************************************************************************** --
  659. -- If the turtle is resuming and the current co-ordinates, orientation and
  660. -- mining state have been matched, then no longer resuming
  661. -- ********************************************************************************** --
  662. function updateResumingFlag()
  663.  
  664.   if (resuming == true) then
  665.     if ((resumeMiningState == currMiningState) and (resumeX == currX) and (resumeY == currY) and (resumeZ == currZ) and (resumeOrient == currOrient)) then
  666.       resuming = false
  667.     end
  668.   end
  669.  
  670. end
  671.  
  672. -- ********************************************************************************** --
  673. -- Generic function to move the Turtle (pushing through any gravel or other
  674. -- things such as mobs that might get in the way).
  675. --
  676. -- The only thing that should stop the turtle moving is bedrock. Where this is
  677. -- found, the function will return after 15 seconds returning false
  678. -- ********************************************************************************** --
  679. function moveTurtle(moveFn, detectFn, digFn, attackFn, compareFn, suckFn, maxDigCount, newX, newY, newZ)
  680.  
  681.   local moveSuccess = false
  682.  
  683.   -- If we are resuming, then don't do anything in this function other than updating the
  684.   -- co-ordinates as if the turtle had moved
  685.   if (resuming == true) then
  686.     -- Set the move success to true (but don't move) - unless this is below bedrock level
  687.     -- in which case return false
  688.     if (currY <= 0) then
  689.       moveSuccess = false
  690.     else
  691.       moveSuccess = true
  692.     end
  693.  
  694.     -- Update the co-ordinates to reflect the movement
  695.     currX = newX
  696.     currY = newY
  697.     currZ = newZ
  698.  
  699.   else
  700.     local prevX, prevY, prevZ
  701.     prevX = currX
  702.     prevY = currY
  703.     prevZ = currZ
  704.  
  705.     ensureFuel()
  706.  
  707.     -- Flag to determine whether digging has been tried yet. If it has
  708.     -- then pause briefly before digging again to allow sand or gravel to
  709.     -- drop
  710.     local digCount = 0
  711.  
  712.     if (lastMoveNeededDig == false) then
  713.       -- Didn't need to dig last time the turtle moved, so try moving first
  714.  
  715.       currX = newX
  716.       currY = newY
  717.       currZ = newZ
  718.       saveLocation()
  719.  
  720.       moveSuccess = moveFn()
  721.  
  722.       -- If move failed, update the co-ords back to the previous co-ords
  723.       if (moveSuccess == false) then
  724.         currX = prevX
  725.         currY = prevY
  726.         currZ = prevZ
  727.         saveLocation()
  728.       end
  729.  
  730.       -- Don't need to set the last move needed dig. It is already false, if
  731.       -- move success is now true, then it won't be changed
  732.     else    
  733.       -- If we are looking for chests, then check that this isn't a chest before trying to dig it
  734.       if (lookForChests == true) then
  735.         if (isNoiseBlock(compareFn) == false) then
  736.           if (detectFn() == true) then
  737.             -- Determine if it is a chest before digging it
  738.             if (isChestBlock(compareFn) == true) then
  739.               -- Have found a chest, empty it before continuing
  740.               emptyChest (suckFn)
  741.             end
  742.           end
  743.         end
  744.       end
  745.  
  746.       -- Try to dig (without doing a detect as it is quicker)
  747.       local digSuccess = digFn()
  748.       if (digSuccess == true) then
  749.         digCount = 1
  750.       end
  751.  
  752.       currX = newX
  753.       currY = newY
  754.       currZ = newZ
  755.       saveLocation()
  756.  
  757.       moveSuccess = moveFn()
  758.  
  759.       if (moveSuccess == true) then
  760.         lastMoveNeededDig = digSuccess
  761.       else
  762.         currX = prevX
  763.         currY = prevY
  764.         currZ = prevZ
  765.         saveLocation()
  766.       end
  767.  
  768.     end
  769.  
  770.     -- Loop until we've successfully moved
  771.     if (moveSuccess == false) then
  772.       while ((moveSuccess == false) and (digCount < maxDigCount)) do
  773.  
  774.         -- If there is a block in front, dig it
  775.         if (detectFn() == true) then
  776.        
  777.             -- If we've already tried digging, then pause before digging again to let
  778.             -- any sand or gravel drop, otherwise check for a chest before digging
  779.             if(digCount == 0) then
  780.               -- Am about to dig a block - check that it is not a chest if necessary
  781.               -- If we are looking for chests, then check that this isn't a chest before moving
  782.               if (lookForChests == true) then
  783.                 if (isNoiseBlock(compareFn) == false) then
  784.                   if (detectFn() == true) then
  785.                     -- Determine if it is a chest before digging it
  786.                     if (isChestBlock(compareFn) == true) then
  787.                       -- Have found a chest, empty it before continuing
  788.                       emptyChest (suckFn)
  789.                     end
  790.                   end
  791.                 end
  792.               end
  793.             else
  794.               sleep(0.1)
  795.             end
  796.  
  797.             digFn()
  798.             digCount = digCount + 1
  799.         else
  800.            -- Am being stopped from moving by a mob, attack it
  801.            attackFn()
  802.         end
  803.  
  804.         currX = newX
  805.         currY = newY
  806.         currZ = newZ
  807.         saveLocation()
  808.  
  809.         -- Try the move again
  810.         moveSuccess = moveFn()
  811.  
  812.         if (moveSuccess == false) then
  813.           currX = prevX
  814.           currY = prevY
  815.           currZ = prevZ
  816.           saveLocation()
  817.         end
  818.       end
  819.  
  820.       if (digCount == 0) then
  821.         lastMoveNeededDig = false
  822.       else
  823.         lastMoveNeededDig = true
  824.       end
  825.     end
  826.   end
  827.  
  828.   -- If we are resuming and the current co-ordinates and orientation are the resume point
  829.   -- then are no longer resuming
  830.   if (moveSuccess == true) then
  831.     updateResumingFlag()
  832.   end
  833.  
  834.   -- Return the move success
  835.   return moveSuccess
  836.  
  837. end
  838.  
  839. -- ********************************************************************************** --
  840. -- Move the turtle forward one block (updating the turtle's position)
  841. -- ********************************************************************************** --
  842. function turtleForward()
  843.  
  844.   -- Determine the new co-ordinate that the turtle will be moving to
  845.   local newX, newZ
  846.  
  847.   -- Update the current co-ordinates
  848.   if (currOrient == direction.FORWARD) then
  849.     newZ = currZ + 1
  850.     newX = currX
  851.   elseif (currOrient == direction.LEFT) then
  852.     newX = currX - 1
  853.     newZ = currZ
  854.   elseif (currOrient == direction.BACK) then
  855.     newZ = currZ - 1
  856.     newX = currX
  857.   elseif (currOrient == direction.RIGHT) then
  858.     newX = currX + 1
  859.     newZ = currZ
  860.   else
  861.     writeMessage ("Invalid currOrient in turtleForward function", messageLevel.ERROR)
  862.   end
  863.  
  864.   local returnVal = moveTurtle(turtle.forward, turtle.detect, turtle.dig, turtle.attack, turtle.compare, turtle.suck, maximumGravelStackSupported, newX, currY, newZ)
  865.  
  866.   if (returnVal == true) then
  867.     -- Check that there is sufficient inventory space as may have picked up a block
  868.     back()
  869.     clearNoiseBlocks(false)
  870.     ensureInventorySpace()
  871.   end
  872.  
  873.   return returnVal
  874. end
  875.  
  876. -- ********************************************************************************** --
  877. -- Move the turtle up one block (updating the turtle's position)
  878. -- ********************************************************************************** --
  879. function turtleUp()
  880.  
  881.   local returnVal = moveTurtle(turtle.up, turtle.detectUp, turtle.digUp, turtle.attackUp, turtle.compareUp, turtle.suckUp, maximumGravelStackSupported, currX, currY + 1, currZ)
  882.  
  883.   if (returnVal == true) then
  884.     -- Check that there is sufficient inventory space as may have picked up a block
  885.     back()
  886.     clearNoiseBlocks(false)
  887.     ensureInventorySpace()
  888.   end
  889.  
  890.   return returnVal
  891. end
  892.  
  893. -- ********************************************************************************** --
  894. -- Move the turtle down one block (updating the turtle's position)
  895. -- ********************************************************************************** --
  896. function turtleDown()
  897.  
  898.   local returnVal = moveTurtle(turtle.down, turtle.detectDown, turtle.digDown, turtle.attackDown, turtle.compareDown, turtle.suckDown, 1, currX, currY - 1, currZ)
  899.  
  900.   if (returnVal == true) then
  901.     -- Check that there is sufficient inventory space as may have picked up a block
  902.     back()
  903.     clearNoiseBlocks(false)
  904.     ensureInventorySpace()
  905.   end
  906.  
  907.   return returnVal
  908.  
  909. end
  910.  
  911. -- ********************************************************************************** --
  912. -- Move the turtle back one block (updating the turtle's position)
  913. -- ********************************************************************************** --
  914. function turtleBack()
  915.  
  916.   -- Assume that the turtle will move, and switch the co-ords back if it doesn't
  917.   -- (do this so that we can write the co-ords to a file before moving)
  918.   local newX, newZ
  919.   local prevX, prevZ
  920.   prevX = currX
  921.   prevZ = currZ
  922.  
  923.   -- Update the current co-ordinates
  924.   if (currOrient == direction.FORWARD) then
  925.     newZ = currZ - 1
  926.     newX = currX
  927.   elseif (currOrient == direction.LEFT) then
  928.     newX = currX + 1
  929.     newZ = currZ
  930.   elseif (currOrient == direction.BACK) then
  931.     newZ = currZ + 1
  932.     newX = currX
  933.   elseif (currOrient == direction.RIGHT) then
  934.     newX = currX - 1
  935.     newZ = currZ
  936.   else
  937.     writeMessage ("Invalid currOrient in turtleBack function", messageLevel.ERROR)
  938.   end
  939.  
  940.   -- First try to move back using the standard function
  941.  
  942.   currX = newX
  943.   currZ = newZ
  944.   saveLocation()
  945.   local returnVal = turtle.back()
  946.  
  947.   if (returnVal == false) then
  948.     -- Didn't move. Reset the co-ordinates to the previous value
  949.     currX = prevX
  950.     currZ = prevZ
  951.  
  952.     -- Reset the location back to the previous location (because the turn takes 0.8 of a second
  953.     -- so could be stopped before getting to the forward function)
  954.     saveLocation()
  955.  
  956.     turtle.turnRight()
  957.     turtle.turnRight()
  958.  
  959.     -- Try to move by using the forward function (note, the orientation will be set as
  960.     -- the same way as this function started because if the function stops, that is the
  961.     -- direction that we want to consider the turtle to be pointing)
  962.  
  963.     returnVal = moveTurtle(turtle.forward, turtle.detect, turtle.dig, turtle.attack, turtle.compare, turtle.suck, maximumGravelStackSupported, newX, currY, newZ)
  964.  
  965.     turtle.turnRight()
  966.     turtle.turnRight()
  967.   end
  968.  
  969.   if (returnVal == true) then
  970.     -- Check that there is sufficient inventory space as may have picked up a block
  971.     back()
  972.     clearNoiseBlocks(false)
  973.     ensureInventorySpace()
  974.   end
  975.    
  976.   return returnVal
  977. end
  978.  
  979. -- ********************************************************************************** --
  980. -- Turns the turtle (updating the current orientation at the same time)
  981. -- ********************************************************************************** --
  982. function turtleTurn(turnDir)
  983.  
  984.   if (turnDir == direction.LEFT) then
  985.     if (currOrient == direction.FORWARD) then
  986.       currOrient = direction.LEFT
  987.     elseif (currOrient == direction.LEFT) then
  988.       currOrient = direction.BACK
  989.     elseif (currOrient == direction.BACK) then
  990.       currOrient = direction.RIGHT
  991.     elseif (currOrient == direction.RIGHT) then
  992.       currOrient = direction.FORWARD
  993.     else
  994.       writeMessage ("Invalid currOrient in turtleTurn function", messageLevel.ERROR)
  995.     end
  996.  
  997.     -- If we are resuming, just check to see whether have reached the resume point, otherwise
  998.     -- turn
  999.     if (resuming == true) then
  1000.       updateResumingFlag()
  1001.     else
  1002.       -- Write the new orientation and turn
  1003.       saveLocation()
  1004.       turtle.turnLeft()
  1005.     end
  1006.  
  1007.   elseif (turnDir == direction.RIGHT) then
  1008.     if (currOrient == direction.FORWARD) then
  1009.       currOrient = direction.RIGHT
  1010.     elseif (currOrient == direction.LEFT) then
  1011.       currOrient = direction.FORWARD
  1012.     elseif (currOrient == direction.BACK) then
  1013.       currOrient = direction.LEFT
  1014.     elseif (currOrient == direction.RIGHT) then
  1015.       currOrient = direction.BACK
  1016.     else
  1017.       writeMessage ("Invalid currOrient in turtleTurn function", messageLevel.ERROR)
  1018.     end
  1019.  
  1020.     -- If we are resuming, just check to see whether have reached the resume point, otherwise
  1021.     -- turn
  1022.     if (resuming == true) then
  1023.       updateResumingFlag()
  1024.  
  1025.       writeMessage("["..currMiningState..", "..currX..", "..currY..", "..currZ..", "..currOrient.."]", messageLevel.DEBUG)
  1026.     else
  1027.       -- Write the new orientation and turn
  1028.       saveLocation()
  1029.       turtle.turnRight()
  1030.     end
  1031.   else
  1032.     writeMessage ("Invalid turnDir in turtleTurn function", messageLevel.ERROR)
  1033.   end
  1034. end
  1035.  
  1036. -- ********************************************************************************** --
  1037. -- Sets the turtle to a specific orientation, irrespective of its current orientation
  1038. -- ********************************************************************************** --
  1039. function turtleSetOrientation(newOrient)
  1040.  
  1041.   if (currOrient ~= newOrient) then
  1042.     if (currOrient == direction.FORWARD) then
  1043.       if (newOrient == direction.RIGHT) then
  1044.         currOrient = newOrient
  1045.  
  1046.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1047.         if (resuming == true) then
  1048.           updateResumingFlag()
  1049.         else
  1050.           -- Write the new orientation and turn
  1051.           saveLocation()
  1052.           turtle.turnRight()
  1053.         end
  1054.       elseif (newOrient == direction.BACK) then
  1055.         currOrient = newOrient
  1056.  
  1057.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1058.         if (resuming == true) then
  1059.           updateResumingFlag()
  1060.         else
  1061.           -- Write the new orientation and turn
  1062.           saveLocation()
  1063.           turtle.turnRight()
  1064.           turtle.turnRight()
  1065.         end
  1066.       elseif (newOrient == direction.LEFT) then
  1067.         currOrient = newOrient
  1068.  
  1069.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1070.         if (resuming == true) then
  1071.           updateResumingFlag()
  1072.         else
  1073.           -- Write the new orientation and turn
  1074.           saveLocation()
  1075.           turtle.turnLeft()
  1076.         end
  1077.       else
  1078.         writeMessage ("Invalid newOrient in turtleSetOrientation function", messageLevel.ERROR)
  1079.       end
  1080.     elseif (currOrient == direction.RIGHT) then
  1081.       if (newOrient == direction.BACK) then
  1082.         currOrient = newOrient
  1083.  
  1084.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1085.         if (resuming == true) then
  1086.           updateResumingFlag()
  1087.         else
  1088.           -- Write the new orientation and turn
  1089.           saveLocation()
  1090.           turtle.turnRight()
  1091.         end
  1092.       elseif (newOrient == direction.LEFT) then
  1093.         currOrient = newOrient
  1094.  
  1095.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1096.         if (resuming == true) then
  1097.           updateResumingFlag()
  1098.         else
  1099.           -- Write the new orientation and turn
  1100.           saveLocation()
  1101.           turtle.turnRight()
  1102.           turtle.turnRight()
  1103.         end
  1104.       elseif (newOrient == direction.FORWARD) then
  1105.         currOrient = newOrient
  1106.  
  1107.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1108.         if (resuming == true) then
  1109.           updateResumingFlag()
  1110.         else
  1111.           -- Write the new orientation and turn
  1112.           saveLocation()
  1113.           turtle.turnLeft()
  1114.         end
  1115.       else
  1116.         writeMessage ("Invalid newOrient in turtleSetOrientation function", messageLevel.ERROR)
  1117.       end
  1118.     elseif (currOrient == direction.BACK) then
  1119.       if (newOrient == direction.LEFT) then
  1120.         currOrient = newOrient
  1121.  
  1122.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1123.         if (resuming == true) then
  1124.           updateResumingFlag()
  1125.         else
  1126.           -- Write the new orientation and turn
  1127.           saveLocation()
  1128.           turtle.turnRight()
  1129.         end
  1130.       elseif (newOrient == direction.FORWARD) then
  1131.         currOrient = newOrient
  1132.  
  1133.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1134.         if (resuming == true) then
  1135.           updateResumingFlag()
  1136.         else
  1137.           -- Write the new orientation and turn
  1138.           saveLocation()
  1139.           turtle.turnRight()
  1140.           turtle.turnRight()
  1141.         end
  1142.       elseif (newOrient == direction.RIGHT) then
  1143.         currOrient = newOrient
  1144.  
  1145.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1146.         if (resuming == true) then
  1147.           updateResumingFlag()
  1148.         else
  1149.           -- Write the new orientation and turn
  1150.           saveLocation()
  1151.           turtle.turnLeft()
  1152.         end
  1153.       else
  1154.         writeMessage ("Invalid newOrient in turtleSetOrientation function", messageLevel.ERROR)
  1155.       end
  1156.     elseif (currOrient == direction.LEFT) then
  1157.       if (newOrient == direction.FORWARD) then
  1158.         currOrient = newOrient
  1159.  
  1160.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1161.         if (resuming == true) then
  1162.           updateResumingFlag()
  1163.         else
  1164.           -- Write the new orientation and turn
  1165.           saveLocation()
  1166.           turtle.turnRight()
  1167.         end
  1168.       elseif (newOrient == direction.RIGHT) then
  1169.         currOrient = newOrient
  1170.  
  1171.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1172.         if (resuming == true) then
  1173.           updateResumingFlag()
  1174.         else
  1175.           -- Write the new orientation and turn
  1176.           saveLocation()
  1177.           turtle.turnRight()
  1178.           turtle.turnRight()
  1179.         end
  1180.       elseif (newOrient == direction.BACK) then
  1181.         currOrient = newOrient
  1182.  
  1183.         -- If resuming, check whether the resume point has been reached, otherwise turn
  1184.         if (resuming == true) then
  1185.           updateResumingFlag()
  1186.         else
  1187.           -- Write the new orientation and turn
  1188.           saveLocation()
  1189.           turtle.turnLeft()
  1190.         end
  1191.       else
  1192.         writeMessage ("Invalid newOrient in turtleSetOrientation function", messageLevel.ERROR)
  1193.       end
  1194.     else
  1195.       writeMessage ("Invalid currOrient in turtleTurn function", messageLevel.ERROR)
  1196.     end
  1197.   end
  1198. end
  1199.  
  1200. -- ********************************************************************************** --
  1201. -- Determines if a particular block is considered a noise block or not. A noise
  1202. -- block is one that is a standard block in the game (stone, dirt, gravel etc.) and
  1203. -- is one to ignore as not being an ore. Function works by comparing the block
  1204. -- in question against a set of blocks in the turtle's inventory which are known not to
  1205. -- be noise blocks. Param is the function to use to compare the block for a noise block
  1206. -- ********************************************************************************** --
  1207. function isNoiseBlock(compareFn)
  1208.  
  1209.   -- Consider air to be a noise block
  1210.   local returnVal = false
  1211.  
  1212.   if (resuming == true) then
  1213.     returnVal = true
  1214.   else
  1215.     local seamLoop = 1
  1216.     local prevSelectedSlot  
  1217.  
  1218.     -- If the currently selected slot is a noise block, then compare against this first
  1219.     -- so that the slot doesn't need to be selected again (there is a 0.05s cost to do
  1220.     -- this even if it is the currently selected slot)
  1221.     if (currentlySelectedSlot <= noiseBlocksCount) then
  1222.       returnVal = compareFn()
  1223.     end
  1224.  
  1225.     if (returnVal == false) then
  1226.       prevSelectedSlot = currentlySelectedSlot
  1227.       while((returnVal == false) and (seamLoop <= noiseBlocksCount)) do
  1228.         if (seamLoop ~= prevSelectedSlot) then
  1229.           turtle.select(seamLoop)
  1230.           currentlySelectedSlot = seamLoop
  1231.           returnVal = compareFn()
  1232.         end
  1233.         seamLoop = seamLoop + 1
  1234.       end
  1235.     end
  1236.   end
  1237.  
  1238.   -- Return the calculated value
  1239.   return returnVal
  1240.  
  1241. end
  1242.  
  1243. -- ********************************************************************************** --
  1244. -- Determines if a particular block is a chest. Returns false if it is not a chest
  1245. -- or chests are not being detected
  1246. -- ********************************************************************************** --
  1247. function isChestBlock(compareFn)
  1248.  
  1249.   -- Check the block in the appropriate direction to see whether it is a chest. Only
  1250.   -- do this if we are looking for chests
  1251.   local returnVal = false
  1252.   if (lookForChests == true) then
  1253.     turtle.select(15)
  1254.     currentlySelectedSlot = 15
  1255.     returnVal = compareFn()
  1256.   end
  1257.  
  1258.   -- Return the calculated value
  1259.   return returnVal
  1260.  
  1261. end
  1262.  
  1263. -- ********************************************************************************** --
  1264. -- Function to calculate the number of non seam blocks in the turtle's inventory. This
  1265. -- is all of the blocks at the start of the inventory (before the first empty slot is
  1266. -- found
  1267. -- ********************************************************************************** --
  1268. function determineNoiseBlocksCountCount()
  1269.   -- Determine the location of the first empty inventory slot. All items before this represent
  1270.   -- noise items.
  1271.   local foundFirstBlankInventorySlot = false
  1272.   noiseBlocksCount = 1
  1273.   while ((noiseBlocksCount < 16) and (foundFirstBlankInventorySlot == false)) do
  1274.     if (turtle.getItemCount(noiseBlocksCount) > 0) then
  1275.       noiseBlocksCount = noiseBlocksCount + 1
  1276.     else
  1277.       foundFirstBlankInventorySlot = true
  1278.     end
  1279.   end
  1280.   noiseBlocksCount = noiseBlocksCount - 1
  1281.  
  1282.   -- Determine whether a chest was provided, and hence whether we should support
  1283.   -- looking for chests
  1284.   if (turtle.getItemCount(15) > 0) then
  1285.     --lookForChests = true
  1286.     useEnderChest = true
  1287.     lastEmptySlot = 14
  1288.     miningOffset = 1
  1289.     writeMessage("Using ender chest", messageLevel.DEBUG)
  1290.   else
  1291.     writeMessage("NO ENDER CHEST")
  1292.     useEnderChest = false
  1293.     lastEmptySlot = 15
  1294.     miningOffset = 1
  1295.     writeMessage("Not using ender chest", messageLevel.DEBUG)
  1296.   end
  1297. end
  1298.  
  1299. -- ********************************************************************************** --
  1300. -- Creates a quarry mining out only ores and leaving behind any noise blocks
  1301. -- ********************************************************************************** --
  1302. function createQuarry()
  1303.  
  1304.   -- Determine the top mining layer layer. The turtle mines in layers of 3, and the bottom layer
  1305.   -- is the layer directly above bedrock.
  1306.   --
  1307.   -- The actual layer that the turtle operates in is the middle of these three layers,
  1308.   -- so determine the top layer
  1309.   local topMiningLayer = startHeight + ((bottomLayer - startHeight - 2) % 3) - 1 + miningOffset
  1310.  
  1311.   -- If the top layer is up, then ignore it and move to the next layer
  1312.   if (topMiningLayer > currY) then
  1313.     topMiningLayer = topMiningLayer - 3
  1314.   end
  1315.  
  1316.   local startedLayerToRight = true -- Only used where the quarry is of an odd width
  1317.  
  1318.   -- Loop over each mining row
  1319.   local miningLevel
  1320.   for miningLevel = (bottomLayer + miningOffset), topMiningLayer, 3 do
  1321.     writeMessage("Mining Layer: "..miningLevel, messageLevel.INFO)
  1322.     haveBeenAtZeroZeroOnLayer = false
  1323.  
  1324.     -- While the initial shaft is being dug out, set the level to return to in order to unload
  1325.     -- to the just take the turtle straight back up
  1326.     if (miningLevel == (bottomLayer + miningOffset)) then
  1327.       levelToReturnTo = startHeight
  1328.     end
  1329.  
  1330.     -- Move to the correct level to start mining
  1331.     if (currY > miningLevel) then
  1332.       while (currY > miningLevel) do
  1333.         turtleDown()
  1334.       end
  1335.     elseif (currY < miningLevel) then
  1336.       while (currY < miningLevel) do
  1337.         turtleUp()
  1338.       end
  1339.     end
  1340.  
  1341.     -- Am now mining the levels (update the mining state to reflect that fact)
  1342.     currMiningState = miningState.LAYER
  1343.  
  1344.     -- Set the layer to return via when returning to the surface as the one below the currently
  1345.     -- mined one
  1346.     if (miningLevel == (bottomLayer + miningOffset)) then
  1347.       levelToReturnTo = (bottomLayer + miningOffset)
  1348.     else
  1349.       levelToReturnTo = miningLevel - 3
  1350.     end
  1351.  
  1352.     -- Move turtle into the correct orientation to start mining (if this is the
  1353.     -- first row to be mined, then don't need to turn, otherwise turn towards the next
  1354.     -- mining section)
  1355.  
  1356.     writeMessage("Mining Level: "..miningLevel..", Bottom Layer: "..bottomLayer..", Mining Offset: "..miningOffset, messageLevel.DEBUG)
  1357.  
  1358.     if (miningLevel > (bottomLayer + miningOffset)) then
  1359.       -- Turn towards the next mining layer
  1360.       if (quarryWidth % 2 == 0) then
  1361.         -- An even width quarry, always turn right
  1362.         turtleTurn(direction.RIGHT)
  1363.       else
  1364.         -- Turn the opposite direction to that which we turned before
  1365.         if (startedLayerToRight == true) then
  1366.           turtleTurn(direction.LEFT)
  1367.           startedLayerToRight = false
  1368.         else
  1369.           turtleTurn(direction.RIGHT)
  1370.           startedLayerToRight = true
  1371.         end
  1372.       end
  1373.     end
  1374.  
  1375.     local mineRows
  1376.     local onNearSideOfQuarry = true
  1377.     local diggingAway = true
  1378.     for mineRows = 1, quarryWidth do
  1379.  
  1380.       -- If this is not the first row, then get into position to mine the next row
  1381.       if ((mineRows == 1) and (lookForChests == false)) then
  1382.         -- Not looking for chests, check the block below for being an ore. Only do this
  1383.         -- if we're not looking for chests since the program doesn't support chests in
  1384.         -- bedrock
  1385.         if (isNoiseBlock(turtle.compareDown) == false) then
  1386.           turtle.digDown()
  1387.           back()
  1388.           clearNoiseBlocks(false)
  1389.           ensureInventorySpace()
  1390.         end
  1391.       elseif (mineRows > 1) then
  1392.         -- Move into position for mining the next row
  1393.         if (onNearSideOfQuarry == diggingAway) then
  1394.           if (startedLayerToRight == true) then
  1395.             turtleTurn(direction.LEFT)
  1396.           else
  1397.             turtleTurn(direction.RIGHT)
  1398.           end
  1399.         else
  1400.           if (startedLayerToRight == true) then
  1401.             turtleTurn(direction.RIGHT)
  1402.           else
  1403.             turtleTurn(direction.LEFT)
  1404.           end
  1405.         end
  1406.  
  1407.         turtleForward()
  1408.  
  1409.         -- Before making the final turn, check the block below. Do this
  1410.         -- now because if it is a chest, then we want to back up and
  1411.         -- approach it from the side (so that we don't lose items if we
  1412.         -- have to return to the start through it).
  1413.         --
  1414.         -- This is the point at which it is safe to back up without moving
  1415.         -- out of the quarry area (unless at bedrock in which case don't bother
  1416.         -- as we'll be digging down anyway)
  1417.         if (miningLevel ~= bottomLayer) then
  1418.           if (isNoiseBlock(turtle.compareDown) == false) then
  1419.             -- If we are not looking for chests, then just dig it (it takes
  1420.             -- less time to try to dig and fail as it does to do detect and
  1421.             -- only dig if there is a block there)
  1422.             if (lookForChests == false) then
  1423.               turtle.digDown()
  1424.               back()
  1425.               clearNoiseBlocks(false)
  1426.               ensureInventorySpace()
  1427.             elseif (turtle.detectDown() == true) then
  1428.               if (isChestBlock(turtle.compareDown) == true) then
  1429.                 -- There is a chest block below. Move back and approach
  1430.                 -- from the side to ensure that we don't need to return to
  1431.                 -- start through the chest itself (potentially losing items)
  1432.                 turtleBack()
  1433.                 turtleDown()
  1434.                 currMiningState = miningState.EMPTYCHESTDOWN
  1435.                 emptyChest(turtle.suck)
  1436.                 currMiningState = miningState.LAYER
  1437.                 turtleUp()
  1438.                 turtleForward()
  1439.                 turtle.digDown()
  1440.                 back()
  1441.                 clearNoiseBlocks(false)
  1442.                 ensureInventorySpace()
  1443.               else
  1444.                 turtle.digDown()
  1445.                 back()
  1446.                 clearNoiseBlocks(false)
  1447.                 ensureInventorySpace()
  1448.               end
  1449.             end
  1450.           end
  1451.         end
  1452.  
  1453.         -- Move into final position for mining the next row
  1454.         if (onNearSideOfQuarry == diggingAway) then
  1455.           if (startedLayerToRight == true) then
  1456.             turtleTurn(direction.LEFT)
  1457.           else
  1458.             turtleTurn(direction.RIGHT)
  1459.           end
  1460.         else
  1461.           if (startedLayerToRight == true) then
  1462.             turtleTurn(direction.RIGHT)
  1463.           else
  1464.             turtleTurn(direction.LEFT)
  1465.           end
  1466.         end
  1467.       end
  1468.  
  1469.       -- Dig to the other side of the quarry
  1470.       local blocksMined
  1471.       for blocksMined = 0, (quarryWidth - 1) do
  1472.         if (blocksMined > 0) then
  1473.           -- Only move forward if this is not the first space
  1474.           turtleForward()
  1475.         end
  1476.  
  1477.         -- If the current block is (0,0), then record the fact that the
  1478.         -- turtle has been through this block and what it's orientation was and update the layer
  1479.         -- that it should return via to get back to the surface (it no longer needs to go down
  1480.         -- a level to prevent losing ores).
  1481.         if ((currX == 0) and (currZ == 0)) then
  1482.           -- Am at (0, 0). Remember this, and what direction I was facing so that the quickest route
  1483.           -- to the surface can be taken
  1484.           levelToReturnTo = miningLevel
  1485.           haveBeenAtZeroZeroOnLayer = true
  1486.           orientationAtZeroZero = currOrient
  1487.         end
  1488.  
  1489.         -- If currently at bedrock, just move down until the turtle can't go any
  1490.         -- further. This allows the blocks within the bedrock to be mined
  1491.         if (miningLevel == bottomLayer) then
  1492.           -- Temporarily turn off looking for chests to increase bedrock mining speed (this
  1493.           -- means that the program doesn't support chests below level 5 - but I think
  1494.           -- they they don't exist anyway)
  1495.           local lookForChestsPrev = lookForChests
  1496.           lookForChests = false
  1497.  
  1498.           -- Manually set the flag to determine whether the turtle should try to move first or
  1499.           -- dig first. At bedrock, is very rarely any space
  1500.  
  1501.           -- Just above bedrock layer, dig down until can't dig any lower, and then
  1502.           -- come back up. This replicates how the quarry functions
  1503.           lastMoveNeededDig = true
  1504.           local moveDownSuccess = turtleDown()
  1505.           while (moveDownSuccess == true) do
  1506.             moveDownSuccess = turtleDown()
  1507.           end
  1508.  
  1509.           -- Know that we are moving back up through air, therefore set the flag to force the
  1510.           -- turtle to try moving first
  1511.           lastMoveNeededDig = false
  1512.  
  1513.           -- Have now hit bedrock, move back to the mining layer
  1514.           while (currY < bottomLayer) do
  1515.             turtleUp()
  1516.           end
  1517.  
  1518.           -- Now back at the level above bedrock, again reset the flag to tell the turtle to
  1519.           -- try digging again (because it is rare to find air at bedrock level)
  1520.           lastMoveNeededDig = false
  1521.  
  1522.           -- Reset the look for chests value
  1523.           lookForChests = lookForChestsPrev
  1524.         elseif ((blocksMined > 0) and ((currX ~= 0) or (currZ ~= 0))) then
  1525.           -- This isn't the first block of the row, nor are we at (0, 0) so we need to check the
  1526.           -- block below
  1527.  
  1528.           -- Check the block down for being a noise block (don't need to check the first
  1529.           -- block as it has already been checked in the outer loop)
  1530.           if (isNoiseBlock(turtle.compareDown) == false) then
  1531.             -- If we are not looking for chests, then just dig it (it takes
  1532.             -- less time to try to dig and fail as it does to do detect and
  1533.             -- only dig if there is a block there)
  1534.             if (lookForChests == false) then
  1535.               turtle.digDown()
  1536.               back()
  1537.               clearNoiseBlocks(false)
  1538.               ensureInventorySpace()
  1539.             elseif (turtle.detectDown() == true) then
  1540.               if (isChestBlock(turtle.compareDown) == true) then
  1541.                 -- There is a chest block below. Move back and approach
  1542.                 -- from the side to ensure that we don't need to return to
  1543.                 -- start through the chest itself (potentially losing items)
  1544.                 turtleBack()
  1545.                 currMiningState = miningState.EMPTYCHESTDOWN
  1546.                 turtleDown()
  1547.                 emptyChest(turtle.suck)
  1548.                 currMiningState = miningState.LAYER
  1549.                 turtleUp()
  1550.                 turtleForward()
  1551.                 turtle.digDown()
  1552.                 back()
  1553.                 clearNoiseBlocks(false)
  1554.                 ensureInventorySpace()
  1555.               else
  1556.                 turtle.digDown()
  1557.                 back()
  1558.                 clearNoiseBlocks(false)
  1559.                 ensureInventorySpace()
  1560.               end
  1561.             end
  1562.           end
  1563.         end
  1564.        
  1565.         -- Check the block above for ores (if we're not a (0, 0) in which case
  1566.         -- we know it's air)
  1567.         if ((currX ~= 0) or (currZ ~= 0)) then
  1568.           if (isNoiseBlock(turtle.compareUp) == false) then
  1569.             -- If we are not looking for chests, then just dig it (it takes
  1570.             -- less time to try to dig and fail as it does to do detect and
  1571.             -- only dig if there is a block there)
  1572.             if (lookForChests == false) then
  1573.               turtle.digUp()
  1574.               back()
  1575.               clearNoiseBlocks(false)
  1576.               ensureInventorySpace()
  1577.             elseif (turtle.detectUp() == true) then
  1578.               -- Determine if it is a chest before digging it
  1579.               if (isChestBlock(turtle.compareUp) == true) then
  1580.                 -- There is a chest block above. Empty it before digging it
  1581.                 emptyChest(turtle.suckUp)
  1582.                 turtle.digUp()
  1583.                 back()
  1584.                 clearNoiseBlocks(false)
  1585.                 ensureInventorySpace()
  1586.               else
  1587.                 turtle.digUp()
  1588.                 back()
  1589.                 clearNoiseBlocks(false)
  1590.                 ensureInventorySpace()
  1591.               end
  1592.             end
  1593.           end
  1594.         end
  1595.       end
  1596.  
  1597.       -- Am now at the other side of the quarry
  1598.       onNearSideOfQuarry = not onNearSideOfQuarry
  1599.     end
  1600.  
  1601.     -- If we were digging away from the starting point, will be digging
  1602.     -- back towards it on the next layer
  1603.     diggingAway = not diggingAway
  1604.   end
  1605.  
  1606.   -- Return to the start
  1607.   returnToStartAndUnload(false)
  1608.  
  1609.   -- Face forward
  1610.   turtleSetOrientation(direction.FORWARD)
  1611. end
  1612.  
  1613. -- ********************************************************************************** --
  1614. -- Reads the next number from a given file
  1615. -- ********************************************************************************** --
  1616. function readNumber(inputFile)
  1617.  
  1618.   local returnVal
  1619.   local nextLine = inputFile.readLine()
  1620.   if (nextLine ~= nil) then
  1621.     returnVal = tonumber(nextLine)
  1622.   end
  1623.  
  1624.   return returnVal
  1625. end
  1626.  
  1627. -- ********************************************************************************** --
  1628. -- Startup function to support resuming mining turtle
  1629. -- ********************************************************************************** --
  1630. function isResume()
  1631.  
  1632.   local returnVal = false
  1633.  
  1634.   -- Try to open the resume file
  1635.   local resumeFile = fs.open(startupParamsFile, "r")
  1636.   if (resumeFile == nil) then
  1637.     -- No resume file (presume that we are not supporting it)
  1638.     supportResume = false
  1639.   else
  1640.     writeMessage("Found startup params file", messageLevel.DEBUG)
  1641.  
  1642.     -- Read in the startup params
  1643.     quarryWidth = readNumber(resumeFile)
  1644.     startHeight = readNumber(resumeFile)
  1645.     noiseBlocksCount = readNumber(resumeFile)
  1646.     lastEmptySlot = readNumber(resumeFile)
  1647.     resumeFile.close()
  1648.  
  1649.     -- If the parameters were successfully read, then set the resuming flag to true
  1650.     if ((quarryWidth ~= nil) and (startHeight ~= nil) and (noiseBlocksCount ~= nil) and (lastEmptySlot ~= nil)) then
  1651.  
  1652.       resuming = true
  1653.       writeMessage("Read params", messageLevel.DEBUG)
  1654.  
  1655.       -- Determine the look for chest and mining offset
  1656.       if (lastEmptySlot == 14) then
  1657.         lookForChests = true
  1658.         miningOffset = 0
  1659.       else
  1660.         lookForChests = false
  1661.         miningOffset = 1
  1662.       end
  1663.  
  1664.       -- Get the turtle resume location
  1665.       resumeFile = fs.open(oreQuarryLocation, "r")
  1666.       if (resumeFile ~= nil) then
  1667.  
  1668.         resumeMiningState = readNumber(resumeFile)
  1669.         resumeX = readNumber(resumeFile)
  1670.         resumeY = readNumber(resumeFile)
  1671.         resumeZ = readNumber(resumeFile)
  1672.         resumeOrient = readNumber(resumeFile)
  1673.         resumeFile.close()
  1674.  
  1675.         -- Ensure that the resume location has been found
  1676.         if ((resumeMiningState ~= nil) and (resumeX ~= nil) and (resumeY ~= nil) and (resumeZ ~= nil) and (resumeOrient ~= nil)) then
  1677.           returnVal = true
  1678.           local emptiedInventory = false
  1679.  
  1680.           -- Perform any mining state specific startup
  1681.           if (resumeMiningState == miningState.EMPTYINVENTORY) then
  1682.             -- Am mid way through an empty inventory cycle. Complete it before
  1683.             -- starting the main Quarry function
  1684.             returnToStartAndUnload(true)
  1685.             resuming = true
  1686.  
  1687.             -- Continue from the current position
  1688.             resumeX = currX
  1689.             resumeY = currY
  1690.             levelToReturnTo = resumeY
  1691.             resumeZ = currZ
  1692.             resumeOrient = currOrient
  1693.  
  1694.             writeMessage("Resuming with state of "..currMiningState, messageLevel.DEBUG)
  1695.             resumeMiningState = currMiningState
  1696.             emptiedInventory = true
  1697.           end
  1698.  
  1699.           -- If was emptying a chest when the program stopped, then move back
  1700.           -- to a point which the Quarry
  1701.           if (resumeMiningState == miningState.EMPTYCHESTDOWN) then
  1702.  
  1703.             -- Set the current X, Y, Z and orientation to the true position that
  1704.             -- the turtle is at
  1705.             if (emptiedInventory == false) then
  1706.               currX = resumeX
  1707.               currY = resumeY
  1708.               currZ = resumeZ
  1709.               currOrient = resumeOrient
  1710.             end
  1711.  
  1712.             -- Set the mining state as layer, assume haven't been through zero
  1713.             -- zero and set the level to return to as the one below the current one
  1714.             currMiningState = miningState.LAYER
  1715.             levelToReturnTo = currY - 2
  1716.             haveBeenAtZeroZeroOnLayer = false
  1717.  
  1718.             -- Temporarily disable resuming (so that the new location is written to the file
  1719.             -- in case the program stops again)
  1720.             resuming = false
  1721.             turtleUp()
  1722.             resuming = true
  1723.  
  1724.             resumeY = currY
  1725.             resumeMiningState = miningState.LAYER
  1726.           end
  1727.         end
  1728.       end
  1729.     end
  1730.  
  1731.     if (returnVal == false) then
  1732.       writeMessage("Failed to resume", messageLevel.ERROR)
  1733.     end
  1734.   end
  1735.  
  1736.   return returnVal
  1737. end
  1738.  
  1739. -- ********************************************************************************** --
  1740. -- Main Function                                          
  1741. -- ********************************************************************************** --
  1742. -- Process the input arguments - storing them to global variables
  1743. local args = { ... }
  1744. local paramsOK = true
  1745.  
  1746. function run()
  1747. -- Detect whether this is a wireless turtle, and if so, open the modem
  1748. isWirelessTurtle = peripheral.isPresent("right")
  1749. if (isWirelessTurtle == true) then
  1750.   turtleId = os.getComputerLabel()
  1751.   rednet.open("right")
  1752. end
  1753.  
  1754. if (#args == 0) then
  1755.   -- Is this a resume?
  1756.   if (isResume() == false) then
  1757.     paramsOK = false
  1758.   end
  1759. elseif (#args == 1) then
  1760.   quarryWidth = tonumber(args[1])
  1761.   local x, y, z = gps.locate(5)
  1762.   startHeight = y
  1763.   if (startHeight == nil) then
  1764.     writeMessage("Can't locate GPS", messageLevel.FATAL)
  1765.     paramsOK = false
  1766.   end
  1767. elseif (#args == 2) then
  1768.   if (args[2] == "/r") then
  1769.     quarryWidth = tonumber(args[1])
  1770.     supportResume = false
  1771.   else
  1772.     quarryWidth = tonumber(args[1])
  1773.     startHeight = tonumber(args[2])
  1774.   end
  1775. elseif (#args == 3) then
  1776.   quarryWidth = tonumber(args[1])
  1777.   startHeight = tonumber(args[2])
  1778.   if (args[3] == "/r") then
  1779.     supportResume = false
  1780.   else
  1781.     bottomLayer = tonumber(args[3])
  1782.   end
  1783. end
  1784.  
  1785. if ((paramsOK == false) and (resuming == false)) then
  1786.   writeMessage("Usage: "..shell.getRunningProgram().." <diameter> [turtleY] [/r]", messageLevel.FATAL)
  1787.   paramsOK = false
  1788. end
  1789.  
  1790. if (paramsOK == true) then
  1791.   if ((startHeight < 6) or (startHeight > 128)) then
  1792.     writeMessage("turtleY must be between 6 and 128", messageLevel.FATAL)
  1793.     paramsOK = false
  1794.   end
  1795.  
  1796.   if ((quarryWidth < 2) or (quarryWidth > 64)) then
  1797.     writeMessage("diameter must be between 2 and 64", messageLevel.FATAL)
  1798.     paramsOK = false
  1799.   end
  1800. end
  1801.  
  1802. if (paramsOK == true) then
  1803.   writeMessage("---------------------------------", messageLevel.INFO)
  1804.   writeMessage("** Ore Quarry v0.7 by AustinKK **", messageLevel.INFO)
  1805.   writeMessage("---------------------------------", messageLevel.INFO)
  1806.   if (resuming == true) then
  1807.     writeMessage("Resuming...", messageLevel.INFO)
  1808.   end
  1809.  
  1810.   -- Set the turtle's starting position
  1811.   currX = 0
  1812.   currY = startHeight
  1813.   currZ = 0
  1814.   currOrient = direction.FORWARD
  1815.  
  1816.   -- Calculate which blocks in the inventory signify noise blocks
  1817.   if (resuming == false) then
  1818.     determineNoiseBlocksCountCount()
  1819.   end
  1820.  
  1821.   if ((noiseBlocksCount == 0) or (noiseBlocksCount > 13)) then
  1822.     writeMessage("No noise blocks have been been added. Please place blocks that the turtle should not mine (e.g. Stone, Dirt, Gravel etc.) in the first few slots of the turtle\'s inventory. The first empty slot signifies the end of the noise blocks.", messageLevel.FATAL)
  1823.   else
  1824.     -- If we are supporting resume (and are not currently in the process of resuming)
  1825.     -- then store startup parameters in appropriate files
  1826.     if ((supportResume == true) and (resuming == false)) then
  1827.       -- Write the startup parameters to  file
  1828.       local outputFile = io.open(startupParamsFile, "w")
  1829.       outputFile:write(quarryWidth)
  1830.       outputFile:write("\n")
  1831.       outputFile:write(startHeight)
  1832.       outputFile:write("\n")
  1833.       outputFile:write(noiseBlocksCount)
  1834.       outputFile:write("\n")
  1835.       outputFile:write(lastEmptySlot)
  1836.       outputFile:write("\n")
  1837.       outputFile:close()
  1838.  
  1839.       -- Setup the startup file
  1840.  
  1841.       -- Take a backup of the current startup file
  1842.       if (fs.exists("startup") == true) then
  1843.         fs.copy("startup", startupBackup)
  1844.       end
  1845.      
  1846.       -- Write a new startup file to resume the turtle
  1847.       outputFile = io.open("startup", "a")
  1848.       outputFile:write("\nshell.run(\"")
  1849.       outputFile:write(shell.getRunningProgram())
  1850.       outputFile:write("\")\n")
  1851.       outputFile:close()
  1852.  
  1853.     end
  1854.  
  1855.     -- Create a Quarry
  1856.     turtle.select(1)
  1857.     currentlySelectedSlot = 1
  1858.     createQuarry()
  1859.  
  1860.     -- Restore the file system to its original configuration
  1861.     if (supportResume == true) then
  1862.       fs.delete("startup")
  1863.       if (fs.exists(startupBackup) == true) then
  1864.         fs.move(startupBackup, "startup")
  1865.       end
  1866.  
  1867.       if (fs.exists(startupParamsFile) == true) then
  1868.         fs.delete(startupParamsFile)
  1869.       end
  1870.  
  1871.       if (fs.exists(oreQuarryLocation) == true) then
  1872.         fs.delete(oreQuarryLocation)
  1873.       end
  1874.  
  1875.       if (fs.exists(returnToStartFile) == true) then
  1876.         fs.delete(returnToStartFile)
  1877.       end
  1878.     end
  1879.   end
  1880. end
  1881. end
  1882. parallel.waitForAll(run,stop)
Advertisement
Add Comment
Please, Sign In to add comment