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 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 Connection_Add(PathfinderConnection Connection, ref int OutputNum) { OutputNum = ConnectionCount; if ( Connections.GetUpperBound(0) < ConnectionCount ) { Array.Resize(ref Connections, ConnectionCount * 2 + 1 + 1); } Connections[ConnectionCount] = Connection; ConnectionCount++; if ( ParentNode == null ) { Layer.Network.FindParentNode_Add(this); } }
public void UnlinkParentDependants() { if ( DependantConnection != null ) { PathfinderConnection tmpConnection = DependantConnection; DependantConnection = null; tmpConnection.LinkDecrease(); } }
public void RaiseDependant() { PathfinderConnection tmpConnectionA = default(PathfinderConnection); if ( DependantConnection != null ) { return; } if ( NodeA.ParentNode != NodeB.ParentNode ) { if ( NodeA.ParentNode != null && NodeB.ParentNode != null ) { tmpConnectionA = NodeA.ParentNode.FindConnection(NodeB.ParentNode); if ( tmpConnectionA == null ) { DependantConnection = new PathfinderConnection(this); DependantConnection.LinkIncrease(); DependantConnection.RaiseDependant(); } else { DependantConnection = tmpConnectionA; DependantConnection.LinkIncrease(); } } } }
public void ForceDeallocate() { DependantConnection = null; NodeA = null; NodeB = null; }
public void Connection_Add(PathfinderConnection NewConnection) { if ( Connections.GetUpperBound(0) < ConnectionCount ) { Array.Resize(ref Connections, (ConnectionCount + 1) * 2); } Connections[ConnectionCount] = NewConnection; Connections[ConnectionCount].Layer_ConnectionNum = ConnectionCount; ConnectionCount++; }