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