NanoBob

Computercraft storage turtle

Jun 21st, 2016
498
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.48 KB | None | 0 0
  1. local sendChannel=666
  2. local pingLimit=5
  3.  
  4. if fs.exists("event")==false then shell.run("pastebin get UKPy4iiE event") end
  5. if os.loadAPI("event")==false then error("Failed to load event API") end
  6.  
  7. if fs.exists("data")==false then shell.run("pastebin get LnvzL7ur data") end
  8. if os.loadAPI("data")==false then error("Failed to load data API") end
  9.  
  10. if fs.exists("utils")==false then shell.run("pastebin get dyvydHtK utils") end
  11. if os.loadAPI("utils")==false then error("Failed to load utils API") end
  12.  
  13. local self={
  14.     facing="north",
  15.     pos={x=0,y=0,z=0},
  16. }
  17.  
  18.  
  19. local pingtimer
  20. local pongtimer
  21. local failedPings=0
  22. local dropoffTimer
  23. local failedDrops=0
  24. local localChannel
  25. local task={}
  26.  
  27. function self.updatePos()
  28.     print(textutils.serialise(self.pos))
  29.     data.set("position",self.pos.x..","..self.pos.y..","..self.pos.z,"db/position")
  30. end
  31.  
  32. function self.getFilePos()
  33.     local pos=data.get("position","db/position")
  34.     if pos==nil then return end
  35.     local x=utils.split(pos,",",1)
  36.     local y=utils.split(pos,",",2)
  37.     local z=utils.split(pos,",",3)
  38.     return x,y,z
  39. end
  40.  
  41. function self.move(direction,ammount,digging)
  42.     if ammount==nil then ammount=1 end
  43.     local moveFunction=nil
  44.     local digFunction=nil
  45.     local directionalAxis=""
  46.     if direction=="up" then
  47.         moveFunction=turtle.up
  48.         digFunction=turtle.digUp
  49.         directionalAxis="y|+1"
  50.     elseif direction=="down" then
  51.         moveFunction=turtle.down
  52.         digFunction=turtle.digDown
  53.         directionalAxis="y|-1"
  54.     else
  55.         if direction=="back" then
  56.             self.turn("right",2)
  57.         elseif direction=="right" then
  58.             self.turn("right")
  59.         elseif direction=="left" then
  60.             self.turn("left")
  61.         end
  62.         moveFunction=turtle.forward
  63.         digFunction=turtle.dig
  64.         if self.facing=="north" then
  65.             directionalAxis="z|-1"
  66.         elseif self.facing=="east" then
  67.             directionalAxis="x|1"
  68.         elseif self.facing=="south" then
  69.             directionalAxis="z|1"
  70.         elseif self.facing=="west" then
  71.             directionalAxis="x|-1"
  72.         end
  73.     end
  74.     for i=1,ammount do
  75.         if digging==true then
  76.             digFunction()
  77.         end
  78.         local axis=utils.split(directionalAxis,"|",1)
  79.         local delta=tonumber(utils.split(directionalAxis,"|",2))
  80.         local returned=moveFunction()
  81.         if returned==true then
  82.             self.pos[axis]=self.pos[axis]+delta
  83.             self.updatePos()
  84.         end
  85.         if returned==false then return returned end
  86.     end
  87. end
  88.  
  89. local facing={
  90.     [0]="west","north","east","south","west","north",
  91.     north=1,east=2,south=3,west=4,
  92. }
  93.  
  94. function self.turn(direction,ammount)
  95.     for i=1,ammount do
  96.         if direction=="right" then
  97.             turtle.turnRight()
  98.             self.facing=facing[ facing[self.facing]+1 ]
  99.         else
  100.             turtle.turnLeft()
  101.             self.facing=facing[ facing[self.facing]-1 ]
  102.         end
  103.     end
  104.     data.set("facing",self.facing,"db/position")
  105. end
  106.  
  107. function self.setFacing(targetFacing)
  108.     local targetFacing=string.lower(targetFacing)
  109.     local currentFacing=string.lower(self.facing)
  110.     if targetFacing==currentFacing then
  111.         return
  112.     else
  113.         local currentFacingIndex=facing[currentFacing]
  114.         local facingIndex=facing[targetFacing]
  115.         local turns=facingIndex-currentFacingIndex
  116.         if turns<0 then
  117.             turns=turns+4
  118.         end
  119.         if turns==3 then
  120.             self.turn("left",1)
  121.         else
  122.             for i=1,turns do
  123.                 self.turn("right",1)
  124.             end
  125.         end
  126.     end
  127. end
  128.  
  129. function self.goto(x,y,z,fails)
  130.     if turtle.getFuelLevel() == 0 then
  131.         wireless.transmit(replyChannel,localChannel,"status|Out of fuel")
  132.         print("Awaiting fuel in slot 16")
  133.         turtle.select(16)
  134.         while turtle.getFuelLevel() == 0 do
  135.             turtle.refuel()
  136.         end
  137.     end
  138.     local fails=fails
  139.     if fails==nil then
  140.         fails=0
  141.     end
  142.     --print("going from "..tostring(self.pos.x)..","..tostring(self.pos.y)..","..tostring(self.pos.z).."\n to "..tostring(x)..","..tostring(y)..","..tostring(z))
  143.     local yDistance=(self.pos.y-y)*-1
  144.     --print("Y axis travel distance : "..yDistance)
  145.     local yTravel=true
  146.     if yDistance>0 then
  147.         yTravel=self.move("up",yDistance)
  148.     elseif yDistance<0 then
  149.         yTravel=self.move("down",yDistance*-1)
  150.     end
  151.     local xDistance=(self.pos.x-x)*-1
  152.     --print("X axis travel distance : "..xDistance)
  153.     local xTravel=true
  154.     if xDistance>0 then
  155.         self.setFacing("east")
  156.     elseif xDistance<0 then
  157.         self.setFacing("west")
  158.         xDistance=xDistance*-1
  159.     end
  160.     xTravel=self.move("forward",xDistance)
  161.     local zDistance=(self.pos.z-z)*-1
  162.     --print("Z axis travel distance : "..zDistance)
  163.     local zTravel=true
  164.     if zDistance>0 then
  165.         self.setFacing("south")
  166.     elseif zDistance<0 then
  167.         self.setFacing("north")
  168.         zDistance=zDistance*-1
  169.     end
  170.     zTravel=self.move("forward",zDistance)
  171.     if xTravel==false or zTravel==false or yTravel==false then
  172.         if fails==6 or fails == 8 or fails == 10 then
  173.             self.move("up",1)
  174.             self.move("forward",2)
  175.             self.move("down",1)
  176.         elseif fails == 5 or fails == 7 or fails == 9 then
  177.             local originalFacing = self.facing
  178.             if originalFacing == "north" then
  179.                 self.setFacing("west")
  180.                 self.move("forward",1)
  181.                 self.setFacing(originalFacing)
  182.                 self.move("forward",2)
  183.                 self.setFacing("east")
  184.                 self.move("forward",1)
  185.                 self.setFacing(originalFacing)
  186.             elseif originalFacing == "south" then
  187.                 self.setFacing("east")
  188.                 self.move("forward",1)
  189.                 self.setFacing(originalFacing)
  190.                 self.move("forward",2)
  191.                 self.setFacing("west")
  192.                 self.move("forward",1)
  193.                 self.setFacing(originalFacing)
  194.             elseif originalFacing == "west" then
  195.                 self.setFacing("north")
  196.                 self.move("forward",1)
  197.                 self.setFacing(originalFacing)
  198.                 self.move("forward",2)
  199.                 self.setFacing("south")
  200.                 self.move("forward",1)
  201.                 self.setFacing(originalFacing)
  202.             else
  203.                 self.setFacing("south")
  204.                 self.move("forward",1)
  205.                 self.setFacing(originalFacing)
  206.                 self.move("forward",2)
  207.                 self.setFacing("north")
  208.                 self.move("forward",1)
  209.                 self.setFacing(originalFacing)
  210.             end
  211.         end
  212.         fails=fails+1
  213.         if fails>=11 then
  214.             return false
  215.         end
  216.         sleep(1)
  217.         return self.goto(x,y,z,fails)
  218.     end
  219.     return true
  220. end
  221.  
  222. local slotTable = {
  223.     1,2,3,5,6,7,9,10,11
  224. }
  225.  
  226. function self.pickup(itemname,count,targetSlot)
  227.     local chest=peripheral.wrap("bottom")
  228.     local items=chest.getAllStacks()
  229.     local count=tonumber(count)
  230.     local remainder=count
  231.     local targetSlot = slotTable[tonumber(targetSlot)]
  232.     print(itemname .. " : " .. count .. " : " .. tostring(targetSlot) )
  233.     for slot,item in pairs(items) do
  234.         --print(item.all().display_name)
  235.         if string.lower(item.all().display_name)==itemname then
  236.             local count=item.all().qty
  237.             if count>remainder then
  238.                 chest.pushItem("up",slot,remainder,targetSlot)
  239.                 remainder=0
  240.             else
  241.                 chest.pushItem("up",slot,count,targetSlot)
  242.                 remainder=remainder-count
  243.             end
  244.         end
  245.         if remainder<=0 then
  246.             break
  247.         end
  248.     end
  249. end
  250.  
  251. function self.dropoff(x,y,z)
  252.     if self.goto(x,y,z) then
  253.         for i=1,16 do
  254.             if turtle.getItemCount(i)>0 then
  255.                 turtle.select(i)
  256.                 turtle.dropDown()
  257.             end
  258.         end
  259.     end
  260. end
  261.  
  262. function initPos()
  263.     local x,y,z=self.getFilePos()
  264.     if x==nil or y==nil or z==nil then
  265.         print("Please input coordinates:")
  266.         io.write("x: ")
  267.         x=tonumber(read())
  268.         io.write("y: ")
  269.         y=tonumber(read())
  270.         io.write("z: ")
  271.         z=tonumber(read())
  272.     end
  273.     self.pos.x,self.pos.y,self.pos.z=tonumber(x),tonumber(y),tonumber(z)
  274.     self.updatePos()
  275.     local facing=data.get("facing","db/position")
  276.     if facing==nil then
  277.         print("Please input facing:")
  278.         io.write("facing: ")
  279.         facing=read()
  280.         data.set("facing",facing,"db/position")
  281.     end
  282.     self.facing=facing
  283. end
  284.  
  285. function initConnection()
  286.     if localChannel~=nil then
  287.         wireless.close(localChannel)
  288.     end
  289.     wireless=peripheral.wrap("left")
  290.     localChannel=math.random(1000,5000)
  291.     wireless.open(localChannel)
  292.     repeat
  293.         wireless.transmit(sendChannel,localChannel,"assign")
  294.         local timer=os.startTimer(5)
  295.         repeat
  296.             tEvent,var,sender,receiver,message=os.pullEvent()
  297.             --print(localChannel.." | "..event.." : "..tostring(message))
  298.         until tEvent=="modem_message" or tEvent=="timer"
  299.         if message=="denied" then
  300.             wireless.close(localChannel)
  301.             localChannel=math.random(1000,5000)
  302.             wireless.open(localChannel)
  303.         end
  304.     until message=="confirmed"
  305.     failedPings=0
  306. end
  307.  
  308. function init()
  309.     initPos()
  310.     initConnection()
  311. end
  312. init()
  313.  
  314. function craft(replyChannel,message,isFinal)
  315.     local count=tonumber(utils.split(message,"|",2))
  316.     local allSubs=utils.getSplits(message,"|")
  317.     local itemSubs = {}
  318.     for i = 3, #allSubs do
  319.         itemSubs[#itemSubs+1]=allSubs[i]
  320.     end
  321.     for i,itemSub in pairs(itemSubs) do
  322.         local item=utils.split(itemSub,";",1)
  323.         local pos=utils.split(itemSub,";",2)
  324.         local slot = utils.split(itemSub,";",3)
  325.         if pos~=nil then
  326.             local x=utils.split(pos,",",1)
  327.             local y=utils.split(pos,",",2)
  328.             local z=utils.split(pos,",",3)
  329.             self.goto(x,y,z)
  330.             self.pickup(item,count,slot)
  331.         end
  332.     end
  333.    
  334.     turtle.craft(count)
  335.    
  336.     if isFinal == true then
  337.         dropoffTimer=os.startTimer(5)
  338.         wireless.transmit(replyChannel,localChannel,"requestDropoff")
  339.     else
  340.         self.dropoff(self.pos.x,self.pos.y,self.pos.z)
  341.         wireless.transmit(sendChannel,localChannel,"requestRestPos")
  342.     end
  343. end
  344.  
  345. local messageHandles={
  346.     ["ping"]=function(replyChannel,message)
  347.         return "pong"
  348.     end,
  349.    
  350.     ["get"]=function(replyChannel,message)
  351.         wireless.transmit(replyChannel,localChannel,"status|working")
  352.         local item=utils.split(message,"|",2)
  353.         local count=tonumber(utils.split(message,"|",3))
  354.         local pos=utils.split(message,"|",4)
  355.         if pos==nil then return end
  356.         local x=utils.split(pos,",",1)
  357.         local y=utils.split(pos,",",2)
  358.         local z=utils.split(pos,",",3)
  359.         self.goto(x,y,z)
  360.         self.pickup(item,count)
  361.         dropoffTimer=os.startTimer(5)
  362.         wireless.transmit(replyChannel,localChannel,"requestDropoff")
  363.     end,
  364.    
  365.     ["craft"]=function(replyChannel,message)
  366.         wireless.transmit(replyChannel,localChannel,"status|working")
  367.         craft(replyChannel,message,true)
  368.     end,
  369.    
  370.     ["innerCraft"]=function(replyChannel,message)
  371.         craft(replyChannel,message,false)
  372.         wireless.transmit(sendChannel,localChannel,"requestRestPos")
  373.     end,
  374.    
  375.     ["goto"]=function(replyChannel,message)
  376.         wireless.transmit(replyChannel,localChannel,"status|working")
  377.         local pos=utils.split(message,"|",2)
  378.         local x=tonumber(utils.split(pos,",",1))
  379.         local y=tonumber(utils.split(pos,",",2))
  380.         local z=tonumber(utils.split(pos,",",3))
  381.         self.goto(x,y,z)
  382.         pingtimer=os.startTimer(10)
  383.         return("status|idle")
  384.     end,
  385.    
  386.     ["pong"]=function()
  387.         pongtimer=nil
  388.         failedPings=failedPings-1
  389.         if failedPings<0 then failedPings=0 end
  390.     end,
  391.    
  392.     ["loadstring"]=function(_,message)
  393.         local func = loadstring(utils.split(message,"|",2))
  394.         setfenv(func, getfenv())
  395.         func()
  396.     end,
  397.    
  398.     ["run"]=function(_,message)
  399.         wireless.transmit(replyChannel,localChannel,"status|working")
  400.         shell.run(utils.split(message,"|",2))
  401.         pingtimer=os.startTimer(10)
  402.         return("status|idle")
  403.     end,
  404.    
  405.     ["returnDropoff"]=function(_,message)
  406.         failedDrops=0
  407.         local pos=utils.split(message,"|",2)
  408.         local x=tonumber(utils.split(pos,",",1))
  409.         local y=tonumber(utils.split(pos,",",2))
  410.         local z=tonumber(utils.split(pos,",",3))
  411.         self.dropoff(x,y,z)
  412.         wireless.transmit(sendChannel,localChannel,"requestRestPos")
  413.     end,
  414.    
  415.     ["returnHomePos"]=function(_,message)
  416.         local pos=utils.split(message,"|",2)
  417.         local x=tonumber(utils.split(pos,",",1))
  418.         local y=tonumber(utils.split(pos,",",2))
  419.         local z=tonumber(utils.split(pos,",",3))
  420.         self.goto(x,y,z)
  421.         pingtimer=os.startTimer(10)
  422.         wireless.transmit(sendChannel,localChannel,"status|idle")  
  423.     end,
  424. }
  425.  
  426. function handleMessages(side,channel,replyChannel,message)
  427.     --print(tostring(replyChannel).." : "..tostring(message))
  428.     if replyChannel==nil then return end
  429.     local messageType=utils.split(message,"|",1)
  430.     if messageHandles[messageType]==nil then return end
  431.     local returnMessage=messageHandles[messageType](replyChannel,message)
  432.     if returnMessage==nil then return end
  433.     wireless.transmit(replyChannel,localChannel,returnMessage)
  434. end
  435. event.addHandler("modem_message",handleMessages)
  436.  
  437. function timerExpired(id)
  438.     --print("Timer: "..tostring(id).." | Pingtimer:"..tostring(pingtimer))
  439.     if id==pingtimer then
  440.         wireless.transmit(sendChannel,localChannel,"ping")
  441.         pongtimer=os.startTimer(1)
  442.         pingtimer=nil
  443.     elseif id==pongtimer then
  444.         failedPings=failedPings+1
  445.         print("Ping was not answered. Rep: "..failedPings)
  446.         if failedPings>pingLimit then
  447.             initConnection()
  448.         end
  449.     elseif id==dropoffTimer then
  450.         failedDrops=failedDrops+1
  451.         if failedDrops>5 then
  452.             wireless.transmit(sendChannel,localChannel,"status|idle")
  453.             return
  454.         end
  455.         wireless.transmit(sendChannel,localChannel,"requestDropoff")
  456.         dropoffTimer=os.startTimer(5)
  457.     end
  458. end
  459. event.addHandler("timer",timerExpired)
  460.  
  461. while true do
  462.     pingtimer=os.startTimer(10)
  463.     repeat
  464.         event.handleCCEvents()
  465.     until pingtimer==nil
  466. end
Add Comment
Please, Sign In to add comment