rustapi/actions/
extrude_sector.rs1use crate::prelude::*;
2use rusterix::Surface;
3
4pub struct ExtrudeSector {
5 id: TheId,
6 nodeui: TheNodeUI,
7}
8
9impl Action for ExtrudeSector {
10 fn new() -> Self
11 where
12 Self: Sized,
13 {
14 let mut nodeui: TheNodeUI = TheNodeUI::default();
15
16 nodeui.add_item(TheNodeUIItem::Checkbox(
18 "actionSurfEnable".into(),
19 "".into(),
20 "".into(),
21 true,
22 ));
23
24 let item = TheNodeUIItem::FloatEditSlider(
25 "actionDepth".into(),
26 "".into(),
27 "".into(),
28 0.2,
29 0.0..=1.0,
30 false,
31 );
32 nodeui.add_item(item);
33
34 nodeui.add_item(TheNodeUIItem::Checkbox(
35 "actionBackOpen".into(),
36 "".into(),
37 "".into(),
38 false,
39 ));
40
41 let item = TheNodeUIItem::Markdown("desc".into(), "".into());
42 nodeui.add_item(item);
43
44 Self {
45 id: TheId::named(&fl!("action_extrude_sector")),
46 nodeui,
47 }
48 }
49
50 fn id(&self) -> TheId {
51 self.id.clone()
52 }
53
54 fn info(&self) -> String {
55 fl!("action_extrude_sector_desc")
56 }
57
58 fn role(&self) -> ActionRole {
59 ActionRole::Editor
60 }
61
62 fn accel(&self) -> Option<TheAccelerator> {
63 Some(TheAccelerator::new(TheAcceleratorKey::ALT, 'e'))
64 }
65
66 fn is_applicable(&self, map: &Map, _ctx: &mut TheContext, server_ctx: &ServerContext) -> bool {
67 if server_ctx.editor_view_mode == EditorViewMode::D2 {
69 return false;
70 }
71
72 !map.selected_sectors.is_empty() && map.selected_linedefs.is_empty()
73 }
74
75 fn apply(
76 &self,
77 map: &mut Map,
78 _ui: &mut TheUI,
79 _ctx: &mut TheContext,
80 server_ctx: &mut ServerContext,
81 ) -> Option<ProjectUndoAtom> {
82 let mut changed = false;
83 let prev = map.clone();
84
85 let distance = self.nodeui.get_f32_value("actionDepth").unwrap_or(2.0);
86 let surf_enable = self
87 .nodeui
88 .get_bool_value("actionSurfEnable")
89 .unwrap_or(true);
90 let back_open = self
91 .nodeui
92 .get_bool_value("actionBackOpen")
93 .unwrap_or(false);
94
95 for sector_id in map.selected_sectors.clone() {
97 let mut surface_id_opt: Option<Uuid> = None;
99 for (sid, s) in map.surfaces.iter() {
100 if s.sector_id == sector_id {
101 surface_id_opt = Some(*sid);
102 break;
103 }
104 }
105
106 if surface_id_opt.is_none() {
108 if let Some(_sec) = map.find_sector(sector_id) {
109 let mut surf = Surface::new(sector_id);
110 surf.calculate_geometry(map);
111 let id = surf.id;
112 map.surfaces.insert(id, surf);
113 surface_id_opt = Some(id);
114 }
115 }
116
117 if let Some(sid) = surface_id_opt {
118 if let Some(surf) = map.surfaces.get_mut(&sid) {
119 surf.extrusion.enabled = surf_enable;
121 surf.extrusion.depth = distance;
122 surf.extrusion.cap_front = true; surf.extrusion.cap_back = !back_open; surf.extrusion.flip_normal = false; changed = true;
126 }
127 }
128 }
129
130 if changed {
131 Some(ProjectUndoAtom::MapEdit(
132 server_ctx.pc,
133 Box::new(prev),
134 Box::new(map.clone()),
135 ))
136 } else {
137 None
138 }
139 }
140
141 fn params(&self) -> TheNodeUI {
142 self.nodeui.clone()
143 }
144
145 fn handle_event(
146 &mut self,
147 event: &TheEvent,
148 _project: &mut Project,
149 _ui: &mut TheUI,
150 _ctx: &mut TheContext,
151 _server_ctx: &mut ServerContext,
152 ) -> bool {
153 self.nodeui.handle_event(event)
154 }
155}