emily99

CC: Temp Paste

Jun 22nd, 2023 (edited)
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.24 KB | None | 0 0
  1. if not turtle then
  2. printError("Requires a Turtle")
  3. return
  4. end
  5.  
  6. if 0 ~= tonumber(settings.get("miner.done",0)) then
  7. printError("Current area marked as done! Change settings or run 'miner/sethome.lua' to allow another excavation.")
  8. error()
  9. end
  10.  
  11. -- Mine in a quarry pattern until we hit something we can't dig
  12. local size = tonumber(settings.get("miner.exc_rad",20))
  13. if size < 1 then
  14. printError("Excavate diameter must be positive")
  15. error()
  16. end
  17.  
  18. -- gps.locate() that does not return until it succeeds
  19. local function locate()
  20. local printed = false
  21. local x,y,z
  22. repeat
  23. x,y,z = gps.locate()
  24. if x == nil then
  25. if not printed then
  26. print("GPS Error! Please fix!")
  27. printed = true
  28. end
  29. _await(5)
  30. end
  31. until x ~= nil
  32. return x,y,z
  33. end
  34.  
  35. -- Save settings to disk
  36. local function save()
  37. settings.save(".settings")
  38. end
  39.  
  40. -- Setup network
  41. local donet = false
  42. local sides = {"up","down","left","right","forward","back"}
  43. local function openNet()
  44. if rednet.isOpen() then
  45. donet = true
  46. return true
  47. else
  48. for i = 1,#sides do
  49. if peripheral.getType(sides[i]) == "modem" then
  50. if rednet.open(sides[i]) then
  51. donet = true
  52. return true
  53. end
  54. end
  55. end
  56. end
  57. return false
  58. end
  59. local function sendPos()
  60. if not donet then return end
  61. local x,y,z = locate()
  62. rednet.broadcast({x,y,z},"excgps")
  63. end
  64. if not openNet() then
  65. printError("Failed to open rednet connection; modem required")
  66. error()
  67. end
  68.  
  69. -- Mine straight down this far first
  70. local startDepth = tonumber(settings.get("miner.sdepth",10))
  71. -- Max distance to mine down before stopping, even if no bedrock reached
  72. local maxDepth = tonumber(settings.get("miner.mdepth",999))
  73. -- Extra distance to travel forwards before starting mining
  74. local wanderDist = tonumber(settings.get("miner.wander",0))
  75.  
  76. --The home location to return supplies to, absolute coordinates
  77. local homex = tonumber(settings.get("miner.homex",nil))
  78. local homey = tonumber(settings.get("miner.homey",nil))
  79. local homez = tonumber(settings.get("miner.homez",nil))
  80. local hxDir = tonumber(settings.get("miner.homexd",nil))
  81. local hzDir = tonumber(settings.get("miner.homezd",nil))
  82.  
  83. -- Some forward-declarations
  84. local goTo, refuel, simFwd
  85. local _await, _awaitRefuel
  86.  
  87. local xPos, zPos, depth
  88. local tohomeFuel
  89.  
  90. local function refuel(ammount)
  91. local fuelLevel = turtle.getFuelLevel()
  92. if fuelLevel == "unlimited" then
  93. return true
  94. end
  95.  
  96. local needed = ammount or xPos + zPos + depth + tohomeFuel + 64
  97. if turtle.getFuelLevel() < needed then
  98. for n = 1, 16 do
  99. if turtle.getItemCount(n) > 0 then
  100. turtle.select(n)
  101. if turtle.refuel(1) then
  102. while turtle.getItemCount(n) > 0 and turtle.getFuelLevel() < needed do
  103. turtle.refuel(1)
  104. end
  105. if turtle.getFuelLevel() >= needed then
  106. turtle.select(1)
  107. return true
  108. end
  109. end
  110. end
  111. end
  112. turtle.select(1)
  113. return false
  114. end
  115.  
  116. return true
  117. end
  118. local function fuelCheck()
  119. refuel(16)
  120. _await(0)
  121. end
  122. function _await(s)
  123. sendPos()
  124. sleep(s or 0.05)
  125. end
  126. function _awaitRefuel()
  127. repeat
  128. os.pullEvent("turtle_inventory")
  129. until refuel()
  130. end
  131.  
  132. -- Use two separate locates to determine facing direction
  133. local function getDirs(bMine)
  134. local x1,_1,z1 = locate()
  135. fuelCheck()
  136. while not turtle.forward() do
  137. if bMine then turtle.dig() end
  138. fuelCheck()
  139. _await()
  140. end
  141. local x2,_2,z2 = locate()
  142. local xd,zd = x2-x1,z2-z1
  143. while not turtle.back() do
  144. if bMine then turtle.dig() end
  145. fuelCheck()
  146. _await()
  147. end
  148. return xd,zd
  149. end
  150.  
  151. -- Save current position as the home position if none saved
  152. if homex == nil or homey == nil or homez == nil then
  153. homex, homey, homez = locate()
  154. settings.set("miner.homex",homex)
  155. settings.set("miner.homey",homey)
  156. settings.set("miner.homez",homez)
  157. save()
  158. end
  159. local xDir, zDir = getDirs(hxDir ~= nil and hzDir ~= nil)
  160. if hxDir == nil or hzDir == nil then
  161. hxDir,hzDir = xDir,zDir
  162. settings.set("miner.homexd",hxDir)
  163. settings.set("miner.homezd",hzDir)
  164. save()
  165. end
  166.  
  167. local function turnLeft()
  168. turtle.turnLeft()
  169. xDir, zDir = zDir, -xDir
  170. end
  171.  
  172. local function turnRight()
  173. turtle.turnRight()
  174. xDir, zDir = -zDir, xDir
  175. end
  176.  
  177. -- The position to start this tunnel from
  178. local tx,ty,tz = homex + hxDir*wanderDist, homey-startDepth, homez + hzDir*wanderDist
  179. -- The home position, relative to the tunnel start, y is inverted
  180. local hx,hy,hz = homex-tx,ty-homey,homez-tz
  181. -- The launch position
  182. local sx,sy,sz = locate()
  183.  
  184. local athome = sx==homex and sy==homey and sz==homez
  185. local resume_deposit = not athome and 0 == tonumber(settings.get("miner.is_exc",0))
  186. local resume = not athome
  187.  
  188. -- Relative coordinates to the tunnel start position
  189. depth = ty-sy --inverted!
  190. xPos, zPos = sx-tx, sz-tz
  191.  
  192. -- The fuel required from tx,ty,tz to homex,homey,homez and a little extra
  193. tohomeFuel = math.abs(tx-homex) + math.abs(ty-homey) + math.abs(tz-homez) + 16
  194.  
  195. local function unload(bKeepFuel)
  196. print("Unloading items...")
  197. --Never hold fuel stack if fuel is infinite
  198. if turtle.getFuelLevel() == "unlimited" then
  199. bKeepFuel = false
  200. end
  201. for n = 1, 16 do
  202. local nCount = turtle.getItemCount(n)
  203. if nCount > 0 then
  204. turtle.select(n)
  205. local bDrop = true
  206. if bKeepFuel and turtle.refuel(0) then
  207. bDrop = false
  208. bKeepFuel = false
  209. end
  210. if bDrop then
  211. --First drop into any container above
  212. if turtle.detectUp() then
  213. turtle.dropUp()
  214. end
  215. if turtle.getItemCount(n) > 0 then
  216. --Then to each side, if there's any left
  217. for _ = 1,4 do
  218. if turtle.detect() and turtle.getItemCount(n) > 0 then
  219. turtle.drop()
  220.  
  221. end
  222. turnLeft()
  223. end
  224. end
  225. --finally, if anything remains, just drop it on the ground
  226. if turtle.getItemCount(n) > 0 then
  227. turtle.drop()
  228. end
  229. end
  230. end
  231. end
  232. turtle.select(1)
  233. end
  234.  
  235. local function returnSupplies()
  236. local x, y, z, xd, zd = xPos, depth, zPos, xDir, zDir
  237. print("Returning to surface...")
  238. goTo(0, 0, 0) --returns to the relative start
  239. goTo(hx, hy, hz, hxDir, -hzDir) --returns to home
  240.  
  241. local fuelNeeded = 3 * (x + y + z) + 1 + tohomeFuel
  242. if not refuel(fuelNeeded) then
  243. unload(true)
  244. print("Waiting for fuel")
  245. redstone.setOutput("top", true)
  246. _awaitRefuel()
  247. redstone.setOutput("top", false)
  248. unload(true) --prevent >1 stack of fuel from being stored
  249. else
  250. unload(true)
  251. end
  252.  
  253. print("Resuming mining...")
  254. goTo(0, 0, 0)
  255. goTo(x, y, z, xd, zd)
  256. end
  257.  
  258. local function collect()
  259. local bFull = true
  260. local nTotalItems = 0
  261. for n = 1, 16 do
  262. local nCount = turtle.getItemCount(n)
  263. if nCount == 0 then
  264. bFull = false
  265. end
  266. nTotalItems = nTotalItems + nCount
  267. end
  268.  
  269. if bFull then
  270. print("No empty slots left.")
  271. return false
  272. end
  273. return true
  274. end
  275.  
  276. local function countSlots()
  277. local slotcount = 0
  278. for n = 1, 16 do
  279. if turtle.getItemCount(n) == 0 then
  280. slotcount = slotcount + 1
  281. end
  282. end
  283. return slotcount
  284. end
  285.  
  286. local function tryForwards()
  287. if resume then
  288. simFwd()
  289. return true
  290. end
  291.  
  292. if not refuel() then
  293. print("Not enough Fuel")
  294. returnSupplies()
  295. end
  296.  
  297. while not turtle.forward() do
  298. if turtle.detect() then
  299. if turtle.dig() then
  300. if not collect() then
  301. returnSupplies()
  302. end
  303. else
  304. return false
  305. end
  306. elseif turtle.attack() then
  307. if not collect() then
  308. returnSupplies()
  309. end
  310. else
  311. _await()
  312. end
  313. fuelCheck()
  314. end
  315.  
  316. xPos = xPos + xDir
  317. zPos = zPos + zDir
  318. return true
  319. end
  320.  
  321. local function tryDown()
  322. if not refuel() then
  323. print("Not enough Fuel")
  324. returnSupplies()
  325. end
  326.  
  327. if depth + 1 > maxDepth then
  328. return false
  329. end
  330.  
  331. while not turtle.down() do
  332. if turtle.detectDown() then
  333. if turtle.digDown() then
  334. if not collect() then
  335. returnSupplies()
  336. end
  337. else
  338. return false
  339. end
  340. elseif turtle.attackDown() then
  341. if not collect() then
  342. returnSupplies()
  343. end
  344. else
  345. _await()
  346. end
  347. fuelCheck()
  348. end
  349.  
  350. depth = depth + 1
  351. if math.fmod(depth, 10) == 0 then
  352. print("Descended " .. depth .. " metres.")
  353. end
  354.  
  355. return true
  356. end
  357.  
  358. local function goY(y)
  359. if y == nil then return end
  360. while depth > y do
  361. if turtle.up() then
  362. depth = depth - 1
  363. elseif turtle.digUp() or turtle.attackUp() then
  364. collect()
  365. else
  366. _await()
  367. end
  368. fuelCheck()
  369. end
  370.  
  371. while depth < y do
  372. if turtle.down() then
  373. depth = depth + 1
  374. elseif turtle.digDown() or turtle.attackDown() then
  375. collect()
  376. else
  377. _await()
  378. end
  379. fuelCheck()
  380. end
  381. end
  382.  
  383. local function goX(x)
  384. if x == nil then return end
  385. if xPos > x then
  386. while xDir ~= -1 do
  387. turnLeft()
  388. end
  389. while xPos > x do
  390. if turtle.forward() then
  391. xPos = xPos - 1
  392. elseif turtle.dig() or turtle.attack() then
  393. collect()
  394. else
  395. _await()
  396. end
  397. fuelCheck()
  398. end
  399. elseif xPos < x then
  400. while xDir ~= 1 do
  401. turnLeft()
  402. end
  403. while xPos < x do
  404. if turtle.forward() then
  405. xPos = xPos + 1
  406. elseif turtle.dig() or turtle.attack() then
  407. collect()
  408. else
  409. _await()
  410. end
  411. fuelCheck()
  412. end
  413. end
  414. end
  415.  
  416. local function goZ(z)
  417. if z == nil then return end
  418. if zPos > z then
  419. while zDir ~= -1 do
  420. turnLeft()
  421. end
  422. while zPos > z do
  423. if turtle.forward() then
  424. zPos = zPos - 1
  425. elseif turtle.dig() or turtle.attack() then
  426. collect()
  427. else
  428. _await()
  429. end
  430. fuelCheck()
  431. end
  432. elseif zPos < z then
  433. while zDir ~= 1 do
  434. turnLeft()
  435. end
  436. while zPos < z do
  437. if turtle.forward() then
  438. zPos = zPos + 1
  439. elseif turtle.dig() or turtle.attack() then
  440. collect()
  441. else
  442. _await()
  443. end
  444. fuelCheck()
  445. end
  446. end
  447. end
  448.  
  449. local function goXZ(x,z)
  450. if hzDir ~= 0 then
  451. goZ(z)
  452. goX(x)
  453. else
  454. goX(x)
  455. goZ(z)
  456. end
  457. end
  458.  
  459. function goTo(x, y, z, xd, zd)
  460. goXZ(x,z)
  461. goY(y)
  462.  
  463. while (zd ~= nil and zDir ~= zd) or (xd ~= nil and xDir ~= xd) do
  464. turnLeft()
  465. end
  466. end
  467.  
  468. if athome then
  469. if not refuel(256) then
  470. print("Waiting for fuel...")
  471. redstone.setOutput("top", true)
  472. while not refuel(256) do
  473. os.pullEvent("turtle_inventory")
  474. end
  475. redstone.setOutput("top", false)
  476. end
  477.  
  478. if countSlots() < 15 then
  479. print("Depositing down to 1 stack of fuel...")
  480. unload(true)
  481. end
  482. print("Excavating...")
  483. goTo(0,0,0,hxDir,hzDir)
  484. else
  485. if (depth < 0 and (sy > homey or sx ~= homex or sz ~= homez)) or math.abs(xPos) > size or math.abs(yPos) > size then
  486. printError("Cannot resume from current position; might mine through important things.")
  487. printError("Please reposition me back to my home, or underground near where I was mining!")
  488. error()
  489. end
  490. print("Resuming...")
  491. end
  492.  
  493. turtle.select(1)
  494.  
  495. local alternate = 0
  496. local done = false
  497.  
  498. --Store some values which will be used to resume from a terminated state
  499. local rxp,rzp = xPos,zPos
  500. if resume and not resume_deposit then
  501. xPos,zPos = 0,0
  502. goTo(nil,nil,nil,hxDir,hzDir)
  503. end
  504. function simFwd()
  505. if not resume then return end
  506. xPos = xPos+xDir
  507. zPos = zPos+zDir
  508. if xPos == rxp and zPos == rzp then
  509. resume = false
  510. end
  511. end
  512. --
  513.  
  514. if not resume_deposit then
  515. settings.set("miner.is_exc",1)
  516. save()
  517.  
  518. while not done do
  519. for n = 1, size do
  520. for _ = 1, size - 1 do
  521. if not tryForwards() then
  522. done = true
  523. break
  524. end
  525. end
  526. if done then
  527. break
  528. end
  529. if n < size then
  530. if math.fmod(n + alternate, 2) == 0 then
  531. turnLeft()
  532. if not tryForwards() then
  533. done = true
  534. break
  535. end
  536. turnLeft()
  537. else
  538. turnRight()
  539. if not tryForwards() then
  540. done = true
  541. break
  542. end
  543. turnRight()
  544. end
  545. end
  546. end
  547. if done then
  548. break
  549. end
  550.  
  551. if size > 1 then
  552. if math.fmod(size, 2) == 0 then
  553. turnRight()
  554. else
  555. if alternate == 0 then
  556. turnLeft()
  557. else
  558. turnRight()
  559. end
  560. alternate = 1 - alternate
  561. end
  562. end
  563.  
  564. if not tryDown() then
  565. done = true
  566. break
  567. end
  568. end
  569.  
  570. settings.set("miner.is_exc",0)
  571. save()
  572. end
  573.  
  574. print("Returning to surface...")
  575.  
  576. goTo(0, 0, 0) --returns to the relative start
  577. goTo(hx, hy, hz, hxDir, -hzDir) --returns to home
  578. unload(false)
  579. goTo(nil,nil,nil,hxDir,hzDir)
  580.  
  581. print("Excavate complete.")
  582. if 0 ~= tonumber(settings.get("miner.autoinc",1)) then
  583. settings.set("miner.wander",wanderDist+size)
  584. save()
  585. print("Ready to excavate again!")
  586. else
  587. settings.set("miner.done",1)
  588. save()
  589. end
  590.  
  591.  
Add Comment
Please, Sign In to add comment