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.

67 lines
2.0 KiB

  1. use glc::vector::Vector4f;
  2. use space_crush_common::components::{Player, PlayerOwned, Position, Ship, ShipObstacle};
  3. use specs::{prelude::*, ReadStorage, System, World, WriteExpect};
  4. use crate::resources::Geometry;
  5. #[derive(Default)]
  6. pub struct Ships;
  7. #[derive(SystemData)]
  8. pub struct ShipsData<'a> {
  9. geometry: WriteExpect<'a, Geometry>,
  10. positions: ReadStorage<'a, Position>,
  11. player_owned: ReadStorage<'a, PlayerOwned>,
  12. players: ReadStorage<'a, Player>,
  13. ships: ReadStorage<'a, Ship>,
  14. }
  15. impl<'a> System<'a> for Ships {
  16. type SystemData = ShipsData<'a>;
  17. fn run(&mut self, data: Self::SystemData) {
  18. let ShipsData {
  19. mut geometry,
  20. positions,
  21. player_owned,
  22. players,
  23. ships,
  24. } = data;
  25. gl::enable(gl::BLEND);
  26. gl::blend_func(gl::SRC_ALPHA, gl::ONE);
  27. for (position, player_owned, ship) in (&positions, &player_owned, &ships).join() {
  28. let ship_pos = position.get();
  29. let type_ = ship.type_();
  30. let player_id = player_owned.owner();
  31. let player = players.get(player_id).unwrap();
  32. let ship_data = player.ship_data(type_);
  33. geometry.render_lines(
  34. Vector4f::new(0.0, 0.0, 1.0, 0.2),
  35. &[*ship_pos, ship_pos + ship.dir() * ship_data.speed],
  36. );
  37. geometry.render_lines(
  38. Vector4f::new(1.0, 0.0, 0.0, 0.2),
  39. &[*ship_pos, ship_pos + ship.target_dir() * 100.0],
  40. );
  41. geometry.render_lines(
  42. Vector4f::new(1.0, 1.0, 1.0, 0.2),
  43. &[*ship_pos, *ship.target_pos()],
  44. );
  45. if let ShipObstacle::Known(obstacle) = ship.obstacle() {
  46. let obstacle_pos = positions.get(obstacle).unwrap().get();
  47. geometry.render_lines(
  48. Vector4f::new(0.0, 1.0, 0.0, 0.2),
  49. &[*ship_pos, *obstacle_pos],
  50. );
  51. }
  52. }
  53. gl::disable(gl::BLEND);
  54. }
  55. }