diff --git a/game/dcs/aircrafttype.py b/game/dcs/aircrafttype.py index be23c4fe..808142e5 100644 --- a/game/dcs/aircrafttype.py +++ b/game/dcs/aircrafttype.py @@ -94,6 +94,10 @@ class AircraftType: dcs_unit_type: Type[FlyingType] name: str description: str + year_introduced: str + country_of_origin: str + manufacturer: str + role: str price: int carrier_capable: bool lha_capable: bool @@ -189,11 +193,22 @@ class AircraftType: radio_config = RadioConfig.from_data(data.get("radios", {})) + try: + introduction = data["introduced"] + if introduction is None: + introduction = "N/A" + except KeyError: + introduction = "No data." + for variant in data.get("variants", [aircraft.id]): yield AircraftType( dcs_unit_type=aircraft, name=variant, description=data.get("description", "No data."), + year_introduced=introduction, + country_of_origin=data.get("origin", "No data."), + manufacturer=data.get("manufacturer", "No data."), + role=data.get("role", "No data."), price=price, carrier_capable=data.get("carrier_capable", False), lha_capable=data.get("lha_capable", False), diff --git a/qt_ui/windows/QUnitInfoWindow.py b/qt_ui/windows/QUnitInfoWindow.py index 0438b952..a5c67bb2 100644 --- a/qt_ui/windows/QUnitInfoWindow.py +++ b/qt_ui/windows/QUnitInfoWindow.py @@ -1,3 +1,6 @@ +from __future__ import annotations + +from dataclasses import dataclass from typing import Type, Union import dcs @@ -10,7 +13,7 @@ from PySide2.QtWidgets import ( QTextBrowser, QFrame, ) -from dcs.unittype import UnitType +from dcs.unittype import VehicleType import gen.flights.ai_flight_planner_db from game import db @@ -20,9 +23,58 @@ from gen.flights.flight import FlightType from qt_ui.uiconstants import AIRCRAFT_BANNERS, VEHICLE_BANNERS +@dataclass(frozen=True) +class UnitInfo: + name: str + description: str + introduction_year: str + origin: str + manufacturer: str + role: str + + @classmethod + def from_unit_type( + cls, country: str, unit_type: Union[AircraftType, Type[VehicleType]] + ) -> UnitInfo: + if isinstance(unit_type, AircraftType): + return cls.from_aircraft(unit_type) + else: + return cls.from_vehicle_type(country, unit_type) + + @classmethod + def from_aircraft(cls, aircraft: AircraftType) -> UnitInfo: + return UnitInfo( + aircraft.name, + aircraft.description, + aircraft.year_introduced, + aircraft.country_of_origin, + aircraft.manufacturer, + aircraft.role, + ) + + @classmethod + def from_vehicle_type(cls, country: str, unit_type: Type[VehicleType]) -> UnitInfo: + name = db.unit_get_expanded_info(country, unit_type, "name") + manufacturer = db.unit_get_expanded_info(country, unit_type, "manufacturer") + origin = db.unit_get_expanded_info(country, unit_type, "country-of-origin") + role = db.unit_get_expanded_info(country, unit_type, "role") + introduction = db.unit_get_expanded_info( + country, unit_type, "year-of-variant-introduction" + ) + description = db.unit_get_expanded_info(country, unit_type, "text") + return UnitInfo( + name, + description, + introduction, + origin, + manufacturer, + role, + ) + + class QUnitInfoWindow(QDialog): def __init__( - self, game: Game, unit_type: Union[AircraftType, Type[UnitType]] + self, game: Game, unit_type: Union[AircraftType, Type[VehicleType]] ) -> None: super().__init__() self.setModal(True) @@ -40,9 +92,6 @@ class QUnitInfoWindow(QDialog): self.setMaximumWidth(640) self.setWindowFlags(Qt.WindowStaysOnTopHint) - self.initUi() - - def initUi(self): self.layout = QGridLayout() header = QLabel(self) @@ -50,11 +99,8 @@ class QUnitInfoWindow(QDialog): pixmap = None - if ( - dcs.planes.plane_map.get(self.unit_type.id) is not None - or dcs.helicopters.helicopter_map.get(self.unit_type.id) is not None - ): - pixmap = AIRCRAFT_BANNERS.get(self.unit_type.id) + if isinstance(self.unit_type, AircraftType): + pixmap = AIRCRAFT_BANNERS.get(self.unit_type.dcs_id) elif dcs.vehicles.vehicle_map.get(self.unit_type.id) is not None: pixmap = VEHICLE_BANNERS.get(self.unit_type.id) if pixmap is None: @@ -69,23 +115,20 @@ class QUnitInfoWindow(QDialog): self.details_grid_layout = QGridLayout() self.details_grid_layout.setMargin(0) + unit_info = UnitInfo.from_unit_type(self.game.player_country, self.unit_type) self.name_box = QLabel( - f"Name: {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'manufacturer')} {self.name}" + f"Name: {unit_info.manufacturer} {unit_info.name}" ) self.name_box.setProperty("style", "info-element") - self.country_box = QLabel( - f"Country of Origin: {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'country-of-origin')}" - ) + self.country_box = QLabel(f"Country of Origin: {unit_info.origin}") self.country_box.setProperty("style", "info-element") - self.role_box = QLabel( - f"Role: {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'role')}" - ) + self.role_box = QLabel(f"Role: {unit_info.role}") self.role_box.setProperty("style", "info-element") self.year_box = QLabel( - f"Variant Introduction: {db.unit_get_expanded_info(self.game.player_country, self.unit_type, 'year-of-variant-introduction')}" + f"Variant Introduction: {unit_info.introduction_year}" ) self.year_box.setProperty("style", "info-element") @@ -99,10 +142,7 @@ class QUnitInfoWindow(QDialog): self.gridLayout.addWidget(self.details_grid, 1, 0) # If it's an aircraft, include the task list. - if ( - dcs.planes.plane_map.get(self.unit_type.id) is not None - or dcs.helicopters.helicopter_map.get(self.unit_type.id) is not None - ): + if isinstance(unit_type, AircraftType): self.tasks_box = QLabel( f"In-Game Tasks: {self.generateAircraftTasks()}" ) @@ -112,9 +152,7 @@ class QUnitInfoWindow(QDialog): # Finally, add the description box. self.details_text = QTextBrowser() self.details_text.setProperty("style", "info-desc") - self.details_text.setText( - db.unit_get_expanded_info(self.game.player_country, self.unit_type, "text") - ) + self.details_text.setText(unit_info.description) self.gridLayout.addWidget(self.details_text, 3, 0) self.layout.addLayout(self.gridLayout, 1, 0) @@ -122,26 +160,27 @@ class QUnitInfoWindow(QDialog): def generateAircraftTasks(self) -> str: aircraft_tasks = "" - if self.unit_type in gen.flights.ai_flight_planner_db.CAP_CAPABLE: + unit_type = self.unit_type.dcs_unit_type + if unit_type in gen.flights.ai_flight_planner_db.CAP_CAPABLE: aircraft_tasks = ( aircraft_tasks + f"{FlightType.BARCAP}, {FlightType.ESCORT}, {FlightType.INTERCEPTION}, {FlightType.SWEEP}, {FlightType.TARCAP}, " ) - if self.unit_type in gen.flights.ai_flight_planner_db.CAS_CAPABLE: + if unit_type in gen.flights.ai_flight_planner_db.CAS_CAPABLE: aircraft_tasks = ( aircraft_tasks + f"{FlightType.CAS}, {FlightType.BAI}, {FlightType.OCA_AIRCRAFT}, " ) - if self.unit_type in gen.flights.ai_flight_planner_db.SEAD_CAPABLE: + if unit_type in gen.flights.ai_flight_planner_db.SEAD_CAPABLE: aircraft_tasks = aircraft_tasks + f"{FlightType.SEAD}, " - if self.unit_type in gen.flights.ai_flight_planner_db.DEAD_CAPABLE: + if unit_type in gen.flights.ai_flight_planner_db.DEAD_CAPABLE: aircraft_tasks = aircraft_tasks + f"{FlightType.DEAD}, " - if self.unit_type in gen.flights.ai_flight_planner_db.ANTISHIP_CAPABLE: + if unit_type in gen.flights.ai_flight_planner_db.ANTISHIP_CAPABLE: aircraft_tasks = aircraft_tasks + f"{FlightType.ANTISHIP}, " - if self.unit_type in gen.flights.ai_flight_planner_db.RUNWAY_ATTACK_CAPABLE: + if unit_type in gen.flights.ai_flight_planner_db.RUNWAY_ATTACK_CAPABLE: aircraft_tasks = aircraft_tasks + f"{FlightType.OCA_RUNWAY}, " - if self.unit_type in gen.flights.ai_flight_planner_db.STRIKE_CAPABLE: + if unit_type in gen.flights.ai_flight_planner_db.STRIKE_CAPABLE: aircraft_tasks = aircraft_tasks + f"{FlightType.STRIKE}, " - if self.unit_type in gen.flights.ai_flight_planner_db.REFUELING_CAPABALE: + if unit_type in gen.flights.ai_flight_planner_db.REFUELING_CAPABALE: aircraft_tasks = aircraft_tasks + f"{FlightType.REFUELING}, " return aircraft_tasks[:-2]