예제 #1
0
        protected override void CreateMap()
        {
            // Maintain a list of points bordering the current list of rooms so we can attach
            // more rooms. Also track of the facing of the wall the point comes from.
            IList <int> openPoints = new List <int>();

            // Also keep track of the rooms and where they are.
            IList <Room> initialRooms = new List <Room>();

            int[,] occupied = new int[Width, Height];

            // Set up the initial placement of the map. Include special features, if any.
            int          counter  = InitialPlacement(initialRooms, openPoints, ref occupied);
            IList <Room> allRooms = new List <Room>(initialRooms);

            while (openPoints.Count > 0)
            {
                // Choose a random point to create a room around;
                int index  = openPoints[Rand.Next(openPoints.Count)];
                int availX = index % Width;
                int availY = index / Width;

                // Fit a room around the point as best as possible. AdjustRoom should avoid most
                // collisions between rooms.
                int  width  = (int)Rand.NextGamma(_ALPHA, _BETA);
                int  height = (int)Rand.NextGamma(_ALPHA, _BETA);
                Room room   = AdjustRoom(availX, availY, width, height, occupied);

                // Update the room list, the open point list, and the location grid.
                RemoveOpenPoints(room, openPoints);
                if (TrackRoom(room, allRooms, counter + 1, ref occupied))
                {
                    counter++;
                }

                AddOpenPoints(room, openPoints, occupied);
            }

            // Use the largest areas as rooms and triangulate them to calculate hallways.
            RoomList = allRooms
                       .OrderByDescending(r => r.Area)
                       .Take((int)(allRooms.Count * _FILL_PERCENT))
                       .ToList();

            // Ensure that prefab elements are included
            foreach (Room initial in initialRooms)
            {
                if (!RoomList.Contains(initial))
                {
                    RoomList.Add(initial);
                }
            }

            // If we don't get enough rooms, we can't (and don't need to) triangulate, so just
            // draw in what we have.
            if (RoomList.Count == 1)
            {
                CreateRoomWithoutBorder(RoomList[0]);
            }
            else if (RoomList.Count == 2)
            {
                // Add the only hallway to the hall list
                Adjacency = new ICollection <int>[] { new[] { 1 }, new[] { 0 } };
                ClearRoomsBetween(RoomList[0], RoomList[1], allRooms, occupied);
            }
            else
            {
                var polygon = new Polygon();
                foreach (Room room in RoomList)
                {
                    polygon.Add(new Vertex(room.Center.X, room.Center.Y));
                }
                IMesh delaunay = polygon.Triangulate();

                // Reduce the number of edges and clear out rooms along the remaining edges.
                ICollection <int>[] adj = BuildAdjacencyList(delaunay.Edges, RoomList.Count);
                var edges = TrimEdges(adj, RoomList).ToList();

                // Restore some edges, so exploring is a bit more interesting
                RestoreEdges(edges, delaunay.Edges.ToList(), adj, _END_TYPE);
                Adjacency = BuildAdjacencyList(edges, RoomList.Count);

                foreach (Edge edge in edges)
                {
                    ClearRoomsBetween(RoomList[edge.P0], RoomList[edge.P1], allRooms, occupied);
                }
            }

            PostProcess();
        }