made corredors easier to move

This commit is contained in:
grimsace
2026-05-21 10:20:43 -05:00
parent 336a91fbe9
commit 66f35a0f7a
4 changed files with 130 additions and 97 deletions
+1
View File
@@ -96,6 +96,7 @@ impl Default for DungeonApp {
impl Drop for DungeonApp { impl Drop for DungeonApp {
// Cleans up background resources when the app is dropped. // Cleans up background resources when the app is dropped.
fn drop(&mut self) { fn drop(&mut self) {
self.settings.overlay_level_index = None;
if let Err(err) = settings::save_settings(&self.settings) { if let Err(err) = settings::save_settings(&self.settings) {
eprintln!("Failed to save settings: {err}"); eprintln!("Failed to save settings: {err}");
} }
+14 -4
View File
@@ -374,10 +374,20 @@ pub fn corridor_drag_at_pointer(
} }
let layout = &app.levels[app.settings.active_level_index]; let layout = &app.levels[app.settings.active_level_index];
let corridor_index = layout let mut room_cells = std::collections::HashSet::new();
.corridors for room in &layout.rooms {
.iter() for x in room.x..(room.x + room.width) {
.position(|corridor| corridor.path.contains(&clicked))?; for y in room.y..(room.y + room.height) {
room_cells.insert((x, y));
}
}
}
let corridor_index = layout.corridors.iter().position(|corridor| {
corridor
.cells(app.settings.cols, app.settings.rows, &room_cells)
.contains(&clicked)
})?;
Some(CorridorDragState { Some(CorridorDragState {
corridor_index, corridor_index,
+113
View File
@@ -31,6 +31,119 @@ pub struct Corridor {
pub width: usize, pub width: usize,
} }
impl Corridor {
// Return all cells belonging to this corridor given the grid size and room cells to exclude.
pub fn cells(
&self,
cols: usize,
rows: usize,
room_cells: &std::collections::HashSet<(usize, usize)>,
) -> std::collections::HashSet<(usize, usize)> {
let mut cells = std::collections::HashSet::new();
if cols == 0 || rows == 0 {
return cells;
}
let width = self.width.max(1);
let min_offset = -((width as isize - 1) / 2);
let max_offset = width as isize / 2;
if self.path.len() == 1 {
let (x, y) = self.path[0];
for dy in min_offset..=max_offset {
let ny = y as isize + dy;
if ny < 0 || ny >= rows as isize {
continue;
}
let cell = (x, ny as usize);
if !room_cells.contains(&cell) {
cells.insert(cell);
}
}
return cells;
}
for pair in self.path.windows(2) {
let a = pair[0];
let b = pair[1];
if a == b {
continue;
}
if a.0 != b.0 {
let x0 = a.0.min(b.0);
let x1 = a.0.max(b.0);
let y = a.1 as isize;
for x in x0..=x1 {
for dy in min_offset..=max_offset {
let ny = y + dy;
if ny < 0 || ny >= rows as isize {
continue;
}
let cell = (x, ny as usize);
if !room_cells.contains(&cell) {
cells.insert(cell);
}
}
}
} else {
let y0 = a.1.min(b.1);
let y1 = a.1.max(b.1);
let x = a.0 as isize;
for y in y0..=y1 {
for dx in min_offset..=max_offset {
let nx = x + dx;
if nx < 0 || nx >= cols as isize {
continue;
}
let cell = (nx as usize, y);
if !room_cells.contains(&cell) {
cells.insert(cell);
}
}
}
}
}
for turn in self.path.windows(3) {
let prev = turn[0];
let corner = turn[1];
let next = turn[2];
let incoming = (
corner.0 as isize - prev.0 as isize,
corner.1 as isize - prev.1 as isize,
);
let outgoing = (
next.0 as isize - corner.0 as isize,
next.1 as isize - corner.1 as isize,
);
if incoming == outgoing {
continue;
}
for dx in min_offset..=max_offset {
let nx = corner.0 as isize + dx;
if nx < 0 || nx >= cols as isize {
continue;
}
for dy in min_offset..=max_offset {
let ny = corner.1 as isize + dy;
if ny < 0 || ny >= rows as isize {
continue;
}
let cell = (nx as usize, ny as usize);
if !room_cells.contains(&cell) {
cells.insert(cell);
}
}
}
}
cells
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Door { pub struct Door {
pub from: (usize, usize), pub from: (usize, usize),
+1 -92
View File
@@ -82,101 +82,10 @@ pub fn corridor_cells(layout: &DungeonLayout, cols: usize, rows: usize) -> HashS
} }
for corridor in &layout.corridors { for corridor in &layout.corridors {
let width = corridor.width.max(1); for cell in corridor.cells(cols, rows, &room_cells) {
let min_offset = -((width as isize - 1) / 2);
let max_offset = width as isize / 2;
if corridor.path.len() == 1 {
let (x, y) = corridor.path[0];
for dy in min_offset..=max_offset {
let ny = y as isize + dy;
if ny < 0 || ny >= rows as isize {
continue;
}
let cell = (x, ny as usize);
if !room_cells.contains(&cell) {
cells.insert(cell); cells.insert(cell);
} }
} }
continue;
}
for pair in corridor.path.windows(2) {
let a = pair[0];
let b = pair[1];
if a == b {
continue;
}
if a.0 != b.0 {
let x0 = a.0.min(b.0);
let x1 = a.0.max(b.0);
let y = a.1 as isize;
for x in x0..=x1 {
for dy in min_offset..=max_offset {
let ny = y + dy;
if ny < 0 || ny >= rows as isize {
continue;
}
let cell = (x, ny as usize);
if !room_cells.contains(&cell) {
cells.insert(cell);
}
}
}
} else {
let y0 = a.1.min(b.1);
let y1 = a.1.max(b.1);
let x = a.0 as isize;
for y in y0..=y1 {
for dx in min_offset..=max_offset {
let nx = x + dx;
if nx < 0 || nx >= cols as isize {
continue;
}
let cell = (nx as usize, y);
if !room_cells.contains(&cell) {
cells.insert(cell);
}
}
}
}
}
for turn in corridor.path.windows(3) {
let prev = turn[0];
let corner = turn[1];
let next = turn[2];
let incoming = (
corner.0 as isize - prev.0 as isize,
corner.1 as isize - prev.1 as isize,
);
let outgoing = (
next.0 as isize - corner.0 as isize,
next.1 as isize - corner.1 as isize,
);
if incoming == outgoing {
continue;
}
for dx in min_offset..=max_offset {
let nx = corner.0 as isize + dx;
if nx < 0 || nx >= cols as isize {
continue;
}
for dy in min_offset..=max_offset {
let ny = corner.1 as isize + dy;
if ny < 0 || ny >= rows as isize {
continue;
}
let cell = (nx as usize, ny as usize);
if !room_cells.contains(&cell) {
cells.insert(cell);
}
}
}
}
}
cells cells
} }