Rewrite IADS tgo update method for correct updating

These Events are covered
- Mission Debriefing
- Capture Event
- GroundObject Buy Menu
This commit is contained in:
RndName 2022-11-10 20:55:04 +01:00
parent c33ba2c5af
commit d0d56aceb6
3 changed files with 54 additions and 14 deletions

View File

@ -132,10 +132,20 @@ class MissionResultsProcessor:
@staticmethod @staticmethod
def commit_ground_losses(debriefing: Debriefing, events: GameUpdateEvents) -> None: def commit_ground_losses(debriefing: Debriefing, events: GameUpdateEvents) -> None:
killed_ground_objects = []
for ground_object_loss in debriefing.ground_object_losses: for ground_object_loss in debriefing.ground_object_losses:
ground_object_loss.theater_unit.kill(events) ground_object_loss.theater_unit.kill(events)
killed_ground_objects.append(ground_object_loss.theater_unit.ground_object)
for scenery_object_loss in debriefing.scenery_object_losses: for scenery_object_loss in debriefing.scenery_object_losses:
scenery_object_loss.ground_unit.kill(events) scenery_object_loss.ground_unit.kill(events)
killed_ground_objects.append(scenery_object_loss.ground_unit.ground_object)
# Update the IADS network if any participant had losses
iads_network = debriefing.game.theater.iads_network
for killed_ground_object in killed_ground_objects:
if killed_ground_object in iads_network.participating:
iads_network.update_network(events)
return
@staticmethod @staticmethod
def commit_damaged_runways(debriefing: Debriefing) -> None: def commit_damaged_runways(debriefing: Debriefing) -> None:

View File

@ -839,18 +839,24 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
events.update_control_point(self) events.update_control_point(self)
# All the attached TGOs have either been depopulated or captured. Tell the UI to # All the attached TGOs have either been depopulated or captured. Tell the UI to
# update their state. Also update orientation and IADS state for specific tgos # update their state. Also update the orientation of all TGOs
iads_update_required = False
iads_network = game.theater.iads_network
for tgo in self.connected_objectives: for tgo in self.connected_objectives:
if isinstance(tgo, IadsGroundObject) or isinstance( if isinstance(tgo, IadsGroundObject) or isinstance(
tgo, VehicleGroupGroundObject tgo, VehicleGroupGroundObject
): ):
if isinstance(tgo, IadsGroundObject): if not iads_update_required and tgo in iads_network.participating:
game.theater.iads_network.update_tgo(tgo, events) iads_update_required = True
conflict_heading = game.theater.heading_to_conflict_from(tgo.position) conflict_heading = game.theater.heading_to_conflict_from(tgo.position)
tgo.rotate(conflict_heading or tgo.heading) tgo.rotate(conflict_heading or tgo.heading)
if not tgo.is_control_point: if not tgo.is_control_point:
events.update_tgo(tgo) events.update_tgo(tgo)
# Update the IADS Network
if iads_update_required:
iads_network.update_network(events)
@property @property
def required_aircraft_start_type(self) -> Optional[StartType]: def required_aircraft_start_type(self) -> Optional[StartType]:
return None return None

View File

@ -112,6 +112,17 @@ class IadsNetwork:
else: else:
raise RuntimeError("Invalid iads_config in campaign") raise RuntimeError("Invalid iads_config in campaign")
@property
def participating(self) -> Iterator[TheaterGroundObject]:
"""All unique participating TGOs. First primary then secondary"""
secondary_nodes = []
for node in self.nodes:
yield node.group.ground_object
for connection in node.connections.values():
if connection.ground_object not in secondary_nodes:
secondary_nodes.append(connection.ground_object)
yield from secondary_nodes
def skynet_nodes(self, game: Game) -> list[SkynetNode]: def skynet_nodes(self, game: Game) -> list[SkynetNode]:
"""Get all skynet nodes from the IADS Network""" """Get all skynet nodes from the IADS Network"""
skynet_nodes: list[SkynetNode] = [] skynet_nodes: list[SkynetNode] = []
@ -143,30 +154,39 @@ class IadsNetwork:
def update_tgo(self, tgo: TheaterGroundObject, events: GameUpdateEvents) -> None: def update_tgo(self, tgo: TheaterGroundObject, events: GameUpdateEvents) -> None:
"""Update the IADS Network for the given TGO""" """Update the IADS Network for the given TGO"""
# Remove existing nodes for the given tgo # Remove existing nodes for the given tgo if there are any
for cn in self.nodes: for cn in self.nodes:
if cn.group.ground_object == tgo: if cn.group.ground_object == tgo:
self.nodes.remove(cn) self.nodes.remove(cn)
# Also delete all connections for the given node
for cID in cn.connections: for cID in cn.connections:
events.delete_iads_connection(cID) events.delete_iads_connection(cID)
node = self.node_for_tgo(tgo) # Try to create a new primary node for the TGO
node = self._new_node_for_tgo(tgo)
if node is None: if node is None:
# Not participating # the ground object is not participating to the IADS Network
return return
# Add connections to the new node # Create the connections to the secondary nodes
primary_node = node.group.ground_object.original_name if self.iads_config:
if self.iads_config and primary_node in self.iads_config:
# If iads_config was defined and campaign designer added a config for the # If iads_config was defined and campaign designer added a config for the
# given primary node generate the connections from the config # given primary node generate the connections from the config.
# If the primary node was not defined in the iads_config it will be added
# without any connections
self._add_connections_from_config(node) self._add_connections_from_config(node)
else: else:
# Otherwise calculate the connections by range # Otherwise calculate the connections by range
self._add_connections_by_range(node) self._calculate_connections_by_range(node)
events.update_iads_node(node) events.update_iads_node(node)
def update_network(self, events: GameUpdateEvents) -> None:
"""Update all primary nodes of the IADS and recalculate connections"""
primary_nodes = [node.group.ground_object for node in self.nodes]
for primary_node in primary_nodes:
self.update_tgo(primary_node, events)
def node_for_group(self, group: IadsGroundGroup) -> IadsNetworkNode: def node_for_group(self, group: IadsGroundGroup) -> IadsNetworkNode:
"""Get existing node from the iads network or create a new node""" """Get existing node from the iads network or create a new node"""
for cn in self.nodes: for cn in self.nodes:
@ -182,7 +202,9 @@ class IadsNetwork:
for cn in self.nodes: for cn in self.nodes:
if cn.group.ground_object == tgo: if cn.group.ground_object == tgo:
return cn return cn
return self._new_node_for_tgo(tgo)
def _new_node_for_tgo(self, tgo: TheaterGroundObject) -> Optional[IadsNetworkNode]:
# Create new connection_node if none exists # Create new connection_node if none exists
node: Optional[IadsNetworkNode] = None node: Optional[IadsNetworkNode] = None
for group in tgo.groups: for group in tgo.groups:
@ -249,6 +271,8 @@ class IadsNetwork:
def _add_connections_from_config(self, node: IadsNetworkNode) -> None: def _add_connections_from_config(self, node: IadsNetworkNode) -> None:
"""Add all connections for the given primary node based on the iads_config""" """Add all connections for the given primary node based on the iads_config"""
primary_node = node.group.ground_object.original_name primary_node = node.group.ground_object.original_name
# iads_config uses defaultdict, therefore when the connections of a primary
# node where not defined in the iads_config they will just be empty
connections = self.iads_config[primary_node] connections = self.iads_config[primary_node]
for secondary_node in connections: for secondary_node in connections:
try: try:
@ -259,8 +283,8 @@ class IadsNetwork:
) )
continue continue
def _add_connections_by_range(self, node: IadsNetworkNode) -> None: def _calculate_connections_by_range(self, node: IadsNetworkNode) -> None:
"""Add all connections for the given primary node based range calculation""" """Add all connections for the primary node by calculating them by range"""
primary_tgo = node.group.ground_object primary_tgo = node.group.ground_object
for nearby_go in self.ground_objects.values(): for nearby_go in self.ground_objects.values():
# Find nearby Power or Connection # Find nearby Power or Connection
@ -294,4 +318,4 @@ class IadsNetwork:
if node is None: if node is None:
# TGO does not participate to iads network # TGO does not participate to iads network
continue continue
self._add_connections_by_range(node) self._calculate_connections_by_range(node)