public static Point3D[] FindWaypoints(Mobile m, Map map, Point3D start, Point3D goal)
		{
			DateTime s = DateTime.Now;
			if (m_Nodes == null)
				return null; // sanity check

			if (!SameIsland(start, goal))
				return null;

			if (!Utility.InRange(start, goal, 512))
				return null;

			SearchNodeHeap open = new SearchNodeHeap();
			ArrayList closed = new ArrayList();

			SectorNode goalnode = m_Nodes[goal.X >> Map.SectorShift, goal.Y >> Map.SectorShift];

			open.Add(new SearchNode(m_Nodes[start.X >> Map.SectorShift, start.Y >> Map.SectorShift], null, 0, goal));

			while (open.Count > 0)
			{
				SearchNode curnode = open.Pop();
				closed.Add(curnode);

				if (curnode.SectorNode == goalnode)
					break;

				for (int i = 0; i < curnode.SectorNode.NumLinks; i++)
				{
					SearchNode newnode = new SearchNode(curnode.SectorNode.Links[i], curnode, curnode.G + curnode.SectorNode.Distances[i], goal);
					
					if (closed.Contains(newnode))
						continue;

					SearchNode existing = open.FindMatch(newnode);
					if (existing == null)
						open.Add(newnode);
					else if (newnode.G < existing.G)
						open.Adjust(newnode);
					// else skip
				}
			}

			SearchNode sn = (SearchNode)closed[closed.Count - 1];
			if (sn.SectorNode == goalnode)
			{
				Stack nodes = new Stack();
				while (sn != null)
				{
					closed.Remove(sn);
					nodes.Push(sn);
					sn = sn.Parent;
				}

				Point3D[] points = new Point3D[nodes.Count + 1];
				for (int i = 0; i < points.Length - 1; i++)
					points[i] = ((SearchNode)nodes.Pop()).SectorNode.Point;
				points[points.Length - 1] = goal;

				return points;
			}

			return null;
		}
        public static Point3D[] FindWaypoints(Mobile m, Map map, Point3D start, Point3D goal)
        {
            DateTime s = DateTime.Now;

            if (m_Nodes == null)
            {
                return(null);                // sanity check
            }
            if (!SameIsland(start, goal))
            {
                return(null);
            }

            if (!Utility.InRange(start, goal, 512))
            {
                return(null);
            }

            SearchNodeHeap open   = new SearchNodeHeap();
            ArrayList      closed = new ArrayList();

            SectorNode goalnode = m_Nodes[goal.X >> Map.SectorShift, goal.Y >> Map.SectorShift];

            open.Add(new SearchNode(m_Nodes[start.X >> Map.SectorShift, start.Y >> Map.SectorShift], null, 0, goal));

            while (open.Count > 0)
            {
                SearchNode curnode = open.Pop();
                closed.Add(curnode);

                if (curnode.SectorNode == goalnode)
                {
                    break;
                }

                for (int i = 0; i < curnode.SectorNode.NumLinks; i++)
                {
                    SearchNode newnode = new SearchNode(curnode.SectorNode.Links[i], curnode, curnode.G + curnode.SectorNode.Distances[i], goal);

                    if (closed.Contains(newnode))
                    {
                        continue;
                    }

                    SearchNode existing = open.FindMatch(newnode);
                    if (existing == null)
                    {
                        open.Add(newnode);
                    }
                    else if (newnode.G < existing.G)
                    {
                        open.Adjust(newnode);
                    }
                    // else skip
                }
            }

            SearchNode sn = (SearchNode)closed[closed.Count - 1];

            if (sn.SectorNode == goalnode)
            {
                Stack nodes = new Stack();
                while (sn != null)
                {
                    closed.Remove(sn);
                    nodes.Push(sn);
                    sn = sn.Parent;
                }

                Point3D[] points = new Point3D[nodes.Count + 1];
                for (int i = 0; i < points.Length - 1; i++)
                {
                    points[i] = ((SearchNode)nodes.Pop()).SectorNode.Point;
                }
                points[points.Length - 1] = goal;

                return(points);
            }

            return(null);
        }