Advertisement
BombBloke

Hive Maintenance Turtle (ComputerCraft)

Jun 1st, 2013
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.71 KB | None | 0 0
  1. -- Hive Maintenance
  2. -- ----------------------------------------------------------
  3.  
  4. -- Tries to keep my barrels stocked with "real" resources,
  5. -- so's I don't have to worry about converting combs myself.
  6.  
  7. -- ----------------------------------------------------------
  8.  
  9. -- Initialise important values:
  10.  
  11. -- ----------------------------------------------------------
  12.  
  13. -- First three indexes are co-ords. All thereafter are linked nodes.
  14. local node = {{596,-237,64,   2},       --   1, hive central.
  15.     {596,-234,64,   1,3,10},  --   2, processed resource dropoff.
  16.     {603,-234,64,   2,14,5},  --   3, mid-eastern barrel.
  17.     {603,-218,64,   13},      --   4, the recharge station.
  18.     {610,-234,64,   3,6},     --   5, phospher pickup (eastern barrel).
  19.     {610,-230,64,   5,7},     --   6, centrifuge output chest.
  20.     {610,-228,64,   6,8},     --   7, centrifuge.
  21.     {610,-227,64,   7,9},     --   8, redstone energy cell.
  22.     {610,-226,64,   8,11},    --   9, squeezer.
  23.     {590,-234,64,   2,12},    --  10, tiny dust collection (mid-western barrel).
  24.     {610,-219,64,   9},       --  11, compressor.
  25.     {580,-234,64,   10},      --  12, western barrel.
  26.     {603,-220,64,   14,4},    --  13, furnace.
  27.     {603,-222,64,   3,13}}    --  14, furnace pickup.
  28.  
  29. -- Stuff to centrifuge.
  30. local comb  = {"tin comb","bronze comb","platinum comb","radioactive comb","lapis comb","diamond comb",
  31.     "copper comb","titanium comb","gold comb","fossilised comb","iron comb","ruby comb",
  32.     "electrum comb","glowing comb","brazen comb","clay comb","static comb","dripping comb",
  33.     "silver comb","invar comb","leaden comb","stringy comb","propolis","simmering comb"}
  34.    
  35. -- Stuff to combine (2x2 crafts).
  36. local tinydust = {"stone","stone brick","tiny pile of ruby dust","tiny pile of diamond dust",
  37.     "tiny pile of electrum dust","tiny pile of silver dust","tiny pile of titanium dust",
  38.     "tiny pile of platinum dust","tiny pile of invar dust","tiny pile of lead dust",
  39.     "tiny pile of gold dust","tiny pile of copper dust","tiny pile of bronze dust",
  40.     "tiny pile of brass dust","tiny pile of iron dust","tiny pile of tin dust"}
  41.    
  42. -- Stuff to furnace.
  43. local furnace = {"cobble","electrum dust","silver dust","invar dust","lead dust","gold dust",
  44.     "copper dust","bronze dust","brass dust","iron dust","tin dust","sticky resin"}
  45.    
  46. -- Stuff to compress (and how much is needed per operation).
  47. local compression = {{"lapis lazuli",9},{"glowstone dust",4},{"clay dust",1}}
  48.  
  49. -- Job timer IDs. [1] = furnace, [2] = compression, [3] = centrifuge.
  50. local worktimer = {0,0,0}
  51.  
  52. -- Misc stuff.
  53. local facing = {"north","east","south","west"}
  54. local direction = 1
  55. local curnode = 1
  56. local curcombbarrel = 1
  57. local curcompressor = 1
  58. local curfurnace = 1
  59. local curdust = 1
  60. local getmagmafuel = true
  61. local x = 0
  62. local y = 0
  63. local z = 0
  64. local sender = 0
  65. local message = ""
  66.  
  67. -- ----------------------------------------------------------
  68.  
  69. -- Functions and stuff:
  70.  
  71. -- ----------------------------------------------------------
  72.  
  73. -- Returns true if the turtle is carrying anything.
  74. local function carrying()
  75.     for i=1,16 do if turtle.getItemCount(i) ~= 0 then return true end end
  76.     return false
  77. end
  78.  
  79. -- Poll the inventory server re a given barrel.
  80. local function getBarrel(barreltype)
  81.     message = nil
  82.    
  83.     rednet.open("right")
  84.     while message == nil do
  85.         rednet.send(invserver,barreltype)
  86.         sender, message = rednet.receive(5)
  87.     end
  88.     rednet.close("right")
  89.    
  90.     return textutils.unserialize(message)
  91. end
  92.  
  93. -- Returns true if the turtle is at the specified node.
  94. local function atNode(tnode) return (x == node[tnode][1] and y == node[tnode][2] and z == node[tnode][3]) end
  95.  
  96. -- Accepts strings representing compass-facings to turn the turtle.
  97. local function faceDirection(targetdirection)
  98.     local tardir = 1
  99.     for i=1,4 do if targetdirection == facing[i] then tardir = i end end
  100.    
  101.     if tardir < direction then
  102.         if tardir == 1 and direction == 4 then
  103.             turtle.turnRight()
  104.         else
  105.             for i=1,direction-tardir do turtle.turnLeft() end
  106.         end
  107.     elseif tardir > direction then
  108.         if tardir == 4 and direction == 1 then
  109.             turtle.turnLeft()
  110.         else
  111.             for i=1,tardir-direction do turtle.turnRight() end
  112.         end
  113.     end
  114.    
  115.     direction = tardir
  116. end
  117.  
  118. -- Travel to a co-ordinate.
  119. local function goToPos(targetx,targety,targetz)
  120.     while (x ~= targetx) or (y ~= targety) or (z ~= targetz) do
  121.         if z > targetz then
  122.             if turtle.down() then z = z - 1 end
  123.         elseif z < targetz then
  124.             if turtle.up() then z = z + 1 end
  125.         end
  126.        
  127.         if x > targetx then
  128.             if direction ~= 4 then faceDirection("west") end
  129.             if turtle.forward() then x = x - 1 end
  130.         elseif x < targetx then
  131.             if direction ~= 2 then faceDirection("east") end
  132.             if turtle.forward() then x = x + 1 end
  133.         end
  134.        
  135.         if y > targety then
  136.             if direction ~= 1 then faceDirection("north") end
  137.             if turtle.forward() then y = y - 1 end
  138.         elseif y < targety then
  139.             if direction ~= 3 then faceDirection("south") end
  140.             if turtle.forward() then y = y + 1 end
  141.         end
  142.     end
  143. end
  144.  
  145. -- Travel to a node and update the node tracker.
  146. local function goToNode(desnode)
  147.     goToPos(node[desnode][1],node[desnode][2],node[desnode][3])
  148.     curnode = desnode
  149. end
  150.  
  151. -- Required by the below function.
  152. local function checkNextNode(priornode,testnode,desnode)
  153.     local distance = 255
  154.     local testdistance = 255
  155.     for i=1,table.getn(node[testnode])-3 do if node[testnode][3+i] ~= priornode and node[testnode][3+i] ~= curnode then
  156.         if node[testnode][3+i] == desnode then return desnode, (math.abs(node[testnode][1]-node[desnode][1]) + math.abs(node[testnode][2]-node[desnode][2])) end
  157.         testdistance = checkNextNode(testnode,node[testnode][3+i],desnode) + (math.abs(node[testnode][1]-node[node[testnode][3+i]][1]) + math.abs(node[testnode][2]-node[node[testnode][3+i]][2]))
  158.         if testdistance < distance then distance = testdistance end
  159.     end end
  160.     return distance
  161. end
  162.  
  163. -- Travels one node, in a direction that's best to get to an ultimate destination node.
  164. -- Will hence tend to be called multiple times in order to get there.
  165. local function headToNode(desnode)
  166.     if not atNode(desnode) then
  167.         local distance = 255
  168.         local testdistance = 255
  169.         local nextnode = 255
  170.         for i=1,table.getn(node[curnode])-3 do
  171.             if node[curnode][3+i] == desnode then
  172.                 goToNode(desnode)
  173.                 return
  174.             end
  175.             testdistance = checkNextNode(curnode,node[curnode][3+i],desnode) + (math.abs(node[curnode][1]-node[node[curnode][3+i]][1]) + math.abs(node[curnode][2]-node[node[curnode][3+i]][2]))
  176.             if testdistance < distance then
  177.                 distance = testdistance
  178.                 nextnode = node[curnode][3+i]
  179.             end
  180.         end
  181.         goToNode(nextnode)
  182.     end
  183. end
  184.  
  185. -- Refuel the turtle itself.
  186. local function goGetFuel()
  187.     print("I'm hungry. Off to eat some EU...")
  188.     while not atNode(4) do headToNode(4) end
  189.     faceDirection("east")
  190.     print("OMNOMNOM")
  191.     while turtle.getFuelLevel() < 10000 do sleep(30) end
  192.     print("Ah, that hit the spot!")
  193.     print("")
  194. end
  195.  
  196. -- Dumps the turtle's inventory into the dropoff chest.
  197. local function dropOff()
  198.     print("Dropping off loot...")
  199.     while not atNode(2) do headToNode(2) end
  200.     faceDirection("south")
  201.     for i=1,16 do if turtle.getItemCount(i) ~= 0 then
  202.         turtle.select(i)
  203.         turtle.drop()
  204.     end end
  205.     turtle.select(1)
  206.     print("")
  207. end
  208.  
  209. local function fuelMagmaticEngines()
  210.     barrelinfo = getBarrel("phosphor")
  211.    
  212.     print("I wonder how the lava production is going?")
  213.     while not atNode(9) do headToNode(9) end
  214.     faceDirection("west")
  215.     turtle.select(1)
  216.     turtle.suck()
  217.    
  218.     if turtle.getItemCount(1) ~= 0 then
  219.         print("Guess it hasn't finished the last phosphor load. Good!")
  220.         print("")
  221.         turtle.drop()
  222.         getmagmafuel = false
  223.         return
  224.     end
  225.    
  226.     print("Needs more phosphor!")
  227.     while not atNode(barrelinfo[1]) do headToNode(barrelinfo[1]) end
  228.     goToPos(barrelinfo[2],barrelinfo[3],barrelinfo[4])
  229.  
  230.     turtle.suckUp()
  231.    
  232.     if turtle.getItemCount(1) < 2 then
  233.         print((turtle.getItemCount(1) == 0) and "Erk! Out of phosphor!" or "Only ONE phosphor?!")
  234.         print("")
  235.         curcombbarrel = table.getn(comb)
  236.         goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  237.         return
  238.     end
  239.    
  240.     if bit.band(turtle.getItemCount(1),1) == 1 then turtle.transferTo(5,1) end
  241.     while not atNode(9) do headToNode(9) end
  242.     faceDirection("east")
  243.     turtle.select(2)
  244.     while turtle.getItemCount(2) < 64 do turtle.suck() end
  245.     turtle.transferTo(6,turtle.getItemCount(2) - (turtle.getItemCount(1) / 2))
  246.    
  247.     faceDirection("west")
  248.     turtle.select(1)
  249.     turtle.drop()
  250.     turtle.select(2)
  251.     turtle.drop()
  252.    
  253.     print("Lava production restocked.")
  254.     getmagmafuel = false
  255.    
  256.     if carrying() then dropOff() else print("") end
  257. end
  258.  
  259. -- Combine things together (craft).
  260. local function combineDustPiles()
  261.     print("Let's go combine some "..tinydust[curdust].."s.")
  262.     turtle.select(1)
  263.    
  264.     barrelinfo = getBarrel(tinydust[curdust])
  265.        
  266.     if barrelinfo[5] then
  267.         while not atNode(barrelinfo[1]) do headToNode(barrelinfo[1]) end
  268.         goToPos(barrelinfo[2],barrelinfo[3],barrelinfo[4])
  269.  
  270.         if not turtle.suckUp() then
  271.             print("No items here...")
  272.             print("")
  273.         elseif turtle.getItemCount(1) < 4 then
  274.             print("Not enough items here! Bah!")
  275.         else
  276.             print("Able to get "..math.floor(turtle.getItemCount(1) / 4).." new items!")
  277.             turtle.transferTo(2,math.floor(turtle.getItemCount(1) / 4))
  278.             turtle.transferTo(5,math.floor(turtle.getItemCount(1) / 3))
  279.             turtle.transferTo(6,math.floor(turtle.getItemCount(1) / 2))
  280.             turtle.craft()         
  281.         end
  282.  
  283.         goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  284.         if carrying() then dropOff() end
  285.     else
  286.         print("Current barrel is fully processed. Will skip it.")
  287.         print("")
  288.     end
  289.    
  290.     curdust = curdust + 1
  291.     if curdust > table.getn(tinydust) then curdust = 1 end
  292. end
  293.  
  294. -- Burn baby burn!
  295. local function cookStuff()
  296.     print("Let's go smelt some "..furnace[curfurnace]..".")
  297.    
  298.     barrelinfo = getBarrel(furnace[curfurnace])
  299.    
  300.     if barrelinfo[5] then
  301.         turtle.select(1)
  302.         while not atNode(barrelinfo[1]) do headToNode(barrelinfo[1]) end
  303.         goToPos(barrelinfo[2],barrelinfo[3],barrelinfo[4])
  304.  
  305.         if not turtle.suckUp() then
  306.             print("Nothing to cook...")
  307.             print("")
  308.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  309.         else
  310.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  311.             while not atNode(13) do headToNode(13) end
  312.             goToPos(604,-220,65)
  313.             worktimer[1] = os.startTimer(turtle.getItemCount(1) * 6.55)
  314.             turtle.suckDown()
  315.             turtle.dropDown()
  316.  
  317.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  318.             while not atNode(14) do headToNode(14) end
  319.             faceDirection("east")
  320.             while turtle.suck() do end 
  321.             if carrying() then dropOff() else print("") end
  322.         end
  323.     else
  324.         print("Current barrel is fully processed. Will skip it.")
  325.         print("")
  326.     end
  327.    
  328.     curfurnace = curfurnace + 1
  329.     if curfurnace > table.getn(furnace) then curfurnace = 1 end
  330. end
  331.  
  332. -- Some stuff needs to be packed down for efficient storage.
  333. local function compressStuff()
  334.     print("Let's go compress some "..compression[curcompressor][1].."s.")
  335.    
  336.     barrelinfo = getBarrel(compression[curcompressor][1])
  337.    
  338.     if barrelinfo[5] then
  339.         turtle.select(1)
  340.         while not atNode(barrelinfo[1]) do headToNode(barrelinfo[1]) end
  341.         goToPos(barrelinfo[2],barrelinfo[3],barrelinfo[4])
  342.  
  343.         if not turtle.suckUp() then
  344.             print("Nothing to compress...")
  345.             print("")
  346.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  347.         elseif turtle.getItemCount(1) < compression[curcompressor][2] then
  348.             print("Not enough to compress! Bah!")
  349.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  350.             dropOff()
  351.         else
  352.             print("Able to get "..math.floor(turtle.getItemCount(1) / compression[curcompressor][2]).." condensed items!")
  353.             turtle.transferTo(2,turtle.getItemCount(1) % compression[curcompressor][2])
  354.  
  355.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  356.             while not atNode(11) do headToNode(11) end
  357.             goToPos(609,-219,65)
  358.             worktimer[2] = os.startTimer((turtle.getItemCount(1) / compression[curcompressor][2]) * 20)
  359.             turtle.suckDown()
  360.             turtle.dropDown()      
  361.  
  362.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  363.             faceDirection("south")
  364.             while turtle.suck() do end 
  365.             if carrying() then dropOff() else print("") end
  366.         end
  367.     else
  368.         print("Current barrel is fully processed. Will skip it.")
  369.         print("")
  370.     end
  371.    
  372.     curcompressor = curcompressor + 1
  373.     if curcompressor > table.getn(compression) then curcompressor = 1 end
  374. end
  375.  
  376. -- Grabs a comb stack and processes it.
  377. local function processComb()
  378.     turtle.select(1)
  379.     print("Off to grab a stack of "..comb[curcombbarrel].."s...")
  380.    
  381.     barrelinfo = getBarrel(comb[curcombbarrel])
  382.    
  383.     if barrelinfo[5] then
  384.         while not atNode(barrelinfo[1]) do headToNode(barrelinfo[1]) end
  385.         goToPos(barrelinfo[2],barrelinfo[3],barrelinfo[4])
  386.  
  387.         if not turtle.suckUp() then
  388.             print("Huh, guess there aren't any combs of this type...")
  389.             print("")
  390.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  391.         else
  392.             print("Got "..turtle.getItemCount(1).." combs to process.")
  393.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  394.  
  395.             while not atNode(7) do headToNode(7) end
  396.             goToPos(609,-228,65)
  397.             faceDirection("east")
  398.             worktimer[3] = os.startTimer(turtle.getItemCount(1) * 5.25)
  399.             turtle.suckDown()
  400.             turtle.dropDown()
  401.            
  402.             goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  403.             while not atNode(6) do headToNode(6) end
  404.             faceDirection("west")
  405.             while turtle.suck() do end
  406.         end
  407.     else
  408.         print("Current barrel is fully processed. Will skip it.")
  409.         print("")
  410.     end
  411.    
  412.     curcombbarrel = curcombbarrel + 1
  413.     if curcombbarrel > table.getn(comb) then
  414.         getmagmafuel = true
  415.         curcombbarrel = 1
  416.     end
  417. end
  418.  
  419. -- ----------------------------------------------------------
  420.  
  421. -- Primary functions:
  422.  
  423. -- ----------------------------------------------------------
  424.  
  425. -- Reset the timer table as need be, flagging jobs as ready.
  426. local function catchTimers()
  427.     local event = ""
  428.     local timerID = 0
  429.     while true do
  430.         event, timerID = os.pullEvent("timer")
  431.         for i=1,table.getn(worktimer) do if worktimer[i] == timerID then
  432.             worktimer[i] = 0
  433.             break
  434.         end end
  435.     end
  436. end
  437.  
  438. -- Primary work loop.
  439. local function main()
  440.     while true do
  441.         if turtle.getFuelLevel() < 1000 then goGetFuel() end
  442.         if carrying() then dropOff() end
  443.         if getmagmafuel then fuelMagmaticEngines() end
  444.         combineDustPiles()
  445.         if worktimer[1] == 0 then cookStuff() end
  446.         if worktimer[2] == 0 then compressStuff() end
  447.         if worktimer[3] == 0 then processComb() end
  448.     end
  449. end
  450.  
  451. -- ----------------------------------------------------------
  452.  
  453. -- I've just booted up. Where am I? Who am I? etc...
  454.  
  455. -- ----------------------------------------------------------
  456.  
  457. -- Ping the inventory server until it answers.
  458. rednet.open("right")
  459. while invserver == nil do
  460.     rednet.broadcast("Hello InvServer")
  461.     invserver, message = rednet.receive(5)
  462. end
  463. rednet.close("right")
  464.  
  465. x, y, z = gps.locate(5)
  466.  
  467. -- Ping the GPS servers until I get a valid reading.
  468. while x == nil or y == nil or z == nil do
  469.     x, y, z = gps.locate(5)
  470.     sleep(5)
  471. end
  472.  
  473. -- Just a way of isolating some throw-away local variables.
  474. do
  475.     while not turtle.forward() do turtle.turnLeft() end
  476.     local tempx, tempy, tempz = gps.locate(5)
  477.  
  478.     if x > tempx then
  479.         direction = 4
  480.     elseif x < tempx then
  481.         direction = 2
  482.     elseif y > tempy then
  483.         direction = 1
  484.     else direction = 3 end
  485. end
  486.  
  487. x, y, z = gps.locate(5)
  488. print("I'm at "..x..","..y..","..z..", I have "..turtle.getFuelLevel().." fuel and I'm facing "..facing[direction]..".")
  489. print("")
  490.  
  491. -- Go to the nearest node first:
  492. do
  493.     local temp1 = 255
  494.     local temp2 = 0
  495.     for i=1,table.getn(node) do
  496.         temp2 = math.sqrt(math.pow(x - node[i][1],2) + math.pow(y - node[i][2],2))
  497.         temp2 = math.sqrt(math.pow(temp2,2) + math.pow(z - node[i][3],2))
  498.         if temp2 < temp1 then
  499.             temp1 = temp2
  500.             curnode = i
  501.         end
  502.     end
  503. end
  504. goToPos(node[curnode][1],node[curnode][2],node[curnode][3])
  505.  
  506. parallel.waitForAny(main, catchTimers)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement