1use super::{Direction, IVec3, Rotation};
2use super::{
3 grid::{SimpleGrid, is_house},
4 template::{MansionTemplatePiece, Mirror, above, add_piece, compose_rotation, relative},
5};
6
7#[expect(
8 clippy::too_many_lines,
9 reason = "mirrors vanilla's MansionPiecePlacer.createRoof inline traversal"
10)]
11pub(super) fn create_roof(
12 pieces: &mut Vec<MansionTemplatePiece>,
13 roof_origin: IVec3,
14 rotation: Rotation,
15 grid: &SimpleGrid,
16 above_grid: Option<&SimpleGrid>,
17 start_x: i32,
18 start_y: i32,
19) {
20 for y in 0..grid.height {
21 for x in 0..grid.width {
22 let mut pos = relative(
23 roof_origin,
24 rotation,
25 Direction::South,
26 8 + (y - start_y) * 8,
27 );
28 pos = relative(pos, rotation, Direction::East, (x - start_x) * 8);
29 let is_above = above_grid.is_some_and(|g| is_house(g, x, y));
30
31 if is_house(grid, x, y) && !is_above {
32 add_piece(pieces, "roof", above(pos, 3), rotation, Mirror::None);
33
34 if !is_house(grid, x + 1, y) {
35 let p = relative(pos, rotation, Direction::East, 6);
36 add_piece(pieces, "roof_front", p, rotation, Mirror::None);
37 }
38 if !is_house(grid, x - 1, y) {
39 let p = relative(
40 relative(pos, rotation, Direction::East, 0),
41 rotation,
42 Direction::South,
43 7,
44 );
45 add_piece(
46 pieces,
47 "roof_front",
48 p,
49 compose_rotation(rotation, Rotation::Clockwise180),
50 Mirror::None,
51 );
52 }
53 if !is_house(grid, x, y - 1) {
54 let p = relative(pos, rotation, Direction::West, 1);
55 add_piece(
56 pieces,
57 "roof_front",
58 p,
59 compose_rotation(rotation, Rotation::CounterClockwise90),
60 Mirror::None,
61 );
62 }
63 if !is_house(grid, x, y + 1) {
64 let p = relative(
65 relative(pos, rotation, Direction::East, 6),
66 rotation,
67 Direction::South,
68 6,
69 );
70 add_piece(
71 pieces,
72 "roof_front",
73 p,
74 compose_rotation(rotation, Rotation::Clockwise90),
75 Mirror::None,
76 );
77 }
78 }
79 }
80 }
81
82 if let Some(above_g) = above_grid {
83 for y in 0..grid.height {
84 for x in 0..grid.width {
85 let mut pos = relative(
86 roof_origin,
87 rotation,
88 Direction::South,
89 8 + (y - start_y) * 8,
90 );
91 pos = relative(pos, rotation, Direction::East, (x - start_x) * 8);
92 let is_above = is_house(above_g, x, y);
93 if !is_house(grid, x, y) || !is_above {
94 continue;
95 }
96
97 if !is_house(grid, x + 1, y) {
98 let p = relative(pos, rotation, Direction::East, 7);
99 add_piece(pieces, "small_wall", p, rotation, Mirror::None);
100 }
101 if !is_house(grid, x - 1, y) {
102 let p = relative(
103 relative(pos, rotation, Direction::West, 1),
104 rotation,
105 Direction::South,
106 6,
107 );
108 add_piece(
109 pieces,
110 "small_wall",
111 p,
112 compose_rotation(rotation, Rotation::Clockwise180),
113 Mirror::None,
114 );
115 }
116 if !is_house(grid, x, y - 1) {
117 let p = relative(
118 relative(pos, rotation, Direction::West, 0),
119 rotation,
120 Direction::North,
121 1,
122 );
123 add_piece(
124 pieces,
125 "small_wall",
126 p,
127 compose_rotation(rotation, Rotation::CounterClockwise90),
128 Mirror::None,
129 );
130 }
131 if !is_house(grid, x, y + 1) {
132 let p = relative(
133 relative(pos, rotation, Direction::East, 6),
134 rotation,
135 Direction::South,
136 7,
137 );
138 add_piece(
139 pieces,
140 "small_wall",
141 p,
142 compose_rotation(rotation, Rotation::Clockwise90),
143 Mirror::None,
144 );
145 }
146
147 if !is_house(grid, x + 1, y) {
148 if !is_house(grid, x, y - 1) {
149 let p = relative(
150 relative(pos, rotation, Direction::East, 7),
151 rotation,
152 Direction::North,
153 2,
154 );
155 add_piece(pieces, "small_wall_corner", p, rotation, Mirror::None);
156 }
157 if !is_house(grid, x, y + 1) {
158 let p = relative(
159 relative(pos, rotation, Direction::East, 8),
160 rotation,
161 Direction::South,
162 7,
163 );
164 add_piece(
165 pieces,
166 "small_wall_corner",
167 p,
168 compose_rotation(rotation, Rotation::Clockwise90),
169 Mirror::None,
170 );
171 }
172 }
173 if !is_house(grid, x - 1, y) {
174 if !is_house(grid, x, y - 1) {
175 let p = relative(
176 relative(pos, rotation, Direction::West, 2),
177 rotation,
178 Direction::North,
179 1,
180 );
181 add_piece(
182 pieces,
183 "small_wall_corner",
184 p,
185 compose_rotation(rotation, Rotation::CounterClockwise90),
186 Mirror::None,
187 );
188 }
189 if !is_house(grid, x, y + 1) {
190 let p = relative(
191 relative(pos, rotation, Direction::West, 1),
192 rotation,
193 Direction::South,
194 8,
195 );
196 add_piece(
197 pieces,
198 "small_wall_corner",
199 p,
200 compose_rotation(rotation, Rotation::Clockwise180),
201 Mirror::None,
202 );
203 }
204 }
205 }
206 }
207 }
208
209 for y in 0..grid.height {
210 for x in 0..grid.width {
211 let mut pos = relative(
212 roof_origin,
213 rotation,
214 Direction::South,
215 8 + (y - start_y) * 8,
216 );
217 pos = relative(pos, rotation, Direction::East, (x - start_x) * 8);
218 let is_above = above_grid.is_some_and(|g| is_house(g, x, y));
219 if !is_house(grid, x, y) || is_above {
220 continue;
221 }
222
223 if !is_house(grid, x + 1, y) {
224 let p = relative(pos, rotation, Direction::East, 6);
225 if !is_house(grid, x, y + 1) {
226 let p2 = relative(p, rotation, Direction::South, 6);
227 add_piece(pieces, "roof_corner", p2, rotation, Mirror::None);
228 } else if is_house(grid, x + 1, y + 1) {
229 let p2 = relative(p, rotation, Direction::South, 5);
230 add_piece(pieces, "roof_inner_corner", p2, rotation, Mirror::None);
231 }
232 if !is_house(grid, x, y - 1) {
233 add_piece(
234 pieces,
235 "roof_corner",
236 p,
237 compose_rotation(rotation, Rotation::CounterClockwise90),
238 Mirror::None,
239 );
240 } else if is_house(grid, x + 1, y - 1) {
241 let p2 = relative(
242 relative(pos, rotation, Direction::East, 9),
243 rotation,
244 Direction::North,
245 2,
246 );
247 add_piece(
248 pieces,
249 "roof_inner_corner",
250 p2,
251 compose_rotation(rotation, Rotation::Clockwise90),
252 Mirror::None,
253 );
254 }
255 }
256
257 if !is_house(grid, x - 1, y) {
258 let p = relative(pos, rotation, Direction::East, 0);
259 let p = relative(p, rotation, Direction::South, 0);
260 if !is_house(grid, x, y + 1) {
261 let p2 = relative(p, rotation, Direction::South, 6);
262 add_piece(
263 pieces,
264 "roof_corner",
265 p2,
266 compose_rotation(rotation, Rotation::Clockwise90),
267 Mirror::None,
268 );
269 } else if is_house(grid, x - 1, y + 1) {
270 let p2 = relative(
271 relative(p, rotation, Direction::South, 8),
272 rotation,
273 Direction::West,
274 3,
275 );
276 add_piece(
277 pieces,
278 "roof_inner_corner",
279 p2,
280 compose_rotation(rotation, Rotation::CounterClockwise90),
281 Mirror::None,
282 );
283 }
284 if !is_house(grid, x, y - 1) {
285 add_piece(
286 pieces,
287 "roof_corner",
288 p,
289 compose_rotation(rotation, Rotation::Clockwise180),
290 Mirror::None,
291 );
292 } else if is_house(grid, x - 1, y - 1) {
293 let p2 = relative(p, rotation, Direction::South, 1);
294 add_piece(
295 pieces,
296 "roof_inner_corner",
297 p2,
298 compose_rotation(rotation, Rotation::Clockwise180),
299 Mirror::None,
300 );
301 }
302 }
303 }
304 }
305}