meigrafd

Turtle Miner - GPSExcavate

Jun 18th, 2017
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.56 KB | None | 0 0
  1. --https://pastebin.com/6DkYuXQa
  2.  
  3. args = {...}
  4. rednet.open("right")
  5. -- Make sure turtle is positioned correctly
  6. term.clear()
  7. term.setCursorPos(1,1)
  8. print("I am set up to dig a rectangle downward in a forward-left direction. There should be a refuel chest to my right and a dropoff chest behind me. Is this how I am set up?")
  9. print("\(y/n\)")
  10. while true do
  11.     local event, character = os.pullEvent()
  12.     if event == "char" and character == "y" then
  13.         print("Initializing...")
  14.         sleep(1)
  15.         break
  16.     elseif event == "char" and character == "n" then
  17.         print("Please set up correctly.")
  18.         error()
  19.     end
  20. end
  21.  
  22. local function forward() --Forward movement
  23.     --Move forward
  24.     local i = 0 --Iterator for bedrock/strong player detection
  25.     while not turtle.forward() do
  26.         if not turtle.dig() then --Detect blocks
  27.             i = i + 1
  28.             turtle.attack() --Detect entities
  29.             if i == 30 then
  30.                 return false --If movement fails
  31.             end
  32.         end
  33.     end
  34.     --Clear above and below
  35.     if turtle.detectUp() then
  36.         turtle.digUp()
  37.     end
  38.     if turtle.detectDown() then
  39.         turtle.digDown()
  40.     end
  41.     --Position tracking
  42.     if currentpos.f == 0 then
  43.         currentpos.z = currentpos.z + 1
  44.     elseif currentpos.f == 1 then
  45.         currentpos.x = currentpos.x - 1
  46.     elseif currentpos.f == 2 then
  47.         currentpos.z = currentpos.z - 1
  48.     elseif currentpos.f == 3 then
  49.         currentpos.x = currentpos.x + 1
  50.     else
  51.         running = false
  52.         error("Something went wrong with the direction :P")
  53.     end
  54.     return true
  55. end
  56. local function turnRight() --Right turn with position tracking
  57.     turtle.turnRight()
  58.     if currentpos.f < 3 then
  59.         currentpos.f = currentpos.f + 1
  60.     else
  61.         currentpos.f = 0
  62.     end
  63. end
  64. local function turnLeft() --Left turn with position tracking
  65.     turtle.turnLeft()
  66.     if currentpos.f > 0 then
  67.         currentpos.f = currentpos.f - 1
  68.     else
  69.         currentpos.f = 3
  70.     end
  71. end
  72. local function down() --Downward movement
  73.     --Move down
  74.     local i = 0 --Iterator for bedrock detection
  75.     while not turtle.down() do
  76.         if not turtle.digDown() then --Detect blocks
  77.             i = i + 1
  78.             turtle.attackDown() --Detect entities
  79.             if i == 25 then
  80.                 return false --If movement fails
  81.             end
  82.         end
  83.     end
  84.     --Position tracking
  85.     currentpos.y = currentpos.y - 1
  86.     return true
  87. end
  88. local function mineDown() --Moves one layer downward
  89.     if currentpos.y == edge.y + 2 then --If close to bottom (2 blocks away)
  90.         if not down() then --If downward movement fails, return to start
  91.             shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
  92.             running = false
  93.             error("I think I tried to dig bedrock.")
  94.         end
  95.     elseif currentpos.y == edge.y + 3 then --If close to bottom (3 blocks away)
  96.         for i=1,2 do
  97.             if not down() then --If downward movement fails, return to start
  98.                 shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
  99.                 running = false
  100.                 error("I think I tried to dig bedrock.")
  101.             end
  102.         end
  103.     else --If far enough from bottom
  104.         for i=1,3 do
  105.             if not down() then --If downward movement fails, return to start
  106.                 shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
  107.                 running = false
  108.                 error("I think I tried to dig bedrock.")
  109.             end
  110.         end
  111.     end
  112. end
  113. local function getFuelLevel() --Check if fuel level is unlimited
  114.     local fuelLevel = turtle.getFuelLevel()
  115.     if type(fuelLevel) == "string" then
  116.         fuelLevel = 9001e9001
  117.     end
  118.     return fuelLevel
  119. end
  120. local function findDistance(x,y,z,newx,newy,newz) --Find how many blocks to travel to get somewhere (non-diagonally)
  121.     local distance = 0
  122.     local xDist = 0
  123.     local yDist = 0
  124.     local zDist = 0
  125.     if x > newx then
  126.         xDist = x - newx
  127.     elseif x < newx then
  128.         xDist = newx - x
  129.     end
  130.     if y > newy then
  131.         yDist = y - newy
  132.     elseif y < newy then
  133.         yDist = newy - y
  134.     end
  135.     if z > newz then
  136.         zDist = z - newz
  137.     elseif z < newz then
  138.         zDist = newz - z
  139.     end
  140.     distance = xDist + yDist + zDist
  141.     return distance
  142. end
  143. local function saveLoc()
  144.     --Write variables to savefile
  145.     local fPos = fs.open("GPSExcavateCurrentpos","w")
  146.     fPos.writeLine(currentpos.x)
  147.     fPos.writeLine(currentpos.y)
  148.     fPos.writeLine(currentpos.z)
  149.     fPos.writeLine(currentpos.f)
  150.     fPos.writeLine(edge.x)
  151.     fPos.writeLine(edge.y)
  152.     fPos.writeLine(edge.z)
  153.     fPos.writeLine(backwards)
  154.     fPos.writeLine(totalMined)
  155.     fPos.writeLine(lastSlot)
  156.     fPos.close()
  157. end
  158. local function detectUnwanted()
  159.     local unwantedSlots = 0
  160.     for i=1, lastSlot do
  161.         turtle.select(i)
  162.         if turtle.compareTo(13) or turtle.compareTo(14) or turtle.compareTo(15) or turtle.compareTo(16) then
  163.             unwantedSlots = unwantedSlots + 1
  164.         end
  165.     end
  166.     turtle.select(1)
  167.     return unwantedSlots
  168. end
  169. local function dropUnwanted()
  170.     local freeSlots = 0
  171.     turtle.turnLeft()
  172.     turtle.turnLeft()
  173.     for i=1, lastSlot do
  174.         turtle.select(i)
  175.         if turtle.compareTo(13) or turtle.compareTo(14) or turtle.compareTo(15) or turtle.compareTo(16) then
  176.             turtle.drop()
  177.         end
  178.     end
  179.     turtle.turnLeft()
  180.     turtle.turnLeft()
  181.     turtle.select(1)
  182. end
  183. local function dropAll() --Drop mined resources, display amounts
  184.     local mined = 0
  185.     turtle.turnRight()
  186.     turtle.turnRight()
  187.     for i=1,lastSlot do
  188.         turtle.select(i)
  189.         mined = mined + turtle.getItemCount(i)
  190.         turtle.drop()
  191.     end
  192.     --This will send to rednet soon
  193.     totalMined = totalMined + mined
  194.     print("Minerals mined this run: "..mined)
  195.     print("Total mined: "..totalMined)
  196.     turtle.select(1)
  197.     turtle.turnRight()
  198.     turtle.turnRight()
  199. end
  200. local function refuel() --Refuel if needed
  201.     turtle.turnRight()
  202.     turtle.select(1)
  203.     while getFuelLevel() < findDistance(currentpos.x,currentpos.y,currentpos.z,0,0,0) + 400 do --Enough to make it back to where he was digging and dig a bit
  204.         turtle.suck()
  205.         if turtle.getItemCount(1) == 0 then --If no fuel is in the box
  206.             print("Please put fuel in my top-left slot, then press space.")
  207.             while true do
  208.                 local event, character = os.pullEvent()
  209.                 if event == "key" and character == 57 then
  210.                     print("Refueling...")
  211.                     sleep(1)
  212.                     break
  213.                 end
  214.             end
  215.         end
  216.         if not turtle.refuel() then --If item isn't fuel
  217.             print("This is not fuel! Please remove it, then press space.")
  218.             while true do
  219.                 local event, character = os.pullEvent()
  220.                 if event == "key" and character == 57 then
  221.                     print("Refueling...")
  222.                     sleep(1)
  223.                     break
  224.                 end
  225.             end
  226.         end
  227.     end
  228.     turtle.turnLeft()
  229. end
  230. local function dropRefuel()
  231.     print("Dropping & refueling")
  232.     shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
  233.     dropAll()
  234.     refuel()
  235.     shell.run("goto","special",currentpos.x,currentpos.y,currentpos.z,currentpos.f,0,0,0,0) --Return to where he left off
  236. end
  237. local function excavate() --The actual excavation process
  238.     while running do --Make sure stop signal hasn't been sent
  239.         turtle.select(1)
  240.         if currentpos.x == 0 and currentpos.y == 0 and currentpos.z == 0 then --To start off a layer down
  241.             down()
  242.             turtle.digDown()
  243.         end
  244.         if ( currentpos.x == edge.x and currentpos.y == edge.y + 1 and currentpos.z == edge.z or currentpos.x == edge.x and currentpos.y == edge.y + 1 and currentpos.z == 0 ) and not backwards or ( currentpos.x == 0 and currentpos.y == edge.y + 1 and currentpos.z == 0 or currentpos.x == 0 and currentpos.y == edge.y + 1 and currentpos.z == edge.z ) and backwards then --Very long check to see if at the end of process
  245.             if lastSlot ~= 16 and detectUnwanted()  then
  246.                 dropUnwanted()
  247.             end
  248.             shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
  249.             dropAll()
  250.             print("Done digging a hole! Whew, that was hard work.")
  251.             done = true --Record that turtle is finished digging
  252.             running = false --Stop other "stopping" loop
  253.             break
  254.         end
  255.         if turtle.getItemCount(lastSlot) > 0 then --Check if inventory is full or fuel is low
  256.             if lastSlot ~= 16 then
  257.                 if detectUnwanted() < 3 then
  258.                     dropUnwanted()
  259.                     dropRefuel()
  260.                 else
  261.                     dropUnwanted()
  262.                 end
  263.                 if turtle.getItemCount(lastSlot) > 0 then
  264.                     turtle.select(lastSlot)
  265.                     while turtle.getItemCount(lastSlot) > 0 do
  266.                         for i=1, lastSlot do
  267.                             turtle.transferTo(i)
  268.                         end
  269.                     end
  270.                     turtle.select(1)
  271.                 end
  272.             else
  273.                 dropRefuel()
  274.             end
  275.         end
  276.         if getFuelLevel() < (findDistance(currentpos.x,currentpos.y,currentpos.z,0,0,0) + 16) then
  277.             if lastSlot ~= 16 then
  278.                 dropUnwanted()
  279.             end
  280.             dropRefuel()
  281.         end
  282.         if ( currentpos.x == edge.x and currentpos.z == edge.z or currentpos.x == edge.x and currentpos.z == 0 ) and not backwards then --If at the end of a layer
  283.             mineDown()
  284.             turnRight()
  285.             turnRight()
  286.             backwards = true --Switching directions
  287.             turtle.digDown()
  288.         elseif ( currentpos.x == 0 and currentpos.z == 0 or currentpos.x == 0 and currentpos.z == edge.z ) and backwards then --If at the end of a layer
  289.             mineDown()
  290.             turnLeft()
  291.             turnLeft()
  292.             backwards = false --Switching directions
  293.             turtle.digDown()
  294.         elseif currentpos.z == edge.z then --If at edge, turn around and do next line
  295.             if backwards then
  296.                 turnRight()
  297.                 forward()
  298.                 turnRight()
  299.             else
  300.                 turnLeft()
  301.                 forward()
  302.                 turnLeft()
  303.             end
  304.         elseif currentpos.z == 0 and currentpos.x ~= 0 then --If at edge, turn around and do next line
  305.             if backwards then
  306.                 turnLeft()
  307.                 forward()
  308.                 turnLeft()
  309.             else
  310.                 turnRight()
  311.                 forward()
  312.                 turnRight()
  313.             end
  314.         end
  315.         if not forward() then --If movement fails, return to start
  316.             shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
  317.             running = false
  318.             error("I think I tried to dig bedrock.")
  319.         end
  320.         saveLoc()
  321.     end
  322. end
  323. local function stop() --Ability to stop turtle mid-excavation. This will wait until current action is done, then exit the excavate function
  324.     while running do
  325.         local event, data, message = os.pullEvent()
  326.         if event == "char" and data == "p" then --If direct keypress
  327.             print("Stopping...")
  328.             running = false
  329.             break
  330.         elseif event == "rednet_message" and message == "stop" then --If rednet stop signal
  331.             print("Stopping...")
  332.             running = false
  333.             id = tonumber(data)
  334.             break
  335.         end
  336.     end
  337. end
  338. local function restart() --To restart from previous digging
  339.     print("Restarting from saved position...")
  340.     if not fs.exists("GPSExcavateCurrentpos") then -- Check for save file
  341.         error("Could not find saved position!")
  342.     end
  343.     --Read save file, change variables
  344.     local fPos = fs.open("GPSExcavateCurrentpos","r")
  345.     currentpos.x = tonumber(fPos.readLine())
  346.     currentpos.y = tonumber(fPos.readLine())
  347.     currentpos.z = tonumber(fPos.readLine())
  348.     currentpos.f = tonumber(fPos.readLine())
  349.     edge.x = tonumber(fPos.readLine())
  350.     edge.y = tonumber(fPos.readLine())
  351.     edge.z = tonumber(fPos.readLine())
  352.     local backwardsString = fPos.readLine()
  353.     if backwardsString == "true" then
  354.         backwards = true
  355.     else
  356.         backwards = false
  357.     end
  358.     totalMined = tonumber(fPos.readLine())
  359.     lastSlot = tonumber(fPos.readLine())
  360.     fPos.close()
  361.     shell.run("goto","special",currentpos.x,currentpos.y,currentpos.z,currentpos.f,0,0,0,0) --Go to position where turtle left off
  362.     restarting = true
  363.     print("Let the diggy-hole recommence!")
  364. end
  365.  
  366. totalMined = 0 --Total mined out blocks over course of excavation
  367. restarting = false --Whether turtle is restarting from save
  368. done = false --Whether turtle has completed excavation
  369. running = true --Whether turtle is currently digging
  370. backwards = false --Which direction turtle is digging the layers currently
  371. currentpos = {} --Current position storage. It's a table just because it is easier, no real need for it
  372. edge = {} --Boundaries of hole. Same deal as currentpos, no real reason to have it as a table
  373. id = -1 --Id of computer that sent the rednet message. This is so that it can reply when it has stopped
  374. w, l, d = 0, 0, 0 --Width, length, depth of hole. This is just for input of numbers
  375. currentpos.x, currentpos.y, currentpos.z, currentpos.f = 0, 0, 0, 0 --Initialise pieces of currentpos
  376. lastSlot = 16 --Slot in which to make sure there are no blocks: this is to keep any comparing slots free
  377.  
  378. if #args == 1 and args[1] == "restart" then --If restarting from save
  379.     restart()
  380. elseif #args == 2 and tonumber(args[1]) > 1 and tonumber(args[2]) > 2 then --If a square hole is wanted
  381.     w = tonumber(args[1])
  382.     l = w
  383.     d = tonumber(args[2])
  384. elseif #args == 3 and tonumber(args[1]) > 1 and tonumber(args[2]) > 1 and tonumber(args[3]) > 2 then --If a non-square hole is wanted
  385.     w = tonumber(args[1])
  386.     l = tonumber(args[2])
  387.     d = tonumber(args[3])
  388. else --If arguments improperly input, print usage
  389.     print("Usage: \"GPSExcavate <side> <depth>\" or \"GPSExcavate <width> <length> <depth>\"")
  390.     print("Note: depth must be at least 3.")
  391.     print("To restart digging, use: \"GPSExcavate restart\"")
  392.     error()
  393. end
  394. if not restarting then --Input edge locations
  395.     edge.x = w - 1
  396.     edge.y = -(d - 1)
  397.     edge.z = l - 1
  398.     print("Would you like the turtle not to collect certain blocks?")
  399.     print("\(y/n\)")
  400.     while true do
  401.         local event, character = os.pullEvent()
  402.         if event == "char" and character == "y" then
  403.             lastSlot = 12
  404.             print("Please put unwanted blocks in the bottom four slots, then press space to continue.")
  405.             while true do
  406.                 local event, character = os.pullEvent()
  407.                 if event == "key" and character == 57 then
  408.                     print("Turtle will not collect these blocks.")
  409.                     break
  410.                 end
  411.             end
  412.             break
  413.         elseif event == "char" and character == "n" then
  414.             lastSlot = 16
  415.             break
  416.         end
  417.     end
  418.     print("Let the diggy-hole commence! Digging a hole "..w.." by "..l.." by "..d.." meters.")
  419. end
  420. print("Press \"p\" to save and stop at any time.")
  421. parallel.waitForAll(excavate,stop) --Actual running of program. This is to enable stopping mid-digging
  422. if not done then --If turtle was stopped before the end
  423.     print("Saving position and dimensions...")
  424.     sleep(1)
  425.     saveLoc()
  426.     print("Position and dimensions saved. Returning to base...")
  427.     shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
  428.     dropAll()
  429.     print("Excavation stopped.")
  430.     if id ~= -1 then --If stop signal was sent by rednet, reply when done returning
  431.         rednet.send(id,"stopped")
  432.     end
  433. else --Get rid of save file if turtle is done excavating. I will find a way to have rednet in here too
  434.     fs.delete("GPSExcavateCurrentpos")
  435. end
  436. print("Next hole please? :D")
  437.  --Delete variables so they don't persist
  438. args, currentpos, edge, id, done, restarting, running, w, l, d, backwards, lastSlot = nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil
  439. rednet.close("right")
Add Comment
Please, Sign In to add comment