Assign laser codes to players with TGPs.

This doesn't configure the bombs in the mission or anything yet; it only
pre-assigns a laser code for the player to use if they choose to.
This commit is contained in:
Dan Albert 2021-07-31 16:49:58 -07:00
parent fc45c3b98c
commit 73ba7933da
4 changed files with 44 additions and 44 deletions

View File

@ -294,8 +294,10 @@ class Operation:
cls._generate_ground_units()
cls._generate_transports()
cls._generate_destroyed_units()
cls._generate_air_units()
# Generate ground conflicts first so the JTACs get the first laser code (1688)
# rather than the first player flight with a TGP.
cls._generate_ground_conflicts()
cls._generate_air_units()
cls.assign_channels_to_flights(
cls.airgen.flights, cls.airsupportgen.air_support
)
@ -357,6 +359,7 @@ class Operation:
cls.game,
cls.radio_registry,
cls.tacan_registry,
cls.laser_code_registry,
cls.unit_map,
air_support=cls.airsupportgen.air_support,
)

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import itertools
import logging
import random
from dataclasses import dataclass
from dataclasses import dataclass, field
from datetime import timedelta
from functools import cached_property
from typing import Dict, List, Optional, TYPE_CHECKING, Type, Union, Iterable, Any
@ -65,7 +65,7 @@ from dcs.unitgroup import FlyingGroup, ShipGroup, StaticGroup
from dcs.unittype import FlyingType
from game import db
from game.data.weapons import Pylon
from game.data.weapons import Pylon, WeaponType as WeaponTypeEnum
from game.dcs.aircrafttype import AircraftType
from game.factions.faction import Faction
from game.settings import Settings
@ -90,6 +90,7 @@ from gen.flights.flight import (
FlightWaypoint,
FlightWaypointType,
)
from gen.lasercoderegistry import LaserCodeRegistry
from gen.radios import RadioFrequency, RadioRegistry
from gen.runways import RunwayData
from gen.tacan import TacanBand, TacanRegistry
@ -138,6 +139,8 @@ class FlightData:
flight_type: FlightType
aircraft_type: AircraftType
#: All units in the flight.
units: List[FlyingUnit]
@ -165,49 +168,24 @@ class FlightData:
#: Radio frequency for intra-flight communications.
intra_flight_channel: RadioFrequency
#: Map of radio frequencies to their assigned radio and channel, if any.
frequency_to_channel_map: Dict[RadioFrequency, ChannelAssignment]
#: Bingo fuel value in lbs.
bingo_fuel: Optional[int]
joker_fuel: Optional[int]
def __init__(
self,
package: Package,
aircraft_type: AircraftType,
flight_type: FlightType,
units: List[FlyingUnit],
size: int,
friendly: bool,
departure_delay: timedelta,
departure: RunwayData,
arrival: RunwayData,
divert: Optional[RunwayData],
waypoints: List[FlightWaypoint],
intra_flight_channel: RadioFrequency,
bingo_fuel: Optional[int],
joker_fuel: Optional[int],
custom_name: Optional[str],
) -> None:
self.package = package
self.aircraft_type = aircraft_type
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
self.frequency_to_channel_map = {}
self.bingo_fuel = bingo_fuel
self.joker_fuel = joker_fuel
laser_codes: list[Optional[int]]
custom_name: Optional[str]
callsign: str = field(init=False)
#: Map of radio frequencies to their assigned radio and channel, if any.
frequency_to_channel_map: Dict[RadioFrequency, ChannelAssignment] = field(
init=False, default_factory=dict
)
def __post_init__(self) -> None:
self.callsign = create_group_callsign_from_unit(self.units[0])
self.custom_name = custom_name
@property
def client_units(self) -> List[FlyingUnit]:
@ -247,6 +225,7 @@ class AircraftConflictGenerator:
game: Game,
radio_registry: RadioRegistry,
tacan_registry: TacanRegistry,
laser_code_registry: LaserCodeRegistry,
unit_map: UnitMap,
air_support: AirSupport,
) -> None:
@ -255,6 +234,7 @@ class AircraftConflictGenerator:
self.settings = settings
self.radio_registry = radio_registry
self.tacan_registy = tacan_registry
self.laser_code_registry = laser_code_registry
self.unit_map = unit_map
self.flights: List[FlightData] = []
self.air_support = air_support
@ -361,6 +341,7 @@ class AircraftConflictGenerator:
self._setup_payload(flight, group)
self._setup_livery(flight, group)
laser_codes = []
for unit, pilot in zip(group.units, flight.roster.pilots):
player = pilot is not None and pilot.player
self.set_skill(unit, pilot, blue=flight.departure.captured)
@ -368,6 +349,11 @@ class AircraftConflictGenerator:
if player and group.late_activation:
group.late_activation = False
code: Optional[int] = None
if flight.loadout.has_weapon_of_type(WeaponTypeEnum.TGP) and player:
code = self.laser_code_registry.get_next_laser_code()
laser_codes.append(code)
# Set up F-14 Client to have pre-stored alignment
if unit_type is F_14B:
unit.set_property(F_14B.Properties.INSAlignmentStored.id, True)
@ -423,6 +409,7 @@ class AircraftConflictGenerator:
bingo_fuel=flight.flight_plan.bingo_fuel,
joker_fuel=flight.flight_plan.joker_fuel,
custom_name=flight.custom_name,
laser_codes=laser_codes,
)
)

View File

@ -31,6 +31,12 @@ class Loadout:
def derive_custom(self, name: str) -> Loadout:
return Loadout(name, self.pylons, self.date, is_custom=True)
def has_weapon_of_type(self, weapon_type: WeaponType) -> bool:
for weapon in self.pylons.values():
if weapon is not None and weapon.weapon_group.type is weapon_type:
return True
return False
@staticmethod
def _fallback_for(
weapon: Weapon,
@ -79,9 +85,7 @@ class Loadout:
def replace_lgbs_if_no_tgp(
self, unit_type: AircraftType, date: datetime.date
) -> None:
for weapon in self.pylons.values():
if weapon is not None and weapon.weapon_group.type is WeaponType.TGP:
# Have a TGP. Nothing to do.
if self.has_weapon_of_type(WeaponType.TGP):
return
new_pylons = dict(self.pylons)

View File

@ -354,6 +354,12 @@ class BriefingPage(KneeboardPage):
["Bingo", "Joker"],
)
if any(self.flight.laser_codes):
codes: list[list[str]] = []
for idx, code in enumerate(self.flight.laser_codes, start=1):
codes.append([str(idx), "" if code is None else str(code)])
writer.table(codes, ["#", "Laser Code"])
writer.write(path)
def airfield_info_row(