예제 #1
0
    public GenRoom GetOtherRoom(GenRoomConnection connection)
    {
        GenConnection con = connection.connection;

        Debug.Assert(con.a != null && con.b != null, $"The room {GetHashCode()} is connected to a null room");
        GenRoom result = con.a;

        if (con.a == this)
        {
            result = con.b;
            Debug.Assert(con.b != this, $"The connection is self looping to the room: {GetHashCode()}");
        }
        else
        {
            Debug.Assert(con.b == this, $"The connection doesn't belong to the room: {GetHashCode()}");
        }
        return(result);
    }
예제 #2
0
    public static bool GenerateLayout(LevelGenerator generator, uint generationIndex)
    {
        Queue <GenRoom> rooms    = new Queue <GenRoom>(4);
        List <GenRoom>  genRooms = new List <GenRoom>(12);

        rooms.Enqueue(generator.firstRoom);
        while (rooms.Count > 0)
        {
            GenRoom room = rooms.Dequeue();
            if (room.generationIndex != generationIndex)
            {
                GenRoom firstGeneratedPrevRoom = null;
                int     connectionCount        = 0;
                for (GenRoomConnection connection = room.firstConnection; connection != null; connection = connection.next, connectionCount++)
                {
                    GenRoom otherRoom = room.GetOtherRoom(connection);
                    if (otherRoom.generationIndex != generationIndex)
                    {
                        rooms.Enqueue(otherRoom);
                    }
                    else if (firstGeneratedPrevRoom == null)
                    {
                        firstGeneratedPrevRoom = otherRoom;
                    }
                }

                GenRoomInfo roomInfo = generator.collection.GetRandomRoom(room.type);
                Debug.Assert(roomInfo.doors.Count >= connectionCount);
                // TODO: GetRandomRoom based on connectionCount

                if (firstGeneratedPrevRoom != null)
                {
                    List <GenRoom> connectedRooms = new List <GenRoom>(1)
                    {
                        firstGeneratedPrevRoom
                    };
                    List <Vector2Int> positions = GetUnconnectedPositions(firstGeneratedPrevRoom, roomInfo);
                    int positionCount           = positions.Count;

                    for (GenRoomConnection connection = room.firstConnection; connection != null; connection = connection.next)
                    {
                        GenRoom otherRoom = room.GetOtherRoom(connection);
                        if (otherRoom.generationIndex == generationIndex && otherRoom != firstGeneratedPrevRoom)
                        {
                            connectedRooms.Add(otherRoom);
                            List <Vector2Int> otherPositions = GetUnconnectedPositions(otherRoom, roomInfo);

                            for (int i = positions.Count - 1; i >= 0; --i)
                            {
                                if (!otherPositions.Contains(positions[i]))
                                {
                                    positions.RemoveAt(i);
                                }
                            }

                            if (positions.Count == 0)
                            {
                                Debug.Log($"FAILED: Couldn't find any connected positions for the room: {room.name} from the {positionCount} started positions!");
                                return(false);
                            }
                        }
                    }

                    RemoveCollidedPositions(genRooms, connectedRooms, positions, roomInfo.size);
                    if (positions.Count == 0)
                    {
                        if (positionCount == 0)
                        {
                            Debug.Log($"FAILED: Couldn't find any started positions for the room: {room.name} from the previous room: {firstGeneratedPrevRoom.name}");
                        }
                        else
                        {
                            Debug.Log($"FAILED: Couldn't find any uncollided positions  for the room: {room.name} from the {positionCount} started positions!");
                        }
                        return(false);
                    }

                    Vector2Int randomPos = positions.RandomElement();
                    InitGenRoom(genRooms, room, roomInfo, randomPos, generationIndex);
                    for (GenRoomConnection connection = room.firstConnection; connection != null; connection = connection.next)
                    {
                        GenRoom otherRoom = room.GetOtherRoom(connection);
                        if (otherRoom.generationIndex == generationIndex)
                        {
                            RectInt door = GetUnconnectedMatchDoors(room, otherRoom).RandomElement();
                            connection.connection.rect = door;
                            Debug.Assert(room.unconnectedDoors.Remove(new RectInt(door.position - room.rect.position, door.size)));
                            Debug.Assert(otherRoom.unconnectedDoors.Remove(new RectInt(door.position - otherRoom.rect.position, door.size)));
                        }
                    }
                }
                else
                {
                    InitGenRoom(genRooms, room, roomInfo, Vector2Int.zero, generationIndex);
                }
            }
        }

        return(true);