Cleanup Theater Ground Object.

A whole bunch of this data is redundant.
This commit is contained in:
Dan Albert 2020-11-06 18:06:42 -08:00
parent 4cf406aefa
commit 853ee5aac4
8 changed files with 43 additions and 57 deletions

View File

@ -87,8 +87,8 @@ class Debriefing:
for i, ground_object in enumerate(cp.ground_objects): for i, ground_object in enumerate(cp.ground_objects):
logging.info(unit) logging.info(unit)
logging.info(ground_object.string_identifier) logging.info(ground_object.group_name)
if ground_object.matches_string_identifier(unit): if ground_object.is_same_group(unit):
unit = DebriefingDeadUnitInfo(country, player_unit, ground_object.dcs_identifier) unit = DebriefingDeadUnitInfo(country, player_unit, ground_object.dcs_identifier)
self.dead_buildings.append(unit) self.dead_buildings.append(unit)
elif ground_object.dcs_identifier in ["AA", "CARRIER", "LHA"]: elif ground_object.dcs_identifier in ["AA", "CARRIER", "LHA"]:

View File

@ -145,8 +145,8 @@ class Event:
if ground_object.is_dead: if ground_object.is_dead:
continue continue
if ground_object.matches_string_identifier(destroyed_ground_unit_name): if ground_object.is_same_group(destroyed_ground_unit_name):
logging.info("cp {} killing ground object {}".format(cp, ground_object.string_identifier)) logging.info("cp {} killing ground object {}".format(cp, ground_object.group_name))
cp.ground_objects[i].is_dead = True cp.ground_objects[i].is_dead = True
info = Information("Building destroyed", info = Information("Building destroyed",

View File

@ -1298,7 +1298,7 @@ class DeadIngressBuilder(PydcsWaypointBuilder):
target_group = self.package.target target_group = self.package.target
if isinstance(target_group, TheaterGroundObject): 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. if tgroup is not None: # the Mission group name because of SkyNet prefixes.
task = AttackGroup(tgroup.id) task = AttackGroup(tgroup.id)
task.params["expend"] = "All" task.params["expend"] = "All"
@ -1309,7 +1309,7 @@ class DeadIngressBuilder(PydcsWaypointBuilder):
task.params["groupAttack"] = True task.params["groupAttack"] = True
waypoint.tasks.append(task) waypoint.tasks.append(task)
else: 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): for i, t in enumerate(self.waypoint.targets):
if self.group.units[0].unit_type == JF_17 and i < 4: if self.group.units[0].unit_type == JF_17 and i < 4:
@ -1327,7 +1327,7 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
target_group = self.package.target target_group = self.package.target
if isinstance(target_group, TheaterGroundObject): 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. if tgroup is not None: # the Mission group name because of SkyNet prefixes.
waypoint.add_task(EngageTargetsInZone( waypoint.add_task(EngageTargetsInZone(
position=tgroup.position, position=tgroup.position,
@ -1337,7 +1337,7 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
]) ])
) )
else: 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): for i, t in enumerate(self.waypoint.targets):
if self.group.units[0].unit_type == JF_17 and i < 4: if self.group.units[0].unit_type == JF_17 and i < 4:

View File

@ -135,7 +135,7 @@ class BuildingSiteGenerator(GenericGroundObjectGenerator):
if not self.ground_object.is_dead: if not self.ground_object.is_dead:
self.m.vehicle_group( self.m.vehicle_group(
country=self.country, country=self.country,
name=self.ground_object.string_identifier, name=self.ground_object.group_name,
_type=unit_type, _type=unit_type,
position=self.ground_object.position, position=self.ground_object.position,
heading=self.ground_object.heading, heading=self.ground_object.heading,
@ -144,7 +144,7 @@ class BuildingSiteGenerator(GenericGroundObjectGenerator):
def generate_static(self, static_type: StaticType) -> None: def generate_static(self, static_type: StaticType) -> None:
self.m.static_group( self.m.static_group(
country=self.country, country=self.country,
name=self.ground_object.string_identifier, name=self.ground_object.group_name,
_type=static_type, _type=static_type,
position=self.ground_object.position, position=self.ground_object.position,
heading=self.ground_object.heading, heading=self.ground_object.heading,

View File

@ -42,11 +42,10 @@ class GroupGenerator:
def get_generated_group(self) -> unitgroup.VehicleGroup: def get_generated_group(self) -> unitgroup.VehicleGroup:
return self.vg return self.vg
def add_unit(self, unit_type: VehicleType, name: str, pos_x: float, pos_y: float, heading: int): def add_unit(self, unit_type: VehicleType, name: str, pos_x: float,
nn = "cgroup|" + str(self.go.cp_id) + '|' + str(self.go.group_id) + '|' + str(self.go.group_identifier) + "|" + name pos_y: float, heading: int) -> Vehicle:
unit = Vehicle(self.game.next_unit_id(), 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.x = pos_x
unit.position.y = pos_y unit.position.y = pos_y
unit.heading = heading unit.heading = heading
@ -88,6 +87,7 @@ class GroupGenerator:
current_offset += outer_offset current_offset += outer_offset
return positions return positions
class ShipGroupGenerator(GroupGenerator): class ShipGroupGenerator(GroupGenerator):
"""Abstract class for other ship generator classes""" """Abstract class for other ship generator classes"""
def __init__(self, game: Game, ground_object: TheaterGroundObject, faction: Faction): 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 = self.vg.add_waypoint(self.position, 0)
wp.ETA_locked = True wp.ETA_locked = True
def add_unit(self, unit_type, name, pos_x, pos_y, heading): def add_unit(self, unit_type, name, pos_x, pos_y, heading) -> Ship:
nn = "cgroup|" + str(self.go.cp_id) + '|' + str(self.go.group_id) + '|' + str(self.go.group_identifier) + "|" + name
unit = Ship(self.game.next_unit_id(), 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.x = pos_x
unit.position.y = pos_y unit.position.y = pos_y
unit.heading = heading unit.heading = heading

View File

@ -95,7 +95,7 @@ class QFlightTypeComboBox(QComboBox):
yield from self.ENEMY_AIRBASE_MISSIONS yield from self.ENEMY_AIRBASE_MISSIONS
elif isinstance(self.target, TheaterGroundObject): elif isinstance(self.target, TheaterGroundObject):
# TODO: Filter more based on the category. # TODO: Filter more based on the category.
friendly = self.target.parent_control_point(self.theater).captured friendly = self.target.control_point.captured
if friendly: if friendly:
yield from self.FRIENDLY_GROUND_OBJECT_MISSIONS yield from self.FRIENDLY_GROUND_OBJECT_MISSIONS
else: else:

View File

@ -1,7 +1,7 @@
from PySide2.QtGui import QStandardItem, QStandardItemModel from PySide2.QtGui import QStandardItem, QStandardItemModel
from game import Game from game import Game
from gen import Conflict, FlightWaypointType from gen import BuildingGroundObject, Conflict, FlightWaypointType
from gen.flights.flight import FlightWaypoint from gen.flights.flight import FlightWaypoint
from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox
from theater import ControlPointType from theater import ControlPointType
@ -71,7 +71,7 @@ class QPredefinedWaypointSelectionComboBox(QFilteredComboBox):
for cp in self.game.theater.controlpoints: for cp in self.game.theater.controlpoints:
if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured): if (self.include_enemy and not cp.captured) or (self.include_friendly and cp.captured):
for ground_object in cp.ground_objects: 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( wpt = FlightWaypoint(
FlightWaypointType.CUSTOM, FlightWaypointType.CUSTOM,
ground_object.position.x, ground_object.position.x,

View File

@ -8,7 +8,6 @@ from dcs.unit import Unit
from dcs.unitgroup import Group from dcs.unitgroup import Group
if TYPE_CHECKING: if TYPE_CHECKING:
from .conflicttheater import ConflictTheater
from .controlpoint import ControlPoint from .controlpoint import ControlPoint
from .missiontarget import MissionTarget from .missiontarget import MissionTarget
@ -72,29 +71,21 @@ CATEGORY_MAP = {
class TheaterGroundObject(MissionTarget): class TheaterGroundObject(MissionTarget):
def __init__(self, name: str, category: str, group_id: int, object_id: int, def __init__(self, name: str, category: str, group_id: int, position: Point,
position: Point, heading: int, cp_id: int, dcs_identifier: str, heading: int, control_point: ControlPoint, dcs_identifier: str,
airbase_group: bool, sea_object: bool) -> None: airbase_group: bool, sea_object: bool) -> None:
super().__init__(name, position) super().__init__(name, position)
self.category = category self.category = category
self.group_id = group_id self.group_id = group_id
self.object_id = object_id
self.heading = heading self.heading = heading
self.cp_id = cp_id self.control_point = control_point
self.dcs_identifier = dcs_identifier self.dcs_identifier = dcs_identifier
self.airbase_group = airbase_group self.airbase_group = airbase_group
self.sea_object = sea_object self.sea_object = sea_object
self.is_dead = False self.is_dead = False
# TODO: There is never more than one group.
self.groups: List[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 @property
def units(self) -> List[Unit]: 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])) return list(itertools.chain.from_iterable([g.units for g in self.groups]))
@property @property
def name_abbrev(self) -> str: def group_name(self) -> str:
return ABBREV_NAME[self.category] """The name of the unit group."""
return f"{self.category}|{self.group_id}"
def __str__(self) -> str: def __str__(self) -> str:
return NAME_BY_CATEGORY[self.category] return NAME_BY_CATEGORY[self.category]
def matches_string_identifier(self, identifier): def is_same_group(self, identifier: str) -> bool:
return self.string_identifier == identifier return self.group_id == identifier
@property @property
def obj_name(self) -> str: def obj_name(self) -> str:
return self.name 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): class BuildingGroundObject(TheaterGroundObject):
def __init__(self, name: str, category: str, group_id: int, object_id: int, def __init__(self, name: str, category: str, group_id: int, object_id: int,
@ -132,14 +117,19 @@ class BuildingGroundObject(TheaterGroundObject):
name=name, name=name,
category=category, category=category,
group_id=group_id, group_id=group_id,
object_id=object_id,
position=position, position=position,
heading=heading, heading=heading,
cp_id=control_point.id, control_point=control_point,
dcs_identifier=dcs_identifier, dcs_identifier=dcs_identifier,
airbase_group=False, airbase_group=False,
sea_object=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): class GenericCarrierGroundObject(TheaterGroundObject):
@ -154,10 +144,9 @@ class CarrierGroundObject(GenericCarrierGroundObject):
name=name, name=name,
category="CARRIER", category="CARRIER",
group_id=group_id, group_id=group_id,
object_id=0,
position=control_point.position, position=control_point.position,
heading=0, heading=0,
cp_id=control_point.id, control_point=control_point,
dcs_identifier="CARRIER", dcs_identifier="CARRIER",
airbase_group=True, airbase_group=True,
sea_object=True sea_object=True
@ -172,10 +161,9 @@ class LhaGroundObject(GenericCarrierGroundObject):
name=name, name=name,
category="LHA", category="LHA",
group_id=group_id, group_id=group_id,
object_id=0,
position=control_point.position, position=control_point.position,
heading=0, heading=0,
cp_id=control_point.id, control_point=control_point,
dcs_identifier="LHA", dcs_identifier="LHA",
airbase_group=True, airbase_group=True,
sea_object=True sea_object=True
@ -189,16 +177,18 @@ class MissileSiteGroundObject(TheaterGroundObject):
name=name, name=name,
category="aa", category="aa",
group_id=group_id, group_id=group_id,
object_id=0,
position=position, position=position,
heading=0, heading=0,
cp_id=control_point.id, control_point=control_point,
dcs_identifier="AA", dcs_identifier="AA",
airbase_group=False, airbase_group=False,
sea_object=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): class SamGroundObject(TheaterGroundObject):
def __init__(self, name: str, group_id: int, position: Point, def __init__(self, name: str, group_id: int, position: Point,
control_point: ControlPoint, for_airbase: bool) -> None: control_point: ControlPoint, for_airbase: bool) -> None:
@ -206,10 +196,9 @@ class SamGroundObject(TheaterGroundObject):
name=name, name=name,
category="aa", category="aa",
group_id=group_id, group_id=group_id,
object_id=0,
position=position, position=position,
heading=0, heading=0,
cp_id=control_point.id, control_point=control_point,
dcs_identifier="AA", dcs_identifier="AA",
airbase_group=for_airbase, airbase_group=for_airbase,
sea_object=False sea_object=False
@ -223,10 +212,9 @@ class ShipGroundObject(TheaterGroundObject):
name=name, name=name,
category="aa", category="aa",
group_id=group_id, group_id=group_id,
object_id=0,
position=position, position=position,
heading=0, heading=0,
cp_id=control_point.id, control_point=control_point,
dcs_identifier="AA", dcs_identifier="AA",
airbase_group=False, airbase_group=False,
sea_object=True sea_object=True