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.

95 lines
2.9 KiB

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