fixed crash caused by minimums falling below maximums

This commit is contained in:
grimsace
2026-06-02 11:39:28 -05:00
parent 19161648d7
commit 81ba54ba4d
3 changed files with 165 additions and 264 deletions
+13 -4
View File
@@ -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 {
+23 -9
View File
@@ -132,15 +132,20 @@ pub fn assign_start_end_markers(layouts: &mut Vec<DungeonLayout>, 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::<Vec<_>>(),
layout.rooms.len(), seed::derive_seed(settings.seed, 11_000 + idx as u64))
pick_room_index(
&(0..layout.rooms.len()).collect::<Vec<_>>(),
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<DungeonLayout>, 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::<Vec<_>>(),
layout.rooms.len(), seed::derive_seed(settings.seed, 12_000 + idx as u64))
pick_room_index(
&(0..layout.rooms.len()).collect::<Vec<_>>(),
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
}
}
+129 -251
View File
@@ -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<usize>,
drag_range: std::ops::RangeInclusive<usize>,
) {
) -> 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<usize>,
drag_range: std::ops::RangeInclusive<usize>,
) {
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;
}
}
}