void FloodFill(IntVector StartLocation, int IslandId, HashSet <IntVector> Visited, List <FloorIslandNode> IslandNodes, FloorChunkDB ChunkDB)
        {
            FloorChunk PreferedChunk = ChunkDB.GetChunkAt(StartLocation);

            if (!PreferedChunk.bConnectDoors)
            {
                // We don't want doors here
                return;
            }
            if (PreferedChunk == null)
            {
                return;
            }

            Queue <IntVector> Queue = new Queue <IntVector>();

            Queue.Enqueue(StartLocation);

            while (Queue.Count > 0)
            {
                IntVector Location = Queue.Dequeue();

                FloorChunk CurrentChunk = ChunkDB.GetChunkAt(Location);
                if (CurrentChunk != PreferedChunk)
                {
                    continue;
                }

                // Create a node here
                FloorIslandNode Node = new FloorIslandNode();
                Node.IslandId = IslandId;
                Node.Chunk    = CurrentChunk;
                Node.Location = Location;

                IslandNodes.Add(Node);

                // Add the neighbors to the queue
                List <IntVector> Neighbors = new List <IntVector>();
                Neighbors.Add(Location + new IntVector(-1, 0, 0));
                Neighbors.Add(Location + new IntVector(1, 0, 0));
                Neighbors.Add(Location + new IntVector(0, 0, 1));
                Neighbors.Add(Location + new IntVector(0, 0, -1));

                foreach (IntVector Neighbor in Neighbors)
                {
                    if (Visited.Contains(Neighbor))
                    {
                        continue;
                    }
                    FloorChunk NeighborChunk = ChunkDB.GetChunkAt(Neighbor);
                    if (NeighborChunk != null && NeighborChunk.Id == CurrentChunk.Id)
                    {
                        Queue.Enqueue(Neighbor);
                        Visited.Add(Neighbor);
                    }
                }
            }
        }
        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);
            }
        }