Advertisement
Wassaa

GPSExcavate

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