diff --git a/game/debriefing.py b/game/debriefing.py index ce473ef4..857c4143 100644 --- a/game/debriefing.py +++ b/game/debriefing.py @@ -30,6 +30,7 @@ from game.unitmap import ( FrontLineUnit, GroundObjectUnit, UnitMap, + FlyingUnit, ) from gen.flights.flight import Flight @@ -41,24 +42,24 @@ DEBRIEFING_LOG_EXTENSION = "log" @dataclass(frozen=True) class AirLosses: - player: List[Flight] - enemy: List[Flight] + player: List[FlyingUnit] + enemy: List[FlyingUnit] @property - def losses(self) -> Iterator[Flight]: + def losses(self) -> Iterator[FlyingUnit]: return itertools.chain(self.player, self.enemy) def by_type(self, player: bool) -> Dict[Type[FlyingType], int]: losses_by_type: Dict[Type[FlyingType], int] = defaultdict(int) losses = self.player if player else self.enemy for loss in losses: - losses_by_type[loss.unit_type] += 1 + losses_by_type[loss.flight.unit_type] += 1 return losses_by_type def surviving_flight_members(self, flight: Flight) -> int: losses = 0 for loss in self.losses: - if loss == flight: + if loss.flight == flight: losses += 1 return flight.count - losses @@ -239,14 +240,14 @@ class Debriefing: player_losses = [] enemy_losses = [] for unit_name in self.state_data.killed_aircraft: - flight = self.unit_map.flight(unit_name) - if flight is None: + aircraft = self.unit_map.flight(unit_name) + if aircraft is None: logging.error(f"Could not find Flight matching {unit_name}") continue - if flight.departure.captured: - player_losses.append(flight) + if aircraft.flight.departure.captured: + player_losses.append(aircraft) else: - enemy_losses.append(flight) + enemy_losses.append(aircraft) return AirLosses(player_losses, enemy_losses) def dead_ground_units(self) -> GroundLosses: diff --git a/game/event/event.py b/game/event/event.py index 33334100..98575253 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -123,8 +123,9 @@ class Event: @staticmethod def commit_air_losses(debriefing: Debriefing) -> None: for loss in debriefing.air_losses.losses: - aircraft = loss.unit_type - cp = loss.departure + loss.pilot.alive = False + aircraft = loss.flight.unit_type + cp = loss.flight.departure available = cp.base.total_units_of_type(aircraft) if available <= 0: logging.error( diff --git a/game/squadrons.py b/game/squadrons.py index e571f42f..62083091 100644 --- a/game/squadrons.py +++ b/game/squadrons.py @@ -52,7 +52,7 @@ class Squadron: player: bool def __post_init__(self) -> None: - self.available_pilots = list(self.pilots) + self.available_pilots = list(self.active_pilots) def claim_available_pilot(self) -> Optional[Pilot]: if not self.available_pilots: @@ -78,7 +78,7 @@ class Squadron: self.available_pilots.extend(new_pilots) def return_all_pilots(self) -> None: - self.available_pilots = list(self.pilots) + self.available_pilots = list(self.active_pilots) @property def faker(self) -> Faker: diff --git a/game/unitmap.py b/game/unitmap.py index e8b6ac28..296d5f06 100644 --- a/game/unitmap.py +++ b/game/unitmap.py @@ -7,12 +7,19 @@ from dcs.unitgroup import FlyingGroup, Group, VehicleGroup from dcs.unittype import VehicleType from game import db +from game.squadrons import Pilot from game.theater import Airfield, ControlPoint, TheaterGroundObject from game.theater.theatergroundobject import BuildingGroundObject, SceneryGroundObject from game.transfers import CargoShip, Convoy, TransferOrder from gen.flights.flight import Flight +@dataclass(frozen=True) +class FlyingUnit: + flight: Flight + pilot: Pilot + + @dataclass(frozen=True) class FrontLineUnit: unit_type: Type[VehicleType] @@ -45,7 +52,7 @@ class Building: class UnitMap: def __init__(self) -> None: - self.aircraft: Dict[str, Flight] = {} + self.aircraft: Dict[str, FlyingUnit] = {} self.airfields: Dict[str, Airfield] = {} self.front_line_units: Dict[str, FrontLineUnit] = {} self.ground_object_units: Dict[str, GroundObjectUnit] = {} @@ -55,17 +62,19 @@ class UnitMap: self.airlifts: Dict[str, AirliftUnit] = {} def add_aircraft(self, group: FlyingGroup, flight: Flight) -> None: - for unit in group.units: + for pilot, unit in zip(flight.pilots, group.units): # The actual name is a String (the pydcs translatable string), which # doesn't define __eq__. name = str(unit.name) if name in self.aircraft: raise RuntimeError(f"Duplicate unit name: {name}") - self.aircraft[name] = flight + if pilot is None: + raise ValueError(f"{name} has no pilot assigned") + self.aircraft[name] = FlyingUnit(flight, pilot) if flight.cargo is not None: self.add_airlift_units(group, flight.cargo) - def flight(self, unit_name: str) -> Optional[Flight]: + def flight(self, unit_name: str) -> Optional[FlyingUnit]: return self.aircraft.get(unit_name, None) def add_airfield(self, airfield: Airfield) -> None: