using FarseerPhysics; using Microsoft.Xna.Framework; using System.Collections.Generic; using System.Linq; namespace Barotrauma { class PathNode { private WayPoint wayPoint; private int wayPointID; public int state; public PathNode Parent; private Vector2 position; public float F,G,H; public List connections; public float[] distances; public WayPoint Waypoint { get { return wayPoint; } } public Vector2 Position { get {return position;} } public PathNode(WayPoint wayPoint) { this.wayPoint = wayPoint; this.position = wayPoint.SimPosition; wayPointID = wayPoint.ID; connections = new List(); } public static List GenerateNodes(List wayPoints) { var nodes = new Dictionary(); foreach (WayPoint wayPoint in wayPoints) { nodes.Add(wayPoint.ID, new PathNode(wayPoint)); } foreach (KeyValuePair node in nodes) { foreach (MapEntity linked in node.Value.wayPoint.linkedTo) { PathNode connectedNode = null; nodes.TryGetValue(linked.ID, out connectedNode); if (connectedNode == null) continue; node.Value.connections.Add(connectedNode); } } var nodeList = nodes.Values.ToList(); foreach (PathNode node in nodeList) { node.distances = new float[node.connections.Count]; for (int i = 0; i< node.distances.Length; i++) { node.distances[i] = Vector2.Distance(node.position, node.connections[i].position); } } return nodeList; } } class PathFinder { public delegate float? GetNodePenaltyHandler(PathNode node, PathNode prevNode); public GetNodePenaltyHandler GetNodePenalty; List nodes; private bool insideSubmarine; public PathFinder(List wayPoints, bool insideSubmarine = false) { nodes = PathNode.GenerateNodes(wayPoints.FindAll(w => w.MoveWithLevel != insideSubmarine)); this.insideSubmarine = insideSubmarine; } public SteeringPath FindPath(Vector2 start, Vector2 end) { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); float closestDist = 0.0f; PathNode startNode = null; foreach (PathNode node in nodes) { Vector2 nodePos = node.Position; //if node waypoint is one of submarine waypoints outside the sub, transform position //if (node.Waypoint != null && node.Waypoint.Submarine != null && node.Waypoint.CurrentHull == null) //{ // nodePos -= node.Waypoint.Submarine.Position; //} float dist = System.Math.Abs(start.X-nodePos.X)+ System.Math.Abs(start.Y - nodePos.Y)*10.0f + Vector2.Distance(end,nodePos)/2.0f; if (dist finalPath = new List(); PathNode pathNode = end; while (pathNode != start && pathNode != null) { finalPath.Add(pathNode.Waypoint); path.Cost += pathNode.F; pathNode = pathNode.Parent; } finalPath.Reverse(); foreach (WayPoint wayPoint in finalPath) { path.AddNode(wayPoint); } return path; } } }