kittykiller

Yet another branch mine program

Mar 18th, 2014
405
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 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 52
  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