コード例 #1
0
        void ConnectIslandRecursive(int IslandId, Dictionary <int, List <FloorIslandAdjacency> > AdjacencyByIslands,
                                    HashSet <int> IslandVisited, System.Random random, FloorDoorManager DoorManager, Dictionary <int, FloorChunk> IslandToChunkMap)
        {
            if (IslandVisited.Contains(IslandId))
            {
                return;
            }
            IslandVisited.Add(IslandId);

            if (!AdjacencyByIslands.ContainsKey(IslandId))
            {
                // No adjacent islands
                return;
            }

            List <FloorIslandAdjacency> AdjacentNodes = AdjacencyByIslands[IslandId];
            HashSet <int> AdjacentIslands             = new HashSet <int>();

            foreach (FloorIslandAdjacency AdjacentNode in AdjacentNodes)
            {
                AdjacentIslands.Add(AdjacentNode.A.IslandId);
                AdjacentIslands.Add(AdjacentNode.B.IslandId);
            }
            AdjacentIslands.Remove(IslandId);
            IslandNodePriorityPredicate SortPredicate = new IslandNodePriorityPredicate(IslandToChunkMap);

            int[] AdjacentIslandArray = new List <int>(AdjacentIslands).ToArray();
            System.Array.Sort(AdjacentIslandArray, SortPredicate);

            foreach (int AdjacentIsland in AdjacentIslandArray)
            {
                if (IslandVisited.Contains(AdjacentIsland))
                {
                    continue;
                }

                // Find all the adjacent cells between these two islands
                List <FloorIslandAdjacency> EdgeNodes = new List <FloorIslandAdjacency>();
                foreach (FloorIslandAdjacency AdjacentNode in AdjacentNodes)
                {
                    if (AdjacentNode.A.IslandId == AdjacentIsland || AdjacentNode.B.IslandId == AdjacentIsland)
                    {
                        EdgeNodes.Add(AdjacentNode);
                    }
                }

                // Connect a door in any one of the edge nodes
                if (EdgeNodes.Count > 0)
                {
                    int Index = random.Next(0, EdgeNodes.Count);
                    FloorIslandAdjacency DoorEdge = EdgeNodes[Index];
                    // Create a door here
                    DoorManager.RegisterDoor(DoorEdge.A.Location, DoorEdge.B.Location);

                    // Move into this room now
                    ConnectIslandRecursive(AdjacentIsland, AdjacencyByIslands, IslandVisited, random, DoorManager, IslandToChunkMap);
                }
            }
        }
コード例 #2
0
        void CreateDoors(int y)
        {
            // Tag all islands
            // Create adjacency list
            // Do a DFS on the tagged islands and connect the islands with doors

            HashSet <IntVector>    Visited     = new HashSet <IntVector>();
            List <FloorIslandNode> IslandNodes = new List <FloorIslandNode>();
            int TotalIslands = 0;

            // Tag islands with a flood fill.  This helps if custom volume split existing
            // rooms into multiple parts and needs to be treated separately (islands)
            {
                int IslandId = 0;
                for (int x = 0; x < floorPlanConfig.BuildingSize.x; x++)
                {
                    for (int z = 0; z < floorPlanConfig.BuildingSize.z; z++)
                    {
                        IntVector Location = new IntVector(x, y, z);
                        if (!Visited.Contains(Location))
                        {
                            // Flood fill from here
                            Visited.Add(Location);
                            FloodFill(Location, IslandId, Visited, IslandNodes, ChunkDB);
                            IslandId++;
                        }
                    }
                }
                TotalIslands = IslandId;
            }

            // Create a node map for faster access
            Dictionary <IntVector, FloorIslandNode> IslandNodeByLocation = new Dictionary <IntVector, FloorIslandNode>();

            foreach (FloorIslandNode Node in IslandNodes)
            {
                if (Node.IslandId == -1)
                {
                    continue;
                }
                IslandNodeByLocation.Add(Node.Location, Node);
            }

            // Create adjacency list for each island
            List <FloorIslandAdjacency> AdjacencyList = new List <FloorIslandAdjacency>();

            for (int x = 0; x < floorPlanConfig.BuildingSize.x; x++)
            {
                for (int z = 0; z < floorPlanConfig.BuildingSize.z; z++)
                {
                    IntVector Loc00 = new IntVector(x, y, z);
                    if (!IslandNodeByLocation.ContainsKey(Loc00))
                    {
                        continue;
                    }
                    FloorIslandNode Node00 = IslandNodeByLocation[Loc00];
                    if (Node00.IslandId == -1)
                    {
                        continue;
                    }

                    // Test along the left cell
                    {
                        IntVector Loc10 = new IntVector(x + 1, y, z);
                        if (IslandNodeByLocation.ContainsKey(Loc10))
                        {
                            FloorIslandNode Node10 = IslandNodeByLocation[Loc10];
                            if (Node10.IslandId != -1 && Node00.IslandId != Node10.IslandId)
                            {
                                // Different adjacent nodes.  Add to the list
                                FloorIslandAdjacency Adjacency = new FloorIslandAdjacency();
                                Adjacency.A = Node00;
                                Adjacency.B = Node10;
                                AdjacencyList.Add(Adjacency);
                            }
                        }
                    }

                    // Test along the bottom cell
                    {
                        IntVector Loc01 = new IntVector(x, y, z + 1);
                        if (IslandNodeByLocation.ContainsKey(Loc01))
                        {
                            FloorIslandNode Node01 = IslandNodeByLocation[Loc01];
                            if (Node01.IslandId != -1 && Node00.IslandId != Node01.IslandId)
                            {
                                // Different adjacent nodes.  Add to the list
                                FloorIslandAdjacency Adjacency = new FloorIslandAdjacency();
                                Adjacency.A = Node00;
                                Adjacency.B = Node01;
                                AdjacencyList.Add(Adjacency);
                            }
                        }
                    }
                }
            }

            // Create another lookup for faster access
            Dictionary <int, List <FloorIslandAdjacency> > AdjacencyByIsland = new Dictionary <int, List <FloorIslandAdjacency> >();

            foreach (FloorIslandAdjacency Adjacency in AdjacencyList)
            {
                int IslandA = Adjacency.A.IslandId;
                int IslandB = Adjacency.B.IslandId;
                if (!AdjacencyByIsland.ContainsKey(IslandA))
                {
                    AdjacencyByIsland.Add(IslandA, new List <FloorIslandAdjacency>());
                }
                if (!AdjacencyByIsland.ContainsKey(IslandB))
                {
                    AdjacencyByIsland.Add(IslandB, new List <FloorIslandAdjacency>());
                }

                AdjacencyByIsland[IslandA].Add(Adjacency);
                AdjacencyByIsland[IslandB].Add(Adjacency);
            }

            Dictionary <int, FloorChunk> IslandToChunkMap = new Dictionary <int, FloorChunk>();

            foreach (FloorIslandNode IslandNode in IslandNodes)
            {
                if (IslandToChunkMap.ContainsKey(IslandNode.IslandId))
                {
                    continue;
                }
                IslandToChunkMap.Add(IslandNode.IslandId, IslandNode.Chunk);
            }

            // Connect the islands to the main network with doors
            HashSet <int> IslandVisited = new HashSet <int>();

            for (int IslandId = 0; IslandId < TotalIslands; IslandId++)
            {
                ConnectIslandRecursive(IslandId, AdjacencyByIsland, IslandVisited, random, DoorManager, IslandToChunkMap);
            }
        }