Inheritance: GraphModifier
Beispiel #1
0
        // Token: 0x060022EB RID: 8939 RVA: 0x001924B8 File Offset: 0x001906B8
        internal static void DeserializeReferences(GraphSerializationContext ctx)
        {
            int num = ctx.reader.ReadInt32();

            for (int i = 0; i < num; i++)
            {
                ulong         key        = ctx.reader.ReadUInt64();
                GraphNode     graphNode  = ctx.DeserializeNodeReference();
                GraphNode     graphNode2 = ctx.DeserializeNodeReference();
                GraphNode     graphNode3 = ctx.DeserializeNodeReference();
                GraphNode     graphNode4 = ctx.DeserializeNodeReference();
                Vector3       vector     = ctx.DeserializeVector3();
                Vector3       vector2    = ctx.DeserializeVector3();
                bool          flag       = ctx.reader.ReadBoolean();
                GraphModifier graphModifier;
                if (!GraphModifier.usedIDs.TryGetValue(key, out graphModifier))
                {
                    throw new Exception("Tried to deserialize a NodeLink2 reference, but the link could not be found in the scene.\nIf a NodeLink2 is included in serialized graph data, the same NodeLink2 component must be present in the scene when loading the graph data.");
                }
                NodeLink2 nodeLink = graphModifier as NodeLink2;
                if (!(nodeLink != null))
                {
                    throw new Exception("Tried to deserialize a NodeLink2 reference, but the link was not of the correct type or it has been destroyed.\nIf a NodeLink2 is included in serialized graph data, the same NodeLink2 component must be present in the scene when loading the graph data.");
                }
                if (graphNode != null)
                {
                    NodeLink2.reference[graphNode] = nodeLink;
                }
                if (graphNode2 != null)
                {
                    NodeLink2.reference[graphNode2] = nodeLink;
                }
                if (nodeLink.startNode != null)
                {
                    NodeLink2.reference.Remove(nodeLink.startNode);
                }
                if (nodeLink.endNode != null)
                {
                    NodeLink2.reference.Remove(nodeLink.endNode);
                }
                nodeLink.startNode      = (graphNode as PointNode);
                nodeLink.endNode        = (graphNode2 as PointNode);
                nodeLink.connectedNode1 = graphNode3;
                nodeLink.connectedNode2 = graphNode4;
                nodeLink.postScanCalled = flag;
                nodeLink.clamped1       = vector;
                nodeLink.clamped2       = vector2;
            }
        }
Beispiel #2
0
 /** Works like a constructor, but can be used even for pooled objects. Returns \a this for easy chaining */
 public RichSpecial Initialize(NodeLink2 nodeLink, GraphNode first)
 {
     this.nodeLink = nodeLink;
     if (first == nodeLink.StartNode)
     {
         this.first  = nodeLink.StartTransform;
         this.second = nodeLink.EndTransform;
         reverse     = false;
     }
     else
     {
         this.first  = nodeLink.EndTransform;
         this.second = nodeLink.StartTransform;
         reverse     = true;
     }
     return(this);
 }
Beispiel #3
0
 public RichSpecial Initialize(NodeLink2 nodeLink, GraphNode first)
 {
     this.nodeLink = nodeLink;
     if (first == nodeLink.StartNode)
     {
         this.first = nodeLink.StartTransform;
         this.second = nodeLink.EndTransform;
         this.reverse = false;
     }
     else
     {
         this.first = nodeLink.EndTransform;
         this.second = nodeLink.StartTransform;
         this.reverse = true;
     }
     return this;
 }
Beispiel #4
0
        /** Use this for initialization.
         *
         * \param s Optionally provide in order to take tag penalties into account. May be null if you do not use a Seeker\
         * \param p Path to follow
         * \param mergePartEndpoints If true, then adjacent parts that the path is split up in will
         * try to use the same start/end points. For example when using a link on a navmesh graph
         * Instead of first following the path to the center of the node where the link is and then
         * follow the link, the path will be adjusted to go to the exact point where the link starts
         * which usually makes more sense.
         * \param simplificationMode The path can optionally be simplified. This can be a bit expensive for long paths.
         */
        public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode)
        {
            if (p.error)
            {
                throw new System.ArgumentException("Path has an error");
            }

            List <GraphNode> nodes = p.path;

            if (nodes.Count == 0)
            {
                throw new System.ArgumentException("Path traverses no nodes");
            }

            seeker = s;
            // Release objects back to object pool
            // Yeah, I know, it's casting... but this won't be called much
            for (int i = 0; i < parts.Count; i++)
            {
                if (parts[i] is RichFunnel)
                {
                    ObjectPool <RichFunnel> .Release(parts[i] as RichFunnel);
                }
                else if (parts[i] is RichSpecial)
                {
                    ObjectPool <RichSpecial> .Release(parts[i] as RichSpecial);
                }
            }

            parts.Clear();
            currentPart = 0;

            // Initialize new

            //Break path into parts
            for (int i = 0; i < nodes.Count; i++)
            {
                if (nodes[i] is TriangleMeshNode)
                {
                    var        graph = AstarData.GetGraph(nodes[i]);
                    RichFunnel f     = ObjectPool <RichFunnel> .Claim().Initialize(this, graph);

                    f.funnelSimplificationMode = simplificationMode;

                    int  sIndex            = i;
                    uint currentGraphIndex = nodes[sIndex].GraphIndex;


                    for (; i < nodes.Count; i++)
                    {
                        if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node))
                        {
                            break;
                        }
                    }
                    i--;

                    if (sIndex == 0)
                    {
                        f.exactStart = p.vectorPath[0];
                    }
                    else
                    {
                        f.exactStart = (Vector3)nodes[mergePartEndpoints ? sIndex - 1 : sIndex].position;
                    }

                    if (i == nodes.Count - 1)
                    {
                        f.exactEnd = p.vectorPath[p.vectorPath.Count - 1];
                    }
                    else
                    {
                        f.exactEnd = (Vector3)nodes[mergePartEndpoints ? i + 1 : i].position;
                    }

                    f.BuildFunnelCorridor(nodes, sIndex, i);

                    parts.Add(f);
                }
                else if (NodeLink2.GetNodeLink(nodes[i]) != null)
                {
                    NodeLink2 nl = NodeLink2.GetNodeLink(nodes[i]);

                    int  sIndex            = i;
                    uint currentGraphIndex = nodes[sIndex].GraphIndex;

                    for (i++; i < nodes.Count; i++)
                    {
                        if (nodes[i].GraphIndex != currentGraphIndex)
                        {
                            break;
                        }
                    }
                    i--;

                    if (i - sIndex > 1)
                    {
                        throw new System.Exception("NodeLink2 path length greater than two (2) nodes. " + (i - sIndex));
                    }
                    else if (i - sIndex == 0)
                    {
                        //Just continue, it might be the case that a NodeLink was the closest node
                        continue;
                    }

                    RichSpecial rps = ObjectPool <RichSpecial> .Claim().Initialize(nl, nodes[sIndex]);

                    parts.Add(rps);
                }
            }
        }
Beispiel #5
0
 public override void OnEnterPool()
 {
     nodeLink = null;
 }
Beispiel #6
0
        public static List <PathPart> SplitIntoParts(Path path)
        {
            var nodes = path.path;

            var result = ListPool <PathPart> .Claim();

            if (nodes == null || nodes.Count == 0)
            {
                return(result);
            }

            // Loop through the path and split it into
            // parts joined by links
            for (int i = 0; i < nodes.Count; i++)
            {
                if (nodes[i] is TriangleMeshNode || nodes[i] is GridNodeBase)
                {
                    var part = new PathPart();
                    part.startIndex = i;
                    uint currentGraphIndex = nodes[i].GraphIndex;

                    // Loop up until we find a node in another graph
                    // Ignore NodeLink3 nodes
                    for (; i < nodes.Count; i++)
                    {
                        if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node))
                        {
                            break;
                        }
                    }

                    i--;
                    part.endIndex = i;

                    // If this is the first part in the path, use the exact start point
                    // otherwise use the position of the node right before the start of this
                    // part which is likely the end of the link to this part
                    if (part.startIndex == 0)
                    {
                        part.startPoint = path.vectorPath[0];
                    }
                    else
                    {
                        part.startPoint = (Vector3)nodes[part.startIndex - 1].position;
                    }

                    if (part.endIndex == nodes.Count - 1)
                    {
                        part.endPoint = path.vectorPath[path.vectorPath.Count - 1];
                    }
                    else
                    {
                        part.endPoint = (Vector3)nodes[part.endIndex + 1].position;
                    }

                    result.Add(part);
                }
                else if (NodeLink2.GetNodeLink(nodes[i]) != null)
                {
                    var part = new PathPart();
                    part.startIndex = i;
                    var currentGraphIndex = nodes[i].GraphIndex;

                    for (i++; i < nodes.Count; i++)
                    {
                        if (nodes[i].GraphIndex != currentGraphIndex)
                        {
                            break;
                        }
                    }
                    i--;

                    if (i - part.startIndex == 0)
                    {
                        // Just ignore it, it might be the case that a NodeLink was the closest node
                        continue;
                    }
                    else if (i - part.startIndex != 1)
                    {
                        throw new System.Exception("NodeLink2 link length greater than two (2) nodes. " + (i - part.startIndex + 1));
                    }

                    part.endIndex   = i;
                    part.isLink     = true;
                    part.startPoint = (Vector3)nodes[part.startIndex].position;
                    part.endPoint   = (Vector3)nodes[part.endIndex].position;
                    result.Add(part);
                }
                else
                {
                    throw new System.Exception("Unsupported node type or null node");
                }
            }

            return(result);
        }
Beispiel #7
0
        public static List <Funnel.PathPart> SplitIntoParts(Path path)
        {
            List <GraphNode>       path2 = path.path;
            List <Funnel.PathPart> list  = ListPool <Funnel.PathPart> .Claim();

            if (path2 == null || path2.Count == 0)
            {
                return(list);
            }
            for (int i = 0; i < path2.Count; i++)
            {
                if (path2[i] is TriangleMeshNode || path2[i] is GridNodeBase)
                {
                    Funnel.PathPart pathPart = default(Funnel.PathPart);
                    pathPart.startIndex = i;
                    uint graphIndex = path2[i].GraphIndex;
                    while (i < path2.Count && (path2[i].GraphIndex == graphIndex || path2[i] is NodeLink3Node))
                    {
                        i++;
                    }
                    i--;
                    pathPart.endIndex = i;
                    if (pathPart.startIndex == 0)
                    {
                        pathPart.startPoint = path.vectorPath[0];
                    }
                    else
                    {
                        pathPart.startPoint = (Vector3)path2[pathPart.startIndex - 1].position;
                    }
                    if (pathPart.endIndex == path2.Count - 1)
                    {
                        pathPart.endPoint = path.vectorPath[path.vectorPath.Count - 1];
                    }
                    else
                    {
                        pathPart.endPoint = (Vector3)path2[pathPart.endIndex + 1].position;
                    }
                    list.Add(pathPart);
                }
                else
                {
                    if (!(NodeLink2.GetNodeLink(path2[i]) != null))
                    {
                        throw new Exception("Unsupported node type or null node");
                    }
                    Funnel.PathPart pathPart2 = default(Funnel.PathPart);
                    pathPart2.startIndex = i;
                    uint graphIndex2 = path2[i].GraphIndex;
                    i++;
                    while (i < path2.Count && path2[i].GraphIndex == graphIndex2)
                    {
                        i++;
                    }
                    i--;
                    if (i - pathPart2.startIndex != 0)
                    {
                        if (i - pathPart2.startIndex != 1)
                        {
                            throw new Exception("NodeLink2 link length greater than two (2) nodes. " + (i - pathPart2.startIndex + 1));
                        }
                        pathPart2.endIndex   = i;
                        pathPart2.isLink     = true;
                        pathPart2.startPoint = (Vector3)path2[pathPart2.startIndex].position;
                        pathPart2.endPoint   = (Vector3)path2[pathPart2.endIndex].position;
                        list.Add(pathPart2);
                    }
                }
            }
            return(list);
        }
Beispiel #8
0
        // Token: 0x06002140 RID: 8512 RVA: 0x001890A0 File Offset: 0x001872A0
        public void Initialize(Seeker seeker, Path path, bool mergePartEndpoints, bool simplificationMode)
        {
            if (path.error)
            {
                throw new ArgumentException("Path has an error");
            }
            List <GraphNode> path2 = path.path;

            if (path2.Count == 0)
            {
                throw new ArgumentException("Path traverses no nodes");
            }
            this.seeker = seeker;
            for (int i = 0; i < this.parts.Count; i++)
            {
                RichFunnel  richFunnel  = this.parts[i] as RichFunnel;
                RichSpecial richSpecial = this.parts[i] as RichSpecial;
                if (richFunnel != null)
                {
                    ObjectPool <RichFunnel> .Release(ref richFunnel);
                }
                else if (richSpecial != null)
                {
                    ObjectPool <RichSpecial> .Release(ref richSpecial);
                }
            }
            this.Clear();
            this.Endpoint = path.vectorPath[path.vectorPath.Count - 1];
            for (int j = 0; j < path2.Count; j++)
            {
                if (path2[j] is TriangleMeshNode)
                {
                    NavmeshBase navmeshBase = AstarData.GetGraph(path2[j]) as NavmeshBase;
                    if (navmeshBase == null)
                    {
                        throw new Exception("Found a TriangleMeshNode that was not in a NavmeshBase graph");
                    }
                    RichFunnel richFunnel2 = ObjectPool <RichFunnel> .Claim().Initialize(this, navmeshBase);

                    richFunnel2.funnelSimplification = simplificationMode;
                    int  num        = j;
                    uint graphIndex = path2[num].GraphIndex;
                    while (j < path2.Count && (path2[j].GraphIndex == graphIndex || path2[j] is NodeLink3Node))
                    {
                        j++;
                    }
                    j--;
                    if (num == 0)
                    {
                        richFunnel2.exactStart = path.vectorPath[0];
                    }
                    else
                    {
                        richFunnel2.exactStart = (Vector3)path2[mergePartEndpoints ? (num - 1) : num].position;
                    }
                    if (j == path2.Count - 1)
                    {
                        richFunnel2.exactEnd = path.vectorPath[path.vectorPath.Count - 1];
                    }
                    else
                    {
                        richFunnel2.exactEnd = (Vector3)path2[mergePartEndpoints ? (j + 1) : j].position;
                    }
                    richFunnel2.BuildFunnelCorridor(path2, num, j);
                    this.parts.Add(richFunnel2);
                }
                else if (NodeLink2.GetNodeLink(path2[j]) != null)
                {
                    NodeLink2 nodeLink    = NodeLink2.GetNodeLink(path2[j]);
                    int       num2        = j;
                    uint      graphIndex2 = path2[num2].GraphIndex;
                    j++;
                    while (j < path2.Count && path2[j].GraphIndex == graphIndex2)
                    {
                        j++;
                    }
                    j--;
                    if (j - num2 > 1)
                    {
                        throw new Exception("NodeLink2 path length greater than two (2) nodes. " + (j - num2));
                    }
                    if (j - num2 != 0)
                    {
                        RichSpecial item = ObjectPool <RichSpecial> .Claim().Initialize(nodeLink, path2[num2]);

                        this.parts.Add(item);
                    }
                }
            }
        }
Beispiel #9
0
        // Token: 0x06000033 RID: 51 RVA: 0x0000417C File Offset: 0x0000257C
        public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode)
        {
            if (p.error)
            {
                throw new ArgumentException("Path has an error");
            }
            List <GraphNode> path = p.path;

            if (path.Count == 0)
            {
                throw new ArgumentException("Path traverses no nodes");
            }
            this.seeker = s;
            for (int i = 0; i < this.parts.Count; i++)
            {
                if (this.parts[i] is RichFunnel)
                {
                    ObjectPool <RichFunnel> .Release(this.parts[i] as RichFunnel);
                }
                else if (this.parts[i] is RichSpecial)
                {
                    ObjectPool <RichSpecial> .Release(this.parts[i] as RichSpecial);
                }
            }
            this.parts.Clear();
            this.currentPart = 0;
            for (int j = 0; j < path.Count; j++)
            {
                if (path[j] is TriangleMeshNode)
                {
                    IFunnelGraph graph      = AstarData.GetGraph(path[j]) as IFunnelGraph;
                    RichFunnel   richFunnel = ObjectPool <RichFunnel> .Claim().Initialize(this, graph);

                    richFunnel.funnelSimplificationMode = simplificationMode;
                    int  num        = j;
                    uint graphIndex = path[num].GraphIndex;
                    while (j < path.Count)
                    {
                        if (path[j].GraphIndex != graphIndex && !(path[j] is NodeLink3Node))
                        {
                            break;
                        }
                        j++;
                    }
                    j--;
                    if (num == 0)
                    {
                        richFunnel.exactStart = p.vectorPath[0];
                    }
                    else if (mergePartEndpoints)
                    {
                        richFunnel.exactStart = (Vector3)path[num - 1].position;
                    }
                    else
                    {
                        richFunnel.exactStart = (Vector3)path[num].position;
                    }
                    if (j == path.Count - 1)
                    {
                        richFunnel.exactEnd = p.vectorPath[p.vectorPath.Count - 1];
                    }
                    else if (mergePartEndpoints)
                    {
                        richFunnel.exactEnd = (Vector3)path[j + 1].position;
                    }
                    else
                    {
                        richFunnel.exactEnd = (Vector3)path[j].position;
                    }
                    richFunnel.BuildFunnelCorridor(path, num, j);
                    this.parts.Add(richFunnel);
                }
                else if (path[j] != null && NodeLink2.GetNodeLink(path[j]) != null)
                {
                    NodeLink2 nodeLink    = NodeLink2.GetNodeLink(path[j]);
                    int       num2        = j;
                    uint      graphIndex2 = path[num2].GraphIndex;
                    for (j++; j < path.Count; j++)
                    {
                        if (path[j].GraphIndex != graphIndex2)
                        {
                            break;
                        }
                    }
                    j--;
                    if (j - num2 > 1)
                    {
                        throw new Exception("NodeLink2 path length greater than two (2) nodes. " + (j - num2));
                    }
                    if (j - num2 != 0)
                    {
                        RichSpecial item = ObjectPool <RichSpecial> .Claim().Initialize(nodeLink, path[num2]);

                        this.parts.Add(item);
                    }
                }
            }
        }
Beispiel #10
0
		public override void OnEnterPool () {
			nodeLink = null;
		}
Beispiel #11
0
        /// <summary>Use this for initialization.</summary>
        /// <param name="seeker">Optionally provide in order to take tag penalties into account. May be null if you do not use a Seeker\</param>
        /// <param name="path">Path to follow</param>
        /// <param name="mergePartEndpoints">If true, then adjacent parts that the path is split up in will
        /// try to use the same start/end points. For example when using a link on a navmesh graph
        /// Instead of first following the path to the center of the node where the link is and then
        /// follow the link, the path will be adjusted to go to the exact point where the link starts
        /// which usually makes more sense.</param>
        /// <param name="simplificationMode">The path can optionally be simplified. This can be a bit expensive for long paths.</param>
        public void Initialize(Seeker seeker, Path path, bool mergePartEndpoints, bool simplificationMode)
        {
            if (path.error)
            {
                throw new System.ArgumentException("Path has an error");
            }

            List <GraphNode> nodes = path.path;

            if (nodes.Count == 0)
            {
                throw new System.ArgumentException("Path traverses no nodes");
            }

            this.seeker = seeker;
            // Release objects back to object pool
            // Yeah, I know, it's casting... but this won't be called much
            for (int i = 0; i < parts.Count; i++)
            {
                var funnelPart  = parts[i] as RichFunnel;
                var specialPart = parts[i] as RichSpecial;
                if (funnelPart != null)
                {
                    ObjectPool <RichFunnel> .Release(ref funnelPart);
                }
                else if (specialPart != null)
                {
                    ObjectPool <RichSpecial> .Release(ref specialPart);
                }
            }

            Clear();

            // Initialize new
            Endpoint = path.vectorPath[path.vectorPath.Count - 1];

            //Break path into parts
            for (int i = 0; i < nodes.Count; i++)
            {
                if (nodes[i] is TriangleMeshNode)
                {
                    var graph = AstarData.GetGraph(nodes[i]) as NavmeshBase;
                    if (graph == null)
                    {
                        throw new System.Exception("Found a TriangleMeshNode that was not in a NavmeshBase graph");
                    }

                    RichFunnel f = ObjectPool <RichFunnel> .Claim().Initialize(this, graph);

                    f.funnelSimplification = simplificationMode;

                    int  sIndex            = i;
                    uint currentGraphIndex = nodes[sIndex].GraphIndex;


                    for (; i < nodes.Count; i++)
                    {
                        if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node))
                        {
                            break;
                        }
                    }
                    i--;

                    if (sIndex == 0)
                    {
                        f.exactStart = path.vectorPath[0];
                    }
                    else
                    {
                        f.exactStart = (Vector3)nodes[mergePartEndpoints ? sIndex - 1 : sIndex].position;
                    }

                    if (i == nodes.Count - 1)
                    {
                        f.exactEnd = path.vectorPath[path.vectorPath.Count - 1];
                    }
                    else
                    {
                        f.exactEnd = (Vector3)nodes[mergePartEndpoints ? i + 1 : i].position;
                    }

                    f.BuildFunnelCorridor(nodes, sIndex, i);

                    parts.Add(f);
                }
                else if (NodeLink2.GetNodeLink(nodes[i]) != null)
                {
                    NodeLink2 nl = NodeLink2.GetNodeLink(nodes[i]);

                    int  sIndex            = i;
                    uint currentGraphIndex = nodes[sIndex].GraphIndex;

                    for (i++; i < nodes.Count; i++)
                    {
                        if (nodes[i].GraphIndex != currentGraphIndex)
                        {
                            break;
                        }
                    }
                    i--;

                    if (i - sIndex > 1)
                    {
                        throw new System.Exception("NodeLink2 path length greater than two (2) nodes. " + (i - sIndex));
                    }
                    else if (i - sIndex == 0)
                    {
                        //Just continue, it might be the case that a NodeLink was the closest node
                        continue;
                    }

                    RichSpecial rps = ObjectPool <RichSpecial> .Claim().Initialize(nl, nodes[sIndex]);

                    parts.Add(rps);
                }
                else if (!(nodes[i] is PointNode))
                {
                    // Some other graph type which we do not have support for
                    throw new System.InvalidOperationException("The RichAI movment script can only be used on recast/navmesh graphs. A node of type " + nodes[i].GetType().Name + " was in the path.");
                }
            }
        }
Beispiel #12
0
        public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode)
        {
            if (p.error)
            {
                throw new ArgumentException("Path has an error");
            }
            List <GraphNode> path = p.path;

            if (path.Count == 0)
            {
                throw new ArgumentException("Path traverses no nodes");
            }
            this.seeker = s;
            for (int i = 0; i < this.parts.Count; i++)
            {
                RichFunnel  funnel  = this.parts[i] as RichFunnel;
                RichSpecial special = this.parts[i] as RichSpecial;
                if (funnel != null)
                {
                    Pathfinding.Util.ObjectPool <RichFunnel> .Release(ref funnel);
                }
                else if (special != null)
                {
                    Pathfinding.Util.ObjectPool <RichSpecial> .Release(ref special);
                }
            }
            this.parts.Clear();
            this.currentPart = 0;
            for (int j = 0; j < path.Count; j++)
            {
                if (path[j] is TriangleMeshNode)
                {
                    NavGraph   graph = AstarData.GetGraph(path[j]);
                    RichFunnel item  = Pathfinding.Util.ObjectPool <RichFunnel> .Claim().Initialize(this, graph);

                    item.funnelSimplificationMode = simplificationMode;
                    int  start      = j;
                    uint graphIndex = path[start].GraphIndex;
                    while (j < path.Count)
                    {
                        if ((path[j].GraphIndex != graphIndex) && !(path[j] is NodeLink3Node))
                        {
                            break;
                        }
                        j++;
                    }
                    j--;
                    if (start == 0)
                    {
                        item.exactStart = p.vectorPath[0];
                    }
                    else
                    {
                        item.exactStart = (Vector3)path[!mergePartEndpoints ? start : (start - 1)].position;
                    }
                    if (j == (path.Count - 1))
                    {
                        item.exactEnd = p.vectorPath[p.vectorPath.Count - 1];
                    }
                    else
                    {
                        item.exactEnd = (Vector3)path[!mergePartEndpoints ? j : (j + 1)].position;
                    }
                    item.BuildFunnelCorridor(path, start, j);
                    this.parts.Add(item);
                    continue;
                }
                if (NodeLink2.GetNodeLink(path[j]) != null)
                {
                    NodeLink2 nodeLink = NodeLink2.GetNodeLink(path[j]);
                    int       num5     = j;
                    uint      num6     = path[num5].GraphIndex;
                    j++;
                    while (j < path.Count)
                    {
                        if (path[j].GraphIndex != num6)
                        {
                            break;
                        }
                        j++;
                    }
                    j--;
                    if ((j - num5) > 1)
                    {
                        throw new Exception("NodeLink2 path length greater than two (2) nodes. " + (j - num5));
                    }
                    if ((j - num5) != 0)
                    {
                        RichSpecial special2 = Pathfinding.Util.ObjectPool <RichSpecial> .Claim().Initialize(nodeLink, path[num5]);

                        this.parts.Add(special2);
                    }
                }
            }
        }