DZCreeper

Ender Excavate

Jan 12th, 2013
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.62 KB | None | 0 0
  1. args = {...}
  2. rednet.open("right")
  3. term.clear()
  4. term.setCursorPos(1,1)
  5. print("I am set up to dig a rectangle downward in a forward-left direction. There should be a refuel chest in Slot 1 and Refuel Chest in Slot 2. Is this how I am set up?")
  6. print("They MUST be EnderChests, and DON'T use stacks of fuel smaller than 32")
  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.     while turtle.detectUp() do
  34.         turtle.digUp()
  35.     end
  36.     while turtle.detectDown() do
  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.  
  157. local function enderDrop() --Uses EnderChest in Slot 1 to empty inventory
  158.     turtle.dig()
  159.     turtle.select(1)
  160.     turtle.place()
  161.         for z = 3,16 do
  162.             turtle.select(z)
  163.             turtle.drop()
  164.         end
  165.     turtle.select(1)
  166.     turtle.dig()
  167. end
  168.  
  169. local function enderFuel()
  170.     turtle.dig()
  171.     turtle.select(2)
  172.     turtle.place()
  173.     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
  174.         turtle.suck()
  175.         if turtle.getItemCount(1) == 0 then --If no fuel is in the box
  176.             print("Please put fuel in my top-left slot, then press space.")
  177.             while true do
  178.                 local event, character = os.pullEvent()
  179.                 if event == "key" and character == 57 then
  180.                     print("Refueling...")
  181.                     sleep(1)
  182.                     break
  183.                 end
  184.             end
  185.         end
  186.         if not turtle.refuel() then --If item isn't fuel
  187.             print("This is not fuel! Please remove it, then press space.")
  188.             while true do
  189.                 local event, character = os.pullEvent()
  190.                 if event == "key" and character == 57 then
  191.                     print("Refueling...")
  192.                     sleep(1)
  193.                     break
  194.                 end
  195.             end
  196.         end
  197.     end
  198.     turtle.dig()
  199. end
  200.  
  201. local function dropRefuel()
  202.     print("Dropping & refueling")
  203.     enderDrop()
  204.     enderFuel()
  205. end
  206. local function excavate() --The actual excavation process
  207.     while running do --Make sure stop signal hasn't been sent
  208.         turtle.select(1)
  209.         if currentpos.x == 0 and currentpos.y == 0 and currentpos.z == 0 then --To start off a layer down
  210.             down()
  211.             turtle.digDown()
  212.         end
  213.         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
  214.  
  215.             shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
  216.             enderDrop()
  217.             print("Done digging a hole! Whew, that was hard work.")
  218.             done = true --Record that turtle is finished digging
  219.             running = false --Stop other "stopping" loop
  220.             break
  221.         end
  222.         if turtle.getItemCount(lastSlot) > 0 then --Check if inventory is full or fuel is low
  223.            
  224.             dropRefuel()
  225.         end
  226.         if getFuelLevel() < (findDistance(currentpos.x,currentpos.y,currentpos.z,0,0,0) + 16) then
  227.  
  228.             dropRefuel()
  229.         end
  230.         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
  231.             mineDown()
  232.             turnRight()
  233.             turnRight()
  234.             backwards = true --Switching directions
  235.             turtle.digDown()
  236.         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
  237.             mineDown()
  238.             turnLeft()
  239.             turnLeft()
  240.             backwards = false --Switching directions
  241.             turtle.digDown()
  242.         elseif currentpos.z == edge.z then --If at edge, turn around and do next line
  243.             if backwards then
  244.                 turnRight()
  245.                 forward()
  246.                 turnRight()
  247.             else
  248.                 turnLeft()
  249.                 forward()
  250.                 turnLeft()
  251.             end
  252.         elseif currentpos.z == 0 and currentpos.x ~= 0 then --If at edge, turn around and do next line
  253.             if backwards then
  254.                 turnLeft()
  255.                 forward()
  256.                 turnLeft()
  257.             else
  258.                 turnRight()
  259.                 forward()
  260.                 turnRight()
  261.             end
  262.         end
  263.         if not forward() then --If movement fails, return to start
  264.             shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
  265.             running = false
  266.             error("I think I tried to dig bedrock.")
  267.         end
  268.         saveLoc()
  269.     end
  270. end
  271. local function stop() --Ability to stop turtle mid-excavation. This will wait until current action is done, then exit the excavate function
  272.     while running do
  273.         local event, data, message = os.pullEvent()
  274.         if event == "char" and data == "p" then --If direct keypress
  275.             print("Stopping...")
  276.             running = false
  277.             break
  278.         elseif event == "rednet_message" and message == "stop" then --If rednet stop signal
  279.             print("Stopping...")
  280.             running = false
  281.             id = tonumber(data)
  282.             break
  283.         end
  284.     end
  285. end
  286. local function restart() --To restart from previous digging
  287.     print("Restarting from saved position...")
  288.     if not fs.exists("GPSExcavateCurrentpos") then -- Check for save file
  289.         error("Could not find saved position!")
  290.     end
  291.     --Read save file, change variables
  292.     local fPos = fs.open("GPSExcavateCurrentpos","r")
  293.     currentpos.x = tonumber(fPos.readLine())
  294.     currentpos.y = tonumber(fPos.readLine())
  295.     currentpos.z = tonumber(fPos.readLine())
  296.     currentpos.f = tonumber(fPos.readLine())
  297.     edge.x = tonumber(fPos.readLine())
  298.     edge.y = tonumber(fPos.readLine())
  299.     edge.z = tonumber(fPos.readLine())
  300.     local backwardsString = fPos.readLine()
  301.     if backwardsString == "true" then
  302.         backwards = true
  303.     else
  304.         backwards = false
  305.     end
  306.     totalMined = tonumber(fPos.readLine())
  307.     lastSlot = tonumber(fPos.readLine())
  308.     fPos.close()
  309.     shell.run("goto","special",currentpos.x,currentpos.y,currentpos.z,currentpos.f,0,0,0,0) --Go to position where turtle left off
  310.     restarting = true
  311.     print("Let the diggy-hole recommence!")
  312. end
  313.  
  314.  
  315. restarting = false --Whether turtle is restarting from save
  316. done = false --Whether turtle has completed excavation
  317. running = true --Whether turtle is currently digging
  318. backwards = false --Which direction turtle is digging the layers currently
  319. currentpos = {} --Current position storage. It's a table just because it is easier, no real need for it
  320. edge = {} --Boundaries of hole. Same deal as currentpos, no real reason to have it as a table
  321. id = -1 --Id of computer that sent the rednet message. This is so that it can reply when it has stopped
  322. w, l, d = 0, 0, 0 --Width, length, depth of hole. This is just for input of numbers
  323. currentpos.x, currentpos.y, currentpos.z, currentpos.f = 0, 0, 0, 0 --Initialise pieces of currentpos
  324. lastSlot = 16
  325.  
  326.  
  327. if #args == 1 and args[1] == "restart" then --If restarting from save
  328.     restart()
  329. elseif #args == 2 and tonumber(args[1]) > 1 and tonumber(args[2]) > 2 then --If a square hole is wanted
  330.     w = tonumber(args[1])
  331.     l = w
  332.     d = tonumber(args[2])
  333. 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
  334.     w = tonumber(args[1])
  335.     l = tonumber(args[2])
  336.     d = tonumber(args[3])
  337. else --If arguments improperly input, print usage
  338.     print("Usage: \"GPSExcavate <side> <depth>\" or \"GPSExcavate <width> <length> <depth>\"")
  339.     print("Note: depth must be at least 3.")
  340.     print("To restart digging, use: \"GPSExcavate restart\"")
  341.     error()
  342. end
  343. if not restarting then --Input edge locations
  344.     edge.x = w - 1
  345.     edge.y = -(d - 1)
  346.     edge.z = l - 1
  347.  
  348.     print("Let the diggy-hole commence! Digging a hole "..w.." by "..l.." by "..d.." meters.")
  349. end
  350. print("Press \"p\" to save and stop at any time.")
  351. parallel.waitForAll(excavate,stop) --Actual running of program. This is to enable stopping mid-digging
  352. if not done then --If turtle was stopped before the end
  353.     print("Saving position and dimensions...")
  354.     sleep(1)
  355.     saveLoc()
  356.     print("Position and dimensions saved. Returning to base...")
  357.     shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
  358.     enderDrop()
  359.     print("Excavation stopped.")
  360.     if id ~= -1 then --If stop signal was sent by rednet, reply when done returning
  361.         rednet.send(id,"stopped")
  362.     end
  363. else --Get rid of save file if turtle is done excavating. I will find a way to have rednet in here too
  364.     fs.delete("GPSExcavateCurrentpos")
  365. end
  366. print("Next hole please? :D")
  367.  --Delete variables so they don't persist
  368. args, currentpos, edge, id, done, restarting, running, w, l, d, backwards = nil, nil, nil, nil, nil, nil, nil, nil, nil, nil
  369. rednet.close("right")
Advertisement
Add Comment
Please, Sign In to add comment