shirkit

Turtle end

Feb 23rd, 2013
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.91 KB | None | 0 0
  1. -- This script is based on the code of Plorntus (http://turtlescripts.com/project/gjdh0m-Auto-multimining-bot-quarry)
  2.  
  3. -- Custom Variables Changable.
  4. local port = "right"
  5. local timeOutOnRednet = 2
  6. local limitSize = 64 -- Maximum size of the quarry (64 is the recommended)
  7.  
  8. -- DO NOT CHANGE ANYTHING BELOW
  9. rednet.open(port)
  10.  
  11. -- These are XYZ values relative to the quarry. At default they will all be 0 as quarry is at 0,0
  12. local qu_x = 0
  13. local qu_y = 0
  14. local qu_z = -1
  15.  
  16. -- permanent variables, do not change
  17.  
  18. local facing = 2    -- my facing direction
  19. local tmove = 0     -- how many steps I moved since last refuel
  20. local fuelFor = 0   -- how many steps I can move with last refuel
  21.  
  22. local doneFirstLane = false
  23. local currentLane = {}
  24. local mainbot = false
  25. local w,h = term.getSize()
  26. local text = {}
  27.  
  28. function checkFuel (blocksNeeded)
  29.     if turtle.getFuelLevel() < blocksNeeded then
  30.         local moreFuel = true
  31.         local fuelNeeded = blocksNeeded - turtle.getFuelLevel()
  32.        
  33.         while fuelNeeded > 0 do
  34.             if turtle.refuel(1) == false then
  35.                 if takeItems("front") == false then
  36.                     return false
  37.                 end
  38.             end
  39.             fuelNeeded = blocksNeeded - turtle.getFuelLevel()
  40.         end
  41.         turtle.drop()
  42.         fuelFor = turtle.getFuelLevel()
  43.         tmove = 0
  44.         return true
  45.     else
  46.         return true
  47.     end
  48.     return false
  49. end
  50.  
  51. function split(sstr, pattern)
  52.    local t = {}
  53.    local fpat = "(.-)" .. pattern
  54.    local last_end = 1
  55.    local s, e, cap = sstr:find(fpat, 1)
  56.    while s do
  57.       if s ~= 1 or cap ~= "" then
  58.          table.insert(t,cap)
  59.       end
  60.       last_end = e+1
  61.       s, e, cap = sstr:find(fpat, last_end)
  62.    end
  63.    if last_end <= #sstr then
  64.       cap = sstr:sub(last_end)
  65.       table.insert(t, cap)
  66.    end
  67.    return t
  68. end
  69.  
  70. -- Terminal Drawning
  71. function printP(str)
  72.     table.insert(text,str)
  73.     if table.getn(text) > h then
  74.         table.remove(text,1)
  75.     end
  76.     drawFuelLevel()
  77. end
  78.  
  79. function drawFuelLevel()
  80.     term.clear()
  81.    
  82.     local fuelLevel = turtle.getFuelLevel()
  83.     local fuel = " Fuel: " .. fuelLevel
  84.     term.setCursorPos(w - #fuel+1, 1)
  85.     term.write(fuel)
  86.    
  87.     local pos = " Pos:"..qu_x..","..qu_y..","..qu_z
  88.     term.setCursorPos(w - #pos+1,2)
  89.     term.write(pos)
  90.    
  91.     local mov = " Moved:"..tmove
  92.     term.setCursorPos(w - #mov+1,3)
  93.     term.write(mov)
  94.    
  95.     local ffor = " Had:"..fuelFor
  96.     term.setCursorPos(w - #ffor+1,4)
  97.     term.write(ffor)
  98.    
  99.     for k=table.getn(text),1,-1 do
  100.         term.setCursorPos(1,k)
  101.         term.write(text[k])
  102.     end
  103. end
  104. -- Terminal Drawning end
  105.  
  106. -- Function finds and sets up with the nearest quarry
  107. function setupToNearestQuarry ()
  108.     local smallestDis = 0
  109.     local ownerID = 0
  110.     rednet.broadcast("CCQuarry LOCATE")
  111.     local startedTime = os.clock()
  112.     while (os.clock() - startedTime) <= timeOutOnRednet do
  113.         local id, mess, dis = rednet.receive(timeOutOnRednet)
  114.         if (mess == "CCQuarry PING") then
  115.             if ownerID == 0 or smallestDis > dis then
  116.                 smallestDis = dis
  117.                 ownerID = id
  118.             end
  119.         end
  120.     end
  121.     if (smallestDis == 0) then
  122.         return false
  123.     else return ownerID end
  124. end
  125.  
  126. function checkIfMainBotWithQuarry (qid)
  127.     local setupInformation = sendAndGetResponse(qid,"SETUP","")
  128.     if setupInformation ~= false then
  129.         if setupInformation[3] == "MAINBOT" then
  130.             return true
  131.         elseif setupInformation == "SLAVE" then
  132.             return false
  133.         end
  134.     else
  135.         -- general failure
  136.         turtle.up()    
  137.         turtle.digUp()
  138.         turtle.up()    
  139.         endWithError("1")
  140.     end
  141. end
  142.  
  143. -- Turning functions
  144. function turn(direction)
  145.     if direction == "left" or direction == "right" then
  146.         local d = 0
  147.         if direction == "left" then d = 1; turtle.turnLeft() else d = -1; turtle.turnRight() end
  148.         facing = facing + d
  149.         if (facing == -1) then facing = 3 elseif (facing == 4) then facing = 0 end
  150.         return true
  151.     end
  152.     return false
  153. end
  154.  
  155. -- Function turns to the specified facing location.
  156. function turnToN (face)
  157.     if face == facing then return true end
  158.     local lOrR = (facing - face + 4) % 4
  159.     if lOrR > 2 then
  160.         turn("left")
  161.     elseif lOrR < 2 then
  162.         turn("right")
  163.     else
  164.         turn("left")
  165.         turn("left")
  166.     end
  167.     return true
  168. end
  169.  
  170. function turnTo (nesw)
  171.     if nesw == "north" then
  172.         turnToN(0)
  173.     elseif nesw == "south" then
  174.         turnToN(2)
  175.     elseif nesw == "west" then
  176.         turnToN(1)
  177.     elseif nesw == "east" then
  178.         turnToN(3)
  179.     end
  180. end
  181. -- Turning functions end
  182.  
  183. -- Move functions
  184. function move (dir)
  185.     if dir == "up" then
  186.         if turtle.up() then
  187.             qu_y = qu_y + 1
  188.             tmove = tmove + 1
  189.             drawFuelLevel()
  190.             return true
  191.         else
  192.             return false
  193.         end
  194.     elseif dir == "down" then
  195.         if turtle.down() then
  196.             qu_y = qu_y - 1
  197.             tmove = tmove + 1
  198.             drawFuelLevel()
  199.             return true
  200.         else
  201.             return false
  202.         end
  203.     elseif dir == "north" or dir == "south" or dir == "west" or dir == "east" then
  204.         turnTo(dir)
  205.         local moved = turtle.forward()
  206.         if moved then
  207.             tmove = tmove + 1
  208.             drawFuelLevel()
  209.             if dir == "north" then qu_z = qu_z + 1 elseif dir == "south" then qu_z = qu_z - 1 elseif dir == "west" then qu_x = qu_x - 1 elseif dir == "east" then qu_x = qu_x + 1 end
  210.         return true
  211.         else
  212.             return false
  213.         end
  214.     end
  215.     return false
  216. end
  217.  
  218. function moveTo (targetX, targetZ,forever)
  219.     local way = "west"
  220.     if targetX > qu_x then
  221.         way = "east"
  222.     end
  223.     while targetX ~= qu_x do
  224.         if move(way) == false and forever == false then
  225.             return false
  226.         end
  227.     end
  228.     way = "south"
  229.     if targetZ > qu_z then
  230.         way = "north"
  231.     end
  232.     while targetZ ~= qu_z do
  233.         if move(way) == false and forever == false then
  234.             return false
  235.         end
  236.     end
  237.     return true
  238. end
  239. -- Move functions end
  240.  
  241. function doMainbotFunctions(qid)
  242.     local lengthOfCurrentQuarry = 0
  243.     local widthOfCurrentQuarry = 1
  244.     -- Setting new orientation without using turn functions so we get our 0 point.
  245.     for side = 1, 4, 1 do
  246.      if turtle.detect() == false then
  247.         break
  248.      end
  249.      turtle.turnLeft()
  250.      if side == 4 then
  251.         endWithError("2")
  252.       end  
  253.     end
  254.     facing = 0
  255.     turnTo("east")
  256.  
  257.     while not checkFuel((limitSize * 2) + 32) do
  258.         -- we couldn't see any fuel to get, let's wait for someone to fuel me up
  259.         -- TODO send message to PC informing problem
  260.         printP("Need more fuel. Add more fuel then type to continue");
  261.         read()
  262.     end
  263.    
  264.     -- Give extra fuel just in case!
  265.     while move("north") do
  266.         lengthOfCurrentQuarry = lengthOfCurrentQuarry + 1
  267.         if (lengthOfCurrentQuarry >= limitSize) then
  268.             break
  269.         end
  270.     end
  271.     sendMessage(qid, "LENGTH", lengthOfCurrentQuarry)
  272.     for a = 2, lengthOfCurrentQuarry, 1 do
  273.         move("south")
  274.     end
  275.     while move("east") do
  276.         widthOfCurrentQuarry = widthOfCurrentQuarry +  1
  277.         if (widthOfCurrentQuarry >= limitSize) then
  278.             break
  279.         end
  280.     end
  281.     sendMessage(qid, "WIDTH", widthOfCurrentQuarry)
  282.     printP("Quarry is "..lengthOfCurrentQuarry.. " long and ".. widthOfCurrentQuarry.." wide")
  283.     for a = 2, widthOfCurrentQuarry, 1 do
  284.         move("west")   
  285.     end
  286.  
  287.     moveTo(-1,0,true)
  288.     turnTo("south")
  289.     local items = checkChangedSlot({}, false)
  290.     while takeItems("front") do end
  291.     local changedItems = checkChangedSlot(items, true)
  292.     moveTo(0,0,true)
  293.     turnTo("south")
  294.     setupNewBots(changedItems, qid)
  295.     move("south")
  296. end
  297.  
  298. function waitForBotToMove()
  299.     while turtle.detect() do sleep(0.1) end
  300.     return true
  301. end
  302.  
  303. -- Function assumes  it is positioned in the correct location
  304. function setupNewBots (arr, qid)
  305.     sendMessage(qid, "STARTUP", "")
  306.     for botSlot = 1, table.getn(arr), 1 do
  307.         turtle.select(arr[botSlot])
  308.         while (turtle.getItemCount(arr[botSlot]) ~= 0) do
  309.             turtle.place()
  310.             sendMessage(qid, "TURNONBOT","")
  311.             waitForBotToMove()
  312.         end
  313.     end
  314.     sendMessage(qid, "DONESTARTUP", "")
  315. end
  316.  
  317. function endWithError (number)
  318.     printP("Ending with error code:"..number".")
  319.     os.exit()
  320. end
  321.  
  322. -- Function assumes there will be a response... if not youre fucked!
  323. function sendAndGetResponse (recid, messageID, message)
  324.     sendMessage(recid,messageID,message)
  325.     local startedTime = os.clock()
  326.     while (os.clock() - startedTime) <= timeOutOnRednet do
  327.         local id, mess, dis = rednet.receive(timeOutOnRednet)
  328.         if mess ~= nil and (id == recid or recid == 0) then
  329.             local splitMessage = split(mess, " ")
  330.             if (splitMessage[1] == "CCQuarry") then
  331.                 if (splitMessage[2] == messageID) then
  332.                     return splitMessage
  333.                 end
  334.             end
  335.         end
  336.     end
  337.     return false
  338. end
  339.  
  340. function sendAndGetResponseNoTimeout (recid, messageID, message)
  341.     sendMessage(recid,messageID,message)
  342.     while true do
  343.         local id, mess, dis = rednet.receive()
  344.         if mess ~= nil and (id == recid or recid == 0) then
  345.             local splitMessage = split(mess, " ")
  346.             if splitMessage[1] == "CCQuarry" and splitMessage[2] == messageID then
  347.                 return splitMessage
  348.             end
  349.         end
  350.     end
  351.     -- I assume this will never be reached but just in case >.>
  352.     return false
  353. end
  354.  
  355. function waitForResponseNoTimeout (recid,messageID)
  356.     while true do
  357.         local id, mess, dis = rednet.receive()
  358.         if mess ~= nil and (id == recid or recid == 0) then
  359.             local splitMessage = split(mess, " ")
  360.             if splitMessage[1] == "CCQuarry" and splitMessage[2] == messageID then
  361.                 return splitMessage
  362.             end
  363.         end
  364.     end
  365.     -- I assume this will never be reached but just in case >.>
  366.     return false
  367. end
  368.  
  369. function sendMessage (qid, messageID, message)
  370.     rednet.send(qid,"CCQuarry "..messageID.." "..message)
  371. end
  372.  
  373. -- Function returns array of the slots it placed the items from or false if could not take items
  374. function takeItems (direction)
  375.     if direction ~= "up" and direction ~= "down" and direction ~= "front" then endWithError("3"); end
  376.     local emptySlot = getNextEmptySlot()
  377.     local checkArr = {}
  378.     if (emptySlot ~= false) then
  379.         turtle.select(emptySlot)
  380.     else
  381.         checkArr = checkChangedSlot({}, false)
  382.     end
  383.     local success = false
  384.     if direction == "up" then
  385.         success = turtle.suckUp()
  386.     elseif direction == "down" then
  387.         success = turtle.suckDown()
  388.     else
  389.         success = turtle.suck()
  390.     end
  391.     if success then
  392.         if emptySlot ~= false then return {emptySlot}
  393.         else
  394.             return checkChangedSlot(checkArr, true)
  395.         end
  396.     else return false; end
  397. end
  398.  
  399. -- Function gives an array of all the slots and their counts if secondCheck is false and array is just a blank array
  400. -- If secondCheck is true it expects the array and loops through until it finds changes. It will return an array of changed slots
  401. -- Useful for when you take from an inventory and it fills a slot up you can find where it put it.
  402. function checkChangedSlot (array, secondCheck)
  403.     local newArr = {}  
  404.     if secondCheck == false then
  405.         for a = 1, 16, 1 do
  406.             newArr[a] = turtle.getItemCount(a)
  407.         end
  408.         return newArr
  409.     else
  410.         if table.getn(array) == 16 then
  411.             for a = 1, 16, 1 do
  412.                 if array[a] ~= turtle.getItemCount(a) then
  413.                     newArr[(table.getn(newArr) + 1)] = a
  414.                 end
  415.             end
  416.             return newArr
  417.         else
  418.             printP("Array given to checkChangedSlot is not 16 in length. Cannot continue.")
  419.         end
  420.     end
  421. end
  422.  
  423. function getNextEmptySlot ()
  424.     for a = 1, 16, 1 do
  425.         if turtle.getItemCount(a) == 0 then
  426.             return a
  427.         end
  428.     end
  429.     return false
  430. end
  431.  
  432. function getWorkingLane (qid)
  433.     local dd = sendAndGetResponseNoTimeout(qid, "LANE","")
  434.     return dd
  435. end
  436.  
  437. local attempedOverflow = false
  438.  
  439. function moveQueuePlace(p)
  440.     local didmove = true
  441.     -- first get into the waiting lane only if we are at working lane
  442.     if qu_y == 0 then
  443.         didmove = move("up") and didmove
  444.     end
  445.     -- only try to go there if our queue position is in front
  446.     if p < qu_z then
  447.         didmove =  moveTo(currentLane[1]-1,p,false) and didmove
  448.         if didmove == false then
  449.             -- we couldn't get into waiting lane, so just stay at working lane
  450.             if qu_y == 1 and attempedOverflow == false  then
  451.                 -- get into overflow lane if we were in service lane
  452.                 attempedOverflow = true
  453.                 while move("up") == false do end
  454.             end
  455.             -- try to get in position (in both working lane and overflow lane)
  456.             didmove = moveTo(currentLane[1]-1,p,false)
  457.             if didmove == false then
  458.                 -- we ran out of options, we tried on all 3 lanes, let's get out of the overflowlane if that's the case
  459.                 if qu_y == 2 then
  460.                     while move("down") == false do end
  461.                 end
  462.             end
  463.         end
  464.     end
  465. end
  466.  
  467. function waitToGoService (qid)
  468.     -- ask for our position in the queue
  469.     local resp = sendAndGetResponseNoTimeout(qid, "QUEUE", "")
  470.     if resp[3] == "0" then
  471.         printP("I'm off to service")
  472.     else
  473.         keepWaiting(qid,false)
  474.     end
  475. end
  476.  
  477. function keepWaiting (qid)
  478.     local wait = true
  479.     local resp
  480.     while wait == true do
  481.         resp = waitForResponseNoTimeout(qid,"QUEUE")
  482.         local pos = tonumber(resp[3])
  483.         if pos > 0 then
  484.             if pos < qu_z then
  485.                 moveQueuePlace(pos)
  486.             end
  487.         else
  488.             wait = false
  489.         end
  490.     end
  491. end
  492.  
  493. function requestQueuePosition (qid)
  494.     -- grab a resposonse from pc
  495.     local resp = sendAndGetResponseNoTimeout(qid, "QUEUE", "")
  496.    
  497.     local po = tonumber(resp[3])
  498.     if po > 0 then
  499.    
  500.         printP("I'm at "..resp[3].." in queue")
  501.    
  502.         moveQueuePlace(po)
  503.         printP("Waiting for service")
  504.         waitToGoService(qid)
  505.     else
  506.         printP("Nobody in front of me!")
  507.     end
  508.     attempedOverflow = false
  509. end
  510.  
  511. function unload()
  512.     -- go to pit stop
  513.     if moveTo(0,-1,false) == false then
  514.         move("up")
  515.         moveTo(0,-1,true)
  516.     end
  517.     while move("down") == true do end
  518.    
  519.     -- unload items
  520.     turnTo("west")
  521.     for inv = 1, 16, 1 do
  522.         turtle.select(inv)
  523.         turtle.drop()
  524.     end
  525.    
  526.     return true
  527. end
  528.  
  529. function startDigging(qid)
  530.     turtle.digDown()
  531.     while move("down") or turtle.digDown() do end
  532.     while qu_y ~= 0 do
  533.         if move("up") == false then
  534.             turtle.digUp()
  535.         end
  536.     end
  537. end
  538.  
  539. function processLane (qid)
  540.     local getCurrLane = ""
  541.    
  542.     if doneFirstLane == false and mainbot == true then
  543.         -- just tell the mainbot to get the first lane
  544.         getCurrLane = split("CCQuarry LANE 1 1"," ")
  545.         doneFirstLane = true
  546.     else
  547.         getCurrLane = getWorkingLane(qid)
  548.     end
  549.    
  550.     if getCurrLane ~= false  then
  551.         if getCurrLane[3] ~= "ENDLANE" then
  552.        
  553.             -- identify the lane where I should work
  554.             currentLane[1] = getCurrLane[3] + 0
  555.             currentLane[2] = getCurrLane[4] + 0
  556.             printP("Current lane ".. currentLane[1] .. " , "..currentLane[2])
  557.             printP("Refueling")
  558.            
  559.             -- refuel the turtle
  560.             turnTo("east")
  561.             checkFuel(10 + currentLane[1] * 2 + currentLane[2] * 2 + 256)
  562.             printP("Ready, going to work")
  563.            
  564.             -- go to moving lane
  565.             move("up")
  566.             sendMessage(qid, "DONESERVICE", "")
  567.             move("up")
  568.             move("up")
  569.            
  570.             -- go tomy lane and work
  571.             while moveTo(currentLane[1] - 1, currentLane[2] - 1,false) == false do
  572.                 turtle.dig()
  573.             end
  574.             move("down")
  575.             move("down")
  576.             startDigging(qid)
  577.             printP("Digging done")
  578.            
  579.             -- grab my position in the queue
  580.             requestQueuePosition(qid)
  581.             printP("Unloading items")
  582.             unload()
  583.             printP("Lane completed")
  584.             return true
  585.         else
  586.             return false
  587.         end
  588.     else
  589.         endWithError("1")
  590.     end
  591. end
  592.  
  593. -- grab the nearest quarry
  594. local MasterID = setupToNearestQuarry()
  595.  
  596. printP("Starting Up 1")
  597. if MasterID ~= false then
  598.     mainbot = checkIfMainBotWithQuarry (MasterID)
  599.     if mainbot then doMainbotFunctions(MasterID) end
  600.     while processLane(MasterID) do end
  601.     printP("Job finished")
  602.     -- grab the turtle above if any
  603.     move("up")
  604.     move("up")
  605.     turtle.digUp()
  606.     turtle.suckUp()
  607.     move("up")
  608.     sendMessage(MasterID, "DONESERVICE", "")
  609. else
  610.     endWithError("4")
  611. end
Add Comment
Please, Sign In to add comment