added secret doors
This commit is contained in:
+25
-6
@@ -16,6 +16,7 @@ const CORRIDOR: (u8, u8, u8, u8) = (210, 190, 120, 255);
|
||||
const BLACK: (u8, u8, u8, u8) = (0, 0, 0, 255);
|
||||
const OPEN_DOOR: (u8, u8, u8, u8) = (80, 200, 120, 255);
|
||||
const LOCKED_DOOR: (u8, u8, u8, u8) = (220, 70, 70, 255);
|
||||
const SECRET_DOOR: (u8, u8, u8, u8) = (170, 80, 170, 255);
|
||||
const ARCHWAY: (u8, u8, u8, u8) = (230, 140, 60, 255);
|
||||
const WINDOW: (u8, u8, u8, u8) = (70, 130, 220, 255);
|
||||
const WHITE: (u8, u8, u8, u8) = (255, 255, 255, 255);
|
||||
@@ -32,6 +33,7 @@ enum DoorStyle {
|
||||
ShortDash,
|
||||
Dotted,
|
||||
DashDot,
|
||||
DashDotDot,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -241,7 +243,9 @@ fn render_pixmap(layout: &DungeonLayout, settings: &UiSettings) -> Result<Pixmap
|
||||
|
||||
for door in &layout.doors {
|
||||
let (color, style) = if settings.colorblind_mode {
|
||||
let s = if door.archway {
|
||||
let s = if door.secret {
|
||||
DoorStyle::DashDotDot
|
||||
} else if door.archway {
|
||||
DoorStyle::Dotted
|
||||
} else if door.locked {
|
||||
DoorStyle::ShortDash
|
||||
@@ -249,6 +253,8 @@ fn render_pixmap(layout: &DungeonLayout, settings: &UiSettings) -> Result<Pixmap
|
||||
DoorStyle::LongDash
|
||||
};
|
||||
(BLACK, s)
|
||||
} else if door.secret {
|
||||
(SECRET_DOOR, DoorStyle::Solid)
|
||||
} else if door.archway {
|
||||
(ARCHWAY, DoorStyle::Solid)
|
||||
} else if door.locked {
|
||||
@@ -322,14 +328,19 @@ fn export_composite_masks(
|
||||
.ok_or_else(|| "Failed to allocate archways mask canvas".to_string())?;
|
||||
let mut locked_doors = Pixmap::new(g.width, g.height)
|
||||
.ok_or_else(|| "Failed to allocate locked doors mask canvas".to_string())?;
|
||||
let mut secret_doors = Pixmap::new(g.width, g.height)
|
||||
.ok_or_else(|| "Failed to allocate secret doors mask canvas".to_string())?;
|
||||
let mut windows = Pixmap::new(g.width, g.height)
|
||||
.ok_or_else(|| "Failed to allocate windows mask canvas".to_string())?;
|
||||
fill_bg(&mut doors, BLACK);
|
||||
fill_bg(&mut archways, BLACK);
|
||||
fill_bg(&mut locked_doors, BLACK);
|
||||
fill_bg(&mut secret_doors, BLACK);
|
||||
fill_bg(&mut windows, BLACK);
|
||||
for door in &layout.doors {
|
||||
if door.archway {
|
||||
if door.secret {
|
||||
draw_door(&mut secret_doors, &g, door, door_w, WHITE, DoorStyle::Solid);
|
||||
} else if door.archway {
|
||||
draw_door(&mut archways, &g, door, door_w, WHITE, DoorStyle::Solid);
|
||||
} else if door.locked {
|
||||
draw_door(&mut locked_doors, &g, door, door_w, WHITE, DoorStyle::Solid);
|
||||
@@ -354,6 +365,7 @@ fn export_composite_masks(
|
||||
save_mask_image(folder, "doors_mask", &doors, settings)?;
|
||||
save_mask_image(folder, "archways_mask", &archways, settings)?;
|
||||
save_mask_image(folder, "locked_doors_mask", &locked_doors, settings)?;
|
||||
save_mask_image(folder, "secret_doors_mask", &secret_doors, settings)?;
|
||||
save_mask_image(folder, "windows_mask", &windows, settings)?;
|
||||
if settings.export_show_grid {
|
||||
let mut grid = Pixmap::new(g.width, g.height)
|
||||
@@ -601,19 +613,23 @@ fn build_svg(layout: &DungeonLayout, settings: &UiSettings) -> String {
|
||||
|
||||
for door in &layout.doors {
|
||||
let (color, dash) = if settings.colorblind_mode {
|
||||
if door.archway {
|
||||
if door.secret {
|
||||
("black", Some("7,3,1,3,1,4"))
|
||||
} else if door.archway {
|
||||
("black", Some("2,4"))
|
||||
} else if door.locked {
|
||||
("black", Some("6,4"))
|
||||
} else {
|
||||
("black", Some("14,7"))
|
||||
}
|
||||
} else if door.secret {
|
||||
("rgb(170,80,170)", None)
|
||||
} else if door.archway {
|
||||
("rgb(70,130,220)", None)
|
||||
("rgb(230,140,60)", None)
|
||||
} else if door.locked {
|
||||
("rgb(80,200,120)", None)
|
||||
} else {
|
||||
("rgb(220,70,70)", None)
|
||||
} else {
|
||||
("rgb(80,200,120)", None)
|
||||
};
|
||||
|
||||
if let Some((x1, y1, x2, y2)) =
|
||||
@@ -1117,6 +1133,9 @@ fn draw_line(
|
||||
DoorStyle::ShortDash => stroke_path(pixmap, x1, y1, x2, y2, width, color, Some((6.0, 4.0))),
|
||||
DoorStyle::Dotted => dotted_line(pixmap, x1, y1, x2, y2, width, color),
|
||||
DoorStyle::DashDot => stroke_path(pixmap, x1, y1, x2, y2, width, color, Some((7.0, 3.0))),
|
||||
DoorStyle::DashDotDot => {
|
||||
stroke_path(pixmap, x1, y1, x2, y2, width, color, Some((7.0, 3.0)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+121
@@ -35,6 +35,7 @@ pub struct Door {
|
||||
pub span_width: bool,
|
||||
pub locked: bool,
|
||||
pub archway: bool,
|
||||
pub secret: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -58,6 +59,7 @@ pub struct DoorSettings {
|
||||
pub frequency_percent: usize,
|
||||
pub room_hallway_percent: usize,
|
||||
pub locked_percent: usize,
|
||||
pub secret_percent: usize,
|
||||
pub allow_middle_corridor_doors: bool,
|
||||
}
|
||||
|
||||
@@ -359,6 +361,7 @@ pub fn apply_doors(
|
||||
span_width: true,
|
||||
locked: place_door && rng.next_f32() <= locked,
|
||||
archway: !place_door,
|
||||
secret: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -373,6 +376,7 @@ pub fn apply_doors(
|
||||
span_width: true,
|
||||
locked: place_door && rng.next_f32() <= locked,
|
||||
archway: !place_door,
|
||||
secret: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -392,6 +396,7 @@ pub fn apply_doors(
|
||||
span_width: true,
|
||||
locked: place_door && rng.next_f32() <= locked,
|
||||
archway: !place_door,
|
||||
secret: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -412,6 +417,7 @@ pub fn apply_doors(
|
||||
span_width: false,
|
||||
locked: rng.next_f32() <= locked,
|
||||
archway: false,
|
||||
secret: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -425,11 +431,14 @@ pub fn apply_doors(
|
||||
span_width: false,
|
||||
locked: rng.next_f32() <= locked,
|
||||
archway: false,
|
||||
secret: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply_secret_doors(layout, seed, settings);
|
||||
}
|
||||
|
||||
fn apply_packed_room_doors(layout: &mut DungeonLayout, seed: u64, settings: DoorSettings) {
|
||||
@@ -460,8 +469,116 @@ fn apply_packed_room_doors(layout: &mut DungeonLayout, seed: u64, settings: Door
|
||||
span_width: width > 1,
|
||||
locked: place_door && rng.next_f32() <= locked,
|
||||
archway: !place_door,
|
||||
secret: false,
|
||||
});
|
||||
}
|
||||
|
||||
apply_secret_doors(layout, seed, settings);
|
||||
}
|
||||
|
||||
fn apply_secret_doors(layout: &mut DungeonLayout, seed: u64, settings: DoorSettings) {
|
||||
let secret_percent = settings.secret_percent.min(100);
|
||||
let chance = (secret_percent as f32) / 100.0;
|
||||
if chance <= 0.0 || layout.rooms.is_empty() || layout.doors.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut rng = SimpleRng::new(seed::derive_seed(seed, 0x5EC2_E700_u64));
|
||||
let room_door_map = room_to_door_indices(layout);
|
||||
let eligible_secret_doors = (0..layout.doors.len())
|
||||
.filter(|&door_idx| {
|
||||
let door = &layout.doors[door_idx];
|
||||
!door.archway
|
||||
&& !door.locked
|
||||
&& door_is_secret_eligible_for_rooms(layout, &room_door_map, door_idx)
|
||||
})
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
for (door_idx, door) in layout.doors.iter_mut().enumerate() {
|
||||
if !eligible_secret_doors.contains(&door_idx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if rng.next_f32() <= chance {
|
||||
door.locked = false;
|
||||
door.archway = false;
|
||||
door.secret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn door_is_secret_eligible_for_rooms(
|
||||
layout: &DungeonLayout,
|
||||
room_door_map: &[Vec<usize>],
|
||||
door_idx: usize,
|
||||
) -> bool {
|
||||
for door_indices in room_door_map {
|
||||
if !door_indices.contains(&door_idx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for &other_door_idx in door_indices {
|
||||
if other_door_idx == door_idx {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !door_directly_connects_rooms(layout, other_door_idx) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn room_to_door_indices(layout: &DungeonLayout) -> Vec<Vec<usize>> {
|
||||
let mut room_door_map = vec![Vec::new(); layout.rooms.len()];
|
||||
for (door_idx, door) in layout.doors.iter().enumerate() {
|
||||
for (room_idx, room) in layout.rooms.iter().enumerate() {
|
||||
if door_touches_room(door, room) {
|
||||
room_door_map[room_idx].push(door_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
room_door_map
|
||||
}
|
||||
|
||||
fn secret_room_ids(layout: &DungeonLayout) -> HashSet<usize> {
|
||||
let mut secret_rooms = HashSet::new();
|
||||
for door in layout.doors.iter().filter(|door| door.secret) {
|
||||
for (room_idx, room) in layout.rooms.iter().enumerate() {
|
||||
if door_touches_room(door, room) {
|
||||
secret_rooms.insert(room_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
secret_rooms
|
||||
}
|
||||
|
||||
fn door_touches_room(door: &Door, room: &Room) -> bool {
|
||||
cell_in_room(door.from, room) || cell_in_room(door.to, room)
|
||||
}
|
||||
|
||||
fn door_directly_connects_rooms(layout: &DungeonLayout, door_idx: usize) -> bool {
|
||||
let Some(door) = layout.doors.get(door_idx) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let touching_rooms = layout
|
||||
.rooms
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(room_idx, room)| door_touches_room(door, room).then_some(room_idx))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
touching_rooms.len() >= 2
|
||||
}
|
||||
|
||||
fn cell_in_room(cell: (usize, usize), room: &Room) -> bool {
|
||||
cell.0 >= room.x
|
||||
&& cell.0 < room.x + room.width
|
||||
&& cell.1 >= room.y
|
||||
&& cell.1 < room.y + room.height
|
||||
}
|
||||
|
||||
pub fn apply_windows(
|
||||
@@ -532,9 +649,13 @@ fn collect_window_segments(
|
||||
allow_internal_windows: bool,
|
||||
) -> Vec<WindowSegment> {
|
||||
let corridor_cells = corridor_cells(layout, cols, rows);
|
||||
let secret_rooms = secret_room_ids(layout);
|
||||
let mut segments = Vec::new();
|
||||
|
||||
for (room_idx, room) in layout.rooms.iter().enumerate() {
|
||||
if secret_rooms.contains(&room_idx) {
|
||||
continue;
|
||||
}
|
||||
collect_room_side_segments(
|
||||
room_idx,
|
||||
room,
|
||||
|
||||
+78
-7
@@ -16,6 +16,13 @@ use layout::{
|
||||
};
|
||||
use ui::{AddTool, UiSettings, draw_side_panel};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum ManualDoorKind {
|
||||
Regular,
|
||||
Locked,
|
||||
Secret,
|
||||
}
|
||||
|
||||
// Boot the native app and start the egui event loop.
|
||||
fn main() -> eframe::Result<()> {
|
||||
let options = eframe::NativeOptions::default();
|
||||
@@ -164,6 +171,7 @@ impl eframe::App for DungeonApp {
|
||||
draw_legend_entry_colorblind(ui, "Walls", LegendStyle::SolidLine);
|
||||
draw_legend_entry_colorblind(ui, "Doors", LegendStyle::LongDash);
|
||||
draw_legend_entry_colorblind(ui, "Locked Doors", LegendStyle::ShortDash);
|
||||
draw_legend_entry_colorblind(ui, "Secret Doors", LegendStyle::DashDotDotLine);
|
||||
draw_legend_entry_colorblind(ui, "Archways", LegendStyle::DottedLine);
|
||||
draw_legend_entry_colorblind(ui, "Windows", LegendStyle::DashDotLine);
|
||||
} else {
|
||||
@@ -172,6 +180,7 @@ impl eframe::App for DungeonApp {
|
||||
draw_legend_entry(ui, Color32::BLACK, "Walls");
|
||||
draw_legend_entry(ui, Color32::from_rgb(80, 200, 120), "Doors");
|
||||
draw_legend_entry(ui, Color32::from_rgb(220, 70, 70), "Locked Doors");
|
||||
draw_legend_entry(ui, Color32::from_rgb(170, 80, 170), "Secret Doors");
|
||||
draw_legend_entry(ui, Color32::from_rgb(230, 140, 60), "Archways");
|
||||
draw_legend_entry(ui, Color32::from_rgb(70, 130, 220), "Windows");
|
||||
}
|
||||
@@ -511,13 +520,18 @@ impl DungeonApp {
|
||||
self.settings.add_tool = AddTool::None;
|
||||
}
|
||||
}
|
||||
AddTool::Door | AddTool::LockedDoor => {
|
||||
AddTool::Door | AddTool::LockedDoor | AddTool::SecretDoor => {
|
||||
self.add_corridor_drag = None;
|
||||
if response.clicked()
|
||||
&& let Some(pointer_pos) = response.interact_pointer_pos()
|
||||
{
|
||||
let locked = self.settings.add_tool == AddTool::LockedDoor;
|
||||
self.add_door_at_pointer(pointer_pos, geometry, locked);
|
||||
let kind = match self.settings.add_tool {
|
||||
AddTool::Door => ManualDoorKind::Regular,
|
||||
AddTool::LockedDoor => ManualDoorKind::Locked,
|
||||
AddTool::SecretDoor => ManualDoorKind::Secret,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.add_door_at_pointer(pointer_pos, geometry, kind);
|
||||
self.settings.add_tool = AddTool::None;
|
||||
}
|
||||
}
|
||||
@@ -926,11 +940,13 @@ impl DungeonApp {
|
||||
span_width: false,
|
||||
locked: false,
|
||||
archway: true,
|
||||
secret: false,
|
||||
});
|
||||
}
|
||||
let door = &mut self.layout.doors[idx];
|
||||
door.locked = false;
|
||||
door.archway = true;
|
||||
door.secret = false;
|
||||
door.width = 1;
|
||||
door.span_width = false;
|
||||
self.layout.doors.extend(spawned);
|
||||
@@ -978,7 +994,7 @@ impl DungeonApp {
|
||||
&mut self,
|
||||
pointer_pos: egui::Pos2,
|
||||
geometry: &GridGeometry,
|
||||
locked: bool,
|
||||
kind: ManualDoorKind,
|
||||
) {
|
||||
let Some(edge) = self.door_edge_at_pointer(pointer_pos, geometry) else {
|
||||
return;
|
||||
@@ -1014,11 +1030,13 @@ impl DungeonApp {
|
||||
span_width: false,
|
||||
locked: false,
|
||||
archway: true,
|
||||
secret: false,
|
||||
});
|
||||
}
|
||||
let door = &mut self.layout.doors[idx];
|
||||
door.locked = locked;
|
||||
door.locked = kind == ManualDoorKind::Locked;
|
||||
door.archway = false;
|
||||
door.secret = kind == ManualDoorKind::Secret;
|
||||
door.width = 1;
|
||||
door.span_width = false;
|
||||
self.layout.doors.extend(spawned);
|
||||
@@ -1043,8 +1061,9 @@ impl DungeonApp {
|
||||
to: edge.1,
|
||||
width: 1,
|
||||
span_width: false,
|
||||
locked,
|
||||
locked: kind == ManualDoorKind::Locked,
|
||||
archway: false,
|
||||
secret: kind == ManualDoorKind::Secret,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1385,6 +1404,8 @@ fn draw_layout(
|
||||
for door in &layout.doors {
|
||||
let color = if colorblind_mode {
|
||||
Color32::BLACK
|
||||
} else if door.secret {
|
||||
Color32::from_rgb(170, 80, 170)
|
||||
} else if door.archway {
|
||||
Color32::from_rgb(230, 140, 60)
|
||||
} else if door.locked {
|
||||
@@ -1393,7 +1414,9 @@ fn draw_layout(
|
||||
Color32::from_rgb(80, 200, 120)
|
||||
};
|
||||
let style = if colorblind_mode {
|
||||
if door.archway {
|
||||
if door.secret {
|
||||
DoorLineStyle::DashDotDot
|
||||
} else if door.archway {
|
||||
DoorLineStyle::Dotted
|
||||
} else if door.locked {
|
||||
DoorLineStyle::ShortDash
|
||||
@@ -1736,6 +1759,7 @@ fn door_settings_from_ui(settings: &UiSettings) -> DoorSettings {
|
||||
frequency_percent: settings.door_frequency_percent,
|
||||
room_hallway_percent: settings.room_hallway_door_percent,
|
||||
locked_percent: settings.locked_door_percent,
|
||||
secret_percent: settings.secret_door_percent,
|
||||
allow_middle_corridor_doors: settings.allow_middle_corridor_doors,
|
||||
}
|
||||
}
|
||||
@@ -1846,6 +1870,7 @@ enum DoorLineStyle {
|
||||
ShortDash,
|
||||
Dotted,
|
||||
DashDot,
|
||||
DashDotDot,
|
||||
}
|
||||
|
||||
// Draw a line with solid, dashed, or dotted styling.
|
||||
@@ -1864,6 +1889,7 @@ fn draw_styled_line(
|
||||
DoorLineStyle::ShortDash => draw_dashed_line(painter, from, to, stroke, 6.0, 4.0),
|
||||
DoorLineStyle::Dotted => draw_dotted_line(painter, from, to, stroke),
|
||||
DoorLineStyle::DashDot => draw_dash_dot_line(painter, from, to, stroke),
|
||||
DoorLineStyle::DashDotDot => draw_dash_dot_dot_line(painter, from, to, stroke),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1943,6 +1969,44 @@ fn draw_dash_dot_line(painter: &egui::Painter, from: egui::Pos2, to: egui::Pos2,
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_dash_dot_dot_line(
|
||||
painter: &egui::Painter,
|
||||
from: egui::Pos2,
|
||||
to: egui::Pos2,
|
||||
stroke: Stroke,
|
||||
) {
|
||||
let dx = to.x - from.x;
|
||||
let dy = to.y - from.y;
|
||||
let len = (dx * dx + dy * dy).sqrt();
|
||||
if len <= 0.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let ux = dx / len;
|
||||
let uy = dy / len;
|
||||
let radius = (stroke.width * 0.35).max(1.0);
|
||||
let mut dist = 0.0_f32;
|
||||
while dist < len {
|
||||
let dash_end = (dist + 7.0).min(len);
|
||||
let p0 = egui::pos2(from.x + ux * dist, from.y + uy * dist);
|
||||
let p1 = egui::pos2(from.x + ux * dash_end, from.y + uy * dash_end);
|
||||
painter.line_segment([p0, p1], stroke);
|
||||
dist = dash_end + 3.0;
|
||||
if dist >= len {
|
||||
break;
|
||||
}
|
||||
let dot1 = egui::pos2(from.x + ux * dist, from.y + uy * dist);
|
||||
painter.circle_filled(dot1, radius, stroke.color);
|
||||
dist += 3.0;
|
||||
if dist >= len {
|
||||
break;
|
||||
}
|
||||
let dot2 = egui::pos2(from.x + ux * dist, from.y + uy * dist);
|
||||
painter.circle_filled(dot2, radius, stroke.color);
|
||||
dist += 4.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the center position of a grid cell.
|
||||
fn cell_center(geometry: &GridGeometry, col: usize, row: usize) -> egui::Pos2 {
|
||||
egui::pos2(
|
||||
@@ -1993,6 +2057,7 @@ enum LegendStyle {
|
||||
ShortDash,
|
||||
DottedLine,
|
||||
DashDotLine,
|
||||
DashDotDotLine,
|
||||
}
|
||||
|
||||
// Draw a patterned legend entry for colorblind mode.
|
||||
@@ -2069,6 +2134,12 @@ fn draw_legend_entry_colorblind(ui: &mut egui::Ui, label: &str, style: LegendSty
|
||||
egui::pos2(rect.right() - 1.0, rect.center().y),
|
||||
Stroke::new(2.0, Color32::BLACK),
|
||||
),
|
||||
LegendStyle::DashDotDotLine => draw_dash_dot_dot_line(
|
||||
ui.painter(),
|
||||
egui::pos2(rect.left() + 1.0, rect.center().y),
|
||||
egui::pos2(rect.right() - 1.0, rect.center().y),
|
||||
Stroke::new(2.0, Color32::BLACK),
|
||||
),
|
||||
}
|
||||
|
||||
ui.add_space(6.0);
|
||||
|
||||
@@ -114,6 +114,7 @@ pub struct UiSettings {
|
||||
pub door_frequency_percent: usize,
|
||||
pub room_hallway_door_percent: usize,
|
||||
pub locked_door_percent: usize,
|
||||
pub secret_door_percent: usize,
|
||||
pub allow_middle_corridor_doors: bool,
|
||||
pub windows_enabled: bool,
|
||||
pub min_window_width: usize,
|
||||
@@ -151,6 +152,7 @@ impl Default for UiSettings {
|
||||
door_frequency_percent: 30,
|
||||
room_hallway_door_percent: 70,
|
||||
locked_door_percent: 25,
|
||||
secret_door_percent: 10,
|
||||
allow_middle_corridor_doors: false,
|
||||
windows_enabled: false,
|
||||
min_window_width: 1,
|
||||
@@ -178,6 +180,7 @@ pub enum AddTool {
|
||||
Corridor,
|
||||
Door,
|
||||
LockedDoor,
|
||||
SecretDoor,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
@@ -581,6 +584,21 @@ fn draw_layout_tab(ui: &mut egui::Ui, settings: &mut UiSettings, result: &mut Si
|
||||
.changed();
|
||||
});
|
||||
|
||||
ui.add_space(8.0);
|
||||
ui.label("Secret Door Chance (%)");
|
||||
ui.horizontal(|ui| {
|
||||
result.settings_changed |= ui
|
||||
.add(egui::Slider::new(&mut settings.secret_door_percent, 0..=100).show_value(false))
|
||||
.changed();
|
||||
result.settings_changed |= ui
|
||||
.add(
|
||||
egui::DragValue::new(&mut settings.secret_door_percent)
|
||||
.speed(1.0)
|
||||
.range(0..=100),
|
||||
)
|
||||
.changed();
|
||||
});
|
||||
|
||||
ui.add_space(8.0);
|
||||
result.settings_changed |= ui
|
||||
.checkbox(
|
||||
@@ -690,6 +708,11 @@ fn draw_add_tab(ui: &mut egui::Ui, settings: &mut UiSettings) {
|
||||
AddTool::LockedDoor,
|
||||
"Add Locked Door",
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut settings.add_tool,
|
||||
AddTool::SecretDoor,
|
||||
"Add Secret Door",
|
||||
);
|
||||
});
|
||||
|
||||
ui.add_space(6.0);
|
||||
@@ -698,6 +721,7 @@ fn draw_add_tab(ui: &mut egui::Ui, settings: &mut UiSettings) {
|
||||
AddTool::Corridor => ui.label("Click-drag to place a corridor between two cells."),
|
||||
AddTool::Door => ui.label("Click a room/corridor edge to place a door."),
|
||||
AddTool::LockedDoor => ui.label("Click a room/corridor edge to place a locked door."),
|
||||
AddTool::SecretDoor => ui.label("Click a room/corridor edge to place a secret door."),
|
||||
AddTool::None => ui.label("Select a tool to add rooms or corridors."),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user