Skip to main content

veloren_world/site/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 = "dyn-lib")]
32    #[unsafe(export_name = "as_dyn_structure_gliderfinish")]
33    fn as_dyn_outer(&self) -> Option<(&dyn Structure, &'static str)> {
34        Some((Self::as_dyn_impl(self), "as_dyn_structure_gliderfinish"))
35    }
36
37    fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
38        let red = Fill::Brick(BlockKind::Wood, Rgb::new(200, 0, 0), 24);
39        let green = Fill::Brick(BlockKind::Wood, Rgb::new(0, 200, 0), 24);
40        let white = Fill::Brick(BlockKind::GlowingRock, Rgb::new(200, 200, 200), 24);
41        let black = Fill::Brick(BlockKind::Wood, Rgb::new(0, 0, 0), 24);
42        let wood = Fill::Brick(BlockKind::Wood, Rgb::new(40, 30, 20), 24);
43
44        let base = self.alt + 6;
45
46        // Base
47        let foundation_0 = painter.aabb(Aabb {
48            min: Vec2::new(
49                self.center.x - self.radius - 4,
50                self.center.y - self.radius - 4,
51            )
52            .with_z(base - 50),
53            max: Vec2::new(
54                self.center.x + self.radius + 4,
55                self.center.y + self.radius + 4,
56            )
57            .with_z(base - 2),
58        });
59        let foundation_1 = painter.aabb(Aabb {
60            min: Vec2::new(
61                self.center.x - self.radius - 3,
62                self.center.y - self.radius - 3,
63            )
64            .with_z(base - 2),
65            max: Vec2::new(
66                self.center.x + self.radius + 3,
67                self.center.y + self.radius + 3,
68            )
69            .with_z(base - 1),
70        });
71        let foundation_2 = painter.aabb(Aabb {
72            min: Vec2::new(
73                self.center.x - self.radius - 2,
74                self.center.y - self.radius - 2,
75            )
76            .with_z(base - 1),
77            max: Vec2::new(
78                self.center.x + self.radius + 2,
79                self.center.y + self.radius + 2,
80            )
81            .with_z(base),
82        });
83        let platform = painter.aabb(Aabb {
84            min: Vec2::new(
85                self.center.x - self.radius - 1,
86                self.center.y - self.radius - 1,
87            )
88            .with_z(base),
89            max: Vec2::new(
90                self.center.x + self.radius + 1,
91                self.center.y + self.radius + 1,
92            )
93            .with_z(base + 1),
94        });
95        let above_platform = painter.aabb(Aabb {
96            min: Vec2::new(
97                self.center.x - self.radius - 4,
98                self.center.y - self.radius - 4,
99            )
100            .with_z(base - 2),
101            max: Vec2::new(
102                self.center.x + self.radius + 4,
103                self.center.y + self.radius + 4,
104            )
105            .with_z(base + 30),
106        });
107
108        // Checkerboard pattern
109        let mut white_fills = Vec::new();
110        let mut black_fills = Vec::new();
111        for i in 0..self.radius * 2 {
112            for j in 0..self.radius * 2 {
113                let white_tile_start = (i % 4 == 0 && j % 4 == 0) || (i % 4 == 2 && j % 4 == 2);
114                let black_tile_start = (i % 4 == 0 && j % 4 == 2) || (i % 4 == 2 && j % 4 == 0);
115                if white_tile_start {
116                    let tile_start = Vec2::new(
117                        self.center.x - self.radius + i,
118                        self.center.y - self.radius + j,
119                    );
120                    let tile_end = tile_start + self.tile_width;
121                    let white_tile = painter.aabb(Aabb {
122                        min: tile_start.with_z(base),
123                        max: tile_end.with_z(base + 1),
124                    });
125                    white_fills.push(white_tile);
126                } else if black_tile_start {
127                    let tile_start = Vec2::new(
128                        self.center.x - self.radius + i,
129                        self.center.y - self.radius + j,
130                    );
131                    let tile_end = tile_start + self.tile_width;
132                    let black_tile = painter.aabb(Aabb {
133                        min: tile_start.with_z(base),
134                        max: tile_end.with_z(base + 1),
135                    });
136                    black_fills.push(black_tile);
137                }
138            }
139        }
140
141        let green_fills = [platform];
142        let red_fills = [foundation_2];
143        let wood_fills = [foundation_0, foundation_1];
144        let clears = [above_platform];
145
146        let fills = [
147            (&clears as &[_], None),
148            (&wood_fills, Some(wood)),
149            (&red_fills, Some(red)),
150            (&green_fills, Some(green)),
151            (&black_fills, Some(black)),
152            (&white_fills, Some(white)),
153        ];
154
155        for (primitives, fill_color_maybe) in fills {
156            for prim in primitives {
157                if let Some(fill_color) = &fill_color_maybe {
158                    prim.fill(fill_color.clone());
159                } else {
160                    prim.clear();
161                }
162            }
163        }
164    }
165}