Polygone

Justinjah91's Turtle Mining Program

Nov 28th, 2020
2,127
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2. This program is designed to create a branch mine with 3x3 hallways, with multiple turtles working in tandem. Each turtle is responsible for either a branch or the main trunk of the mine. It is recommended to use at least 3 turtles (one for the main trunk and one for a branch on each side of the trunk), but fewer can be used with some manual repositioning. How it works:
  3.  
  4. * The turtle will mine out a 3x3 area. As it does so, it will compare the blocks in the walls with whatever is placed in its first slot. If that block does not match slot 1, it will be replaced with whatever is in slot 2. For example, I use this with stone in slot 1 and cobblestone in slot 2. This means that anything in the walls that ISN'T stone will be replaced with cobblestone. If you were to place cobblestone in slots 1 and 2, the walls would end up being solid cobblestone. As it mines out these slices, a turtle will place torches so that the tunnel remains safe from mob spawns. For optimum torch utilization, users are recommended to make the length of their tunnels a multiple of 10.
  5.  
  6. * Before beginning each 3x3 slice of a tunnel, the turtle will check to make sure it has enough materials to adequately complete that slice. If it does not, it will return to the beginning of the branch mine to resupply. If the turtle's inventory gets full, it will also return to this position to unload.
  7.  
  8. * As the main trunk is mined out, the turtle assigned to this task will leave redstone torches behind in addition to normal torches. These function as markers to let the turtles know which way to go to get to the drop-off chest.
  9.  
  10. * When the turtles are finished with mining out the branches, they will return to the main trunk and position themselves for the next branch. The user will need to specify the direction that the turtle will need to go (either right or left) to reach the next tunnel position.
  11.  
  12. * Lastly, more than 1 turtle can be assigned to work on each side of the main trunk (each working on their own tunnels). The number of turtles needs to be specified by the user.
  13.  
  14. For specifics of the setup, go to https://imgur.com/a/p9jCJT1
  15.  
  16. Inventory Layout:
  17. 1 - Stone
  18. 2 - Cobble
  19. 3 - Torches
  20. 4 - Redstone Torches (Optional)
  21. 16 - Fuel (Optional)
  22. --]]
  23. function usage()  --Displays usage tips when invalid inputs are entered
  24.     usagetext = {
  25.     'Usage: Safebranch <type> <length>','       <direction> <# of turtles>',' ',' ','<type> can be "side" or "main"',' ','<length> is the length of the tunnel','         you want mined',' ','<direction> is the direction the turtle','            should go when finished (l','            or r). This argument may be','            omitted for "main" tunnels',' ','<# of turtles> is the number of turtles','               on this side of the main','               tunnel. This argument','               may be omitted for','               "main" tunnels',' ','The arguments may be omitted for a text','prompt. For more help, type "Safebranch','help"',''}
  26.     textutils.pagedTabulate(usagetext)
  27.     return
  28. end
  29.  
  30. function clc()    --Quick command to clear the terminal (I use matlab a lot, so clc is natural for me)
  31.     term.clear()
  32.     term.setCursorPos(1,1)
  33. end
  34.  
  35. function stuck()    --Displays "I'm stuck" messages
  36.     print('I think I might have gotten myself stuck...')
  37.     print('Terminate program or press enter after obstacle is cleared.')
  38.     read()
  39. end
  40.  
  41. function searchinv()    --Searches turtle's inventory for items like currently selected item, and reloads slot if they are found
  42.     local ini_slot = turtle.getSelectedSlot()
  43.     if turtle.getFuelLevel() == 'unlimited' then
  44.         endslot = 16
  45.     else
  46.         endslot = 15
  47.     end
  48.     for i = 4,endslot do
  49.         restocktorches()    --If turtle is at the reloading station, this makes sure the turtle has at least 32 torches
  50.         turtle.select(i)
  51.         if turtle.compareTo(ini_slot) then
  52.             turtle.transferTo(ini_slot)
  53.             if ini_slot == cobble then
  54.                 if turtle.getItemCount(ini_slot) > 22 then      --At most, a turtle will need 22 pieces of cobble for a slice of branch mine. This makes sure he has it
  55.                     turtle.select(ini_slot)
  56.                     return true
  57.                 end
  58.             else
  59.                 turtle.select(ini_slot)
  60.                 return true
  61.             end
  62.         end
  63.     end
  64.     turtle.select(ini_slot)
  65.     return false
  66. end
  67.  
  68. function addfuel()          --Checks if a turtle needs fuel, and refuels if it does.
  69.     if turtle.getFuelLevel() == 'unlimited' then
  70.     elseif turtle.getFuelLevel() == 0 then
  71.         local ini_slot = turtle.getSelectedSlot()
  72.         turtle.select(fuel)
  73.         if turtle.getItemCount() > 1 then
  74.             turtle.refuel(1)
  75.         elseif turtle.getItemCount() == 1 then
  76.             for i = 4,15 do
  77.                 turtle.select(i)
  78.                 if turtle.refuel(1) then
  79.                     break
  80.                 elseif i == 15 then
  81.                     turtle.select(fuel)
  82.                     print('I am out of fuel. Please load fuel into slot '..tostring(fuel))
  83.                     print('Press enter after fuel is loaded.')
  84.                     read()
  85.                     turtle.refuel(1)               
  86.                 end
  87.             end
  88.         else
  89.             print('Slot '..tostring(fuel)..' must contain a fuel item!')
  90.         end
  91.         turtle.select(ini_slot)
  92.     end
  93. end
  94.  
  95. function tup()      --Guarantees that a turtle will move up when told (gravel, sand, water, lava, and mob proof)
  96.     addfuel()
  97.     local attempt = 0
  98.     while turtle.up() == false do
  99.         turtle.digUp()
  100.         turtle.attackUp()
  101.         attempt = attempt + 1
  102.         if attempt >= 10 then
  103.             stuck()
  104.         end
  105.     end
  106. end
  107.  
  108. function tdn()      --Guarantees that a turtle will move down when told (gravel, sand, water, lava, and mob proof)
  109.     addfuel()
  110.     local attempt = 0
  111.     while turtle.down() == false do
  112.         turtle.digDown()
  113.         turtle.attackDown()
  114.         attempt = attempt + 1
  115.         if attempt >= 10 then
  116.             stuck()
  117.         end
  118.     end
  119. end
  120.  
  121. function tfd()      --Guarantees that a turtle will move forward when told (gravel, sand, water, lava, and mob proof)
  122.     addfuel()
  123.     local attempt = 0
  124.     while turtle.forward() == false do
  125.         turtle.dig()
  126.         turtle.attack()
  127.         attempt = attempt + 1
  128.         if attempt >= 10 then
  129.             stuck()
  130.         end
  131.     end
  132. end
  133.  
  134. function tbk()      --Guarantees that a turtle will move back when told (gravel, sand, water, lava, and mob proof)
  135.     addfuel()
  136.     if turtle.back() == false then
  137.         turtle.turnRight()
  138.         turtle.turnRight()
  139.         tfd()
  140.         turtle.turnRight()
  141.         turtle.turnRight()
  142.     end
  143. end
  144.  
  145. function cup()      --Compares the block above turtle to slot 1 and replaces it with slot 2 if it doesnt match
  146.     local ini_slot = turtle.getSelectedSlot()
  147.     turtle.select(stone)
  148.     if turtle.compareUp() == false then
  149.         turtle.select(cobble)
  150.         if turtle.getItemCount() <= 1 then
  151.             if searchinv() == false then
  152.                 print('I need more of item '..tostring(cobble)..'.')
  153.                 print('Press enter after reloading...')
  154.                 read()
  155.             end
  156.         end
  157.         local attempt = 0
  158.         while turtle.placeUp() == false do
  159.             turtle.digUp()
  160.             turtle.attackUp()
  161.             attempt = attempt + 1
  162.             if attempt >= 10 then
  163.                 stuck()
  164.             end
  165.         end
  166.     end
  167.     turtle.select(ini_slot)
  168. end
  169.  
  170. function cdn()      --Compares the block below turtle to slot 1 and replaces it with slot 2 if it doesnt match
  171.     local ini_slot = turtle.getSelectedSlot()
  172.     turtle.select(stone)
  173.     if turtle.compareDown() == false then
  174.         turtle.select(cobble)
  175.         if turtle.getItemCount() <= 1 then
  176.             if searchinv() == false then
  177.                 print('I need more of item '..tostring(cobble)..'.')
  178.                 print('Press enter after reloading...')
  179.                 read()
  180.             end
  181.         end
  182.         local attempt = 0
  183.         while turtle.placeDown() == false do
  184.             turtle.digDown()
  185.             turtle.attackDown()
  186.             attempt = attempt + 1
  187.             if attempt >= 10 then
  188.                 stuck()
  189.             end
  190.         end
  191.     end
  192.     turtle.select(ini_slot)
  193. end
  194.  
  195. function cfd()          --Compares the block in front of turtle to slot 1 and replaces it with slot 2 if it doesnt match
  196.     local ini_slot = turtle.getSelectedSlot()
  197.     turtle.select(stone)
  198.     if turtle.compare() == false then
  199.         turtle.select(cobble)
  200.         if turtle.getItemCount() <= 1 then
  201.             if searchinv() == false then
  202.                 print('I need more of item '..tostring(cobble)..'.')
  203.                 print('Press enter after reloading...')
  204.                 read()
  205.             end
  206.         end
  207.         local attempt = 0
  208.         while turtle.place() == false do
  209.             turtle.dig()
  210.             turtle.attack()
  211.             attempt = attempt + 1
  212.             if attempt >= 10 then
  213.                 stuck()
  214.             end
  215.         end
  216.     end
  217.     turtle.select(ini_slot)
  218. end
  219.  
  220. function placetorch(torchtype)      --Turns turtle around and places either a torch or a redstone torch
  221.     local ini_slot = turtle.getSelectedSlot()
  222.     torchtype = torchtype or 0
  223.     turtle.turnLeft()
  224.     turtle.turnLeft()
  225.     local attempt = 0
  226.     if string.lower(torchtype) == 'rs' then
  227.         turtle.select(rstorch)
  228.     else
  229.         turtle.select(torch)
  230.     end
  231.     if turtle.getItemCount() <= 1 then
  232.         print('I need more torches in slot '..tostring(turtle.getSelectedSlot())..'.')
  233.         print('Press enter after reloading...')
  234.         read()
  235.     end
  236.     tup()
  237.     tfd()
  238.     while turtle.placeDown() == false do
  239.         turtle.attackDown()
  240.         turtle.digDown()
  241.         attempt = attempt + 1
  242.         if attempt >= 10 then
  243.             stuck()
  244.         end
  245.     end
  246.     tbk()
  247.     tdn()
  248.     turtle.turnLeft()
  249.     turtle.turnLeft()
  250.     turtle.select(ini_slot)
  251. end
  252.  
  253. function checkstock(position)       --Checks to make sure turtle has sufficient supplies for this slice of mining. Position is fed to this function so the turtle can get back to its tunnel if it needs to go restock
  254.     position = position or 0
  255.     local ini_slot = turtle.getSelectedSlot()
  256.     if turtle.getItemCount(stone) < 1 then
  257.         turtle.select(stone)
  258.         if searchinv() == false then
  259.             print('I need more of item '..tostring(stone)..'.')
  260.             print('Press enter after reloading...')
  261.             read()
  262.         end
  263.     elseif turtle.getItemCount(cobble) < 22 then
  264.         turtle.select(cobble)
  265.         if searchinv() == false then
  266.             print('Restocking on item '..tostring(cobble)..'.')
  267.             restock(position)
  268.         end
  269.     elseif turtle.getItemCount(torch) < math.ceil(length/5) then
  270.         turtle.select(torch)
  271.         if searchinv() == false then
  272.             print('Restocking on torches.')
  273.             restock(position)
  274.         end
  275.     elseif tunneltype == 'main' and turtle.getItemCount(rstorch) < math.ceil(length/5) then
  276.         turtle.select(rstorch)
  277.         if searchinv() == false then
  278.             print('Restocking on rs torches.')
  279.             restock(position)
  280.         end
  281.     elseif turtle.getFuelLevel() ~= 'unlimited' and turtle.getItemCount(fuel) < 4 then
  282.         turtle.select(fuel)
  283.         if searchinv() == false then
  284.             print('Restocking on fuel.')
  285.             restock(position)
  286.         end
  287.     else
  288.         emptyslots = 0
  289.         for i = 1,16 do
  290.             if turtle.getItemCount(i) == 0 then
  291.                 emptyslots = emptyslots + 1
  292.             end
  293.         end
  294.         if emptyslots == 0 then
  295.             restock(position)
  296.         else
  297.             return true
  298.         end    
  299.     end
  300.     turtle.select(ini_slot)
  301. end
  302.  
  303. function restock(position)          --Sends the turtle back to the unload/reload chests to restock or deposit excess materials
  304.     turtle.turnLeft()
  305.     tfd()
  306.     turtle.turnLeft()
  307.     if tunneltype == 'side' then        --Determines if the turtle is a branch miner or trunk miner
  308.         for j = 1,position do
  309.             tfd()
  310.         end
  311.         if rs.getInput('front') then    --Determines which way the chests are and orients to begin travel
  312.             turtle.turnRight()
  313.             side = 'l'
  314.         else
  315.             while turtle.forward() == false do
  316.                 turtle.attack()
  317.             end
  318.             while turtle.forward() == false do
  319.                 turtle.attack()
  320.             end
  321.             turtle.turnLeft()
  322.             while turtle.forward() == false do
  323.                 turtle.attack()
  324.             end
  325.             while turtle.forward() == false do
  326.                 turtle.attack()
  327.             end
  328.             side = 'r'
  329.         end
  330.     end
  331.     distfromchest = 0                       --This variable keeps up with how far the turtle travels to reach chest so it can get back to its tunnel
  332.     while turtle.detect() == false do
  333.         while turtle.forward() == false do
  334.             addfuel()
  335.             turtle.attack()
  336.         end
  337.         distfromchest = distfromchest + 1
  338.         if turtle.detect() then
  339.             local boolean, data = turtle.inspect() 
  340.             if string.find(string.lower(data.name),'turtle') then
  341.                 print('Detected another turtle. Waiting in line...')
  342.                 while turtle.detect() do
  343.                     sleep(7)
  344.                 end
  345.             elseif data.name == 'minecraft:chest' then
  346.             else
  347.                 print('Unknown Obstacle. Wating for clearance.')
  348.                 print('Press enter to continue...')
  349.                 read()
  350.             end
  351.         end
  352.     end
  353.     local ini_slot = turtle.getSelectedSlot()
  354.     if turtle.getItemCount(cobble) < 64 then        --Reloads cobble if needed
  355.         for i = 4,15 do
  356.             restocktorches()
  357.             turtle.select(i)
  358.             if turtle.compareTo(cobble) then
  359.                 turtle.transferTo(cobble)
  360.             end
  361.         end
  362.         if turtle.getItemCount(cobble) < 64 then
  363.             turtle.select(cobble)
  364.             turtle.suckDown()
  365.         end
  366.     end
  367.     if tunneltype == 'side' then
  368.         startslot = 4
  369.     else
  370.         startslot = 5
  371.     end
  372.     if turtle.getFuelLimit() == 'unlimited' then
  373.         endslot = 16
  374.     else
  375.         endslot = 15
  376.     end
  377.    
  378.     for i = startslot,endslot do
  379.         restocktorches()
  380.         turtle.select(i)
  381.         if turtle.compareTo(cobble) then            --Deposits excess materials
  382.             turtle.dropDown()
  383.         else
  384.             turtle.drop()
  385.         end
  386.     end
  387.     turtle.select(ini_slot)
  388.     tup()
  389.     turtle.turnLeft()
  390.     tfd()
  391.     tfd()
  392.     tdn()
  393.     turtle.turnLeft()
  394.     for z = distfromchest,1,-1 do               --Returns to branch or main trunk end
  395.         tfd()
  396.     end
  397.     if tunneltype == 'side' then
  398.         if side == 'r' then
  399.             turtle.turnRight()
  400.         else
  401.             tfd()
  402.             tfd()
  403.             turtle.turnLeft()
  404.             tfd()
  405.             tfd()
  406.         end
  407.         for j = 1, position do
  408.             tfd()
  409.         end
  410.     end
  411.     turtle.turnLeft()
  412.     tfd()
  413.     turtle.turnRight() 
  414. end
  415.  
  416. function restocktorches()                   --Controls whether the hopper at the restock chests will load more torches into turtle
  417.     if turtle.getItemCount(torch) > 31 then
  418.         rs.setOutput('right',true)
  419.     else
  420.         rs.setOutput('right',false)
  421.     end
  422. end
  423.  
  424. function moveover()             --Once turtle is done with branch, this function makes it return to the trunk and position itself for the next branch
  425.     tup()
  426.     turtle.turnRight()
  427.     turtle.turnRight()
  428.     turtle.select(torch)
  429.     remainder = (length/10-math.floor(length/10))*10
  430.     for i = length,1,-1 do
  431.         tfd()
  432.         if i == length and remainder <4 and remainder ~= 0 then     --Removes excess torches that are not needed. Light level will stay above 7
  433.             turtle.digDown()
  434.         elseif i/5 == math.floor(i/5) and i/10 ~= math.floor(i/10) then
  435.             turtle.digDown()
  436.         end
  437.     end
  438.     if direction == 'l' then
  439.         turtle.turnRight()
  440.     else
  441.         turtle.turnLeft()
  442.     end
  443.     for i = 1,5*turtles do
  444.         turtle.forward()
  445.     end
  446.     turtle.down()
  447.     if direction == 'l' then
  448.         turtle.turnRight()
  449.     else
  450.         turtle.turnLeft()
  451.     end
  452. end
  453.  
  454. function progress(i)            --Function to display progress bar while mining
  455.     percent = (i+1)/length
  456.     clc()
  457.     print('Mining in progress...')
  458.     print()
  459.     print()
  460.     print('<                                   >')
  461.     term.setCursorPos(2,4)
  462.     bar = math.ceil(percent*35)
  463.     for j = 1,bar do
  464.         write('=')
  465.     end
  466.     term.setCursorPos(17,5)
  467.     print(tostring(percent*100-percent*100%0.1)..'%')
  468. end
  469. ---------------------------------------
  470. -----------------CODE------------------
  471. ---------------------------------------
  472.  
  473. local args = {...}
  474.  
  475. stone = 1    --Slot index for materials
  476. cobble = 2  
  477. torch = 3    
  478. rstorch = 4  
  479. fuel = 16              
  480.  
  481. helptext = {
  482. 'Safebranch is designed to mine out a ','branch mine with 3x3 tunnels with ','multiple turtles mining their own ','branches simultaneously. As they mine, ','they will remove any ores from the ','walls, and fill in empty space to block ','off natural caverns, water, lava, etc. ','In addition, they will place down ','torches periodically to prevent mobs ','from spawning. To work as intended, it ','is recommended to have at least 3 ','turtles going at a time (1 on the main ','"trunk" of the mine, and 1 for each ','branch on either side, but you can use ','as few as 1 turtle with manual ','placement after each tunnel. Below is a','diagram of the intended usage. The Ds ','represent walls, with "dashed" lines ','representing the excavation path of the','turtles.',' ','            D   D',' sideshaft','            D   D',' ','            D   D','DDDDDDDDDDDDDDDDD D D D D D D D','              T D','               TD    mainshaft','              T D','DDDDDDDDDDDDDDDDD D D D D D D D','            D   D',' ','            D   D',' sideshaft','            D   D',' '}          
  483.              
  484. if #args == 0 then   --If no arguments, give a text prompt instead
  485.     print('Is this a side branch or the main shaft? ')
  486.     write('Type main or side: ')
  487.     tunneltype = string.lower(read())
  488.     print()
  489.     print('How long do you want the tunnel to be?')
  490.     write('Enter a number greater than 0: ')
  491.     length = tonumber(read())
  492.     if tunneltype == 'side' then
  493.         print()
  494.         print('Once the turtle is finished, should it move to the left or right to start the next one?')
  495.         write('Type either L or R: ')
  496.         direction = string.lower(read())
  497.         print()
  498.         print('How many turtles (including this one) are on this side of the branch mine?')
  499.         write('Enter a number greater than 0: ')
  500.         turtles = tonumber(read())
  501.     end
  502. elseif string.lower(args[1]) == 'help' then
  503.     clc()
  504.     textutils.pagedTabulate(helptext)
  505.     return
  506. elseif #args == 2 then
  507.     if string.lower(args[1]) ~= 'main' then
  508.         usage()
  509.         return
  510.     end
  511.     tunneltype = string.lower(args[1])
  512.     length = tonumber(args[2])
  513. elseif string.lower(args[1]) == 'side' and tonumber(args[2]) > 0 and (string.lower(args[3]) == 'l' or string.lower(args[3]) == 'r') and tonumber(args[4]) >= 1 then
  514.     tunneltype = string.lower(args[1])
  515.     length = tonumber(args[2])
  516.     direction = string.lower(args[3])
  517.     turtles = tonumber(args[4])
  518. else
  519.     usage()
  520.     return
  521. end
  522.  
  523. clc()
  524.  
  525. for i = 0,length-1 do
  526.     checkstock(i)       --Checks to make sure turtle has enough materials
  527.     if i ~= 0 then      --Checks to see if turtle needs to place a torch behind itself
  528.         if i/5 == math.floor(i/5) then
  529.             placetorch()
  530.         elseif tunneltype == 'main' and (i+1)/5 == math.floor((i+1)/5) then
  531.             placetorch('rs')
  532.         end
  533.     end
  534.    
  535. --Middle column of slice   
  536.     tfd()
  537.     cfd()
  538.     cdn()
  539.     tup()
  540.     cfd()
  541.     tup()
  542.     cfd()
  543.     cup()
  544.     turtle.turnLeft()
  545.    
  546. --Left column of slice
  547.     tfd()
  548.     cfd()
  549.     cup()
  550.     turtle.turnRight()
  551.     cfd()
  552.     tdn()
  553.     cfd()
  554.     turtle.turnLeft()
  555.     cfd()
  556.     tdn()
  557.     cfd()
  558.     cdn()
  559.     turtle.turnRight()
  560.     cfd()
  561.     turtle.turnRight()
  562.    
  563. --Right column of slice
  564.     tfd()
  565.     tfd()
  566.     cfd()
  567.     cdn()
  568.     turtle.turnLeft()
  569.     cfd()
  570.     tup()
  571.     cfd()
  572.     turtle.turnRight()
  573.     cfd()
  574.     tup()
  575.     cfd()
  576.     cup()
  577.     turtle.turnLeft()
  578.     cfd()
  579.     turtle.turnLeft()
  580.     tfd()
  581.     turtle.turnRight()
  582.     tdn()
  583.     tdn()
  584.    
  585.     progress(i)     --Update progress bar
  586.    
  587.     if i == length-1 then   --Place torch at end of tunnel
  588.         placetorch()
  589.         if tunneltype == 'side' then
  590.             moveover()
  591.         end
  592.     end
  593. end
  594.  
  595. turtle.select(1)
RAW Paste Data