選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

167 行
4.9 KiB

  1. use shrev::{EventChannel, ReaderId};
  2. use specs::{
  3. prelude::*, Entities, Entity, LazyUpdate, ReadExpect, ReadStorage, System, World, WriteStorage,
  4. };
  5. use crate::{
  6. components::{
  7. Fleet, FleetMoving, FleetOrbiting, FleetOwned, MeetingPoint, Player, PlayerOwned,
  8. ShipMoving, ShipOrbiting,
  9. },
  10. misc::{LogResult, WorldHelper},
  11. Error,
  12. };
  13. pub struct ShipControl {
  14. ship_control_event_id: ReaderId<ShipControlEvent>,
  15. }
  16. #[derive(Debug)]
  17. pub enum ShipControlEvent {
  18. SetMoving { ship: Entity, fleet: Entity },
  19. SetOrbiting { ship: Entity, target: Entity },
  20. }
  21. #[derive(SystemData)]
  22. pub struct ShipControlData<'a> {
  23. ship_control_events: ReadExpect<'a, EventChannel<ShipControlEvent>>,
  24. lazy: Read<'a, LazyUpdate>,
  25. entities: Entities<'a>,
  26. players: ReadStorage<'a, Player>,
  27. player_owned: WriteStorage<'a, PlayerOwned>,
  28. fleets: WriteStorage<'a, Fleet>,
  29. fleets_moving: WriteStorage<'a, FleetMoving>,
  30. fleets_orbiting: WriteStorage<'a, FleetOrbiting>,
  31. meeting_points: WriteStorage<'a, MeetingPoint>,
  32. ships_orbiting: WriteStorage<'a, ShipOrbiting>,
  33. ships_moving: WriteStorage<'a, ShipMoving>,
  34. fleet_owned: WriteStorage<'a, FleetOwned>,
  35. }
  36. struct Processor<'a> {
  37. lazy: Read<'a, LazyUpdate>,
  38. entities: Entities<'a>,
  39. players: ReadStorage<'a, Player>,
  40. player_owned: WriteStorage<'a, PlayerOwned>,
  41. fleets: WriteStorage<'a, Fleet>,
  42. fleets_moving: WriteStorage<'a, FleetMoving>,
  43. fleets_orbiting: WriteStorage<'a, FleetOrbiting>,
  44. meeting_points: WriteStorage<'a, MeetingPoint>,
  45. ships_orbiting: WriteStorage<'a, ShipOrbiting>,
  46. ships_moving: WriteStorage<'a, ShipMoving>,
  47. fleet_owned: WriteStorage<'a, FleetOwned>,
  48. }
  49. impl ShipControl {
  50. pub fn new(world: &mut World) -> Result<Self, Error> {
  51. world.insert(EventChannel::<ShipControlEvent>::default());
  52. let ship_control_event_id = world.register_event_reader::<ShipControlEvent>()?;
  53. Ok(Self {
  54. ship_control_event_id,
  55. })
  56. }
  57. }
  58. impl<'a> System<'a> for ShipControl {
  59. type SystemData = ShipControlData<'a>;
  60. fn run(&mut self, data: Self::SystemData) {
  61. let ShipControlData {
  62. ship_control_events,
  63. lazy,
  64. entities,
  65. players,
  66. player_owned,
  67. fleets,
  68. fleets_moving,
  69. fleets_orbiting,
  70. meeting_points,
  71. ships_orbiting,
  72. ships_moving,
  73. fleet_owned,
  74. } = data;
  75. let mut processor = Processor {
  76. lazy,
  77. entities,
  78. players,
  79. player_owned,
  80. fleets,
  81. fleets_moving,
  82. fleets_orbiting,
  83. meeting_points,
  84. ships_orbiting,
  85. ships_moving,
  86. fleet_owned,
  87. };
  88. let events = ship_control_events.read(&mut self.ship_control_event_id);
  89. for event in events {
  90. match event {
  91. ShipControlEvent::SetMoving { ship, fleet } => processor.set_moving(*ship, *fleet),
  92. ShipControlEvent::SetOrbiting { ship, target } => {
  93. processor.set_orbiting(*ship, *target)
  94. }
  95. }
  96. }
  97. }
  98. }
  99. impl Processor<'_> {
  100. fn set_moving(&mut self, ship_id: Entity, fleet_id: Entity) {
  101. let fleet_owned = self.fleet_owned.get_mut(ship_id).unwrap();
  102. fleet_owned.set_owner(fleet_id);
  103. self.ships_orbiting.remove(ship_id);
  104. self.ships_moving
  105. .insert(ship_id, ShipMoving::new())
  106. .panic("Unable to create component 'ShipsMoving'");
  107. }
  108. fn set_orbiting(&mut self, ship_id: Entity, target_id: Entity) {
  109. let player_owned = self.player_owned.get(ship_id).unwrap();
  110. let player_id = player_owned.owner();
  111. let player = self.players.get(player_id).unwrap();
  112. let meeting_point = self.meeting_points.get_mut(target_id).unwrap();
  113. let fleet_id = match meeting_point.fleet(player.index()) {
  114. Some(fleet_id) => fleet_id,
  115. None => {
  116. let fleet_id = Fleet::builder()
  117. .player(player_id)
  118. .orbiting(target_id)
  119. .lazy(
  120. &self.lazy,
  121. &self.entities,
  122. &mut self.player_owned,
  123. &mut self.fleets,
  124. &mut self.fleets_moving,
  125. &mut self.fleets_orbiting,
  126. )
  127. .panic("Unable to create new entitiy: Fleet");
  128. meeting_point.add_fleet(player.index(), fleet_id);
  129. fleet_id
  130. }
  131. };
  132. let fleet_owned = self.fleet_owned.get_mut(ship_id).unwrap();
  133. fleet_owned.set_owner(fleet_id);
  134. self.ships_moving.remove(ship_id);
  135. self.ships_orbiting
  136. .insert(ship_id, ShipOrbiting::new())
  137. .panic("Unable to create component 'ShipOrbiting'");
  138. }
  139. }