Jharakn

Quarry

Jan 2nd, 2013
801
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.29 KB | None | 0 0
  1. -- *********************************
  2. -- Quarry Turtle Program
  3. -- By Jharakn
  4. -- *********************************
  5.  
  6. -- Change Log
  7. -- 0.1: first release
  8. -- 0.2: update startup to allow turtle to move down to first solid ground 12/01/13
  9. -- 0.3: pushed the os.getComputerLabel() in the broadcast function to a global variable on suspicion that too many calls of it was causing server instability.
  10. -- 0.4 (27/03/13): updated fuelcheck function to not crash if the server it set up that computercraft turtles use no fuel.
  11. -- 0.5 (04/04/13): changed the gps check at home location to move under the chest not above it to prevent clash my my mining barge.
  12.  
  13.  
  14.  
  15. -- *********************** --
  16. -- Create Global Variables --
  17. -- *********************** --
  18.  
  19. -- using computercraft GPS nomenclature so x is north/south y is east/west and z is up/down
  20.  
  21. current = {x=0, y=0, z=0, d=0}
  22.  
  23. home = {x=0, y=0, z=0}
  24.  
  25. --Quarry point that the turtle was last at, might be a little out of date due to the writescheduler
  26. quarry = {x=0, y=0, z=0, d=0}
  27.  
  28. -- defined at startup these boundaries mark the edge of the quarry
  29. boundary = {xMax=0, xMin=0, yMax=0, yMin=0}
  30.  
  31.  
  32. -- these directions will be updated with the gps function, numbers set to absolute
  33. -- values based on north/easet/south/west values
  34. direction = {forward=0, right=0, back=0, left =0}
  35.  
  36. -- various operation flags for the turtle
  37. flag = {xReverse=false, yReverse=false, atHome=false, quarrying=true, quarryComplete=false}
  38.  
  39. -- misc variables for the turtle
  40. filterSlots = 1
  41. bedrockCounter = 1
  42. bedrockMessageCounter = 1
  43.  
  44. -- misc variables that are not written to the save file
  45. writeSchedulerCounter = 0
  46. turtleName = os.getComputerLabel()
  47.  
  48.  
  49. -- ********************************************************************** --
  50. -- close the program dispaying error message the function was called with --
  51. -- ********************************************************************** --
  52. function errorStop(displayMessage)
  53.  
  54. broadcast("Error - "..displayMessage)
  55.  
  56. print("")
  57. print("turtle encountered an error and stopped")
  58. print("message recieved was:")
  59. print(displayMessage)
  60. print("")
  61. print("press r to restart")
  62. while true do
  63. local event, character = os.pullEvent()
  64. if event == "char" and character == "r" then break end
  65. end
  66. os.reboot()
  67. end
  68.  
  69. -- ****************************************************** --
  70. -- prints a debug message of most of the global variables --
  71. -- call with true to end the program too --
  72. -- ****************************************************** --
  73. function debugger(endProgram)
  74. term.clear()
  75. term.setCursorPos(1, 1)
  76. print("x coords")
  77. print("xMin:", boundary.xMin, " current.x:", current.x, " xMax:", boundary.xMax)
  78. print("y coords")
  79. print("yMin:", boundary.yMin, " current.y:", current.y, " yMax:", boundary.yMax)
  80. print("flag.xReverse=", flag.xReverse, " flag.yReverse=", flag.yReverse)
  81. print("current.d:", current.d)
  82.  
  83. if endProgram == true then
  84. errorStop("debugger wanted to close program")
  85. end
  86. end
  87.  
  88. -- ************************************ --
  89. -- halts the program until c is pressed --
  90. -- ************************************ --
  91. function halt()
  92. while true do
  93. local event, character = os.pullEvent()
  94. if event == "char" and character == "c" then break end
  95. end
  96. end
  97.  
  98. -- **************************************************************** --
  99. -- Broadcasts a message the function was called with to the rednet --
  100. -- **************************************************************** --
  101. function broadcast(message)
  102. print(message)
  103. rednet.open("right")
  104. if (turtleName == nil) then
  105. rednet.broadcast(message)
  106. else
  107. -- Broadcast the message (prefixed with the turtle's id)
  108. rednet.broadcast("[".. turtleName.."] "..message)
  109. end
  110. rednet.close("right")
  111. end
  112.  
  113. -- ************************************************************ --
  114. -- a variaty of tests to ensure the turtle hasn't wandered off --
  115. -- ************************************************************ --
  116. function positionCheck()
  117. --5 is added to the boundarys just in case the turtle is picked up and dropped outside the boundarys of the quarry by a player
  118. if current.x < (boundary.xMin -5) then
  119. errorStop("turtle Moved outside its boundaries")
  120. end
  121. if current.x < (boundary.xMax +5) then
  122. errorStop("turtle Moved outside its boundaries")
  123. end
  124. if current.y < (boundary.yMin -5) then
  125. errorStop("turtle Moved outside its boundaries")
  126. end
  127. if current.y < (boundary.xMax +5) then
  128. errorStop("turtle Moved outside its boundaries")
  129. end
  130. local zCheck = false
  131. if current.z >= 7 then
  132. for i = 7, 199, 3 do
  133. if current.z == i then
  134. zCheck = true
  135. break
  136. end
  137. if zCheck == false then
  138. errorStop("turtle Quarrying on wrong level")
  139. end
  140. end
  141. end
  142. end
  143.  
  144. -- **************************** --
  145. -- Move Up and update current.z --
  146. -- **************************** --
  147. function moveUp()
  148. local counter = 0
  149. while turtle.up() == false do
  150. turtle.digUp()
  151. turtle.attackUp()
  152. counter = counter + 1
  153. if counter == 30 then break end
  154. end
  155. if counter == 100 then
  156. errorStop("timeout on dig up")
  157. else
  158. current.z = current.z + 1
  159. end
  160. end
  161.  
  162. -- ************************************************* --
  163. -- Move Down and update current.z, call with true to --
  164. -- make the function terminate early and return --
  165. -- false if it can't move for detecting bedrock --
  166. -- ************************************************* --
  167. function moveDown(bedrockDetect)
  168. local counter = 0
  169. local returnVar = true
  170. while turtle.down() == false do
  171. turtle.digDown()
  172. turtle.attackDown()
  173. counter = counter + 1
  174. if bedrockDetect == true and counter == 2 then
  175. returnVar = false
  176. break
  177. end
  178. if counter == 30 then break end
  179. end
  180. if counter == 100 then
  181. errorStop("timeout on dig down")
  182. else
  183. if returnVar == true then
  184. current.z = current.z - 1
  185. end
  186. return returnVar
  187. end
  188. end
  189.  
  190. -- ********************************************** --
  191. -- Move Forward and update current.x or current.y --
  192. -- ********************************************** --
  193. function moveForward()
  194. local counter = 0
  195. while turtle.forward() == false do
  196. turtle.dig()
  197. turtle.attack()
  198. counter = counter + 1
  199. if counter == 30 then break end
  200. end
  201. if counter == 100 then
  202. errorStop("timeout on dig forward")
  203. else
  204. if current.d == 1 then current.y = current.y + 1 end
  205. if current.d == 2 then current.x = current.x + 1 end
  206. if current.d == 3 then current.y = current.y - 1 end
  207. if current.d == 4 then current.x = current.x - 1 end
  208. end
  209. end
  210.  
  211. -- ****************************************************************** --
  212. -- Turn the turtle based on input and current.d and update current.d --
  213. -- ****************************************************************** --
  214. function turn(turnToDirection)
  215. while current.d ~= turnToDirection do
  216. if current.d < turnToDirection then
  217. if current.d == 1 and turnToDirection == 4 then
  218. turtle.turnLeft()
  219. current.d = 4
  220. else
  221. turtle.turnRight()
  222. current.d = current.d + 1
  223. end
  224. else
  225. if current.d == 4 and turnToDirection == 1 then
  226. turtle.turnRight()
  227. current.d = 1
  228. else
  229. turtle.turnLeft()
  230. current.d = current.d - 1
  231. end
  232. end
  233. end
  234. end
  235.  
  236. -- ************************************************************** --
  237. -- Goto as specific location and turn to face the right direction --
  238. -- if reverse is true the turtle matches x then y then z rather --
  239. -- than z then y then x --
  240. -- ************************************************************** --
  241. function goto(x, y, z, d, reverse)
  242.  
  243. if reverse == false then
  244. while current.z ~= z do -- match z location
  245. if current.z < z then
  246. moveUp()
  247. writeScheduler()
  248. fuelCheck()
  249. elseif current.z > z then
  250. moveDown(false)
  251. writeScheduler()
  252. fuelCheck()
  253. end
  254. end
  255. elseif reverse == true then
  256. while current.x ~= x do -- match x location
  257. if current.x < x then
  258. turn(2)
  259. moveForward()
  260. writeScheduler()
  261. fuelCheck()
  262. elseif current.x > x then
  263. turn(4)
  264. moveForward()
  265. writeScheduler()
  266. fuelCheck()
  267. end
  268. end
  269. else
  270. errorStop("goto function incorrectly called")
  271. end
  272. while current.y ~= y do -- match y location
  273. if current.y < y then
  274. turn(1)
  275. moveForward()
  276. writeScheduler()
  277. fuelCheck()
  278. elseif current.y > y then
  279. turn(3)
  280. moveForward()
  281. writeScheduler()
  282. fuelCheck()
  283. end
  284. end
  285. if reverse == false then
  286. while current.x ~= x do -- match x location
  287. if current.x < x then
  288. turn(2)
  289. moveForward()
  290. writeScheduler()
  291. fuelCheck()
  292. elseif current.x > x then
  293. turn(4)
  294. moveForward()
  295. writeScheduler()
  296. fuelCheck()
  297. end
  298. end
  299. elseif reverse == true then
  300. while current.z ~= z do -- match z location
  301. if current.z < z then
  302. moveUp()
  303. writeScheduler()
  304. fuelCheck()
  305. elseif current.z > z then
  306. moveDown(false)
  307. writeScheduler()
  308. fuelCheck()
  309. end
  310. end
  311. else
  312. errorStop("goto function incorrectly called")
  313. end
  314. turn(d) -- turn to face the right direction
  315. end
  316.  
  317. -- *************************************************************************************************** --
  318. -- Use the GPS function to detect turtle position and move forward and back to detect facing direction --
  319. -- if called with true will update direction table --
  320. -- *************************************************************************************************** --
  321. function GPS(updateDirection)
  322.  
  323. local forward = 0
  324. local right = 0
  325. local back = 0
  326. local left = 0
  327.  
  328. rednet.open("right")
  329. local x1, y1, z1 = gps.locate(5,false)
  330. if x1 == nil then
  331. errorStop("no GPS signal")
  332. end
  333.  
  334. --If the turtle finds itself below layer 5 move back up to layer 5, then run the gps again
  335. --otherwise it might get blocked by bedrock
  336. if z1 < 5 then
  337. local counter = z1
  338. while counter ~= 5 do
  339. moveUp()
  340. counter = counter + 1
  341. end
  342. x1, y1, z1 = gps.locate(5,false)
  343. if x1 == nil then
  344. errorStop("no GPS signal")
  345. end
  346. end
  347.  
  348. moveForward()
  349.  
  350. local x2, y2, z2 = gps.locate(5,false)
  351. if x2 == nil then
  352. errorStop("no GPS signal")
  353. end
  354. turtle.back()
  355. rednet.close("right")
  356.  
  357. if y1 - y2 == -1 then --have taken two measurments can use the change to work out which direction the turtle moved in
  358. current.d = 1; forward = 1; right = 2; back = 3; left = 4
  359. elseif x1 - x2 == -1 then
  360. current.d = 2; forward = 2; right = 3; back = 4; left = 1
  361. elseif y1 - y2 == 1 then
  362. current.d = 3; forward = 3; right = 4; back = 1; left = 2
  363. elseif x1 - x2 == 1 then
  364. current.d = 4; forward = 4; right = 1; back = 2; left = 3
  365. else
  366. errorStop("both GPS samples are identical, what?!?!?")
  367. end
  368.  
  369. current.x = x1; current.y = y1; current.z = z1
  370.  
  371. if updateDirection == true then
  372. direction.forward = forward; direction.right = right; direction.back = back; direction.left = left
  373. end
  374. end
  375.  
  376. -- ************************************************************** --
  377. -- write the gloabal variables to a file named QuarryInstructions --
  378. -- NOTE: this function should always be called with pcall --
  379. -- or a server lag spike might crash the program --
  380. -- ************************************************************** --
  381. function writeVariables()
  382. local writeTable = {} --build a table to serialise into the new file with all the global variables
  383. writeTable["current_x"] = current.x; writeTable["current_y"] = current.y; writeTable["current_z"] = current.z; writeTable["current_d"] = current.d
  384. writeTable["home_x"] = home.x; writeTable["home_y"] = home.y; writeTable["home_z"] = home.z
  385. writeTable["quarry_x"] = quarry.x; writeTable["quarry_y"] = quarry.y; writeTable["quarry_z"] = quarry.z; writeTable["quarry_d"] = quarry.d
  386. writeTable["boundary_xMax"] = boundary.xMax; writeTable["boundary_xMin"] = boundary.xMin; writeTable["boundary_yMax"] = boundary.yMax; writeTable["boundary_yMin"] = boundary.yMin
  387. writeTable["direction_forward"] = direction.forward; writeTable["direction_right"] = direction.right; writeTable["direction_back"] = direction.back; writeTable["direction_left"] = direction.left
  388. writeTable["flag_xReverse"] = flag.xReverse; writeTable["flag_yReverse"] = flag.yReverse; writeTable["flag_atHome"] = flag.atHome; writeTable["flag_quarrying"] = flag.quarrying; writeTable["flag_quarryComplete"] = flag.quarryComplete
  389. writeTable["filterSlots"] = filterSlots; writeTable["bedrockCounter"] = bedrockCounter; writeTable["bedrockMessageCounter"] = bedrockMessageCounter
  390.  
  391. local file = fs.open("QuarryInstructions","w") --serialise and write the writeTable variable
  392. file.write(textutils.serialize(writeTable))
  393. file.close()
  394. end
  395.  
  396. -- ******************************************************************** --
  397. -- calls the write function ever nth time, designed to prevent constant --
  398. -- write calls generating server lag --
  399. -- ******************************************************************** --
  400. function writeScheduler()
  401. --adjust this variable for delay to instruction saving, higher value = less server lag but a greater error when the turtle is restarting
  402. local saveDelay = 10
  403.  
  404. writeSchedulerCounter = writeSchedulerCounter + 1
  405. if writeSchedulerCounter == saveDelay then
  406. if pcall(writeVariables) == false then
  407. broadcast("Warning - Write failure")
  408. end
  409. writeSchedulerCounter = 0
  410. end
  411. end
  412.  
  413. -- *********************************************************************************************************************************** --
  414. -- Start the program, checking for an existing QuarryInstructions file, if it exists it will detect its location with gps and continue --
  415. -- otherwise it will ask the user for a new instruction set, check its gps location and begin --
  416. -- *********************************************************************************************************************************** --
  417. function startup()
  418. if fs.exists("QuarryInstructions") == true then --existing instructions startup
  419.  
  420. --Read the Quarry instructions file and update global variables
  421. local file = fs.open("QuarryInstructions","r")
  422. local data = file.readAll()
  423. file.close()
  424. local readTable = {}
  425. readTable = textutils.unserialize(data)
  426. current.x = readTable["current_x"]; current.y = readTable["current_y"]; current.z = readTable["current_z"]; current.d = readTable["current_d"]
  427. home.x = readTable["home_x"]; home.y = readTable["home_y"]; home.z = readTable["home_z"]
  428. quarry.x = readTable["quarry_x"]; quarry.y = readTable["quarry_y"]; quarry.z = readTable["quarry_z"]; quarry.d = readTable["quarry_d"]
  429. boundary.xMax = readTable["boundary_xMax"]; boundary.xMin = readTable["boundary_xMin"]; boundary.yMax = readTable["boundary_yMax"]; boundary.yMin = readTable["boundary_yMin"]
  430. direction.forward = readTable["direction_forward"]; direction.right = readTable["direction_right"]; direction.back = readTable["direction_back"]; direction.left = readTable["direction_left"]
  431. flag.xReverse = readTable["flag_xReverse"]; flag.yReverse = readTable["flag_yReverse"]; flag.atHome = readTable["flag_atHome"]; flag.quarrying = readTable["flag_quarrying"]; flag.quarryComplete = readTable["flag_quarryComplete"]
  432. filterSlots = readTable["filterSlots"]; bedrockCounter = readTable["bedrockCounter"]; bedrockMessageCounter = readTable["bedrockMessageCounter"]
  433.  
  434. --examine the atHome flag, if true a gps cycle might cause the turtle to destroy a chest so we move down a space and run the gps instead
  435. if flag.atHome == true then
  436. moveDown(false)
  437. GPS()
  438. moveUp()
  439. elseif flag.atHome == false then
  440. GPS()
  441. else
  442. errorStop("corrupted GPS flag at Startup")
  443. end
  444.  
  445. --examine the quarrying flag, if its true return to the last known quarrying point and continue
  446. --if its false we can assume it was doing an unload cycle, so do that which will automatically
  447. --return to the quarry point on completion
  448. if flag.quarrying == true then
  449. goto(quarry.x, quarry.y, quarry.z, quarry.d, false)
  450. elseif flag.quarrying == false then
  451. unloadCycle()
  452. else
  453. errorStop("corrupted quarry flag at startup")
  454. end
  455.  
  456. broadcast("Resuming existing Quarry")
  457.  
  458. else -- new quarry startup
  459. term.clear() --ask the user to enter a quarry size
  460. term.setCursorPos(1, 1)
  461. print("**********************************")
  462. print("** Quarrying Program by Jharakn **")
  463. print("**********************************")
  464. print("")
  465. print("No previous instruction set found, starting new quarry:")
  466. print("Please enter a Quarry Diameter")
  467. local quarryDiameter = (tonumber(read()) - 1) --need a data validation step here
  468. print("Thank you, starting operation")
  469. sleep(3)
  470. term.clear()
  471. term.setCursorPos(1, 1)
  472.  
  473. GPS(true) --grab the turtle location and update its direction table
  474.  
  475. home.x = current.x; home.y = current.y; home.z = current.z --make the home locations
  476.  
  477. if current.d == 1 then --update the boundaries and flags based on the turtles current direction
  478. boundary.xMax = current.x + quarryDiameter
  479. boundary.xMin = current.x
  480. boundary.yMax = current.y + quarryDiameter
  481. boundary.yMin = current.y
  482. flag.xReverse = false
  483. flag.yReverse = false
  484. flag.atHome = false; flag.Quarrying = true; flag.quarryComplete = false
  485. elseif current.d == 2 then
  486. boundary.xMax = current.x + quarryDiameter
  487. boundary.xMin = current.x
  488. boundary.yMax = current.y
  489. boundary.yMin = current.y - quarryDiameter
  490. flag.xReverse = false
  491. flag.yReverse = true
  492. flag.atHome = false; flag.Quarrying = true; flag.quarryComplete = false
  493. elseif current.d == 3 then
  494. boundary.xMax = current.x
  495. boundary.xMin = current.x - quarryDiameter
  496. boundary.yMax = current.y
  497. boundary.yMin = current.y - quarryDiameter
  498. flag.xReverse = true
  499. flag.yReverse = true
  500. flag.atHome = false; flag.Quarrying = true; flag.quarryComplete = false
  501. elseif current.d == 4 then
  502. boundary.xMax = current.x
  503. boundary.xMin = current.x - quarryDiameter
  504. boundary.yMax = current.y + quarryDiameter
  505. boundary.yMin = current.y
  506. flag.xReverse = true
  507. flag.yReverse = false
  508. flag.atHome = false; flag.Quarrying = true; flag.quarryComplete = false
  509. else
  510. errorStop("corrupted current.d value in startup")
  511. end
  512.  
  513. local i = 1
  514. while turtle.getItemCount(i) ~= 0 do
  515. i = i + 1
  516. end
  517. filterSlots = i - 1 -- because it will count the first empty slot and you the last full one which was the previous number
  518.  
  519. -- Move down until it hits solid ground (needed since my mining barge floats in the air)
  520. while turtle.detectDown() == false do
  521. moveDown()
  522. end
  523.  
  524. local startLayer = 7
  525. while (current.z - startLayer) >= 3 do -- work out which level the turtle need to start on to terminate part 1 at level 5
  526. startLayer = startLayer + 3
  527. end
  528.  
  529. while current.z ~= startLayer do
  530. moveDown(false)
  531. end
  532.  
  533. broadcast("Building New Quarry")
  534.  
  535. end
  536. end
  537.  
  538. -- **************************************************************************** --
  539. -- checks above and below the turtle for filtered blocks as defined at startup --
  540. -- if there not filtered the turtle mines them --
  541. -- **************************************************************************** --
  542. function oreCheck()
  543. local mineUp = true
  544. local mineDown = true
  545.  
  546. if current.z == 5 then --Bedrock cleanup section
  547. while moveDown(true) == true do sleep(0) end
  548. while current.z ~= 5 do moveUp() end
  549.  
  550. --Broadcaster for bedrock to stop the turtle being so quiet when its clearing bedrock
  551. local bedrockDone = bedrockCounter / ((boundary.xMax - boundary.xMin + 1) * (boundary.yMax - boundary.yMin + 1) + 1)
  552.  
  553. if bedrockDone >= 0.1 and bedrockMessageCounter == 1 then
  554. broadcast("("..os.time()..")Clearing Bedrock, 10% complete")
  555. bedrockMessageCounter = 2
  556. end
  557. if bedrockDone >= 0.2 and bedrockMessageCounter == 2 then
  558. broadcast("Clearing Bedrock, 20% complete")
  559. bedrockMessageCounter = 3
  560. end
  561. if bedrockDone >= 0.3 and bedrockMessageCounter == 3 then
  562. broadcast("("..os.time()..")Clearing Bedrock, 30% complete")
  563. bedrockMessageCounter = 4
  564. end
  565. if bedrockDone >= 0.4 and bedrockMessageCounter == 4 then
  566. broadcast("("..os.time()..")Clearing Bedrock, 40% complete")
  567. bedrockMessageCounter = 5
  568. end
  569. if bedrockDone >= 0.5 and bedrockMessageCounter == 5 then
  570. broadcast("("..os.time()..")Clearing Bedrock, 50% complete")
  571. bedrockMessageCounter = 6
  572. end
  573. if bedrockDone >= 0.6 and bedrockMessageCounter == 6 then
  574. broadcast("("..os.time()..")Clearing Bedrock, 60% complete")
  575. bedrockMessageCounter = 7
  576. end
  577. if bedrockDone >= 0.7 and bedrockMessageCounter == 7 then
  578. broadcast("("..os.time()..")Clearing Bedrock, 70% complete")
  579. bedrockMessageCounter = 8
  580. end
  581. if bedrockDone >= 0.8 and bedrockMessageCounter == 8 then
  582. broadcast("("..os.time()..")Clearing Bedrock, 80% complete")
  583. bedrockMessageCounter = 9
  584. end
  585. if bedrockDone >= 0.9 and bedrockMessageCounter == 9 then
  586. broadcast("("..os.time()..")Clearing Bedrock, 90% complete")
  587. bedrockMessageCounter = nil
  588. end
  589. bedrockCounter = bedrockCounter + 1
  590.  
  591.  
  592. else -- Normal quarrying section
  593. mineUp = turtle.detectUp(); mineDown = turtle.detectDown() --add air to make a potential filter block
  594. if mineUp == true or mineDown == true then
  595. for i = 1,filterSlots do
  596. turtle.select(i)
  597. if turtle.compareUp() == true then mineUp = false end
  598. if turtle.compareDown() == true then mineDown = false end
  599. end
  600. if mineUp == true then turtle.digUp() end
  601. if mineDown == true then turtle.digDown() end
  602. end
  603. if mineUp == true or mineDown == true then
  604. broadcast("("..os.time()..")Found Ore @ Level "..current.z)
  605. end
  606. end
  607. end
  608.  
  609. -- *************************************************************************************** --
  610. -- Refuels the turtle if low on fuel from slot 16, returns false if slot 16 is running low --
  611. -- *************************************************************************************** --
  612. function fuelCheck()
  613. --server might be set up that turtles need no fuel check that
  614. if turtle.getFuelLevel() ~= nil then
  615. if turtle.getFuelLevel() < 10 then
  616. turtle.select(16)
  617. turtle.refuel(1)
  618. turtle.select(1)
  619. end
  620. if turtle.getItemCount(16) < 10 then
  621. broadcast("Fuel Low - returning home")
  622. return false
  623. else
  624. return true
  625. end
  626. end
  627. end
  628.  
  629. -- ********************************************************************************************** --
  630. -- checks slot 15 in the inventory, if it has an item the turtle needs unloading so returns false --
  631. -- ********************************************************************************************** --
  632. function invCheck()
  633. if turtle.getItemCount(15) == 0 then
  634. return true
  635. else
  636. broadcast("Inventory full - returning home")
  637. return false
  638. end
  639. end
  640.  
  641. -- ************************************************************************************************* --
  642. -- Returns home to unload its inventory and top up its fuel supplies then return to the mining point --
  643. -- ************************************************************************************************* --
  644. function unloadCycle()
  645.  
  646. --update the turtle objective just in case the chunk unloads whilst its traveling home
  647. --and commit these changes to memory this will also update the quarry locations so its
  648. --got the freshest locations
  649. flag.quarrying = false
  650. pcall(writeVariables)
  651.  
  652. --return home
  653. goto(home.x, home.y, home.z, direction.back, false)
  654.  
  655. --update flag.atHome so if it loads again at this point it won't eat its output chest
  656. flag.atHome = true
  657. pcall(writeVariables)
  658.  
  659. --turn to face unload chest and unload filter items till just 1 remain each
  660. turn(direction.back)
  661. for i = 1,filterSlots do
  662. turtle.select(i)
  663. if turtle.drop(turtle.getItemCount(i)-1) == false then
  664. errorStop("Output chest has overflowed")
  665. end
  666. end
  667.  
  668. --output all of the remaining items except fuel in slot 16
  669. for i = filterSlots + 1, 15 do
  670. turtle.select(i)
  671. if turtle.getItemCount(i) ~= 0 then
  672. if turtle.drop() == false then
  673. errorStop("Output chest has overflowed")
  674. end
  675. end
  676. end
  677.  
  678. -- turn to face the fuel chest and top off slot 16
  679. turn(direction.left)
  680. turtle.select(15)
  681. if turtle.suck() == false then
  682. broadcast("Warning - Fuel chest empty")
  683. end
  684. turtle.transferTo(16, turtle.getItemSpace(16))
  685. turtle.drop()
  686. turtle.select(1)
  687.  
  688. -- update the turtle objective and return to the quarry point
  689. flag.quarrying = true
  690. flag.atHome = false
  691. pcall(writeVariables)
  692. goto(quarry.x, quarry.y, quarry.z, quarry.d, true)
  693. end
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701. -- **************************** --
  702. -- MAIN PROGRAM --
  703. -- **************************** --
  704.  
  705. ----------------------
  706. -- Phase 1: Startup --
  707. ----------------------
  708. broadcast("Starting Program")
  709. if fuelCheck() == false then --preflight checks, needs at least 2 fuel for the gps function called in startup()
  710. errorStop("turtle has no fuel in slot 16")
  711. end
  712.  
  713. startup()
  714. pcall(writeVariables)
  715.  
  716. --debugger(true)
  717.  
  718. ---------------------------
  719. -- Phase 2: Build Quarry --
  720. ---------------------------
  721.  
  722. if flag.quarryComplete == false then
  723. local yMoveSkip = true --yMoveSkip used to prevent a move in the y direction when starting a new z layer
  724. oreCheck()
  725. while flag.quarryComplete == false do -- loop for z
  726.  
  727. if flag.yReverse == false then
  728. while current.y ~= boundary.yMax do --loop for yReverse == false
  729. if yMoveSkip == false then
  730. turn(1)
  731. moveForward()
  732. quarry.x = current.x; quarry.y = current.y; quarry.z = current.z; quarry.d = current.d
  733. writeScheduler()
  734. oreCheck()
  735. if fuelCheck() == false or invCheck() == false then unloadCycle() end
  736. end
  737.  
  738. if flag.xReverse == false then
  739. turn(2)
  740. while current.x ~= boundary.xMax do --loop for xReverse == false (in yReverse == false)
  741. moveForward()
  742. quarry.x = current.x; quarry.y = current.y; quarry.z = current.z; quarry.d = current.d
  743. writeScheduler()
  744. oreCheck()
  745. if fuelCheck() == false or invCheck() == false then unloadCycle() end
  746. end
  747. elseif flag.xReverse == true then
  748. turn(4)
  749. while current.x ~= boundary.xMin do --loop for xReverse == true (in yReverse == false)
  750. moveForward()
  751. quarry.x = current.x; quarry.y = current.y; quarry.z = current.z; quarry.d = current.d
  752. writeScheduler()
  753. oreCheck()
  754. if fuelCheck() == false or invCheck() == false then unloadCycle() end
  755. end
  756. else
  757. errorStop("xReverse flag corrupted")
  758. end
  759.  
  760. if flag.xReverse == true then -- flip the xReverse flag
  761. flag.xReverse = false
  762. else
  763. flag.xReverse = true
  764. end
  765.  
  766. if yMoveSkip == true then yMoveSkip = false end -- remove the yMoveSkip
  767. end
  768. elseif flag.yReverse == true then
  769. while current.y ~= boundary.yMin do --loop for yReverse == true
  770. if yMoveSkip == false then
  771. turn(3)
  772. moveForward()
  773. quarry.x = current.x; quarry.y = current.y; quarry.z = current.z; quarry.d = current.d
  774. writeScheduler()
  775. oreCheck()
  776. if fuelCheck() == false or invCheck() == false then unloadCycle() end
  777. end
  778.  
  779. if flag.xReverse == false then
  780. turn(2)
  781. while current.x ~= boundary.xMax do --loop for xReverse == false (in yReverse == true)
  782. moveForward()
  783. quarry.x = current.x; quarry.y = current.y; quarry.z = current.z; quarry.d = current.d
  784. writeScheduler()
  785. oreCheck()
  786. if fuelCheck() == false or invCheck() == false then unloadCycle() end
  787. end
  788. elseif flag.xReverse == true then
  789. turn(4)
  790. while current.x ~=boundary.xMin do --loop for xReverse == true (in yReverse == true)
  791. moveForward()
  792. quarry.x = current.x; quarry.y = current.y; quarry.z = current.z; quarry.d = current.d
  793. writeScheduler()
  794. oreCheck()
  795. if fuelCheck() == false or invCheck() == false then unloadCycle() end
  796. end
  797. else
  798. errorStop("xReverse flag corrupted")
  799. end
  800.  
  801. if flag.xReverse == true then -- flip the xReverse flag
  802. flag.xReverse = false
  803. else
  804. flag.xReverse = true
  805. end
  806.  
  807. if yMoveSkip == true then yMoveSkip = false end -- remove the yMoveSkip
  808. end
  809. else
  810. errorStop("yReverse flag corrupted")
  811. end
  812.  
  813. if flag.yReverse == false then -- flip the yReverse flag
  814. flag.yReverse = true
  815. else
  816. flag.yReverse = false
  817. end
  818.  
  819. --If the loop compleates at lvl 5 then the quarry is completed
  820. if current.z == 5 then flag.quarryComplete = true end
  821.  
  822. -- keep moving the turtle until it hits z level 5
  823. if current.z ~= 5 then
  824. moveDown(false)
  825. end
  826. if current.z ~= 5 then
  827. moveDown(false)
  828. end
  829. if current.z ~= 5 then
  830. moveDown(false)
  831. end
  832.  
  833. yMoveSkip = true
  834. quarry.x = current.x; quarry.y = current.y; quarry.z = current.z; quarry.d = current.d
  835. writeScheduler()
  836. oreCheck()
  837. pcall(writeVariables)
  838.  
  839. broadcast("Starting Quarrying on level "..current.z)
  840.  
  841. end
  842. end
  843.  
  844.  
  845. -----------------------
  846. -- Phase 3: shutdown --
  847. -----------------------
  848. broadcast("Quarry finished - returning home")
  849. goto(home.x, home.y, home.z, direction.back, false)
  850.  
  851. --final unload of inventory items
  852. for i = 1,filterSlots do
  853. turtle.select(i)
  854. if turtle.drop(turtle.getItemCount(i)-1) == false then
  855. errorStop("Output chest has overflowed")
  856. end
  857. end
  858. for i = filterSlots + 1, 15 do
  859. turtle.select(i)
  860. if turtle.getItemCount(i) ~= 0 then
  861. if turtle.drop() == false then
  862. errorStop("Output chest has overflowed")
  863. end
  864. end
  865. end
  866.  
  867. --remove the QuarryInstructions file as its no longer needed
  868. fs.delete("QuarryInstructions")
  869.  
  870. turn(direction.forward)
  871. broadcast("Turtle Finished")
Advertisement
Add Comment
Please, Sign In to add comment