Advertisement
Sxw1212

Flow

Jul 29th, 2013
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.45 KB | None | 0 0
  1. -- Flow turtle library
  2. -- By Sxw1212
  3.  
  4. local data = { pos = {}, map = {}, waypoints = {}, mapping = true, advmapping = false }
  5.  
  6. function load()
  7.     if fs.exists("/.flow.dat") then
  8.         local fh = fs.open("/.flow.dat", "r")
  9.         if fh then
  10.             data = textutils.unserialize(fh.readAll())
  11.             fh.close()
  12.         else
  13.             print("Error loading data file")
  14.         end
  15.     end
  16.     if data.pos == {} then
  17.         print("Set position with setPos(x, y, z, f)")
  18.     end
  19. end
  20.  
  21. function save()
  22.     fs.delete("/.flow.dat")
  23.     local fh = fs.open("/.flow.dat", "w")
  24.     if fh then
  25.         fh.write(textutils.serialize(data))
  26.         fh.close()
  27.     else
  28.         print("Error saving")
  29.     end
  30. end
  31.  
  32. function setMapping(mapping)
  33.     data.mapping = mapping
  34.     save()
  35. end
  36.  
  37. function setAdvMapping(advmapping)
  38.     data.advmapping = advmapping
  39.     save()
  40. end
  41.  
  42. function setPos(x, y, z, f)
  43.     data.pos = {x, y, z, f}
  44.     save()
  45. end
  46.  
  47. function finc()
  48.     if data.pos[4] == 0 then
  49.         data.pos[3] = data.pos[3] + 1
  50.     elseif data.pos[4] == 1 then
  51.         data.pos[1] = data.pos[1] - 1
  52.     elseif data.pos[4] == 2 then
  53.         data.pos[3] = data.pos[3] - 1
  54.     elseif data.pos[4] == 3 then
  55.         data.pos[1] = data.pos[1] + 1
  56.     end
  57.     save()
  58. end
  59.  
  60. function binc()
  61.     if data.pos[4] == 0 then
  62.         data.pos[3] = data.pos[3] - 1
  63.     elseif data.pos[4] == 1 then
  64.         data.pos[1] = data.pos[1] + 1
  65.     elseif data.pos[4] == 2 then
  66.         data.pos[3] = data.pos[3] + 1
  67.     elseif data.pos[4] == 3 then
  68.         data.pos[1] = data.pos[1] - 1
  69.     end
  70.     save()
  71. end
  72.  
  73. function linc()
  74.     if data.pos[4] == 0 then
  75.         data.pos[4] = 3
  76.     else
  77.         data.pos[4] = data.pos[4] - 1
  78.     end
  79.     save()
  80. end
  81.  
  82. function rinc()
  83.     if data.pos[4] == 3 then
  84.         data.pos[4] = 0
  85.     else
  86.         data.pos[4] = data.pos[4] + 1
  87.     end
  88.     save()
  89. end
  90.  
  91. function initpos(x, y, z)
  92.     if not data.map[x] then
  93.         data.map[x] = {}
  94.     end
  95.     if not data.map[x][y] then
  96.         data.map[x][y] = {}
  97.     end
  98.     if not data.map[x][y][z] then
  99.         data.map[x][y][z] = false
  100.     end
  101. end
  102.  
  103. function incf()
  104.     local f = data.pos[4]
  105.     if f == 0 then
  106.         return data.pos[1], data.pos[3] + 1
  107.     elseif f == 1 then
  108.         return data.pos[1] - 1, data.pos[3]
  109.     elseif f == 2 then
  110.         return data.pos[1], data.pos[3] - 1
  111.     elseif f == 3 then
  112.         return data.pos[1] + 1, data.pos[3]
  113.     end
  114. end
  115.  
  116. function advmap()
  117.     if data.advmapping then
  118.         local x = data.pos[1]
  119.         local y = data.pos[2]
  120.         local z = data.pos[3]
  121.         local f = data.pos[4]
  122.         turnLeft()
  123.         map(true)
  124.         turnRight()
  125.         turnRight()
  126.         map(true)
  127.         turnLeft()
  128.     end
  129. end
  130.  
  131. function map(recurse)
  132.     if data.mapping then
  133.         local x = data.pos[1]
  134.         local y = data.pos[2]
  135.         local z = data.pos[3]
  136.         local f = data.pos[4]
  137.         initpos(x, y, z)
  138.         data.map[x][y][z] = false
  139.         initpos(x, y + 1, z)
  140.         if turtle.detectUp() then
  141.             data.map[x][y+1][z] = true
  142.         end
  143.         initpos(x, y - 1, z)
  144.         if turtle.detectDown() then
  145.             data.map[x][y-1][z] = true
  146.         end
  147.         x, z = incf()
  148.         initpos(x, y, z)
  149.         if turtle.detect() then
  150.             data.map[x][y][z] = true
  151.         end
  152.         if not recurse then
  153.             advmap()
  154.         end
  155.         save()
  156.     end
  157. end
  158.  
  159. function getPos()
  160.     return data.pos
  161. end
  162.  
  163. -- Basic turtle movement
  164.  
  165. local oldturtle = {}
  166. for k, v in pairs(turtle) do
  167.     oldturtle[k] = v
  168. end
  169.  
  170. function forward()
  171.     if oldturtle.forward() then
  172.         finc()
  173.         map()
  174.         return true
  175.     else
  176.         return false
  177.     end
  178. end
  179.  
  180. function back()
  181.     if oldturtle.back() then
  182.         binc()
  183.         map()
  184.         return true
  185.     else
  186.         return false
  187.     end
  188. end
  189.  
  190. function up()
  191.     if oldturtle.up() then
  192.         data.pos[2] = data.pos[2] + 1
  193.         map()
  194.         return true
  195.     else
  196.         return false
  197.     end
  198. end
  199.  
  200. function down()
  201.     if oldturtle.down() then
  202.         data.pos[2] = data.pos[2] - 1
  203.         map()
  204.         return true
  205.     else
  206.         return false
  207.     end
  208. end
  209.  
  210. function turnLeft()
  211.     oldturtle.turnLeft()
  212.     linc()
  213.     return true
  214. end
  215.  
  216. function turnRight()
  217.     oldturtle.turnRight()
  218.     rinc()
  219.     return true
  220. end
  221.  
  222. turtle.up = up
  223. turtle.down = down
  224. turtle.turnLeft = turnLeft
  225. turtle.turnRight = turnRight
  226. turtle.forward = forward
  227. turtle.back = back
  228.  
  229. -- More advanced movement
  230.  
  231. function face(f, recurse)
  232.     if data.pos[4] == f then
  233.         return true
  234.     end
  235.     local turn = data.pos[4] - f
  236.     if turn == -1 or turn == 3 then
  237.         turnRight()
  238.     elseif turn == 1 or 3 then
  239.         turnLeft()
  240.     elseif math.abs(turn) == 2 then
  241.         turnLeft()
  242.         turnLeft()
  243.     end
  244.     if not recurse then
  245.         face(f, true)
  246.     end
  247.     return true
  248. end
  249.  
  250. turtle.face = face
  251.  
  252. -- Oh my god I hate pathfinding, but I need it xD
  253. -- Nomap is optional, don't use it unless you KNOW there is a path, and even then... :P
  254. -- TL;DR: Dont use it.
  255. function pathfind(x, y, z, nomap, recurse)
  256.     local function cost(x, y, z)
  257.         if data.map[x] then
  258.             if data.map[x][y] then
  259.                 -- I use == false because it's unknown
  260.                 if data.map[x][y][z] then
  261.                     return nil
  262.                 elseif data.map[x][y][z] == false then
  263.                     return 1
  264.                 end
  265.             end
  266.         end
  267.         return nomap
  268.     end
  269.     local path = Pathfinder.findPath3D(cost, data.pos[1], data.pos[2], data.pos[3], x, y, z)
  270.     if path then
  271.         while path do
  272.             local curDir = data.pos[4]
  273.             if path.position.x > data.pos[1] then
  274.                 curDir = 3
  275.             elseif path.position.x < data.pos[1] then
  276.                 curDir = 1
  277.             elseif path.position.z > data.pos[3] then
  278.                 curDir = 0
  279.             elseif path.position.z < data.pos[3] then
  280.                 curDir = 2
  281.             end
  282.             face(curDir)
  283.            
  284.             if data.pos[2] < path.position.y then
  285.                 up()
  286.             elseif data.pos[2] > path.position.y then
  287.                 down()
  288.             elseif data.pos[1] ~= path.position.x or data.pos[3] ~= path.position.z then
  289.                 forward()
  290.             end
  291.            
  292.             path = path.next
  293.         end
  294.         if not recurse then
  295.             local done = true
  296.             if x ~= data.pos[1] then
  297.                 done = false
  298.             elseif y ~= data.pos[2] then
  299.                 done = false
  300.             elseif z ~= data.pos[3] then
  301.                 done = false
  302.             end
  303.             if not done then
  304.                 -- In case of minor changes
  305.                 pathfind(x, y, z, nomap, true)
  306.             end
  307.         end
  308.         return true
  309.     else
  310.         return false
  311.     end
  312. end
  313.  
  314. function setWaypoint(name, x, y, z)
  315.     x = x or data.pos[1]
  316.     y = y or data.pos[2]
  317.     z = z or data.pos[3]
  318.     data.waypoints[name] = {x, y, z}
  319.     save()
  320. end
  321.  
  322. function gotoWaypoint(name)
  323.     if data.waypoints[name] then
  324.         return pathfind(data.waypoints[name][1], data.waypoints[name][2], data.waypoints[name][3])
  325.     end
  326.     return false
  327. end
  328.  
  329. function delWaypoint(name)
  330.     data.waypoints[name] = nil
  331.     save()
  332. end
  333.  
  334. function getWaypoints(name)
  335.     return data.waypoints
  336. end
  337.  
  338. function reset(sure)
  339.     if sure then
  340.         data.waypoints = {}
  341.         data.map = {}
  342.         save()
  343.         return true
  344.     else
  345.         return false
  346.     end
  347. end
  348.  
  349. -- Misc
  350.  
  351. function wander(moves)
  352.     for i = 1, moves do
  353.         local move = math.floor(math.random()*5)
  354.         if move == 0 then
  355.             forward()
  356.         elseif move == 1 then
  357.             back()
  358.         elseif move == 2 then
  359.             turnLeft()
  360.         elseif move == 3 then
  361.             up()
  362.         elseif move == 4 then
  363.             down()
  364.         end
  365.     end
  366. end
  367.  
  368. load()
  369.  
  370. function update(file)
  371.     file = file or "/flow"
  372.     local url = "https://raw.github.com/Sxw1212/ccprograms/master/flow"
  373.     local req = http.get(url)
  374.     if req then
  375.         local fh = fs.open(file, "w")
  376.         fh.write(req.readAll())
  377.         fh.close()
  378.         return true
  379.     else
  380.         return false
  381.     end
  382. end
  383.  
  384. -- All credit goes to TehPers on the pathfinder API
  385. if not fs.exists("/.pf/flow") then
  386.     fs.makeDir("/.pf")
  387.     local burl = "https://raw.github.com/Sxw1212/ccprograms/master/TehPers/Pathfinder/"
  388.     local files = { "MinHeap", "Pathfinder", "deepcopy", "Point", "SearchNode", "Surr" }
  389.     for k, v in pairs(files) do
  390.         local req = http.get(burl .. v)
  391.         if req then
  392.             local fh = fs.open("/.pf/" ..v, "w")
  393.             fh.write(req.readAll())
  394.             fh.close()
  395.         else
  396.             error("Error loading Pathfinder")
  397.         end
  398.     end
  399.     fs.makeDir("/.pf/flow")
  400. end
  401.  
  402. os.loadAPI("/.pf/Pathfinder")
  403. os.loadAPI("/.pf/Point")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement