static void InitGenRoom(List <GenRoom> genRooms, GenRoom room, GenRoomInfo info, Vector2Int pos, uint generationIndex) { room.info = info; room.rect = new RectInt(pos, info.size); room.unconnectedDoors = new List <RectInt>(info.doors); room.generationIndex = generationIndex; genRooms.Add(room); }
static List <Vector2Int> GetUnconnectedPositions(GenRoom room, GenRoomInfo roomInfo) { List <Vector2Int> result = new List <Vector2Int>(); foreach (RectInt unconnectedDoor in room.unconnectedDoors) { foreach (RectInt door in roomInfo.doors) { if ((door.size == unconnectedDoor.size) && (roomInfo.size - door.position != room.rect.size - unconnectedDoor.position)) { result.Add(unconnectedDoor.position + room.rect.position - door.position); } } } return(result); }
public void AddEdgarRooms(RoomType type, params Edgar.Unity.RoomTemplateSettings[] rooms) { Debug.Assert(!roomTypes.ContainsKey(type), $"The type: {type} has already been added"); roomTypes[type] = new RangedInt(this.rooms.Count, this.rooms.Count + rooms.Length - 1); foreach (var room in rooms) { var rect = room.GetOutline().BoundingRectangle; var doors = room.GetComponent <Edgar.Unity.Doors>(); GenRoomInfo info = new GenRoomInfo(rect.Width + 1, rect.Height + 1, doors.DoorsList.Count, room.name, room.gameObject); foreach (var door in doors.DoorsList) { Debug.Assert(rect.A.X < rect.B.X && rect.A.Y < rect.B.Y, $"({rect.A}, {rect.B})"); // A is always min and B is always max Vector2Int pos = door.From.ToVector3Int().ToVector2Int(); pos.x -= rect.A.X; pos.y -= rect.A.Y; // NOTE: The door.To isn't neccessary greater than the door.From and they might be negative Vector2Int size = MathUtils.Abs((door.To - door.From).ToVector3Int().ToVector2Int()) + Vector2Int.one; info.doors.Add(new RectInt(pos, size)); } this.rooms.Add(info); } }
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);