public PathList[] GetPath(PathfinderNode[] StartNodes, PathfinderNode FinishNode, int Accuracy, int MinClearance) { var StartNodeCount = StartNodes.GetUpperBound(0) + 1; var Paths = new PathList[NodeLayerCount]; var LayerStartNodes = new PathfinderNode[NodeLayerCount, StartNodeCount]; var LayerFinishNodes = new PathfinderNode[NodeLayerCount]; var LayerNum = 0; var Destinations = new PathfinderNode[24]; var DestinationCount = 0; var FinishIsParent = default(bool); var CalcNodeCount = new int[24]; var FloodRouteArgs = new sFloodRouteArgs(); var FinalLayer = 0; var StartCanReach = new bool[StartNodeCount]; var tmpNodeA = default(PathfinderNode); var tmpNodeB = default(PathfinderNode); var CanReachCount = 0; var FirstLayer = 0; var BestPaths = new Path[24]; var BestValues = new float[24]; var PathNum = 0; var StopMultiPathing = default(bool); var Visit = NetworkLargeArrays.Nodes_Booleans; var NodeValues = NetworkLargeArrays.Nodes_ValuesA; var Nodes_Nodes = NetworkLargeArrays.Nodes_Nodes; var StartPath = NetworkLargeArrays.Nodes_Path; var A = 0; var B = 0; var C = 0; var D = 0; var E = 0; FinalLayer = StartNodes[0].Layer.Network_LayerNum; LayerFinishNodes[FinalLayer] = FinishNode; B = FinalLayer; do { if ( LayerFinishNodes[B].ParentNode == null ) { FirstLayer = B; break; } LayerFinishNodes[B + 1] = LayerFinishNodes[B].ParentNode; B++; } while ( true ); for ( A = 0; A <= StartNodeCount - 1; A++ ) { LayerStartNodes[FinalLayer, A] = StartNodes[A]; B = FinalLayer; do { if ( LayerStartNodes[B, A].ParentNode == null ) { if ( LayerStartNodes[B, A] == LayerFinishNodes[B] ) { StartCanReach[A] = true; CanReachCount++; } break; } LayerStartNodes[B + 1, A] = LayerStartNodes[B, A].ParentNode; B++; } while ( true ); } if ( CanReachCount == 0 ) { return null; } LayerNum = FirstLayer; Paths[LayerNum].Paths = new Path[0]; Paths[LayerNum].Paths[0] = new Path(); Paths[LayerNum].PathCount = 1; Paths[LayerNum].Paths[0].Nodes = new PathfinderNode[1]; Paths[LayerNum].Paths[0].Nodes[0] = LayerFinishNodes[LayerNum]; Paths[LayerNum].Paths[0].NodeCount = 1; var LastLayer = 0; do { LastLayer = LayerNum; LayerNum--; if ( LayerNum < FinalLayer ) { break; } if ( StopMultiPathing ) { if ( Accuracy < 0 ) { Debugger.Break(); } for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ ) { CalcNodeCount[PathNum] = Math.Min(Accuracy, Convert.ToInt32(Paths[LastLayer].Paths[PathNum].NodeCount - 1)); } Destinations[0] = Paths[LastLayer].Paths[0].Nodes[CalcNodeCount[0]]; DestinationCount = 1; FinishIsParent = true; } else { if ( Accuracy >= 0 ) { for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ ) { if ( Paths[LastLayer].Paths[PathNum].NodeCount > Accuracy ) { StopMultiPathing = true; break; } } } Destinations[0] = LayerFinishNodes[LayerNum]; if ( LayerNum == FinalLayer ) { DestinationCount = 1; } else { for ( A = 0; A <= Destinations[0].ConnectionCount - 1; A++ ) { Destinations[1 + A] = Destinations[0].Connections[A].GetOtherNode(Destinations[0]); } DestinationCount = 1 + Destinations[0].ConnectionCount; } for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ ) { CalcNodeCount[PathNum] = Paths[LastLayer].Paths[PathNum].NodeCount - 1; } FinishIsParent = false; } for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ ) { for ( A = 0; A <= CalcNodeCount[PathNum]; A++ ) { tmpNodeA = Paths[LastLayer].Paths[PathNum].Nodes[A]; for ( D = 0; D <= tmpNodeA.ConnectionCount - 1; D++ ) { tmpNodeB = tmpNodeA.Connections[D].GetOtherNode(tmpNodeA); for ( E = 0; E <= tmpNodeB.ConnectionCount - 1; E++ ) { C = tmpNodeB.Connections[E].GetOtherNode(tmpNodeB).Layer_NodeNum; Visit[C] = false; } } } } for ( PathNum = 0; PathNum <= Paths[LastLayer].PathCount - 1; PathNum++ ) { for ( A = 0; A <= CalcNodeCount[PathNum]; A++ ) { tmpNodeA = Paths[LastLayer].Paths[PathNum].Nodes[A]; C = tmpNodeA.Layer_NodeNum; Visit[C] = true; for ( E = 0; E <= tmpNodeA.NodeCount - 1; E++ ) { C = tmpNodeA.Nodes[E].Layer_NodeNum; NodeValues[C] = float.MaxValue; } for ( D = 0; D <= tmpNodeA.ConnectionCount - 1; D++ ) { tmpNodeB = tmpNodeA.Connections[D].GetOtherNode(tmpNodeA); C = tmpNodeB.Layer_NodeNum; Visit[C] = true; for ( E = 0; E <= tmpNodeB.NodeCount - 1; E++ ) { C = tmpNodeB.Nodes[E].Layer_NodeNum; NodeValues[C] = float.MaxValue; } } } } FloodRouteArgs = new sFloodRouteArgs(); FloodRouteArgs.CurrentPath = StartPath; FloodRouteArgs.FinishNodes = Destinations; FloodRouteArgs.FinishNodeCount = DestinationCount; FloodRouteArgs.FinishIsParent = FinishIsParent; FloodRouteArgs.Visit = Visit; FloodRouteArgs.NodeValues = NodeValues; FloodRouteArgs.SourceNodes = Nodes_Nodes; FloodRouteArgs.MinClearance = MinClearance; for ( A = 0; A <= DestinationCount - 1; A++ ) { BestPaths[A] = null; BestValues[A] = float.MaxValue; } for ( A = 0; A <= StartNodeCount - 1; A++ ) { if ( StartCanReach[A] ) { StartPath.NodeCount = 1; StartPath.Nodes[0] = LayerStartNodes[LayerNum, A]; StartPath.Value = 0.0F; FloodRouteArgs.BestPaths = new Path[DestinationCount]; FloodRoute(ref FloodRouteArgs); for ( PathNum = 0; PathNum <= DestinationCount - 1; PathNum++ ) { if ( FloodRouteArgs.BestPaths[PathNum] != null ) { if ( FloodRouteArgs.BestPaths[PathNum].Value < BestValues[PathNum] ) { BestValues[PathNum] = FloodRouteArgs.BestPaths[PathNum].Value; BestPaths[PathNum] = FloodRouteArgs.BestPaths[PathNum]; } } } } } Paths[LayerNum].Paths = new Path[DestinationCount]; Paths[LayerNum].PathCount = 0; for ( PathNum = 0; PathNum <= DestinationCount - 1; PathNum++ ) { if ( BestPaths[PathNum] != null ) { Paths[LayerNum].Paths[Paths[LayerNum].PathCount] = BestPaths[PathNum]; Paths[LayerNum].PathCount++; } } Array.Resize(ref Paths[LayerNum].Paths, Paths[LayerNum].PathCount); if ( Paths[LayerNum].PathCount == 0 ) { return null; } } while ( true ); return Paths; }
public Path[] GetAllPaths(PathfinderNode[] StartNodes, PathfinderNode FinishNode, int MinClearance) { var StartNodeCount = StartNodes.GetUpperBound(0) + 1; var LayerStartNodes = new PathfinderNode[32, StartNodeCount]; var LayerFinishNodes = new PathfinderNode[32]; var LayerNum = 0; var FloodRouteDArgs = new sFloodRouteAllArgs(); var FinalLayer = 0; var StartCanReach = new bool[StartNodeCount]; var tmpNodeA = default(PathfinderNode); var CanReachCount = 0; var FirstLayer = 0; var SubPaths = new Path[32]; var Nodes_Nodes = NetworkLargeArrays.Nodes_Nodes; var Visit = NetworkLargeArrays.Nodes_Booleans; var NodeValues = NetworkLargeArrays.Nodes_ValuesA; var NodeValuesB = NetworkLargeArrays.Nodes_ValuesB; var A = 0; var B = 0; var C = 0; var D = 0; FinalLayer = StartNodes[0].Layer.Network_LayerNum; LayerFinishNodes[FinalLayer] = FinishNode; B = FinalLayer; do { if ( LayerFinishNodes[B].ParentNode == null ) { FirstLayer = B; break; } LayerFinishNodes[B + 1] = LayerFinishNodes[B].ParentNode; B++; } while ( true ); for ( A = 0; A <= StartNodeCount - 1; A++ ) { LayerStartNodes[FinalLayer, A] = StartNodes[A]; B = FinalLayer; do { if ( LayerStartNodes[B, A].ParentNode == null ) { if ( LayerStartNodes[B, A] == LayerFinishNodes[B] ) { StartCanReach[A] = true; CanReachCount++; } break; } LayerStartNodes[B + 1, A] = LayerStartNodes[B, A].ParentNode; B++; } while ( true ); } if ( CanReachCount == 0 ) { return null; } LayerNum = FirstLayer; SubPaths[LayerNum] = new Path(); SubPaths[LayerNum].Nodes = new[] {LayerFinishNodes[LayerNum]}; SubPaths[LayerNum].NodeCount = 1; var LastLayer = 0; do { LastLayer = LayerNum; LayerNum--; if ( LayerNum < FinalLayer ) { break; } for ( A = 0; A <= SubPaths[LastLayer].NodeCount - 1; A++ ) { tmpNodeA = SubPaths[LastLayer].Nodes[A]; for ( B = 0; B <= tmpNodeA.ConnectionCount - 1; B++ ) { C = tmpNodeA.Connections[B].GetOtherNode(tmpNodeA).Layer_NodeNum; Visit[C] = false; } } for ( A = 0; A <= SubPaths[LastLayer].NodeCount - 1; A++ ) { tmpNodeA = SubPaths[LastLayer].Nodes[A]; C = tmpNodeA.Layer_NodeNum; Visit[C] = true; for ( D = 0; D <= tmpNodeA.NodeCount - 1; D++ ) { C = tmpNodeA.Nodes[D].Layer_NodeNum; NodeValues[C] = float.MaxValue; NodeValuesB[C] = float.MaxValue; } } FloodRouteDArgs = new sFloodRouteAllArgs(); FloodRouteDArgs.FinishNode = LayerFinishNodes[LayerNum]; FloodRouteDArgs.Visit = Visit; FloodRouteDArgs.NodeValuesA = NodeValues; FloodRouteDArgs.SourceNodes = Nodes_Nodes; FloodRouteDArgs.NodeValuesB = NodeValuesB; FloodRouteDArgs.MinClearance = MinClearance; FloodRouteDArgs.BestTolerance = (float)(Math.Pow(1.1D, LayerNum)); FloodRouteDArgs.StartNodes = new PathfinderNode[StartNodeCount]; for ( A = 0; A <= StartNodeCount - 1; A++ ) { if ( StartCanReach[A] ) { FloodRouteDArgs.StartNodes[FloodRouteDArgs.StartNodeCount] = LayerStartNodes[LayerNum, A]; FloodRouteDArgs.StartNodeCount++; } } Array.Resize(ref FloodRouteDArgs.StartNodes, FloodRouteDArgs.StartNodeCount); FloodRouteAll(ref FloodRouteDArgs); SubPaths[LayerNum] = new Path(); SubPaths[LayerNum].Nodes = new PathfinderNode[FloodRouteDArgs.BestNodeCount]; for ( A = 0; A <= FloodRouteDArgs.BestNodeCount - 1; A++ ) { SubPaths[LayerNum].Nodes[A] = FloodRouteDArgs.SourceNodes[A]; } SubPaths[LayerNum].NodeCount = FloodRouteDArgs.BestNodeCount; if ( FloodRouteDArgs.BestNodeCount == 0 ) { Debugger.Break(); return SubPaths; } } while ( true ); return SubPaths; }