Example #1
0
		public Room Generate(Random random, Area area)
		{
			if (_roomCount >= MaxRooms)
			{
				return null;
			}

			// Don't place the room on the area's edge.
			// This will keep rooms from being adjacent to each other.
			var placeableBounds = area.Bounds.Inflate(-1);

			var width = random.Next(MinWidth, placeableBounds.Width + 1);
			var height = random.Next(MinHeight, placeableBounds.Height + 1);

			// Find a place in the area to put the room.
			while (true)
			{
				var x = random.Next(placeableBounds.Left, placeableBounds.Right - width + 1 + 1);
				var y = random.Next(placeableBounds.Top, placeableBounds.Bottom - height + 1 + 1);
				var roomBounds = new RectI(x, y, width, height);
				if (placeableBounds.Contains(roomBounds))
				{
					_roomCount++;
					return new Room(random, roomBounds);
				}
			}
		}
		private void RenderRooms(Chunk chunk, Area area, IProgress<string> progress)
		{
			if (area.Room != null)
			{
				area.Room.Render(this, chunk, _floorId, _wallId);
			}

			if (area.SubArea1 != null)
			{
				RenderRooms(chunk, area.SubArea1, progress);
			}
			if (area.SubArea2 != null)
			{
				RenderRooms(chunk, area.SubArea2, progress);
			}
		}
		private void RenderCorridors(Chunk chunk, Area area, IProgress<string> progress)
		{
			if (area.SubArea1 != null)
			{
				RenderCorridors(chunk, area.SubArea1, progress);
			}
			if (area.SubArea2 != null)
			{
				RenderCorridors(chunk, area.SubArea2, progress);
			}

			if ((area.SubArea1 != null) && (area.SubArea2 != null))
			{
				var room1 = area.SubArea1.GetConnectableRoom();
				var room2 = area.SubArea2.GetConnectableRoom();
				ConnectRooms(chunk, room1, room2, progress);
			}
		}
		private IEnumerable<Room> CollectRooms(Area area)
		{
			var rooms = new List<Room>();

			if (area.Room != null)
			{
				yield return area.Room;
			}

			if (area.SubArea1 != null)
			{
				foreach (var room in CollectRooms(area.SubArea1))
				{
					yield return room;
				}
			}
			if (area.SubArea2 != null)
			{
				foreach (var room in CollectRooms(area.SubArea2))
				{
					yield return room;
				}
			}

			yield break;
		}
		private void DecorateWithDoors(Chunk chunk, Area area, IProgress<string> progress)
		{
			// TODO: This is causing rooms to be disconnected in some cases (when rooms are adjacent).

			foreach (var room in CollectRooms(area))
			{
				// Check the room bounds places to put doors, ignoring the corners.
				// This will also make sure that doors aren't placed directly next to eachother.

				for (var row = room.Bounds.Top + 1; row <= room.Bounds.Bottom - 1; row++)
				{
					if (!room.HasWestDoor)
					{
						if (chunk[ChunkLayer.Blocking, room.Bounds.Left - 1, row] == 0)
						{
							if ((chunk[ChunkLayer.Blocking, room.Bounds.Left, row - 1] == _wallId) &&
								(chunk[ChunkLayer.Blocking, room.Bounds.Left, row + 1] == _wallId))
							{
								chunk[ChunkLayer.Blocking, room.Bounds.Left, row] = _doorId;
								room.HasWestDoor = true;
							}
						}
					}
					if (!room.HasEastDoor)
					{
						if (chunk[ChunkLayer.Blocking, room.Bounds.Right + 1, row] == 0)
						{
							if ((chunk[ChunkLayer.Blocking, room.Bounds.Right, row - 1] == _wallId) &&
								(chunk[ChunkLayer.Blocking, room.Bounds.Right, row + 1] == _wallId))
							{
								chunk[ChunkLayer.Blocking, room.Bounds.Right, row] = _doorId;
								room.HasEastDoor = true;
							}
						}
					}
				}

				for (var column = room.Bounds.Left + 1; column <= room.Bounds.Right - 1; column++)
				{
					if (!room.HasNorthDoor)
					{
						if (chunk[ChunkLayer.Blocking, column, room.Bounds.Top - 1] == 0)
						{
							if ((chunk[ChunkLayer.Blocking, column - 1, room.Bounds.Top] == _wallId) &&
								(chunk[ChunkLayer.Blocking, column + 1, room.Bounds.Top] == _wallId))
							{
								chunk[ChunkLayer.Blocking, column, room.Bounds.Top] = _doorId;
								room.HasNorthDoor = true;
							}
						}
					}
					if (!room.HasSouthDoor)
					{
						if (chunk[ChunkLayer.Blocking, column, room.Bounds.Bottom + 1] == 0)
						{
							if ((chunk[ChunkLayer.Blocking, column - 1, room.Bounds.Bottom] == _wallId) &&
								(chunk[ChunkLayer.Blocking, column + 1, room.Bounds.Bottom] == _wallId))
							{
								chunk[ChunkLayer.Blocking, column, room.Bounds.Bottom] = _doorId;
								room.HasSouthDoor = true;
							}
						}
					}
				}
			}
		}