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