예제 #1
0
        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();
        }
예제 #2
0
        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;
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
 public void UnlinkParentDependants()
 {
     if ( DependantConnection != null )
     {
         PathfinderConnection tmpConnection = DependantConnection;
         DependantConnection = null;
         tmpConnection.LinkDecrease();
     }
 }
예제 #5
0
        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();
                    }
                }
            }
        }
예제 #6
0
 public void ForceDeallocate()
 {
     DependantConnection = null;
     NodeA = null;
     NodeB = null;
 }
예제 #7
0
 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++;
 }