diff --git a/src/app.rs b/src/app.rs index a8fe54c..8f3b49b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -10,16 +10,16 @@ use std::thread; use crate::exporter; use crate::interact::{ - draw_grid, AddCorridorDrag, AddDoorDrag, DragState, HoverMarker, MultiDragState, - MultiResizeState, ResizeState, SelectedItem, SelectionBoxDrag, + AddCorridorDrag, AddDoorDrag, DragState, HoverMarker, MultiDragState, MultiResizeState, + ResizeState, SelectedItem, SelectionBoxDrag, draw_grid, }; use crate::layout::{ - self, populate_random_markers, populate_stairs, DoorSettings, DungeonLayout, WindowSettings, + self, DoorSettings, DungeonLayout, WindowSettings, populate_random_markers, populate_stairs, }; use crate::rendering::draw_layout; use crate::saveandload; use crate::settings; -use crate::ui::{draw_legend_panel, draw_level_tabs, draw_side_panel, AddTool, UiSettings}; +use crate::ui::{AddTool, UiSettings, draw_legend_panel, draw_level_tabs, draw_side_panel}; use eframe::egui; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -542,6 +542,15 @@ pub fn clamp_dependent_settings(settings: &mut UiSettings) { if settings.min_levels > settings.max_levels { settings.max_levels = settings.min_levels; } + if settings.min_stair_width > settings.max_stair_width { + settings.max_stair_width = settings.min_stair_width; + } + if settings.min_stair_height > settings.max_stair_height { + settings.max_stair_height = settings.min_stair_height; + } + if settings.min_stairs_per_level > settings.max_stairs_per_level { + settings.max_stairs_per_level = settings.min_stairs_per_level; + } } impl DungeonApp { diff --git a/src/layout/generation/markers.rs b/src/layout/generation/markers.rs index 48bb7bb..f217d8f 100644 --- a/src/layout/generation/markers.rs +++ b/src/layout/generation/markers.rs @@ -132,15 +132,20 @@ pub fn assign_start_end_markers(layouts: &mut Vec, settings: &UiS let placed_cell = layout.start_markers[placed_idx].cell; if let Some(pos) = available.iter().position(|&r| { let room = &layout.rooms[r]; - placed_cell.0 >= room.x && placed_cell.0 < room.x + room.width - && placed_cell.1 >= room.y && placed_cell.1 < room.y + room.height + placed_cell.0 >= room.x + && placed_cell.0 < room.x + room.width + && placed_cell.1 >= room.y + && placed_cell.1 < room.y + room.height }) { available.remove(pos); } } let room_idx = if available.is_empty() { - pick_room_index(&(0..layout.rooms.len()).collect::>(), - layout.rooms.len(), seed::derive_seed(settings.seed, 11_000 + idx as u64)) + pick_room_index( + &(0..layout.rooms.len()).collect::>(), + layout.rooms.len(), + seed::derive_seed(settings.seed, 11_000 + idx as u64), + ) } else { available[0] }; @@ -164,15 +169,20 @@ pub fn assign_start_end_markers(layouts: &mut Vec, settings: &UiS let placed_cell = layout.end_markers[placed_idx].cell; if let Some(pos) = available.iter().position(|&r| { let room = &layout.rooms[r]; - placed_cell.0 >= room.x && placed_cell.0 < room.x + room.width - && placed_cell.1 >= room.y && placed_cell.1 < room.y + room.height + placed_cell.0 >= room.x + && placed_cell.0 < room.x + room.width + && placed_cell.1 >= room.y + && placed_cell.1 < room.y + room.height }) { available.remove(pos); } } let room_idx = if available.is_empty() { - pick_room_index(&(0..layout.rooms.len()).collect::>(), - layout.rooms.len(), seed::derive_seed(settings.seed, 12_000 + idx as u64)) + pick_room_index( + &(0..layout.rooms.len()).collect::>(), + layout.rooms.len(), + seed::derive_seed(settings.seed, 12_000 + idx as u64), + ) } else { available[0] }; @@ -556,7 +566,11 @@ pub fn get_stair_count(settings: &UiSettings, gap_idx: usize) -> usize { settings.min_stairs_per_level } else { let range_seed = seed::derive_seed(settings.seed, 0x0002_A3B4_u64 + gap_idx as u64); - (range_seed as usize % (settings.max_stairs_per_level - settings.min_stairs_per_level + 1)) + (range_seed as usize + % (settings + .max_stairs_per_level + .saturating_sub(settings.min_stairs_per_level) + + 1)) + settings.min_stairs_per_level } } diff --git a/src/ui/tabs.rs b/src/ui/tabs.rs index 8a45236..957108d 100644 --- a/src/ui/tabs.rs +++ b/src/ui/tabs.rs @@ -244,34 +244,16 @@ pub fn draw_layout_tab(ui: &mut egui::Ui, settings: &mut UiSettings, result: &mu ui.label(RichText::new("Levels").strong()); ui.add_space(8.0); - ui.label("Min Levels"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.min_levels, 1..=20).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.min_levels) - .speed(1.0) - .range(1..=100), - ) - .changed(); - }); - - ui.add_space(8.0); - ui.label("Max Levels"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.max_levels, 1..=20).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.max_levels) - .speed(1.0) - .range(1..=100), - ) - .changed(); - }); + draw_min_max_slider_rows( + ui, + result, + "Min Levels", + "Max Levels", + &mut settings.min_levels, + &mut settings.max_levels, + 1..=20, + 1..=100, + ); ui.add_space(12.0); ui.separator(); @@ -294,34 +276,16 @@ pub fn draw_layout_tab(ui: &mut egui::Ui, settings: &mut UiSettings, result: &mu }); ui.add_space(8.0); - ui.label("Min Room Size"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.min_room_size, 2..=30).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.min_room_size) - .speed(1.0) - .range(2..=200), - ) - .changed(); - }); - - ui.add_space(8.0); - ui.label("Max Room Size"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.max_room_size, 2..=30).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.max_room_size) - .speed(1.0) - .range(2..=200), - ) - .changed(); - }); + draw_min_max_slider_rows( + ui, + result, + "Min Room Size", + "Max Room Size", + &mut settings.min_room_size, + &mut settings.max_room_size, + 2..=30, + 2..=200, + ); ui.add_space(8.0); result.settings_changed |= ui @@ -355,34 +319,16 @@ pub fn draw_layout_tab(ui: &mut egui::Ui, settings: &mut UiSettings, result: &mu }); ui.add_space(8.0); - ui.label("Min Corridor Width"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.min_corridor_width, 1..=10).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.min_corridor_width) - .speed(1.0) - .range(1..=50), - ) - .changed(); - }); - - ui.add_space(8.0); - ui.label("Max Corridor Width"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.max_corridor_width, 1..=10).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.max_corridor_width) - .speed(1.0) - .range(1..=50), - ) - .changed(); - }); + draw_min_max_slider_rows( + ui, + result, + "Min Corridor Width", + "Max Corridor Width", + &mut settings.min_corridor_width, + &mut settings.max_corridor_width, + 1..=10, + 1..=50, + ); ui.add_space(8.0); ui.label("Dead-End Rooms (%)"); @@ -487,34 +433,16 @@ pub fn draw_layout_tab(ui: &mut egui::Ui, settings: &mut UiSettings, result: &mu if settings.windows_enabled { ui.add_space(8.0); - ui.label("Min Window Width"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.min_window_width, 1..=5).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.min_window_width) - .speed(1.0) - .range(1..=5), - ) - .changed(); - }); - - ui.add_space(8.0); - ui.label("Max Window Width"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.max_window_width, 1..=5).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.max_window_width) - .speed(1.0) - .range(1..=5), - ) - .changed(); - }); + draw_min_max_slider_rows( + ui, + result, + "Min Window Width", + "Max Window Width", + &mut settings.min_window_width, + &mut settings.max_window_width, + 1..=5, + 1..=5, + ); ui.add_space(8.0); ui.label("Window Frequency (%)"); @@ -575,94 +503,40 @@ pub fn draw_layout_tab(ui: &mut egui::Ui, settings: &mut UiSettings, result: &mu .changed(); ui.add_space(8.0); - ui.label("Min Stair Width"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.min_stair_width, 1..=5).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.min_stair_width) - .speed(1.0) - .range(1..=10), - ) - .changed(); - }); + draw_min_max_slider_rows( + ui, + result, + "Min Stair Width", + "Max Stair Width", + &mut settings.min_stair_width, + &mut settings.max_stair_width, + 1..=5, + 1..=10, + ); ui.add_space(8.0); - ui.label("Max Stair Width"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.max_stair_width, 1..=5).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.max_stair_width) - .speed(1.0) - .range(1..=10), - ) - .changed(); - }); + draw_min_max_slider_rows( + ui, + result, + "Min Stair Height", + "Max Stair Height", + &mut settings.min_stair_height, + &mut settings.max_stair_height, + 1..=5, + 1..=10, + ); ui.add_space(8.0); - ui.label("Min Stair Height"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.min_stair_height, 1..=5).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.min_stair_height) - .speed(1.0) - .range(1..=10), - ) - .changed(); - }); - - ui.add_space(8.0); - ui.label("Max Stair Height"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.max_stair_height, 1..=5).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.max_stair_height) - .speed(1.0) - .range(1..=10), - ) - .changed(); - }); - - ui.add_space(8.0); - ui.label("Min Stairs Per Level"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.min_stairs_per_level, 0..=10).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.min_stairs_per_level) - .speed(1.0) - .range(0..=20), - ) - .changed(); - }); - - ui.add_space(8.0); - ui.label("Max Stairs Per Level"); - ui.horizontal(|ui| { - result.settings_changed |= ui - .add(egui::Slider::new(&mut settings.max_stairs_per_level, 0..=10).show_value(false)) - .changed(); - result.settings_changed |= ui - .add( - egui::DragValue::new(&mut settings.max_stairs_per_level) - .speed(1.0) - .range(0..=20), - ) - .changed(); - }); + draw_min_max_slider_rows( + ui, + result, + "Min Stairs Per Level", + "Max Stairs Per Level", + &mut settings.min_stairs_per_level, + &mut settings.max_stairs_per_level, + 0..=10, + 0..=20, + ); } // Render the Add tab controls. @@ -805,34 +679,22 @@ pub fn draw_start_and_end_tab( ) { ui.label(RichText::new("Start Markers").strong()); ui.add_space(8.0); - draw_usize_slider_row( + draw_min_max_slider_rows( ui, result, "Min Start Marker Size", - &mut settings.min_start_marker_size, - 1..=10, - 1..=10, - ); - draw_usize_slider_row( - ui, - result, "Max Start Marker Size", + &mut settings.min_start_marker_size, &mut settings.max_start_marker_size, 1..=10, 1..=10, ); - draw_usize_slider_row( + draw_min_max_slider_rows( ui, result, "Min Start Marker Count", - &mut settings.min_start_marker_count, - 1..=20, - 1..=100, - ); - draw_usize_slider_row( - ui, - result, "Max Start Marker Count", + &mut settings.min_start_marker_count, &mut settings.max_start_marker_count, 1..=20, 1..=100, @@ -843,34 +705,22 @@ pub fn draw_start_and_end_tab( ui.add_space(8.0); ui.label(RichText::new("End Markers").strong()); ui.add_space(8.0); - draw_usize_slider_row( + draw_min_max_slider_rows( ui, result, "Min End Marker Size", - &mut settings.min_end_marker_size, - 1..=10, - 1..=10, - ); - draw_usize_slider_row( - ui, - result, "Max End Marker Size", + &mut settings.min_end_marker_size, &mut settings.max_end_marker_size, 1..=10, 1..=10, ); - draw_usize_slider_row( + draw_min_max_slider_rows( ui, result, "Min End Marker Count", - &mut settings.min_end_marker_count, - 1..=20, - 1..=100, - ); - draw_usize_slider_row( - ui, - result, "Max End Marker Count", + &mut settings.min_end_marker_count, &mut settings.max_end_marker_count, 1..=20, 1..=100, @@ -896,18 +746,12 @@ pub fn draw_monsters_and_traps_tab( 0..=100, 0..=100, ); - draw_usize_slider_row( + draw_min_max_slider_rows( ui, result, "Min Traps Per Room/Corridor", - &mut settings.min_traps_per_area, - 0..=20, - 0..=100, - ); - draw_usize_slider_row( - ui, - result, "Max Traps Per Room/Corridor", + &mut settings.min_traps_per_area, &mut settings.max_traps_per_area, 0..=20, 0..=100, @@ -926,24 +770,17 @@ pub fn draw_monsters_and_traps_tab( 0..=100, 0..=100, ); - draw_usize_slider_row( + draw_min_max_slider_rows( ui, result, "Min Monsters Per Room/Corridor", - &mut settings.min_monsters_per_area, - 0..=20, - 0..=100, - ); - draw_usize_slider_row( - ui, - result, "Max Monsters Per Room/Corridor", + &mut settings.min_monsters_per_area, &mut settings.max_monsters_per_area, 0..=20, 0..=100, ); } - // Draws usize slider row. pub fn draw_usize_slider_row( ui: &mut egui::Ui, @@ -952,15 +789,56 @@ pub fn draw_usize_slider_row( value: &mut usize, slider_range: std::ops::RangeInclusive, drag_range: std::ops::RangeInclusive, -) { +) -> bool { + let mut changed = false; ui.label(label); ui.horizontal(|ui| { - result.settings_changed |= ui + if ui .add(egui::Slider::new(value, slider_range).show_value(false)) - .changed(); - result.settings_changed |= ui + .changed() + { + changed = true; + } + if ui .add(egui::DragValue::new(value).speed(1.0).range(drag_range)) - .changed(); + .changed() + { + changed = true; + } }); - ui.add_space(6.0); + result.settings_changed |= changed; + changed +} + +// Draws min/max usize slider rows. +pub fn draw_min_max_slider_rows( + ui: &mut egui::Ui, + result: &mut SidePanelResult, + label_min: &str, + label_max: &str, + min_value: &mut usize, + max_value: &mut usize, + slider_range: std::ops::RangeInclusive, + drag_range: std::ops::RangeInclusive, +) { + if draw_usize_slider_row( + ui, + result, + label_min, + min_value, + slider_range.clone(), + drag_range.clone(), + ) { + if *min_value > *max_value { + *max_value = *min_value; + } + } + + ui.add_space(8.0); + + if draw_usize_slider_row(ui, result, label_max, max_value, slider_range, drag_range) { + if *max_value < *min_value { + *min_value = *max_value; + } + } }