Group briefing data by package.

This is just the refactor to make way for the real change: adding a
package page to the kneeboard so players can get package-level
information like other radio, laser, and STNs.
This commit is contained in:
Dan Albert 2023-10-03 21:15:10 -07:00
parent f9916e47d8
commit e9133bffab
6 changed files with 91 additions and 79 deletions

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import logging
from datetime import datetime
from functools import cached_property
from typing import Any, Dict, List, TYPE_CHECKING
from typing import Any, Dict, TYPE_CHECKING
from dcs.country import Country
from dcs.mission import Mission
@ -58,7 +58,9 @@ class AircraftGenerator:
self.radio_registry = radio_registry
self.tacan_registy = tacan_registry
self.unit_map = unit_map
self.flights: List[FlightData] = []
# A list of per-package briefing data, which is in turn a list of per-flight
# briefing data.
self.briefing_data: list[list[FlightData]] = []
self.mission_data = mission_data
self.helipads = helipads
@ -102,13 +104,16 @@ class AircraftGenerator:
for package in ato.packages:
if not package.flights:
continue
package_briefing_data: list[FlightData] = []
for flight in package.flights:
if flight.alive:
logging.info(f"Generating flight: {flight.unit_type}")
group = self.create_and_configure_flight(
group, briefing_data = self.create_and_configure_flight(
flight, country, dynamic_runways
)
package_briefing_data.append(briefing_data)
self.unit_map.add_aircraft(group, flight)
self.briefing_data.append(package_briefing_data)
def spawn_unused_aircraft(
self, player_country: Country, enemy_country: Country
@ -157,26 +162,25 @@ class AircraftGenerator:
def create_and_configure_flight(
self, flight: Flight, country: Country, dynamic_runways: Dict[str, RunwayData]
) -> FlyingGroup[Any]:
) -> tuple[FlyingGroup[Any], FlightData]:
"""Creates and configures the flight group in the mission."""
group = FlightGroupSpawner(
flight, country, self.mission, self.helipads
).create_flight_group()
self.flights.append(
FlightGroupConfigurator(
flight,
group,
self.game,
self.mission,
self.time,
self.radio_registry,
self.tacan_registy,
self.mission_data,
dynamic_runways,
self.use_client,
self.unit_map,
).configure()
)
briefing_data = FlightGroupConfigurator(
flight,
group,
self.game,
self.mission,
self.time,
self.radio_registry,
self.tacan_registy,
self.mission_data,
dynamic_runways,
self.use_client,
self.unit_map,
).configure()
wpt = group.waypoint("LANDING")
if flight.is_helo and isinstance(flight.arrival, Fob) and wpt:
@ -185,4 +189,4 @@ class AircraftGenerator:
wpt.link_unit = hpad.id
self.helipads[flight.arrival].units.append(hpad)
return group
return group, briefing_data

View File

@ -56,7 +56,7 @@ class MissionInfoGenerator:
self.game = game
self.awacs: List[AwacsInfo] = []
self.comms: List[CommInfo] = []
self.flights: List[FlightData] = []
self.briefing_data: list[list[FlightData]] = []
self.jtacs: List[JtacInfo] = []
self.tankers: List[TankerInfo] = []
self.frontlines: List[FrontLineInfo] = []
@ -79,13 +79,13 @@ class MissionInfoGenerator:
"""
self.comms.append(CommInfo(name, freq))
def add_flight(self, flight: FlightData) -> None:
def add_package_briefing_data(self, data: list[FlightData]) -> None:
"""Adds flight info to the mission.
Args:
flight: Flight information.
data: The list of briefing data for each flight in a package.
"""
self.flights.append(flight)
self.briefing_data.append(data)
def add_jtac(self, jtac: JtacInfo) -> None:
"""Adds a JTAC to the mission.
@ -177,12 +177,13 @@ class BriefingGenerator(MissionInfoGenerator):
# TODO: This should determine if runway is friendly through a method more robust than the existing string match
def generate_allied_flights_by_departure(self) -> None:
"""Create iterable to display allied flights grouped by departure airfield."""
for flight in self.flights:
if not flight.client_units and flight.friendly:
name = flight.departure.airfield_name
if (
name in self.allied_flights_by_departure
): # where else can we get this?
self.allied_flights_by_departure[name].append(flight)
else:
self.allied_flights_by_departure[name] = [flight]
for package in self.briefing_data:
for flight in package:
if not flight.client_units and flight.friendly:
name = flight.departure.airfield_name
if (
name in self.allied_flights_by_departure
): # where else can we get this?
self.allied_flights_by_departure[name].append(flight)
else:
self.allied_flights_by_departure[name] = [flight]

View File

@ -724,12 +724,13 @@ class KneeboardGenerator(MissionInfoGenerator):
that aircraft.
"""
all_flights: Dict[AircraftType, List[KneeboardPage]] = defaultdict(list)
for flight in self.flights:
if not flight.client_units:
continue
all_flights[flight.aircraft_type].extend(
self.generate_flight_kneeboard(flight)
)
for flights in self.briefing_data:
for flight in flights:
if not flight.client_units:
continue
all_flights[flight.aircraft_type].extend(
self.generate_flight_kneeboard(flight)
)
return all_flights
def generate_task_page(self, flight: FlightData) -> Optional[KneeboardPage]:

View File

@ -1,5 +1,6 @@
from __future__ import annotations
import itertools
import logging
import os
from abc import ABC, abstractmethod
@ -135,37 +136,41 @@ class LuaGenerator:
crate_item.add_key_value("weight", weight)
target_points = lua_data.add_item("TargetPoints")
for flight in self.mission_data.flights:
if flight.friendly and flight.flight_type in [
FlightType.ANTISHIP,
FlightType.DEAD,
FlightType.SEAD,
FlightType.STRIKE,
]:
flight_type = str(flight.flight_type)
flight_target = flight.package.target
if flight_target:
flight_target_name = None
flight_target_type = None
if isinstance(flight_target, TheaterGroundObject):
flight_target_name = flight_target.obj_name
flight_target_type = (
flight_type + f" TGT ({flight_target.category})"
all_packages = itertools.chain(
self.game.blue.ato.packages, self.game.red.ato.packages
)
for package in all_packages:
for flight in package.flights:
if flight.blue and flight.flight_type in [
FlightType.ANTISHIP,
FlightType.DEAD,
FlightType.SEAD,
FlightType.STRIKE,
]:
flight_type = str(flight.flight_type)
flight_target = flight.package.target
if flight_target:
flight_target_name = None
flight_target_type = None
if isinstance(flight_target, TheaterGroundObject):
flight_target_name = flight_target.obj_name
flight_target_type = (
flight_type + f" TGT ({flight_target.category})"
)
elif hasattr(flight_target, "name"):
flight_target_name = flight_target.name
flight_target_type = flight_type + " TGT (Airbase)"
target_item = target_points.add_item()
if flight_target_name:
target_item.add_key_value("name", flight_target_name)
if flight_target_type:
target_item.add_key_value("type", flight_target_type)
target_item.add_key_value(
"positionX", str(flight_target.position.x)
)
target_item.add_key_value(
"positionY", str(flight_target.position.y)
)
elif hasattr(flight_target, "name"):
flight_target_name = flight_target.name
flight_target_type = flight_type + " TGT (Airbase)"
target_item = target_points.add_item()
if flight_target_name:
target_item.add_key_value("name", flight_target_name)
if flight_target_type:
target_item.add_key_value("type", flight_target_type)
target_item.add_key_value(
"positionX", str(flight_target.position.x)
)
target_item.add_key_value(
"positionY", str(flight_target.position.y)
)
for cp in self.game.theater.controlpoints:
coalition_object = (

View File

@ -90,7 +90,7 @@ class MissionData:
awacs: list[AwacsInfo] = field(default_factory=list)
runways: list[RunwayData] = field(default_factory=list)
carriers: list[CarrierInfo] = field(default_factory=list)
flights: list[FlightData] = field(default_factory=list)
briefing_data: list[list[FlightData]] = field(default_factory=list)
tankers: list[TankerInfo] = field(default_factory=list)
jtacs: list[JtacInfo] = field(default_factory=list)
logistics: list[LogisticsInfo] = field(default_factory=list)

View File

@ -281,14 +281,15 @@ class MissionGenerator:
self.mission.country(self.game.red.country_name),
)
for flight in aircraft_generator.flights:
if not flight.client_units:
continue
flight.aircraft_type.assign_channels_for_flight(
flight, air_support_generator.mission_data
)
for package in aircraft_generator.briefing_data:
for flight in package:
if not flight.client_units:
continue
flight.aircraft_type.assign_channels_for_flight(
flight, air_support_generator.mission_data
)
self.mission_data.flights = aircraft_generator.flights
self.mission_data.briefing_data = aircraft_generator.briefing_data
def generate_destroyed_units(self) -> None:
"""Add destroyed units to the Mission"""
@ -344,8 +345,8 @@ class MissionGenerator:
if jtac.blue:
gen.add_jtac(jtac)
for flight in mission_data.flights:
gen.add_flight(flight)
for package in mission_data.briefing_data:
gen.add_package_briefing_data(package)
gen.generate()
def setup_combined_arms(self) -> None: