From 66f35a0f7a2aaecd6cff378d35f248354d36d9ad Mon Sep 17 00:00:00 2001 From: grimsace Date: Thu, 21 May 2026 10:20:43 -0500 Subject: [PATCH] made corredors easier to move --- src/app.rs | 1 + src/interact/hit_test.rs | 18 +++++-- src/layout/types.rs | 113 +++++++++++++++++++++++++++++++++++++++ src/layout/utils.rs | 95 +------------------------------- 4 files changed, 130 insertions(+), 97 deletions(-) diff --git a/src/app.rs b/src/app.rs index eb4b29b..6cea5a1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -96,6 +96,7 @@ impl Default for DungeonApp { impl Drop for DungeonApp { // Cleans up background resources when the app is dropped. fn drop(&mut self) { + self.settings.overlay_level_index = None; if let Err(err) = settings::save_settings(&self.settings) { eprintln!("Failed to save settings: {err}"); } diff --git a/src/interact/hit_test.rs b/src/interact/hit_test.rs index 5df0ea7..4ff4e7f 100644 --- a/src/interact/hit_test.rs +++ b/src/interact/hit_test.rs @@ -374,10 +374,20 @@ pub fn corridor_drag_at_pointer( } let layout = &app.levels[app.settings.active_level_index]; - let corridor_index = layout - .corridors - .iter() - .position(|corridor| corridor.path.contains(&clicked))?; + let mut room_cells = std::collections::HashSet::new(); + for room in &layout.rooms { + for x in room.x..(room.x + room.width) { + 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 { corridor_index, diff --git a/src/layout/types.rs b/src/layout/types.rs index ab4b940..ac8d8ee 100644 --- a/src/layout/types.rs +++ b/src/layout/types.rs @@ -31,6 +31,119 @@ pub struct Corridor { 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)] pub struct Door { pub from: (usize, usize), diff --git a/src/layout/utils.rs b/src/layout/utils.rs index 7e0693e..e5cdf0a 100644 --- a/src/layout/utils.rs +++ b/src/layout/utils.rs @@ -82,99 +82,8 @@ pub fn corridor_cells(layout: &DungeonLayout, cols: usize, rows: usize) -> HashS } for corridor in &layout.corridors { - let width = corridor.width.max(1); - 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); - } - } - 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); - } - } - } + for cell in corridor.cells(cols, rows, &room_cells) { + cells.insert(cell); } }