1use super::*;
2use crate::{
3 Land,
4 site::gen::{PrimitiveTransform, spiral_staircase},
5 util::{CARDINALS, DIAGONALS, RandomField, Sampler, within_distance},
6};
7use common::{
8 generation::SpecialEntity,
9 terrain::{BlockKind, SpriteKind},
10};
11use rand::prelude::*;
12use std::f32::consts::PI;
13use vek::*;
14
15pub struct AirshipDock {
17 pub(crate) alt: i32,
19 rotation: f32,
20 pub door_tile: Vec2<i32>,
21 pub center: Vec2<i32>,
22 base: i32,
23 height: i32,
24 pub docking_positions: Vec<Vec3<i32>>,
25 pub door_dir: Vec2<i32>,
26 campfire_pos: Vec3<i32>,
27}
28
29impl AirshipDock {
30 pub fn generate(
31 land: &Land,
32 _rng: &mut impl Rng,
33 site: &Site,
34 door_tile: Vec2<i32>,
35 door_dir: Vec2<i32>,
36 tile_aabr: Aabr<i32>,
37 alt: Option<i32>,
38 ) -> Self {
39 let door_tile_pos: Vec2<i32> = site.tile_center_wpos(door_tile);
40 let bounds = Aabr {
41 min: site.tile_wpos(tile_aabr.min),
42 max: site.tile_wpos(tile_aabr.max),
43 };
44 let center = bounds.center();
45 let alt = alt.unwrap_or_else(|| {
46 land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) as i32
47 });
48 let base = alt + 3;
49 let height = base + 28;
50 let rotation = -f32::atan2(door_dir.x as f32, door_dir.y as f32);
53 let mut docking_positions = vec![];
54 for dir in CARDINALS {
55 let pos = (center + dir * 31).with_z(height + 9);
56 docking_positions.push(pos);
57 }
58 let campfire_dir = Mat2::rotation_z(-PI / 4.0) * door_dir.map(|i| i as f32);
59 let campfire_pos = (center.map(|i| i as f32) + (campfire_dir * 11.0))
60 .map(|f| f.round() as i32)
61 .with_z(height + 9);
62 Self {
63 door_tile: door_tile_pos,
64 alt,
65 rotation,
66 center,
67 base,
68 height,
69 docking_positions,
70 door_dir,
71 campfire_pos,
72 }
73 }
74
75 pub fn spawn_rules(&self, wpos: Vec2<i32>) -> SpawnRules {
76 SpawnRules {
77 trees: {
78 const AIRSHIP_MIN_TREE_DIST2: i32 = 100;
84 !within_distance(wpos, self.center, AIRSHIP_MIN_TREE_DIST2)
85 },
86 waypoints: false,
87 ..SpawnRules::default()
88 }
89 }
90}
91
92impl Structure for AirshipDock {
93 #[cfg(feature = "use-dyn-lib")]
94 const UPDATE_FN: &'static [u8] = b"render_airshipdock\0";
95
96 #[cfg_attr(feature = "be-dyn-lib", unsafe(export_name = "render_airshipdock"))]
97 fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
98 let brick = Fill::Brick(BlockKind::Rock, Rgb::new(80, 75, 85), 24);
99 let wood = Fill::Brick(BlockKind::Rock, Rgb::new(45, 28, 21), 24);
100 let woodalt = Fill::Brick(BlockKind::Rock, Rgb::new(30, 22, 15), 24);
101
102 let base = self.base;
103 let center = self.center;
104 let height = self.height;
105
106 painter
112 .cylinder_with_radius(
113 Vec2::new(center.x - 1, center.y + 12).with_z(base - 5),
114 4.5,
115 7.0,
116 )
117 .rotate_about_min(Mat3::new(1, 0, 0, 0, 0, -1, 0, 1, 0))
118 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
119 .fill(wood.clone());
120
121 painter
123 .cylinder_with_radius(center.with_z(height - 3), 7.0, 1.0)
124 .fill(wood.clone());
125 painter
126 .cylinder_with_radius(center.with_z(height + 6), 7.0, 1.0)
127 .fill(wood.clone());
128 painter
129 .cylinder_with_radius(center.with_z(height + 7), 8.0, 1.0)
130 .fill(wood.clone());
131
132 painter
134 .superquadric(
135 Aabb {
136 min: (center - 8000).with_z(height + 7),
137 max: (center + 8000).with_z(height + 11),
138 },
139 0.3,
140 )
141 .intersect(painter.aabb(Aabb {
142 min: (center - 31).with_z(height + 7),
143 max: (center + 31).with_z(height + 11),
144 }))
145 .fill(woodalt.clone());
146 painter
147 .cylinder_with_radius(center.with_z(height + 8), 19.0, 2.0)
148 .fill(woodalt.clone());
149 painter
150 .cylinder_with_radius(center.with_z(height + 8), 18.0, 2.0)
151 .fill(wood.clone());
152 painter
153 .cylinder_with_radius(center.with_z(height + 9), 18.0, 1.0)
154 .clear();
155 painter
156 .aabb(Aabb {
157 min: Vec2::new(center.x - 30, center.y - 2).with_z(height + 8),
158 max: Vec2::new(center.x + 30, center.y + 2).with_z(height + 10),
159 })
160 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
161 .fill(wood.clone());
162 painter
163 .aabb(Aabb {
164 min: Vec2::new(center.x - 30, center.y - 2).with_z(height + 9),
165 max: Vec2::new(center.x + 30, center.y + 2).with_z(height + 10),
166 })
167 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
168 .clear();
169 painter
170 .aabb(Aabb {
171 min: Vec2::new(center.x - 2, center.y - 30).with_z(height + 8),
172 max: Vec2::new(center.x + 2, center.y + 30).with_z(height + 10),
173 })
174 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
175 .fill(wood.clone());
176 painter
177 .aabb(Aabb {
178 min: Vec2::new(center.x - 2, center.y - 30).with_z(height + 9),
179 max: Vec2::new(center.x + 2, center.y + 30).with_z(height + 10),
180 })
181 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
182 .clear();
183
184 painter
186 .cylinder_with_radius(center.with_z(height + 9), 9.0, 6.0)
187 .intersect(painter.aabb(Aabb {
188 min: (Vec2::new(center.x + 2, center.y - 2)).with_z(height + 9),
189 max: (Vec2::new(center.x + 40, center.y - 40)).with_z(height + 16),
190 }))
191 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
192 .fill(woodalt.clone());
193 painter
195 .cylinder_with_radius(center.with_z(height + 9), 9.0, 5.0)
196 .intersect(painter.aabb(Aabb {
197 min: (Vec2::new(center.x + 3, center.y - 3)).with_z(height + 9),
198 max: (Vec2::new(center.x + 40, center.y - 40)).with_z(height + 15),
199 }))
200 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
201 .clear();
202 painter
204 .cylinder_with_radius(center.with_z(height + 9), 9.0, 1.0)
205 .intersect(painter.aabb(Aabb {
206 min: (Vec2::new(center.x + 3, center.y - 3)).with_z(height + 9),
207 max: (Vec2::new(center.x + 40, center.y - 40)).with_z(height + 11),
208 }))
209 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
210 .fill(woodalt.clone());
211 painter
213 .cylinder_with_radius(center.with_z(height + 9), 8.0, 1.0)
214 .intersect(painter.aabb(Aabb {
215 min: (Vec2::new(center.x + 3, center.y - 3)).with_z(height + 9),
216 max: (Vec2::new(center.x + 40, center.y - 40)).with_z(height + 11),
217 }))
218 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
219 .clear();
220 painter
222 .line(
223 Vec2::new(center.x + 2, center.y - 9).with_z(height + 9),
224 Vec2::new(center.x + 2, center.y - 9).with_z(height + 16),
225 0.5,
226 )
227 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
228 .clear();
229 painter
230 .line(
231 Vec2::new(center.x + 8, center.y - 3).with_z(height + 9),
232 Vec2::new(center.x + 8, center.y - 3).with_z(height + 16),
233 0.5,
234 )
235 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
236 .clear();
237
238 painter
242 .cylinder_with_radius(center.with_z(base), 6.0, 45.0)
243 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
244 .fill(brick.clone());
245
246 painter
247 .cylinder_with_radius(center.with_z(base), 7.0, 1.0)
248 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
249 .fill(brick.clone());
250
251 painter
253 .cylinder_with_radius(center.with_z(base + 35), 7.0, 2.0)
254 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
255 .fill(brick.clone());
256 painter
258 .cylinder_with_radius(center.with_z(height + 9), 7.0, 1.0)
259 .intersect(painter.aabb(Aabb {
260 min: (Vec2::new(center.x + 2, center.y - 8)).with_z(height + 9),
261 max: (Vec2::new(center.x - 8, center.y + 8)).with_z(height + 10),
262 }))
263 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
264 .fill(brick.clone());
265 painter
267 .line(
268 Vec2::new(center.x + 6, center.y - 2).with_z(height + 9),
269 Vec2::new(center.x + 6, center.y + 2).with_z(height + 9),
270 0.5,
271 )
272 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
273 .fill(brick.clone());
274 painter
276 .cylinder_with_radius(center.with_z(base), 5.0, 45.0)
277 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
278 .clear();
279
280 painter
282 .cylinder_with_radius(
283 Vec2::new(center.x - 1, center.y + 12).with_z(base - 5),
284 3.5,
285 7.0,
286 )
287 .rotate_about_min(Mat3::new(1, 0, 0, 0, 0, -1, 0, 1, 0))
288 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
289 .clear();
290 painter
292 .aabb(Aabb {
293 min: Vec2::new(center.x - 11, center.y - 11).with_z(base - 16),
294 max: Vec2::new(center.x + 11, center.y + 11).with_z(base),
295 })
296 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
297 .fill(brick.clone());
298
299 painter
301 .aabb(Aabb {
302 min: Vec2::new(center.x - 6, center.y + 9).with_z(base - 1),
303 max: Vec2::new(center.x + 4, center.y + 11).with_z(base),
304 })
305 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
306 .clear();
307 painter
308 .aabb(Aabb {
309 min: Vec2::new(center.x - 5, center.y + 10).with_z(base - 2),
310 max: Vec2::new(center.x + 3, center.y + 11).with_z(base - 1),
311 })
312 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
313 .clear();
314 painter
316 .cone_with_radius(center.with_z(base + 45), 8.0, 18.0)
317 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
318 .fill(wood.clone());
319 painter
321 .aabb(Aabb {
322 min: Vec2::new(center.x - 1, center.y + 1).with_z(height + 9),
323 max: Vec2::new(center.x + 6, center.y + 6).with_z(height + 17),
324 })
325 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
326 .fill(brick.clone());
327 painter
328 .aabb(Aabb {
329 min: Vec2::new(center.x, center.y + 2).with_z(height + 9),
330 max: Vec2::new(center.x + 6, center.y + 7).with_z(height + 17),
331 })
332 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
333 .clear();
334 painter
336 .aabb(Aabb {
337 min: Vec2::new(center.x - 2, center.y - 15).with_z(height + 8),
338 max: Vec2::new(center.x + 6, center.y + 9).with_z(height + 9),
339 })
340 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
341 .fill(wood.clone());
342
343 painter
345 .aabb(Aabb {
346 min: Vec2::new(center.x + 5, center.y - 2).with_z(height + 10),
347 max: Vec2::new(center.x + 7, center.y + 2).with_z(height + 13),
348 })
349 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
350 .fill(brick.clone());
351 painter
352 .aabb(Aabb {
353 min: Vec2::new(center.x + 5, center.y - 1).with_z(height + 10),
354 max: Vec2::new(center.x + 7, center.y + 1).with_z(height + 15),
355 })
356 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
357 .fill(brick.clone());
358 painter
359 .aabb(Aabb {
360 min: Vec2::new(center.x + 5, center.y - 1).with_z(height + 10),
361 max: Vec2::new(center.x + 7, center.y + 1).with_z(height + 13),
362 })
363 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
364 .clear();
365 let door_rot = if self.rotation == 0.0 {
368 (2, 6)
369 } else if self.rotation == PI / 2.0 {
370 (4, 0)
371 } else if self.rotation == PI {
372 (6, 2) } else {
374 (0, 4)
375 };
376 let sprite_fill = Fill::Block(Block::air(SpriteKind::Door).with_ori(door_rot.0).unwrap());
377 painter
378 .aabb(Aabb {
379 min: Vec3::new(center.x + 6, center.y - 1, height + 10),
380 max: Vec3::new(center.x + 7, center.y + 0, height + 11),
381 })
382 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
383 .fill(sprite_fill.clone());
384 let sprite_fill = Fill::Block(Block::air(SpriteKind::Door).with_ori(door_rot.1).unwrap());
385 painter
386 .aabb(Aabb {
387 min: Vec3::new(center.x + 6, center.y + 0, height + 10),
388 max: Vec3::new(center.x + 7, center.y + 1, height + 11),
389 })
390 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
391 .fill(sprite_fill.clone());
392
393 painter
395 .line(
396 Vec2::new(center.x + 5, center.y - 3).with_z(height - 3),
397 Vec2::new(center.x + 17, center.y - 3).with_z(height + 8),
398 1.0,
399 )
400 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
401 .fill(wood.clone());
402 painter
403 .line(
404 Vec2::new(center.x + 5, center.y + 2).with_z(height - 3),
405 Vec2::new(center.x + 17, center.y + 2).with_z(height + 8),
406 1.0,
407 )
408 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
409 .fill(wood.clone());
410 painter
412 .line(
413 Vec2::new(center.x - 18, center.y - 3).with_z(height + 8),
414 Vec2::new(center.x - 6, center.y - 3).with_z(height - 3),
415 1.0,
416 )
417 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
418 .fill(wood.clone());
419 painter
420 .line(
421 Vec2::new(center.x - 18, center.y + 2).with_z(height + 8),
422 Vec2::new(center.x - 6, center.y + 2).with_z(height - 3),
423 1.0,
424 )
425 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
426 .fill(wood.clone());
427 painter
429 .line(
430 Vec2::new(center.x - 3, center.y - 18).with_z(height + 8),
431 Vec2::new(center.x - 3, center.y - 6).with_z(height - 3),
432 1.0,
433 )
434 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
435 .fill(wood.clone());
436 painter
437 .line(
438 Vec2::new(center.x + 2, center.y - 18).with_z(height + 8),
439 Vec2::new(center.x + 2, center.y - 6).with_z(height - 3),
440 1.0,
441 )
442 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
443 .fill(wood.clone());
444 painter
446 .line(
447 Vec2::new(center.x - 3, center.y + 5).with_z(height - 3),
448 Vec2::new(center.x - 3, center.y + 17).with_z(height + 8),
449 1.0,
450 )
451 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
452 .fill(wood.clone());
453 painter
454 .line(
455 Vec2::new(center.x + 2, center.y + 5).with_z(height - 3),
456 Vec2::new(center.x + 2, center.y + 17).with_z(height + 8),
457 1.0,
458 )
459 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
460 .fill(wood.clone());
461
462 painter
464 .cylinder_with_radius(center.with_z(height + 8), 5.0, 1.0)
465 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
466 .clear();
467
468 let stairs_clear1 = painter.cylinder_with_radius(center.with_z(base), 5.0, 38.0);
469
470 painter
471 .prim(Primitive::sampling(
472 stairs_clear1,
473 spiral_staircase(center.with_z(base + 3), 6.0, 0.5, 9.0),
474 ))
475 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
476 .fill(wood.clone());
477
478 painter
480 .aabb(Aabb {
481 min: Vec2::new(center.x + 1, center.y + 3).with_z(height + 8),
482 max: Vec2::new(center.x + 4, center.y + 5).with_z(height + 9),
483 })
484 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
485 .fill(wood.clone());
486 painter
487 .aabb(Aabb {
488 min: Vec2::new(center.x + 0, center.y + 2).with_z(height + 9),
489 max: Vec2::new(center.x + 6, center.y + 7).with_z(height + 10),
490 })
491 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
492 .fill(brick.clone());
493 painter
494 .aabb(Aabb {
495 min: Vec2::new(center.x + 1, center.y + 3).with_z(height + 9),
496 max: Vec2::new(center.x + 6, center.y + 7).with_z(height + 10),
497 })
498 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
499 .clear();
500 painter
501 .aabb(Aabb {
502 min: Vec2::new(center.x + 0, center.y + 2).with_z(height + 9),
503 max: Vec2::new(center.x + 1, center.y + 3).with_z(height + 17),
504 })
505 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
506 .fill(brick.clone());
507
508 let window_rot = if self.rotation == 0.0 || self.rotation == PI {
509 (2, 4)
510 } else {
511 (4, 2)
512 };
513 let sprite_fill = Fill::Block(
514 Block::air(SpriteKind::Window1)
515 .with_ori(window_rot.0)
516 .unwrap(),
517 );
518 painter
520 .aabb(Aabb {
521 min: Vec2::new(center.x - 6, center.y - 1).with_z(height + 12),
522 max: Vec2::new(center.x - 5, center.y + 1).with_z(height + 15),
523 })
524 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
525 .fill(sprite_fill.clone());
526
527 painter
529 .aabb(Aabb {
530 min: Vec2::new(center.x - 6, center.y - 1).with_z(base + 19),
531 max: Vec2::new(center.x - 5, center.y + 1).with_z(base + 22),
532 })
533 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
534 .fill(sprite_fill.clone());
535 painter
536 .aabb(Aabb {
537 min: Vec2::new(center.x - 6, center.y - 1).with_z(base + 1),
538 max: Vec2::new(center.x - 5, center.y + 1).with_z(base + 4),
539 })
540 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
541 .fill(sprite_fill.clone());
542 painter
543 .aabb(Aabb {
544 min: Vec2::new(center.x + 5, center.y - 1).with_z(base + 4),
545 max: Vec2::new(center.x + 6, center.y + 1).with_z(base + 7),
546 })
547 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
548 .fill(sprite_fill.clone());
549 painter
550 .aabb(Aabb {
551 min: Vec2::new(center.x + 5, center.y - 1).with_z(base + 22),
552 max: Vec2::new(center.x + 6, center.y + 1).with_z(base + 25),
553 })
554 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
555 .fill(sprite_fill.clone());
556 painter
557 .aabb(Aabb {
558 min: Vec2::new(center.x + 5, center.y - 1).with_z(base + 30),
559 max: Vec2::new(center.x + 6, center.y + 1).with_z(base + 33),
560 })
561 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
562 .fill(sprite_fill.clone());
563
564 let sprite_fill = Fill::Block(
565 Block::air(SpriteKind::Window1)
566 .with_ori(window_rot.1)
567 .unwrap(),
568 );
569 painter
571 .aabb(Aabb {
572 min: Vec2::new(center.x - 1, center.y + 5).with_z(base + 17),
573 max: Vec2::new(center.x + 1, center.y + 6).with_z(base + 20),
574 })
575 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
576 .fill(sprite_fill.clone());
577 painter
578 .aabb(Aabb {
579 min: Vec2::new(center.x - 1, center.y - 6).with_z(base + 13),
580 max: Vec2::new(center.x + 1, center.y - 5).with_z(base + 16),
581 })
582 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
583 .fill(sprite_fill.clone());
584
585 painter.rotated_sprite(
587 Vec2::new(center.x - 3, center.y + 5).with_z(base + 8),
588 SpriteKind::WallLampSmall,
589 4,
590 );
591 painter.rotated_sprite(
592 Vec2::new(center.x + 2, center.y + 5).with_z(base + 8),
593 SpriteKind::WallLampSmall,
594 4,
595 );
596 painter.rotated_sprite(
597 Vec2::new(center.x - 3, center.y + 5).with_z(base + 18),
598 SpriteKind::WallLampSmall,
599 4,
600 );
601 painter.rotated_sprite(
602 Vec2::new(center.x + 2, center.y + 5).with_z(base + 18),
603 SpriteKind::WallLampSmall,
604 4,
605 );
606 painter.rotated_sprite(
607 Vec2::new(center.x - 3, center.y - 6).with_z(base + 8),
608 SpriteKind::WallLampSmall,
609 0,
610 );
611 painter.rotated_sprite(
612 Vec2::new(center.x + 2, center.y - 6).with_z(base + 8),
613 SpriteKind::WallLampSmall,
614 0,
615 );
616 painter.rotated_sprite(
617 Vec2::new(center.x - 3, center.y - 6).with_z(base + 18),
618 SpriteKind::WallLampSmall,
619 0,
620 );
621 painter.rotated_sprite(
622 Vec2::new(center.x + 2, center.y - 6).with_z(base + 18),
623 SpriteKind::WallLampSmall,
624 0,
625 );
626
627 painter.rotated_sprite(
628 Vec2::new(center.x + 5, center.y - 3).with_z(base + 13),
629 SpriteKind::WallLampSmall,
630 2,
631 );
632 painter.rotated_sprite(
633 Vec2::new(center.x + 5, center.y + 2).with_z(base + 13),
634 SpriteKind::WallLampSmall,
635 2,
636 );
637 painter.rotated_sprite(
638 Vec2::new(center.x + 5, center.y - 3).with_z(base + 29),
639 SpriteKind::WallLampSmall,
640 2,
641 );
642 painter.rotated_sprite(
643 Vec2::new(center.x + 5, center.y + 2).with_z(base + 29),
644 SpriteKind::WallLampSmall,
645 2,
646 );
647 painter.rotated_sprite(
648 Vec2::new(center.x - 6, center.y - 3).with_z(base + 13),
649 SpriteKind::WallLampSmall,
650 6,
651 );
652 painter.rotated_sprite(
653 Vec2::new(center.x - 6, center.y + 2).with_z(base + 13),
654 SpriteKind::WallLampSmall,
655 6,
656 );
657 painter.rotated_sprite(
658 Vec2::new(center.x - 6, center.y - 3).with_z(base + 29),
659 SpriteKind::WallLampSmall,
660 6,
661 );
662 painter.rotated_sprite(
663 Vec2::new(center.x - 6, center.y + 2).with_z(base + 29),
664 SpriteKind::WallLampSmall,
665 6,
666 );
667 for dir in DIAGONALS {
669 let pos = (center + dir * 12).with_z(height + 7);
670 painter.sprite(pos, SpriteKind::Lantern)
671 }
672 for dir in CARDINALS {
673 let pos = (center + dir * 24).with_z(height + 7);
674 painter.sprite(pos, SpriteKind::Lantern)
675 }
676 let sprite_fill = Fill::Block(Block::air(SpriteKind::Lantern).with_ori(2).unwrap());
677 painter
679 .aabb(Aabb {
680 min: Vec3::new(center.x - 6, center.y + 5, height + 16),
681 max: Vec3::new(center.x - 5, center.y + 6, height + 17),
682 })
683 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
684 .fill(sprite_fill.clone());
685 painter
686 .aabb(Aabb {
687 min: Vec3::new(center.x + 5, center.y + 5, height + 16),
688 max: Vec3::new(center.x + 6, center.y + 6, height + 17),
689 })
690 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
691 .fill(sprite_fill.clone());
692 painter
693 .aabb(Aabb {
694 min: Vec3::new(center.x - 6, center.y - 6, height + 16),
695 max: Vec3::new(center.x - 5, center.y - 5, height + 17),
696 })
697 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
698 .fill(sprite_fill.clone());
699
700 painter
702 .aabb(Aabb {
703 min: Vec3::new(center.x + 7, center.y - 3, height + 13),
704 max: Vec3::new(center.x + 8, center.y - 4, height + 14),
705 })
706 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
707 .fill(Fill::Block(
708 Block::air(SpriteKind::LanternAirshipWallBrownS)
709 .with_ori(4)
710 .unwrap(),
711 ));
712 painter
713 .aabb(Aabb {
714 min: Vec3::new(center.x + 3, center.y - 7, height + 13),
715 max: Vec3::new(center.x + 4, center.y - 8, height + 14),
716 })
717 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
718 .fill(Fill::Block(
719 Block::air(SpriteKind::LanternAirshipWallBrownS)
720 .with_ori(6)
721 .unwrap(),
722 ));
723
724 painter
727 .aabb(Aabb {
728 min: Vec3::new(center.x - 2, center.y - 3, base + 6),
729 max: Vec3::new(center.x - 1, center.y + -2, base + 7),
730 })
731 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
732 .fill(sprite_fill.clone());
733 painter
734 .aabb(Aabb {
735 min: Vec3::new(center.x - 2, center.y - 3, base + 15),
736 max: Vec3::new(center.x - 1, center.y + -2, base + 16),
737 })
738 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
739 .fill(sprite_fill.clone());
740 painter
741 .aabb(Aabb {
742 min: Vec3::new(center.x - 2, center.y - 3, base + 24),
743 max: Vec3::new(center.x - 1, center.y + -2, base + 25),
744 })
745 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
746 .fill(sprite_fill.clone());
747 painter
748 .aabb(Aabb {
749 min: Vec3::new(center.x - 2, center.y - 3, base + 33),
750 max: Vec3::new(center.x - 1, center.y + -2, base + 34),
751 })
752 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
753 .fill(sprite_fill.clone());
754 painter
755 .aabb(Aabb {
756 min: Vec3::new(center.x - 2, center.y - 3, base + 44),
757 max: Vec3::new(center.x - 1, center.y + -2, base + 45),
758 })
759 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
760 .fill(sprite_fill.clone());
761
762 let mut sprite_positions = vec![];
764 for a in 0..5 {
765 sprite_positions.push(Vec2::new(center.x + 1 + a, center.y + 2));
766 }
767 for b in 0..=1 {
768 sprite_positions.push(Vec2::new(center.x, center.y + 3 + b));
769 }
770 for sprite_pos in sprite_positions {
771 let rows = (RandomField::new(0).get(sprite_pos.with_z(base)) % 3) as i32;
772 for r in 0..rows {
773 painter
774 .aabb(Aabb {
775 min: sprite_pos.with_z(height + 10 + r),
776 max: (sprite_pos + 1).with_z(height + 11 + r),
777 })
778 .rotate_about(Mat3::rotation_z(self.rotation).as_(), center.with_z(base))
779 .fill(Fill::Block(Block::air(
780 match (RandomField::new(0).get(sprite_pos.with_z(base + r)) % 2) as i32 {
781 0 => SpriteKind::Barrel,
782 _ => SpriteKind::CrateBlock,
783 },
784 )));
785 }
786 }
787
788 painter.spawn(
790 EntityInfo::at(self.campfire_pos.map(|e| e as f32 + 0.5))
791 .into_special(SpecialEntity::Waypoint),
792 );
793 }
794}