Advertisement
Silverlan

Untitled

Mar 12th, 2013
206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.39 KB | None | 0 0
  1. NODE_TYPE_GROUND = 2
  2. NODE_TYPE_AIR = 3
  3. NODE_TYPE_CLIMB = 4
  4. NODE_TYPE_WATER = 5
  5.  
  6. local AINET_VERSION_NUMBER = 37
  7. local NUM_HULLS = 10
  8. local MAX_NODES = 1500
  9.  
  10. local SIZEOF_INT = 4
  11. local SIZEOF_SHORT = 2
  12. local function toUShort(b)
  13.     local i = {string.byte(b,1,SIZEOF_SHORT)}
  14.     return i[1] +i[2] *256
  15. end
  16. local function toInt(b)
  17.     local i = {string.byte(b,1,SIZEOF_INT)}
  18.     i = i[1] +i[2] *256 +i[3] *65536 +i[4] *16777216
  19.     if(i > 2147483647) then return i -4294967296 end
  20.     return i
  21. end
  22. local function ReadInt(f) return toInt(f:Read(SIZEOF_INT)) end
  23. local function ReadUShort(f) return toUShort(f:Read(SIZEOF_SHORT)) end
  24.  
  25.  
  26. local _R = debug.getregistry()
  27. local meta = {}
  28. _R.Nodegraph = meta
  29. local methods = {}
  30. meta.__index = methods
  31. function meta:__tostring()
  32.     local str = "Nodegraph [" .. table.Count(self:GetNodes()) .. " Nodes] [" .. table.Count(self:GetLinks()) .. " Links] [AINET " .. self:GetAINetVersion() .. "] [MAP " .. self:GetMapVersion() .. "]"
  33.     return str
  34. end
  35. methods.MetaName = "Nodegraph"
  36. function _R.Nodegraph.Create(f)
  37.     local t = {}
  38.     setmetatable(t,meta)
  39.     if(f) then if(!t:ParseFile(f)) then t:Clear() end
  40.     else t:Clear() end
  41.     return t
  42. end
  43.  
  44. function _R.Nodegraph.Read(f)
  45.     if(!f) then f = "maps/graphs/" .. game.GetMap() .. ".ain" end
  46.     return _R.Nodegraph.Create(f)
  47. end
  48.  
  49. function methods:Clear()
  50.     self.m_nodegraph = {
  51.         ainet_version = AINET_VERSION_NUMBER,
  52.         map_version = 1196,
  53.         nodes = {},
  54.         links = {},
  55.         lookup = {}
  56.     }
  57. end
  58.  
  59. function methods:GetAINetVersion() return self:GetData().ainet_version end
  60.  
  61. function methods:GetMapVersion() return self:GetData().map_version end
  62.  
  63. function methods:ParseFile(f)
  64.     f = file.Open(f,"rb","GAME")
  65.         if(!f) then return end
  66.         local ainet_ver = ReadInt(f)
  67.         local map_ver = ReadInt(f)
  68.         local nodegraph = {
  69.             ainet_version = ainet_ver,
  70.             map_version = map_ver
  71.         }
  72.         if(ainet_ver != AINET_VERSION_NUMBER) then
  73.             MsgN("Unknown graph file")
  74.             return
  75.         end
  76.         local numNodes = ReadInt(f)
  77.         if(numNodes > MAX_NODES || numNodes < 0) then
  78.             MsgN("Graph file has an unexpected amount of nodes")
  79.             return
  80.         end
  81.         local nodes = {}
  82.         for i = 1,numNodes do
  83.             local v = Vector(f:ReadFloat(),f:ReadFloat(),f:ReadFloat())
  84.             local yaw = f:ReadFloat()
  85.             local flOffsets = {}
  86.             for i = 1,NUM_HULLS do
  87.                 flOffsets[i] = f:ReadFloat()
  88.             end
  89.             local nodetype = f:ReadByte()
  90.             local nodeinfo = ReadUShort(f)
  91.             local zone = f:ReadShort()
  92.            
  93.             local node = {
  94.                 pos = v,
  95.                 yaw = yaw,
  96.                 offset = flOffsets,
  97.                 type = nodetype,
  98.                 info = nodeinfo,
  99.                 zone = zone,
  100.                 neighbor = {},
  101.                 numneighbors = 0,
  102.                 link = {},
  103.                 numlinks = 0
  104.             }
  105.             table.insert(nodes,node)
  106.         end
  107.         local numLinks = ReadInt(f)
  108.         local links = {}
  109.         for i = 1,numLinks do
  110.             local link = {}
  111.             local srcID = f:ReadShort()
  112.             local destID = f:ReadShort()
  113.             local nodesrc = nodes[srcID +1]
  114.             local nodedest = nodes[destID +1]
  115.             if(nodesrc && nodedest) then
  116.                 table.insert(nodesrc.neighbor,nodedest)
  117.                 nodesrc.numneighbors = nodesrc.numneighbors +1
  118.                
  119.                 table.insert(nodesrc.link,link)
  120.                 nodesrc.numlinks = nodesrc.numlinks +1
  121.                 link.src = nodesrc
  122.                 link.srcID = srcID +1
  123.                
  124.                 table.insert(nodedest.neighbor,nodesrc)
  125.                 nodedest.numneighbors = nodedest.numneighbors +1
  126.                
  127.                 table.insert(nodedest.link,link)
  128.                 nodedest.numlinks = nodedest.numlinks +1
  129.                 link.dest = nodedest
  130.                 link.destID = destID +1
  131.             else MsgN("Unknown link source or destination " .. srcID .. " " .. destID) end
  132.             local moves = {}
  133.             for i = 1,NUM_HULLS do
  134.                 moves[i] = f:ReadByte()
  135.             end
  136.             link.move = moves
  137.             table.insert(links,link)
  138.         end
  139.         local lookup = {}
  140.         for i = 1,numNodes do
  141.             table.insert(lookup,ReadInt(f))
  142.         end
  143.     f:Close()
  144.     nodegraph.nodes = nodes
  145.     nodegraph.links = links
  146.     nodegraph.lookup = lookup
  147.     self.m_nodegraph = nodegraph
  148.     return nodegraph
  149. end
  150.  
  151. function methods:GetData() return self.m_nodegraph end
  152.  
  153. function methods:GetNodes() return self:GetData().nodes end
  154. function methods:GetLinks() return self:GetData().links end
  155. function methods:GetLookupTable() return self:GetData().lookup end
  156.  
  157. function methods:GetNode(nodeID) return self:GetNodes()[nodeID] end
  158.  
  159. function methods:AddNode(pos,type,yaw,info)
  160.     type = type || NODE_TYPE_GROUND
  161.     local nodes = self:GetNodes()
  162.     local numNodes = table.Count(nodes)
  163.     if(numNodes == MAX_NODES) then return false end
  164.     local offset = {}
  165.     for i = 1,NUM_HULLS do offset[i] = 0 end
  166.     local node = {
  167.         pos = pos,
  168.         yaw = yaw || 0,
  169.         offset = offset,
  170.         type = type,
  171.         info = info || 0,
  172.         zone = 0,
  173.         neighbor = {},
  174.         numneighbors = 0,
  175.         link = {},
  176.         numlinks = 0
  177.     }
  178.     local nodeID = table.insert(nodes,node)
  179.     local lookup = self:GetLookupTable()
  180.     lookup[nodeID] = -1
  181.     return nodeID
  182. end
  183.  
  184. function methods:RemoveLinks(nodeID)
  185.     local nodes = self:GetNodes()
  186.     local node = nodes[nodeID]
  187.     if(!node) then return end
  188.     local links = self:GetLinks()
  189.     for _,link in pairs(links) do
  190.         if(link.dest == node) then
  191.             links[_] = nil
  192.             if(link.src) then
  193.                 for _,linkSrc in pairs(link.src.link) do
  194.                     if(linkSrc.dest == node || linkSrc.src == node) then
  195.                         link.src.link[_] = nil
  196.                     end
  197.                 end
  198.             end
  199.         elseif(link.src == node) then
  200.             links[_] = nil
  201.             if(link.dest) then
  202.                 for _,linkSrc in pairs(link.dest.link) do
  203.                     if(linkSrc.dest == node || linkSrc.src == node) then
  204.                         link.dest.link[_] = nil
  205.                     end
  206.                 end
  207.             end
  208.         end
  209.     end
  210.     node.link = {}
  211. end
  212.  
  213. function methods:RemoveNode(nodeID)
  214.     local nodes = self:GetNodes()
  215.     if(!nodes[nodeID]) then return end
  216.     self:RemoveLinks(nodeID)
  217.     nodes[nodeID] = nil
  218.     local lookup = self:GetLookupTable()
  219.     lookup[nodeID] = nil
  220. end
  221.  
  222. function methods:RemoveLink(src,dest)
  223.     local nodes = self:GetNodes()
  224.     local nodeSrc = nodes[src]
  225.     local nodeDest = nodes[dest]
  226.     if(!nodeSrc || !nodeDest) then return end
  227.     local links = self:GetLinks()
  228.     for _,link in pairs(links) do
  229.         if((link.src == nodeSrc && link.dest == nodeDest) || (link.src == nodeDest && link.dest == nodeSrc)) then
  230.             links[_] = nil
  231.         end
  232.     end
  233.     for _,linkSrc in pairs(nodeSrc.link) do
  234.         if((linkSrc.src == nodeSrc && linkSrc.dest == nodeDest) || (linkSrc.src == nodeDest && linkSrc.dest == nodeSrc)) then
  235.             nodeSrc.link[_] = nil
  236.         end
  237.     end
  238.     for _,linkDest in pairs(nodeDest.link) do
  239.         if((linkDest.src == nodeSrc && linkDest.dest == nodeDest) || (linkDest.src == nodeDest && linkDest.dest == nodeSrc)) then
  240.             nodeDest.link[_] = nil
  241.         end
  242.     end
  243. end
  244.  
  245. function methods:AddLink(src,dest,move)
  246.     if(src == dest) then return end
  247.     local nodes = self:GetNodes()
  248.     local nodeSrc = nodes[src]
  249.     local nodeDest = nodes[dest]
  250.     if(!nodeSrc || !nodeDest) then return end
  251.     if(!move) then
  252.         move = {}
  253.         for i = 1,NUM_HULLS do move[i] = 1 end
  254.     end
  255.     local link = {
  256.         src = nodeSrc,
  257.         dest = nodeDest,
  258.         srcID = src,
  259.         destID = dest,
  260.         move = move
  261.     }
  262.     table.insert(nodeSrc.link,link)
  263.     table.insert(self:GetLinks(),link)
  264. end
  265.  
  266. function methods:GetLink(src,dest)
  267.     local nodes = self:GetNodes()
  268.     local nodeSrc = nodes[src]
  269.     local nodeDest = nodes[dest]
  270.     if(!nodeSrc || !nodeDest) then return end
  271.     for _,link in pairs(nodeSrc.link) do
  272.         if(link.src == nodeDest || link.dest == nodeDest) then return link end
  273.     end
  274.     for _,link in pairs(nodeDest.link) do
  275.         if(link.src == nodeSrc || link.dest == nodeSrc) then return link end
  276.     end
  277. end
  278.  
  279. function methods:HasLink(src,dest)
  280.     return self:GetLink(src,dest) != nil
  281. end
  282.  
  283. local function writeBytesInt(f,num)
  284.     f:WriteByte(bit.band(num,0xFF))
  285.     f:WriteByte(bit.rshift(num,bit.band(8,0xFF)))
  286.     f:WriteByte(bit.rshift(num,bit.band(16,0xFF)))
  287.     f:WriteByte(bit.rshift(num,bit.band(24,0xFF)))
  288. end
  289. local function writeBytesUShort(f,num)
  290.     f:WriteByte(bit.band(num,0xFF))
  291.     f:WriteByte(bit.rshift(num,bit.band(8,0xFF)))
  292. end
  293.  
  294. function methods:Save(f)
  295.     if(!f) then
  296.         file.CreateDir("nodegraph")
  297.         f = "nodegraph/" .. game.GetMap() .. ".txt"
  298.     end
  299.     local data = self:GetData()
  300.     local nodes = data.nodes
  301.     local nodeID = 1
  302.     local nodeIDs = {}
  303.     for _,node in pairs(nodes) do // Put everything in a sequential order
  304.         nodes[_] = nil
  305.         nodes[nodeID] = node
  306.         nodeIDs[_] = nodeID
  307.         nodeID = nodeID +1
  308.     end
  309.     local links = data.links
  310.     local linkID = 1
  311.     for _,link in pairs(links) do // Update the node IDs in the links and put everything in a sequential order
  312.         links[_] = nil
  313.         links[linkID] = link
  314.         link.destID = nodeIDs[link.destID]
  315.         link.srcID = nodeIDs[link.srcID]
  316.         link.dest = nodes[link.destID]
  317.         link.src = nodes[link.srcID]
  318.         linkID = linkID +1
  319.     end
  320.     local lookup = table.Copy(data.lookup)
  321.     data.lookup = {}
  322.     for nodeID,_ in pairs(lookup) do // Update the lookup table
  323.         data.lookup[nodeIDs[nodeID]] = _
  324.     end
  325.     lookup = data.lookup
  326.     local f = file.Open(f,"wb","DATA")
  327.         writeBytesInt(f,data.ainet_version)
  328.         writeBytesInt(f,data.map_version)
  329.         local numNodes = #nodes
  330.         writeBytesInt(f,numNodes)
  331.         for i = 1,numNodes do
  332.             local node = nodes[i]
  333.             for i = 1,3 do f:WriteFloat(node.pos[i]) end
  334.             f:WriteFloat(node.yaw)
  335.             for i = 1,NUM_HULLS do
  336.                 f:WriteFloat(node.offset[i])
  337.             end
  338.             f:WriteByte(node.type)
  339.             writeBytesUShort(f,node.info)
  340.             f:WriteShort(node.zone)
  341.         end
  342.         local numLinks = #links
  343.         writeBytesInt(f,numLinks)
  344.         for i = 1,numLinks do
  345.             local link = links[i]
  346.             f:WriteShort(link.srcID -1)
  347.             f:WriteShort(link.destID -1)
  348.             for i = 1,NUM_HULLS do
  349.                 f:WriteByte(link.move[i])
  350.             end
  351.         end
  352.         for i = 1,numNodes do
  353.             writeBytesInt(f,lookup[i])
  354.         end
  355.     f:Close()
  356. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement