Advertisement
NanoBob

Storage Turtle

Feb 29th, 2016
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.63 KB | None | 0 0
  1. local sendChannel=666
  2. local pingLimit=5
  3.  
  4. if fs.exists("events")==false then shell.run("pastebin get L7KYC10V events") end
  5. if os.loadAPI("events")==false then error("Failed to load events API") end
  6.  
  7. if fs.exists("data")==false then shell.run("pastebin get 5FpayqrQ 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 c4CBkgKV 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.     local fails=fails
  131.     if fails==nil then
  132.         fails=0
  133.     end
  134.     --print("going from "..tostring(self.pos.x)..","..tostring(self.pos.y)..","..tostring(self.pos.z).."\n to "..tostring(x)..","..tostring(y)..","..tostring(z))
  135.     local yDistance=(self.pos.y-y)*-1
  136.     --print("Y axis travel distance : "..yDistance)
  137.     local yTravel=true
  138.     if yDistance>0 then
  139.         local yTravel=self.move("up",yDistance)
  140.     elseif yDistance<0 then
  141.         local yTravel=self.move("down",yDistance*-1)
  142.     end
  143.     local xDistance=(self.pos.x-x)*-1
  144.     --print("X axis travel distance : "..xDistance)
  145.     local xTravel=true
  146.     if xDistance>0 then
  147.         self.setFacing("east")
  148.     elseif xDistance<0 then
  149.         self.setFacing("west")
  150.         xDistance=xDistance*-1
  151.     end
  152.     xTravel=self.move("forward",xDistance)
  153.     local zDistance=(self.pos.z-z)*-1
  154.     --print("Z axis travel distance : "..zDistance)
  155.     local zTravel=true
  156.     if zDistance>0 then
  157.         self.setFacing("south")
  158.     elseif zDistance<0 then
  159.         self.setFacing("north")
  160.         zDistance=zDistance*-1
  161.     end
  162.     zTravel=self.move("forward",zDistance)
  163.     if xTravel==false or zTravel==false or yTravel==false then
  164.         fails=fails+1
  165.         if fails>=11 then
  166.             return false
  167.         end
  168.         sleep(1)
  169.         self.goto(x,y,z,fails)
  170.     end
  171. end
  172.  
  173. function self.pickup(itemname,count)
  174.     local chest=peripheral.wrap("bottom")
  175.     local items=chest.getAllStacks()
  176.     local count=tonumber(count)
  177.     local remainder=count
  178.     for slot,item in pairs(items) do
  179.         --print(item.all().display_name)
  180.         if string.lower(item.all().display_name)==itemname then
  181.             local count=item.all().qty
  182.             print(count..":"..remainder)
  183.             if count>remainder then
  184.                 chest.pushItem("up",slot,remainder)
  185.                 remainder=0
  186.             else
  187.                 chest.pushItem("up",slot,count)
  188.                 remainder=remainder-count
  189.             end
  190.         end
  191.         if remainder<=0 then
  192.             break
  193.         end
  194.     end
  195. end
  196.  
  197. function self.dropoff(x,y,z)
  198.     self.goto(x,y,z)
  199.     for i=1,16 do
  200.         turtle.select(i)
  201.         turtle.dropDown()
  202.     end
  203. end
  204.  
  205. function initPos()
  206.     local x,y,z=self.getFilePos()
  207.     if x==nil or y==nil or z==nil then
  208.         print("Please input coordinates:")
  209.         io.write("x: ")
  210.         x=tonumber(read())
  211.         io.write("y: ")
  212.         y=tonumber(read())
  213.         io.write("z: ")
  214.         z=tonumber(read())
  215.     end
  216.     self.pos.x,self.pos.y,self.pos.z=x,y,z
  217.     self.updatePos()
  218.     local facing=data.get("facing","db/position")
  219.     if facing==nil then
  220.         print("Please input facing:")
  221.         io.write("facing: ")
  222.         facing=read()
  223.         data.set("facing",facing,"db/position")
  224.     end
  225.     self.facing=facing
  226. end
  227.  
  228. function initConnection()
  229.     if localChannel~=nil then
  230.         wireless.close(localChannel)
  231.     end
  232.     wireless=peripheral.wrap("left")
  233.     localChannel=math.random(5000)
  234.     wireless.open(localChannel)
  235.     repeat
  236.         wireless.transmit(sendChannel,localChannel,"assign")
  237.         local timer=os.startTimer(5)
  238.         repeat
  239.             event,var,sender,receiver,message=os.pullEvent()
  240.             --print(localChannel.." | "..event.." : "..tostring(message))
  241.         until event=="modem_message" or event=="timer"
  242.         if message=="denied" then
  243.             wireless.close(localChannel)
  244.             localChannel=math.random(5000)
  245.             wireless.open(localChannel)
  246.         end
  247.     until message=="confirmed"
  248.     failedPings=0
  249. end
  250.  
  251. function init()
  252.     initPos()
  253.     initConnection()
  254. end
  255. init()
  256.  
  257.  
  258. local messageHandles={
  259.     ["ping"]=function(replyChannel,message)
  260.         return "pong"
  261.     end,
  262.     ["get"]=function(replyChannel,message)
  263.         wireless.transmit(replyChannel,localChannel,"status|working")
  264.         local item=utils.split(message,"|",2)
  265.         local count=tonumber(utils.split(message,"|",3))
  266.         local pos=utils.split(message,"|",4)
  267.         if pos==nil then return end
  268.         local x=utils.split(pos,",",1)
  269.         local y=utils.split(pos,",",2)
  270.         local z=utils.split(pos,",",3)
  271.         self.goto(x,y,z)
  272.         self.pickup(item,count)
  273.         dropoffTimer=os.startTimer(5)
  274.         wireless.transmit(replyChannel,localChannel,"requestDropoff")
  275.     end,
  276.     ["goto"]=function(replyChannel,message)
  277.         wireless.transmit(replyChannel,localChannel,"status|working")
  278.         local pos=utils.split(message,"|",2)
  279.         local x=tonumber(utils.split(pos,",",1))
  280.         local y=tonumber(utils.split(pos,",",2))
  281.         local z=tonumber(utils.split(pos,",",3))
  282.         self.goto(x,y,z)
  283.         pingtimer=os.startTimer(10)
  284.         return("status|idle")
  285.     end,
  286.     ["pong"]=function()
  287.         pongtimer=nil
  288.         failedPings=failedPings-1
  289.         if failedPings<0 then failedPings=0 end
  290.     end,
  291.     ["loadstring"]=function(_,message)
  292.         local func = loadstring(utils.split(message,"|",2))
  293.         setfenv(func, getfenv())
  294.         func()
  295.     end,
  296.     ["run"]=function(_,message)
  297.         wireless.transmit(replyChannel,localChannel,"status|working")
  298.         shell.run(utils.split(message,"|",2))
  299.         pingtimer=os.startTimer(10)
  300.         return("status|idle")
  301.     end,
  302.    
  303.     ["returnDropoff"]=function(_,message)
  304.         failedDrops=0
  305.         local pos=utils.split(message,"|",2)
  306.         local x=tonumber(utils.split(pos,",",1))
  307.         local y=tonumber(utils.split(pos,",",2))
  308.         local z=tonumber(utils.split(pos,",",3))
  309.         self.dropoff(x,y,z)
  310.         wireless.transmit(sendChannel,localChannel,"requestRestPos")
  311.     end,
  312.    
  313.     ["returnHomePos"]=function(_,message)
  314.         local pos=utils.split(message,"|",2)
  315.         local x=tonumber(utils.split(pos,",",1))
  316.         local y=tonumber(utils.split(pos,",",2))
  317.         local z=tonumber(utils.split(pos,",",3))
  318.         self.goto(x,y,z)
  319.         wireless.transmit(sendChannel,localChannel,"status|idle")  
  320.         pingtimer=os.startTimer(10)
  321.     end,
  322. }
  323.  
  324. function handleMessages(side,channel,replyChannel,message)
  325.     --print(tostring(replyChannel).." : "..tostring(message))
  326.     if replyChannel==nil then return end
  327.     local messageType=utils.split(message,"|",1)
  328.     if messageHandles[messageType]==nil then return end
  329.     local returnMessage=messageHandles[messageType](replyChannel,message)
  330.     if returnMessage==nil then return end
  331.     wireless.transmit(replyChannel,localChannel,returnMessage)
  332. end
  333. events.addHandler("modem_message",handleMessages)
  334.  
  335. function timerExpired(id)
  336.     --print("Timer: "..tostring(id).." | Pingtimer:"..tostring(pingtimer))
  337.     if id==pingtimer then
  338.         wireless.transmit(sendChannel,localChannel,"ping")
  339.         pongtimer=os.startTimer(1)
  340.         pingtimer=nil
  341.     elseif id==pongtimer then
  342.         failedPings=failedPings+1
  343.         print("Ping was not answered. Rep: "..failedPings)
  344.         if failedPings>pingLimit then
  345.             initConnection()
  346.         end
  347.     elseif id==dropoffTimer then
  348.         failedDrops=failedDrops+1
  349.         if failedDrops>5 then
  350.             wireless.transmit(sendChannel,localChannel,"status|idle")
  351.             return
  352.         end
  353.         wireless.transmit(sendChannel,localChannel,"requestDropoff")
  354.         dropoffTimer=os.startTimer(5)
  355.     end
  356. end
  357. events.addHandler("timer",timerExpired)
  358.  
  359. while true do
  360.     pingtimer=os.startTimer(10)
  361.     repeat
  362.         events.handleCCEvents()
  363.     until pingtimer==nil
  364. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement