veloren_world/site2/plot/
barn.rs

1use super::*;
2use crate::Land;
3use common::generation::EntityInfo;
4use gen::render_prefab;
5use rand::prelude::*;
6use vek::*;
7
8pub struct Barn {
9    /// Tile position of the door tile
10    pub door_tile: Vec2<i32>,
11    /// Axis aligned bounding region for the house
12    bounds: Aabr<i32>,
13    /// Approximate altitude of the door tile
14    pub(crate) alt: i32,
15    is_desert: bool,
16}
17
18impl Barn {
19    pub fn generate(
20        land: &Land,
21        _rng: &mut impl Rng,
22        site: &Site,
23        door_tile: Vec2<i32>,
24        door_dir: Vec2<i32>,
25        tile_aabr: Aabr<i32>,
26        is_desert: bool,
27    ) -> Self {
28        let door_tile_pos = site.tile_center_wpos(door_tile);
29        let bounds = Aabr {
30            min: site.tile_wpos(tile_aabr.min),
31            max: site.tile_wpos(tile_aabr.max),
32        };
33        Self {
34            door_tile: door_tile_pos,
35            bounds,
36            alt: land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) as i32 + 2,
37            is_desert,
38        }
39    }
40}
41
42impl Structure for Barn {
43    #[cfg(feature = "use-dyn-lib")]
44    const UPDATE_FN: &'static [u8] = b"render_barn\0";
45
46    #[cfg_attr(feature = "be-dyn-lib", export_name = "render_barn")]
47    fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
48        let base = self.alt;
49        let center = self.bounds.center();
50
51        let length = 18;
52        let width = 6;
53
54        // solid dirt to fill any gaps underneath the barn
55        let dirt = Fill::Block(Block::new(BlockKind::Earth, Rgb::new(161, 116, 86)));
56
57        painter
58            .aabb(Aabb {
59                min: Vec2::new(center.x - length - 4, center.y - width - 5).with_z(base - 10),
60                max: Vec2::new(center.x + length + 9, center.y + width + 8).with_z(base - 1),
61            })
62            .fill(dirt);
63
64        // air to clear any hills that appear inside of the the barn
65        let air = Fill::Block(Block::new(BlockKind::Air, Rgb::new(255, 255, 255)));
66
67        painter
68            .aabb(Aabb {
69                min: Vec2::new(center.x - length - 4, center.y - width - 5).with_z(base),
70                max: Vec2::new(center.x + length + 9, center.y + width + 8).with_z(base + 20),
71            })
72            .fill(air);
73
74        // Barn prefab
75        let barn_path = "site_structures.plot_structures.barn";
76        let entrance_pos: Vec3<i32> = (center.x, center.y, self.alt).into();
77
78        let barn_site_pos: Vec3<i32> = entrance_pos + Vec3::new(0, 0, -1);
79        render_prefab(barn_path, barn_site_pos, painter);
80
81        // barn animals
82        let mut thread_rng = thread_rng();
83
84        let barn_animals = [
85            "common.entity.wild.peaceful.cattle",
86            "common.entity.wild.peaceful.horse",
87        ];
88
89        let desert_barn_animals = [
90            "common.entity.wild.peaceful.antelope",
91            "common.entity.wild.peaceful.zebra",
92            "common.entity.wild.peaceful.camel",
93        ];
94
95        for _ in 1..=5 {
96            let npc_rng = thread_rng.gen_range(0..=1);
97            let desert_npc_rng = thread_rng.gen_range(0..=2);
98
99            let spec = if self.is_desert {
100                desert_barn_animals[desert_npc_rng]
101            } else {
102                barn_animals[npc_rng]
103            };
104
105            painter.spawn(
106                EntityInfo::at(Vec3::new(center.x, center.y, self.alt).as_()).with_asset_expect(
107                    spec,
108                    &mut thread_rng,
109                    None,
110                ),
111            );
112        }
113    }
114}