|
- use glc::vector::{Angle, Vector2f, Vector4f};
- use space_crush_common::{
- components::{Fleet, Orbit, Player, Position},
- constants::SHIP_ORBIT_DISTANCE_MAX,
- continue_if_none,
- misc::LogResult,
- return_if_none,
- };
- use specs::{prelude::*, ReadExpect, ReadStorage, System, World, WriteExpect};
-
- use crate::{
- misc::{HorizontalAlign, Text, TextManager, VerticalAlign},
- resources::{Camera, Geometry, PlayerState},
- Error,
- };
-
- pub struct Fleets {
- text: Text,
- }
-
- #[derive(SystemData)]
- pub struct FleetData<'a> {
- player_state: ReadExpect<'a, PlayerState>,
- geometry: WriteExpect<'a, Geometry>,
- camera: ReadExpect<'a, Camera>,
- positions: ReadStorage<'a, Position>,
- players: ReadStorage<'a, Player>,
- orbits: ReadStorage<'a, Orbit>,
- fleets: ReadStorage<'a, Fleet>,
- }
-
- impl Fleets {
- pub fn new(manager: &TextManager) -> Result<Self, Error> {
- let cache = manager.create_cache()?;
- let text = cache
- .new_text()
- .scale(20.0)
- .font("resources/fonts/DroidSansMono.ttf")
- .color(0.7, 0.7, 0.7, 1.0)
- .vert_align(VerticalAlign::Center)
- .horz_align(HorizontalAlign::Center)
- .text("")
- .build()?;
-
- Ok(Self { text })
- }
- }
-
- impl<'a> System<'a> for Fleets {
- type SystemData = FleetData<'a>;
-
- fn run(&mut self, data: Self::SystemData) {
- let FleetData {
- player_state,
- mut geometry,
- camera,
- positions,
- players,
- orbits,
- fleets,
- } = data;
-
- let player = return_if_none!(players.get(player_state.player_id));
-
- gl::enable(gl::BLEND);
-
- for (position, orbit) in (&positions, &orbits).join() {
- let fleet_id = continue_if_none!(orbit.fleets.get(player.index));
- let fleet_id = continue_if_none!(fleet_id);
- let fleet = continue_if_none!(fleets.get(*fleet_id));
-
- gl::blend_func(gl::SRC_ALPHA, gl::ONE);
- gl::blend_equation(gl::FUNC_ADD);
- geometry.render_lines(
- Vector4f::new(0.5, 0.5, 0.5, 0.05),
- &create_circle(position.pos, orbit.min),
- );
- geometry.render_lines(
- Vector4f::new(0.5, 0.5, 0.5, 0.05),
- &create_circle(position.pos, orbit.max),
- );
- geometry.render_lines(
- Vector4f::new(0.5, 0.5, 0.5, 0.05),
- &create_circle(position.pos, SHIP_ORBIT_DISTANCE_MAX * orbit.max),
- );
-
- gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
- gl::blend_equation(gl::FUNC_SUBTRACT);
- self.text
- .update(
- 0,
- format!(
- "F:{}\nB:{}\nT:{}",
- fleet.count.fighter, fleet.count.bomber, fleet.count.transporter
- ),
- )
- .panic("Unable to update text")
- .render_offset(&camera.world_to_window(position.pos));
- }
-
- gl::blend_equation(gl::FUNC_ADD);
- gl::disable(gl::BLEND);
- }
- }
-
- fn create_circle(p: Vector2f, r: f32) -> Vec<Vector2f> {
- let mut points = Vec::new();
-
- for i in 0..=180 {
- points.push(Vector2f::new(
- p.x + r * Angle::Deg(i as f32 * 2.0).cos(),
- p.y + r * Angle::Deg(i as f32 * 2.0).sin(),
- ));
- }
-
- points
- }
|