Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

114 linhas
3.9 KiB

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