public List <uint> FindBestPath(JVector origin, JVector destination) { if (_tradelanes.Count == 0) { return(null); } var tldist = new Dictionary <uint, double>(); var tlprev = new Dictionary <uint, uint>(); foreach (var tl in _tradelanes) { if (tldist.ContainsKey(tl.Key)) { continue; } JVector x1 = Solars[tl.Key].Position, x2 = Solars[tl.Value].Position; double t = -(x1 - origin).Dot(x2 - x1) / (x2 - x1).LengthSq(); double cruiseTravel = 0, tlTravel = (x2 - x1).Length() / UniverseDB.TradelaneSpeed; if (t >= 0 && t <= 1) { JVector newintersect = x1 + (x2 - x1) * t; cruiseTravel = (newintersect - origin).Length(); } else if (t < 0) { t = 0; cruiseTravel = x1.DistanceTo(origin); } else if (t > 1) { t = 1; cruiseTravel = x2.DistanceTo(origin); } tlprev.Add(tl.Key, 0); tlprev.Add(tl.Value, 0); tldist.Add(tl.Key, cruiseTravel / UniverseDB.CruiseSpeed + tlTravel * t); tldist.Add(tl.Value, cruiseTravel / UniverseDB.CruiseSpeed + tlTravel * (1 - t)); } /*double dist = origin.DistanceTo(destination); * Solar closest = null; * foreach (KeyValuePair<uint, uint> tl in tradelanes) * { * Solar s = solars[tl.Key]; * double newdist = s.position.DistanceTo(destination); * if (newdist < dist) * { * dist = newdist; * closest = s; * } * } * if (closest == null) * return null; // Cruise directly to destination*/ var nodes = new HashSet <PathfindingNode>(); foreach (var ns in _pathfinding) { nodes.Add(ns.Value); } while (nodes.Count > 0) { KeyValuePair <uint, double> u = tldist.Where(x => nodes.Contains(_pathfinding[x.Key])) .Aggregate((p1, p2) => (p1.Value < p2.Value) ? p1 : p2); nodes.Remove(_pathfinding[u.Key]); if (u.Value == Double.MaxValue) { return(null); // derp? } foreach (PathfindingConnection c in _pathfinding[u.Key].Connections) { if (nodes.Contains(c.To)) { double alt = tldist[c.From.SolarID] + c.Cost; if (alt < tldist[c.To.SolarID]) { tldist[c.To.SolarID] = alt; tlprev[c.To.SolarID] = c.From.SolarID; } } } } var objects = new List <uint>(); { uint u = 0; double mindist = Double.MaxValue; foreach (var tl in tldist) { var s = Solars[tl.Key]; double dist = s.Position.DistanceTo(destination) / UniverseDB.CruiseSpeed + tl.Value; if (dist < mindist) { u = tl.Key; mindist = dist; } } while (tlprev[u] != 0) { objects.Add(u); u = tlprev[u]; } objects.Add(u); uint lastadded = u; uint minu = u; mindist = Solars[u].Position.DistanceTo(origin); if (Solars[u].PrevRing != 0) { while (Solars[u].PrevRing != 0) { u = Solars[u].PrevRing; double d = Solars[u].Position.DistanceTo(origin); if (d < mindist) { minu = u; mindist = d; } } } else { while (Solars[u].NextRing != 0) { u = Solars[u].NextRing; double d = Solars[u].Position.DistanceTo(origin); if (d < mindist) { minu = u; mindist = d; } } } if (minu == lastadded) { objects.Remove(lastadded); } else { objects.Add(minu); } } objects.Reverse(); return(objects); }