コード例 #1
0
    def _load_all(cls) -> None:
        for file in Path("resources/groups").glob("*.yaml"):
            if not file.is_file():
                raise RuntimeError(f"{file.name} is not a valid ForceGroup")

            with file.open(encoding="utf-8") as data_file:
                data = yaml.safe_load(data_file)

            name = data["name"]

            group_tasks = [
                GroupTask.by_description(n) for n in data.get("tasks")
            ]
            if not group_tasks:
                logging.error(f"ForceGroup {name} has no valid tasking")
                continue

            units: list[UnitType[Any]] = []
            for unit in data.get("units"):
                if GroundUnitType.exists(unit):
                    units.append(GroundUnitType.named(unit))
                elif ShipUnitType.exists(unit):
                    units.append(ShipUnitType.named(unit))
                else:
                    logging.error(
                        f"Unit {unit} of ForceGroup {name} is invalid")
            if len(units) == 0:
                logging.error(f"ForceGroup {name} has no valid units")
                continue

            statics = []
            for static in data.get("statics", []):
                static_type = static_type_from_name(static)
                if static_type is None:
                    logging.error(f"Static {static} for {file} is not valid")
                else:
                    statics.append(static_type)

            layouts = [LAYOUTS.by_name(n) for n in data.get("layouts")]
            if not layouts:
                logging.error(f"ForceGroup {name} has no valid layouts")
                continue

            force_group = ForceGroup(
                name=name,
                units=units,
                statics=statics,
                tasks=group_tasks,
                layouts=layouts,
            )

            cls._by_name[force_group.name] = force_group

        cls._loaded = True
コード例 #2
0
 def unit_type(self) -> Optional[UnitType[Any]]:
     if issubclass(self.type, VehicleType):
         return next(GroundUnitType.for_dcs_type(self.type))
     elif issubclass(self.type, ShipType):
         return next(ShipUnitType.for_dcs_type(self.type))
     # None for not available StaticTypes
     return None
コード例 #3
0
    def for_layout(layout: TgoLayout, faction: Faction) -> ForceGroup:
        """Create a ForceGroup from the given TgoLayout which is usable by the faction

        This will iterate through all possible TgoLayoutGroups and check if the
        unit_types are accessible by the faction. All accessible units will be added to
        the force group
        """
        units: set[UnitType[Any]] = set()
        statics: set[Type[DcsUnitType]] = set()
        for group in layout.all_groups:
            if group.optional and not group.fill:
                continue
            for unit_type in group.possible_types_for_faction(faction):
                if issubclass(unit_type, VehicleType):
                    units.add(next(GroundUnitType.for_dcs_type(unit_type)))
                elif issubclass(unit_type, ShipType):
                    units.add(next(ShipUnitType.for_dcs_type(unit_type)))
                elif issubclass(unit_type, StaticType):
                    statics.add(unit_type)

        return ForceGroup(
            ", ".join([t.description for t in layout.tasks]),
            list(units),
            list(statics),
            layout.tasks,
            [layout],
        )
コード例 #4
0
 def unit_types_for_group(self,
                          group: TgoLayoutGroup) -> Iterator[UnitType[Any]]:
     for dcs_type in self.dcs_unit_types_for_group(group):
         if issubclass(dcs_type, VehicleType):
             yield next(GroundUnitType.for_dcs_type(dcs_type))
         elif issubclass(dcs_type, ShipType):
             yield next(ShipUnitType.for_dcs_type(dcs_type))
コード例 #5
0
 def update_total_value(self):
     total_value = 0
     if not self.ground_object.purchasable:
         return
     for u in self.ground_object.units:
         # Hack: Unknown variant.
         unit_type = next(GroundUnitType.for_dcs_type(vehicles.vehicle_map[u.type]))
         total_value += unit_type.price
     if self.sell_all_button is not None:
         self.sell_all_button.setText("Disband (+$" + str(self.total_value) + "M)")
     self.total_value = total_value
コード例 #6
0
 def make_unit_name(unit: Unit, dead: bool) -> str:
     dead_label = " [DEAD]" if dead else ""
     unit_display_name = unit.type
     dcs_unit_type = vehicle_map.get(unit.type)
     if dcs_unit_type is not None:
         # TODO: Make the TGO contain GroundUnitType instead of the pydcs Group.
         # This is a hack because we can't know which variant was used.
         try:
             unit_display_name = next(
                 GroundUnitType.for_dcs_type(dcs_unit_type)
             ).name
         except StopIteration:
             pass
     return f"Unit #{unit.id} - {unit_display_name}{dead_label}"
コード例 #7
0
 def initialize_for_faction(self, faction: Faction) -> ForceGroup:
     """Initialize a ForceGroup for the given Faction.
     This adds accessible units to LayoutGroups with the fill property"""
     for layout in self.layouts:
         for group in layout.all_groups:
             if group.fill and not self.has_unit_for_layout_group(group):
                 for unit_type in group.possible_types_for_faction(faction):
                     if issubclass(unit_type, VehicleType):
                         self.units.append(
                             next(GroundUnitType.for_dcs_type(unit_type)))
                     elif issubclass(unit_type, ShipType):
                         self.units.append(
                             next(ShipUnitType.for_dcs_type(unit_type)))
                     elif issubclass(unit_type, StaticType):
                         self.statics.append(unit_type)
     return self
コード例 #8
0
    def add_unit_to_group(
        self,
        group: VehicleGroup,
        unit_type: Type[VehicleType],
        name: str,
        position: Point,
        heading: int,
    ) -> Vehicle:
        unit = Vehicle(self.game.next_unit_id(), f"{group.name}|{name}",
                       unit_type.id)
        unit.position = position
        unit.heading = heading
        group.add_unit(unit)

        # get price of unit to calculate the real price of the whole group
        try:
            ground_unit_type = next(GroundUnitType.for_dcs_type(unit_type))
            self.price += ground_unit_type.price
        except StopIteration:
            logging.error(f"Cannot get price for unit {unit_type.name}")

        return unit
コード例 #9
0
    def doLayout(self):

        self.update_total_value()
        self.intelBox = QGroupBox("Units :")
        self.intelLayout = QGridLayout()
        i = 0
        for g in self.ground_object.groups:
            if not hasattr(g, "units_losts"):
                g.units_losts = []
            for unit in g.units:
                unit_display_name = unit.type
                dcs_unit_type = vehicles.vehicle_map.get(unit.type)
                if dcs_unit_type is not None:
                    # Hack: Don't know which variant is used.
                    try:
                        unit_display_name = next(
                            GroundUnitType.for_dcs_type(dcs_unit_type)
                        ).name
                    except StopIteration:
                        pass
                self.intelLayout.addWidget(
                    QLabel(
                        "<b>Unit #"
                        + str(unit.id)
                        + " - "
                        + str(unit_display_name)
                        + "</b>"
                    ),
                    i,
                    0,
                )
                i = i + 1

            for unit in g.units_losts:
                dcs_unit_type = vehicles.vehicle_map.get(unit.type)
                if dcs_unit_type is None:
                    continue

                # Hack: Don't know which variant is used.

                try:
                    unit_type = next(GroundUnitType.for_dcs_type(dcs_unit_type))
                    name = unit_type.name
                    price = unit_type.price
                except StopIteration:
                    name = dcs_unit_type.name
                    price = 0

                self.intelLayout.addWidget(
                    QLabel(f"<b>Unit #{unit.id} - {name}</b> [DEAD]"), i, 0
                )
                if self.cp.captured:
                    repair = QPushButton(f"Repair [{price}M]")
                    repair.setProperty("style", "btn-success")
                    repair.clicked.connect(
                        lambda u=unit, g=g, p=unit_type.price: self.repair_unit(g, u, p)
                    )
                    self.intelLayout.addWidget(repair, i, 1)
                i = i + 1
        stretch = QVBoxLayout()
        stretch.addStretch()
        self.intelLayout.addLayout(stretch, i, 0)

        self.buildingBox = QGroupBox("Buildings :")
        self.buildingsLayout = QGridLayout()

        j = 0
        total_income = 0
        received_income = 0
        for i, building in enumerate(self.buildings):
            if building.dcs_identifier not in FORTIFICATION_BUILDINGS:
                self.buildingsLayout.addWidget(
                    QBuildingInfo(building, self.ground_object), j / 3, j % 3
                )
                j = j + 1

            if building.category in REWARDS.keys():
                total_income = total_income + REWARDS[building.category]
                if not building.is_dead:
                    received_income = received_income + REWARDS[building.category]
            else:
                logging.warning(building.category + " not in REWARDS")

        self.financesBox = QGroupBox("Finances: ")
        self.financesBoxLayout = QGridLayout()
        self.financesBoxLayout.addWidget(
            QLabel("Available: " + str(total_income) + "M"), 2, 1
        )
        self.financesBoxLayout.addWidget(
            QLabel("Receiving: " + str(received_income) + "M"), 2, 2
        )

        self.financesBox.setLayout(self.financesBoxLayout)
        self.buildingBox.setLayout(self.buildingsLayout)
        self.intelBox.setLayout(self.intelLayout)
コード例 #10
0
ファイル: faction.py プロジェクト: Starfire13/dcs_liberation
    def from_json(cls: Type[Faction], json: Dict[str, Any]) -> Faction:
        faction = Faction(locales=json.get("locales"))

        faction.country = json.get("country", "/")
        if faction.country not in [c.name for c in country_dict.values()]:
            raise AssertionError(
                'Faction\'s country ("{}") is not a valid DCS country ID'.
                format(faction.country))

        faction.name = json.get("name", "")
        if not faction.name:
            raise AssertionError("Faction has no valid name")

        faction.authors = json.get("authors", "")
        faction.description = json.get("description", "")

        faction.aircrafts = [
            AircraftType.named(n) for n in json.get("aircrafts", [])
        ]
        faction.awacs = [AircraftType.named(n) for n in json.get("awacs", [])]
        faction.tankers = [
            AircraftType.named(n) for n in json.get("tankers", [])
        ]

        faction.aircrafts = list(
            set(faction.aircrafts + faction.awacs + faction.tankers))

        faction.frontline_units = [
            GroundUnitType.named(n) for n in json.get("frontline_units", [])
        ]
        faction.artillery_units = [
            GroundUnitType.named(n) for n in json.get("artillery_units", [])
        ]
        faction.infantry_units = [
            GroundUnitType.named(n) for n in json.get("infantry_units", [])
        ]
        faction.logistics_units = [
            GroundUnitType.named(n) for n in json.get("logistics_units", [])
        ]
        faction.air_defense_units = [
            GroundUnitType.named(n) for n in json.get("air_defense_units", [])
        ]
        faction.missiles = [
            GroundUnitType.named(n) for n in json.get("missiles", [])
        ]

        faction.naval_units = [
            ShipUnitType.named(n) for n in json.get("naval_units", [])
        ]

        faction.preset_groups = [
            ForceGroup.named(n) for n in json.get("preset_groups", [])
        ]

        faction.requirements = json.get("requirements", {})

        faction.carrier_names = json.get("carrier_names", [])
        faction.helicopter_carrier_names = json.get("helicopter_carrier_names",
                                                    [])

        faction.has_jtac = json.get("has_jtac", False)
        jtac_name = json.get("jtac_unit", None)
        if jtac_name is not None:
            faction.jtac_unit = AircraftType.named(jtac_name)
        else:
            faction.jtac_unit = None

        # Load doctrine
        doctrine = json.get("doctrine", "modern")
        if doctrine == "modern":
            faction.doctrine = MODERN_DOCTRINE
        elif doctrine == "coldwar":
            faction.doctrine = COLDWAR_DOCTRINE
        elif doctrine == "ww2":
            faction.doctrine = WWII_DOCTRINE
        else:
            faction.doctrine = MODERN_DOCTRINE

        # Load the building set
        building_set = json.get("building_set", "default")
        if building_set == "default":
            faction.building_set = DEFAULT_AVAILABLE_BUILDINGS
        elif building_set == "ww2free":
            faction.building_set = WW2_FREE
        elif building_set == "ww2ally":
            faction.building_set = WW2_ALLIES_BUILDINGS
        elif building_set == "ww2germany":
            faction.building_set = WW2_GERMANY_BUILDINGS
        else:
            faction.building_set = DEFAULT_AVAILABLE_BUILDINGS

        # Add required buildings for the game logic (e.g. ammo, factory..)
        faction.building_set.extend(REQUIRED_BUILDINGS)

        # Load liveries override
        faction.liveries_overrides = {}
        liveries_overrides = json.get("liveries_overrides", {})
        for name, livery in liveries_overrides.items():
            aircraft = AircraftType.named(name)
            faction.liveries_overrides[aircraft] = [s.lower() for s in livery]

        faction.unrestricted_satnav = json.get("unrestricted_satnav", False)

        return faction
コード例 #11
0
ファイル: faction.py プロジェクト: kavinsky/dcs_liberation
    def from_json(cls: Type[Faction], json: Dict[str, Any]) -> Faction:
        faction = Faction(locales=json.get("locales"))

        faction.country = json.get("country", "/")
        if faction.country not in [c.name for c in country_dict.values()]:
            raise AssertionError(
                'Faction\'s country ("{}") is not a valid DCS country ID'.format(
                    faction.country
                )
            )

        faction.name = json.get("name", "")
        if not faction.name:
            raise AssertionError("Faction has no valid name")

        faction.authors = json.get("authors", "")
        faction.description = json.get("description", "")

        faction.aircrafts = [AircraftType.named(n) for n in json.get("aircrafts", [])]
        faction.awacs = [AircraftType.named(n) for n in json.get("awacs", [])]
        faction.tankers = [AircraftType.named(n) for n in json.get("tankers", [])]

        faction.aircrafts = list(
            set(faction.aircrafts + faction.awacs + faction.tankers)
        )

        faction.frontline_units = [
            GroundUnitType.named(n) for n in json.get("frontline_units", [])
        ]
        faction.artillery_units = [
            GroundUnitType.named(n) for n in json.get("artillery_units", [])
        ]
        faction.infantry_units = [
            GroundUnitType.named(n) for n in json.get("infantry_units", [])
        ]
        faction.logistics_units = [
            GroundUnitType.named(n) for n in json.get("logistics_units", [])
        ]

        faction.ewrs = json.get("ewrs", [])

        faction.air_defenses = json.get("air_defenses", [])
        # Compatibility for older factions. All air defenses now belong to a
        # single group and the generator decides what belongs where.
        faction.air_defenses.extend(json.get("sams", []))
        faction.air_defenses.extend(json.get("shorads", []))

        faction.missiles = json.get("missiles", [])
        faction.coastal_defenses = json.get("coastal_defenses", [])
        faction.requirements = json.get("requirements", {})

        faction.carrier_names = json.get("carrier_names", [])
        faction.helicopter_carrier_names = json.get("helicopter_carrier_names", [])
        faction.navy_generators = json.get("navy_generators", [])
        faction.aircraft_carrier = load_all_ships(json.get("aircraft_carrier", []))
        faction.helicopter_carrier = load_all_ships(json.get("helicopter_carrier", []))
        faction.destroyers = load_all_ships(json.get("destroyers", []))
        faction.cruisers = load_all_ships(json.get("cruisers", []))
        faction.has_jtac = json.get("has_jtac", False)
        jtac_name = json.get("jtac_unit", None)
        if jtac_name is not None:
            faction.jtac_unit = AircraftType.named(jtac_name)
        else:
            faction.jtac_unit = None
        faction.navy_group_count = int(json.get("navy_group_count", 1))
        faction.missiles_group_count = int(json.get("missiles_group_count", 0))
        faction.coastal_group_count = int(json.get("coastal_group_count", 0))

        # Load doctrine
        doctrine = json.get("doctrine", "modern")
        if doctrine == "modern":
            faction.doctrine = MODERN_DOCTRINE
        elif doctrine == "coldwar":
            faction.doctrine = COLDWAR_DOCTRINE
        elif doctrine == "ww2":
            faction.doctrine = WWII_DOCTRINE
        else:
            faction.doctrine = MODERN_DOCTRINE

        # Load the building set
        building_set = json.get("building_set", "default")
        if building_set == "default":
            faction.building_set = DEFAULT_AVAILABLE_BUILDINGS
        elif building_set == "ww2free":
            faction.building_set = WW2_FREE
        elif building_set == "ww2ally":
            faction.building_set = WW2_ALLIES_BUILDINGS
        elif building_set == "ww2germany":
            faction.building_set = WW2_GERMANY_BUILDINGS
        else:
            faction.building_set = DEFAULT_AVAILABLE_BUILDINGS

        # Load liveries override
        faction.liveries_overrides = {}
        liveries_overrides = json.get("liveries_overrides", {})
        for name, livery in liveries_overrides.items():
            aircraft = AircraftType.named(name)
            faction.liveries_overrides[aircraft] = [s.lower() for s in livery]

        faction.unrestricted_satnav = json.get("unrestricted_satnav", False)

        return faction