diff --git a/game/armedforces/forcegroup.py b/game/armedforces/forcegroup.py index 9c1c7c62..4f09b738 100644 --- a/game/armedforces/forcegroup.py +++ b/game/armedforces/forcegroup.py @@ -62,6 +62,8 @@ class ForceGroup: 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))) @@ -81,6 +83,36 @@ class ForceGroup: def __str__(self) -> str: return self.name + def has_unit_for_layout_group(self, group: TgoLayoutGroup) -> bool: + for unit in self.units: + if ( + unit.dcs_unit_type in group.unit_types + or unit.unit_class in group.unit_classes + ): + return True + return False + + @classmethod + def for_faction_by_name(cls, name: str, faction: Faction) -> ForceGroup: + """Load a PresetGroup as ForceGroup with faction sensitive handling""" + force_group = cls.named(name) + for layout in force_group.layouts: + for groups in layout.groups.values(): + for group in groups: + if group.fill and not force_group.has_unit_for_layout_group(group): + for unit_type in group.possible_types_for_faction(faction): + if issubclass(unit_type, VehicleType): + force_group.units.append( + next(GroundUnitType.for_dcs_type(unit_type)) + ) + elif issubclass(unit_type, ShipType): + force_group.units.append( + next(ShipUnitType.for_dcs_type(unit_type)) + ) + elif issubclass(unit_type, StaticType): + force_group.statics.append(unit_type) + return force_group + @classmethod def named(cls, name: str) -> ForceGroup: if not cls._loaded: diff --git a/game/factions/faction.py b/game/factions/faction.py index 3503cda2..53312c4f 100644 --- a/game/factions/faction.py +++ b/game/factions/faction.py @@ -216,7 +216,8 @@ class Faction: # This has to be loaded AFTER GroundUnitType and ShipUnitType to work properly faction.preset_groups = [ - ForceGroup.named(n) for n in json.get("preset_groups", []) + ForceGroup.for_faction_by_name(n, faction) + for n in json.get("preset_groups", []) ] faction.requirements = json.get("requirements", {}) diff --git a/game/layout/layout.py b/game/layout/layout.py index 45b7878d..667c69f5 100644 --- a/game/layout/layout.py +++ b/game/layout/layout.py @@ -96,6 +96,9 @@ class TgoLayoutGroup: # Defines if this groupTemplate is required or not optional: bool = False + # Should this be filled by accessible units if optional or not + fill: bool = True + def possible_types_for_faction(self, faction: Faction) -> list[Type[DcsUnitType]]: """Determine the possible dcs unit types for the TgoLayoutGroup and the given faction""" unit_types = [t for t in self.unit_types if faction.has_access_to_dcs_type(t)] diff --git a/game/layout/layoutloader.py b/game/layout/layoutloader.py index c6548695..3fef361a 100644 --- a/game/layout/layoutloader.py +++ b/game/layout/layoutloader.py @@ -166,6 +166,7 @@ class LayoutLoader: group_mapping.fallback_classes, ) group_layout.optional = group_mapping.optional + group_layout.fill = group_mapping.fill # Add the group at the correct index layout.add_layout_group(group_name, group_layout, g_id) layout_unit = LayoutUnit.from_unit(unit) diff --git a/game/layout/layoutmapping.py b/game/layout/layoutmapping.py index a4dea739..b7f19550 100644 --- a/game/layout/layoutmapping.py +++ b/game/layout/layoutmapping.py @@ -19,6 +19,9 @@ class GroupLayoutMapping: # Defines if the group is required for the template or can be skipped optional: bool = False + # Should this be filled by accessible units if optional or not + fill: bool = True + # All static units for the group statics: list[str] = field(default_factory=list) @@ -40,6 +43,7 @@ class GroupLayoutMapping: @staticmethod def from_dict(d: dict[str, Any]) -> GroupLayoutMapping: optional = d["optional"] if "optional" in d else False + fill = d["fill"] if "fill" in d else True statics = d["statics"] if "statics" in d else [] unit_count = d["unit_count"] if "unit_count" in d else [] unit_types = [] @@ -59,6 +63,7 @@ class GroupLayoutMapping: return GroupLayoutMapping( d["name"], optional, + fill, statics, unit_count, unit_types, diff --git a/resources/layouts/anti_air/4_Launcher_Site.yaml b/resources/layouts/anti_air/4_Launcher_Site.yaml index 8748de79..269a2490 100644 --- a/resources/layouts/anti_air/4_Launcher_Site.yaml +++ b/resources/layouts/anti_air/4_Launcher_Site.yaml @@ -12,12 +12,14 @@ groups: - SearchTrackRadar - name: Track Radar optional: true # Allow groups without TR + fill: false # Do not fill with faction possible units unit_count: - 1 unit_classes: - TrackRadar - name: Command Post optional: true + fill: false # Do not fill with faction possible units unit_count: - 1 unit_classes: diff --git a/resources/layouts/anti_air/6_Launcher_Site.yaml b/resources/layouts/anti_air/6_Launcher_Site.yaml index b5ff9617..dd7aa4b2 100644 --- a/resources/layouts/anti_air/6_Launcher_Site.yaml +++ b/resources/layouts/anti_air/6_Launcher_Site.yaml @@ -12,17 +12,18 @@ groups: - SearchTrackRadar - name: Track Radar optional: true # Allow groups without TR + fill: false # Do not fill with faction possible units unit_count: - 1 unit_classes: - TrackRadar - name: Command Post optional: true + fill: false # Do not fill with faction possible units unit_count: - 1 unit_classes: - CommandPost - - name: Launcher unit_count: - 6 diff --git a/resources/layouts/anti_air/Cold_War_Flak_Site.yaml b/resources/layouts/anti_air/Cold_War_Flak_Site.yaml index c0028079..bb271d91 100644 --- a/resources/layouts/anti_air/Cold_War_Flak_Site.yaml +++ b/resources/layouts/anti_air/Cold_War_Flak_Site.yaml @@ -3,8 +3,9 @@ tasks: - AAA groups: - AAA: - - name: Cold War Flak Site Radar + - name: Cold War Flak Site Radar optional: true # Only available to Late Cold War + fill: false # Do not fill with faction possible units unit_count: - 1 unit_classes: diff --git a/resources/layouts/anti_air/SHORAD_TR.yaml b/resources/layouts/anti_air/SHORAD_TR.yaml index 01e1e3d8..cde98530 100644 --- a/resources/layouts/anti_air/SHORAD_TR.yaml +++ b/resources/layouts/anti_air/SHORAD_TR.yaml @@ -5,6 +5,7 @@ groups: - SHORAD: - name: SHORAD STR optional: true + fill: false # Do not fill with faction possible units unit_count: - 1 unit_classes: @@ -13,6 +14,7 @@ groups: - TrackRadar - name: SHORAD OTR optional: true + fill: false # Do not fill with faction possible units unit_count: - 1 unit_classes: