use super::*;
use crate::{
site2::{gen::PrimitiveTransform, util::Dir},
Land,
};
use common::terrain::BlockKind;
use rand::prelude::*;
use vek::*;
pub struct GliderRing {
center: Vec2<i32>,
direction: Dir,
number: usize,
base: i32,
ring_thickness: i32,
ring_height: i32,
ring_radius: i32,
}
impl GliderRing {
pub fn generate(
land: &Land,
_rng: &mut impl Rng,
_site: &Site,
wpos: &Vec2<i32>,
number: usize,
direction: Dir,
) -> Self {
Self {
center: *wpos,
direction,
number,
base: land.get_alt_approx(*wpos) as i32 + 1,
ring_thickness: 4,
ring_height: 35,
ring_radius: 16,
}
}
}
impl Structure for GliderRing {
#[cfg(feature = "use-dyn-lib")]
const UPDATE_FN: &'static [u8] = b"render_glider_ring\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "render_glider_ring")]
fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
let rotate_turns = match self.direction {
Dir::X => 0,
Dir::Y => 1,
Dir::NegX => 2,
Dir::NegY => 3,
};
let rotation_center = Vec3::new(self.center.x, self.center.y, self.base);
let red = Fill::Brick(BlockKind::Wood, Rgb::new(200, 0, 0), 24);
let green = Fill::Brick(BlockKind::Wood, Rgb::new(0, 200, 0), 24);
let white = Fill::Brick(BlockKind::GlowingRock, Rgb::new(200, 200, 200), 24);
let black = Fill::Brick(BlockKind::Wood, Rgb::new(0, 0, 0), 24);
let wood = Fill::Brick(BlockKind::Wood, Rgb::new(55, 25, 8), 24);
let ring_base = self.base + self.ring_height;
let ring_diameter = self.ring_radius * 2;
let ring_top = ring_base + ring_diameter;
let base = painter.aabb(Aabb {
min: Vec2::new(self.center.x - 1, self.center.y - 2).with_z(self.base - 30),
max: Vec2::new(self.center.x + 2, self.center.y + 2)
.with_z(self.base + self.ring_height + 1),
});
let green_ring = painter.horizontal_cylinder(
Aabb {
min: Vec2::new(self.center.x - 1, self.center.y - self.ring_radius)
.with_z(ring_base),
max: Vec2::new(self.center.x, self.center.y + self.ring_radius).with_z(ring_top),
},
Dir::X,
);
let red_ring = painter.horizontal_cylinder(
Aabb {
min: Vec2::new(self.center.x, self.center.y - self.ring_radius).with_z(ring_base),
max: Vec2::new(self.center.x + 2, self.center.y + self.ring_radius)
.with_z(ring_top),
},
Dir::X,
);
let front_white_ring = painter.horizontal_cylinder(
Aabb {
min: Vec2::new(
self.center.x - 1,
self.center.y - self.ring_radius + self.ring_thickness - 1,
)
.with_z(ring_base + self.ring_thickness - 1),
max: Vec2::new(
self.center.x,
self.center.y + self.ring_radius - self.ring_thickness + 1,
)
.with_z(ring_top - self.ring_thickness + 1),
},
Dir::X,
);
let back_white_ring = painter.horizontal_cylinder(
Aabb {
min: Vec2::new(
self.center.x + 1,
self.center.y - self.ring_radius + self.ring_thickness - 1,
)
.with_z(ring_base + self.ring_thickness - 1),
max: Vec2::new(
self.center.x + 2,
self.center.y + self.ring_radius - self.ring_thickness + 1,
)
.with_z(ring_top - self.ring_thickness + 1),
},
Dir::X,
);
let mut black_fills = Vec::new();
for y in self.center.y - self.ring_radius + self.ring_thickness - 1
..=self.center.y + self.ring_radius - self.ring_thickness + 1
{
if y % 4 == 0 {
let stripe = painter
.aabb(Aabb {
min: Vec2::new(self.center.x - 1, y + 1).with_z(ring_base),
max: Vec2::new(self.center.x, y + 3).with_z(ring_top),
})
.intersect(front_white_ring);
black_fills.push(stripe);
}
}
for z in ring_base + self.ring_thickness + 3..=ring_top - self.ring_thickness - 9 {
if z % 4 == 0 {
let stripe = painter
.aabb(Aabb {
min: Vec2::new(
self.center.x - 1,
self.center.y - self.ring_radius + self.ring_thickness - 1,
)
.with_z(z + 1),
max: Vec2::new(
self.center.x,
self.center.y + self.ring_radius - self.ring_thickness + 1,
)
.with_z(z + 3),
})
.intersect(front_white_ring);
black_fills.push(stripe);
}
}
let ring_clear = painter.horizontal_cylinder(
Aabb {
min: Vec2::new(
self.center.x - 5,
self.center.y - self.ring_radius + self.ring_thickness,
)
.with_z(ring_base + self.ring_thickness),
max: Vec2::new(
self.center.x + 6,
self.center.y + self.ring_radius - self.ring_thickness,
)
.with_z(ring_top - self.ring_thickness),
},
Dir::X,
);
let sign_base = ring_top - self.ring_thickness - 1;
let sign_height = 7;
let sign = painter.aabb(Aabb {
min: Vec2::new(self.center.x - 1, self.center.y - 3).with_z(sign_base),
max: Vec2::new(self.center.x + 1, self.center.y + 3).with_z(sign_base + sign_height),
});
let numeral_origin = Vec3::new(self.center.x, self.center.y - 2, sign_base + 1);
let numeral = painter
.numeral(numeral_origin, self.number)
.rotate_z_90_about(2, rotation_center);
let wood_fills = [base];
let red_fills = [red_ring];
let green_fills = [green_ring];
let white_fills = [front_white_ring, back_white_ring];
let sign_fills = [numeral];
let black_sign_fills = [sign];
let clear_fills = [ring_clear];
let fills = [
(&wood_fills as &[_], Some(wood)),
(&red_fills, Some(red)),
(&green_fills, Some(green)),
(&white_fills, Some(white.clone())),
(&black_fills, Some(black.clone())),
(&clear_fills, None),
(&black_sign_fills, Some(black)),
(&sign_fills, Some(white)),
];
for (primitives, fill_color_maybe) in fills {
for prim in primitives {
if let Some(fill_color) = &fill_color_maybe {
prim.rotate_z_90_about(rotate_turns, rotation_center)
.fill(fill_color.clone());
} else {
prim.rotate_z_90_about(rotate_turns, rotation_center)
.clear();
}
}
}
}
}