diff --git a/game/debriefing.py b/game/debriefing.py index c0221838..ea5b8758 100644 --- a/game/debriefing.py +++ b/game/debriefing.py @@ -22,7 +22,7 @@ from dcs.unittype import FlyingType, UnitType from game import db from game.theater import Airfield, ControlPoint -from game.unitmap import Building, FrontLineUnit, GroundObjectUnit, UnitMap +from game.unitmap import Building, ConvoyUnit, FrontLineUnit, GroundObjectUnit, UnitMap from gen.flights.flight import Flight if TYPE_CHECKING: @@ -60,6 +60,9 @@ class GroundLosses: player_front_line: List[FrontLineUnit] = field(default_factory=list) enemy_front_line: List[FrontLineUnit] = field(default_factory=list) + player_convoy: List[ConvoyUnit] = field(default_factory=list) + enemy_convoy: List[ConvoyUnit] = field(default_factory=list) + player_ground_objects: List[GroundObjectUnit] = field(default_factory=list) enemy_ground_objects: List[GroundObjectUnit] = field(default_factory=list) @@ -120,6 +123,11 @@ class Debriefing: yield from self.ground_losses.player_front_line yield from self.ground_losses.enemy_front_line + @property + def convoy_losses(self) -> Iterator[ConvoyUnit]: + yield from self.ground_losses.player_convoy + yield from self.ground_losses.enemy_convoy + @property def ground_object_losses(self) -> Iterator[GroundObjectUnit]: yield from self.ground_losses.player_ground_objects @@ -148,6 +156,16 @@ class Debriefing: losses_by_type[loss.unit_type] += 1 return losses_by_type + def convoy_losses_by_type(self, player: bool) -> Dict[Type[UnitType], int]: + losses_by_type: Dict[Type[UnitType], int] = defaultdict(int) + if player: + losses = self.ground_losses.player_convoy + else: + losses = self.ground_losses.enemy_convoy + for loss in losses: + losses_by_type[loss.unit_type] += 1 + return losses_by_type + def building_losses_by_type(self, player: bool) -> Dict[str, int]: losses_by_type: Dict[str, int] = defaultdict(int) if player: @@ -186,6 +204,14 @@ class Debriefing: losses.enemy_front_line.append(front_line_unit) continue + convoy_unit = self.unit_map.convoy_unit(unit_name) + if convoy_unit is not None: + if convoy_unit.transfer.player: + losses.player_convoy.append(convoy_unit) + else: + losses.enemy_convoy.append(convoy_unit) + continue + ground_object_unit = self.unit_map.ground_object_unit(unit_name) if ground_object_unit is not None: if ground_object_unit.ground_object.control_point.captured: diff --git a/game/event/event.py b/game/event/event.py index ea7f0e17..157b7461 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -154,6 +154,23 @@ class Event: logging.info(f"{unit_type} destroyed from {control_point}") control_point.base.armor[unit_type] -= 1 + @staticmethod + def commit_convoy_losses(debriefing: Debriefing) -> None: + for loss in debriefing.convoy_losses: + unit_type = loss.unit_type + transfer = loss.transfer + available = loss.transfer.units.get(unit_type, 0) + convoy_name = f"convoy from {transfer.position} to {transfer.destination}" + if available <= 0: + logging.error( + f"Found killed {unit_type} in {convoy_name} but that convoy has " + "none available." + ) + continue + + logging.info(f"{unit_type} destroyed in {convoy_name}") + transfer.units[unit_type] -= 1 + @staticmethod def commit_ground_object_losses(debriefing: Debriefing) -> None: for loss in debriefing.ground_object_losses: @@ -186,6 +203,7 @@ class Event: self.commit_air_losses(debriefing) self.commit_front_line_losses(debriefing) + self.commit_convoy_losses(debriefing) self.commit_ground_object_losses(debriefing) self.commit_building_losses(debriefing) self.commit_damaged_runways(debriefing) diff --git a/qt_ui/windows/QDebriefingWindow.py b/qt_ui/windows/QDebriefingWindow.py index d4fa312b..4b62c397 100644 --- a/qt_ui/windows/QDebriefingWindow.py +++ b/qt_ui/windows/QDebriefingWindow.py @@ -72,6 +72,17 @@ class QDebriefingWindow(QDialog): except AttributeError: logging.exception(f"Issue adding {unit_type} to debriefing information") + convoy_losses = self.debriefing.convoy_losses_by_type(player=True) + for unit_type, count in convoy_losses.items(): + try: + lostUnitsLayout.addWidget( + QLabel(f"{db.unit_type_name(unit_type)} from convoy"), row, 0 + ) + lostUnitsLayout.addWidget(QLabel(str(count)), row, 1) + row += 1 + except AttributeError: + logging.exception(f"Issue adding {unit_type} to debriefing information") + building_losses = self.debriefing.building_losses_by_type(player=True) for building, count in building_losses.items(): try: @@ -113,6 +124,17 @@ class QDebriefingWindow(QDialog): enemylostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1) row += 1 + convoy_losses = self.debriefing.convoy_losses_by_type(player=False) + for unit_type, count in convoy_losses.items(): + try: + lostUnitsLayout.addWidget( + QLabel(f"{db.unit_type_name(unit_type)} from convoy"), row, 0 + ) + lostUnitsLayout.addWidget(QLabel(str(count)), row, 1) + row += 1 + except AttributeError: + logging.exception(f"Issue adding {unit_type} to debriefing information") + building_losses = self.debriefing.building_losses_by_type(player=False) for building, count in building_losses.items(): try: diff --git a/qt_ui/windows/QWaitingForMissionResultWindow.py b/qt_ui/windows/QWaitingForMissionResultWindow.py index 2efa730b..3b06e877 100644 --- a/qt_ui/windows/QWaitingForMissionResultWindow.py +++ b/qt_ui/windows/QWaitingForMissionResultWindow.py @@ -148,16 +148,19 @@ class QWaitingForMissionResultWindow(QDialog): QLabel(str(len(list(debriefing.front_line_losses)))), 1, 1 ) - updateLayout.addWidget(QLabel("Other ground units destroyed"), 2, 0) + updateLayout.addWidget(QLabel("Convoy units destroyed"), 2, 0) + updateLayout.addWidget(QLabel(str(len(list(debriefing.convoy_losses)))), 2, 1) + + updateLayout.addWidget(QLabel("Other ground units destroyed"), 3, 0) updateLayout.addWidget( - QLabel(str(len(list(debriefing.ground_object_losses)))), 2, 1 + QLabel(str(len(list(debriefing.ground_object_losses)))), 3, 1 ) - updateLayout.addWidget(QLabel("Buildings destroyed"), 3, 0) - updateLayout.addWidget(QLabel(str(len(list(debriefing.building_losses)))), 3, 1) + updateLayout.addWidget(QLabel("Buildings destroyed"), 4, 0) + updateLayout.addWidget(QLabel(str(len(list(debriefing.building_losses)))), 4, 1) - updateLayout.addWidget(QLabel("Base Capture Events"), 4, 0) - updateLayout.addWidget(QLabel(str(len(debriefing.base_capture_events))), 4, 1) + updateLayout.addWidget(QLabel("Base Capture Events"), 5, 0) + updateLayout.addWidget(QLabel(str(len(debriefing.base_capture_events))), 5, 1) # Clear previous content of the window for i in reversed(range(self.gridLayout.count())):