diff --git a/game/debriefing.py b/game/debriefing.py index 5886270e..b33b24b6 100644 --- a/game/debriefing.py +++ b/game/debriefing.py @@ -87,8 +87,8 @@ class Debriefing: for i, ground_object in enumerate(cp.ground_objects): logging.info(unit) - logging.info(ground_object.string_identifier) - if ground_object.matches_string_identifier(unit): + logging.info(ground_object.group_name) + if ground_object.is_same_group(unit): unit = DebriefingDeadUnitInfo(country, player_unit, ground_object.dcs_identifier) self.dead_buildings.append(unit) elif ground_object.dcs_identifier in ["AA", "CARRIER", "LHA"]: diff --git a/game/event/event.py b/game/event/event.py index a45b64eb..5eda578b 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -145,8 +145,8 @@ class Event: if ground_object.is_dead: continue - if ground_object.matches_string_identifier(destroyed_ground_unit_name): - logging.info("cp {} killing ground object {}".format(cp, ground_object.string_identifier)) + if ground_object.is_same_group(destroyed_ground_unit_name): + logging.info("cp {} killing ground object {}".format(cp, ground_object.group_name)) cp.ground_objects[i].is_dead = True info = Information("Building destroyed", diff --git a/gen/aircraft.py b/gen/aircraft.py index f2269012..fccfdacb 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -1298,7 +1298,7 @@ class DeadIngressBuilder(PydcsWaypointBuilder): target_group = self.package.target if isinstance(target_group, TheaterGroundObject): - tgroup = self.mission.find_group(target_group.group_identifier, search="match") # Match search is used due to TheaterGroundObject.name not matching + tgroup = self.mission.find_group(target_group.group_name, search="match") # Match search is used due to TheaterGroundObject.name not matching if tgroup is not None: # the Mission group name because of SkyNet prefixes. task = AttackGroup(tgroup.id) task.params["expend"] = "All" @@ -1309,7 +1309,7 @@ class DeadIngressBuilder(PydcsWaypointBuilder): task.params["groupAttack"] = True waypoint.tasks.append(task) else: - logging.error(f"Could not find group for DEAD mission {target_group.group_identifier}") + logging.error(f"Could not find group for DEAD mission {target_group.group_name}") for i, t in enumerate(self.waypoint.targets): if self.group.units[0].unit_type == JF_17 and i < 4: @@ -1327,7 +1327,7 @@ class SeadIngressBuilder(PydcsWaypointBuilder): target_group = self.package.target if isinstance(target_group, TheaterGroundObject): - tgroup = self.mission.find_group(target_group.group_identifier, search="match") # Match search is used due to TheaterGroundObject.name not matching + tgroup = self.mission.find_group(target_group.group_name, search="match") # Match search is used due to TheaterGroundObject.name not matching if tgroup is not None: # the Mission group name because of SkyNet prefixes. waypoint.add_task(EngageTargetsInZone( position=tgroup.position, @@ -1337,7 +1337,7 @@ class SeadIngressBuilder(PydcsWaypointBuilder): ]) ) else: - logging.error(f"Could not find group for DEAD mission {target_group.group_identifier}") + logging.error(f"Could not find group for DEAD mission {target_group.group_name}") for i, t in enumerate(self.waypoint.targets): if self.group.units[0].unit_type == JF_17 and i < 4: diff --git a/gen/groundobjectsgen.py b/gen/groundobjectsgen.py index e0e5c1ee..1989452e 100644 --- a/gen/groundobjectsgen.py +++ b/gen/groundobjectsgen.py @@ -135,7 +135,7 @@ class BuildingSiteGenerator(GenericGroundObjectGenerator): if not self.ground_object.is_dead: self.m.vehicle_group( country=self.country, - name=self.ground_object.string_identifier, + name=self.ground_object.group_name, _type=unit_type, position=self.ground_object.position, heading=self.ground_object.heading, @@ -144,7 +144,7 @@ class BuildingSiteGenerator(GenericGroundObjectGenerator): def generate_static(self, static_type: StaticType) -> None: self.m.static_group( country=self.country, - name=self.ground_object.string_identifier, + name=self.ground_object.group_name, _type=static_type, position=self.ground_object.position, heading=self.ground_object.heading, diff --git a/gen/sam/group_generator.py b/gen/sam/group_generator.py index f35f1a0e..1bd57939 100644 --- a/gen/sam/group_generator.py +++ b/gen/sam/group_generator.py @@ -42,11 +42,10 @@ class GroupGenerator: def get_generated_group(self) -> unitgroup.VehicleGroup: return self.vg - def add_unit(self, unit_type: VehicleType, name: str, pos_x: float, pos_y: float, heading: int): - nn = "cgroup|" + str(self.go.cp_id) + '|' + str(self.go.group_id) + '|' + str(self.go.group_identifier) + "|" + name - + def add_unit(self, unit_type: VehicleType, name: str, pos_x: float, + pos_y: float, heading: int) -> Vehicle: unit = Vehicle(self.game.next_unit_id(), - nn, unit_type.id) + f"{self.go.group_name}|{name}", unit_type.id) unit.position.x = pos_x unit.position.y = pos_y unit.heading = heading @@ -88,6 +87,7 @@ class GroupGenerator: current_offset += outer_offset return positions + class ShipGroupGenerator(GroupGenerator): """Abstract class for other ship generator classes""" def __init__(self, game: Game, ground_object: TheaterGroundObject, faction: Faction): @@ -100,11 +100,9 @@ class ShipGroupGenerator(GroupGenerator): wp = self.vg.add_waypoint(self.position, 0) wp.ETA_locked = True - def add_unit(self, unit_type, name, pos_x, pos_y, heading): - nn = "cgroup|" + str(self.go.cp_id) + '|' + str(self.go.group_id) + '|' + str(self.go.group_identifier) + "|" + name - + def add_unit(self, unit_type, name, pos_x, pos_y, heading) -> Ship: unit = Ship(self.game.next_unit_id(), - nn, unit_type) + f"{self.go.group_name}|{name}", unit_type) unit.position.x = pos_x unit.position.y = pos_y unit.heading = heading diff --git a/qt_ui/widgets/combos/QFlightTypeComboBox.py b/qt_ui/widgets/combos/QFlightTypeComboBox.py index 429ff902..d1a27382 100644 --- a/qt_ui/widgets/combos/QFlightTypeComboBox.py +++ b/qt_ui/widgets/combos/QFlightTypeComboBox.py @@ -95,7 +95,7 @@ class QFlightTypeComboBox(QComboBox): yield from self.ENEMY_AIRBASE_MISSIONS elif isinstance(self.target, TheaterGroundObject): # TODO: Filter more based on the category. - friendly = self.target.parent_control_point(self.theater).captured + friendly = self.target.control_point.captured if friendly: yield from self.FRIENDLY_GROUND_OBJECT_MISSIONS else: diff --git a/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py b/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py index aac3b3c4..72ece41e 100644 --- a/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py +++ b/qt_ui/widgets/combos/QPredefinedWaypointSelectionComboBox.py @@ -1,7 +1,7 @@ from PySide2.QtGui import QStandardItem, QStandardItemModel from game import Game -from gen import Conflict, FlightWaypointType +from gen import BuildingGroundObject, Conflict, FlightWaypointType from gen.flights.flight import FlightWaypoint from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox from theater import ControlPointType @@ -71,7 +71,7 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox): for cp in self.game.theater.controlpoints: if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): for ground_object in cp.ground_objects: - if not ground_object.is_dead and not ground_object.dcs_identifier == "AA": + if not ground_object.is_dead and not isinstance(ground_object, BuildingGroundObject): wpt = FlightWaypoint( FlightWaypointType.CUSTOM, ground_object.position.x, diff --git a/theater/theatergroundobject.py b/theater/theatergroundobject.py index b9010da9..34a98c87 100644 --- a/theater/theatergroundobject.py +++ b/theater/theatergroundobject.py @@ -8,7 +8,6 @@ from dcs.unit import Unit from dcs.unitgroup import Group if TYPE_CHECKING: - from .conflicttheater import ConflictTheater from .controlpoint import ControlPoint from .missiontarget import MissionTarget @@ -72,29 +71,21 @@ CATEGORY_MAP = { class TheaterGroundObject(MissionTarget): - def __init__(self, name: str, category: str, group_id: int, object_id: int, - position: Point, heading: int, cp_id: int, dcs_identifier: str, + def __init__(self, name: str, category: str, group_id: int, position: Point, + heading: int, control_point: ControlPoint, dcs_identifier: str, airbase_group: bool, sea_object: bool) -> None: super().__init__(name, position) self.category = category self.group_id = group_id - self.object_id = object_id self.heading = heading - self.cp_id = cp_id + self.control_point = control_point self.dcs_identifier = dcs_identifier self.airbase_group = airbase_group self.sea_object = sea_object self.is_dead = False + # TODO: There is never more than one group. self.groups: List[Group] = [] - @property - def string_identifier(self): - return "{}|{}|{}|{}".format(self.category, self.cp_id, self.group_id, self.object_id) - - @property - def group_identifier(self) -> str: - return "{}|{}".format(self.category, self.group_id) - @property def units(self) -> List[Unit]: """ @@ -103,26 +94,20 @@ class TheaterGroundObject(MissionTarget): return list(itertools.chain.from_iterable([g.units for g in self.groups])) @property - def name_abbrev(self) -> str: - return ABBREV_NAME[self.category] + def group_name(self) -> str: + """The name of the unit group.""" + return f"{self.category}|{self.group_id}" def __str__(self) -> str: return NAME_BY_CATEGORY[self.category] - def matches_string_identifier(self, identifier): - return self.string_identifier == identifier + def is_same_group(self, identifier: str) -> bool: + return self.group_id == identifier @property def obj_name(self) -> str: return self.name - def parent_control_point(self, theater: ConflictTheater) -> ControlPoint: - """Searches the theater for the parent control point.""" - for cp in theater.controlpoints: - if cp.id == self.cp_id: - return cp - raise RuntimeError("Could not find matching control point in theater") - class BuildingGroundObject(TheaterGroundObject): def __init__(self, name: str, category: str, group_id: int, object_id: int, @@ -132,14 +117,19 @@ class BuildingGroundObject(TheaterGroundObject): name=name, category=category, group_id=group_id, - object_id=object_id, position=position, heading=heading, - cp_id=control_point.id, + control_point=control_point, dcs_identifier=dcs_identifier, airbase_group=False, sea_object=False ) + self.object_id = object_id + + @property + def group_name(self) -> str: + """The name of the unit group.""" + return f"{self.category}|{self.group_id}|{self.object_id}" class GenericCarrierGroundObject(TheaterGroundObject): @@ -154,10 +144,9 @@ class CarrierGroundObject(GenericCarrierGroundObject): name=name, category="CARRIER", group_id=group_id, - object_id=0, position=control_point.position, heading=0, - cp_id=control_point.id, + control_point=control_point, dcs_identifier="CARRIER", airbase_group=True, sea_object=True @@ -172,10 +161,9 @@ class LhaGroundObject(GenericCarrierGroundObject): name=name, category="LHA", group_id=group_id, - object_id=0, position=control_point.position, heading=0, - cp_id=control_point.id, + control_point=control_point, dcs_identifier="LHA", airbase_group=True, sea_object=True @@ -189,16 +177,18 @@ class MissileSiteGroundObject(TheaterGroundObject): name=name, category="aa", group_id=group_id, - object_id=0, position=position, heading=0, - cp_id=control_point.id, + control_point=control_point, dcs_identifier="AA", airbase_group=False, sea_object=False ) +# TODO: Differentiate types. +# This type gets used both for AA sites (SAM, AAA, or SHORAD) but also for the +# armor garrisons at airbases. These should each be split into their own types. class SamGroundObject(TheaterGroundObject): def __init__(self, name: str, group_id: int, position: Point, control_point: ControlPoint, for_airbase: bool) -> None: @@ -206,10 +196,9 @@ class SamGroundObject(TheaterGroundObject): name=name, category="aa", group_id=group_id, - object_id=0, position=position, heading=0, - cp_id=control_point.id, + control_point=control_point, dcs_identifier="AA", airbase_group=for_airbase, sea_object=False @@ -223,10 +212,9 @@ class ShipGroundObject(TheaterGroundObject): name=name, category="aa", group_id=group_id, - object_id=0, position=position, heading=0, - cp_id=control_point.id, + control_point=control_point, dcs_identifier="AA", airbase_group=False, sea_object=True