Advertisement
hoblin

Drones

Dec 28th, 2012
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.75 KB | None | 0 0
  1. --[[
  2.  
  3. ===================================
  4.     DRONES v4.1
  5. ===================================
  6.  
  7. Originally created by Pooslice <[email protected]> (replace underscore with dot)
  8.  
  9. Changes to previous version:
  10. * (v4.1) Fixed a wrong loop-condition that prevented initial startup
  11. * Fixed a bug where drones could get confused if two controller turtles were used directly next to each other.
  12. * Finished turtles now get picked up by the main turtle at the end and are placed in their respective chest.
  13. * Introduced the 'force' parameter to start immediately without further user interaction.
  14. * Improved some of the pathfinding for handling unexpected blocks in the turtle's way during maintenance.
  15. * Improved fuel management during vertical digging (after hitting bedrock).
  16. * Reduced some waiting times.
  17.  
  18. For more information read the forum post: http://www.computercraft.info/forums2/index.php?/topic/5241-14-the-lazy-mans-way-to-clear-a-chunk/
  19. ]]--
  20.  
  21. STARTUPTIME = os.clock()
  22.  
  23. -- get call parameters
  24. local tArgs = { ... }
  25.  
  26. -- get the script name and path. a bit hacky, but it works ...
  27. SCRIPTPATH = shell.getRunningProgram()
  28. if string.find(SCRIPTPATH, "/") then
  29.     SCRIPTNAME = string.reverse(SCRIPTPATH)
  30.     SCRIPTNAME = string.reverse(string.sub(SCRIPTNAME, 0, string.find(SCRIPTNAME, "/")-1))
  31. else
  32.     SCRIPTNAME = SCRIPTPATH
  33. end
  34.  
  35. -- constants
  36. -- values below 100 make no sense as the distance to the refuel station will be that high already
  37. -- 4 coal per turtle -> one stack of coal initially plus one coal for the floppy setup
  38. REFUELTHRESHOLD = 96 * 4
  39. DEBUGMODE = false
  40. LOGFILENAME = nil
  41. -- untested and therefore not yet accessible
  42. DILIGENTMODE = false
  43.  
  44. function debug(message)
  45.     if DEBUGMODE then print(message) end
  46.     if LOGFILENAME then
  47.         local fp = fs.open(LOGFILENAME, "a")
  48.         if fp then
  49.             fp.writeLine(message)
  50.             fp.close()
  51.         end
  52.     end
  53. end
  54.  
  55. debug("Startup-Time: " .. STARTUPTIME)
  56.  
  57. -- compensate for fuelless mode
  58. FUELLESS = false
  59. if turtle.getFuelLevel() == "unlimited" then
  60.     FUELLESS = true
  61.     turtle.getFuelLevel = function()
  62.         return 2 + REFUELTHRESHOLD
  63.     end
  64. end
  65.  
  66. -- don't care where
  67. rednet.open("right")
  68. -- rednet.open("left")
  69. -- rednet.open("top")
  70. -- rednet.open("bottom")
  71. -- rednet.open("front")
  72. -- rednet.open("back")
  73.  
  74. -- try to clear the space above the turtle
  75. function clearUp()
  76.     debug("clearUp()")
  77.     if not turtle.detectUp() then
  78.         while turtle.attackUp() do end
  79.     end
  80.     turtle.digUp()
  81.     return not turtle.detectUp()
  82. end
  83.  
  84. -- see clearUp()
  85. function clearDown()
  86.     debug("clearDown()")
  87.     if not turtle.detectDown() then
  88.         while turtle.attackDown() do end
  89.     end
  90.     turtle.digDown()
  91.     return not turtle.detectDown()
  92. end
  93.  
  94. -- see clearUp()
  95. function clearForward()
  96.     debug("clearForward()")
  97.     if not turtle.detect() then
  98.         while turtle.attack() do end
  99.     end
  100.     turtle.dig()
  101.     return not turtle.detect()
  102. end
  103.  
  104. -- as clearUp(), but also tries to move in that direction
  105. function tryUp()
  106.     debug("tryUp()")
  107.     if turtle.up() then
  108.         return true
  109.     end
  110.     clearUp()
  111.     return turtle.up()
  112. end
  113.  
  114. -- see tryUp()
  115. function tryDown()
  116.     debug("tryDown()")
  117.     if turtle.down() then
  118.         return true
  119.     end
  120.     clearDown()
  121.     return turtle.down()
  122. end
  123.  
  124. -- see tryUp()
  125. -- with our digging strategy a maximum of 2 blocks must be digged out (one normal and one if it is falling sand or gravel)
  126. -- we add one try in case something went wrong or there was some lag
  127. function tryForward()
  128.     debug("tryForward()")
  129.     for i = 1, 3 do
  130.         if turtle.forward() then
  131.             return true
  132.         end
  133.         if not turtle.detect() then
  134.             while turtle.attack() do end
  135.         end
  136.         turtle.dig()
  137.     end
  138.     return turtle.forward()
  139. end
  140.  
  141. -- try to use one item from the inventory as fuel
  142. function refuelOneFromInventory()
  143.     for i = 1, 16 do
  144.         local fl = turtle.getFuelLevel()
  145.         turtle.select(i)
  146.         turtle.refuel(1)
  147.         if turtle.getFuelLevel() > fl then
  148.             return true
  149.         end
  150.     end
  151.     return false
  152. end
  153.  
  154. -- check if turtle's inventory is completely full
  155. function isInventoryFull()
  156.     debug("isInventoryFull()")
  157.     for i = 1, 16 do
  158.         if turtle.getItemCount(i) == 0 then
  159.             return false
  160.         end
  161.     end
  162.     return true
  163. end
  164.  
  165. -- return to our chest, drop everything there and refuel if necessary
  166. -- returns new x, y, z and face which should be the same as when calling the function
  167. function maintenance(refuelId, x, y, z, face)
  168.     debug("maintenance(" .. refuelId .. ", " .. x .. ", " .. y .. ", " .. z .. ", ??)")
  169.     local dx, dy, dz, dface = x, y, z, face
  170.     -- move below our chest
  171.     while y > 4 do
  172.         if tryUp() then
  173.             y = y - 1
  174.         end
  175.     end
  176.     -- could come across other turtles -> no digging
  177.     while y > 0 do
  178.         while not turtle.up() do sleep(1) end
  179.         y = y - 1
  180.     end
  181.     if face then
  182.         turtle.turnRight()
  183.         turtle.turnRight()
  184.     end
  185.     while x > 0 do
  186.         while not turtle.forward() do sleep(1) end
  187.         x = x - 1
  188.     end
  189.     turtle.turnRight()
  190.     turtle.turnRight()
  191.     -- Try to refuel from inventory if necessary
  192.     while turtle.getFuelLevel() < REFUELTHRESHOLD and refuelOneFromInventory() do
  193.         debug("Refuelled one from inventory. New level: " .. turtle.getFuelLevel())
  194.     end
  195.     -- drop all into the chest - overflow is ignored
  196.     for i = 1, 16 do
  197.         turtle.select(i)
  198.         turtle.dropUp()
  199.     end
  200.     -- refuel from station if still necessary
  201.     if turtle.getFuelLevel() < REFUELTHRESHOLD then
  202.         debug("Refuel needed: " .. turtle.getFuelLevel() .. " < " .. REFUELTHRESHOLD)
  203.         debug("Going to refuel at the station")
  204.         -- go to fuel station
  205.         -- from now on we could cross other turtles' lanes and will therefore only move, not dig
  206.         while not turtle.forward() do sleep(1) end
  207.         turtle.turnRight()
  208.         while z > 0 do
  209.             while not turtle.forward() do sleep(1) end
  210.             z = z - 1
  211.         end
  212.         turtle.turnRight()
  213.         turtle.turnRight()
  214.         while not turtle.up() do sleep(1) end
  215.         while not turtle.up() do sleep(1) end
  216.         -- refuel
  217.         while true do
  218.             -- refuel all and send fuel level until >  REFUELTHRESHOLD
  219.             for i = 1, 16 do
  220.                 turtle.select(i)
  221.                 turtle.refuel()
  222.             end
  223.             local message = {}
  224.             message["message"] = "fuelLevel"
  225.             message["fuelLevel"] = turtle.getFuelLevel()
  226.             rednet.send(refuelId, textutils.serialize(message))
  227.             if message["fuelLevel"] > REFUELTHRESHOLD then
  228.                 break
  229.             end
  230.         end
  231.         debug("Refuelling at station successful. Returning to lane.")
  232.         -- go back to lane
  233.         if dz == 0 then
  234.             turtle.turnRight()
  235.             while not turtle.forward() do sleep(1) end
  236.             while not turtle.down() do sleep(1) end
  237.             while not turtle.down() do sleep(1) end
  238.             while not turtle.down() do sleep(1) end
  239.             while not turtle.back() do sleep(1) end
  240.             while not turtle.back() do sleep(1) end
  241.             x = 0
  242.             y = 1
  243.             z = 0
  244.         else
  245.             while z < dz do
  246.                 while not turtle.forward() do sleep(1) end
  247.                 z = z + 1
  248.             end
  249.             turtle.turnRight()
  250.             while not turtle.down() do sleep(1) end
  251.             while not turtle.down() do sleep(1) end
  252.             y = 0
  253.             while not turtle.back() do sleep(1) end
  254.             x = 0
  255.         end
  256.     end
  257.     face = true
  258.     -- go back to old position
  259.     debug("Returning to old position before maintenance-call.")
  260.     while x < dx do
  261.         while not turtle.forward() do sleep(1) end
  262.         x = x + 1
  263.     end
  264.     if face ~= dface then
  265.         turtle.turnRight()
  266.         turtle.turnRight()
  267.         face = dface
  268.     end
  269.     while y < dy and y < 4 do
  270.         while not turtle.down() do sleep(1) end
  271.         y = y + 1
  272.     end
  273.     while y < dy do
  274.         while not tryDown() do sleep(1) end
  275.         y = y + 1
  276.     end
  277.     return x, y, z, face
  278. end
  279.  
  280. function diglane(lane, refuelId)
  281.     debug("digLane(" .. lane .. ", " .. refuelId .. ")")
  282.     -- x is forward (lane direction), y is depth below start (positive int), z is lane, true means facing in positive x direction
  283.     local x, y, z, face = 1, 0, lane, true
  284.     -- near bedrock we switch the digging strategy to vertical shafts instead of horizontal tunnels
  285.     local digVertical = false
  286.     -- big loop with many if-statements that magically does the right next step
  287.     while true do
  288.         -- check if we have enough fuel for returning to the station
  289.         local distToRefuelStation = y + x + 1 + z + 2
  290.         -- check if we have enough fuel for clearing the next row and returning to the refuel station (if not mining vertically)
  291.         -- 15 forward, 3 down, 15 backward, 3 up
  292.         local distToRefuelStationAfterNextLane = 15 + 3 + 15 + 3 + distToRefuelStation
  293.         debug("Digging ... distToRefuelStation: " .. distToRefuelStation .. ", Fuel: " .. turtle.getFuelLevel())
  294.         if turtle.getFuelLevel() - distToRefuelStation < 5 then -- some safety margin that was chosen arbitrarily
  295.             debug("Trying to refuel from inventory.")
  296.             -- try to refuel from inventory
  297.             if not refuelOneFromInventory() then
  298.                 debug("Inventory was not enough. Starting maintenance routine.")
  299.                 -- did not work or was not enough -> start maintenance routine
  300.                 x, y, z, face = maintenance(refuelId, x, y, z, face)
  301.             end
  302.         elseif (x == 0) and (not digVertical) and (turtle.getFuelLevel() - distToRefuelStationAfterNextLane < 3) then
  303.             debug("Trying to refuel from inventory.")
  304.             -- try to refuel from inventory
  305.             if not refuelOneFromInventory() then
  306.                 debug("Inventory was not enough. Starting maintenance routine.")
  307.                 -- did not work or was not enough -> start maintenance routine
  308.                 x, y, z, face = maintenance(refuelId, x, y, z, face)
  309.             end
  310.         elseif isInventoryFull() then
  311.             debug("Inventory is full. Starting maintenance routine.")
  312.             x, y, z, face = maintenance(refuelId, x, y, z, face)
  313.         else
  314.             -- dig
  315.             if not digVertical then
  316.                 if y % 3 > 0 then
  317.                     if tryDown() then
  318.                         y = y + 1
  319.                     else
  320.                         debug("Hit the ground. Will go to vertical mode.")
  321.                         digVertical = "start"
  322.                     end
  323.                 else
  324.                     if not clearUp() then
  325.                         debug("Seems, we moved one too far. Going back.")
  326.                         -- can only be the case if we accidently moved into a bedrock "gap"
  327.                         turtle.turnRight()
  328.                         turtle.turnRight()
  329.                         tryForward()
  330.                         turtle.turnRight()
  331.                         turtle.turnRight()
  332.                         if face then
  333.                             x = x - 1
  334.                         else
  335.                             x = x + 1
  336.                         end
  337.                         if tryUp() then
  338.                             y = y - 1
  339.                         end
  340.                         debug("And starting vertical mode.")
  341.                         digVertical = "start"
  342.                     else
  343.                         if (not clearDown()) or (not tryForward()) then
  344.                             debug("Could not clear down or go forward. Starting vertical mode.")
  345.                             digVertical = "start"
  346.                         else
  347.                             if face then
  348.                                 x = x + 1
  349.                             else
  350.                                 x = x - 1
  351.                             end
  352.                             clearUp()
  353.                             if x == 0 or x == 15 then
  354.                                 turtle.turnRight()
  355.                                 turtle.turnRight()
  356.                                 face = not face
  357.                                 if not tryDown() then
  358.                                     debug("At a border and could not go down. Starting vertical mode.")
  359.                                     digVertical = "start"
  360.                                 else
  361.                                     y = y + 1
  362.                                 end
  363.                             end
  364.                         end
  365.                     end
  366.                 end
  367.             else
  368.                 if digVertical == "start" then
  369.                     -- make next step towards x15 with face towards x0
  370.                     if not face then
  371.                         turtle.turnRight()
  372.                         turtle.turnRight()
  373.                         face = not face
  374.                     end
  375.                     if x < 15 then
  376.                         debug("Moving towards the end of the lane.")
  377.                         if not tryForward() then
  378.                             if tryUp() then
  379.                                 y = y - 1
  380.                             else
  381.                                 -- need to backtrack
  382.                                 debug("Moved into a gap. Backtracking ...")
  383.                                 turtle.turnRight()
  384.                                 turtle.turnRight()
  385.                                 if tryForward() then
  386.                                     x = x - 1
  387.                                 end
  388.                                 if tryUp() then
  389.                                     y = y - 1
  390.                                 end
  391.                                 turtle.turnRight()
  392.                                 turtle.turnRight()
  393.                             end
  394.                         else
  395.                             x = x + 1
  396.                         end
  397.                     else
  398.                         debug("In position for vertical digging")
  399.                         digVertical = "digVertical"
  400.                         turtle.turnRight()
  401.                         turtle.turnRight()
  402.                         face = not face
  403.                     end
  404.                 elseif digVertical == "digVertical" then
  405.                     -- because we are in the last stages and hit bedrock, we have a clearer estimate (upper bound) of how much fuel we need for the rest
  406.                     if (z == 0) then
  407.                         -- as below, but the cost for returning to the lane is 6 (see maintenance routine)
  408.                         REFUELTHRESHOLD = 10 * x + 2 * y + 14
  409.                     else
  410.                         -- back to lane, 2 down, 1 back, x forward, y down, at most 4 down and 4 up, 4 up plus 4 down plus 1 forward per unfinished field, then y to our chest
  411.                         -- REFUELTHRESHOLD = z + 2 + 1 + x + y + 4 + 4 + x * (1 + 4 + 4) + y
  412.                         REFUELTHRESHOLD = 10 * x + 2 * y + z + 11
  413.                     end
  414.                     if tryDown() then
  415.                         y = y + 1
  416.                     else
  417.                         if x > 0 then
  418.                             debug("At the bottom. Going to next field.")
  419.                             -- bedrock has 5 layers at most
  420.                             -- also clear any 'gaps' we might encounter when diligent mode is enabled
  421.                             if DILIGENTMODE then
  422.                                 for i = 1, 3 do
  423.                                     clearForward()
  424.                                     turtle.turnRight()
  425.                                     turtle.turnRight()
  426.                                     clearForward()
  427.                                     while not tryUp() do sleep(1) end
  428.                                 end
  429.                                 turtle.turnRight()
  430.                                 turtle.turnRight()
  431.                                 while not tryUp() do sleep(1) end
  432.                             else
  433.                                 while not tryUp() do sleep(1) end
  434.                                 while not tryUp() do sleep(1) end
  435.                                 while not tryUp() do sleep(1) end
  436.                                 while not tryUp() do sleep(1) end
  437.                             end
  438.                             y = y - 4
  439.                             while not tryForward() do sleep(1) end
  440.                             x = x - 1
  441.                         else
  442.                             debug("Cleared the last block. Returning now.")
  443.                             break
  444.                         end
  445.                     end
  446.                 end
  447.             end
  448.         end
  449.     end
  450.     -- TODO: DILIGENTMODE ...
  451.    
  452.     -- we should be at x0. so we go up and drop everything to our chest
  453.     while y > 4 do
  454.         while not tryUp() do sleep(1) end
  455.         y = y - 1
  456.     end
  457.     -- could cross other turtles' paths -> no digging
  458.     while y > 0 do
  459.         while not turtle.up() do sleep(1) end
  460.         y = y - 1
  461.     end
  462.     debug("Dropping everything into the chest.")
  463.     for i = 1, 16 do
  464.         if turtle.getItemCount(i) > 0 then
  465.             turtle.select(i)
  466.             turtle.dropUp()
  467.         end
  468.     end
  469.     turtle.turnRight()
  470.     turtle.turnRight()
  471.     face = not face
  472.     -- send finished to control
  473.     local m = {}
  474.     m["message"] = "laneFinished"
  475.     rednet.send(refuelId, textutils.serialize(m))
  476. end
  477.  
  478. function setuplane()
  479.     -- copy program from disk to local dir
  480.     fs.copy(SCRIPTPATH, SCRIPTNAME)
  481.  
  482.     turtle.turnLeft()
  483.    
  484.     local lane, refuelId
  485.     while true do
  486.         -- say hello
  487.         local broadcast = {}
  488.         broadcast["message"] = "hello"
  489.         rednet.broadcast(textutils.serialize(broadcast))
  490.         -- get welcome with our lane number
  491.         local id, message, distance = rednet.receive(5)
  492.         if message and distance < 1.4 then
  493.             local m = {}
  494.             m = textutils.unserialize(message)
  495.             if m["message"] == "welcome" and m["lane"] > -1 then
  496.                 lane = m["lane"] + 0
  497.                 refuelId = id
  498.                 break
  499.             end
  500.         end
  501.     end
  502.  
  503.     -- send fuel level, then get and use one fuel
  504.     for i = 1, 16 do
  505.         if turtle.getItemCount(i) == 0 then
  506.             turtle.select(i)
  507.             break
  508.         end
  509.     end
  510.     local message = {}
  511.     message["message"] = "fuelLevel"
  512.     message["fuelLevel"] = turtle.getFuelLevel()
  513.     message["lane"] = lane
  514.     rednet.send(refuelId, textutils.serialize(message))
  515.     local chestSlot
  516.     while true do
  517.         -- refuel all and send fuel level until >  REFUELTHRESHOLD
  518.         while (not FUELLESS) and (not refuelOneFromInventory()) do sleep(1) end
  519.         -- select lowest empty slot (to detect chest placement later on)
  520.         for i = 1, 16 do
  521.             if turtle.getItemCount(i) == 0 then
  522.                 chestSlot = i
  523.                 break
  524.             end
  525.         end
  526.         message["fuelLevel"] = turtle.getFuelLevel()
  527.         rednet.send(refuelId, textutils.serialize(message))
  528.         if message["fuelLevel"] > REFUELTHRESHOLD then
  529.             break
  530.         end
  531.     end
  532.     -- get chest
  533.     while turtle.getItemCount(chestSlot) < 1 do sleep(1) end
  534.     -- only the first turtle needs to clear a path
  535.     if lane == 15 then
  536.         while not tryDown() do sleep(1) end
  537.     else
  538.         while not turtle.down() do sleep(1) end
  539.     end
  540.     -- dig/go to our lane
  541.     for i = 1, lane do
  542.         if lane == 15 then
  543.             while not tryForward() do sleep(1) end
  544.         else
  545.             while not turtle.forward() do sleep(1) end
  546.         end
  547.     end
  548.     turtle.turnRight()
  549.     -- place chest
  550.     turtle.select(chestSlot)
  551.     clearUp()
  552.     clearDown()
  553.     turtle.placeUp()
  554.     while not tryForward() do sleep(1) end
  555.     if lane == 0 then
  556.         turtle.suckUp()
  557.     end
  558.  
  559.     -- dig lane
  560.     shell.run(SCRIPTNAME, "diglane", lane, refuelId)
  561. end
  562.  
  563. function refuelStation(workers)
  564.     debug("refuelStation: " .. textutils.serialize(workers))
  565.     if not workers then
  566.         workers = {}
  567.         for i = 0, 15 do
  568.             workers[i] = -1
  569.         end
  570.     end
  571.     print("Waiting for refuel requests. Will automatically exit if all lanes are complete. Press SPACE to exit early.")
  572.     print()
  573.     while true do
  574.         local allDone = true
  575.         for i = 0, 15 do
  576.             if workers[i] > -1 then
  577.                 allDone = false
  578.                 break
  579.             end
  580.         end
  581.         if allDone then
  582.             print("All lanes are done.")
  583.             break
  584.         end
  585.         local event, id, message, distance = os.pullEvent()
  586.         print(event)
  587.         print(id)
  588.         print(message)
  589.         print(distance)
  590.         if event == "rednet_message" and (distance == nil or distance < 1.4) and message then
  591.             local m = {}
  592.             m = textutils.unserialize(message)
  593.             if m["message"] == "fuelLevel" and m["fuelLevel"] <= REFUELTHRESHOLD then
  594.                 for i = 5, 16 do
  595.                     if turtle.getItemCount(i) > 0 then
  596.                         turtle.select(i)
  597.                         turtle.drop(1)
  598.                         break
  599.                     end
  600.                 end
  601.             end
  602.         elseif event == "rednet_message" and message then
  603.             local m = {}
  604.             m = textutils.unserialize(message)
  605.             if m["message"] == "laneFinished" then
  606.                 for i = 0, 15 do
  607.                     if workers[i] == id then
  608.                         debug("Received laneFinished from " .. id .. " and cleared workers[" .. i .. "]")
  609.                         workers[i] = -1
  610.                         break
  611.                     end
  612.                 end
  613.             end
  614.         elseif event == "key" and id == 57 then
  615.             break
  616.         end
  617.     end
  618.    
  619.     -- clearup the drones (place them into their chest)
  620.     tryForward()
  621.     turtle.turnRight()
  622.     turtle.turnRight()
  623.     while not tryDown() do sleep(1) end
  624.     while not tryDown() do sleep(1) end
  625.     while not tryForward() do sleep(1) end
  626.     turtle.turnRight()
  627.     for i = 1, 16 do
  628.         if turtle.getItemCount(i) > 0 then
  629.             turtle.select(i)
  630.             turtle.dropUp()
  631.         end
  632.     end
  633.     turtle.select(1)
  634.     for i = 1, 15 do
  635.         while not tryForward() do sleep(1) end
  636.         turtle.dropUp()
  637.     end
  638. end
  639.  
  640. function setup(force)
  641.     local force = force or false
  642.    
  643.     print("Please put ...")
  644.     print("... 16 wireless mining turtles in slot 1.")
  645.     print("... 16 iron or better chests in slot 2.")
  646.     print("... a floppy disk in slot 3.")
  647.     print("... a disk drive in slot 4.")
  648.     print("... fuel of any kind in slots 5-16.")
  649.     print()
  650.     print("Press RETURN to start or SPACE to exit.")
  651.     print()
  652.    
  653.     while not force do
  654.         local event, id, message = os.pullEvent()
  655.         if event == "key" and id == 28 then
  656.             break
  657.         elseif event == "key" and id == 57 then
  658.             return
  659.         end
  660.     end
  661.  
  662.     -- need fuel to place the floppy and cleanup after finish
  663.     while turtle.getFuelLevel() < 23 do
  664.         for i = 1, 16 do
  665.             turtle.select(i)
  666.             if turtle.refuel(1) then
  667.                 break
  668.             end
  669.         end
  670.         sleep(1)
  671.     end
  672.    
  673.     -- need some space below me
  674.     if not tryDown() then
  675.         print("No space below me")
  676.         return
  677.     end
  678.    
  679.     -- clear the floppy block
  680.     turtle.turnRight()
  681.     if not tryForward() then
  682.         print("Could not clear block in front for the floppy.")
  683.         return
  684.     end
  685.     while not turtle.back() do sleep(1) end
  686.    
  687.     -- place the disk drive and insert floppy
  688.     turtle.select(4)
  689.     while not turtle.place() do sleep(1) end
  690.     turtle.select(3)
  691.     while not turtle.drop() do sleep(1) end
  692.    
  693.     -- write startup file to floppy
  694.     fs.copy(SCRIPTPATH, "disk/" .. SCRIPTNAME)
  695.     local fp = fs.open("disk/startup", "w")
  696.     fp.writeLine("shell.run(\"disk/".. SCRIPTNAME .. "\", \"setuplane\")")
  697.     fp.close()
  698.    
  699.     -- move back to our position
  700.     while not tryUp() do sleep(1) end
  701.    
  702.     -- list of worker computerIDs
  703.     local workers = {}
  704.    
  705.     -- place, refuel and send off 16 drones
  706.     for i = 0, 15 do
  707.         print("Placing drone " .. i + 1 .. " of 16.")
  708.         print()
  709.         -- place the drone
  710.         turtle.select(1)
  711.         while turtle.detectDown() do sleep(1) end
  712.         turtle.placeDown()
  713.         -- boot the drone, thanks to dustpuppy for reminding me about the peripheral API
  714.         peripheral.call("bottom", "turnOn")
  715.         -- wait for announce, send lane number, wait for confirmation
  716.         -- the drone id is stored in the workers table
  717.         while true do
  718.             local id, message, distance = rednet.receive(5)
  719.             local m = {}
  720.             if message then
  721.                 m = textutils.unserialize(message)
  722.             end
  723.             if m["message"] == "hello" and distance < 1.4 then
  724.                 local answer = {}
  725.                 answer["message"] = "welcome"
  726.                 answer["lane"] = 15 - i
  727.                 rednet.send(id, textutils.serialize(answer))
  728.             elseif m and m["message"] == "fuelLevel" and m["lane"] == 15 - i then
  729.                 workers[15 - i] = id
  730.                 break
  731.             end
  732.         end
  733.         -- refuel drone to at least the threshold
  734.         if not FUELLESS then
  735.             while true do
  736.                 for j = 5, 16 do
  737.                     if turtle.getItemCount(j) > 0 then
  738.                         turtle.select(j)
  739.                         turtle.dropDown(1)
  740.                         break
  741.                     end
  742.                 end
  743.                 local id, message, distance = rednet.receive(5)
  744.                 local m = {}
  745.                 if message then
  746.                     m = textutils.unserialize(message)
  747.                 end
  748.                 if m["message"] == "fuelLevel" and m["fuelLevel"] > REFUELTHRESHOLD then
  749.                     break
  750.                 end
  751.             end
  752.         end
  753.         -- place chest in drone inventory
  754.         turtle.select(2)
  755.         turtle.dropDown(1)
  756.     end
  757.    
  758.     -- All drones placed. We switch to refuelling mode
  759.     shell.run(SCRIPTNAME, "refuelstation", textutils.serialize(workers))
  760. end
  761.  
  762. function printUsage()
  763.     print("Usage of " .. SCRIPTNAME .. " command:")
  764.     print()
  765.     print(SCRIPTNAME .. " setup|force|setuplane|diglane <laneNo> <refuelId>|refuelstation <serializedIdList>")
  766.     print("If you are not sure, you probably want the setup.")
  767.     print()
  768. end
  769.  
  770. -- =========================================
  771. --                  MAIN
  772. -- =========================================
  773.  
  774. if tArgs[1] == "setup" then
  775.     setup()
  776. elseif tArgs[1] == "force" then
  777.     setup(true)
  778. elseif tArgs[1] == "setuplane" then
  779.     setuplane()
  780. elseif tArgs[1] == "diglane" and tArgs[2] and tArgs[3] and tArgs[2] + 0 > -1 and tArgs[3] + 0 > -1 then
  781.     diglane(tArgs[2] + 0, tArgs[3] + 0)
  782. elseif tArgs[1] == "refuelstation" and tArgs[2] then
  783.     refuelStation(textutils.unserialize(tArgs[2]))
  784. else
  785.     printUsage()
  786. end
  787.  
  788. rednet.close("right")
  789. rednet.close("left")
  790. rednet.close("top")
  791. rednet.close("bottom")
  792. rednet.close("front")
  793. rednet.close("back")
  794.  
  795. ENDTIME = os.clock()
  796. print("Starttime:" .. STARTUPTIME)
  797. print("Endtime: " .. ENDTIME)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement