PhyscoKillerMonkey

Branch Mine

Apr 1st, 2014
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.76 KB | None | 0 0
  1. --[[
  2. ##name: ]]--
  3. program_name = "am-cc Branch Mining"
  4. --[[
  5. ##file: am/turtle/branch.lua
  6. ##version: ]]--
  7. program_version = "3.5.2.6"
  8. --[[
  9.  
  10. ##type: turtle
  11. ##desc: Mines a branch mine with a trunk and 5 branches each divded into two 50 length halves.
  12.  
  13. ##images:
  14. https://github.com/AngellusMortis/am-cc/tree/master/images/branch.lua
  15.  
  16. ##detailed:
  17. By default, creates a branch mine this fashion (by default):
  18. Top:
  19. Trunk (main shaft)
  20. |-
  21. vv
  22. XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  23. XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  24. |--> XXX_T_________T_________T_________T_________T_________TCCT_________T_________T_________T_________T_________T_XXX
  25. | XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  26. | XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  27. |--> XXX_T_________T_________T_________T_________T_________TCCT_________T_________T_________T_________T_________T_XXX
  28. | XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  29. | XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  30. |--> XXX_T_________T_________T_________T_________T_________TCCT_________T_________T_________T_________T_________T_XXX
  31. | XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  32. | XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  33. |--> XXX_T_________T_________T_________T_________T_________TCCT_________T_________T_________T_________T_________T_XXX
  34. | XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  35. | XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  36. |--> XXX_T_________T_________T_________T_________T_________TCCT_________T_________T_________T_________T_________T_XXX
  37. B XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX__XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  38. r XXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXCZ_CXXXXXXXXXXXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXX_XXX
  39. a ^ ^ ^^ ^ ^ ^
  40. n |-------------------------|------------------------||-|------------------------|-------------------------|
  41. c | || |
  42. h Branch connectors Torch Chest| Fuel Chest
  43. e Chest Chest
  44. s
  45.  
  46. All Chests are to drop off ores/stuff from mining except for the three marked chests near start position (0, 0, 0)
  47.  
  48. Side (branch): Side (trunk, front view for chest locations):
  49. XXXXXX
  50. XXXXXXXXXXXXXXX XX__XX
  51. XTXXTXXTXXTXXTX XXC_XX
  52. X_XX_XX_XX_XX_X XCZ_CX
  53. XXXXXXXXXXXXXXX XXXXXX
  54.  
  55. Key:
  56. X : stone/dirt/gravel/cobblestone
  57. _ : air
  58. T : torch
  59. C : Chest
  60. Z : Coord position (0, 0, 0)
  61.  
  62. Directions (T = turtle, assuming facing in direction of mine):
  63. 2
  64.  
  65. 3 T 1
  66.  
  67. 0
  68.  
  69. Up: 4
  70. Down: 5
  71.  
  72. ##planned:
  73. #save/resume feature
  74. #liquids
  75.  
  76. ##issues:
  77.  
  78. ##parameters:
  79. args[1]: display to redirect to (side or name) (default: nil) enter "false" to disable redirection
  80. args[2]: Use collected coal as fuel (default: false)
  81. args[3]: Number of branches
  82. args[4]: Number of blocks between each branch (default: 2)
  83. args[5]: Length of branch in blocks (default: 52)
  84. args[6]: distance between torches (default: 10)
  85. args[7]: Number of blocks between connections between branches (default: 26)
  86.  
  87. --]]
  88.  
  89. local args = { ... }
  90.  
  91. local log_file = ".branch.log"
  92.  
  93. local settings_file = ".branch.settings"
  94. local settings = nil
  95.  
  96. local progress_file = ".branch.progress"
  97. local progress = nil
  98.  
  99. -- used for testing for ores (anything not in this list is considered an "ore")
  100. -- by default should be cobblestone, dirt, stone, and gravel
  101. local test_slots = {}
  102.  
  103. -- variable to hold wireless modem
  104. local transmitter = nil
  105.  
  106. -- random variables
  107. local ids_line = 1
  108.  
  109. -- error messages
  110. local has_error = false
  111. local message_press_enter = "Press ENTER to continue..."
  112. local message_error_clear = "__clear"
  113. local message_error_file = "File could not be opened"
  114. local message_error_move = "Cannot move"
  115. local message_error_dig = "Cannot dig"
  116. local message_error_fuel = "Out of fuel"
  117. local message_error_chest = "Out of chests"
  118. local message_error_no_chest = "No chest to put items in"
  119. local message_error_torch = "Out of torches"
  120. local message_error_cobble = "Not enough cobblestone"
  121. local message_error_modem = "No modem connected"
  122. local message_error_modem_side = nil -- see init_settings
  123. local message_error_modem_wireless = "Modem cannot do wireless"
  124. local message_error_failed_to_place_chest = "Could not place chest"
  125. local message_error_failed_to_place_torch = "Could not place torch"
  126. local message_error_failed_to_place_torch_wall = "Could not place wall for torch"
  127. local message_error_failed_to_send_message = "Failed to send message"
  128. local message_error_display_width = "Display is not wide enough"
  129. local message_error_display_height = "Display is not tall enough"
  130. local message_error_trunk = "trunk_height must be 2 or 3"
  131. local message_error_liquids = "Encountered liquids"
  132.  
  133.  
  134. -- function prototypes (only as needed)
  135. local print_error = nil
  136. local log = nil
  137. local init_settings = nil
  138. local read_settings = nil
  139. local write_settings = nil
  140. local init_progress = nil
  141. local read_progress = nil
  142. local write_progress = nil
  143. local update_progress = nil
  144. local empty_inventory = nil
  145.  
  146. -- functions
  147. -- need this function for bools
  148. local function setting_or_default(setting_value, default)
  149. if (settings[setting_value] == nil) then
  150. return default
  151. end
  152. return settings[setting_value]
  153. end
  154. -- init settings variable
  155. init_settings = function()
  156. read_settings()
  157.  
  158. settings = settings or {}
  159.  
  160. -- debug settings
  161. settings["debug"] = setting_or_default("debug", false)
  162.  
  163. -- mine config
  164. settings["use_coal"] = setting_or_default("use_coal", false)
  165. settings["number_of_branches"] = settings["number_of_branches"] or 5
  166. settings["branch_between_distance"] = settings["branch_between_distance"] or 2
  167. settings["branch_length"] = settings["branch_length"] or 64
  168. settings["torch_distance"] = settings["torch_distance"] or 10
  169. settings["branch_connector_distance"] = settings["branch_connector_distance"] or 26
  170. settings["trunk_width"] = settings["trunk_width"] or 2
  171. settings["trunk_height"] = settings["trunk_height"] or 3
  172.  
  173. -- turtle(slots) config
  174. -- chest and torch slots are to keep track of supplies
  175. settings["torch_slot"] = settings["torch_slot"] or 1
  176. settings["chest_slot"] = settings["chest_slot"] or 2
  177. -- cobblestone slot use to place so torch can be placed
  178. settings["cobblestone_slot"] = settings["cobblestone_slot"] or 3
  179.  
  180. -- level of coal to reach when refueling
  181. settings["min_continue_fuel_level"] = settings["min_continue_fuel_level"] or 500
  182. -- ticks between attempts to move (see force_forward, force_up, and force_down)
  183. settings["tick_delay"] = settings["tick_delay"] or 2
  184.  
  185. -- wireless broadcast settings
  186. -- do broadcast
  187. -- on receiver will determine wether or not to retransmit (range extension)
  188. settings["transmit_progress"] = setting_or_default("transmit_progress", true)
  189. -- if you have multiple modems (wired and wireless), set this to force
  190. -- side of modem if perhiperal.find() is picking the wired one
  191. settings["transmitter_side"] = setting_or_default("transmitter_side", nil)
  192. -- should not need to change these
  193. settings["transmit_channel"] = settings["transmit_channel"] or 60000
  194. settings["receive_channel"] = settings["receive_channel"] or 60001
  195.  
  196. -- attempt to redirect to monitor for receiver?
  197. -- side monitor if perhiperal.find() is picking an undesired one (works with networked monitors)
  198. settings["redirect_to_monitor"] = setting_or_default("redirect_to_monitor", true)
  199. settings["monitor_side"] = setting_or_default("monitor_side", nil)
  200.  
  201. --save/load functionaility
  202. -- WIP, do NOT use
  203. settings["allow_resume"] = setting_or_default("allow_resume", false)
  204.  
  205. write_settings()
  206.  
  207. message_error_modem_side = "No modem connected ("..tostring(settings["transmitter_side"])..")"
  208. end
  209. -- writes current progress to progress file
  210. write_settings = function()
  211. temp_seralized = textutils.serialize(settings)
  212. handle = fs.open(settings_file, "w")
  213.  
  214. if (handle == nil) then
  215. print_error(message_error_file, true)
  216. else
  217. handle.write(temp_seralized)
  218. handle.close()
  219. end
  220. temp_seralized = string.gsub(temp_seralized, "[\n ]", "")
  221. log("write: settings: "..temp_seralized)
  222. end
  223. -- reads progress from progress file
  224. read_settings = function()
  225. handle = fs.open(settings_file, "r")
  226.  
  227. if not (handle == nil) then
  228. temp_seralized = handle.readAll()
  229. if (string.len(temp_seralized) > 5) then
  230. settings = textutils.unserialize(temp_seralized)
  231. temp_seralized = string.gsub(temp_seralized, "[\n ]", "")
  232. log("read: settings: "..temp_seralized)
  233. handle.close()
  234. end
  235. end
  236. end
  237. -- init progress variable
  238. init_progress = function()
  239. if not (turtle == nil) then
  240. read_progress()
  241. end
  242. if (progress == nil) then
  243. progress = {}
  244. progress["task"] = nil
  245. progress["position"] = {{0, 0, 0}, 2}
  246. progress["branch"] = {}
  247. progress["branch"]["current"] = 1
  248. progress["branch"]["progress"] = nil
  249. progress["branch"]["side"] = nil
  250. progress["branch"]["height"] = 1
  251. progress["trunk"] = {}
  252. progress["trunk"]["remaining"] = nil
  253. if (turtle == nil) then
  254. progress["paired_id"] = nil
  255. progress["retransmit_id"] = nil
  256. end
  257. end
  258.  
  259. if (settings["allow_resume"]) then
  260. write_progress()
  261. end
  262. end
  263. -- writes current progress to progress file
  264. write_progress = function()
  265. temp_seralized = textutils.serialize(progress)
  266. handle = fs.open(progress_file, "w")
  267.  
  268. if (handle == nil) then
  269. print_error(message_error_file, true)
  270. else
  271. handle.write(temp_seralized)
  272. handle.close()
  273. end
  274. temp_seralized = string.gsub(temp_seralized, "[\n ]", "")
  275. log("write: progress: "..temp_seralized)
  276. end
  277. -- reads progress from progress file
  278. read_progress = function()
  279. handle = fs.open(progress_file, "r")
  280.  
  281. if not (handle == nil) then
  282. temp_seralized = handle.readAll()
  283. if (string.len(temp_seralized) > 5) then
  284. progress = textutils.unserialize(temp_seralized)
  285. temp_seralized = string.gsub(temp_seralized, "[\n ]", "")
  286. log("read: progress: "..temp_seralized)
  287. handle.close()
  288. end
  289. end
  290. end
  291. -- updates value in progress variable (DO NOT DO IT MANUALLY)
  292. update_progress = function(progress_item, new_value, index_1, index_2)
  293. log("update: "..tostring(progress_item).."["..tostring(index_1).."]["..tostring(index_2).."] "..tostring(new_value))
  294. if (progress_item == "position") and (index_2 == nil) then
  295. progress[progress_item][index_1] = new_value
  296. elseif (progress_item == "position") then
  297. progress[progress_item][index_1][index_2] = new_value
  298. elseif (progress_item == "branch") then
  299. progress[progress_item][index_1] = new_value
  300. else
  301. progress[progress_item] = new_value
  302. end
  303. if not (turtle == nil) and (settings["allow_resume"]) then
  304. write_progress()
  305. end
  306. end
  307. -- opposite direction
  308. local function get_opposite_direction(direction)
  309. if (direction == 0) then
  310. return 2
  311. elseif (direction == 1) then
  312. return 3
  313. elseif (direction == 2) then
  314. return 0
  315. elseif (direction == 3) then
  316. return 1
  317. elseif (direction == 4) then
  318. return 5
  319. elseif (direction == 5) then
  320. return 4
  321. end
  322. return nil
  323. end
  324. -- if debug, logs message to file
  325. log = function(message)
  326. if (settings["debug"]) then
  327. handle = nil
  328. if (fs.exists(log_file)) then
  329. handle = fs.open(log_file, "a")
  330. else
  331. handle = fs.open(log_file, "w")
  332. end
  333. if (handle == nil) then
  334. settings["debug"] = false
  335. print_error(message_error_file)
  336. else
  337. handle.writeLine("["..tostring(os.time()).."]: "..tostring(message))
  338. handle.close()
  339. end
  340. end
  341. end
  342. -- send message to receiver
  343. local function send_message(message_type, message_data)
  344. message_data = message_data or {}
  345. if (message_data["turtle_id"] == nil) and not (turtle == nil) then
  346. message_data["turtle_id"] = os.computerID()
  347. elseif (message_data["turtle_id"] == nil) then
  348. message_data["turtle_id"] = progress["paired_id"]
  349. end
  350. if (message_data["type"] == nil) then
  351. message_data["type"] = message_type
  352. end
  353. if (turtle == nil) then
  354. message_data["retransmit_id"] = os.computerID()
  355. end
  356.  
  357. if (message_data["type"] == nil) or (message_data["turtle_id"] == nil) then
  358. temp_seralized = string.gsub(textutils.serialize(message_data), "[\n ]", "")
  359. log("send: "..temp_seralized)
  360. print_error(message_error_failed_to_send_message, false, false)
  361. return
  362. end
  363. temp_seralized = string.gsub(textutils.serialize(message_data), "[\n ]", "")
  364. log("send: "..temp_seralized)
  365. transmitter.transmit(settings["transmit_channel"], settings["receive_channel"], textutils.serialize(message_data))
  366.  
  367. if (message_type == "check") or (message_type == "branch_update") then
  368. os.startTimer(3)
  369. local do_loop = true
  370. -- open channel for listening
  371. if (turtle == nil) then
  372. transmitter.close(settings["transmit_channel"])
  373. end
  374. transmitter.open(settings["receive_channel"])
  375. while (do_loop) do
  376. local event, modemSide, senderChannel,
  377. replyChannel, message, senderDistance = os.pullEvent()
  378.  
  379. temp_seralized = string.gsub(tostring(message), "[\n ]", "")
  380. log("pull: "..event..": "..temp_seralized)
  381. if (event == "modem_message") then
  382. message_data = textutils.unserialize(message)
  383.  
  384. -- confrim event
  385. if (message_data["type"] == "confrim") and
  386. ((not (turtle == nil) and (message_data["turtle_id"] == os.computerID())) or
  387. ((turtle == nil) and (message_data["turtle_id"] == progress["paired_id"]) and (message_data["retransmit_id"] == os.computerID()))) then
  388. do_loop = false
  389. end
  390. elseif (event == "timer") then
  391. log("timer")
  392. do_loop = false
  393. message_data = {}
  394. message_data["number_of_branches"] = settings["number_of_branches"]
  395. message_data["branch"] = progress["branch"]["current"]
  396. send_message("start", message_data)
  397. end
  398. end
  399. transmitter.close(settings["receive_channel"])
  400. if (turtle == nil) then
  401. transmitter.open(settings["transmit_channel"])
  402. end
  403. end
  404. end
  405. -- Force clears the current terminal line and then
  406. -- sets it to first positions (was having trouble with term.clearLine())
  407. local function clear_line()
  408. pos = {term.getCursorPos()}
  409. term_size = {term.getSize()}
  410. term.setCursorPos(1, pos[2])
  411. term.write(string.rep(" ",term_size[1]))
  412. term.setCursorPos(1, pos[2])
  413. end
  414. -- used by receiver to confrim request
  415. local function send_confrim(id)
  416. local confrim_data = {}
  417. confrim_data["type"] = "confrim"
  418. confrim_data["turtle_id"] = id
  419. if not (progress["retransmit_id"] == nil) then
  420. confrim_data["retransmit_id"] = progress["retransmit_id"]
  421. end
  422. temp_seralized = string.gsub(textutils.serialize(confrim_data), "[\n ]", "")
  423. log("confrim: "..temp_seralized)
  424. transmitter.transmit(settings["receive_channel"], settings["transmit_channel"], textutils.serialize(confrim_data))
  425. end
  426. -- writes text in color, if display supports color
  427. local function color_write(text, color)
  428. if (term.isColor()) then
  429. term.setTextColor(color)
  430. end
  431. term.write(text)
  432. if (term.isColor()) then
  433. term.setTextColor(colors.white)
  434. end
  435. end
  436. -- prints message_press_enter on last line and waits for user to press ENTER
  437. local function wait_for_enter()
  438. term_size = {term.getSize()}
  439. term.setCursorPos(1, (term_size[2]-1))
  440. clear_line()
  441. print(message_press_enter)
  442. repeat
  443. event, param1 = os.pullEvent("key")
  444. until param1 == 28
  445. term.setCursorPos(1, (term_size[2]-1))
  446. clear_line()
  447. end
  448. -- prints error on second to last line and then waits for ENTER
  449. -- if fatal is set to true, terminates program instead with error message
  450. print_error = function (error_message, fatal, wait)
  451. fatal = fatal or false
  452. if (turtle == nil) and (wait == nil) then
  453. wait = false
  454. elseif (wait == nil) then
  455. wait = true
  456. end
  457. local prefix = "ERROR"
  458. if (wait == false) then
  459. prefix = "WARN"
  460. end
  461. log(prefix..": "..error_message.." ["..tostring(fatal).."]["..tostring(wait).."]")
  462.  
  463. -- if turtle and transmit is on, send to receiver
  464. if (not (turtle == nil)) and (settings["transmit_progress"]) then
  465. local error_data = {}
  466. error_data["error"] = error_message
  467. error_data["wait"] = wait
  468. send_message("error", error_data)
  469. end
  470.  
  471. -- if fatal, terminate
  472. if (fatal) then
  473. error(error_message)
  474. else
  475. has_error = true
  476. term_size = {term.getSize()}
  477. term.setCursorPos(1, (term_size[2]-2))
  478. clear_line()
  479. color_write(prefix..": "..error_message, colors.red)
  480. -- if turtle, wait for user to press ENTER
  481. if not (turtle == nil) then
  482. if (wait) then
  483. wait_for_enter()
  484. term.setCursorPos(1, (term_size[2]-2))
  485. clear_line()
  486. has_error = false
  487. end
  488. -- if transmit, tell receiver error has been cleared
  489. if (settings["transmit_progress"]) then
  490. local error_data = {}
  491. error_data["error"] = message_error_clear
  492. send_message("error", error_data)
  493. end
  494. else
  495. if (wait) then
  496. wait_for_enter()
  497. term.setCursorPos(1, (term_size[2]-2))
  498. clear_line()
  499. end
  500. end
  501. end
  502. end
  503. -- set current task for turtle (just for visual)
  504. local function set_task(main, sub)
  505. update_progress("task", main)
  506. log("task: "..main.." "..sub)
  507. term_size = {term.getSize()}
  508. term.setCursorPos(1,ids_line+4)
  509. clear_line()
  510. color_write(main, colors.cyan)
  511. term.setCursorPos(term_size[1]-((#sub)-1),ids_line+4)
  512. color_write(sub, colors.yellow)
  513.  
  514. -- if turtle and transmit, send task data to receivers
  515. if (not (turtle == nil)) and (settings["transmit_progress"]) then
  516. local send_data = {}
  517. send_data["main"] = main
  518. send_data["sub"] = sub
  519. send_message("task", send_data)
  520. end
  521. end
  522.  
  523. -- turtle functions
  524. -- rotate turtle and update progress["position"]
  525. local function rotate(direction)
  526. local offset = direction - progress["position"][2]
  527. update_progress("position", direction, 2)
  528. if (offset == 0) then
  529. return
  530. elseif (math.abs(offset) == 2) then
  531. turtle.turnRight()
  532. turtle.turnRight()
  533. elseif (offset == 3) or (offset == -1) then
  534. turtle.turnRight()
  535. else
  536. turtle.turnLeft()
  537. end
  538. end
  539. -- only works in CC1.6
  540. local function detect_liquid_forward()
  541. if (turtle.detect()) then
  542. turtle.select(settings["cobblestone_slot"])
  543. if (turtle.place()) then
  544. print_error(message_error_liquids)
  545. end
  546. end
  547. end
  548. -- force the turtle to move forward
  549. -- kills anything in way
  550. -- digs anything out of the way
  551. -- can generate error if unable to move after 10 tries and block in front or 50 tries (mob)
  552. -- updates progress["position"]
  553. local function force_forward(allow_fail)
  554. allow_fail = allow_fail or false
  555. count = 0
  556. detect_liquid_forward()
  557. local move_success = turtle.forward()
  558. while not (move_success) do
  559. turtle.select(1)
  560. turtle.attack()
  561. turtle.dig()
  562.  
  563. count = count + 1
  564. if (count > 10 and turtle.detect()) or (count > 50) then
  565. if (allow_fail) then
  566. break
  567. end
  568. print_error(message_error_move)
  569. count = 0
  570. end
  571. os.sleep(0.05 * settings["tick_delay"])
  572. detect_liquid_forward()
  573. move_success = turtle.forward()
  574. end
  575.  
  576. if (move_success) then
  577. turtle.suck()
  578. turtle.suckUp()
  579. turtle.suckDown()
  580.  
  581. if (progress["position"][2] == 0) then
  582. update_progress("position", progress["position"][1][3] - 1, 1, 3)
  583. elseif (progress["position"][2] == 1) then
  584. update_progress("position", progress["position"][1][1] + 1, 1, 1)
  585. elseif (progress["position"][2] == 2) then
  586. update_progress("position", progress["position"][1][3] + 1, 1, 3)
  587. else
  588. update_progress("position", progress["position"][1][1] - 1, 1, 1)
  589. end
  590. end
  591. return move_success
  592. end
  593. -- force turtle to dig (keeps digging until no block)
  594. local function force_dig_forward(allow_fail)
  595. allow_fail = allow_fail or false
  596. count = 0
  597. detect_liquid_forward()
  598. while (turtle.detect()) do
  599. turtle.select(1)
  600. turtle.attack()
  601. turtle.dig()
  602. turtle.suck()
  603. turtle.suckUp()
  604. turtle.suckDown()
  605. count = count + 1
  606. if (count > 10 and turtle.detect()) or (count > 50) then
  607. if (allow_fail) then
  608. break
  609. end
  610. print_error(message_error_dig.." (forward)")
  611. count = 0
  612. end
  613. os.sleep(0.5 * settings["tick_delay"])
  614. detect_liquid_forward()
  615. end
  616. end
  617. -- only works in CC1.6
  618. local function detect_liquid_up()
  619. if (turtle.detectUp()) then
  620. turtle.select(settings["cobblestone_slot"])
  621. if (turtle.placeUp()) then
  622. print_error(message_error_liquids)
  623. end
  624. end
  625. end
  626. -- force the turtle to move up
  627. -- digs anything out of the way
  628. -- can generate error if unable to move after 10 tries
  629. -- updates progress["position"]
  630. local function force_up(allow_fail)
  631. allow_fail = allow_fail or false
  632. count = 0
  633. detect_liquid_up()
  634. success = turtle.up()
  635. while not (success) do
  636. turtle.select(1)
  637. turtle.digUp()
  638. count = count + 1
  639. if (count > 10) then
  640. if (allow_fail) then
  641. break
  642. end
  643. print_error(message_error_move)
  644. count = 0
  645. end
  646. os.sleep(0.5 * settings["tick_delay"])
  647. detect_liquid_up()
  648. success = turtle.up()
  649. end
  650. if (success) then
  651. turtle.suckUp()
  652. update_progress("position", progress["position"][1][2] + 1, 1, 2)
  653. end
  654. return success
  655. end
  656. -- force turtle to dig up (keeps digging until no block)
  657. local function force_dig_up(allow_fail)
  658. allow_fail = allow_fail or false
  659. count = 0
  660. detect_liquid_up()
  661. while (turtle.detectUp()) do
  662. turtle.select(1)
  663. turtle.digUp()
  664. turtle.suckUp()
  665. count = count + 1
  666. if (count > 10) then
  667. if (allow_fail) then
  668. break
  669. end
  670. print_error(message_error_dig.." (up)")
  671. count = 0
  672. end
  673. os.sleep(0.5 * settings["tick_delay"])
  674. detect_liquid_up()
  675. end
  676. end
  677. -- only works in CC1.6
  678. local function detect_liquid_down()
  679. if (turtle.detectDown()) then
  680. turtle.select(settings["cobblestone_slot"])
  681. if (turtle.placeDown()) then
  682. print_error(message_error_liquids)
  683. end
  684. end
  685. end
  686. -- force the turtle to move down
  687. -- digs anything out of the way
  688. -- can generate error if unable to move after 10 tries
  689. -- updates progress["position"]
  690. local function force_down(allow_fail)
  691. allow_fail = allow_fail or false
  692. count = 0
  693. detect_liquid_down()
  694. success = turtle.down()
  695. while not (success) do
  696. turtle.select(1)
  697. turtle.digDown()
  698. count = count + 1
  699. if (count > 10) then
  700. if (allow_fail) then
  701. break
  702. end
  703. print_error(message_error_move)
  704. count = 0
  705. end
  706. os.sleep(0.5 * settings["tick_delay"])
  707. detect_liquid_down()
  708. success = turtle.down()
  709. end
  710. if (success) then
  711. turtle.suckDown()
  712. update_progress("position", progress["position"][1][2] - 1, 1, 2)
  713. end
  714. return success
  715. end
  716. -- force turtle to dig down (keeps digging until no block)
  717. local function force_dig_down(allow_fail)
  718. allow_fail = allow_fail or false
  719. count = 0
  720. detect_liquid_down()
  721. while (turtle.detectDown()) do
  722. turtle.select(1)
  723. turtle.digDown()
  724. turtle.suckDown()
  725. count = count + 1
  726. if (count > 10) then
  727. if (allow_fail) then
  728. break
  729. end
  730. print_error(message_error_dig.." (down)")
  731. count = 0
  732. end
  733. os.sleep(0.5 * settings["tick_delay"])
  734. detect_liquid_down()
  735. end
  736. end
  737. -- uses all fuel in inventory
  738. local function use_all_fuel()
  739. for i=1,16 do
  740. if not (i == settings["chest_slot"]) then
  741. turtle.select(i)
  742. turtle.refuel(64)
  743. end
  744. end
  745. end
  746. -- moves turtle to coords and facing direction
  747. -- allows for both negative and positive coords for X and Y, but NOT Z
  748. local function goto_position(coord, facing)
  749. temp_seralized = string.gsub(textutils.serialize({coord, facing}), "[\n ]", "")
  750. log("goto: "..temp_seralized)
  751. -- move turtle out of branch connector if in one
  752. branchs_z = {settings["branch_between_distance"]}
  753. for i=2,settings["number_of_branches"] do
  754. table.insert(branchs_z, branchs_z[#branchs_z]+settings["branch_between_distance"]+1)
  755. end
  756. distance_from_branch = -1
  757. for i=1,#branchs_z do
  758. if (progress["position"][1][3] >= branchs_z[i]) then
  759. temp_distance = progress["position"][1][3] - branchs_z[i]
  760. if (temp_distance < distance_from_branch) or (distance_from_branch == -1) then
  761. distance_from_branch = progress["position"][1][3] - branchs_z[i]
  762. end
  763. else
  764. break
  765. end
  766. end
  767. for i=1,distance_from_branch do
  768. rotate(0)
  769. force_forward()
  770. end
  771.  
  772. -- move turtle to trunk
  773. min_trunk = 0
  774. max_trunk = (settings["trunk_width"])-1
  775. while (progress["position"][1][1] > max_trunk) do
  776. rotate(3)
  777. force_forward()
  778. end
  779. while (progress["position"][1][1] < min_trunk) do
  780. rotate(1)
  781. force_forward()
  782. end
  783.  
  784. -- goto y coord
  785. while (progress["position"][1][2] > coord[2]) do
  786. force_down()
  787. end
  788. while (progress["position"][1][2] < coord[2]) do
  789. force_up()
  790. end
  791.  
  792. -- goto z coord
  793. while (progress["position"][1][3] > coord[3]) do
  794. rotate(0)
  795. force_forward()
  796. end
  797. while (progress["position"][1][3] < coord[3]) do
  798. rotate(2)
  799. force_forward()
  800. end
  801.  
  802. -- goto x coord
  803. while (progress["position"][1][1] > coord[1]) do
  804. rotate(3)
  805. force_forward()
  806. end
  807. while (progress["position"][1][1] < coord[1]) do
  808. rotate(1)
  809. force_forward()
  810. end
  811.  
  812. -- rotate to facing
  813. rotate(facing)
  814. end
  815. -- calculate the distance from the fuel chest
  816. local function get_distance_from_fuel()
  817. -- fuel position is (trunk_width-1, 0, 0)
  818. return math.abs(progress["position"][1][1]-(settings["trunk_width"]-1))+math.abs(progress["position"][1][2])+math.abs(progress["position"][1][3])
  819. end
  820. local function get_fuel_amount_for_branch()
  821. return get_distance_from_fuel() + ((settings["branch_length"] + (settings["branch_length"]/settings["branch_connector_distance"])*(settings["branch_between_distance"]*2))*2 + settings["trunk_width"])*2
  822. end
  823. -- test if it is nesscary to get resources
  824. local function get_fuel_and_supplies_if_needed(required_fuel)
  825. set_task("Supplies", "Checking")
  826.  
  827. -- check fuel
  828. local previous_position = {{progress["position"][1][1], progress["position"][1][2], progress["position"][1][3]}, progress["position"][2]}
  829. local has_moved = false
  830. if (turtle.getFuelLevel() < required_fuel) then
  831. if (required_fuel < settings["min_continue_fuel_level"]) then
  832. required_fuel = settings["min_continue_fuel_level"]
  833. end
  834. has_moved = true
  835. set_task("Supplies", "Fuel")
  836. goto_position({(settings["trunk_width"]-1), 0, 0}, 1)
  837. need_fuel = (turtle.getFuelLevel() < required_fuel)
  838. while (need_fuel) do
  839. if not (turtle.suck()) then
  840. print_error(message_error_fuel)
  841. end
  842. use_all_fuel()
  843. need_fuel = (turtle.getFuelLevel() < required_fuel)
  844. end
  845. end
  846.  
  847. -- check torches/chests
  848. set_task("Supplies", "Checking")
  849. local need_chests = (turtle.getItemCount(settings["chest_slot"]) <= 1)
  850. local need_torches = (turtle.getItemCount(settings["torch_slot"]) <= (((settings["branch_length"]/settings["torch_distance"])+1)*2))
  851. if (need_chests or need_torches) then
  852. has_moved = true
  853. set_task("Supplies", "Items")
  854. goto_position({0, 0, 0}, 3)
  855.  
  856. -- resupply chests
  857. while (need_chests) do
  858. set_task("Supplies", "Chests")
  859. turtle.select(settings["chest_slot"])
  860. turtle.dropUp()
  861. turtle.suckUp()
  862. need_chests = (turtle.getItemCount(settings["chest_slot"]) <= 1)
  863. if (need_chests) then
  864. print_error(message_error_chest)
  865. end
  866. end
  867. -- resupply torches
  868. while (need_torches) do
  869. set_task("Supplies", "Torches")
  870. turtle.select(settings["torch_slot"])
  871. turtle.drop()
  872. turtle.suck()
  873. need_torches = (turtle.getItemCount(settings["torch_slot"]) <= (((settings["branch_length"]/settings["torch_distance"])+1)*2))
  874. if (need_torches) then
  875. print_error(message_error_torch)
  876. end
  877. end
  878. end
  879.  
  880. empty_slots = false
  881. for i=1,16 do
  882. empty_slots = empty_slots or (turtle.getItemCount(i) == 0)
  883. end
  884. if not empty_slots then
  885. has_moved = true
  886. set_task("Supplies", "Emptying")
  887. goto_position({progress["branch"]["side"]-1, 1, ((settings["branch_between_distance"]+1)*progress["branch"]["current"])-1}, 2)
  888. empty_inventory()
  889. end
  890.  
  891. if (has_moved) then
  892. -- return to previous position
  893. set_task("Supplies", "Returning")
  894. goto_position(unpack(previous_position))
  895. end
  896. end
  897.  
  898. -- main functions
  899. empty_inventory = function()
  900. for i=1,16 do
  901. set_task("Emptying", string.format("%3d%%", (i/16)*100))
  902. turtle.select(i)
  903. if (i == settings["torch_slot"]) or (i == settings["chest_slot"]) or (i == settings["cobblestone_slot"]) then
  904. else
  905. is_test_block = false
  906. for index,value in ipairs(test_slots) do
  907. is_test_block = (is_test_block or (i == value))
  908. end
  909. if (is_test_block) then
  910. to_drop = turtle.getItemCount(i)-1
  911. if (to_drop > 0) then
  912. turtle.dropUp(to_drop)
  913. end
  914. else
  915. turtle.dropUp(64)
  916. end
  917. end
  918. end
  919. end
  920. -- check for ores and mine them if they are there
  921. -- will mine out anything that is not stone, dirt, gravel, or cobblestone
  922. -- if do_down, will check block below turtle, otherwise, will check block above
  923. local function dig_ores(movement)
  924. movement = movement or {}
  925.  
  926. if (#movement == 0) then
  927. previous_face = progress["position"][2]
  928. end
  929.  
  930. -- down
  931. if (turtle.detectDown()) then
  932. not_ore_block = false
  933. for index,value in ipairs(test_slots) do
  934. turtle.select(value)
  935. not_ore_block = (not_ore_block or turtle.compareDown())
  936. end
  937. if not (not_ore_block) then
  938. if (#movement == 0) then
  939. -- check for needed supplies
  940. required_fuel = get_fuel_amount_for_branch()
  941. get_fuel_and_supplies_if_needed(required_fuel)
  942. set_task("Mining Vein", "")
  943. end
  944. if (force_down(true)) then
  945. movement[#movement+1]=4
  946. os.sleep(0.05 * settings["tick_delay"])
  947. dig_ores(movement)
  948. end
  949. end
  950. end
  951. -- up
  952. if (turtle.detectUp()) then
  953. not_ore_block = false
  954. for index,value in ipairs(test_slots) do
  955. turtle.select(value)
  956. not_ore_block = (not_ore_block or turtle.compareUp())
  957. end
  958. if not (not_ore_block) then
  959. if (#movement == 0) then
  960. -- check for needed supplies
  961. required_fuel = get_fuel_amount_for_branch()
  962. get_fuel_and_supplies_if_needed(required_fuel)
  963. set_task("Mining Vein", "")
  964. end
  965. if (force_up(true)) then
  966. movement[#movement+1]=5
  967. os.sleep(0.05 * settings["tick_delay"])
  968. dig_ores(movement)
  969. end
  970. end
  971. end
  972.  
  973. sides_to_check = {}
  974. if (#movement == 0) then
  975. sides_to_check = {0, 2}
  976. else
  977. sides_to_check = {0, 1, 2, 3}
  978. end
  979. -- sides
  980. for i,v in ipairs(sides_to_check) do
  981. rotate(v)
  982. if (turtle.detect()) then
  983. not_ore_block = false
  984. for index,value in ipairs(test_slots) do
  985. turtle.select(value)
  986. not_ore_block = (not_ore_block or turtle.compare())
  987. end
  988. if not (not_ore_block) then
  989. if (#movement == 0) then
  990. -- check for needed supplies
  991. required_fuel = get_fuel_amount_for_branch()
  992. get_fuel_and_supplies_if_needed(required_fuel)
  993. set_task("Mining Vein", "")
  994. end
  995. if (force_forward(true)) then
  996. movement[#movement+1]=get_opposite_direction(v)
  997. os.sleep(0.05 * settings["tick_delay"])
  998. dig_ores(movement)
  999. end
  1000. end
  1001. end
  1002. end
  1003.  
  1004. if (#movement > 0) then
  1005. if (movement[#movement] == 4) then
  1006. force_up()
  1007. elseif (movement[#movement] == 5) then
  1008. force_down()
  1009. else
  1010. rotate(movement[#movement])
  1011. force_forward()
  1012. end
  1013. movement[#movement] = nil
  1014. else
  1015. rotate(previous_face)
  1016. end
  1017. end
  1018. -- digs out part of trunk of length
  1019. local function dig_out_trunk(length)
  1020. log("trunk: "..length)
  1021. -- check for needed supplies
  1022. required_fuel = get_fuel_amount_for_branch()
  1023. get_fuel_and_supplies_if_needed(required_fuel)
  1024.  
  1025. set_task("Trunk", string.format("%3d%%", 0))
  1026. rotate(2)
  1027. for i=1,length do
  1028. force_forward()
  1029. if (settings["trunk_height"] == 3) then
  1030. force_up()
  1031. end
  1032. turtle.select(settings["chest_slot"])
  1033. if not (turtle.compareUp()) then
  1034. force_dig_up()
  1035. end
  1036. rotate(1)
  1037. for i=1,(settings["trunk_width"]-1) do
  1038. force_forward()
  1039. if (i == settings["trunk_width"]-1) then
  1040. turtle.select(settings["chest_slot"])
  1041. if not (turtle.compareUp()) then
  1042. force_dig_up()
  1043. end
  1044. else
  1045. force_dig_up()
  1046. end
  1047. if (settings["trunk_height"] == 3) then
  1048. force_dig_down()
  1049. end
  1050. end
  1051. rotate(3)
  1052. for i=1,(settings["trunk_width"]-1) do
  1053. force_forward()
  1054. end
  1055. if (settings["trunk_height"] == 3) then
  1056. force_down()
  1057. end
  1058. rotate(2)
  1059. set_task("Trunk", string.format("%3d%%", (i/length)*100))
  1060. end
  1061. end
  1062. -- digs out a single branch
  1063. local function dig_branch()
  1064. -- check for needed supplies
  1065. required_fuel = get_distance_from_fuel() + ((settings["branch_length"] + (settings["branch_length"]/settings["branch_connector_distance"])*(settings["branch_between_distance"]*2))*2 + settings["trunk_width"])*2
  1066. get_fuel_and_supplies_if_needed(required_fuel)
  1067.  
  1068. set_task("Branch", string.format("%3d%%", 0))
  1069. progress["branch"]["side"] = progress["branch"]["side"] or 1
  1070.  
  1071. -- each path through loop is one half of branch (each side of trunk)
  1072. for x=progress["branch"]["side"],2 do
  1073. update_progress("branch", x, "side")
  1074. if (x == 1) then
  1075. rotate(3)
  1076. else
  1077. rotate(1)
  1078. end
  1079.  
  1080. if (progress["branch"]["height"] == nil) then
  1081. update_progress("branch", 1, "height")
  1082. end
  1083.  
  1084. if (progress["branch"]["height"] == 1) then
  1085. if (progress["branch"]["progress"] == nil) or (progress["branch"]["progress"] == 1) then
  1086. -- place supply chest
  1087. force_up()
  1088. if not (turtle.compareUp()) then
  1089. force_up()
  1090. force_dig_up()
  1091. force_down()
  1092. turtle.select(settings["chest_slot"])
  1093. while not (turtle.placeUp()) do
  1094. print_error(message_error_failed_to_place_chest)
  1095. turtle.select(settings["chest_slot"])
  1096. end
  1097. else
  1098. turtle.select(settings["chest_slot"])
  1099. turtle.placeUp()
  1100. end
  1101. end
  1102. progress["branch"]["progress"] = progress["branch"]["progress"] or 1
  1103. -- mine out top of branch
  1104. for i=progress["branch"]["progress"],settings["branch_length"] do
  1105. update_progress("branch", i, "progress")
  1106. set_task("Branch", string.format("%3d%%", (x-1)*50+((i/settings["branch_length"])*100)/4))
  1107. force_forward()
  1108. dig_ores()
  1109.  
  1110. -- mine out branch connectors
  1111. if (i%settings["branch_connector_distance"]) == 0 then
  1112. rotate(2)
  1113. for j=1,settings["branch_between_distance"] do
  1114. force_forward()
  1115. dig_ores()
  1116. end
  1117. force_down()
  1118. rotate(0)
  1119. for j=1,settings["branch_between_distance"] do
  1120. force_forward()
  1121. dig_ores()
  1122. end
  1123. force_up()
  1124. if (x == 1) then
  1125. rotate(3)
  1126. else
  1127. rotate(1)
  1128. end
  1129. end
  1130.  
  1131. -- verfiy blocks are in place for torches (placed later)
  1132. if (((i%settings["torch_distance"]) == 1)) then
  1133. log("branch: place: torch wall")
  1134. if (has_error) then
  1135. term_size = {term.getSize()}
  1136. term.setCursorPos(1, (term_size[2]-2))
  1137. clear_line()
  1138. has_error = false
  1139. end
  1140. if (settings["transmit_progress"]) then
  1141. send_message("check")
  1142. end
  1143. rotate(2)
  1144. if (not (turtle.detect())) or (not (turtle.detectUp())) then
  1145. if (turtle.getItemCount(settings["cobblestone_slot"]) > 3) then
  1146. turtle.select(settings["cobblestone_slot"])
  1147. turtle.placeUp()
  1148. turtle.place()
  1149. else
  1150. print_error(message_error_failed_to_place_torch_wall, false, false)
  1151. end
  1152. end
  1153. if (x == 1) then
  1154. rotate(3)
  1155. else
  1156. rotate(1)
  1157. end
  1158. end
  1159. end
  1160. if (x == 1) then
  1161. rotate(1)
  1162. else
  1163. rotate(3)
  1164. end
  1165. --mine out bottom level of branch (return)
  1166. force_down()
  1167. update_progress("branch", 0, "height")
  1168. update_progress("branch", 1, "progress")
  1169. end
  1170.  
  1171. if (progress["branch"]["progress"] == nil) then
  1172. update_progress("branch", 1, "progress")
  1173. end
  1174.  
  1175. for i=progress["branch"]["progress"],settings["branch_length"] do
  1176. set_task("Branch", string.format("%3d%%", (x-1)*50+((i/settings["branch_length"])*100)/4+25))
  1177. force_forward()
  1178. dig_ores()
  1179.  
  1180. -- place torches
  1181. if (i%settings["torch_distance"]) == 1 then
  1182. log("branch: place: torch")
  1183. if (has_error) then
  1184. term_size = {term.getSize()}
  1185. term.setCursorPos(1, (term_size[2]-2))
  1186. clear_line()
  1187. has_error = false
  1188. end
  1189. if (settings["transmit_progress"]) then
  1190. send_message("check")
  1191. end
  1192. turtle.select(settings["torch_slot"])
  1193. if not (turtle.placeUp()) then
  1194. print_error(message_error_failed_to_place_torch, false, false)
  1195. end
  1196. end
  1197. end
  1198. update_progress("branch", nil, "progress")
  1199. set_task("Emptying", string.format("%3d%%", 0))
  1200. force_up()
  1201. -- use fuel is told too
  1202. if (settings["use_coal"]) then
  1203. use_all_fuel()
  1204. end
  1205. turtle.select(settings["chest_slot"])
  1206. while not (turtle.compareUp()) do
  1207. print_error(message_error_no_chest)
  1208. end
  1209. -- empty out inventory (except for supplies)
  1210. empty_inventory()
  1211. set_task("Branch", string.format("%3d%%", x*50))
  1212. force_down()
  1213.  
  1214. -- move to current location to continue
  1215. if (x == 1) then
  1216. rotate(1)
  1217. for i=1,(settings["trunk_width"]-1) do
  1218. force_forward()
  1219. end
  1220. else
  1221. rotate(3)
  1222. for i=1,(settings["trunk_width"]-1) do
  1223. force_forward()
  1224. end
  1225. end
  1226.  
  1227. update_progress("branch", 1, "height")
  1228. update_progress("branch", 1, "progress")
  1229. end
  1230.  
  1231. update_progress("branch", 1, "height")
  1232. update_progress("branch", 1, "progress")
  1233. update_progress("branch", 1, "side")
  1234. rotate(2)
  1235. end
  1236.  
  1237. local function run_turtle_main()
  1238. -- verify trunk height (program not adjusted for otherwise)
  1239. if not (settings["trunk_height"]==2 or settings["trunk_height"]==3) then
  1240. print_error(message_error_trunk)
  1241. end
  1242. -- check for wireless modem, disable transmit if not there
  1243. if (settings["transmit_progress"]) then
  1244. if not (settings["transmitter_side"] == nil) then
  1245. transmitter = peripheral.wrap(settings["transmitter_side"])
  1246. else
  1247. transmitter = peripheral.find("modem")
  1248. end
  1249. if (transmitter == nil) then
  1250. settings["transmit_progress"] = false
  1251. end
  1252. end
  1253.  
  1254. -- print title
  1255. term_size = {term.getSize()}
  1256. current_branch_location = {term_size[1]-9,ids_line+2}
  1257. term.clear()
  1258. term.setCursorPos(1,1)
  1259. color_write(program_name.." v"..program_version, colors.lime)
  1260. -- if transmit, print computer ID to indicate it
  1261. if (settings["transmit_progress"]) then
  1262. term.setCursorPos(term_size[1]-4,ids_line)
  1263. color_write(string.format("%5d", os.computerID()), colors.white)
  1264. end
  1265.  
  1266. -- if no progress, start new
  1267. if (progress["task"] == nil) then
  1268. -- verfiy there is at least __some__ fuel to get started
  1269. while (turtle.getFuelLevel() == 0) do
  1270. use_all_fuel()
  1271. if (turtle.getFuelLevel() == 0) then
  1272. term.setCursorPos(1,ids_line+3)
  1273. color_write("Put at least one piece of fuel in", colors.cyan)
  1274. wait_for_enter()
  1275. term.setCursorPos(1,ids_line+3)
  1276. clear_line()
  1277. end
  1278. end
  1279.  
  1280. -- remind use to have stone, dirt, gravel, and cobblestone
  1281. term.setCursorPos(1,ids_line+3)
  1282. color_write("Leave slots 1 and 2 empty", colors.cyan)
  1283. term.setCursorPos(1,ids_line+4)
  1284. color_write("Put a stack of cobblestone in slot "..settings["cobblestone_slot"], colors.cyan)
  1285. term.setCursorPos(1,ids_line+5)
  1286. color_write("Put any \"do not mine\" blocks in others", colors.cyan)
  1287. term.setCursorPos(3,ids_line+6)
  1288. color_write("i.e.: cobblestone, stone,", colors.cyan)
  1289. term.setCursorPos(4,ids_line+7)
  1290. color_write("dirt, gravel", colors.cyan)
  1291. wait_for_enter()
  1292. while (turtle.getItemCount(settings["cobblestone_slot"]) < 64) do
  1293. print_error(message_error_cobble)
  1294. end
  1295. -- add items in all slots but 1 and 2 to test_slots
  1296. term.setCursorPos(1,ids_line+3)
  1297. clear_line()
  1298. term.setCursorPos(1,ids_line+4)
  1299. clear_line()
  1300. term.setCursorPos(1,ids_line+5)
  1301. clear_line()
  1302. term.setCursorPos(1,ids_line+6)
  1303. clear_line()
  1304. term.setCursorPos(1,ids_line+7)
  1305. clear_line()
  1306. end
  1307.  
  1308. for i=1,16 do
  1309. if (turtle.getItemCount(i) > 0) then
  1310. test_slots[#test_slots+1] = i
  1311. end
  1312. end
  1313.  
  1314. -- print current branch data
  1315. term.setCursorPos(1,ids_line+2)
  1316. color_write("Current Branch", colors.cyan)
  1317. term.setCursorPos(unpack(current_branch_location))
  1318. color_write(string.format("%3d", progress["branch"]["current"]), colors.yellow)
  1319. term.setCursorPos(term_size[1]-5,ids_line+2)
  1320. color_write("of", colors.white)
  1321. term.setCursorPos(term_size[1]-2,ids_line+2)
  1322. color_write(string.format("%3d", settings["number_of_branches"]), colors.magenta)
  1323.  
  1324. -- if transmit, send start signal to receiver
  1325. if (settings["transmit_progress"]) then
  1326. local send_data = {}
  1327. send_data["number_of_branches"] = settings["number_of_branches"]
  1328. send_message("start", send_data)
  1329. end
  1330.  
  1331. -- if no progress, check for supplies and start
  1332. if (progress["task"] == nil) then
  1333. -- Verify starting fuel level
  1334. get_fuel_and_supplies_if_needed(settings["min_continue_fuel_level"])
  1335.  
  1336. -- Dig to branch 1
  1337. dig_out_trunk(settings["branch_between_distance"])
  1338. elseif (progress["task"] == "trunk") then
  1339.  
  1340. end
  1341.  
  1342. -- dig branchs
  1343. for i=progress["branch"]["current"],settings["number_of_branches"] do
  1344. update_progress("branch", i, "current")
  1345. term.setCursorPos(unpack(current_branch_location))
  1346. color_write(string.format("%3d", progress["branch"]["current"]), colors.yellow)
  1347. -- if transmit, update current branch
  1348. if (settings["transmit_progress"]) then
  1349. local send_data = {}
  1350. send_data["branch"] = progress["branch"]["current"]
  1351. send_message("branch_update", send_data)
  1352. end
  1353. log("branch: "..progress["branch"]["current"])
  1354. -- dig branch
  1355. dig_branch()
  1356. -- dig to next branch
  1357. dig_out_trunk(settings["branch_between_distance"]+1)
  1358. end
  1359. -- go back to start
  1360. set_task("Returning", "")
  1361. goto_position({0, 0, 0}, 2)
  1362. --if transmit, sent exit signal
  1363. if (settings["transmit_progress"]) then
  1364. send_message("exit")
  1365. end
  1366. -- delete progress file
  1367. fs.delete(progress_file)
  1368. -- wait for user's acknowledgement of completion
  1369. wait_for_enter()
  1370. term.setCursorPos(1,1)
  1371. term.clear()
  1372. end
  1373.  
  1374. local function run_receiver_main()
  1375. local term_object = term
  1376.  
  1377. -- check for transmitter
  1378. while (transmitter == nil) do
  1379. -- if transmitter_side is not nil, for check on that side
  1380. if not (settings["transmitter_side"] == nil) then
  1381. transmitter = peripheral.wrap(settings["transmitter_side"])
  1382. -- if no transmitter, print error to add one
  1383. if (transmitter == nil) then
  1384. print_error(message_error_modem_side, false, true)
  1385. end
  1386. else
  1387. -- look for transmitter
  1388. transmitter = peripheral.find("modem")
  1389. -- if no transmitter, print error to add one
  1390. if (transmitter == nil) then
  1391. print_error(message_error_modem, false, true)
  1392. end
  1393. end
  1394. end
  1395.  
  1396. -- verify it is a wireless transmitter
  1397. if not (transmitter.isWireless()) then
  1398. print_error(message_error_modem_wireless, false, true)
  1399. end
  1400.  
  1401. if (settings["redirect_to_monitor"]) then
  1402. local temp_monitor = nil
  1403. if not (settings["monitor_side"] == nil) then
  1404. if not (settings["monitor_side"] == false) then
  1405. temp_monitor = peripheral.wrap(settings["monitor_side"])
  1406. end
  1407. else
  1408. temp_monitor = peripheral.find("monitor")
  1409. end
  1410.  
  1411. if not (temp_monitor == nil) then
  1412. term.redirect(temp_monitor)
  1413. else
  1414. settings["redirect_to_monitor"] = false
  1415. end
  1416. end
  1417.  
  1418. term_size = {term.getSize()}
  1419.  
  1420. -- print title
  1421. term.clear()
  1422. term.setCursorPos(1,1)
  1423. title = program_name.." v"..program_version
  1424. if (term_size[1] < string.len(title)+17) then
  1425. ids_line = 2
  1426. if (term_size[1] < string.len(title)) or (term_size[1] < 17) then
  1427. print_error(message_error_display_width, true)
  1428. end
  1429. end
  1430. if (term_size[2] < 12) then
  1431. print_error(message_error_display_height, true)
  1432. end
  1433. current_branch_location = {term_size[1]-9,ids_line+2}
  1434. color_write(title, colors.lime)
  1435. term.setCursorPos(1,ids_line+2)
  1436. color_write("Waiting for turtle...", colors.magenta)
  1437.  
  1438. -- open channel for listening
  1439. transmitter.open(settings["transmit_channel"])
  1440. -- listen for events
  1441. do_loop = true
  1442. while (do_loop) do
  1443. local event, modemSide, senderChannel,
  1444. replyChannel, message, senderDistance = os.pullEvent("modem_message")
  1445.  
  1446. local retransmit = false
  1447.  
  1448. local receiver_data = textutils.unserialize(message)
  1449. receiver_data["retransmit_id"] = receiver_data["retransmit_id"] or nil
  1450.  
  1451. temp_seralized = string.gsub(textutils.serialize(receiver_data), "[\n ]", "")
  1452. log("receive: "..temp_seralized)
  1453.  
  1454. -- start event, can only be ran if waiting for turtle (paired_id == nil)
  1455. if (receiver_data["type"] == "start") and (progress["paired_id"] == nil) then
  1456. update_progress("paired_id", receiver_data["turtle_id"])
  1457. update_progress("retransmit_id", receiver_data["retransmit_id"])
  1458. update_progress("branch", receiver_data["branch"] or progress["branch"]["current"], "current")
  1459. settings["number_of_branches"] = receiver_data["number_of_branches"]
  1460.  
  1461. if not (progress["retransmit_id"] == nil) then
  1462. term.setCursorPos(term_size[1]-16,ids_line)
  1463. else
  1464. term.setCursorPos(term_size[1]-10,ids_line)
  1465. end
  1466. color_write(string.format("%5d", os.computerID()), colors.white)
  1467. color_write(":", colors.yellow)
  1468. if not (progress["retransmit_id"] == nil) then
  1469. color_write(string.format("%5d", progress["retransmit_id"]), colors.green)
  1470. color_write(":", colors.yellow)
  1471. end
  1472. color_write(string.format("%5d", progress["paired_id"]), colors.red)
  1473.  
  1474. term.setCursorPos(1,ids_line+2)
  1475. clear_line()
  1476. color_write("Current Branch", colors.cyan)
  1477. term.setCursorPos(unpack(current_branch_location))
  1478. color_write(string.format("%3d", progress["branch"]["current"]), colors.yellow)
  1479. term.setCursorPos(term_size[1]-5,ids_line+2)
  1480. color_write("of", colors.white)
  1481. term.setCursorPos(term_size[1]-2,ids_line+2)
  1482. color_write(string.format("%3d", settings["number_of_branches"]), colors.magenta)
  1483. retransmit = true
  1484. -- branch_update event
  1485. elseif (receiver_data["type"] == "branch_update") and (progress["paired_id"] == receiver_data["turtle_id"]) and (progress["retransmit_id"] == receiver_data["retransmit_id"]) then
  1486. update_progress("branch", receiver_data["branch"], "current")
  1487. term.setCursorPos(unpack(current_branch_location))
  1488. color_write(string.format("%3d", progress["branch"]["current"]), colors.yellow)
  1489. send_confrim(receiver_data["turtle_id"])
  1490. retransmit = true
  1491. -- task event
  1492. elseif (receiver_data["type"] == "task") and (progress["paired_id"] == receiver_data["turtle_id"]) and (progress["retransmit_id"] == receiver_data["retransmit_id"]) then
  1493. set_task(receiver_data["main"], receiver_data["sub"])
  1494. retransmit = true
  1495. -- error event
  1496. elseif (receiver_data["type"] == "check") and (progress["paired_id"] == receiver_data["turtle_id"]) and (progress["retransmit_id"] == receiver_data["retransmit_id"]) then
  1497. send_confrim(receiver_data["turtle_id"])
  1498. retransmit = true
  1499. elseif (receiver_data["type"] == "error") and (progress["paired_id"] == receiver_data["turtle_id"]) and (progress["retransmit_id"] == receiver_data["retransmit_id"]) then
  1500. -- clear previous error
  1501. if (receiver_data["error"] == message_error_clear) then
  1502. term.setCursorPos(1, (term_size[2]-2))
  1503. clear_line()
  1504. -- print error
  1505. else
  1506. print_error(receiver_data["error"], false, receiver_data["wait"])
  1507. end
  1508. retransmit = true
  1509. -- exit event
  1510. elseif (receiver_data["type"] == "exit") and (progress["paired_id"] == receiver_data["turtle_id"]) and (progress["retransmit_id"] == receiver_data["retransmit_id"]) then
  1511. do_loop = false
  1512. retransmit = true
  1513. end
  1514.  
  1515. if (settings["transmit_progress"] and retransmit) then
  1516. receiver_data["retransmit_id"] = nil
  1517. send_message(receiver_data["type"], receiver_data)
  1518. end
  1519. end
  1520. transmitter.close(settings["transmit_channel"])
  1521. set_task("Finished", "")
  1522. wait_for_enter()
  1523. term.setCursorPos(1,1)
  1524. term.clear()
  1525. transmitter.closeAll()
  1526.  
  1527. if (settings["redirect_to_monitor"]) then
  1528. term.redirect(term_object)
  1529. end
  1530. end
  1531.  
  1532. local function main()
  1533. init_settings()
  1534. init_progress()
  1535. fs.delete(log_file)
  1536. if not (turtle == nil) then
  1537. run_turtle_main()
  1538. else
  1539. run_receiver_main()
  1540. end
  1541. end
  1542.  
  1543. main()
Add Comment
Please, Sign In to add comment