mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Fix briefing generation.
I removed the nav target info from the briefing because that doesn't
seem to have been doing what it was intended to do. It didn't give any
actual target information, all it would show was (example is a JF-17
strike mission):
PP1
PP2
PP3
PP4
Without any additional context that doesn't seem too helpful to me.
I'll be following up (hopefully) shortly by adding target information
(type, coordinates, STPT/PP, etc) to both the briefing and the
kneeboard that will cover that.
Refactor a bunch to share some code with the kneeboard generator as
well.
This commit is contained in:
parent
b31e186d1d
commit
9d31c478d3
@ -36,6 +36,4 @@ class FrontlineAttackOperation(Operation):
|
||||
def generate(self):
|
||||
self.briefinggen.title = "Frontline CAS"
|
||||
self.briefinggen.description = "Provide CAS for the ground forces attacking enemy lines. Operation will be considered successful if total number of enemy units will be lower than your own by a factor of 1.5 (i.e. with 12 units from both sides, enemy forces need to be reduced to at least 8), meaning that you (and, probably, your wingmans) should concentrate on destroying the enemy units. Target base strength will be lowered as a result. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
|
||||
self.briefinggen.append_waypoint("CAS AREA IP")
|
||||
self.briefinggen.append_waypoint("CAS AREA EGRESS")
|
||||
super(FrontlineAttackOperation, self).generate()
|
||||
|
||||
@ -266,28 +266,34 @@ class Operation:
|
||||
load_dcs_libe.add_action(DoScript(String(script)))
|
||||
self.current_mission.triggerrules.triggers.append(load_dcs_libe)
|
||||
|
||||
self.assign_channels_to_flights()
|
||||
|
||||
kneeboard_generator = KneeboardGenerator(self.current_mission)
|
||||
|
||||
# Briefing Generation
|
||||
for dynamic_runway in self.groundobjectgen.runways.values():
|
||||
self.briefinggen.add_dynamic_runway(dynamic_runway)
|
||||
|
||||
for tanker in self.airsupportgen.air_support.tankers:
|
||||
self.briefinggen.append_frequency(
|
||||
f"Tanker {tanker.callsign} ({tanker.variant})",
|
||||
f"{tanker.tacan}/{tanker.freq}")
|
||||
self.briefinggen.add_tanker(tanker)
|
||||
kneeboard_generator.add_tanker(tanker)
|
||||
|
||||
if self.is_awacs_enabled:
|
||||
for awacs in self.airsupportgen.air_support.awacs:
|
||||
self.briefinggen.append_frequency(awacs.callsign, awacs.freq)
|
||||
self.briefinggen.add_awacs(awacs)
|
||||
kneeboard_generator.add_awacs(awacs)
|
||||
|
||||
self.assign_channels_to_flights()
|
||||
|
||||
# Generate the briefing
|
||||
self.briefinggen.generate()
|
||||
|
||||
for region, code, name in self.game.jtacs:
|
||||
kneeboard_generator.add_jtac(name, region, code)
|
||||
kneeboard_generator.generate(self.airgen.flights)
|
||||
# TODO: Radio info? Type?
|
||||
jtac = JtacInfo(name, region, code)
|
||||
self.briefinggen.add_jtac(jtac)
|
||||
kneeboard_generator.add_jtac(jtac)
|
||||
|
||||
for flight in self.airgen.flights:
|
||||
self.briefinggen.add_flight(flight)
|
||||
kneeboard_generator.add_flight(flight)
|
||||
|
||||
self.briefinggen.generate()
|
||||
kneeboard_generator.generate()
|
||||
|
||||
def assign_channels_to_flights(self) -> None:
|
||||
"""Assigns preset radio channels for client flights."""
|
||||
|
||||
@ -148,8 +148,19 @@ class ChannelAssignment:
|
||||
class FlightData:
|
||||
"""Details of a planned flight."""
|
||||
|
||||
#: List of playable units in the flight.
|
||||
client_units: List[FlyingUnit]
|
||||
flight_type: FlightType
|
||||
|
||||
#: All units in the flight.
|
||||
units: List[FlyingUnit]
|
||||
|
||||
#: Total number of aircraft in the flight.
|
||||
size: int
|
||||
|
||||
#: True if this flight belongs to the player's coalition.
|
||||
friendly: bool
|
||||
|
||||
#: Number of minutes after mission start the flight is set to depart.
|
||||
departure_delay: int
|
||||
|
||||
#: Arrival airport.
|
||||
arrival: RunwayData
|
||||
@ -169,13 +180,18 @@ class FlightData:
|
||||
#: Map of radio frequencies to their assigned radio and channel, if any.
|
||||
frequency_to_channel_map: Dict[RadioFrequency, ChannelAssignment]
|
||||
|
||||
def __init__(self, client_units: List[FlyingUnit], arrival: RunwayData,
|
||||
departure: RunwayData, divert: Optional[RunwayData],
|
||||
waypoints: List[FlightWaypoint],
|
||||
def __init__(self, flight_type: FlightType, units: List[FlyingUnit],
|
||||
size: int, friendly: bool, departure_delay: int,
|
||||
departure: RunwayData, arrival: RunwayData,
|
||||
divert: Optional[RunwayData], waypoints: List[FlightWaypoint],
|
||||
intra_flight_channel: RadioFrequency) -> None:
|
||||
self.client_units = client_units
|
||||
self.arrival = arrival
|
||||
self.flight_type = flight_type
|
||||
self.units = units
|
||||
self.size = size
|
||||
self.friendly = friendly
|
||||
self.departure_delay = departure_delay
|
||||
self.departure = departure
|
||||
self.arrival = arrival
|
||||
self.divert = divert
|
||||
self.waypoints = waypoints
|
||||
self.intra_flight_channel = intra_flight_channel
|
||||
@ -183,6 +199,11 @@ class FlightData:
|
||||
|
||||
self.assign_intra_flight_channel()
|
||||
|
||||
@property
|
||||
def client_units(self) -> List[FlyingUnit]:
|
||||
"""List of playable units in the flight."""
|
||||
return [u for u in self.units if u.is_human()]
|
||||
|
||||
def assign_intra_flight_channel(self) -> None:
|
||||
"""Assigns a channel to the intra-flight frequency."""
|
||||
if not self.client_units:
|
||||
@ -200,10 +221,11 @@ class FlightData:
|
||||
@property
|
||||
def aircraft_type(self) -> FlyingType:
|
||||
"""Returns the type of aircraft in this flight."""
|
||||
return self.client_units[0].unit_type
|
||||
return self.units[0].unit_type
|
||||
|
||||
def num_radio_channels(self, radio_id: int) -> int:
|
||||
"""Returns the number of preset channels for the given radio."""
|
||||
# Note: pydcs only initializes the radio presets for client slots.
|
||||
return self.client_units[0].num_radio_channels(radio_id)
|
||||
|
||||
def channel_for(
|
||||
@ -296,11 +318,9 @@ class AircraftConflictGenerator:
|
||||
for unit_instance in group.units:
|
||||
unit_instance.livery_id = db.PLANE_LIVERY_OVERRIDES[unit_type]
|
||||
|
||||
clients: List[FlyingUnit] = []
|
||||
single_client = flight.client_count == 1
|
||||
for idx in range(0, min(len(group.units), flight.client_count)):
|
||||
unit = group.units[idx]
|
||||
clients.append(unit)
|
||||
if single_client:
|
||||
unit.set_player()
|
||||
else:
|
||||
@ -338,7 +358,11 @@ class AircraftConflictGenerator:
|
||||
departure_runway = fallback_runway
|
||||
|
||||
self.flights.append(FlightData(
|
||||
client_units=clients,
|
||||
flight_type=flight.flight_type,
|
||||
units=group.units,
|
||||
size=len(group.units),
|
||||
friendly=flight.from_cp.captured,
|
||||
departure_delay=flight.scheduled_in,
|
||||
departure=departure_runway,
|
||||
arrival=departure_runway,
|
||||
# TODO: Support for divert airfields.
|
||||
|
||||
@ -641,12 +641,13 @@ AIRFIELD_DATA = {
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True)
|
||||
class RunwayData:
|
||||
airfield_name: str
|
||||
runway_name: str
|
||||
atc: Optional[RadioFrequency] = None
|
||||
tacan: Optional[TacanChannel] = None
|
||||
tacan_callsign: Optional[str] = None
|
||||
ils: Optional[RadioFrequency] = None
|
||||
icls: Optional[int] = None
|
||||
|
||||
@ -665,6 +666,7 @@ class RunwayData:
|
||||
airfield = AIRFIELD_DATA[airport.name]
|
||||
atc = airfield.atc.uhf
|
||||
tacan = airfield.tacan
|
||||
tacan = airfield.tacan_callsign
|
||||
ils = airfield.ils_freq(runway)
|
||||
except KeyError:
|
||||
logging.warning(f"No airfield data for {airport.name}")
|
||||
|
||||
@ -1,68 +1,136 @@
|
||||
import logging
|
||||
import os
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
import random
|
||||
from typing import List, Tuple
|
||||
|
||||
from game import db
|
||||
from .conflictgen import *
|
||||
from .naming import *
|
||||
|
||||
from dcs.mission import *
|
||||
from pydcs.dcs.mission import Mission
|
||||
from .aircraft import FlightData
|
||||
from .airfields import RunwayData
|
||||
from .airsupportgen import AwacsInfo, TankerInfo
|
||||
from .conflictgen import Conflict
|
||||
from .ground_forces.combat_stance import CombatStance
|
||||
from .radios import RadioFrequency
|
||||
|
||||
|
||||
class BriefingGenerator:
|
||||
freqs = None # type: typing.List[typing.Tuple[str, str]]
|
||||
title = "" # type: str
|
||||
description = "" # type: str
|
||||
targets = None # type: typing.List[typing.Tuple[str, str]]
|
||||
waypoints = None # type: typing.List[str]
|
||||
@dataclass
|
||||
class CommInfo:
|
||||
"""Communications information for the kneeboard."""
|
||||
name: str
|
||||
freq: RadioFrequency
|
||||
|
||||
|
||||
@dataclass
|
||||
class JtacInfo:
|
||||
"""JTAC information for the kneeboard."""
|
||||
callsign: str
|
||||
region: str
|
||||
code: str
|
||||
|
||||
|
||||
class MissionInfoGenerator:
|
||||
"""Base type for generators of mission information for the player.
|
||||
|
||||
Examples of subtypes include briefing generators, kneeboard generators, etc.
|
||||
"""
|
||||
|
||||
def __init__(self, mission: Mission) -> None:
|
||||
self.mission = mission
|
||||
self.awacs: List[AwacsInfo] = []
|
||||
self.comms: List[CommInfo] = []
|
||||
self.flights: List[FlightData] = []
|
||||
self.jtacs: List[JtacInfo] = []
|
||||
self.tankers: List[TankerInfo] = []
|
||||
|
||||
def add_awacs(self, awacs: AwacsInfo) -> None:
|
||||
"""Adds an AWACS/GCI to the mission.
|
||||
|
||||
Args:
|
||||
awacs: AWACS information.
|
||||
"""
|
||||
self.awacs.append(awacs)
|
||||
|
||||
def add_comm(self, name: str, freq: RadioFrequency) -> None:
|
||||
"""Adds communications info to the mission.
|
||||
|
||||
Args:
|
||||
name: Name of the radio channel.
|
||||
freq: Frequency of the radio channel.
|
||||
"""
|
||||
self.comms.append(CommInfo(name, freq))
|
||||
|
||||
def add_flight(self, flight: FlightData) -> None:
|
||||
"""Adds flight info to the mission.
|
||||
|
||||
Args:
|
||||
flight: Flight information.
|
||||
"""
|
||||
self.flights.append(flight)
|
||||
|
||||
def add_jtac(self, jtac: JtacInfo) -> None:
|
||||
"""Adds a JTAC to the mission.
|
||||
|
||||
Args:
|
||||
jtac: JTAC information.
|
||||
"""
|
||||
self.jtacs.append(jtac)
|
||||
|
||||
def add_tanker(self, tanker: TankerInfo) -> None:
|
||||
"""Adds a tanker to the mission.
|
||||
|
||||
Args:
|
||||
tanker: Tanker information.
|
||||
"""
|
||||
self.tankers.append(tanker)
|
||||
|
||||
def generate(self) -> None:
|
||||
"""Generates the mission information."""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class BriefingGenerator(MissionInfoGenerator):
|
||||
|
||||
def __init__(self, mission: Mission, conflict: Conflict, game):
|
||||
self.m = mission
|
||||
super().__init__(mission)
|
||||
self.conflict = conflict
|
||||
self.game = game
|
||||
self.title = ""
|
||||
self.description = ""
|
||||
self.dynamic_runways: List[RunwayData] = []
|
||||
|
||||
self.freqs = []
|
||||
self.targets = []
|
||||
self.waypoints = []
|
||||
def add_dynamic_runway(self, runway: RunwayData) -> None:
|
||||
"""Adds a dynamically generated runway to the briefing.
|
||||
|
||||
self.jtacs = []
|
||||
Dynamic runways are any valid landing point that is a unit rather than a
|
||||
map feature. These include carriers, ships with a helipad, and FARPs.
|
||||
"""
|
||||
self.dynamic_runways.append(runway)
|
||||
|
||||
def append_frequency(self, name: str, frequency: str):
|
||||
self.freqs.append((name, frequency))
|
||||
def add_flight_description(self, flight: FlightData):
|
||||
assert flight.client_units
|
||||
|
||||
def append_target(self, description: str, markpoint: str = None):
|
||||
self.targets.append((description, markpoint))
|
||||
|
||||
def append_waypoint(self, description: str):
|
||||
self.waypoints.append(description)
|
||||
|
||||
def add_flight_description(self, flight):
|
||||
|
||||
if flight.client_count <= 0:
|
||||
return
|
||||
|
||||
flight_unit_name = db.unit_type_name(flight.unit_type)
|
||||
aircraft = flight.aircraft_type
|
||||
flight_unit_name = db.unit_type_name(aircraft)
|
||||
self.description += "-" * 50 + "\n"
|
||||
self.description += flight_unit_name + " x " + str(flight.count) + 2 * "\n"
|
||||
self.description += f"{flight_unit_name} x {flight.size + 2}\n\n"
|
||||
|
||||
self.description += "#0 -- TAKEOFF : Take off from " + flight.from_cp.name + "\n"
|
||||
for i, wpt in enumerate(flight.points):
|
||||
self.description += "#" + str(1+i) + " -- " + wpt.name + " : " + wpt.description + "\n"
|
||||
self.description += "#" + str(len(flight.points) + 1) + " -- RTB\n\n"
|
||||
departure = flight.departure.airfield_name
|
||||
self.description += f"#0 -- TAKEOFF : Take off from {departure}\n"
|
||||
for i, wpt in enumerate(flight.waypoints):
|
||||
self.description += f"#{i + 1} -- {wpt.name} : {wpt.description}\n"
|
||||
self.description += f"#{len(flight.waypoints) + 1} -- RTB\n\n"
|
||||
|
||||
group = flight.group
|
||||
if group is not None:
|
||||
for i, nav_target in enumerate(group.nav_target_points):
|
||||
self.description += nav_target.text_comment + "\n"
|
||||
self.description += "\n"
|
||||
self.description += "-" * 50 + "\n"
|
||||
|
||||
def add_ally_flight_description(self, flight):
|
||||
if flight.client_count == 0:
|
||||
flight_unit_name = db.unit_type_name(flight.unit_type)
|
||||
self.description += flight.flight_type.name + " " + flight_unit_name + " x " + str(flight.count) + ", departing in " + str(flight.scheduled_in) + " minutes \n"
|
||||
def add_ally_flight_description(self, flight: FlightData):
|
||||
assert not flight.client_units
|
||||
aircraft = flight.aircraft_type
|
||||
flight_unit_name = db.unit_type_name(aircraft)
|
||||
self.description += (
|
||||
f"{flight.flight_type.name} {flight_unit_name} x {flight.size}, "
|
||||
f"departing in {flight.departure_delay} minutes\n"
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
|
||||
self.description = ""
|
||||
|
||||
self.description += "DCS Liberation turn #" + str(self.game.turn) + "\n"
|
||||
@ -74,52 +142,50 @@ class BriefingGenerator:
|
||||
self.description += "Your flights:" + "\n"
|
||||
self.description += "=" * 15 + "\n\n"
|
||||
|
||||
for planner in self.game.planners.values():
|
||||
for flight in planner.flights:
|
||||
for flight in self.flights:
|
||||
if flight.client_units:
|
||||
self.add_flight_description(flight)
|
||||
|
||||
self.description += "\n"*2
|
||||
self.description += "Planned ally flights:" + "\n"
|
||||
self.description += "=" * 15 + "\n"
|
||||
for planner in self.game.planners.values():
|
||||
if planner.from_cp.captured and len(planner.flights) > 0:
|
||||
self.description += "\nFrom " + planner.from_cp.full_name + " \n"
|
||||
self.description += "-" * 50 + "\n\n"
|
||||
for flight in planner.flights:
|
||||
self.add_ally_flight_description(flight)
|
||||
allied_flights_by_departure = defaultdict(list)
|
||||
for flight in self.flights:
|
||||
if not flight.client_units and flight.friendly:
|
||||
name = flight.departure.airfield_name
|
||||
allied_flights_by_departure[name].append(flight)
|
||||
for departure, flights in allied_flights_by_departure.items():
|
||||
self.description += f"\nFrom {departure}\n"
|
||||
self.description += "-" * 50 + "\n\n"
|
||||
for flight in flights:
|
||||
self.add_ally_flight_description(flight)
|
||||
|
||||
if self.freqs:
|
||||
if self.comms:
|
||||
self.description += "\n\nComms Frequencies:\n"
|
||||
self.description += "=" * 15 + "\n"
|
||||
for name, freq in self.freqs:
|
||||
self.description += "{}: {}\n".format(name, freq)
|
||||
for comm_info in self.comms:
|
||||
self.description += f"{comm_info.name}: {comm_info.freq}\n"
|
||||
self.description += ("-" * 50) + "\n"
|
||||
|
||||
for cp in self.game.theater.controlpoints:
|
||||
if cp.captured and cp.cptype in [ControlPointType.LHA_GROUP, ControlPointType.AIRCRAFT_CARRIER_GROUP]:
|
||||
self.description += cp.name + "\n"
|
||||
self.description += "RADIO : 127.5 Mhz AM\n"
|
||||
self.description += "TACAN : "
|
||||
self.description += str(cp.tacanN)
|
||||
if cp.tacanY:
|
||||
self.description += "Y"
|
||||
else:
|
||||
self.description += "X"
|
||||
self.description += " " + str(cp.tacanI) + "\n"
|
||||
|
||||
if cp.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP and hasattr(cp, "icls"):
|
||||
self.description += "ICLS Channel : " + str(cp.icls) + "\n"
|
||||
self.description += "-" * 50 + "\n"
|
||||
for runway in self.dynamic_runways:
|
||||
self.description += f"{runway.airfield_name}\n"
|
||||
self.description += f"RADIO : {runway.atc}\n"
|
||||
if runway.tacan is not None:
|
||||
self.description += f"TACAN : {runway.tacan} {runway.tacan_callsign}\n"
|
||||
if runway.icls is not None:
|
||||
self.description += f"ICLS Channel : {runway.icls}\n"
|
||||
self.description += "-" * 50 + "\n"
|
||||
|
||||
|
||||
self.description += "JTACS [F-10 Menu] : \n"
|
||||
self.description += "===================\n\n"
|
||||
for jtac in self.game.jtacs:
|
||||
self.description += str(jtac[0]) + " -- Code : " + str(jtac[1]) + "\n"
|
||||
for jtac in self.jtacs:
|
||||
self.description += f"{jtac.region} -- Code : {jtac.code}\n"
|
||||
|
||||
self.m.set_description_text(self.description)
|
||||
self.mission.set_description_text(self.description)
|
||||
|
||||
self.m.add_picture_blue(os.path.abspath("./resources/ui/splash_screen.png"))
|
||||
self.mission.add_picture_blue(os.path.abspath(
|
||||
"./resources/ui/splash_screen.png"))
|
||||
|
||||
|
||||
def generate_ongoing_war_text(self):
|
||||
|
||||
@ -189,6 +189,7 @@ class GroundObjectsGenerator:
|
||||
"N/A",
|
||||
atc=atc_channel,
|
||||
tacan=tacan,
|
||||
tacan_callsign=tacan_callsign,
|
||||
icls=icls_channel,
|
||||
)
|
||||
|
||||
|
||||
@ -23,7 +23,6 @@ only be added per airframe, so PvP missions where each side have the same
|
||||
aircraft will be able to see the enemy's kneeboard for the same airframe.
|
||||
"""
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
@ -36,6 +35,7 @@ from . import units
|
||||
from .aircraft import FlightData
|
||||
from .airfields import RunwayData
|
||||
from .airsupportgen import AwacsInfo, TankerInfo
|
||||
from .briefinggen import CommInfo, JtacInfo, MissionInfoGenerator
|
||||
from .radios import RadioFrequency
|
||||
|
||||
|
||||
@ -95,21 +95,6 @@ class KneeboardPage:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommInfo:
|
||||
"""Communications information for the kneeboard."""
|
||||
name: str
|
||||
freq: RadioFrequency
|
||||
|
||||
|
||||
@dataclass
|
||||
class JtacInfo:
|
||||
"""JTAC information for the kneeboard."""
|
||||
callsign: str
|
||||
region: str
|
||||
code: str
|
||||
|
||||
|
||||
class BriefingPage(KneeboardPage):
|
||||
"""A kneeboard page containing briefing information."""
|
||||
def __init__(self, flight: FlightData, comms: List[CommInfo],
|
||||
@ -208,57 +193,17 @@ class BriefingPage(KneeboardPage):
|
||||
return f"{channel.radio_name} Ch {channel.channel}"
|
||||
|
||||
|
||||
class KneeboardGenerator:
|
||||
class KneeboardGenerator(MissionInfoGenerator):
|
||||
"""Creates kneeboard pages for each client flight in the mission."""
|
||||
|
||||
def __init__(self, mission: Mission) -> None:
|
||||
self.mission = mission
|
||||
self.comms: List[CommInfo] = []
|
||||
self.awacs: List[AwacsInfo] = []
|
||||
self.tankers: List[TankerInfo] = []
|
||||
self.jtacs: List[JtacInfo] = []
|
||||
super().__init__(mission)
|
||||
|
||||
def add_comm(self, name: str, freq: RadioFrequency) -> None:
|
||||
"""Adds communications info to the kneeboard.
|
||||
|
||||
Args:
|
||||
name: Name of the radio channel.
|
||||
freq: Frequency of the radio channel.
|
||||
"""
|
||||
self.comms.append(CommInfo(name, freq))
|
||||
|
||||
def add_awacs(self, awacs: AwacsInfo) -> None:
|
||||
"""Adds an AWACS/GCI to the kneeboard.
|
||||
|
||||
Args:
|
||||
awacs: AWACS information.
|
||||
"""
|
||||
self.awacs.append(awacs)
|
||||
|
||||
def add_tanker(self, tanker: TankerInfo) -> None:
|
||||
"""Adds a tanker to the kneeboard.
|
||||
|
||||
Args:
|
||||
tanker: Tanker information.
|
||||
"""
|
||||
self.tankers.append(tanker)
|
||||
|
||||
def add_jtac(self, callsign: str, region: str, code: str) -> None:
|
||||
"""Adds a JTAC to the kneeboard.
|
||||
|
||||
Args:
|
||||
callsign: Callsign of the JTAC.
|
||||
region: JTAC's area of responsibility.
|
||||
code: Laser code used by the JTAC.
|
||||
"""
|
||||
# TODO: Radio info? Type?
|
||||
self.jtacs.append(JtacInfo(callsign, region, code))
|
||||
|
||||
def generate(self, flights: List[FlightData]) -> None:
|
||||
def generate(self) -> None:
|
||||
"""Generates a kneeboard per client flight."""
|
||||
temp_dir = Path("kneeboards")
|
||||
temp_dir.mkdir(exist_ok=True)
|
||||
for aircraft, pages in self.pages_by_airframe(flights).items():
|
||||
for aircraft, pages in self.pages_by_airframe().items():
|
||||
aircraft_dir = temp_dir / aircraft.id
|
||||
aircraft_dir.mkdir(exist_ok=True)
|
||||
for idx, page in enumerate(pages):
|
||||
@ -266,7 +211,7 @@ class KneeboardGenerator:
|
||||
page.write(page_path)
|
||||
self.mission.add_aircraft_kneeboard(aircraft, page_path)
|
||||
|
||||
def pages_by_airframe(self, flights: List[FlightData]) -> Dict[FlyingType, List[KneeboardPage]]:
|
||||
def pages_by_airframe(self) -> Dict[FlyingType, List[KneeboardPage]]:
|
||||
"""Returns a list of kneeboard pages per airframe in the mission.
|
||||
|
||||
Only client flights will be included, but because DCS does not support
|
||||
@ -278,7 +223,7 @@ class KneeboardGenerator:
|
||||
that aircraft.
|
||||
"""
|
||||
all_flights: Dict[FlyingType, List[KneeboardPage]] = defaultdict(list)
|
||||
for flight in flights:
|
||||
for flight in self.flights:
|
||||
if not flight.client_units:
|
||||
continue
|
||||
all_flights[flight.aircraft_type].extend(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user