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.

116 lines
4.1 KiB

  1. use shrev::{EventChannel, ReaderId};
  2. use space_crush_common::{
  3. components::{Fleet, FleetOwned, Orbit, Player, Position, Ship, ShipType},
  4. continue_if_none,
  5. misc::WorldHelper,
  6. };
  7. use specs::{prelude::*, Entity, ReadStorage, System, World, WriteStorage};
  8. use crate::{
  9. misc::MouseEvent,
  10. resources::{Camera, Config, InputState, PlayerState},
  11. Error,
  12. };
  13. pub struct FleetControl {
  14. mouse_event_id: ReaderId<MouseEvent>,
  15. target_fleet: Option<Entity>,
  16. }
  17. #[derive(SystemData)]
  18. pub struct FleetControlData<'a> {
  19. player_state: WriteExpect<'a, PlayerState>,
  20. mouse_events: ReadExpect<'a, EventChannel<MouseEvent>>,
  21. input_state: ReadExpect<'a, InputState>,
  22. camera: ReadExpect<'a, Camera>,
  23. config: ReadExpect<'a, Config>,
  24. ships: ReadStorage<'a, Ship>,
  25. fleet_owned: WriteStorage<'a, FleetOwned>,
  26. positions: ReadStorage<'a, Position>,
  27. players: ReadStorage<'a, Player>,
  28. orbits: ReadStorage<'a, Orbit>,
  29. fleets: ReadStorage<'a, Fleet>,
  30. }
  31. impl FleetControl {
  32. pub fn new(world: &mut World) -> Result<Self, Error> {
  33. let mouse_event_id = world.register_event_reader::<MouseEvent>()?;
  34. let target_fleet = None;
  35. Ok(Self {
  36. mouse_event_id,
  37. target_fleet,
  38. })
  39. }
  40. }
  41. impl<'a> System<'a> for FleetControl {
  42. type SystemData = FleetControlData<'a>;
  43. fn run(&mut self, data: Self::SystemData) {
  44. let FleetControlData {
  45. mut player_state,
  46. mouse_events,
  47. input_state,
  48. camera,
  49. config,
  50. ships,
  51. mut fleet_owned,
  52. positions,
  53. players,
  54. orbits,
  55. fleets,
  56. } = data;
  57. let events = mouse_events.read(&mut self.mouse_event_id);
  58. for event in events {
  59. match event {
  60. MouseEvent::ButtonDown(button) if button == &config.input.fleet_move_button => {
  61. let pos = camera.view_to_world(input_state.mouse_pos);
  62. for (position, orbit) in (&positions, &orbits).join() {
  63. let r = orbit.max * orbit.max;
  64. if (position.pos - pos).length_sqr() <= r {
  65. let player_id = player_state.player_id;
  66. let player = continue_if_none!(players.get(player_id));
  67. let fleet_id = continue_if_none!(orbit.fleets.get(player.index));
  68. let fleet_id = *continue_if_none!(fleet_id);
  69. self.target_fleet = Some(fleet_id);
  70. break;
  71. }
  72. }
  73. }
  74. MouseEvent::ButtonUp(button) if button == &config.input.fleet_move_button => {
  75. let selection = player_state.selection.take();
  76. let target_fleet = continue_if_none!(self.target_fleet.take());
  77. let mut selection = continue_if_none!(selection);
  78. let fleet = continue_if_none!(fleets.get(selection.fleet));
  79. for (ship, fleet_owned, _) in (&ships, &mut fleet_owned, &fleet.owned).join() {
  80. match &ship.type_ {
  81. ShipType::Fighter if selection.count.fighter > 0 => {
  82. fleet_owned.owner = target_fleet;
  83. selection.count.fighter -= 1;
  84. }
  85. ShipType::Bomber if selection.count.bomber > 0 => {
  86. fleet_owned.owner = target_fleet;
  87. selection.count.bomber -= 1;
  88. }
  89. ShipType::Transporter if selection.count.transporter > 0 => {
  90. fleet_owned.owner = target_fleet;
  91. selection.count.transporter -= 1;
  92. }
  93. _ => (),
  94. }
  95. }
  96. }
  97. MouseEvent::Move(_, _) => {
  98. self.target_fleet = None;
  99. }
  100. _ => (),
  101. }
  102. }
  103. }
  104. }