Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

147 Zeilen
4.9 KiB

  1. use shrev::{EventChannel, ReaderId};
  2. use specs::{
  3. prelude::*, saveload::MarkedBuilder, Entities, Entity, LazyUpdate, ReadExpect, ReadStorage,
  4. System, World, WriteStorage,
  5. };
  6. use crate::{
  7. components::{
  8. Fleet, FleetOwned, Orbit, OrbitOwned, Player, PlayerOwned, Ship, ShipCount, ShipType,
  9. },
  10. continue_if_none,
  11. misc::{LogResult, PersistWorld, Persistence, WorldHelper},
  12. Error,
  13. };
  14. pub struct FleetControl {
  15. fleet_control_event_id: ReaderId<FleetControlEvent>,
  16. }
  17. #[derive(Debug)]
  18. pub enum FleetControlEvent {
  19. Move(MoveArgs),
  20. }
  21. #[derive(Debug)]
  22. pub struct MoveArgs {
  23. player: Entity,
  24. target: Entity,
  25. fleet: Entity,
  26. count: ShipCount,
  27. }
  28. #[derive(SystemData)]
  29. pub struct FleetControlData<'a> {
  30. lazy: Read<'a, LazyUpdate>,
  31. entities: Entities<'a>,
  32. fleet_control_events: ReadExpect<'a, EventChannel<FleetControlEvent>>,
  33. player_owned: WriteStorage<'a, PlayerOwned>,
  34. orbit_owned: WriteStorage<'a, OrbitOwned>,
  35. fleet_owned: WriteStorage<'a, FleetOwned>,
  36. orbits: WriteStorage<'a, Orbit>,
  37. fleets: WriteStorage<'a, Fleet>,
  38. players: ReadStorage<'a, Player>,
  39. ships: ReadStorage<'a, Ship>,
  40. }
  41. impl FleetControl {
  42. pub fn new(world: &mut World) -> Result<Self, Error> {
  43. world.insert(EventChannel::<FleetControlEvent>::default());
  44. let fleet_control_event_id = world.register_event_reader::<FleetControlEvent>()?;
  45. Ok(Self {
  46. fleet_control_event_id,
  47. })
  48. }
  49. }
  50. impl<'a> System<'a> for FleetControl {
  51. type SystemData = FleetControlData<'a>;
  52. fn run(&mut self, data: Self::SystemData) {
  53. let FleetControlData {
  54. lazy,
  55. entities,
  56. fleet_control_events,
  57. mut player_owned,
  58. mut orbit_owned,
  59. mut fleet_owned,
  60. mut orbits,
  61. mut fleets,
  62. players,
  63. ships,
  64. } = data;
  65. let events = fleet_control_events.read(&mut self.fleet_control_event_id);
  66. for event in events {
  67. match event {
  68. FleetControlEvent::Move(args) if args.count.is_all() => {
  69. let orbit_owned = continue_if_none!(orbit_owned.get_mut(args.fleet));
  70. orbit_owned.set_owner(args.target);
  71. }
  72. FleetControlEvent::Move(args) => {
  73. let target_orbit = continue_if_none!(orbits.get_mut(args.target));
  74. let player = continue_if_none!(players.get(args.player));
  75. let mut count = args.count;
  76. let target_fleet = match target_orbit.fleet_mut(player.index()) {
  77. Some(fleet) => *fleet,
  78. f @ None => {
  79. let fleet = lazy
  80. .create_entity(&entities)
  81. .marked::<<PersistWorld as Persistence>::Marker>()
  82. .build();
  83. player_owned
  84. .insert(fleet, PlayerOwned::new(args.player))
  85. .error("Unable to insert component: PlayerOwned");
  86. orbit_owned
  87. .insert(fleet, OrbitOwned::new(args.target))
  88. .error("Unable to insert component: OrbitOwned");
  89. fleets
  90. .insert(fleet, Fleet::default())
  91. .error("Unable to insert component: Fleet");
  92. *f = Some(fleet);
  93. fleet
  94. }
  95. };
  96. let source_fleet = continue_if_none!(fleets.get(args.fleet));
  97. let data = (&mut fleet_owned, &ships, source_fleet.owned());
  98. for (fleet_owned, ship, _) in data.join() {
  99. match ship.type_() {
  100. ShipType::Fighter if count.fighter > 0 => {
  101. count.fighter -= 1;
  102. fleet_owned.set_owner(target_fleet);
  103. }
  104. ShipType::Bomber if count.bomber > 0 => {
  105. count.bomber -= 1;
  106. fleet_owned.set_owner(target_fleet);
  107. }
  108. ShipType::Transporter if count.transporter > 0 => {
  109. count.transporter -= 1;
  110. fleet_owned.set_owner(target_fleet);
  111. }
  112. _ => (),
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. }
  120. impl FleetControlEvent {
  121. pub fn move_(player: Entity, target: Entity, fleet: Entity, count: ShipCount) -> Self {
  122. Self::Move(MoveArgs {
  123. player,
  124. target,
  125. fleet,
  126. count,
  127. })
  128. }
  129. }