made corredors easier to move
This commit is contained in:
@@ -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}");
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
+1
-92
@@ -82,101 +82,10 @@ 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) {
|
||||
for cell in corridor.cells(cols, rows, &room_cells) {
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user