midnightstrider

mine

Mar 24th, 2021 (edited)
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.65 KB | None | 0 0
  1. args = { ... }
  2. -- hasModem hasEnderChest size depth [startDepth]
  3.  
  4. -- Used to denote the current direction relative to the direction the
  5. -- turtle was facing when the program starts. The start direction is FORWARD.
  6. direction = {}
  7. direction.FORWARD = 0
  8. direction.RIGHT = 1
  9. direction.BACKWARD = 2
  10. direction.LEFT = 3
  11.  
  12. -- Tasks the tutle performs
  13. task = {}
  14. task.MINESHAFT = 0
  15. task.MINEXZ = 1
  16. task.MINEXZ_TURN = 2
  17. task.NEXT_LEVEL = 3
  18. task.NEXT_LEVEL_TURN = 4
  19. task.FINISH = 5
  20. task.UNLOAD = 6
  21. task.DIG = 7
  22. task.REFUEL = 8
  23.  
  24. -- Specifies the direction a tutle turns as well as provides the turn value.
  25. turnDirection = {
  26. LEFT = -1,
  27. RIGHT = 1
  28. }
  29.  
  30. -- State variables
  31.  
  32. local size = 0
  33. local depth = 0
  34. local startDepth = 0
  35.  
  36. local facing = direction.FORWARD
  37. local currTask = task.MINESHAFT
  38. local xzTurnMoves = 0
  39. local mineDirection = 0
  40. local mineX = 1
  41. local mineZ = 1
  42. local nextLevel = 1 -- counter for digging down to the next mining level
  43. local level = 1
  44.  
  45. local stepsForward = 0
  46. local stepsRight = 0
  47. local stepsDown = 0
  48.  
  49. local savedForward = 0
  50. local savedRight = 0
  51. local savedDown = 0
  52. local savedFacing = 0
  53.  
  54. local isPaused = false
  55. local hasModem = 0
  56. local hasEnderChest = 0
  57. local maxSlot = 16
  58.  
  59. -- save the current state to a file
  60. function save()
  61.  
  62. local file = fs.open("snapshot", "w")
  63. file.writeLine(currTask)
  64. file.writeLine(size)
  65. file.writeLine(depth)
  66. file.writeLine(startDepth)
  67. file.writeLine(nextLevel)
  68. file.writeLine(mineDirection)
  69. file.writeLine(mineX)
  70. file.writeLine(mineZ)
  71. file.writeLine(xzTurnMoves)
  72. file.writeLine(level)
  73. file.writeLine(stepsForward)
  74. file.writeLine(stepsRight)
  75. file.writeLine(stepsDown)
  76. file.writeLine(savedForward)
  77. file.writeLine(savedRight)
  78. file.writeLine(savedDown)
  79. file.writeLine(facing)
  80. file.writeLine(hasModem)
  81. file.writeLine(hasEnderChest)
  82. file.writeLine(maxSlot)
  83. file.close()
  84. end
  85.  
  86. -- resume the state saved in a snapshot file
  87. function resume()
  88. local file = fs.open("snapshot", "r")
  89.  
  90. if file == nil then
  91. print("Failed to open snapshot file. Cannot resume.")
  92. return
  93. end
  94.  
  95. currTask = tonumber(file.readLine())
  96. size = tonumber(file.readLine())
  97. depth = tonumber(file.readLine())
  98. startDepth = tonumber(file.readLine())
  99. nextLevel = tonumber(file.readLine())
  100. mineDirection = tonumber(file.readLine())
  101. mineX = tonumber(file.readLine())
  102. mineZ = tonumber(file.readLine())
  103. xzTurnMoves = tonumber(file.readLine())
  104. level = tonumber(file.readLine())
  105. stepsForward = tonumber(file.readLine())
  106. stepsRight = tonumber(file.readLine())
  107. stepsDown = tonumber(file.readLine())
  108. savedForward = tonumber(file.readLine())
  109. savedRight = tonumber(file.readLine())
  110. savedDown = tonumber(file.readLine())
  111. facing = tonumber(file.readLine())
  112. hasModem = tonumber(file.readLine())
  113. hasEnderChest = tonumber(file.readLine())
  114. maxSlot = tonumber(file.readLine())
  115.  
  116. file.close()
  117. end
  118.  
  119.  
  120. -- Parse Arguments
  121.  
  122. if args[1] == "resume" then
  123.  
  124. resume()
  125. elseif args[1] == nil or args[2] == nil or args[3] == nil or args[4] == nil then
  126.  
  127. print("hasModem hasEnderChest size depth [startDepth]")
  128. print("Ender chest, if any, should be in slot 16")
  129. return
  130. else
  131.  
  132. hasModem = tonumber(args[1])
  133. hasEnderChest = tonumber(args[2])
  134. size = tonumber(args[3])
  135. depth = tonumber(args[4])
  136. startDepth = 0
  137.  
  138. if args[5] ~= nil then
  139. startDepth = tonumber(args[5])
  140. end
  141.  
  142. if hasEnderChest ~= 0 then
  143. maxSlot = 15
  144. end
  145.  
  146. end
  147.  
  148.  
  149. -- update the direction the turtle is facing
  150. function updateFacing(turnDir)
  151.  
  152. facing = facing + turnDir
  153.  
  154. if facing > 3 then
  155. facing = 0
  156. elseif facing < 0 then
  157. facing = 3
  158. end
  159.  
  160. end
  161.  
  162. -- move the turlte forward one block and dig any block in its path
  163. function forward()
  164.  
  165. while not turtle.forward() do
  166. os.sleep(0)
  167. turtle.dig()
  168. end
  169.  
  170. if facing == direction.FORWARD then
  171. stepsForward = stepsForward + 1
  172. elseif facing == direction.RIGHT then
  173. stepsRight = stepsRight + 1
  174. elseif facing == direction.BACKWARD then
  175. stepsForward = stepsForward - 1
  176. elseif facing == direction.LEFT then
  177. stepsRight = stepsRight - 1
  178. end
  179.  
  180. save()
  181.  
  182. end
  183.  
  184. -- move the turlte down one block and dig any block in its path
  185. function down()
  186. count = 0
  187. while not turtle.down() do
  188. os.sleep(0)
  189. turtle.digDown()
  190. if not turtle.digDown() and turtle.detectDown() then
  191. currTask = task.FINISH
  192. stepsDown = stepsDown - 1
  193. print("Failed to dig down. Going home.")
  194. break
  195. end
  196. count = count + 1
  197. end
  198. stepsDown = stepsDown + 1
  199.  
  200. save()
  201. end
  202.  
  203. -- move the turtle up one block and dig any block in its path
  204. function up()
  205. while not turtle.up() do
  206. os.sleep(0)
  207. turtle.digUp()
  208. end
  209. stepsDown = stepsDown - 1
  210.  
  211. save()
  212. end
  213.  
  214. -- turn the turtle to the left
  215. function turnLeft()
  216. turtle.turnLeft()
  217. updateFacing(turnDirection.LEFT)
  218.  
  219. save()
  220. end
  221.  
  222. -- turn the turtle to the right
  223. function turnRight()
  224. turtle.turnRight()
  225. updateFacing(turnDirection.RIGHT)
  226.  
  227. save()
  228. end
  229.  
  230. -- turn the turtle until it is facing the specified direction.
  231. function setFacing(faceDir)
  232. while facing ~= faceDir do
  233. turnRight();
  234. end
  235. end
  236.  
  237. -- save the turtle current position into buffer variables
  238. function savePosition()
  239. savedForward = stepsForward
  240. savedRight = stepsRight
  241. savedDown = stepsDown
  242. savedFacing = facing
  243. end
  244.  
  245. -- start the refuel task
  246. function refuel()
  247.  
  248. for turn=1, 3 do
  249. local hasInventory = false
  250.  
  251. turnLeft()
  252.  
  253. for slot=1, maxSlot do
  254. if turtle.suck() then
  255. hasInventory = true
  256. end
  257. while turtle.refuel(slot) do
  258. end
  259. end
  260.  
  261. if hasInventory then
  262. for slot=1, maxSlot do
  263. turtle.select(slot)
  264. turtle.drop()
  265. end
  266. end
  267.  
  268. end
  269.  
  270. if checkNeedsFuel() then
  271. currTask = task.FINISH
  272. end
  273.  
  274. end
  275.  
  276. -- return to the saved dig location and continue digging
  277. function returnToDig()
  278. while savedDown ~= stepsDown do
  279. if savedDown < stepsDown then
  280. up()
  281. elseif savedDown > stepsDown then
  282. down()
  283. end
  284. end
  285.  
  286. if savedRight < stepsRight then
  287. setFacing(direction.LEFT)
  288. elseif savedRight > stepsRight then
  289. setFacing(direction.RIGHT)
  290. end
  291.  
  292. while savedRight ~= stepsRight do
  293. forward()
  294. end
  295.  
  296. if savedForward < stepsForward then
  297. setFacing(direction.BACKWARD)
  298. elseif savedForward > stepsForward then
  299. setFacing(direction.FORWARD)
  300. end
  301.  
  302. while savedForward ~= stepsForward do
  303. forward()
  304. end
  305.  
  306. setFacing(savedFacing)
  307.  
  308. currTask = task.MINEXZ
  309. end
  310.  
  311. -- unload the turtles ender chest
  312. function enderUnload()
  313. savePosition()
  314.  
  315. turtle.select(16)
  316. turtle.digUp()
  317.  
  318. while not turtle.placeUp() do
  319. turtle.digUp()
  320. end
  321.  
  322. for slot=1, maxSlot do
  323. turtle.select(slot)
  324. turtle.dropUp()
  325. end
  326.  
  327. turtle.select(16)
  328. turtle.drop()
  329. turtle.digUp()
  330. turtle.select(1)
  331.  
  332. currTask = task.DIG
  333. end
  334.  
  335. -- return back to the location the turtle was at when the program was started
  336. function returnHome()
  337. savePosition()
  338.  
  339. if stepsForward > 0 then
  340. setFacing(direction.BACKWARD)
  341. elseif stepsForward < 0 then
  342. setFacing(direction.FORWARD)
  343. end
  344.  
  345. while stepsForward ~= 0 do
  346. forward()
  347. end
  348.  
  349. if stepsRight > 0 then
  350. setFacing(direction.LEFT)
  351. elseif stepsRight < 0 then
  352. setFacing(direction.RIGHT)
  353. end
  354.  
  355. while stepsRight ~= 0 do
  356. forward()
  357. end
  358.  
  359. while stepsDown ~= 0 do
  360. if stepsDown > 0 then
  361. up()
  362. elseif stepsDown < 0 then
  363. down()
  364. end
  365. end
  366.  
  367. setFacing(direction.BACKWARD)
  368.  
  369.  
  370. for slot=1, maxSlot do
  371. turtle.select(slot)
  372. turtle.drop()
  373. end
  374.  
  375.  
  376. if currTask == task.FINISH then
  377. setFacing(direction.FORWARD)
  378. return
  379. end
  380.  
  381. if currTask == task.UNLOAD or currTask == task.REFUEL then
  382. currTask = task.DIG
  383. refuel()
  384. end
  385. end
  386.  
  387. -- determine if inventory is full (or near full)
  388. function isInventoryFull()
  389. local used = 0
  390.  
  391. for slot=1, maxSlot do
  392. used = used + turtle.getItemCount(slot)
  393. end
  394.  
  395. if used > 400 then
  396. return true
  397. end
  398.  
  399. return false
  400. end
  401.  
  402. -- estimate the distance, and therefore the amount of fuel needed to return home
  403. function estimateDistanceHome()
  404. return math.abs(stepsForward) + math.abs(stepsRight) + math.abs(stepsDown) + 16;
  405. end
  406.  
  407. -- determine if the turtle should refuel
  408. function checkNeedsFuel()
  409. local fuel = turtle.getFuelLevel()
  410.  
  411. if fuel ~= nil and fuel <= estimateDistanceHome() + 10 then
  412. return true
  413. end
  414.  
  415. return false
  416. end
  417.  
  418. -- dig along the X/Z axis
  419. function mineXZ()
  420.  
  421. local turnFlag = mineDirection % 2 == 1
  422.  
  423. turtle.digUp()
  424. turtle.digDown()
  425. forward()
  426. turtle.digUp()
  427. turtle.digDown()
  428.  
  429. if checkNeedsFuel() then
  430. currTask = task.UNLOAD
  431. return
  432. end
  433.  
  434. if isInventoryFull() then
  435. currTask = task.UNLOAD
  436. return
  437. end
  438.  
  439. mineZ = mineZ + 1
  440.  
  441. if mineZ >= size then
  442. mineZ = 1
  443. mineX = mineX + 1
  444. mineDirection = mineDirection + 1
  445.  
  446. if mineX > size then
  447. currTask = task.NEXT_LEVEL_TURN
  448. else
  449. currTask = task.MINEXZ_TURN
  450. end
  451. save()
  452. return
  453. end
  454.  
  455. if mineX > size then
  456. mineX = 1
  457. mineZ = 1
  458. --mineDirection = 0
  459. currTask = task.NEXT_LEVEL
  460. save()
  461. end
  462. end
  463.  
  464. -- turn while digging on the X/Z axis
  465. function mineXZ_Turn(moveForward)
  466.  
  467. local turnFlag = mineDirection % 2 == 1
  468.  
  469. if xzTurnMoves > 4 then
  470. xzTurnMoves = 0
  471. currTask = task.MINEXZ
  472. return
  473. end
  474.  
  475. if turnFlag then
  476. if xzTurnMoves == 0 then
  477. turnLeft()
  478. end
  479.  
  480. if xzTurnMoves == 4 then
  481. turnLeft()
  482. end
  483. else
  484. if xzTurnMoves == 0 then
  485. turnRight()
  486. end
  487.  
  488. if xzTurnMoves == 4 then
  489. turnRight()
  490. end
  491. end
  492.  
  493. if xzTurnMoves == 1 and moveForward then
  494. forward()
  495. end
  496.  
  497. if xzTurnMoves == 2 then
  498. turtle.digUp()
  499. end
  500.  
  501. if xzTurnMoves == 3 then
  502. turtle.digDown()
  503. end
  504.  
  505. xzTurnMoves = xzTurnMoves + 1
  506. end
  507.  
  508. -- dig the initial mineshaft to reach the dig start point
  509. function digMineShaft()
  510. if stepsDown == startDepth then
  511. currTask = task.MINEXZ
  512. return
  513. end
  514.  
  515. down()
  516. end
  517.  
  518. -- move down to the next layer
  519. function mineNextLevel()
  520.  
  521. if level >= depth then
  522. currTask = task.FINISH
  523. return
  524. end
  525.  
  526. if nextLevel > 3 then
  527.  
  528. mineX = 1
  529. mineZ = 1
  530. mineDirection = mineDirection + 1
  531.  
  532. level = level + 1
  533. currTask = task.MINEXZ
  534. nextLevel = 1
  535. turtle.digDown()
  536. return
  537. end
  538.  
  539. nextLevel = nextLevel + 1
  540. down()
  541. end
  542.  
  543. -- process messages from wireless computer
  544. function processMessages()
  545. if hasModem == 0 or hasModem == nil then
  546. return
  547. end
  548.  
  549. rednet.open("right")
  550.  
  551. local senderId, message = rednet.receive(0.1)
  552. if message == nil then
  553. return
  554. end
  555.  
  556. print("Received " .. message)
  557.  
  558. if message == "finishMining" then
  559. isPaused = false
  560. currTask = task.FINISH
  561. print("Received command to finish.")
  562. end
  563.  
  564. if message == "unloadMining" then
  565. isPaused = false
  566. currTask = task.UNLOAD
  567. print("Received command to unload inventory at home base.")
  568. end
  569.  
  570. if message == "pauseMining" then
  571. isPaused = true
  572. save()
  573. print("Received command to pause.")
  574. end
  575.  
  576. if message == "resumeMining" then
  577. isPaused = false
  578. print("Received command to resume.")
  579. end
  580.  
  581. if message == "refuelMining" then
  582. isPaused = false
  583. currTask = task.REFUEL
  584. print("Received command to refuel.")
  585. end
  586.  
  587. rednet.send(senderId, "acknowledged")
  588.  
  589. end
  590.  
  591.  
  592. -- main program loop
  593. while true do
  594.  
  595. if not isPaused then
  596.  
  597. if currTask == task.MINESHAFT then
  598. digMineShaft()
  599. end
  600.  
  601. if currTask == task.MINEXZ then
  602. mineXZ()
  603. end
  604.  
  605. if currTask == task.MINEXZ_TURN then
  606. mineXZ_Turn(true)
  607. end
  608.  
  609. if currTask == task.NEXT_LEVEL then
  610. mineNextLevel()
  611. end
  612.  
  613. if currTask == task.NEXT_LEVEL_TURN then
  614. mineXZ_Turn(false)
  615.  
  616. if currTask == task.MINEXZ then
  617. currTask = task.NEXT_LEVEL
  618. end
  619. end
  620.  
  621. if currTask == task.UNLOAD then
  622. if hasEnderChest == 0 then
  623. returnHome()
  624. else
  625. enderUnload()
  626. end
  627. end
  628.  
  629. if currTask == task.REFUEL then
  630. returnHome()
  631. end
  632.  
  633. if currTask == task.DIG then
  634. returnToDig()
  635. end
  636.  
  637. if currTask == task.FINISH then
  638. break
  639. end
  640.  
  641. end
  642.  
  643. processMessages()
  644.  
  645. if not isPaused then
  646. save()
  647. end
  648.  
  649. end
  650.  
  651. returnHome()
  652. setFacing(direction.FORWARD)
  653. save()
Add Comment
Please, Sign In to add comment