DZCreeper

Digger

Feb 5th, 2013
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.38 KB | None | 0 0
  1. args = {...}
  2. rednet.open("right")
  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. 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. 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. dropUnwanted()
  256. if detectUnwanted() < 3 then
  257. dropRefuel()
  258. elseif turtle.getItemCount(lastSlot) > 0 then
  259. turtle.select(lastSlot)
  260. while turtle.getItemCount(lastSlot) > 0 do
  261. for i=1, lastSlot do
  262. turtle.transferTo(i)
  263. end
  264. end
  265. end
  266. else
  267. dropRefuel()
  268. end
  269. end
  270. if getFuelLevel() < (findDistance(currentpos.x,currentpos.y,currentpos.z,0,0,0) + 16) then
  271. if lastSlot ~= 16 then
  272. dropUnwanted()
  273. end
  274. dropRefuel()
  275. end
  276. 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
  277. mineDown()
  278. turnRight()
  279. turnRight()
  280. backwards = true --Switching directions
  281. turtle.digDown()
  282. 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
  283. mineDown()
  284. turnLeft()
  285. turnLeft()
  286. backwards = false --Switching directions
  287. turtle.digDown()
  288. elseif currentpos.z == edge.z then --If at edge, turn around and do next line
  289. if backwards then
  290. turnRight()
  291. forward()
  292. turnRight()
  293. else
  294. turnLeft()
  295. forward()
  296. turnLeft()
  297. end
  298. elseif currentpos.z == 0 and currentpos.x ~= 0 then --If at edge, turn around and do next line
  299. if backwards then
  300. turnLeft()
  301. forward()
  302. turnLeft()
  303. else
  304. turnRight()
  305. forward()
  306. turnRight()
  307. end
  308. end
  309. if not forward() then --If movement fails, return to start
  310. shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f)
  311. running = false
  312. error("I think I tried to dig bedrock.")
  313. end
  314. saveLoc()
  315. end
  316. end
  317. local function stop() --Ability to stop turtle mid-excavation. This will wait until current action is done, then exit the excavate function
  318. while running do
  319. local event, data, message = os.pullEvent()
  320. if event == "char" and data == "p" then --If direct keypress
  321. print("Stopping...")
  322. running = false
  323. break
  324. elseif event == "rednet_message" and message == "stop" then --If rednet stop signal
  325. print("Stopping...")
  326. running = false
  327. id = tonumber(data)
  328. break
  329. end
  330. end
  331. end
  332. local function restart() --To restart from previous digging
  333. print("Restarting from saved position...")
  334. if not fs.exists("GPSExcavateCurrentpos") then -- Check for save file
  335. error("Could not find saved position!")
  336. end
  337. --Read save file, change variables
  338. local fPos = fs.open("GPSExcavateCurrentpos","r")
  339. currentpos.x = tonumber(fPos.readLine())
  340. currentpos.y = tonumber(fPos.readLine())
  341. currentpos.z = tonumber(fPos.readLine())
  342. currentpos.f = tonumber(fPos.readLine())
  343. edge.x = tonumber(fPos.readLine())
  344. edge.y = tonumber(fPos.readLine())
  345. edge.z = tonumber(fPos.readLine())
  346. local backwardsString = fPos.readLine()
  347. if backwardsString == "true" then
  348. backwards = true
  349. else
  350. backwards = false
  351. end
  352. totalMined = tonumber(fPos.readLine())
  353. lastSlot = tonumber(fPos.readLine())
  354. fPos.close()
  355. shell.run("goto","special",currentpos.x,currentpos.y,currentpos.z,currentpos.f,0,0,0,0) --Go to position where turtle left off
  356. restarting = true
  357. print("Let the diggy-hole recommence!")
  358. end
  359.  
  360. totalMined = 0 --Total mined out blocks over course of excavation
  361. restarting = false --Whether turtle is restarting from save
  362. done = false --Whether turtle has completed excavation
  363. running = true --Whether turtle is currently digging
  364. backwards = false --Which direction turtle is digging the layers currently
  365. currentpos = {} --Current position storage. It's a table just because it is easier, no real need for it
  366. edge = {} --Boundaries of hole. Same deal as currentpos, no real reason to have it as a table
  367. id = -1 --Id of computer that sent the rednet message. This is so that it can reply when it has stopped
  368. w, l, d = 0, 0, 0 --Width, length, depth of hole. This is just for input of numbers
  369. currentpos.x, currentpos.y, currentpos.z, currentpos.f = 0, 0, 0, 0 --Initialise pieces of currentpos
  370. lastSlot = 16 --Slot in which to make sure there are no blocks: this is to keep any comparing slots free
  371.  
  372. if #args == 1 and args[1] == "restart" then --If restarting from save
  373. restart()
  374. elseif #args == 2 and tonumber(args[1]) > 1 and tonumber(args[2]) > 2 then --If a square hole is wanted
  375. w = tonumber(args[1])
  376. l = w
  377. d = tonumber(args[2])
  378. 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
  379. w = tonumber(args[1])
  380. l = tonumber(args[2])
  381. d = tonumber(args[3])
  382. else --If arguments improperly input, print usage
  383. print("Usage: \"GPSExcavate <side> <depth>\" or \"GPSExcavate <width> <length> <depth>\"")
  384. print("Note: depth must be at least 3.")
  385. print("To restart digging, use: \"GPSExcavate restart\"")
  386. error()
  387. end
  388. if not restarting then --Input edge locations
  389. edge.x = w - 1
  390. edge.y = -(d - 1)
  391. edge.z = l - 1
  392. print("Would you like the turtle not to collect certain blocks?")
  393. print("\(y/n\)")
  394. while true do
  395. local event, character = os.pullEvent()
  396. if event == "char" and character == "y" then
  397. lastSlot = 12
  398. print("Please put unwanted blocks in the bottom four slots, then press space to continue.")
  399. while true do
  400. local event, character = os.pullEvent()
  401. if event == "key" and character == 57 then
  402. print("Turtle will not collect these blocks.")
  403. break
  404. end
  405. end
  406. break
  407. elseif event == "char" and character == "n" then
  408. lastSlot = 16
  409. break
  410. end
  411. end
  412. print("Let the diggy-hole commence! Digging a hole "..w.." by "..l.." by "..d.." meters.")
  413. end
  414. print("Press \"p\" to save and stop at any time.")
  415. parallel.waitForAll(excavate,stop) --Actual running of program. This is to enable stopping mid-digging
  416. if not done then --If turtle was stopped before the end
  417. print("Saving position and dimensions...")
  418. sleep(1)
  419. saveLoc()
  420. print("Position and dimensions saved. Returning to base...")
  421. shell.run("goto","special",0,0,0,0,currentpos.x,currentpos.y,currentpos.z,currentpos.f) --Return to start
  422. dropAll()
  423. print("Excavation stopped.")
  424. if id ~= -1 then --If stop signal was sent by rednet, reply when done returning
  425. rednet.send(id,"stopped")
  426. end
  427. else --Get rid of save file if turtle is done excavating. I will find a way to have rednet in here too
  428. fs.delete("GPSExcavateCurrentpos")
  429. end
  430. print("Next hole please? :D/>/>/>")
  431. --Delete variables so they don't persist
  432. args, currentpos, edge, id, done, restarting, running, w, l, d, backwards, lastSlot = nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil
  433. rednet.close("right")
Add Comment
Please, Sign In to add comment