Advertisement
renanmfd

tunneler

Nov 24th, 2022 (edited)
793
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 18.48 KB | None | 0 0
  1. -- pastebin get 9rUhn7TQ startup
  2. --
  3. -- Program for ComputerCraft 1.4 mod for Minecraft.
  4. -- This is a turtle mining program. A better version of the native excavate
  5. -- because:
  6. --   * Mine 3 layers per pass.
  7. --   * Auto-refuel.
  8. --   * Location tracker.
  9. --   * Restart after server down.
  10. --   * Load mined chunk.
  11. --   * Fail safe movents.
  12. --   * Position auto-correct using chunkloader if CC >1.64.
  13. --
  14. -- DEPENDENCIES ---------------------------------------------------------------
  15. --
  16. -- Mods:
  17. --   * EnderStorage (optional - recommended)
  18. --     You can use Minecraft vanilla Ender chest, but you'll need two and some
  19. --     way to remove the items from it and leave the fuel.
  20. --   * ChickenChunks (optional - recommended)
  21. --     Leving the turtle without the Chunkloader is possible. It will work
  22. --     normally until it hits an unloaded chunk.
  23. --
  24. -- QUICK USAGE ----------------------------------------------------------------
  25. --
  26. -- $ pastebin get 9rUhn7TQ startup
  27. -- Load the turtle with:
  28. --   * Slot 1: 1x Enderchest with fuel.
  29. --   * Slot 2: 1x Enderchest for items.
  30. --   * Slot 3: 2x SpotLoader or ChunkLoader
  31. -- $ startup 16w
  32. -- To stop it and reset, hold CTRL+t to stop and execute:
  33. -- $ startup reset
  34. --
  35. -- HOW TO USE -----------------------------------------------------------------
  36. --
  37. -- On a mining turtle, paste and execute the following command to install:
  38. --   $ pastebin get 9rUhn7TQ startup
  39. -- The program accepts one argument, the size of each branch/hole to dig. This
  40. -- number needs to be even starting from 2. If odd number is provided the next
  41. -- integer will be used (ex: 3 will dig 4). The ideal size for efficiency is:
  42. --   * Using spotLoader, 16 (1 chunk).
  43. --   * Using chunkLoader, 32 (4 chunks).
  44. -- This is because for every hole, the turtle needs to put a chunkloader in the
  45. -- next digging spot, turn back to previuos and take the other chunklader. This
  46. -- increases fuel usage.
  47. --
  48. -- FUTURE IMPROVEMENTS --------------------------------------------------------
  49. --
  50. -- * Use a bucket of water to transform lava into obsidian or an empty bucket
  51. --   to get the lava for fuel. This will require Computercraft version 1.64.
  52.  
  53. -------------------------------------------------------------------------------
  54. -- Contants -------------------------------------------------------------------
  55.  
  56. -- Available X,Y direction constants.
  57. local DIRECTION_NORTH = 'north';
  58. local DIRECTION_EAST  = 'east';
  59. local DIRECTION_SOUTH = 'south';
  60. local DIRECTION_WEST  = 'west';
  61.  
  62. -- Available Z direction constants.
  63. local HEIGHT_UP   = 'up';
  64. local HEIGHT_DOWN = 'down';
  65.  
  66. -- Available severity of logs.
  67. local LOG_NOTICE  = 21;
  68. local LOG_WARNING = 22;
  69. local LOG_ERROR   = 23;
  70. local LOG_DEBUG   = 24;
  71.  
  72. -- Program specific constants.
  73. local TURTLE_ENDERCHEST_FUEL = 1
  74. local TURTLE_ENDERCHEST_ITEMS = 2
  75. local TURTLE_CHUNKLOADER = 3
  76. local TURTLE_STORE = 4
  77.  
  78. -------------------------------------------------------------------------------
  79. -- Variables ------------------------------------------------------------------
  80.  
  81. -- Direction the turtle is facing.
  82. local facing = DIRECTION_NORTH
  83.  
  84. -- The X direction based on initial position (0,0,0).
  85. local x  = 0
  86.  
  87. -- The Z direction (hight) based on initial position (0,0,0).
  88. local z = 0
  89.  
  90. -- The X direction based on initial position (0,0,0).
  91. local y = 0
  92.  
  93. -- Name of the file that keep location saved.
  94. local file = "location.cc"
  95.  
  96. -- Function arguments.
  97. local inputs = { ... }
  98.  
  99. -- Size of the excavation site.
  100. local tunnelWidth
  101. local tunnelHeight
  102. local tunnelDepth
  103.  
  104. -------------------------------------------------------------------------------
  105. -- Private functions ----------------------------------------------------------
  106.  
  107. -------------------------------------------------------------------------------
  108. -- @function log()
  109. --
  110. -- Log system with severity.
  111. -- This function makes easier to change how turtles print messages. We change
  112. -- the color based on the severity argument.
  113. --
  114. -- @arg String message
  115. --   Message to be logged.
  116. -- @arg Integer severity
  117. --   One of the log constants that tells the severity of the message.
  118. --
  119. local function log(message, severity)
  120.   local severity = severity or LOG_NOTICE
  121.   local colorOld = term.getTextColor()
  122.   local color
  123.  
  124.   if severity == LOG_NOTICE then
  125.     color = colors.white
  126.   elseif severity == LOG_WARNING then
  127.     color = colors.yellow
  128.   elseif severity == LOG_ERROR then
  129.     color = colors.red
  130.   elseif severity == LOG_DEBUG then
  131.     color = colors.green
  132.   end
  133.  
  134.   term.setTextColor(color)
  135.   print(message)
  136.   term.setTextColor(colorOld)
  137. end
  138.  
  139. -------------------------------------------------------------------------------
  140. -- @function refuel()
  141. --
  142. -- Perform the refuel action using the enderchest. We check if there is space
  143. -- for the chest to be placed and use the last inventory slot to suck the fuel.
  144. --
  145. local function refuel()
  146.   if turtle.detect() then
  147.     if not turtle.dig() then
  148.       log('Bedrock stop - refuel()')
  149.     end
  150.   end
  151.   turtle.select(TURTLE_ENDERCHEST_FUEL)
  152.   turtle.place()
  153.   turtle.select(16)
  154.   turtle.dropDown()
  155.   turtle.suck(16)
  156.   turtle.refuel(64)
  157.   log('Fuel level: ' .. turtle.getFuelLevel() )
  158.   turtle.select(TURTLE_ENDERCHEST_FUEL)
  159.   turtle.dig()
  160.   turtle.select(TURTLE_STORE)
  161. end
  162.  
  163.  
  164. -------------------------------------------------------------------------------
  165. -- @function unloadInventory()
  166. --
  167. -- ??
  168. local function unloadInventory()
  169.   turtle.select(TURTLE_ENDERCHEST_ITEMS)
  170.   turtle.digUp()
  171.   turtle.placeUp()
  172.   for i=TURTLE_STORE, 16 do
  173.     turtle.select(i)
  174.     turtle.dropUp()
  175.   end
  176.   turtle.select(TURTLE_ENDERCHEST_ITEMS)
  177.   turtle.digUp()
  178. end
  179.  
  180. --------------------------------------------------------------
  181. -- @function checkInventory()
  182. --
  183. -- ??
  184. local function checkInventory()
  185.   local result = true
  186.   for i=TURTLE_STORE, 16 do
  187.     turtle.select(i)
  188.     item = turtle.getItemCount(i)
  189.     if item == 0 then
  190.       result = false
  191.       break
  192.     end
  193.   end
  194.   if result then
  195.     unloadInventory()
  196.   end
  197.   turtle.select(TURTLE_STORE)
  198.   return result
  199. end
  200.  
  201. --------------------------------------------------------------
  202. -- @function quickCheckInventory()
  203. --
  204. -- ??
  205. local function quickCheckInventory()
  206.   local result = true
  207.   turtle.select(16)
  208.   item = turtle.getItemCount(16)
  209.   if item == 0 then
  210.     result = false
  211.   else
  212.     unloadInventory()
  213.   end
  214.   turtle.select(TURTLE_STORE)
  215.   return result
  216. end
  217.  
  218. -------------------------------------------------------------------------------
  219. -- @function saveLocation()
  220. --
  221. -- Saves turtle position on file.
  222. local function saveLocation()
  223.   local f = fs.open(file, "w")
  224.   f.writeLine(facing)
  225.   f.writeLine(tostring(x))
  226.   f.writeLine(tostring(z))
  227.   f.writeLine(tostring(y))
  228.   f.writeLine(tostring(tunnelWidth))
  229.   f.writeLine(tostring(tunnelHeight))
  230.   f.writeLine(tostring(tunnelDepth))
  231.   f.close()
  232. end
  233.  
  234. --------------------------------------------------------------
  235. -- @function loadLocation()
  236. --
  237. -- Loads turtle position on file.
  238. local function loadLocation()
  239.   if not fs.exists(file) then
  240.     return false
  241.   end
  242.   local f = fs.open( file , "r" )
  243.   facing = f.readLine()
  244.   x = tonumber(f.readLine())
  245.   z = tonumber(f.readLine())
  246.   y = tonumber(f.readLine())
  247.   tunnelWidth = tonumber(f.readLine())
  248.   tunnelHeight = tonumber(f.readLine())
  249.   tunnelDepth = tonumber(f.readLine())
  250.   f.close()
  251.   return true
  252. end
  253.  
  254. -------------------------------------------------------------------------------
  255. -- @function updateLocation()
  256. --
  257. -- After every sideways (x,y) move, we update the location track variables.
  258. local function updateLocation()
  259.   if facing == DIRECTION_NORTH then
  260.     y = y + 1
  261.   elseif facing == DIRECTION_SOUTH then
  262.     y = y - 1
  263.   elseif facing == DIRECTION_EAST then
  264.     x = x + 1
  265.   elseif facing == DIRECTION_WEST then
  266.     x = x - 1
  267.   else
  268.     log("Invalid facing direction", LOG_ERROR)
  269.   end
  270.   saveLocation()
  271. end
  272.  
  273. -------------------------------------------------------------------------------
  274. -- @function updateHeight()
  275. --
  276. -- After every height change, we update the location track variable.
  277. local function updateHeight(str)
  278.   if str == HEIGHT_DOWN then
  279.     z = z - 1
  280.   elseif str == HEIGHT_UP then
  281.     z = z + 1
  282.   else
  283.     log("Invalid height direction", LOG_ERROR)
  284.   end
  285.   saveLocation()
  286. end
  287.  
  288. -------------------------------------------------------------------------------
  289. -- Public functions -----------------------------------------------------------
  290.  
  291. -------------------------------------------------------------------------------
  292. -- @function forward()
  293. --
  294. -- Move the turtle forward breaking blocks, attacking entities and refuel if
  295. -- needed. If there is an unbreakable block the move fails.
  296. --
  297. -- @return Boolean
  298. --   False if reached unbreakable block, true otherwise.
  299. function forward()
  300.   local max = 30
  301.  
  302.   while not turtle.forward() do
  303.     -- Fuel low.
  304.     if turtle.getFuelLevel() == 0 then
  305.       log("Fuel is over. Refueling!")
  306.       refuel()
  307.     -- Mob on the way.
  308.     elseif turtle.attack() then
  309.       log("Mob on my way. Die!")
  310.       local isAttacking
  311.       repeat
  312.         sleep(1)
  313.       until not turtle.attack()
  314.     -- Block on the way.
  315.     elseif turtle.detect() then
  316.       log("Block on the way. Dig!")
  317.       if not turtle.dig() then
  318.         log("Hit bedrock")
  319.         return false
  320.       end
  321.     end
  322.  
  323.     -- Timeout limit on the loops.
  324.     max = max - 1
  325.     if max <= 0 then
  326.       log("Timeout on forward()")
  327.       return false
  328.     end
  329.   end
  330.   updateLocation()
  331.   return true  
  332. end
  333.  
  334. -------------------------------------------------------------------------------
  335. -- @function nforward()
  336. --
  337. -- Easy and clean way to move more than 1 block forward.
  338. --
  339. -- @arg Integer num
  340. --   Number of blocks to move forward.
  341. -- @return Boolean
  342. --   False if reached unbreakable block, true otherwise.
  343. function nforward(num)
  344.   if num <= 0 then
  345.     log("Invalid argument. Set to 1.", LOG_WARNING)
  346.     num = 1
  347.   end
  348.   log("Old position: x=" .. x .. " y=" .. y, LOG_DEBUG)
  349.   for i=1 , num do
  350.     if not forward() then
  351.       return false
  352.     end
  353.   end
  354.   log("New position: x=" .. x .. " y=" .. y, LOG_DEBUG)
  355.   return true
  356. end
  357.  
  358. -------------------------------------------------------------------------------
  359. -- @function down()
  360. --
  361. -- Move the turtle down, digging if block is bellow, attacking if entity,
  362. -- refuel if needed and checking for bedrock.
  363. --
  364. -- @return Boolean
  365. --   False if bedrock is reached, true otherwise.
  366. function down()
  367.   while not turtle.down() do
  368.     if not turtle.digDown() then
  369.       if turtle.getFuelLevel() == 0 then
  370.         log("Fuel is over. Refueling.")
  371.         refuel()
  372.       elseif turtle.attackDown() then
  373.         log("Mob on the way. Die!")
  374.       else
  375.         log("Bedrock reached.")
  376.         return false
  377.       end
  378.     end
  379.   end
  380.   updateHeight(HEIGHT_DOWN)
  381.   return true
  382. end
  383.  
  384. -------------------------------------------------------------------------------
  385. -- @function up()
  386. --
  387. -- Move the turtle up, digging if any block above, attacking if entity,
  388. -- refuel if needed and checking for bedrock.
  389. --
  390. -- @return Boolean
  391. --   False if bedrock is reached, true otherwise.
  392. function up()
  393.   while not turtle.up() do
  394.     if not turtle.digUp() then
  395.       if turtle.getFuelLevel() == 0 then
  396.         log("Fuel is over. Refueling.")
  397.         refuel()
  398.       elseif turtle.attackUp() then
  399.         log("Mob on the way. Die!")
  400.       else
  401.         log("Bedrock reached.")
  402.         return false
  403.       end
  404.     end
  405.   end
  406.   updateHeight(HEIGHT_UP)
  407.   return true
  408. end
  409.  
  410.  
  411. -------------------------------------------------------------------------------
  412. -- @function left()
  413. --
  414. -- Turn turtle to the left.
  415. function left()
  416.   turtle.turnLeft()
  417.   if facing == DIRECTION_NORTH then
  418.     facing = DIRECTION_WEST
  419.   elseif facing == DIRECTION_SOUTH then
  420.     facing = DIRECTION_EAST
  421.   elseif facing == DIRECTION_EAST then
  422.     facing = DIRECTION_NORTH
  423.   elseif facing == DIRECTION_WEST then
  424.     facing = DIRECTION_SOUTH
  425.   else
  426.     log("Invalid facing direction", LOG_ERROR)
  427.   end
  428.   saveLocation();
  429. end
  430.  
  431. -------------------------------------------------------------------------------
  432. -- @function right()
  433. --
  434. -- Turn turtle to the right.
  435. function right()
  436.   turtle.turnRight()
  437.   if facing == DIRECTION_NORTH then
  438.     facing = DIRECTION_EAST
  439.   elseif facing == DIRECTION_SOUTH then
  440.     facing = DIRECTION_WEST
  441.   elseif facing == DIRECTION_EAST then
  442.     facing = DIRECTION_SOUTH
  443.   elseif facing == DIRECTION_WEST then
  444.     facing = DIRECTION_NORTH
  445.   else
  446.     log("Invalid facing direction", LOG_ERROR)
  447.   end
  448.   saveLocation();
  449. end
  450.  
  451. -------------------------------------------------------------------------------
  452. -- @function turnAround()
  453. --
  454. -- ??
  455. --
  456. -- @return Boolean
  457. --   Return false if turning or facing directions are invalid and true
  458. --   otherwise.
  459. function turnAround()
  460.   left()
  461.   left()
  462. end
  463.  
  464. -------------------------------------------------------------------------------
  465. -- @function turnTo(dir)
  466. --
  467. -- Turn to the argument direction. This is based on initial conditions. Initial
  468. -- facing direction is always north.
  469. --
  470. -- @arg Integer dir
  471. --   One of the direction constants.
  472. -- @return Boolean
  473. --   Return false if turning or facing directions are invalid and true
  474. --   otherwise.
  475. function turnTo(dir)
  476.   log("turnTo(" .. dir .. ")", LOG_DEBUG)
  477.   if dir == DIRECTION_NORTH then
  478.     if facing == DIRECTION_NORTH then
  479.       return true
  480.     elseif facing == DIRECTION_SOUTH then
  481.       right()
  482.       right()
  483.     elseif facing == DIRECTION_EAST then
  484.       left()
  485.     elseif facing == DIRECTION_WEST then
  486.       right()
  487.     else
  488.       log("Invalid facing direction " .. facing, LOG_ERROR)
  489.       return false
  490.     end
  491.   elseif dir == DIRECTION_SOUTH then
  492.     if facing == DIRECTION_SOUTH then
  493.       return true
  494.     elseif facing == DIRECTION_NORTH then
  495.       right()
  496.       right()
  497.     elseif facing == DIRECTION_WEST then
  498.       left()
  499.     elseif facing == DIRECTION_EAST then
  500.       right()
  501.     else
  502.       log("Invalid facing direction " .. facing, LOG_ERROR)
  503.       return false
  504.     end
  505.   elseif dir == DIRECTION_WEST then
  506.     if facing == DIRECTION_WEST then
  507.       return true
  508.     elseif facing == DIRECTION_EAST then
  509.       right()
  510.       right()
  511.     elseif facing == DIRECTION_NORTH then
  512.       left()
  513.     elseif facing == DIRECTION_SOUTH then
  514.       right()
  515.     else
  516.       log("Invalid facing direction " .. facing, LOG_ERROR)
  517.       return false
  518.     end
  519.   elseif dir == DIRECTION_EAST then
  520.     if facing == DIRECTION_EAST then
  521.       return true
  522.     elseif facing == DIRECTION_WEST then
  523.       right()
  524.       right()
  525.     elseif facing == DIRECTION_SOUTH then
  526.       left()
  527.     elseif facing == DIRECTION_NORTH then
  528.       right()
  529.     else
  530.       log("Invalid facing direction " .. facing, LOG_ERROR)
  531.       return false
  532.     end
  533.   else
  534.     log("Invalid goto direction " .. dir, LOG_ERROR)
  535.     return false
  536.   end
  537.   return true
  538. end
  539.  
  540. -------------------------------------------------------------------------------
  541. -- @TODO LIST
  542. -- Transform lava into obsidian
  543. -------------------------------------------------------------------------------
  544.  
  545. -------------------------------------------------------------------------------
  546. function restartLayer()
  547.   if z > 0 then
  548.     while z > 0 do
  549.       down()
  550.     end
  551.   end
  552.   if z < 0 then
  553.     while z < 0 do
  554.       up()
  555.     end
  556.   end
  557.   if x > 0 then
  558.     turnTo(DIRECTION_WEST)
  559.     nforward(x)
  560.   end
  561.   if x < 0 then
  562.     turnTo(DIRECTION_EAST)
  563.     nforward(x)
  564.   end
  565.   turnTo(DIRECTION_NORTH)
  566. end
  567.  
  568. -------------------------------------------------------------------------------
  569. function validateArgs()
  570.   if #inputs ~= 3 then
  571.     printUsage()
  572.     return false
  573.   end
  574.  
  575.   tunnelWidth = tonumber(inputs[1])
  576.   tunnelHeight = tonumber(inputs[2])
  577.   tunnelDepth = tonumber(inputs[3])
  578.  
  579.   if tunnelWidth <= 3 then
  580.     print('Tunnel width must be higher than 1.')
  581.     printUsage()
  582.     return false
  583.   end
  584.   if tunnelHeight <= 3 then
  585.     print('Tunnel height must be higher than 1.')
  586.     printUsage()
  587.     return false
  588.   end
  589.   if tunnelDepth <= 10 then
  590.     print('Depth must be higher than 10.')
  591.     printUsage()
  592.     return false
  593.   end
  594.  
  595.   return true
  596. end
  597.  
  598. -------------------------------------------------------------------------------
  599. function printUsage()
  600.   print('Usage:')
  601.   print('  bt <width> <height> <depth>')
  602. end
  603.  
  604. -------------------------------------------------------------------------------
  605. function checkLabel()
  606.   local label = os.getComputerLabel()
  607.   if not label then
  608.     label = 'excav-' .. os.getComputerID()
  609.     os.setComputerLabel(label)
  610.     log('Turtle label set to ' .. label)
  611.   end
  612. end
  613.  
  614. -------------------------------------------------------------------------------
  615. function tunnelPrimary(isWidthReverse)
  616.   turtle.digUp()
  617.   up()
  618.   turtle.digUp()
  619.   if isWidthReverse then
  620.     turnTo(DIRECTION_WEST)
  621.   else
  622.     turnTo(DIRECTION_EAST)
  623.   end
  624.   turtle.dig()
  625.  
  626.   quickCheckInventory()
  627.  
  628.   if isWidthReverse then
  629.     while x > 0 do
  630.       forward()
  631.       turtle.digUp()
  632.       turtle.dig()
  633.       turtle.digDown()
  634.       quickCheckInventory()
  635.     end
  636.   else
  637.     while x < tunnelWidth do
  638.       forward()
  639.       turtle.digUp()
  640.       turtle.dig()
  641.       turtle.digDown()
  642.       quickCheckInventory()
  643.     end
  644.   end
  645.  
  646.   forward()
  647.   turtle.digUp()
  648.   turtle.digDown()
  649.  
  650.   quickCheckInventory()
  651. end
  652.  
  653. function doHeight(isHeightReverse)
  654.   tunnelPrimary(false)
  655.   turnAround()
  656.  
  657.   if isHeightReverse then
  658.     if z > 0 then
  659.       down()
  660.       turtle.digDown()
  661.     end
  662.     if z > 0 then
  663.       down()
  664.       turtle.digDown()
  665.     end
  666.     if z > 0 then
  667.       down()
  668.       turtle.digDown()
  669.     end
  670.   else
  671.     if z < tunnelHeight - 1 then
  672.       up()
  673.       turtle.digUp()
  674.    end
  675.    if z < tunnelHeight - 1 then
  676.       up()
  677.       turtle.digUp()
  678.     end
  679.     if z < tunnelHeight - 1 then
  680.       up()
  681.       turtle.digUp()
  682.     end
  683.   end
  684.  
  685.   quickCheckInventory()
  686.  
  687.   tunnelPrimary(true)
  688.   turnAround()
  689. end
  690.  
  691. function tunnelSecondary(isHeightReverse)
  692.   if isHeightReverse then
  693.     while z > 1 do
  694.       doHeight(isHeightReverse)
  695.     end
  696.   else
  697.     while z < tunnelHeight - 1 do
  698.       doHeight(isHeightReverse)
  699.     end
  700.   end
  701. end
  702.  
  703. function tunnel()
  704.   tunnelSecondary(false)
  705.   tunnelSecondary(true)
  706. end
  707.  
  708. -------------------------------------------------------------------------------
  709. function main()
  710.   local success
  711.   checkLabel()
  712.  
  713.   if loadLocation() then
  714.     restartLayer()
  715.   else
  716.     if not validateArgs() then
  717.       return
  718.     end
  719.   end
  720.  
  721.   while true do
  722.     tunnel()
  723.     return
  724.   end
  725. end
  726.  
  727. -------------------------------------------------------------------------------
  728. main()
  729.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement