You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 line
3.1 KiB

  1. use glc::vector::{Angle, Vector2f, Vector4f};
  2. use space_crush_common::{
  3. components::{Fleet, Position},
  4. constants::SHIP_ORBIT_DISTANCE_MAX,
  5. misc::LogResult,
  6. };
  7. use specs::{prelude::*, ReadStorage, System, World, WriteExpect};
  8. use crate::{
  9. components::FleetInfo,
  10. misc::{HorizontalAlign, Text, TextManager, VerticalAlign},
  11. resources::{Camera, Geometry},
  12. Error,
  13. };
  14. pub struct Fleets {
  15. text: Text,
  16. }
  17. #[derive(SystemData)]
  18. pub struct FleetData<'a> {
  19. geometry: WriteExpect<'a, Geometry>,
  20. camera: ReadExpect<'a, Camera>,
  21. positions: ReadStorage<'a, Position>,
  22. fleets: ReadStorage<'a, Fleet>,
  23. fleet_infos: ReadStorage<'a, FleetInfo>,
  24. }
  25. impl Fleets {
  26. pub fn new(manager: &TextManager) -> Result<Self, Error> {
  27. let cache = manager.create_cache()?;
  28. let text = cache
  29. .new_text()
  30. .scale(20.0)
  31. .font("resources/fonts/DroidSansMono.ttf")
  32. .color(0.7, 0.7, 0.7, 1.0)
  33. .vert_align(VerticalAlign::Center)
  34. .horz_align(HorizontalAlign::Center)
  35. .text("")
  36. .build()?;
  37. Ok(Self { text })
  38. }
  39. }
  40. impl<'a> System<'a> for Fleets {
  41. type SystemData = FleetData<'a>;
  42. fn run(&mut self, data: Self::SystemData) {
  43. let FleetData {
  44. mut geometry,
  45. camera,
  46. positions,
  47. fleets,
  48. fleet_infos,
  49. } = data;
  50. gl::enable(gl::BLEND);
  51. for (position, fleet, fleet_info) in (&positions, &fleets, &fleet_infos).join() {
  52. gl::blend_func(gl::SRC_ALPHA, gl::ONE);
  53. gl::blend_equation(gl::FUNC_ADD);
  54. geometry.render_lines(
  55. Vector4f::new(0.5, 0.5, 0.5, 0.05),
  56. &create_circle(position.pos, fleet.orbit_min),
  57. );
  58. geometry.render_lines(
  59. Vector4f::new(0.5, 0.5, 0.5, 0.05),
  60. &create_circle(position.pos, fleet.orbit_max),
  61. );
  62. geometry.render_lines(
  63. Vector4f::new(0.5, 0.5, 0.5, 0.05),
  64. &create_circle(position.pos, SHIP_ORBIT_DISTANCE_MAX * fleet.orbit_max),
  65. );
  66. gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
  67. gl::blend_equation(gl::FUNC_SUBTRACT);
  68. self.text
  69. .update(
  70. 0,
  71. format!(
  72. "F:{}\nB:{}\nT:{}",
  73. fleet_info.count.fighter,
  74. fleet_info.count.bomber,
  75. fleet_info.count.transporter
  76. ),
  77. )
  78. .panic("Unable to update text")
  79. .render_offset(&camera.world_to_window(position.pos));
  80. }
  81. gl::blend_equation(gl::FUNC_ADD);
  82. gl::disable(gl::BLEND);
  83. }
  84. }
  85. fn create_circle(p: Vector2f, r: f32) -> Vec<Vector2f> {
  86. let mut points = Vec::new();
  87. for i in 0..=180 {
  88. points.push(Vector2f::new(
  89. p.x + r * Angle::Deg(i as f32 * 2.0).cos(),
  90. p.y + r * Angle::Deg(i as f32 * 2.0).sin(),
  91. ));
  92. }
  93. points
  94. }