Exemple #1
0
        public static RoomTemplateGrid2D ToOldRoomTemplate(this RoomTemplate roomTemplate)
        {
            var             doorMode    = roomTemplate.DoorsMode;
            IDoorModeGrid2D oldDoorMode = null;

            if (roomTemplate.RoomTemplateRepeatMode == null)
            {
                throw new NotSupportedException("Null repeat mode is currently not supported");
            }

            if (doorMode is SimpleDoorMode simpleDoorMode)
            {
                oldDoorMode = new SimpleDoorModeGrid2D(simpleDoorMode.DoorLength, simpleDoorMode.CornerDistance);
            }
            else if (doorMode is ManualDoorMode manualDoorMode)
            {
                oldDoorMode = new ManualDoorModeGrid2D(manualDoorMode.DoorPositions.Select(x => new DoorGrid2D(x.From, x.To)).ToList());
            }
            else
            {
                throw new ArgumentOutOfRangeException();
            }

            return(new RoomTemplateGrid2D(roomTemplate.Shape, oldDoorMode, allowedTransformations: roomTemplate.AllowedTransformations, repeatMode: roomTemplate.RoomTemplateRepeatMode, name: roomTemplate.Name));
        }
    private RoomDescriptionGrid2D GetCorridorDescription()
    {
        var corridorOutline = PolygonGrid2D.GetRectangle(4, 3);
        var corridorDoors   = new ManualDoorModeGrid2D(new List <DoorGrid2D>()
        {
            new DoorGrid2D(new Edgar.Geometry.Vector2Int(0, 1), new Edgar.Geometry.Vector2Int(0, 2)),
            new DoorGrid2D(new Edgar.Geometry.Vector2Int(4, 1), new Edgar.Geometry.Vector2Int(4, 2))
        }
                                                       );
        var corridorRoomTemplate = new RoomTemplateGrid2D(
            corridorOutline,
            corridorDoors,
            allowedTransformations: new List <TransformationGrid2D>()
        {
            TransformationGrid2D.Identity,
            TransformationGrid2D.Rotate90
        },
            name: "corridorRoomTemplate"
            );

        var corridorRoomTemplateLonger = new RoomTemplateGrid2D(
            PolygonGrid2D.GetRectangle(5, 2),
            new ManualDoorModeGrid2D(new List <DoorGrid2D>()
        {
            new DoorGrid2D(new Edgar.Geometry.Vector2Int(0, 1), new Edgar.Geometry.Vector2Int(0, 2)),
            new DoorGrid2D(new Edgar.Geometry.Vector2Int(5, 1), new Edgar.Geometry.Vector2Int(5, 2))
        }
                                     ),
            allowedTransformations: new List <TransformationGrid2D>()
        {
            TransformationGrid2D.Identity,
            TransformationGrid2D.Rotate90
        },
            name: "corridorRoomTemplateLonger"
            );

        var corridorRoomDescription = new RoomDescriptionGrid2D(
            isCorridor: true,
            roomTemplates: new List <RoomTemplateGrid2D>()
        {
            corridorRoomTemplate, corridorRoomTemplateLonger
        }
            );

        return(corridorRoomDescription);
    }
Exemple #3
0
        /// <summary>
        /// Prepare level description.
        /// </summary>
        public LevelDescriptionGrid2D <int> GetLevelDescription()
        {
            //md By default, rooms in generated levels are connected directly - there are no corridors between them. If we want to use corridors, we have to add a corridor room between all pairs of neighboring rooms.

            //md > **Note:** As of now, the whole level geometry is fixed - the generator works only with the room templates that we create at design time. That means that we have to manually create all the shapes of corridor rooms. In the future, I would like to experiment with using path-finding for corridors instead of predefined room templates.

            //md ## Corridor room description
            //md First, we create the outline for the corridor room template. The performance of the generator is the best with rather short corridors, so we will use a 2x1 rectangle:

            var corridorOutline = PolygonGrid2D.GetRectangle(2, 1);

            //md The next step is to add doors. We can no longer use the simple door mode because we want to have exactly two door positions on the opposite sides of the corridor, which is not possible with the simple mode. With the manual mode, we have to specify all the door positions manually.

            var corridorDoors = new ManualDoorModeGrid2D(new List <DoorGrid2D>()
            {
                new DoorGrid2D(new Vector2Int(0, 0), new Vector2Int(0, 1)),
                new DoorGrid2D(new Vector2Int(2, 0), new Vector2Int(2, 1))
            }
                                                         );

            //md Now we can create the corridor room template. We must not forget to allow the 90 degrees rotation because, otherwise we would not be able to connect rooms both vertically and horizontally.

            var corridorRoomTemplate = new RoomTemplateGrid2D(
                corridorOutline,
                corridorDoors,
                allowedTransformations: new List <TransformationGrid2D>()
            {
                TransformationGrid2D.Identity,
                TransformationGrid2D.Rotate90
            }
                );

            //md We can also add another corridor room template which is a little bit longer then the previous one:

            var corridorRoomTemplateLonger = new RoomTemplateGrid2D(
                PolygonGrid2D.GetRectangle(4, 1),
                new ManualDoorModeGrid2D(new List <DoorGrid2D>()
            {
                new DoorGrid2D(new Vector2Int(0, 0), new Vector2Int(0, 1)),
                new DoorGrid2D(new Vector2Int(4, 0), new Vector2Int(4, 1))
            }
                                         ),
                allowedTransformations: new List <TransformationGrid2D>()
            {
                TransformationGrid2D.Identity,
                TransformationGrid2D.Rotate90
            }
                );

            //md Below we can see a visualization of the two room templates:

            //md ![](./corridors/room_templates.png)

            //md And finally, we can create the corridor room description. We must not forget to set the `IsCorridor` flag to `true`.

            var corridorRoomDescription = new RoomDescriptionGrid2D
                                          (
                isCorridor: true,
                roomTemplates: new List <RoomTemplateGrid2D>()
            {
                corridorRoomTemplate, corridorRoomTemplateLonger
            }
                                          );

            //md ## Basic room description
            //md For non-corridor rooms, we will use three rectangular room templates - 6x6 square, 8x8 square and 6x10 rectangle. The full code is omitted for simplicity.

            var basicRoomDescription = GetBasicRoomDescription();

            //md ## Level description
            //md First, we create a level description.

            var levelDescription = new LevelDescriptionGrid2D <int>();

            //md Next, we create a graph of rooms. Instead of adding rooms and connections directly to the level description, it might be sometimes beneficial to first prepare the graph data structure itself and then go through individual rooms and connections and add them to the level description.

            var graph = new UndirectedAdjacencyListGraph <int>();

            graph.AddVerticesRange(0, 13);

            graph.AddEdge(0, 1);
            graph.AddEdge(0, 2);
            graph.AddEdge(0, 8);
            graph.AddEdge(1, 3);
            graph.AddEdge(1, 4);
            graph.AddEdge(1, 5);
            graph.AddEdge(2, 6);
            graph.AddEdge(2, 7);
            graph.AddEdge(5, 9);
            graph.AddEdge(6, 9);
            graph.AddEdge(8, 10);
            graph.AddEdge(8, 11);
            graph.AddEdge(8, 12);

            //md > **Note:** As we want to have corridors between all neighboring rooms, it is better to create the graph only with non-corridor rooms and then add corridor rooms programatically.

            //md When we have the graph ready, we can add non-corridor rooms:

            foreach (var room in graph.Vertices)
            {
                levelDescription.AddRoom(room, basicRoomDescription);
            }

            //md Before we add corridor rooms, we have to figure out how to identify them. As we use integers, probably the easiest way is to number the corridor rooms and keep track which was the last used number:

            var corridorCounter = graph.VerticesCount;

            //md Now we can add corridor rooms. For each edge of the original graph, we create a corridor room and connect it to the two non-corridor rooms:

            foreach (var connection in graph.Edges)
            {
                // We manually insert a new room between each pair of neighboring rooms in the graph
                levelDescription.AddRoom(corridorCounter, corridorRoomDescription);

                // And instead of connecting the rooms directly, we connect them to the corridor room
                levelDescription.AddConnection(connection.From, corridorCounter);
                levelDescription.AddConnection(connection.To, corridorCounter);

                corridorCounter++;
            }

            return(levelDescription);
        }