Guest User

Tortoise

a guest
Mar 1st, 2016
559
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 29.79 KB | None | 0 0
  1. --start by localizing everything
  2. local shell, term, turtle, gps, fs, unpack, pairs, next, getfenv, tonumber, print, tFile = shell, term, turtle, gps, fs, unpack, pairs, next, getfenv, tonumber, print
  3. --(but HD thats pointless) dont argue I am weird like that
  4.  
  5. if not turtle then --why are we even here?
  6.     error("Not a turtle")
  7. end
  8. local function pastebin(sName, sFile) --Gets pastebin files
  9.   tPaste = http.get("http://www.pastebin.com/raw/"..sName)
  10.   if not fs.exists(sFile) then
  11.     local tInternal = fs.open(sFile,"w")
  12.     for line in tPaste.readLine do
  13.       tInternal.writeLine(line)
  14.     end
  15.     tInternal.close()
  16.   end
  17. end
  18.  
  19. --some creative table look up
  20. local tFacing = {
  21.     north={sLeft="west",sRight="east",sBack="south",sForward="z",iMulti=-1},
  22.     east={sLeft="north",sRight="south",sBack="west",sForward="x",iMulti=1},
  23.     south={sLeft="east",sRight="west",sBack="north",sForward="z",iMulti=1},
  24.     west={sLeft="south",sRight="north",sBack="east",sForward="x",iMulti=-1},
  25.     up={sForward="y",iMulti=1},
  26.     down={sForward="y",iMulti=-1}
  27. }
  28.  
  29. local function fGetInventory() --get the turtles inventory currently
  30.     local tOutput = {}
  31.     for i=1,16 do
  32.         tOutput[i] = turtle.getItemDetail(i)
  33.     end
  34.     return tOutput
  35. end
  36.  
  37. if not fs.isDir(".tortoise") then --make the data table if we have never run this turtle before
  38.     fs.makeDir(".tortoise/apis")
  39.     pastebin("0zvqEG6N",".tortoise/apis/daemon")
  40.     for i=1,16 do --find an empty slot
  41.         if turtle.getItemCount(i)==0 then
  42.             turtle.select(i)
  43.             break
  44.         end
  45.         if i==16 then --no empty slot? make one
  46.             turtle.select(i)
  47.             turtle.dropUp()
  48.         end
  49.     end
  50.     local X,y,Z,sFacing
  51.     local equipLeft,equipRight
  52.     turtle.equipLeft()
  53.     local equipLeft = turtle.getItemDetail() --what is in our left hand?
  54.     turtle.equipLeft()
  55.     turtle.equipRight()
  56.     local equipRight = turtle.getItemDetail() --what is in our right hand?
  57.     turtle.equipRight()
  58.     turtle.suckUp() --if we dropped an item earlier lets try to pick it up
  59.     local iX, iY, iZ = gps.locate(2) --if we have a gps may as well double check our position
  60.     if iX then
  61.         local iRot = 0
  62.         while not turtle.forward() do --attempt to move forward
  63.             if not turtle.detect() and not turtle.attack() then --if there isnt a block or mob
  64.                 turtle.refuel()
  65.             else
  66.                 turtle.turnLeft()
  67.                 iRot = iRot + 1
  68.             end
  69.         end
  70.         local iNewX,iNewY,iNewZ = gps.locate(2) --where are we now?
  71.         sFacing = ({[-1]={[0]="west"},[0]={[-1]="north",[1]="south"},[1]={[0]="east"}})[iNewX-iX][iNewZ-iZ] --determine our direction
  72.         if not turtle.back() then
  73.             iX,iZ=iNewX,iNewZ --if we couldnt go back go ahead and make this the new position and stay
  74.         end
  75.         for i=1,iRot%4 do
  76.             turtle.turnRight()
  77.             sFacing = tFacing[sFacing].sRight
  78.         end
  79.         X,Y,Z = iX,iY,iZ
  80.     else
  81.         print("This will only happen once")
  82.         print("Pos: ")
  83.         write("   X: ")
  84.         X = tonumber(read())
  85.         write("   Y: ")
  86.         Y = tonumber(read())
  87.         write("   Z: ")
  88.         Z = tonumber(read())
  89.         write("Facing: ")
  90.         sFacing = read()
  91.         print("Thank you!\nIf this disrupted anything please just reboot the turtle\nWe shouldn't ask any of this again.")
  92.     end
  93.    
  94.     tFile = fs.open(".tortoise/data","w")
  95.     local tData = {
  96.         tPosition = {x=X,y=Y,z=Z},
  97.         sFacing = sFacing,
  98.         tEquipment = {tLeft=equipLeft,tRight=equipRight},
  99.         tInventory = fGetInventory(),
  100.         iFuel = turtle.getFuelLevel(),
  101.         sMove = "none",
  102.         tLog = {},
  103.     }
  104.     tFile.write(textutils.serialize(tData):gsub("\10",""))
  105.     tFile.close()
  106. end
  107.  
  108. if not daemon then
  109.     os.loadAPI(".tortoise/apis/daemon") --this is used for inventory updating and async turtle functions
  110. end
  111.  
  112. local function tblHandle(tbl,key) --for the multi dimensional tables in turtle data
  113.     return {
  114.         __newindex = function(t,k,v)
  115.             rawset(t.handle,k,v)
  116.             tbl[key] = t.handle
  117.         end;
  118.         __index = function(t,k)
  119.             if type(t.handle[k])=="table" then
  120.                 return setmetatable({handle=t.handle[k]},tblHandle(t,k))
  121.             end
  122.             return t.handle[k]
  123.         end;
  124.     }
  125. end
  126.  
  127. local tInternalMeta = { --meta data for our internal stores
  128.     __newindex = function(t,k,v)
  129.         rawset(t.handle,k,v)
  130.         tFile = fs.open(".tortoise/data","w")
  131.         tFile.write(textutils.serialize(t.handle):gsub("\10",""))
  132.         tFile.close()
  133.     end;
  134.     __index = function(t,k)
  135.         if type(rawget(t.handle,k))=="table" then
  136.             return setmetatable({handle=rawget(t.handle,k)},tblHandle(t,k)) --tables are hard
  137.         else
  138.             return rawget(t.handle,k)
  139.         end
  140.     end;
  141. }
  142. tFile = fs.open(".tortoise/data","r")
  143. local tTurtleData = setmetatable({handle=textutils.unserialize(tFile.readLine())},tInternalMeta)--this will handle saving and loading for us automatically
  144. tFile.close()
  145.  
  146. local function fUpdateInventory()
  147.     while true do
  148.         os.pullEventRaw()
  149.         tTurtleData.tInventory = fGetInventory()
  150.     end
  151. end
  152. daemon.add(fUpdateInventory,"tortoise inventory management")
  153.  
  154. local tLog = tTurtleData.tLog
  155.  
  156. local iX, iY, iZ = gps.locate(2) --if we have a gps may as well double check our position
  157. if iX then
  158.     local iRot = 0
  159.     tPos = turtle.tPosition
  160.     if tPos and (tPos.x~=iX or tPos.y~=iY or tPos.z~=iZ) then
  161.         while not turtle.forward() do --attempt to move forward
  162.             if not turtle.detect() and not turtle.attack() then --if there isnt a block or mob
  163.                 turtle.refuel()
  164.             else
  165.                 turtle.turnLeft()
  166.                 iRot = iRot + 1
  167.             end
  168.         end
  169.         local iNewX,iNewY,iNewZ = gps.locate(2) --where are we now?
  170.         tTurtleData.sFacing = ({[-1]={[0]="north"},[0]={[-1]="west",[1]="east"},[1]={[0]="south"}})[iX-iNewX][iZ-iNewZ] --determine our direction
  171.         if not turtle.back() then
  172.             iX,iZ=iNewX,iNewZ --if we couldnt go back go ahead and make this the new position and stay
  173.         end
  174.         for i=1,iRot%4 do
  175.             tTurtleData.sFacing = tFacing[tTurtleData.sFacing].sRight
  176.             turtle.turnRight()
  177.         end
  178.     end
  179.     tTurtleData.tPosition = {x=iX,y=iY,z=iZ}
  180. end
  181.  
  182.  
  183. function updatePosition() --if we moved find out where
  184.     if tTurtleData.sMove~="none" then
  185.         local tInternalFace = tFacing[tTurtleData.sMove] --this is our current direction
  186.         tTurtleData.tPosition[tInternalFace.sForward] = tTurtleData.tPosition[tInternalFace.sForward] + (tInternalFace.iMulti * (tTurtleData.iFuel - turtle.getFuelLevel())) --fancy math determines where we are now in one equation
  187.         tTurtleData.iFuel = turtle.getFuelLevel() --get new fuel level
  188.     end
  189. end
  190. function forward(iNum) --try to move forward
  191.     iNum = iNum or 1
  192.     local bValid
  193.     if iNum > tTurtleData.iFuel then
  194.         return false
  195.     end
  196.     if tTurtleData.sMove~=tTurtleData.sFacing then --if we have turned lets find out where we are first
  197.         updatePosition()
  198.         tTurtleData.sMove=tTurtleData.sFacing
  199.     end
  200.     local iEnd
  201.     for i=1,iNum do
  202.         bValid = turtle.forward()
  203.         if not bValid then
  204.             iEnd = i - 1
  205.             break
  206.         else
  207.             tLog[#tLog.handle+1] = "back"
  208.         end
  209.     end
  210.     return bValid, iEnd --return what happened
  211. end
  212. function back(iNum) --try to move back
  213.     iNum = iNum or 1
  214.     local bValid
  215.     if iNum > tTurtleData.iFuel then
  216.         return false
  217.     end
  218.     if tTurtleData.sMove~=tFacing[tTurtleData.sFacing].sBack then --is the last movement opposite of our current facing?
  219.         updatePosition()
  220.         tTurtleData.sMove=tFacing[tTurtleData.sFacing].sBack
  221.     end
  222.     local iEnd
  223.     for i=1,iNum do
  224.         bValid = turtle.back()
  225.         if not bValid then
  226.             iEnd = i - 1
  227.             break
  228.         else
  229.             tLog[#tLog.handle+1] = "forward"
  230.         end
  231.     end
  232.     return bValid, iEnd --return what happened
  233. end
  234. function up(iNum) --try to go up
  235.     iNum = iNum or 1
  236.     local bValid
  237.     if iNum > tTurtleData.iFuel then
  238.         return false
  239.     end
  240.     if tTurtleData.sMove~="up" then --did we move up earlier?
  241.         updatePosition()
  242.         tTurtleData.sMove="up"
  243.     end
  244.     local iEnd
  245.     for i=1,iNum do
  246.         bValid = turtle.up()
  247.         if not bValid then
  248.             iEnd = i - 1
  249.             break
  250.         else
  251.             tLog[#tLog.handle+1] = "down"
  252.         end
  253.     end
  254.     return bValid, iEnd --return what happened
  255. end
  256. function down(iNum) --same comments for up..in reverse
  257.     iNum = iNum or 1
  258.     local bValid
  259.     if iNum > tTurtleData.iFuel then
  260.         return false
  261.     end
  262.     if tTurtleData.sMove~="down" then
  263.         updatePosition()
  264.         tTurtleData.sMove="down"
  265.     end
  266.     local iEnd
  267.     for i=1,iNum do
  268.         bValid = turtle.down()
  269.         if not bValid then
  270.             iEnd = i - 1
  271.             break
  272.         else
  273.             tLog[#tLog.handle+1] = "up"
  274.         end
  275.     end
  276.     return bValid, iEnd --return what happened
  277. end
  278. function turnLeft() --try to turn left
  279.     tTurtleData.sFacing = tFacing[tTurtleData.sFacing].sLeft --get the facing left of our current
  280.     tLog[#tLog.handle+1] = "turnRight"
  281.     return turtle.turnLeft()
  282. end
  283. function turnRight() --same as above but in reverse
  284.     tTurtleData.sFacing = tFacing[tTurtleData.sFacing].sRight
  285.     tLog[#tLog.handle+1] = "turnLeft"
  286.     return turtle.turnRight()
  287. end
  288. function strafeLeft(iNum)
  289.     turnLeft()
  290.     local bValid, iEnd = forward(iNum)
  291.     turnRight()
  292.     return bValid, iEnd
  293. end
  294. function strafeRight(iNum)
  295.     turnRight()
  296.     local bValid, iEnd = forward(iNum)
  297.     turnLeft()
  298.     return bValid, iEnd
  299. end
  300.  
  301. function reverse()
  302.     tTurtleData.sFacing = tFacing[tTurtleData.sFacing].sBack --get the opposite
  303.     turtle.turnLeft()
  304.     tLog[#tLog.handle+1] = "reverse"
  305.     return turtle.turnLeft()
  306. end
  307. function equipLeft(iSlot,iDamage) --try to equip a new item on the left
  308.     if type(iSlot)=="string" then
  309.         for i=1,16 do
  310.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  311.                 iSlot = i
  312.                 break
  313.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  314.                 iSlot = i
  315.                 break
  316.             end
  317.         end
  318.     end
  319.     if type(iSlot)=="string" then
  320.         return false
  321.     end
  322.     if iSlot then
  323.         turtle.select(iSlot)
  324.     end
  325.     local tItem = turtle.getItemDetail() --if it works what would this item be?
  326.     if turtle.equipLeft() then --now lets equip
  327.         tTurtleData.tEquipment.tLeft = tItem--if it equipped then we know what it now is
  328.         return true
  329.     end
  330.     return false --if we got here we couldnt equip
  331. end
  332. function equipRight(iSlot, iDamage) --same as above but for the right side
  333.     if type(iSlot)=="string" then
  334.         for i=1,16 do
  335.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  336.                 iSlot = i
  337.                 break
  338.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  339.                 iSlot = i
  340.                 break
  341.             end
  342.         end
  343.     end
  344.     if type(iSlot)=="string" then
  345.         return false
  346.     end
  347.     if iSlot then
  348.         turtle.select(iSlot)
  349.     end
  350.     local tItem = turtle.getItemDetail()
  351.     if turtle.equipRight() then
  352.         tTurtleData.tEquipment.tRight = tItem
  353.         return true
  354.     end
  355.     return false
  356. end
  357. function select(iSlot, iDamage)
  358.     if type(iSlot)=="string" then
  359.         for i=1,16 do
  360.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  361.                 iSlot = i
  362.                 break
  363.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  364.                 iSlot = i
  365.                 break
  366.             end
  367.         end
  368.     end
  369.     if type(iSlot)=="string" then
  370.         return false
  371.     end
  372.     return turtle.select(iSlot)
  373. end
  374. function getItemCount(iSlot, iDamage)
  375.     if type(iSlot)=="string" then
  376.         for i=1,16 do
  377.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  378.                 iSlot = i
  379.                 break
  380.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  381.                 iSlot = i
  382.                 break
  383.             end
  384.         end
  385.     end
  386.     if type(iSlot)=="string" then
  387.         return false
  388.     end
  389.     return iSlot and turtle.getItemCount(iSlot) or turtle.getItemCount()
  390. end
  391. function getItemSpace(iSlot, iDamage)
  392.     if type(iSlot)=="string" then
  393.         for i=1,16 do
  394.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  395.                 iSlot = i
  396.                 break
  397.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  398.                 iSlot = i
  399.                 break
  400.             end
  401.         end
  402.     end
  403.     if type(iSlot)=="string" then
  404.         return false
  405.     end
  406.     return iSlot and turtle.getItemSpace(iSlot) or turtle.getItemSpace()
  407. end
  408. function suck(iCount,iSlot, iDamage)
  409.     if type(iSlot)=="string" then
  410.         for i=1,16 do
  411.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  412.                 iSlot = i
  413.                 break
  414.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  415.                 iSlot = i
  416.                 break
  417.             end
  418.         end
  419.     end
  420.     if type(iSlot)=="string" then
  421.         return false
  422.     end
  423.     if iSlot then
  424.         turtle.select(iSlot)
  425.     end
  426.     return iCount and turtle.suck(iCount) or turtle.suck()
  427. end
  428. function suckUp(iCount,iSlot, iDamage)
  429.     if type(iSlot)=="string" then
  430.         for i=1,16 do
  431.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  432.                 iSlot = i
  433.                 break
  434.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  435.                 iSlot = i
  436.                 break
  437.             end
  438.         end
  439.     end
  440.     if type(iSlot)=="string" then
  441.         return false
  442.     end
  443.     if iSlot then
  444.         turtle.select(iSlot)
  445.     end
  446.     return iCount and turtle.suckUp(iCount) or turtle.suckUp()
  447. end
  448. function suckDown(iCount,iSlot, iDamage)
  449.     if type(iSlot)=="string" then
  450.         for i=1,16 do
  451.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  452.                 iSlot = i
  453.                 break
  454.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  455.                 iSlot = i
  456.                 break
  457.             end
  458.         end
  459.     end
  460.     if type(iSlot)=="string" then
  461.         return false
  462.     end
  463.     if iSlot then
  464.         turtle.select(iSlot)
  465.     end
  466.     return iCount and turtle.suckDown(iCount) or turtle.suckDown()
  467. end
  468. function drop(iCount,iSlot, iDamage)
  469.     if type(iSlot)=="string" then
  470.         for i=1,16 do
  471.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  472.                 iSlot = i
  473.                 break
  474.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  475.                 iSlot = i
  476.                 break
  477.             end
  478.         end
  479.     end
  480.     if type(iSlot)=="string" then
  481.         return false
  482.     end
  483.     if iSlot then
  484.         turtle.select(iSlot)
  485.     end
  486.     return iCount and turtle.drop(iCount) or turtle.drop()
  487. end
  488. function dropUp(iCount,iSlot, iDamage)
  489.     if type(iSlot)=="string" then
  490.         for i=1,16 do
  491.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  492.                 iSlot = i
  493.                 break
  494.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  495.                 iSlot = i
  496.                 break
  497.             end
  498.         end
  499.     end
  500.     if type(iSlot)=="string" then
  501.         return false
  502.     end
  503.     if iSlot then
  504.         turtle.select(iSlot)
  505.     end
  506.     return iCount and turtle.dropUp(iCount) or turtle.dropUp()
  507. end
  508. function dropDown(iCount,iSlot, iDamage)
  509.     if type(iSlot)=="string" then
  510.         for i=1,16 do
  511.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  512.                 iSlot = i
  513.                 break
  514.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  515.                 iSlot = i
  516.                 break
  517.             end
  518.         end
  519.     end
  520.     if type(iSlot)=="string" then
  521.         return false
  522.     end
  523.     if iSlot then
  524.         turtle.select(iSlot)
  525.     end
  526.     return iCount and turtle.dropDown(iCount) or turtle.dropDown()
  527. end
  528. function place(sText,iSlot, iDamage)
  529.     if type(iSlot)=="string" then
  530.         for i=1,16 do
  531.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  532.                 iSlot = i
  533.                 break
  534.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  535.                 iSlot = i
  536.                 break
  537.             end
  538.         end
  539.     end
  540.     if type(iSlot)=="string" then
  541.         return false
  542.     end
  543.     if iSlot then
  544.         turtle.select(iSlot)
  545.     end
  546.     return sText and turtle.place(sText) or turtle.place()
  547. end
  548. function placeUp(sText,iSlot, iDamage)
  549.     if type(iSlot)=="string" then
  550.         for i=1,16 do
  551.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  552.                 iSlot = i
  553.                 break
  554.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  555.                 iSlot = i
  556.                 break
  557.             end
  558.         end
  559.     end
  560.     if type(iSlot)=="string" then
  561.         return false
  562.     end
  563.     if iSlot then
  564.         turtle.select(iSlot)
  565.     end
  566.     return sText and turtle.placeUp(sText) or turtle.placeUp()
  567. end
  568. function placeDown(sText,iSlot, iDamage)
  569.     if type(iSlot)=="string" then
  570.         for i=1,16 do
  571.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  572.                 iSlot = i
  573.                 break
  574.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  575.                 iSlot = i
  576.                 break
  577.             end
  578.         end
  579.     end
  580.     if type(iSlot)=="string" then
  581.         return false
  582.     end
  583.     if iSlot then
  584.         turtle.select(iSlot)
  585.     end
  586.     return sText and turtle.placeDown(sText) or turtle.placeDown()
  587. end
  588. function compareTo(iSlot, iDamage)
  589.     if type(iSlot)=="string" then
  590.         for i=1,16 do
  591.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  592.                 iSlot = i
  593.                 break
  594.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  595.                 iSlot = i
  596.                 break
  597.             end
  598.         end
  599.     end
  600.     if type(iSlot)=="string" then
  601.         return false
  602.     end
  603.     return turtle.CompareTo(iSlot)
  604. end
  605. function compareUpTo(iSlot, iDamage)
  606.     if type(iSlot)=="string" then
  607.         for i=1,16 do
  608.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  609.                 iSlot = i
  610.                 break
  611.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  612.                 iSlot = i
  613.                 break
  614.             end
  615.         end
  616.     end
  617.     if type(iSlot)=="string" then
  618.         return false
  619.     end
  620.     local iCurr = turtle.getSelectedSlot()
  621.     turtle.select(iSlot)
  622.     local bResult = turtle.compareUp()
  623.     turtle.select(iCurr)
  624.     return bResult
  625. end
  626. function compareDownTo(iSlot, iDamage)
  627.     if type(iSlot)=="string" then
  628.         for i=1,16 do
  629.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  630.                 iSlot = i
  631.                 break
  632.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  633.                 iSlot = i
  634.                 break
  635.             end
  636.         end
  637.     end
  638.     if type(iSlot)=="string" then
  639.         return false
  640.     end
  641.     local iCurr = turtle.getSelectedSlot()
  642.     turtle.select(iSlot)
  643.     local bResult = turtle.compareDown()
  644.     turtle.select(iCurr)
  645.     return bResult
  646. end
  647.  
  648. function has(sName)
  649.     for i=1,16 do
  650.         if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==sName then
  651.             return i
  652.         end
  653.     end
  654.     return false
  655. end
  656. function transferTo(iSlot,iQuantity, iDamage)
  657.     if type(iSlot)=="string" then
  658.         for i=1,16 do
  659.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  660.                 iSlot = i
  661.                 break
  662.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  663.                 iSlot = i
  664.                 break
  665.             end
  666.         end
  667.     end
  668.     if type(iSlot)=="string" then
  669.         return false
  670.     end
  671.     return iQuantity and turtle.transferTo(iSlot,iQuantity) or turtle.transferTo(iSlot)
  672. end
  673. function transferFrom(iSlot,iQuantity, iDamage)
  674.     if type(iSlot)=="string" then
  675.         for i=1,16 do
  676.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  677.                 iSlot = i
  678.                 break
  679.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  680.                 iSlot = i
  681.                 break
  682.             end
  683.         end
  684.     end
  685.     if type(iSlot)=="string" then
  686.         return false
  687.     end
  688.     local iCurr = turtle.getSelectedSlot()
  689.     turtle.select(iSlot)
  690.     if iQuantity then
  691.         turtle.transferTo(iCurr,iQuantity)
  692.     else
  693.         turtle.transferTo(iCurr)
  694.     end
  695.     turtle.select(iCurr)
  696. end
  697. function transferBetween(iFrom,iTo,iQuantity, iDamageTo, iDamageFrom)
  698.     if type(iFrom)=="string" then
  699.         for i=1,16 do
  700.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iFrom and (not iDamage or tTurtleData.tInventory[i].damage==iDamageFrom) then
  701.                 iFrom = i
  702.                 break
  703.             elseif not tTurtleData.tInventory[i] and iFrom=="empty" then
  704.                 iFrom = i
  705.                 break
  706.             end
  707.         end
  708.     end
  709.     if type(iFrom)=="string" then
  710.         return false
  711.     end
  712.     if type(iTo)=="string" then
  713.         for i=1,16 do
  714.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iTo and (not iDamage or tTurtleData.tInventory[i].damage==iDamageTo) then
  715.                 iTo = i
  716.                 break
  717.             elseif not tTurtleData.tInventory[i] and iTo=="empty" then
  718.                 iTo = i
  719.                 break
  720.             end
  721.         end
  722.     end
  723.     if type(iTo)=="string" then
  724.         return false
  725.     end
  726.     local iCurr = turtle.getSelectedSlot()
  727.     turtle.select(iFrom)
  728.     if iQuantity then
  729.         turtle.transferTo(iTo,iQuantity)
  730.     else
  731.         turtle.transferTo(iTo)
  732.     end
  733.     turtle.select(iCurr)
  734. end
  735. function refuel(iAmount,iSlot, iDamage) --needed because we depend on fuel level
  736.     if type(iSlot)=="string" then
  737.         for i=1,16 do
  738.             if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
  739.                 iSlot = i
  740.                 break
  741.             elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
  742.                 iSlot = i
  743.                 break
  744.             end
  745.         end
  746.     end
  747.     if type(iSlot)=="string" then
  748.         return false
  749.     end
  750.     if iSlot then
  751.         turtle.select(iSlot)
  752.     end
  753.     updatePosition()
  754.     local ok = iAmount and turtle.refuel(iAmount) or turtle.refuel() --because of a bug in the function
  755.     if ok then --if we refueled then
  756.         tTurtleData.iFuel = turtle.getFuelLevel() --set our amount to the current level
  757.         return true
  758.     end
  759.     return false --otherwise, return false
  760. end
  761. function setData(iX,iY,iZ,sFaceing,tEquipLeft,tEquipRight,iFuel,tInventory) --update internal data
  762.     tTurtleData = {
  763.         tPosition = {x=iX,y=iY,z=iZ},--position
  764.         sFacing = sFacing,--direction
  765.         tEquipment = {tLeft=tEquipLeft,tRight=tEquipRight},--equipment
  766.         iFuel = iFuel or turtle.getFuelLevel(),--fuel
  767.         sMove = "none",--since we are changing everything there was no last movement
  768.         tInventory = tInventory or fGetInventory(),
  769.     }
  770. end
  771. function updateData()
  772.     local iX, iY, iZ = gps.locate(2)
  773.     if iX then
  774.         tPos = turtle.sFacing and turtle.tPosition
  775.         if tPos and (tPos.x~=iX or tPos.y~=iY or tPos.z~=iZ) then
  776.             while not turtle.forward() do --attempt to move forward
  777.                 if not turtle.detect() and not turtle.attack() then --if there isnt a block or mob
  778.                     turtle.refuel()
  779.                 end
  780.             end
  781.             local iNewX,iNewY,iNewZ = gps.locate(2) --where are we now?
  782.             tTurtleData.sFacing = ({[-1]={[0]="north"},[0]={[-1]="west",[1]="east"},[1]={[0]="south"}})[iX-iNewX][iZ-iNewZ] --determine our direction
  783.             if not turtle.back() then
  784.                 iX,iZ=iNewX,iNewZ --if we couldnt go back go ahead and make this the new position and stay
  785.             end
  786.         end
  787.         tTurtleData.tPosition = {x=iX,y=iY,z=iZ}
  788.         for i=1,16 do --find an empty slot
  789.             if turtle.getItemCount(i)==0 then
  790.                 turtle.select(i)
  791.                 break
  792.             end
  793.             if i==16 then --no empty slot? make one
  794.                 turtle.select(i)
  795.                 turtle.dropUp()
  796.             end
  797.         end
  798.         turtle.equipLeft()
  799.         tTurtleData.tEquipment.tLeft = turtle.getItemDetail() --what is in our left hand?
  800.         turtle.equipLeft()
  801.         turtle.equipRight()
  802.         tTurtleData.tEquipment.tRight = turtle.getItemDetail() --what is in our right hand?
  803.         turtle.equipRight()
  804.         turtle.suckUp() --if we dropped an item earlier lets try to pick it up
  805.         tTurtleData.sMove = "none"
  806.         tTurtleData.iFuel = turtle.getFuelLevel()
  807.         tTurtleData.tInventory = fGetInventory()
  808.         return true
  809.     else
  810.         return false
  811.     end
  812. end
  813. function getData() --get our internal data
  814.     updatePosition() --update position first though so its accurate
  815.     return tTurtleData.handle
  816. end
  817. function pos()
  818.     updatePosition() --update first
  819.     return tTurtleData.handle.tPosition
  820. end
  821. function getLeft() --left hand
  822.     return tTurtleData.handle.tEquipment.tLeft
  823. end
  824. function getRight() --right hand
  825.     return tTurtleData.handle.tEquipment.tRight
  826. end
  827. function getEquip() --both hands
  828.     return tTurtleData.handle.tEquipment
  829. end
  830.  
  831. --no hands
  832.  
  833. function facing()
  834.     return tTurtleData.handle.sFacing
  835. end
  836.  
  837. function inventory()
  838.     return tTurtleData.handle.tInventory
  839. end
  840.  
  841. function becomeTurtle()
  842.     turtle = {}
  843.     for k, v in next, _G.turtle do --first we need to fix our local turtle table so we don't start any loops
  844.         turtle[k] = v
  845.     end
  846.     for k, v in next, getfenv() do --then we put ourselves in the global turtle table
  847.         _G.turtle[k] = v
  848.     end
  849. end
  850.  
  851. function forwardForce(iNum) --move forward no matter what
  852.     if iNum == 0 then
  853.         return true
  854.     end
  855.     iNum = iNum or 1
  856.     local bValid, iInternal
  857.     if tTurtleData.iFuel >= iNum then
  858.         repeat
  859.             bValid, iInternal = forward(iNum)
  860.             if iInternal then
  861.                 iNum = iNum - iInternal
  862.                 turtle.dig()
  863.                 turtle.attack()
  864.             end
  865.         until bValid
  866.     end
  867. end
  868.  
  869. function backForce(iNum) --move backward no matter what
  870.     if iNum == 0 then
  871.         return true
  872.     end
  873.     iNum = iNum or 1
  874.     local bValid, iInternal
  875.     if tTurtleData.iFuel >= iNum then
  876.         repeat
  877.             bValid, iInternal = back(iNum)
  878.             if iInternal then
  879.                 iNum = iNum - iInternal
  880.                 reverse()
  881.                 turtle.dig()
  882.                 turtle.attack()
  883.                 reverse()
  884.             end
  885.         until bValid
  886.     end
  887. end
  888.  
  889. function upForce(iNum) --move up no matter what
  890.     if iNum == 0 then
  891.         return true
  892.     end
  893.     iNum = iNum or 1
  894.     local bValid, iInternal
  895.     if tTurtleData.iFuel >= iNum then
  896.         repeat
  897.             bValid, iInternal = up(iNum)
  898.             if iInternal then
  899.                 iNum = iNum - iInternal
  900.                 turtle.digUp()
  901.                 turtle.attackUp()
  902.             end
  903.         until bValid
  904.     end
  905. end
  906.  
  907. function downForce(iNum) --move down no matter what
  908.     if iNum == 0 then
  909.         return true
  910.     end
  911.     iNum = iNum or 1
  912.     local bValid, iInternal
  913.     if tTurtleData.iFuel >= iNum then
  914.         repeat
  915.             bValid, iInternal = down(iNum)
  916.             if iInternal then
  917.                 iNum = iNum - iInternal
  918.                 turtle.digDown()
  919.                 turtle.attackDown()
  920.             end
  921.         until bValid
  922.     end
  923. end
  924.  
  925. function strafeRightForce(iNum)
  926.     if iNum == 0 then
  927.         return true
  928.     end
  929.     turnRight()
  930.     iNum = iNum or 1
  931.     local bValid, iInternal
  932.     if tTurtleData.iFuel >= iNum then
  933.         repeat
  934.             bValid, iInternal = forward(iNum)
  935.             if iInternal then
  936.                 iNum = iNum - iInternal
  937.                 turtle.dig()
  938.                 turtle.attack()
  939.             end
  940.         until bValid
  941.     end
  942.     turnLeft()
  943. end
  944.  
  945. function strafeLeftForce(iNum)
  946.     if iNum == 0 then
  947.         return true
  948.     end
  949.     turnLeft()
  950.     iNum = iNum or 1
  951.     local bValid, iInternal
  952.     if tTurtleData.iFuel >= iNum then
  953.         repeat
  954.             bValid, iInternal = forward(iNum)
  955.             if iInternal then
  956.                 iNum = iNum - iInternal
  957.                 turtle.dig()
  958.                 turtle.attack()
  959.             end
  960.         until bValid
  961.     end
  962.     turnRight()
  963. end
  964.  
  965. tTurtleData.tInventory = fGetInventory()
  966.  
  967. function undo(iNum)
  968.     local tEnv = getfenv()
  969.     for i=1,iNum or 1 do
  970.         if #tLog.handle>0 then
  971.             tEnv[table.remove(tLog.handle,#tLog.handle)]()
  972.             table.remove(tLog.handle,#tLog.handle)
  973.             tTurtleData.tLog = tLog.handle
  974.         end
  975.     end
  976. end
  977.  
  978. function undoAll(iNum)
  979.     undo(#tLog.handle)
  980. end
  981.  
  982. function undoForce(iNum)
  983.     local tEnv = getfenv()
  984.     for i=1,iNum or 1 do
  985.         if #tLog.handle>0 then
  986.             local func = table.remove(tLog.handle,#tLog.handle)
  987.             if tEnv[func.."Force"] then
  988.                 tEnv[func.."Force"]()
  989.             else
  990.                 tEnv[func]()
  991.             end
  992.             table.remove(tLog.handle,#tLog.handle)
  993.             tTurtleData.tLog = tLog.handle
  994.         end
  995.     end
  996. end
  997.  
  998. function undoAllForce(iNum)
  999.     undo(#tLog.handle)
  1000. end
  1001.  
  1002. function clearLog()
  1003.     tLog.handle = {}
  1004.     tTurtleData.tLog = tLog
  1005. end
  1006.  
  1007. function goto(iX,iY,iZ)
  1008.     updatePosition()
  1009.     while (iX-tTurtleData.tPosition.x)/tFacing[tTurtleData.sFacing].iMulti<0 or tFacing[tTurtleData.sFacing].sForward~="x" do
  1010.         turnLeft()
  1011.     end
  1012.     forwardForce(math.abs(iX-tTurtleData.tPosition.x))
  1013.     while (iZ-tTurtleData.tPosition.z)/tFacing[tTurtleData.sFacing].iMulti<0 or tFacing[tTurtleData.sFacing].sForward~="z" do
  1014.         turnLeft()
  1015.     end
  1016.     forwardForce(math.abs(iZ-tTurtleData.tPosition.z))
  1017.     if (iY-tTurtleData.tPosition.y) < 0 then
  1018.         downForce(math.abs(iY-tTurtleData.tPosition.y))
  1019.     else
  1020.         upForce(math.abs(iY-tTurtleData.tPosition.y))
  1021.     end
  1022. end
  1023.  
  1024. local tDigAllPos = {}
  1025. local function fClearPos()
  1026.     tDigAllPos = {}
  1027. end
  1028. local function fAddPos(x,y,z)
  1029.     if not y then
  1030.         x,y,z = x.x,x.y,x.z
  1031.     end
  1032.     if not tDigAllPos[x] then
  1033.         tDigAllPos[x] = {}
  1034.     end
  1035.     if not tDigAllPos[x][y] then
  1036.         tDigAllPos[x][y] = {}
  1037.     end
  1038.     tDigAllPos[x][y][z] = true
  1039. end
  1040. local function fGetPos(tPos)
  1041.     return tDigAllPos[tPos.x] and tDigAllPos[tPos.x][tPos.y] and tDigAllPos[tPos.x][tPos.y][tPos.z]
  1042. end
  1043. local function fFixPos(tPos)
  1044.     return {x=tPos.x,y=tPos.y,z=tPos.z}
  1045. end
  1046.  
  1047. local function internalDigAll(fInspect,fStartMove)
  1048.     local bOk, sName,success = fInspect()
  1049.     local iStart = #tLog.handle
  1050.     if not bOk then
  1051.         return false
  1052.     else
  1053.         sName = sName.name
  1054.     end
  1055.     fClearPos()
  1056.     fStartMove()
  1057.     fAddPos(pos())
  1058.     local tPos
  1059.     local iInternalTurns = 0
  1060.     repeat
  1061.         tPos = fFixPos(pos())
  1062.         tPos[tFacing[tTurtleData.sFacing].sForward] = tPos[tFacing[tTurtleData.sFacing].sForward] + tFacing[tTurtleData.sFacing].iMulti
  1063.         if not fGetPos(tPos) then
  1064.             bOk, sInternalName = turtle.inspect()
  1065.             fAddPos(tPos)
  1066.         else
  1067.             bOk = false
  1068.         end
  1069.         success = bOk and sInternalName.name == sName
  1070.             if not success then
  1071.             tPos = fFixPos(pos())
  1072.             tPos[tFacing.up.sForward] = tPos[tFacing.up.sForward] + tFacing.up.iMulti
  1073.             if not fGetPos(tPos) then
  1074.                 bOk, sInternalName = turtle.inspectUp()
  1075.                 fAddPos(tPos)
  1076.             else
  1077.                 bOk = false
  1078.             end
  1079.             success = bOk and sInternalName.name == sName
  1080.             if not success then
  1081.                 tPos = fFixPos(pos())
  1082.                 tPos[tFacing.down.sForward] = tPos[tFacing.down.sForward] + tFacing.down.iMulti
  1083.                 if not fGetPos(tPos) then
  1084.                     bOk, sInternalName = turtle.inspectDown()
  1085.                     fAddPos(tPos)
  1086.                 else
  1087.                     bOk = false
  1088.                 end
  1089.                 success = bOk and sInternalName.name == sName
  1090.                 if success then
  1091.                     downForce()
  1092.                     iInternalTurns = -1
  1093.                 end
  1094.             else
  1095.                 upForce()
  1096.                 iInternalTurns = -1
  1097.             end
  1098.         else
  1099.             forwardForce()
  1100.             iInternalTurns = -1
  1101.         end
  1102.         if iInternalTurns == -1 then
  1103.             iInternalTurns = 0
  1104.         elseif iInternalTurns == 4 then
  1105.             for i=1,4 do
  1106.                 table.remove(tLog.handle,#tLog.handle)
  1107.             end
  1108.             undoForce()
  1109.             iInternalTurns = 0
  1110.             while tLog.handle[#tLog.handle]=="turnRight" and #tLog.handle > iStart do
  1111.                 undoForce()
  1112.             end
  1113.         else
  1114.             turnLeft()
  1115.             iInternalTurns = iInternalTurns + 1
  1116.         end
  1117.         updatePosition()
  1118.     until #tLog.handle == iStart
  1119. end
  1120.  
  1121. function digAll()
  1122.     internalDigAll(turtle.inspect,forwardForce)
  1123. end
  1124. function digAllUp()
  1125.     internalDigAll(turtle.inspectUp,upForce)
  1126. end
  1127. function digAllDown()
  1128.     internalDigAll(turtle.inspectDown,backForce)
  1129. end
Advertisement
Add Comment
Please, Sign In to add comment