XylianLP

goto

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