veloren_world/site2/plot/
glider_finish.rs

1use super::*;
2use crate::Land;
3use common::terrain::BlockKind;
4use rand::prelude::*;
5use vek::*;
6
7/// Represents data generated by the `generate()` method
8pub struct GliderFinish {
9    /// Location of center
10    center: Vec2<i32>,
11    /// Approximate altitude
12    pub(crate) alt: i32,
13    /// Tile side length for checkerboard surface
14    tile_width: i32,
15    /// Distance from the center of the checkerboard platform to the edge.
16    radius: i32,
17}
18
19impl GliderFinish {
20    pub fn generate(land: &Land, _rng: &mut impl Rng, _site: &Site, wpos: Vec2<i32>) -> Self {
21        Self {
22            center: wpos,
23            alt: land.get_alt_approx(wpos) as i32,
24            tile_width: 2,
25            radius: 10,
26        }
27    }
28}
29
30impl Structure for GliderFinish {
31    #[cfg(feature = "use-dyn-lib")]
32    const UPDATE_FN: &'static [u8] = b"render_glider_finish\0";
33
34    #[cfg_attr(feature = "be-dyn-lib", export_name = "render_glider_finish")]
35    fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
36        let red = Fill::Brick(BlockKind::Wood, Rgb::new(200, 0, 0), 24);
37        let green = Fill::Brick(BlockKind::Wood, Rgb::new(0, 200, 0), 24);
38        let white = Fill::Brick(BlockKind::GlowingRock, Rgb::new(200, 200, 200), 24);
39        let black = Fill::Brick(BlockKind::Wood, Rgb::new(0, 0, 0), 24);
40        let wood = Fill::Brick(BlockKind::Wood, Rgb::new(40, 30, 20), 24);
41
42        let base = self.alt + 6;
43
44        // Base
45        let foundation_0 = painter.aabb(Aabb {
46            min: Vec2::new(
47                self.center.x - self.radius - 4,
48                self.center.y - self.radius - 4,
49            )
50            .with_z(base - 50),
51            max: Vec2::new(
52                self.center.x + self.radius + 4,
53                self.center.y + self.radius + 4,
54            )
55            .with_z(base - 2),
56        });
57        let foundation_1 = painter.aabb(Aabb {
58            min: Vec2::new(
59                self.center.x - self.radius - 3,
60                self.center.y - self.radius - 3,
61            )
62            .with_z(base - 2),
63            max: Vec2::new(
64                self.center.x + self.radius + 3,
65                self.center.y + self.radius + 3,
66            )
67            .with_z(base - 1),
68        });
69        let foundation_2 = painter.aabb(Aabb {
70            min: Vec2::new(
71                self.center.x - self.radius - 2,
72                self.center.y - self.radius - 2,
73            )
74            .with_z(base - 1),
75            max: Vec2::new(
76                self.center.x + self.radius + 2,
77                self.center.y + self.radius + 2,
78            )
79            .with_z(base),
80        });
81        let platform = painter.aabb(Aabb {
82            min: Vec2::new(
83                self.center.x - self.radius - 1,
84                self.center.y - self.radius - 1,
85            )
86            .with_z(base),
87            max: Vec2::new(
88                self.center.x + self.radius + 1,
89                self.center.y + self.radius + 1,
90            )
91            .with_z(base + 1),
92        });
93        let above_platform = painter.aabb(Aabb {
94            min: Vec2::new(
95                self.center.x - self.radius - 4,
96                self.center.y - self.radius - 4,
97            )
98            .with_z(base - 2),
99            max: Vec2::new(
100                self.center.x + self.radius + 4,
101                self.center.y + self.radius + 4,
102            )
103            .with_z(base + 30),
104        });
105
106        // Checkerboard pattern
107        let mut white_fills = Vec::new();
108        let mut black_fills = Vec::new();
109        for i in 0..self.radius * 2 {
110            for j in 0..self.radius * 2 {
111                let white_tile_start = (i % 4 == 0 && j % 4 == 0) || (i % 4 == 2 && j % 4 == 2);
112                let black_tile_start = (i % 4 == 0 && j % 4 == 2) || (i % 4 == 2 && j % 4 == 0);
113                if white_tile_start {
114                    let tile_start = Vec2::new(
115                        self.center.x - self.radius + i,
116                        self.center.y - self.radius + j,
117                    );
118                    let tile_end = tile_start + self.tile_width;
119                    let white_tile = painter.aabb(Aabb {
120                        min: tile_start.with_z(base),
121                        max: tile_end.with_z(base + 1),
122                    });
123                    white_fills.push(white_tile);
124                } else if black_tile_start {
125                    let tile_start = Vec2::new(
126                        self.center.x - self.radius + i,
127                        self.center.y - self.radius + j,
128                    );
129                    let tile_end = tile_start + self.tile_width;
130                    let black_tile = painter.aabb(Aabb {
131                        min: tile_start.with_z(base),
132                        max: tile_end.with_z(base + 1),
133                    });
134                    black_fills.push(black_tile);
135                }
136            }
137        }
138
139        let green_fills = [platform];
140        let red_fills = [foundation_2];
141        let wood_fills = [foundation_0, foundation_1];
142        let clears = [above_platform];
143
144        let fills = [
145            (&clears as &[_], None),
146            (&wood_fills, Some(wood)),
147            (&red_fills, Some(red)),
148            (&green_fills, Some(green)),
149            (&black_fills, Some(black)),
150            (&white_fills, Some(white)),
151        ];
152
153        for (primitives, fill_color_maybe) in fills {
154            for prim in primitives {
155                if let Some(fill_color) = &fill_color_maybe {
156                    prim.fill(fill_color.clone());
157                } else {
158                    prim.clear();
159                }
160            }
161        }
162    }
163}