macks2008

my version of computercraft's Excavate program

Feb 16th, 2021 (edited)
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.21 KB | None | 0 0
  1. -- this does not belong to me.
  2. -- most of it came from the ComputerCraft wiki and is presumably under the same license as ComputerCraft itself
  3. -- I just added some comments and a condition to stop at a certain depth
  4. local tArgs = { ... }
  5. local targetDepth
  6. if #tArgs < 1 then
  7.     print( "Usage: excavate <diameter> [targetDepth]" )
  8.     return
  9. elseif #tArgs == 2 then
  10.     targetDepth = tonumber ( tArgs[2] )
  11. end
  12.  
  13. -- Mine in a quarry pattern until we hit something we can't dig
  14. local size = tonumber( tArgs[1] )
  15. if size < 1 then
  16.     print( "Excavate diameter must be positive" )
  17.     return
  18. end
  19.    
  20. local depth = 0       --this keeps track of how far we had descended from our starting position
  21. local unloaded = 0    --this keeps track of how much we have unloaded, and is updated by unload()
  22. local collected = 0   --this keeps track of how many items we have on board, and is updated by collect()
  23.  
  24. local xPos,zPos = 0,0 --these store the turtle's location within its own relativistic world grid
  25. local xDir,zDir = 0,1 --these are a direction vector that assumes we face positive Z initially
  26.                       --(but whether this is true is irrelevant since the API calls for checking the "real"
  27.                       --location are never utilized. We just track our location and direction internally)
  28.  
  29. local goTo -- Filled in further down
  30. local refuel -- Filled in further down
  31.  
  32. local function unload( _bKeepOneFuelStack )
  33.     print( "Unloading items..." )
  34.     for n=1,16 do
  35.         local nCount = turtle.getItemCount(n)
  36.         if nCount > 0 then
  37.             turtle.select(n)           
  38.             local bDrop = true
  39.             if _bKeepOneFuelStack and turtle.refuel(0) then
  40.                 bDrop = false
  41.                 _bKeepOneFuelStack = false
  42.             end        
  43.             if bDrop then
  44.                 turtle.drop()
  45.                 unloaded = unloaded + nCount
  46.             end
  47.         end
  48.     end
  49.     collected = 0
  50.     turtle.select(1)
  51. end
  52.  
  53. local function returnSupplies()
  54.     local x,y,z,xd,zd = xPos,depth,zPos,xDir,zDir
  55.     print( "Returning to surface..." )
  56.     goTo( 0,0,0,0,-1 )
  57.    
  58.     local fuelNeeded = 2*(x+y+z) + 1
  59.     if not refuel( fuelNeeded ) then
  60.         unload( true )
  61.         print( "Waiting for fuel" )
  62.         while not refuel( fuelNeeded ) do
  63.             os.pullEvent( "turtle_inventory" )
  64.         end
  65.     else
  66.         unload( true ) 
  67.     end
  68.    
  69.     print( "Resuming mining..." )
  70.     goTo( x,y,z,xd,zd )
  71. end
  72.  
  73. local function collect()    --checks if inventory has an open slot
  74.     local bFull = true --assume backpack is full until disproven
  75.     local nTotalItems = 0 --start a count of items
  76.     for n=1,16 do
  77.         local nCount = turtle.getItemCount(n)
  78.         if nCount == 0 then
  79.             bFull = false
  80.         end
  81.         nTotalItems = nTotalItems + nCount --to count how much we have on hand
  82.     end
  83.    
  84.     if nTotalItems > collected then
  85.         collected = nTotalItems
  86.         if math.fmod(collected + unloaded, 50) == 0 then
  87.             print( "Mined "..(collected + unloaded).." items." )
  88.         end
  89.     end
  90.    
  91.     if bFull then
  92.         print( "No empty slots left." )
  93.         return false
  94.     end
  95.     return true
  96. end
  97.  
  98. function refuel( amount ) -- checks if we have enough fuel, and if not, search the inventory for valid fuels
  99.     local fuelLevel = turtle.getFuelLevel()
  100.     if fuelLevel == "unlimited" then
  101.         return true -- if fuel requirements are disabled for any reason, this function always returns true
  102.     end
  103.    
  104.     local needed = amount or (xPos + zPos + depth + 2) -- if amount isn't specified, estimate how much we need to get "home"
  105.     if turtle.getFuelLevel() < needed then
  106.         local fueled = false
  107.         for n=1,16 do
  108.             if turtle.getItemCount(n) > 0 then
  109.                 turtle.select(n)
  110.                 if turtle.refuel(1) then
  111.                     while turtle.getItemCount(n) > 0 and turtle.getFuelLevel() < needed do
  112.                         turtle.refuel(1)
  113.                     end
  114.                     if turtle.getFuelLevel() >= needed then
  115.                         turtle.select(1) -- reset the inventory cursor
  116.                         return true
  117.                     end
  118.                 end
  119.             end
  120.         end
  121.         turtle.select(1)
  122.         return false -- if the fuel requirements could not be met, refuel failed
  123.     end
  124.    
  125.     return true
  126. end
  127.  
  128. local function tryForwards()
  129.     if not refuel() then -- only move forward if we can get back from this location
  130.         print( "Not enough Fuel" )
  131.         returnSupplies()
  132.     end
  133.    
  134.     while not turtle.forward() do -- keep trying to move forward (digging or attacking if necessary) until successful
  135.         if turtle.detect() then --is there a block in front of us?
  136.             if turtle.dig() then
  137.                 if not collect() then
  138.                     returnSupplies()
  139.                 end
  140.             else
  141.                 return false -- The block in front of us couldn't be broken
  142.             end
  143.         elseif turtle.attack() then --By the way, even with just a pickaxe, this thing hits decently hard
  144.             if not collect() then
  145.                 returnSupplies()
  146.             end
  147.         else
  148.             sleep( 0.5 )
  149.         end
  150.     end
  151.    
  152.     xPos = xPos + xDir -- adjust the turtle's memory of its location by the direction vector
  153.     zPos = zPos + zDir -- see above
  154.     return true
  155. end
  156.  
  157. local function tryDown()
  158.     if not refuel() then
  159.         print( "Not enough Fuel" )
  160.         returnSupplies()
  161.     end
  162.    
  163.     while not turtle.down() do
  164.         if turtle.detectDown() then
  165.             if turtle.digDown() then
  166.                 if not collect() then
  167.                     returnSupplies()
  168.                 end
  169.             else
  170.                 return false
  171.             end
  172.         elseif turtle.attackDown() then
  173.             if not collect() then
  174.                 returnSupplies()
  175.             end
  176.         else
  177.             sleep( 0.5 )
  178.         end
  179.     end
  180.  
  181.     depth = depth + 1
  182.     if math.fmod( depth, 10 ) == 0 then
  183.         print( "Descended "..depth.." metres." )
  184.     end
  185.  
  186.     return true
  187. end
  188.  
  189. local function turnLeft() --this just updates the direction vector
  190.     turtle.turnLeft()
  191.     xDir, zDir = -zDir, xDir --this is pretty smart vector handling, TBH. I might have to remember this...
  192. end
  193.  
  194. local function turnRight() --this just updates the direction vector
  195.     turtle.turnRight()
  196.     xDir, zDir = zDir, -xDir
  197. end
  198.  
  199. function goTo( x, y, z, xd, zd ) --given a location and a current direction vector, go to location
  200.     while depth > y do --first go up...
  201.         if turtle.up() then
  202.             depth = depth - 1
  203.         elseif turtle.digUp() or turtle.attackUp() then --if something was in the way[...]
  204.             collect()                                   --update the inventory manager. Isn't functional programming fun?
  205.         else
  206.             sleep( 0.5 )
  207.         end
  208.     end --note that this function does not give up if digging and/or attacking fail
  209.  
  210.     if xPos > x then --if we need to go toward negative X
  211.         while xDir ~= -1 do --... but we aren't facing negative X
  212.             turnLeft() --turn and update the vector
  213.         end
  214.         while xPos > x do --start moving left just like we did with up
  215.             if turtle.forward() then
  216.                 xPos = xPos - 1
  217.             elseif turtle.dig() or turtle.attack() then
  218.                 collect()
  219.             else
  220.                 sleep( 0.5 )
  221.             end
  222.         end
  223.     elseif xPos < x then --same as above, but we need to be facing positive X
  224.         while xDir ~= 1 do
  225.             turnLeft()
  226.         end
  227.         while xPos < x do
  228.             if turtle.forward() then
  229.                 xPos = xPos + 1
  230.             elseif turtle.dig() or turtle.attack() then
  231.                 collect()
  232.             else
  233.                 sleep( 0.5 )
  234.             end
  235.         end
  236.     end
  237.    
  238.     if zPos > z then
  239.         while zDir ~= -1 do
  240.             turnLeft()
  241.         end
  242.         while zPos > z do
  243.             if turtle.forward() then
  244.                 zPos = zPos - 1
  245.             elseif turtle.dig() or turtle.attack() then
  246.                 collect()
  247.             else
  248.                 sleep( 0.5 )
  249.             end
  250.         end
  251.     elseif zPos < z then
  252.         while zDir ~= 1 do
  253.             turnLeft()
  254.         end
  255.         while zPos < z do
  256.             if turtle.forward() then
  257.                 zPos = zPos + 1
  258.             elseif turtle.dig() or turtle.attack() then
  259.                 collect()
  260.             else
  261.                 sleep( 0.5 )
  262.             end
  263.         end
  264.     end
  265.    
  266.     while depth < y do
  267.         if turtle.down() then
  268.             depth = depth + 1
  269.         elseif turtle.digDown() or turtle.attackDown() then
  270.             collect()
  271.         else
  272.             sleep( 0.5 )
  273.         end
  274.     end
  275.    
  276.     while zDir ~= zd or xDir ~= xd do
  277.         turnLeft()
  278.     end
  279. end
  280.  
  281. if not refuel() then
  282.     print( "Out of Fuel" )
  283.     return
  284. end
  285. -- end of function definitions.
  286.  
  287. -- program entry point
  288. print( "Excavating..." )
  289.  
  290. local reseal = false
  291. turtle.select(1)
  292. if turtle.digDown() then
  293.     reseal = true
  294. end
  295.  
  296. local alternate = 0
  297. local done = false
  298. while not done do
  299.     for n=1,size do
  300.         for m=1,size-1 do --clear a row
  301.             if not tryForwards() then -- if it ran into something unbreakable
  302.                 done = true
  303.                 break
  304.             end
  305.         end
  306.         if done then
  307.             break
  308.         end
  309.         if n<size then --if we have more rows to clear
  310.             if math.fmod(n + alternate,2) == 0 then --depending on the modulus of this row..
  311.                 turnLeft()
  312.                 if not tryForwards() then
  313.                     done = true
  314.                     break
  315.                 end
  316.                 turnLeft()
  317.             else
  318.                 turnRight()
  319.                 if not tryForwards() then
  320.                     done = true
  321.                     break
  322.                 end
  323.                 turnRight()
  324.             end
  325.         end
  326.     end
  327.     if done then
  328.         break
  329.     end
  330.    
  331.     if size > 1 then
  332.         if math.fmod(size,2) == 0 then
  333.             turnRight()
  334.         else
  335.             if alternate == 0 then
  336.                 turnLeft()
  337.             else
  338.                 turnRight()
  339.             end
  340.             alternate = 1 - alternate
  341.         end
  342.     end
  343.    
  344.     --this check is added temporarily because I want a version of this that only goes down to Y = 60
  345.     local realX, realY, realZ = gps.locate()
  346.     --if not realY then --If gps.locate didn't work, it won't return anything. So check to see if it did.
  347.     --  print("Failed to get my location!")
  348.     --end
  349.     --if realY <= 60 then
  350.     --  done = true
  351.     --  break
  352.     --end
  353.     if (targetDepth ~= nil) and (depth >= targetDepth) then
  354.         done = true
  355.         break
  356.     elseif not tryDown() then
  357.         done = true
  358.         break
  359.     end
  360. end
  361.  
  362. print( "Returning to surface..." )
  363.  
  364. -- Return to where we started
  365. goTo( 0,0,0,0,-1 )
  366. unload( false )
  367. goTo( 0,0,0,0,1 )
  368.  
  369. -- Seal the hole
  370. if reseal then
  371.     turtle.placeDown()
  372. end
  373.  
  374. print( "Mined "..(collected + unloaded).." items total." )
Add Comment
Please, Sign In to add comment