Advertisement
BombBloke

Chopper (ComputerCraft)

Dec 2nd, 2013
426
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.09 KB | None | 0 0
  1. -- Chopper
  2. -- ----------------------------------------------------------
  3.  
  4. -- Efficiency test; can this turtle provide a semi-decent
  5. -- income of wood/charcoal?
  6.  
  7. -- For those reading, plan is to add a companion turtle that
  8. -- uses the resulting (minor) power generation to produce
  9. -- supplies of various building blocks. Stone bricks,
  10. -- glass, planks, etc.
  11.  
  12. -- And then a third that'll build a base from those blocks.
  13.  
  14. -- ----------------------------------------------------------
  15.  
  16. -- Initialise important values:
  17.  
  18. -- ----------------------------------------------------------
  19.  
  20. -- Load locations of interest:
  21. shell.run("node")
  22.  
  23. local facing = {"north","east","south","west"}
  24. local pos, report = {}
  25. local modem = peripheral.wrap("right")
  26.  
  27. -- Number of inventory servers (that should be) online:
  28. local invServerCount, invServer = 0, {}
  29.  
  30. -- ----------------------------------------------------------
  31.  
  32. -- Functions and stuff:
  33.  
  34. -- ----------------------------------------------------------
  35.  
  36. -- Tell the turtle server I'm alive.
  37. local function doTurtleServerReport()
  38.     rednet.send(report,{"Hello TurtleServer",os.getComputerLabel()})
  39.     report = nil
  40. end
  41.  
  42. -- Poll the inventory servers re a given barrel.
  43. local function getAmountOf(barreltype)
  44.     local myMessage
  45.     for i=1,3 do
  46.         for i=1,invServerCount do rednet.send(invServer[i],barreltype) end
  47.         myMessage = {rednet.receive(3)}
  48.         if myMessage and tonumber(myMessage[2]) then break end
  49.     end
  50.    
  51.     if not tonumber(myMessage[2]) then
  52.         print("Warning: Could not get reading for amount of "..barreltype..".")
  53.         return 0
  54.     else return tonumber(myMessage[2]) end
  55. end
  56.  
  57. -- Check if the barrels I fill are filled.
  58. local function barrelsFull()
  59.     for i=1,#barrel do if getAmountOf(barrel[i]) < 4096 then return false end end
  60.     return true
  61. end
  62.  
  63. -- Returns true if the turtle is carrying anything.
  64. local function carrying()
  65.     for i=1,16 do if turtle.getItemCount(i) ~= 0 then return true end end
  66.     return false
  67. end
  68.  
  69. -- Accepts strings representing compass-facings to turn the turtle.
  70. local function faceDirection(targetdirection)
  71.     local tardir = 1
  72.     for i=1,4 do if targetdirection == facing[i] then tardir = i end end
  73.    
  74.     if tardir < pos.direction then
  75.         if tardir == 1 and pos.direction == 4 then
  76.             while not turtle.turnRight() do end
  77.         else
  78.             for i=1,pos.direction-tardir do while not turtle.turnLeft() do end end
  79.         end
  80.     elseif tardir > pos.direction then
  81.         if tardir == 4 and pos.direction == 1 then
  82.             while not turtle.turnLeft() do end
  83.         else
  84.             for i=1,tardir-pos.direction do while not turtle.turnRight() do end end
  85.         end
  86.     end
  87.    
  88.     pos.direction = tardir
  89. end
  90.  
  91. -- Move ahead a block, keeping track of the turtle's position.
  92. local function forward()
  93.     while not turtle.forward() do
  94.         turtle.dig()
  95.         turtle.attack()
  96.     end
  97.    
  98.     if pos.direction == 1 then pos.y = pos.y - 1
  99.     elseif pos.direction == 2 then pos.x = pos.x + 1
  100.     elseif pos.direction == 3 then pos.y = pos.y + 1
  101.     else pos.x = pos.x - 1 end
  102. end
  103.  
  104. local function turn(tardir)
  105.     if tardir == "left" then
  106.         while not turtle.turnLeft() do end
  107.         pos.direction = pos.direction - 1
  108.         if pos.direction < 1 then pos.direction = 4 end
  109.     elseif tardir == "right" then
  110.         while not turtle.turnRight() do end
  111.         pos.direction = pos.direction + 1
  112.         if pos.direction > 4 then pos.direction = 1 end
  113.     end
  114. end
  115.  
  116. -- Travel to a co-ordinate.
  117. local function goToPos(target,digger)
  118.     while (pos.x ~= node[target][1]) or (pos.y ~= node[target][2]) or (pos.z ~= node[target][3]) do
  119.         if pos.z > node[target][3] then
  120.             if digger then
  121.                 while not turtle.down() do
  122.                     turtle.digDown()
  123.                     turtle.attackDown()
  124.                 end
  125.                 pos.z = pos.z - 1
  126.             elseif turtle.down() then pos.z = pos.z - 1 end
  127.         elseif pos.z < node[target][3] then
  128.             if digger then
  129.                 while not turtle.up() do
  130.                     turtle.digUp()
  131.                     turtle.attackUp()
  132.                 end
  133.                 pos.z = pos.z + 1
  134.             elseif turtle.up() then pos.z = pos.z + 1 end
  135.         end
  136.        
  137.         if pos.x > node[target][1] then
  138.             if pos.direction ~= 4 then faceDirection("west") end
  139.             if digger then forward() elseif turtle.forward() then pos.x = pos.x - 1 end
  140.         elseif pos.x < node[target][1] then
  141.             if pos.direction ~= 2 then faceDirection("east") end
  142.             if digger then forward() elseif turtle.forward() then pos.x = pos.x + 1 end
  143.         end
  144.        
  145.         if pos.y > node[target][2] then
  146.             if pos.direction ~= 1 then faceDirection("north") end
  147.             if digger then forward() elseif turtle.forward() then pos.y = pos.y - 1 end
  148.         elseif pos.y < node[target][2] then
  149.             if pos.direction ~= 3 then faceDirection("south") end
  150.             if digger then forward() elseif turtle.forward() then pos.y = pos.y + 1 end
  151.         end
  152.     end
  153.    
  154.     faceDirection(node[target][4])
  155. end
  156.  
  157. -- Refuel the turtle itself.
  158. local function goGetFuel()
  159.     print("I'm hungry. Off to eat some EU...")
  160.     goToPos(3)
  161.     print("OMNOMNOM")
  162.     turtle.select(10)
  163.     while turtle.getFuelLevel() < 5000 do
  164.         turtle.suckUp()
  165.         turtle.refuel()
  166.         sleep(1)
  167.     end
  168.     print("Ah, that hit the spot!")
  169.     print("")
  170. end
  171.  
  172. -- Dumps the turtle's inventory into the dropoff chest.
  173. local function dropOff()
  174.     print("Dropping off loot...")
  175.    
  176.     local safe = false
  177.     if (node[1][4] == "north" and pos.y < node[8][2]) or
  178.        (node[1][4] == "east"  and pos.x > node[8][1]) or
  179.        (node[1][4] == "south" and pos.y > node[8][2]) or
  180.        (node[1][4] == "west"  and pos.x < node[8][1]) then safe = true end
  181.    
  182.     goToPos(8,safe)
  183.     while not turtle.down() do turtle.attackDown() end
  184.     pos.z = pos.z - 1
  185.     for i=1,16 do if turtle.getItemCount(i) ~= 0 then
  186.         turtle.select(i)
  187.         turtle.dropDown()
  188.     end end
  189.     turtle.select(1)
  190.     print("")
  191. end
  192.  
  193. -- Roam the plot collecting and planting.
  194. local function harvest()
  195.     print("I'm a lumberjack and I'm OK!")
  196.     print("")
  197.    
  198.     if node[10][1] then
  199.         goToPos(10,true)
  200.         node[10] = {}
  201.     else
  202.         forward()
  203.         pos.lastX, pos.lastY = 1, 1
  204.     end
  205.    
  206.     for xx = pos.lastX,16 do
  207.         for yy = pos.lastY,16 do
  208.             -- Check if a return to base is required.
  209.             if turtle.getFuelLevel() < 1000 or turtle.getItemCount(15) == 0 or turtle.getItemCount(14) > 0 then
  210.                 node[10][1] = pos.x
  211.                 node[10][2] = pos.y
  212.                 node[10][3] = pos.z
  213.                 node[10][4] = facing[pos.direction]
  214.                 pos.lastX = xx
  215.                 pos.lastY = yy
  216.                 return
  217.             end
  218.            
  219.             -- Combine sapling piles.
  220.             if turtle.getItemCount(15) < 5 then
  221.                 for i=1,14 do if turtle.getItemCount(i) ~= 0 then
  222.                     turtle.select(i)
  223.                     if turtle.compareTo(15) then turtle.transferTo(15) end
  224.                     if turtle.getItemCount(15) == 64 then break end
  225.                 end end
  226.             end
  227.            
  228.             if turtle.detectDown() then
  229.                 -- Dig out the current column if need be.
  230.                 turtle.select(1)
  231.                 while turtle.detectUp() do
  232.                     while not turtle.up() do turtle.digUp() end
  233.                     pos.z = pos.z + 1
  234.                     for i=1,4 do
  235.                         while turtle.detect() do turtle.dig() end
  236.                         while not turtle.turnRight() do end
  237.                     end
  238.                 end
  239.                 while pos.z > node[1][3] do
  240.                     while not turtle.down() do turtle.digDown() end
  241.                     pos.z = pos.z - 1
  242.                 end
  243.             end
  244.            
  245.             -- Re-plant.
  246.             turtle.select(16)
  247.             if turtle.compareDown() or not turtle.detectDown() then
  248.                 while turtle.compareDown() do turtle.digDown() end
  249.                 turtle.select(15)
  250.                 turtle.placeDown()
  251.             end
  252.            
  253.             while turtle.suckDown() do end
  254.            
  255.             -- Move ahead.
  256.             if yy < 16 then
  257.                 forward()
  258.             elseif xx < 16 then
  259.                 if facing[pos.direction] == node[1][4] then
  260.                     turn("right")
  261.                     forward()
  262.                     turn("right")
  263.                 else
  264.                     turn("left")
  265.                     forward()
  266.                     turn("left")
  267.                 end
  268.             end
  269.            
  270.             if report then doTurtleServerReport() end
  271.         end
  272.     end
  273. end
  274.  
  275. -- ----------------------------------------------------------
  276.  
  277. -- Primary functions:
  278.  
  279. -- ----------------------------------------------------------
  280.  
  281. -- Deal with rednet.
  282. local function turtleServer()
  283.     local turtleServerTimeOut, myEvent = os.startTimer(0)
  284.     while true do
  285.         myEvent = {os.pullEvent()}
  286.         if myEvent[1] == "timer" and myEvent[2] == turtleServerTimeOut then
  287.             report = 65535
  288.             turtleServerTimeOut = os.startTimer(600)
  289.         elseif myEvent[1] == "rednet_message" and myEvent[3] == "Hey, you still there?" then
  290.             report = myEvent[2]
  291.             turtleServerTimeOut = os.startTimer(600)
  292.         end
  293.     end
  294. end
  295.  
  296. -- Primary work loop.
  297. local function main()
  298.     while true do
  299.         print("Base maintenance...")
  300.         print("")
  301.  
  302.         if carrying() then dropOff() end      -- Ensure I'm not carrying spare stuff.
  303.  
  304.         if turtle.getFuelLevel() < 1000 then goGetFuel() end
  305.  
  306.         goToPos(4)                            -- Goto log barrel, get logs.
  307.         turtle.select(1)
  308.         turtle.suckUp()
  309.         goToPos(6)                            -- Goto furnace, drop logs.
  310.         turtle.drop()
  311.         goToPos(9)                            -- Collect charcoal from furnace.
  312.         turtle.select(2)
  313.         turtle.suckDown()
  314.         goToPos(7)                            -- Goto generator, drop charcoal.
  315.         turtle.drop()
  316.         if carrying() then dropOff() end
  317.  
  318.         goToPos(2)                            -- Goto sapling barrel, get saplings.
  319.         turtle.select(15)
  320.         turtle.suckUp()
  321.  
  322.         while turtle.getItemCount(15) == 0 do
  323.             print("Oy! No saplings! Waiting a minute...")
  324.             sleep(60)
  325.             turtle.suckUp()
  326.         end
  327.  
  328.         if turtle.getItemCount(16) == 0 then
  329.             goToPos(4)                    -- Goto log barrel, get log(s) for comparisons.
  330.             turtle.select(16)
  331.             turtle.suckUp()
  332.         end
  333.  
  334.         goToPos(8)
  335.         goToPos(1,true)                       -- Prepare to harvest.
  336.        
  337.         --if barrelsFull() then
  338.         --  print("I've filled my barrels, guess I'll take a breather...")
  339.         --  print("")
  340.         --  while barrelsFull() do
  341.         --      sleep(60)
  342.         --      if report then doTurtleServerReport() end
  343.         --  end
  344.         --end
  345.        
  346.         harvest()
  347.     end
  348. end
  349.  
  350. -- ----------------------------------------------------------
  351.  
  352. -- I've just booted up. Where am I? Who am I? etc...
  353.  
  354. -- ----------------------------------------------------------
  355.  
  356. -- Ping the GPS servers until I get a valid reading:
  357. do
  358.     local counter, tempx, tempy, tempz = 0
  359.     while tempx == nil or tempy == nil or tempz == nil do
  360.         tempx, tempz, tempy = gps.locate(5)
  361.         sleep(5)
  362.     end
  363.    
  364.     while not turtle.forward() do
  365.         while not turtle.turnLeft() do end
  366.         counter = counter + 1
  367.         if counter == 20 then -- I really don't wanna do this
  368.             counter = 0
  369.             turtle.dig()
  370.         end
  371.     end
  372.    
  373.     pos.x,pos.z,pos.y = gps.locate(5)
  374.  
  375.     if pos.x < tempx then pos.direction = 4
  376.     elseif pos.x > tempx then pos.direction = 2
  377.     elseif pos.y < tempy then pos.direction = 1
  378.     else pos.direction = 3 end
  379. end
  380.  
  381. -- Broadcast until all inventory servers are identified.
  382. rednet.open("right")
  383. while #invServer < invServerCount do
  384.     rednet.broadcast("Hello InvServer")
  385.     local myTimer = os.startTimer(5)
  386.     while true do
  387.         local myEvent = {os.pullEvent()}
  388.         if myEvent[1] == "timer" and myEvent[2] == myTimer then
  389.             break
  390.         elseif myEvent[1] == "rednet_message" and myEvent[3] == "Hello, InvServerClient!" then
  391.             invServer[#invServer+1] = myEvent[2]
  392.             for i=1,#invServer-1 do if invServer[i] == invServer[#invServer] then invServer[#invServer] = nil end end
  393.             if #invServer == invServerCount then break end
  394.         end
  395.     end
  396. end
  397.  
  398. print("I'm at "..pos.x..","..pos.y..","..pos.z..", I have "..turtle.getFuelLevel().." fuel and I'm facing "..facing[pos.direction]..".")
  399. print("")
  400.  
  401. parallel.waitForAny(main, turtleServer)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement