예제 #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 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++;
        }
예제 #3
0
        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();
        }
예제 #4
0
        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;
        }
예제 #5
0
        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++;
        }
예제 #6
0
        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));
        }
예제 #7
0
 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);
         }
     }
 }
예제 #8
0
        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;
            }
        }
예제 #9
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;
        }
예제 #10
0
        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]);
            }
        }
예제 #11
0
        private void RemoveFromNodes()
        {
            NodeA.Connection_Remove(NodeA_ConnectionNum);
            NodeA = null;
            NodeA_ConnectionNum = -1;

            NodeB.Connection_Remove(NodeB_ConnectionNum);
            NodeB = null;
            NodeB_ConnectionNum = -1;
        }
예제 #12
0
 public PathfinderNode GetOtherNode(PathfinderNode Self)
 {
     if ( NodeA == Self )
     {
         return NodeB;
     }
     else
     {
         return NodeA;
     }
 }
예제 #13
0
 public void ForceDeallocate()
 {
     DependantConnection = null;
     NodeA = null;
     NodeB = null;
 }
예제 #14
0
 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;
     }
 }
예제 #15
0
        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;
        }
예제 #16
0
        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;
        }
예제 #17
0
        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);
            }
        }
예제 #18
0
        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());
        }
예제 #19
0
        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);
                    }
                }
            }
        }
예제 #20
0
        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;
        }
예제 #21
0
        public void ForceDeallocate()
        {
            int A = 0;

            for ( A = 0; A <= ConnectionCount - 1; A++ )
            {
                Connections[A].ForceDeallocate();
            }
            Connections = null;
            Nodes = null;
            ParentNode = null;
            Layer = null;
        }
예제 #22
0
 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));
         }
     }
 }
예제 #23
0
        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;
        }
예제 #24
0
        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;
        }
예제 #25
0
        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();
            }
        }
예제 #26
0
        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;
            }
        }
예제 #27
0
        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();
            }
        }
예제 #28
0
        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;
        }
예제 #29
0
 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++;
 }