public PathfinderConnection(PathfinderConnection SourceConnection) { NodeA = SourceConnection.NodeA.ParentNode; NodeB = SourceConnection.NodeB.ParentNode; NodeA.Connection_Add(this, ref NodeA_ConnectionNum); NodeB.Connection_Add(this, ref NodeB_ConnectionNum); NodeA.Layer.Connection_Add(this); ValueCalc(); }
public void ChangedNode_Add(PathfinderNode NewChangedNode) { if ( NewChangedNode.Layer_ChangedNodeNum >= 0 ) { return; } if ( ChangedNodes.GetUpperBound(0) < ChangedNodeCount ) { Array.Resize(ref ChangedNodes, ChangedNodeCount * 2 + 1 + 1); } ChangedNodes[ChangedNodeCount] = NewChangedNode; ChangedNodes[ChangedNodeCount].Layer_ChangedNodeNum = ChangedNodeCount; ChangedNodeCount++; }
public PathfinderConnection(PathfinderNode NewNodeA, PathfinderNode NewNodeB, float NewValue) { if ( NewNodeA.Layer.Network_LayerNum > 0 | NewNodeB.Layer.Network_LayerNum > 0 | NewValue <= 0.0F ) { Debugger.Break(); return; } Value = NewValue; LinkCount = 1; NodeA = NewNodeA; NodeB = NewNodeB; NodeA.Connection_Add(this, ref NodeA_ConnectionNum); NodeB.Connection_Add(this, ref NodeB_ConnectionNum); NodeA.Layer.Connection_Add(this); RaiseDependant(); }
public Path[] GetAllPaths(PathfinderNode[] StartNodes, PathfinderNode FinishNode, int MinClearance) { int StartNodeCount = StartNodes.GetUpperBound(0) + 1; PathfinderNode[,] LayerStartNodes = new PathfinderNode[32, StartNodeCount]; PathfinderNode[] LayerFinishNodes = new PathfinderNode[32]; int LayerNum = 0; PathfinderNode[] Destinations = new PathfinderNode[24]; sFloodRouteAllArgs FloodRouteDArgs = new sFloodRouteAllArgs(); int FinalLayer = 0; bool[] StartCanReach = new bool[StartNodeCount]; PathfinderNode tmpNodeA = default(PathfinderNode); int CanReachCount = 0; int FirstLayer = 0; Path[] SubPaths = new Path[32]; PathfinderNode[] Nodes_Nodes = NetworkLargeArrays.Nodes_Nodes; bool[] Visit = NetworkLargeArrays.Nodes_Booleans; float[] NodeValues = NetworkLargeArrays.Nodes_ValuesA; float[] NodeValuesB = NetworkLargeArrays.Nodes_ValuesB; int A = 0; int B = 0; int C = 0; int 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; int 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(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; }
public void FindParentNode_Add(PathfinderNode NewFindParentNode) { if ( NewFindParentNode.Network_FindParentNum >= 0 ) { return; } if ( FindParentNodes.GetUpperBound(0) < FindParentNodeCount ) { Array.Resize(ref FindParentNodes, (FindParentNodeCount + 1) * 2); } FindParentNodes[FindParentNodeCount] = NewFindParentNode; FindParentNodes[FindParentNodeCount].Network_FindParentNum = FindParentNodeCount; FindParentNodeCount++; }
private void UpdateNodeConnectedness(clsUpdateNodeConnectednessArgs Args, clsPassageNode PassageNode) { int A = 0; clsConnection tmpConnection = default(clsConnection); clsPassageNode tmpOtherNode = default(clsPassageNode); int PassableCount = 0; Args.Args.PassageNodeVisited[PassageNode.MirrorNum, PassageNode.Num] = true; for ( A = 0; A <= PassageNode.ConnectionCount - 1; A++ ) { tmpConnection = PassageNode.Connections[A].Connection; if ( !(tmpConnection.PassageNodeA.IsOnBorder || tmpConnection.PassageNodeB.IsOnBorder || tmpConnection.PassageNodeA.IsWater || tmpConnection.PassageNodeB.IsWater) && (tmpConnection.IsRamp || tmpConnection.PassageNodeA.Level == tmpConnection.PassageNodeB.Level) ) { tmpOtherNode = PassageNode.Connections[A].GetOther(); if ( !Args.Args.PassageNodeVisited[tmpOtherNode.MirrorNum, tmpOtherNode.Num] ) { UpdateNodeConnectedness(Args, tmpOtherNode); } PassableCount++; } } PathfinderNetwork.PathList[] Paths = null; PathfinderNode[] StartNodes = new PathfinderNode[1]; StartNodes[0] = Args.Args.PassageNodePathNodes[0, Args.OriginalNode.Num]; Paths = Args.Args.PassageNodePathMap.GetPath(StartNodes, Args.Args.PassageNodePathNodes[PassageNode.MirrorNum, PassageNode.Num], -1, 0); Args.Args.NodeConnectedness[Args.OriginalNode.Num] += (float)(PassableCount * Math.Pow(0.999D, Paths[0].Paths[0].Value)); }
private void SetBaseLevel(PathfinderNode Node, int NewLevel, clsBaseNodeLevels BaseLevel) { if ( Node.GetChildNodeCount == 0 ) { int A = 0; float Height = 0; float Lowest = NewLevel; for ( A = 0; A <= Node.GetConnectionCount - 1; A++ ) { Height = BaseLevel.NodeLevels[Node.get_GetConnection(A).GetOtherNode(Node).GetLayer_NodeNum]; if ( Height < Lowest ) { Lowest = Height; } } if ( NewLevel - Lowest > 1.0F ) { BaseLevel.NodeLevels[Node.GetLayer_NodeNum] = Lowest + 1.0F; } else { BaseLevel.NodeLevels[Node.GetLayer_NodeNum] = NewLevel; } } else { int A = 0; for ( A = 0; A <= Node.GetChildNodeCount - 1; A++ ) { SetBaseLevel(Node.get_GetChildNode(A), NewLevel, BaseLevel); } } }
public PathfinderNode GetRandomChildNode(PathfinderNode InputNode, int MinClearance) { if ( InputNode.GetClearance < MinClearance ) { return null; } if ( InputNode.GetChildNodeCount == 0 ) { return InputNode; } else { int A = 0; do { A = Convert.ToInt32(Conversion.Int(VBMath.Rnd() * InputNode.GetChildNodeCount)); } while ( InputNode.get_GetChildNode(A).GetClearance < MinClearance ); PathfinderNode ReturnResult = GetRandomChildNode(InputNode.get_GetChildNode(A), MinClearance); return ReturnResult; } }
public clsResult GenerateRamps() { clsResult ReturnResult = new clsResult("Ramps"); int A = 0; int B = 0; int C = 0; int E = 0; double BestDist = 0; int BestNum = 0; sXY_int XY_int = new sXY_int(); clsPassageNode tmpPassageNodeA = default(clsPassageNode); clsPassageNode tmpPassageNodeB = default(clsPassageNode); double Dist = 0; //make ramps for ( A = 0; A <= ConnectionCount - 1; A++ ) { Connections[A].IsRamp = false; } PathfinderNode tmpNodeA = default(PathfinderNode); PathfinderNode tmpNodeB = default(PathfinderNode); PathfinderNode[,] PassageNodePathNodes = null; PathfinderConnection NewConnection; clsPassageNodeNework PassageNodeNetwork = MakePassageNodeNetwork(); PassageNodePathNodes = PassageNodeNetwork.PassageNodePathNodes; clsConnection[] PossibleRamps = new clsConnection[ConnectionCount]; int PossibleRampCount = 0; PathfinderNode[] GetPathStartNodes = new PathfinderNode[1]; PathfinderNetwork.PathList[] ResultPaths = null; //ramp connections whose points are too far apart bool[] ConnectionsCanRamp = new bool[ConnectionCount]; for ( B = 0; B <= ConnectionCount - 1; B++ ) { C = Math.Abs(Connections[B].PassageNodeA.Level - Connections[B].PassageNodeB.Level); if ( C == 1 ) { if ( !(Connections[B].PassageNodeA.IsOnBorder || Connections[B].PassageNodeB.IsOnBorder) && Connections[B].PassageNodeA.MirrorNum == 0 && Connections[B].PassageNodeA.Num != Connections[B].PassageNodeB.Num ) { ConnectionsCanRamp[B] = true; } else { ConnectionsCanRamp[B] = false; } } else { ConnectionsCanRamp[B] = false; } } clsNodeConnectedness Connectedness = new clsNodeConnectedness(); Connectedness.NodeConnectedness = new float[PassageNodeCount]; Connectedness.PassageNodeVisited = new bool[SymmetryBlockCount, PassageNodeCount]; Connectedness.PassageNodePathNodes = PassageNodePathNodes; Connectedness.PassageNodePathMap = PassageNodeNetwork.Network; PathfinderConnection[] tmpPathConnection = new PathfinderConnection[4]; double Value = 0; double BestDistB = 0; double BaseDist = 0; double RampDist = 0; clsUpdateNodeConnectednessArgs UpdateNodeConnectednessArgs = new clsUpdateNodeConnectednessArgs(); clsUpdateNetworkConnectednessArgs UpdateNetworkConnectednessArgs = new clsUpdateNetworkConnectednessArgs(); UpdateNodeConnectednessArgs.Args = Connectedness; UpdateNetworkConnectednessArgs.Args = Connectedness; UpdateNetworkConnectednessArgs.PassageNodeUpdated = new bool[PassageNodeCount]; UpdateNetworkConnectednessArgs.SymmetryBlockCount = SymmetryBlockCount; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { Connectedness.NodeConnectedness[A] = 0.0F; for ( B = 0; B <= PassageNodeCount - 1; B++ ) { for ( C = 0; C <= SymmetryBlockCount - 1; C++ ) { Connectedness.PassageNodeVisited[C, B] = false; } } UpdateNodeConnectednessArgs.OriginalNode = PassageNodes[0, A]; UpdateNodeConnectedness(UpdateNodeConnectednessArgs, PassageNodes[0, A]); } do { BestNum = -1; BestDist = 1.0F; //for connections that can already reach the other side BestDistB = 0.0F; //for connections that cant PossibleRampCount = 0; for ( B = 0; B <= ConnectionCount - 1; B++ ) { if ( ConnectionsCanRamp[B] && !Connections[B].IsRamp ) { if ( CheckRampAngles(Connections[B], Convert.ToDouble(80.0D * MathUtil.RadOf1Deg), Convert.ToDouble(120.0D * MathUtil.RadOf1Deg), 0.0D * MathUtil.RadOf1Deg) ) { GetPathStartNodes[0] = PassageNodePathNodes[Connections[B].PassageNodeA.MirrorNum, Connections[B].PassageNodeA.Num]; ResultPaths = PassageNodeNetwork.Network.GetPath(GetPathStartNodes, PassageNodePathNodes[Connections[B].PassageNodeB.MirrorNum, Connections[B].PassageNodeB.Num], -1, 0); BaseDist = double.MaxValue; XY_int.X = (int)((Connections[B].PassageNodeA.Pos.X + Connections[B].PassageNodeB.Pos.X) / 2.0D); XY_int.Y = (int)((Connections[B].PassageNodeA.Pos.Y + Connections[B].PassageNodeB.Pos.Y) / 2.0D); for ( E = 0; E <= TotalPlayerCount - 1; E++ ) { Dist = Convert.ToDouble((PlayerBases[E].Pos - XY_int).ToDoubles().GetMagnitude()); if ( Dist < BaseDist ) { BaseDist = Dist; } } RampDist = Math.Max(MaxDisconnectionDist * Math.Pow(RampBase, (BaseDist / 1024.0D)), 1.0F); if ( ResultPaths == null ) { Value = Connectedness.NodeConnectedness[Connections[B].PassageNodeA.Num] + Connectedness.NodeConnectedness[Connections[B].PassageNodeB.Num]; if ( double.MaxValue > BestDist ) { BestDist = double.MaxValue; BestDistB = Value; PossibleRamps[0] = Connections[B]; PossibleRampCount = 1; } else { if ( Value < BestDistB ) { BestDistB = Value; PossibleRamps[0] = Connections[B]; PossibleRampCount = 1; } else if ( Value == BestDistB ) { PossibleRamps[PossibleRampCount] = Connections[B]; PossibleRampCount++; } } } else if ( ResultPaths[0].PathCount != 1 ) { ReturnResult.ProblemAdd("Error: Invalid number of routes returned."); goto Finish; } else if ( ResultPaths[0].Paths[0].Value / RampDist > BestDist ) { BestDist = ResultPaths[0].Paths[0].Value / RampDist; PossibleRamps[0] = Connections[B]; PossibleRampCount = 1; } else if ( ResultPaths[0].Paths[0].Value / RampDist == BestDist ) { PossibleRamps[PossibleRampCount] = Connections[B]; PossibleRampCount++; } else if ( ResultPaths[0].Paths[0].Value <= RampDist ) { ConnectionsCanRamp[B] = false; } } else { ConnectionsCanRamp[B] = false; } } else { ConnectionsCanRamp[B] = false; } } if ( PossibleRampCount > 0 ) { BestNum = (int)(Conversion.Int(VBMath.Rnd() * PossibleRampCount)); PossibleRamps[BestNum].IsRamp = true; tmpPassageNodeA = PossibleRamps[BestNum].PassageNodeA; tmpPassageNodeB = PossibleRamps[BestNum].PassageNodeB; tmpNodeA = PassageNodePathNodes[tmpPassageNodeA.MirrorNum, tmpPassageNodeA.Num]; tmpNodeB = PassageNodePathNodes[tmpPassageNodeB.MirrorNum, tmpPassageNodeB.Num]; NewConnection = tmpNodeA.CreateConnection(tmpNodeB, GetNodePosDist(tmpNodeA, tmpNodeB)); for ( C = 0; C <= PossibleRamps[BestNum].ReflectionCount - 1; C++ ) { PossibleRamps[BestNum].Reflections[C].IsRamp = true; tmpPassageNodeA = PossibleRamps[BestNum].Reflections[C].PassageNodeA; tmpPassageNodeB = PossibleRamps[BestNum].Reflections[C].PassageNodeB; tmpNodeA = PassageNodePathNodes[tmpPassageNodeA.MirrorNum, tmpPassageNodeA.Num]; tmpNodeB = PassageNodePathNodes[tmpPassageNodeB.MirrorNum, tmpPassageNodeB.Num]; NewConnection = tmpNodeA.CreateConnection(tmpNodeB, GetNodePosDist(tmpNodeA, tmpNodeB)); } PassageNodeNetwork.Network.FindCalc(); for ( E = 0; E <= PassageNodeCount - 1; E++ ) { UpdateNetworkConnectednessArgs.PassageNodeUpdated[E] = false; } if ( PossibleRamps[BestNum].PassageNodeA.MirrorNum == 0 ) { UpdateNetworkConnectedness(UpdateNetworkConnectednessArgs, PossibleRamps[BestNum].PassageNodeA); } else if ( PossibleRamps[BestNum].PassageNodeB.MirrorNum == 0 ) { UpdateNetworkConnectedness(UpdateNetworkConnectednessArgs, PossibleRamps[BestNum].PassageNodeB); } else { ReturnResult.ProblemAdd("Error: Initial ramp not in area 0."); goto Finish; } } else { break; } } while ( true ); PathfinderNetwork.sFloodProximityArgs FloodArgs = new PathfinderNetwork.sFloodProximityArgs(); FloodArgs.StartNode = PassageNodeNetwork.PassageNodePathNodes[0, 0]; FloodArgs.NodeValues = PassageNodeNetwork.Network.NetworkLargeArrays.Nodes_ValuesA; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { for ( B = 0; B <= SymmetryBlockCount - 1; B++ ) { FloodArgs.NodeValues[PassageNodeNetwork.PassageNodePathNodes[B, A].Layer_NodeNum] = float.MaxValue; } } PassageNodeNetwork.Network.FloodProximity(FloodArgs); for ( A = 0; A <= PassageNodeCount - 1; A++ ) { for ( B = 0; B <= SymmetryBlockCount - 1; B++ ) { if ( !PassageNodes[B, A].IsWater ) { if ( FloodArgs.NodeValues[PassageNodeNetwork.PassageNodePathNodes[B, A].Layer_NodeNum] == float.MaxValue ) { ReturnResult.ProblemAdd("Land is unreachable. Reduce variation or retry."); goto Finish; } } } } Finish: PassageNodeNetwork.Network.Deallocate(); return ReturnResult; }
public void CheckIntegrity() { //make sure im still a good parent if ( NodeCount >= 2 ) { sVisited Visited = new sVisited(); Visited.Visited = new bool[NodeCount]; int A = 0; FloodCheckInternal(Nodes[0], ref Visited); for ( A = 0; A <= NodeCount - 1; A++ ) { if ( !Visited.Visited[A] ) { goto DisbandAndFind; } } } if ( NodeCount == 1 & ConnectionCount == 0 ) { goto DisbandAndFind; } else if ( NodeCount > 1 ) { SpanCalc(); } else if ( NodeCount == 0 ) { if ( ParentNode != null ) { PathfinderNode tmpNode = ParentNode; tmpNode.Node_Remove(ParentNode_NodeNum); tmpNode.CheckIntegrity(); } if ( Layer.Network_LayerNum > 0 ) { Deallocate(); } } return; DisbandAndFind: int B = 0; PathfinderNode[] Children = new PathfinderNode[NodeCount]; for ( B = 0; B <= NodeCount - 1; B++ ) { Children[B] = Nodes[B]; } int ChildCount = NodeCount; Disband(); for ( B = 0; B <= ChildCount - 1; B++ ) { Children[B].Layer.Network.FindParentNode_Add(Children[B]); } }
private void RemoveFromNodes() { NodeA.Connection_Remove(NodeA_ConnectionNum); NodeA = null; NodeA_ConnectionNum = -1; NodeB.Connection_Remove(NodeB_ConnectionNum); NodeB = null; NodeB_ConnectionNum = -1; }
public PathfinderNode GetOtherNode(PathfinderNode Self) { if ( NodeA == Self ) { return NodeB; } else { return NodeA; } }
public void ForceDeallocate() { DependantConnection = null; NodeA = null; NodeB = null; }
public void CalcNodePos(PathfinderNode Node, ref Position.XY_dbl Pos, ref int SampleCount) { if ( Node.GetLayer.GetNetwork_LayerNum == 0 ) { clsNodeTag NodeTag = default(clsNodeTag); NodeTag = (clsNodeTag)Node.Tag; Pos.X += NodeTag.Pos.X; Pos.Y += NodeTag.Pos.Y; } else { int A = 0; for ( A = 0; A <= Node.GetChildNodeCount - 1; A++ ) { CalcNodePos(Node.get_GetChildNode(A), ref Pos, ref SampleCount); } SampleCount += Node.GetChildNodeCount; } }
public PathfinderConnection FindConnection(PathfinderNode NodeToFind) { int A = 0; PathfinderConnection tmpConnection = default(PathfinderConnection); for ( A = 0; A <= ConnectionCount - 1; A++ ) { tmpConnection = Connections[A]; if ( tmpConnection.GetOtherNode(this) == NodeToFind ) { return tmpConnection; } } return null; }
public clsResult GenerateOil() { clsResult ReturnResult = new clsResult("Oil"); int A = 0; int B = 0; int C = 0; int D = 0; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { for ( B = 0; B <= SymmetryBlockCount - 1; B++ ) { PassageNodes[B, A].OilCount = 0; } } //store passage node route distances clsPassageNodeNework PassageNodePathMap = MakePassageNodeNetwork(); PathfinderNode[] GetPathStartNodes = new PathfinderNode[1]; PathfinderNetwork.PathList[] ResultPaths = null; PassageNodeDists = new float[SymmetryBlockCount, PassageNodeCount, SymmetryBlockCount, PassageNodeCount]; for ( A = 0; A <= PassageNodeCount - 1; A++ ) { for ( D = 0; D <= SymmetryBlockCount - 1; D++ ) { PassageNodeDists[D, A, D, A] = 0.0F; for ( B = 0; B <= PassageNodeCount - 1; B++ ) { for ( C = 0; C <= SymmetryBlockCount - 1; C++ ) { if ( PassageNodes[0, A].IsWater || PassageNodes[C, B].IsWater || (C != 0 & D != 0) ) { PassageNodeDists[D, A, C, B] = float.MaxValue; PassageNodeDists[C, B, D, A] = float.MaxValue; } else { GetPathStartNodes[0] = PassageNodePathMap.PassageNodePathNodes[D, A]; ResultPaths = PassageNodePathMap.Network.GetPath(GetPathStartNodes, PassageNodePathMap.PassageNodePathNodes[C, B], -1, 0); if ( ResultPaths == null ) { ReturnResult.ProblemAdd("Map is not all connected."); PassageNodePathMap.Network.Deallocate(); return ReturnResult; } else { if ( ResultPaths[0].PathCount != 1 ) { Debugger.Break(); } PassageNodeDists[D, A, C, B] = ResultPaths[0].Paths[0].Value; PassageNodeDists[C, B, D, A] = ResultPaths[0].Paths[0].Value; } } } } } } PassageNodePathMap.Network.Deallocate(); //place oil int PlacedExtraOilCount = 0; int MaxBestNodeCount = 0; MaxBestNodeCount = 1; for ( A = 0; A <= OilAtATime - 1; A++ ) { MaxBestNodeCount *= PassageNodeCount; } var oilArgs = new clsOilBalanceLoopArgs { OilClusterSizes = new int[OilAtATime], PlayerOilScore = new double[TopLeftPlayerCount], OilNodes = new clsPassageNode[OilAtATime] }; //balanced oil while ( PlacedExtraOilCount < ExtraOilCount ) { //place oil farthest away from other oil and where it best balances the player oil score for ( A = 0; A <= OilAtATime - 1; A++ ) { oilArgs.OilClusterSizes[A] = Math.Min(ExtraOilClusterSizeMin + (int)(Conversion.Int(VBMath.Rnd() * (ExtraOilClusterSizeMax - ExtraOilClusterSizeMin + 1))), Math.Max((int)(Math.Ceiling(Convert.ToDecimal((ExtraOilCount - PlacedExtraOilCount) / SymmetryBlockCount))), 1)); } oilArgs.OilPossibilities = new clsOilPossibilities(); OilBalanceLoop(oilArgs, 0); clsOilPossibilities.clsPossibility bestPossibility = oilArgs.OilPossibilities.BestPossibility; if ( bestPossibility != null ) { for ( B = 0; B <= OilAtATime - 1; B++ ) { for ( A = 0; A <= SymmetryBlockCount - 1; A++ ) { PassageNodes[A, bestPossibility.Nodes[B].Num].OilCount += oilArgs.OilClusterSizes[B]; } PlacedExtraOilCount += oilArgs.OilClusterSizes[B] * SymmetryBlockCount; } for ( A = 0; A <= TopLeftPlayerCount - 1; A++ ) { oilArgs.PlayerOilScore[A] += bestPossibility.PlayerOilScoreAddition[A]; } } else { ReturnResult.WarningAdd("Could not place all of the oil. " + Convert.ToString(PlacedExtraOilCount) + " oil was placed."); break; } } //base oil for ( A = 0; A <= TopLeftPlayerCount - 1; A++ ) { for ( B = 0; B <= SymmetryBlockCount - 1; B++ ) { PassageNodes[B, PlayerBases[A].Nodes[0].Num].OilCount += BaseOilCount; } } return ReturnResult; }
public void FindParent() { PathfinderNode tmpNodeA = default(PathfinderNode); float BestScore = 0; PathfinderNode BestNode = null; float Score = 0; int A = 0; bool MakeNew = default(bool); int B = 0; int Count = 0; int C = 0; bool Allow = default(bool); PathfinderConnection tmpConnection = default(PathfinderConnection); PathfinderNode DestNode = default(PathfinderNode); if ( NodeCount == 0 & Layer.Network_LayerNum > 0 ) { Debugger.Break(); return; } if ( ParentNode != null ) { Debugger.Break(); return; } BestScore = float.MaxValue; for ( A = 0; A <= ConnectionCount - 1; A++ ) { tmpConnection = Connections[A]; DestNode = tmpConnection.GetOtherNode(this); tmpNodeA = DestNode.ParentNode; if ( tmpNodeA == null ) { tmpNodeA = tmpConnection.GetOtherNode(this); Score = tmpConnection.Value * (0.98F + VBMath.Rnd() * 0.04F); if ( Score < BestScore ) { BestScore = Score; BestNode = tmpNodeA; MakeNew = true; } } else { //dont allow this to join to another when the other has 3 nodes and they only have one connection if ( tmpNodeA.NodeCount == 3 ) { Count = 0; Allow = false; for ( B = 0; B <= tmpNodeA.NodeCount - 1; B++ ) { for ( C = 0; C <= tmpNodeA.Nodes[B].ConnectionCount - 1; C++ ) { if ( tmpNodeA.Nodes[B].Connections[C].GetOtherNode(tmpNodeA.Nodes[B]) == this ) { Count++; if ( Count >= 2 ) { Allow = true; goto CountFinished; } break; } } } CountFinished: 1.GetHashCode(); //TODO: cleanup this loop } else { Allow = true; } if ( Allow ) { Score = (DestNode.SiblingSpan + tmpConnection.Value) * (0.98F + VBMath.Rnd() * 0.04F); if ( Score < BestScore ) { BestScore = Score; BestNode = tmpNodeA; MakeNew = false; } } } } if ( BestNode != null ) { if ( MakeNew ) { PathfinderLayer tmpLayer = default(PathfinderLayer); if ( Layer.ParentLayer == null ) { tmpLayer = new PathfinderLayer(Layer.Network); } else { tmpLayer = Layer.ParentLayer; } PathfinderNode NewNode = new PathfinderNode(tmpLayer); NewNode.Node_Add(this); NewNode.Node_Add(BestNode); NewNode.SpanCalc(); RaiseConnections(); BestNode.RaiseConnections(); NewNode.Layer.Network.FindParentNode_Add(NewNode); } else { if ( BestNode != null ) { BestNode.Node_Add(this); if ( BestNode.NodeCount >= 4 ) { BestNode.Split(); } else { BestNode.SpanCalc(); RaiseConnections(); if ( BestNode.ParentNode == null ) { BestNode.Layer.Network.FindParentNode_Add(BestNode); } } } } } else if ( ConnectionCount > 0 ) { //it is part of a network but there is no suitable parent to join, so make a new isolated parent PathfinderLayer tmpLayer = default(PathfinderLayer); if ( Layer.ParentLayer == null ) { tmpLayer = new PathfinderLayer(Layer.Network); } else { tmpLayer = Layer.ParentLayer; } PathfinderNode NewNode = new PathfinderNode(tmpLayer); NewNode.Node_Add(this); NewNode.SpanCalc(); RaiseConnections(); NewNode.Layer.Network.FindParentNode_Add(NewNode); } }
public float GetNodePosDist(PathfinderNode NodeA, PathfinderNode NodeB) { clsNodeTag TagA = (clsNodeTag)NodeA.Tag; clsNodeTag TagB = (clsNodeTag)NodeB.Tag; return Convert.ToSingle((TagA.Pos - TagB.Pos).ToDoubles().GetMagnitude()); }
public void FloodCheckInternal(PathfinderNode CurrentNode, ref sVisited Visited) { int A = 0; PathfinderNode tmpNode = default(PathfinderNode); PathfinderConnection tmpConnection = default(PathfinderConnection); Visited.Visited[CurrentNode.ParentNode_NodeNum] = true; for ( A = 0; A <= CurrentNode.ConnectionCount - 1; A++ ) { tmpConnection = CurrentNode.Connections[A]; tmpNode = tmpConnection.GetOtherNode(CurrentNode); if ( tmpNode.ParentNode == this ) { if ( !Visited.Visited[tmpNode.ParentNode_NodeNum] ) { FloodCheckInternal(tmpNode, ref Visited); } } } }
private PathfinderNode GetNearestNodeConnection(PathfinderNetwork Network, sXY_int Pos, int MinClearance, float MaxDistance) { int A = 0; PathfinderNode[] TravelNodes = new PathfinderNode[Network.get_GetNodeLayer(0).GetNodeCount * 10]; int TravelNodeCount = 0; float[] NodeTravelDists = new float[Network.get_GetNodeLayer(0).GetNodeCount]; int TravelNodeNum = 0; PathfinderNode CurrentNode = default(PathfinderNode); PathfinderNode OtherNode = default(PathfinderNode); PathfinderConnection tmpConnection = default(PathfinderConnection); PathfinderNode BestNode = null; float TravelDist = 0; bool Flag = default(bool); for ( A = 0; A <= Network.get_GetNodeLayer(0).GetNodeCount - 1; A++ ) { NodeTravelDists[A] = float.MaxValue; } TravelNodes[0] = GetNearestNode(Network, Pos, 1); if ( TravelNodes[0] == null ) { return null; } TravelNodeCount = 1; NodeTravelDists[TravelNodes[0].Layer_NodeNum] = 0.0F; while ( TravelNodeNum < TravelNodeCount ) { CurrentNode = TravelNodes[TravelNodeNum]; if ( CurrentNode.Clearance >= MinClearance ) { if ( BestNode == null ) { BestNode = CurrentNode; } else if ( NodeTravelDists[CurrentNode.Layer_NodeNum] < NodeTravelDists[BestNode.Layer_NodeNum] ) { BestNode = CurrentNode; } } for ( A = 0; A <= CurrentNode.GetConnectionCount - 1; A++ ) { tmpConnection = CurrentNode.get_GetConnection(A); OtherNode = tmpConnection.GetOtherNode(CurrentNode); TravelDist = NodeTravelDists[CurrentNode.Layer_NodeNum] + tmpConnection.GetValue; if ( BestNode == null ) { Flag = true; } else if ( TravelDist < NodeTravelDists[BestNode.Layer_NodeNum] ) { Flag = true; } else { Flag = false; } if ( Flag && TravelDist < NodeTravelDists[OtherNode.Layer_NodeNum] ) { NodeTravelDists[OtherNode.Layer_NodeNum] = TravelDist; TravelNodes[TravelNodeCount] = OtherNode; TravelNodeCount++; } } TravelNodeNum++; } return BestNode; }
public void ForceDeallocate() { int A = 0; for ( A = 0; A <= ConnectionCount - 1; A++ ) { Connections[A].ForceDeallocate(); } Connections = null; Nodes = null; ParentNode = null; Layer = null; }
private void SetBaseLevelRamp(clsSetBaseLevelRampArgs Args, PathfinderNode Node) { if ( Node.GetChildNodeCount == 0 ) { clsNodeTag NodeTag = (clsNodeTag)Node.Tag; sXY_int XY_int = MathUtil.PointGetClosestPosOnLine(Args.Connection.PassageNodeA.Pos, Args.Connection.PassageNodeB.Pos, NodeTag.Pos); float ConnectionLength = Convert.ToSingle((Args.Connection.PassageNodeA.Pos - Args.Connection.PassageNodeB.Pos).ToDoubles().GetMagnitude()); float Extra = ConnectionLength - Args.RampLength; float ConnectionPos = Convert.ToSingle((XY_int - Args.Connection.PassageNodeA.Pos).ToDoubles().GetMagnitude()); float RampPos = MathUtil.Clamp_sng((float)((ConnectionPos - Extra / 2.0F) / Args.RampLength), 0.0F, 1.0F); int Layer_NodeNum = Node.GetLayer_NodeNum; RampPos = (float)(1.0D - (Math.Cos(RampPos * Math.PI) + 1.0D) / 2.0D); if ( RampPos > 0.0F & RampPos < 1.0F ) { float Dist2 = Convert.ToSingle((NodeTag.Pos - XY_int).ToDoubles().GetMagnitude()); if ( Dist2 < Args.RampRadius ) { float Dist2Factor = 1.0F; //Math.Min(3.0F - 3.0F * Dist2 / 384.0F, 1.0F) 'distance fading if ( Args.BaseLevel.NodeLevels[Layer_NodeNum] == Conversion.Int(Args.BaseLevel.NodeLevels[Layer_NodeNum]) ) { Args.BaseLevel.NodeLevels[Layer_NodeNum] = Args.BaseLevel.NodeLevels[Layer_NodeNum] * (1.0F - Dist2Factor) + (Args.Connection.PassageNodeA.Level * (1.0F - RampPos) + Args.Connection.PassageNodeB.Level * RampPos) * Dist2Factor; } else { Args.BaseLevel.NodeLevels[Layer_NodeNum] = (Args.BaseLevel.NodeLevels[Layer_NodeNum] * (2.0F - Dist2Factor) + (Args.Connection.PassageNodeA.Level * (1.0F - RampPos) + Args.Connection.PassageNodeB.Level * RampPos) * Dist2Factor) / 2.0F; } } } } else { int A = 0; for ( A = 0; A <= Node.GetChildNodeCount - 1; A++ ) { SetBaseLevelRamp(Args, Node.get_GetChildNode(A)); } } }
public PathfinderConnection GetOrCreateConnection(PathfinderNode OtherNode, float Value) { PathfinderConnection tmpConnection = default(PathfinderConnection); if ( OtherNode.Layer != Layer ) { return null; } tmpConnection = FindConnection(OtherNode); if ( tmpConnection == null ) { return new PathfinderConnection(this, OtherNode, Value); } return tmpConnection; }
public bool NodeCanReachNode(PathfinderNode StartNode, PathfinderNode FinishNode) { PathfinderNode StartParent = StartNode; PathfinderNode FinishParent = FinishNode; do { if ( StartParent == FinishParent ) { return true; } StartParent = StartParent.ParentNode; if ( StartParent == null ) { return false; } FinishParent = FinishParent.ParentNode; if ( FinishParent == null ) { return false; } } while ( true ); return false; }
public void Node_Add(PathfinderNode NodeToAdd) { if ( Layer == null ) { Debugger.Break(); return; } if ( NodeToAdd.Layer.Network_LayerNum != Layer.Network_LayerNum - 1 ) { Debugger.Break(); return; } if ( NodeToAdd.ParentNode != null ) { Debugger.Break(); return; } if ( Layer_ChangedNodeNum < 0 ) { Layer.ChangedNode_Add(this); } NodeToAdd.ParentNode = this; NodeToAdd.ParentNode_NodeNum = NodeCount; Nodes[NodeCount] = NodeToAdd; NodeCount++; if ( NodeToAdd.ConnectionCount == 0 ) { Debugger.Break(); } if ( NodeToAdd.Clearance > Clearance ) { ClearanceSet(Clearance); } else { ClearanceCalc(); } }
public void FindCalc() { PathfinderNode[] ShuffledNodes = null; int ShuffledNodeCount = 0; int[] Positions = null; int PositionCount = 0; int RandNum = 0; int A = 0; while ( FindParentNodeCount > 0 ) { Positions = new int[FindParentNodeCount]; ShuffledNodeCount = FindParentNodeCount; ShuffledNodes = new PathfinderNode[ShuffledNodeCount]; for ( A = 0; A <= FindParentNodeCount - 1; A++ ) { Positions[PositionCount] = PositionCount; PositionCount++; } for ( A = 0; A <= FindParentNodeCount - 1; A++ ) { RandNum = (int)Conversion.Int(VBMath.Rnd() * PositionCount); ShuffledNodes[Positions[RandNum]] = FindParentNodes[A]; PositionCount--; if ( RandNum < PositionCount ) { Positions[RandNum] = Positions[PositionCount]; } } for ( A = 0; A <= ShuffledNodeCount - 1; A++ ) { if ( ShuffledNodes[A].Network_FindParentNum >= 0 ) { if ( ShuffledNodes[A].ParentNode == null ) { ShuffledNodes[A].FindParent(); } FindParentNode_Remove(ShuffledNodes[A].Network_FindParentNum); } } } //remove empty layers int LayerNum = NodeLayerCount - 1; do { if ( NodeLayers[LayerNum].NodeCount > 0 ) { break; } NodeLayers[LayerNum].Network_LayerNum = -1; if ( LayerNum == 0 ) { break; } NodeLayers[LayerNum - 1].ParentLayer = null; LayerNum--; } while ( true ); if ( LayerNum < NodeLayerCount - 1 ) { Array.Resize(ref NodeLayers, LayerNum + 1); NodeLayerCount = LayerNum + 1; } }
public void Split() { if ( NodeCount != 4 ) { Debugger.Break(); } float Value = 0; float BestValue = 0; PathfinderNode BestNodeA = null; PathfinderNode BestNodeB = null; PathfinderNode BestNodeC = null; PathfinderNode BestNodeD = null; int A = 0; int B = 0; PathfinderNode tmpNodeA = default(PathfinderNode); PathfinderNode tmpNodeB = default(PathfinderNode); PathfinderNode tmpNodeC = default(PathfinderNode); PathfinderNode tmpNodeD = default(PathfinderNode); PathfinderConnection tmpConnectionA = null; PathfinderConnection tmpConnectionB = null; int C = 0; int D = 0; PathfinderNode[] Children = new PathfinderNode[NodeCount]; for ( A = 0; A <= NodeCount - 1; A++ ) { Children[A] = Nodes[A]; } int ChildCount = NodeCount; PathfinderLayer ThisLayer = Layer; Disband(); BestValue = float.MaxValue; for ( A = 0; A <= ChildCount - 1; A++ ) { tmpNodeA = Children[A]; for ( B = A + 1; B <= ChildCount - 1; B++ ) { tmpNodeB = Children[B]; for ( C = 0; C <= ChildCount - 1; C++ ) { if ( Children[C] != tmpNodeA && Children[C] != tmpNodeB ) { break; } } tmpNodeC = Children[C]; for ( D = C + 1; D <= ChildCount - 1; D++ ) { if ( Children[D] != tmpNodeA && Children[D] != tmpNodeB ) { break; } } tmpNodeD = Children[D]; for ( C = 0; C <= tmpNodeA.ConnectionCount - 1; C++ ) { tmpConnectionA = tmpNodeA.Connections[C]; if ( tmpConnectionA.GetOtherNode(tmpNodeA) == tmpNodeB ) { break; } } for ( D = 0; D <= tmpNodeC.ConnectionCount - 1; D++ ) { tmpConnectionB = tmpNodeC.Connections[D]; if ( tmpConnectionB.GetOtherNode(tmpNodeC) == tmpNodeD ) { break; } } if ( C < tmpNodeA.ConnectionCount & D < tmpNodeC.ConnectionCount ) { Value = tmpConnectionA.Value + tmpConnectionB.Value; if ( Value < BestValue ) { BestValue = Value; BestNodeA = tmpNodeA; BestNodeB = tmpNodeB; BestNodeC = tmpNodeC; BestNodeD = tmpNodeD; } } } } if ( BestNodeA != null ) { if ( ParentNode != null ) { tmpNodeA = ParentNode; tmpNodeA.Node_Remove(ParentNode_NodeNum); } else { tmpNodeA = null; } if ( tmpNodeA != null ) { tmpNodeA.CheckIntegrity(); } PathfinderNode NewNodeA = new PathfinderNode(ThisLayer); PathfinderNode NewNodeB = new PathfinderNode(ThisLayer); NewNodeA.Node_Add(BestNodeA); NewNodeA.Node_Add(BestNodeB); NewNodeA.SpanCalc(); BestNodeA.RaiseConnections(); BestNodeB.RaiseConnections(); NewNodeA.Layer.Network.FindParentNode_Add(NewNodeA); NewNodeB.Node_Add(BestNodeC); NewNodeB.Node_Add(BestNodeD); NewNodeB.SpanCalc(); BestNodeC.RaiseConnections(); BestNodeD.RaiseConnections(); NewNodeB.Layer.Network.FindParentNode_Add(NewNodeB); } else { Debugger.Break(); } }
public PathList[] GetPath(PathfinderNode[] StartNodes, PathfinderNode FinishNode, int Accuracy, int MinClearance) { int StartNodeCount = StartNodes.GetUpperBound(0) + 1; PathList[] Paths = new PathList[NodeLayerCount]; PathfinderNode[,] LayerStartNodes = new PathfinderNode[NodeLayerCount, StartNodeCount]; PathfinderNode[] LayerFinishNodes = new PathfinderNode[NodeLayerCount]; int LayerNum = 0; PathfinderNode[] Destinations = new PathfinderNode[24]; int DestinationCount = 0; bool FinishIsParent = default(bool); bool IsInaccurate; int[] CalcNodeCount = new int[24]; sFloodRouteArgs FloodRouteArgs = new sFloodRouteArgs(); int FinalLayer = 0; bool[] StartCanReach = new bool[StartNodeCount]; PathfinderNode tmpNodeA = default(PathfinderNode); PathfinderNode tmpNodeB = default(PathfinderNode); int CanReachCount = 0; int FirstLayer = 0; Path[] BestPaths = new Path[24]; float[] BestValues = new float[24]; int PathNum = 0; bool StopMultiPathing = default(bool); bool[] Visit = NetworkLargeArrays.Nodes_Booleans; float[] NodeValues = NetworkLargeArrays.Nodes_ValuesA; PathfinderNode[] Nodes_Nodes = NetworkLargeArrays.Nodes_Nodes; Path StartPath = NetworkLargeArrays.Nodes_Path; int A = 0; int B = 0; int C = 0; int D = 0; int 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; int LastLayer = 0; do { LastLayer = LayerNum; LayerNum--; if ( LayerNum < FinalLayer ) { break; } else 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; IsInaccurate = 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(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 void Node_Add(PathfinderNode NewNode) { if ( Nodes.GetUpperBound(0) < NodeCount ) { Array.Resize(ref Nodes, (NodeCount + 1) * 2); } Nodes[NodeCount] = NewNode; Nodes[NodeCount].Layer_NodeNum = NodeCount; NodeCount++; }