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.

103 line
3.2 KiB

  1. use shrev::{EventChannel, ReaderId};
  2. use space_crush_common::{
  3. components::{MeetingPoint, Position},
  4. misc::WorldHelper,
  5. systems::FleetControlEvent,
  6. };
  7. use specs::{prelude::*, Entities, Entity, ReadStorage, System, World};
  8. use crate::{
  9. misc::MouseEvent,
  10. resources::{Camera, Config, GameState, InputState, Selection},
  11. Error,
  12. };
  13. pub struct FleetMove {
  14. mouse_event_id: ReaderId<MouseEvent>,
  15. target_meeting_point: Option<Entity>,
  16. }
  17. #[derive(SystemData)]
  18. pub struct FleetMoveData<'a> {
  19. game_state: WriteExpect<'a, GameState>,
  20. fleet_control: WriteExpect<'a, EventChannel<FleetControlEvent>>,
  21. mouse_events: ReadExpect<'a, EventChannel<MouseEvent>>,
  22. input_state: ReadExpect<'a, InputState>,
  23. camera: ReadExpect<'a, Camera>,
  24. config: ReadExpect<'a, Config>,
  25. entities: Entities<'a>,
  26. positions: ReadStorage<'a, Position>,
  27. meeting_points: ReadStorage<'a, MeetingPoint>,
  28. }
  29. impl FleetMove {
  30. pub fn new(world: &mut World) -> Result<Self, Error> {
  31. let mouse_event_id = world.register_event_reader::<MouseEvent>()?;
  32. let target_meeting_point = None;
  33. Ok(Self {
  34. mouse_event_id,
  35. target_meeting_point,
  36. })
  37. }
  38. }
  39. impl<'a> System<'a> for FleetMove {
  40. type SystemData = FleetMoveData<'a>;
  41. fn run(&mut self, data: Self::SystemData) {
  42. let FleetMoveData {
  43. mut game_state,
  44. mut fleet_control,
  45. mouse_events,
  46. input_state,
  47. camera,
  48. config,
  49. entities,
  50. positions,
  51. meeting_points,
  52. } = data;
  53. let events = mouse_events.read(&mut self.mouse_event_id);
  54. for event in events {
  55. match event {
  56. MouseEvent::ButtonDown(button) if button == &config.input.fleet_move_button => {
  57. let pos = camera.view_to_world(input_state.mouse_pos);
  58. for (id, position, meeting_point) in
  59. (&entities, &positions, &meeting_points).join()
  60. {
  61. let r = meeting_point.max() * meeting_point.max();
  62. if (position.get() - pos).length_sqr() <= r {
  63. self.target_meeting_point = Some(id);
  64. break;
  65. }
  66. }
  67. }
  68. MouseEvent::ButtonUp(button) if button == &config.input.fleet_move_button => {
  69. let Selection { fleet, count } = match game_state.selection_mut().take() {
  70. Some(selection) => selection,
  71. None => continue,
  72. };
  73. let target = match self.target_meeting_point {
  74. Some(target) => target,
  75. None => continue,
  76. };
  77. let event = FleetControlEvent::MoveToMeetingPoint {
  78. fleet,
  79. count,
  80. target,
  81. };
  82. fleet_control.single_write(event);
  83. }
  84. MouseEvent::Move(_, _) => {
  85. self.target_meeting_point = None;
  86. }
  87. _ => (),
  88. }
  89. }
  90. }
  91. }