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.

117 lines
4.2 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, GameState, InputState},
  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. game_state: WriteExpect<'a, GameState>,
  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 game_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 = game_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. #[allow(unused_variables)] // TODO
  75. MouseEvent::ButtonUp(button) if button == &config.input.fleet_move_button => {
  76. let selection = game_state.selection.take();
  77. let target_fleet = continue_if_none!(self.target_fleet.take());
  78. let mut selection = continue_if_none!(selection);
  79. let fleet = continue_if_none!(fleets.get(selection.fleet));
  80. for (ship, fleet_owned, _) in (&ships, &mut fleet_owned, fleet.owned()).join() {
  81. match ship.type_() {
  82. ShipType::Fighter if selection.count.fighter > 0 => {
  83. // TODO fleet_owned.set_owner(target_fleet);
  84. selection.count.fighter -= 1;
  85. }
  86. ShipType::Bomber if selection.count.bomber > 0 => {
  87. // TODO fleet_owned.set_owner(target_fleet);
  88. selection.count.bomber -= 1;
  89. }
  90. ShipType::Transporter if selection.count.transporter > 0 => {
  91. // TODO fleet_owned.set_owner(target_fleet);
  92. selection.count.transporter -= 1;
  93. }
  94. _ => (),
  95. }
  96. }
  97. }
  98. MouseEvent::Move(_, _) => {
  99. self.target_fleet = None;
  100. }
  101. _ => (),
  102. }
  103. }
  104. }
  105. }