diff --git a/src/layout.rs b/src/layout.rs index 88aacda..7230d66 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -31,19 +31,39 @@ pub fn generate_layout( rows: usize, target_room_count: usize, seed: u64, + min_room_size: usize, + max_room_size: usize, + square_rooms_only: bool, ) -> DungeonLayout { let mut rng = SimpleRng::new(seed ^ ((cols as u64) << 32) ^ rows as u64); let mut rooms = Vec::new(); let mut corridors = Vec::new(); let mut occupied_corridor_cells = HashSet::new(); - let min_room_size = 2; - if cols < min_room_size || rows < min_room_size || target_room_count == 0 { + if cols < 2 || rows < 2 || target_room_count == 0 { + return DungeonLayout { rooms, corridors }; + } + + let mut min_size = min_room_size.max(2); + let mut max_size = max_room_size.max(min_size); + + if square_rooms_only { + let hard_max = cols.min(rows); + if min_size > hard_max { + min_size = hard_max; + } + if max_size > hard_max { + max_size = hard_max; + } + } else { + min_size = min_size.min(cols.min(rows)); + max_size = max_size.min(cols.max(rows)); + } + + if min_size == 0 || max_size < min_size { return DungeonLayout { rooms, corridors }; } - let max_room_width = (cols / 3).clamp(min_room_size, cols.min(12)); - let max_room_height = (rows / 3).clamp(min_room_size, rows.min(12)); let max_attempts = target_room_count.saturating_mul(40).max(50); for _ in 0..max_attempts { @@ -51,8 +71,26 @@ pub fn generate_layout( break; } - let width = rng.range_inclusive(min_room_size, max_room_width); - let height = rng.range_inclusive(min_room_size, max_room_height); + let width; + let height; + + if square_rooms_only { + let side = rng.range_inclusive(min_size, max_size.min(cols.min(rows))); + width = side; + height = side; + } else { + let width_max = max_size.min(cols); + let height_max = max_size.min(rows); + if min_size > width_max || min_size > height_max { + continue; + } + width = rng.range_inclusive(min_size, width_max); + height = rng.range_inclusive(min_size, height_max); + } + + if width > cols || height > rows { + continue; + } let x = rng.range_inclusive(0, cols - width); let y = rng.range_inclusive(0, rows - height); diff --git a/src/main.rs b/src/main.rs index 2a4a29e..703de49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,9 @@ struct DungeonApp { cols: usize, rows: usize, room_count: usize, + min_room_size: usize, + max_room_size: usize, + square_rooms_only: bool, seed: u64, layout: DungeonLayout, } @@ -27,13 +30,27 @@ impl Default for DungeonApp { let cols = 24; let rows = 18; let room_count = 8; + let min_room_size = 2; + let max_room_size = 6; + let square_rooms_only = false; let seed = 1; - let layout = generate_layout(cols, rows, room_count, seed); + let layout = generate_layout( + cols, + rows, + room_count, + seed, + min_room_size, + max_room_size, + square_rooms_only, + ); Self { cols, rows, room_count, + min_room_size, + max_room_size, + square_rooms_only, seed, layout, } @@ -99,15 +116,70 @@ impl eframe::App for DungeonApp { .changed(); }); + ui.add_space(8.0); + ui.label("Min Room Size"); + ui.horizontal(|ui| { + settings_changed |= ui + .add(egui::Slider::new(&mut self.min_room_size, 2..=30).show_value(false)) + .changed(); + settings_changed |= ui + .add( + egui::DragValue::new(&mut self.min_room_size) + .speed(1.0) + .range(2..=200), + ) + .changed(); + }); + + ui.add_space(8.0); + ui.label("Max Room Size"); + ui.horizontal(|ui| { + settings_changed |= ui + .add(egui::Slider::new(&mut self.max_room_size, 2..=30).show_value(false)) + .changed(); + settings_changed |= ui + .add( + egui::DragValue::new(&mut self.max_room_size) + .speed(1.0) + .range(2..=200), + ) + .changed(); + }); + + ui.add_space(8.0); + settings_changed |= ui + .checkbox(&mut self.square_rooms_only, "Square Rooms Only") + .changed(); + ui.add_space(10.0); if ui.button("Generate New Layout").clicked() { self.seed = self.seed.wrapping_add(1); - self.layout = generate_layout(self.cols, self.rows, self.room_count, self.seed); + self.layout = generate_layout( + self.cols, + self.rows, + self.room_count, + self.seed, + self.min_room_size, + self.max_room_size, + self.square_rooms_only, + ); } }); + if self.min_room_size > self.max_room_size { + self.max_room_size = self.min_room_size; + } + if settings_changed { - self.layout = generate_layout(self.cols, self.rows, self.room_count, self.seed); + self.layout = generate_layout( + self.cols, + self.rows, + self.room_count, + self.seed, + self.min_room_size, + self.max_room_size, + self.square_rooms_only, + ); } egui::CentralPanel::default().show(ctx, |ui| {