mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
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:
parent
fc45c3b98c
commit
73ba7933da
@ -294,8 +294,10 @@ class Operation:
|
|||||||
cls._generate_ground_units()
|
cls._generate_ground_units()
|
||||||
cls._generate_transports()
|
cls._generate_transports()
|
||||||
cls._generate_destroyed_units()
|
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_ground_conflicts()
|
||||||
|
cls._generate_air_units()
|
||||||
cls.assign_channels_to_flights(
|
cls.assign_channels_to_flights(
|
||||||
cls.airgen.flights, cls.airsupportgen.air_support
|
cls.airgen.flights, cls.airsupportgen.air_support
|
||||||
)
|
)
|
||||||
@ -357,6 +359,7 @@ class Operation:
|
|||||||
cls.game,
|
cls.game,
|
||||||
cls.radio_registry,
|
cls.radio_registry,
|
||||||
cls.tacan_registry,
|
cls.tacan_registry,
|
||||||
|
cls.laser_code_registry,
|
||||||
cls.unit_map,
|
cls.unit_map,
|
||||||
air_support=cls.airsupportgen.air_support,
|
air_support=cls.airsupportgen.air_support,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from typing import Dict, List, Optional, TYPE_CHECKING, Type, Union, Iterable, Any
|
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 dcs.unittype import FlyingType
|
||||||
|
|
||||||
from game import db
|
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.dcs.aircrafttype import AircraftType
|
||||||
from game.factions.faction import Faction
|
from game.factions.faction import Faction
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
@ -90,6 +90,7 @@ from gen.flights.flight import (
|
|||||||
FlightWaypoint,
|
FlightWaypoint,
|
||||||
FlightWaypointType,
|
FlightWaypointType,
|
||||||
)
|
)
|
||||||
|
from gen.lasercoderegistry import LaserCodeRegistry
|
||||||
from gen.radios import RadioFrequency, RadioRegistry
|
from gen.radios import RadioFrequency, RadioRegistry
|
||||||
from gen.runways import RunwayData
|
from gen.runways import RunwayData
|
||||||
from gen.tacan import TacanBand, TacanRegistry
|
from gen.tacan import TacanBand, TacanRegistry
|
||||||
@ -138,6 +139,8 @@ class FlightData:
|
|||||||
|
|
||||||
flight_type: FlightType
|
flight_type: FlightType
|
||||||
|
|
||||||
|
aircraft_type: AircraftType
|
||||||
|
|
||||||
#: All units in the flight.
|
#: All units in the flight.
|
||||||
units: List[FlyingUnit]
|
units: List[FlyingUnit]
|
||||||
|
|
||||||
@ -165,49 +168,24 @@ class FlightData:
|
|||||||
#: Radio frequency for intra-flight communications.
|
#: Radio frequency for intra-flight communications.
|
||||||
intra_flight_channel: RadioFrequency
|
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 value in lbs.
|
||||||
bingo_fuel: Optional[int]
|
bingo_fuel: Optional[int]
|
||||||
|
|
||||||
joker_fuel: Optional[int]
|
joker_fuel: Optional[int]
|
||||||
|
|
||||||
def __init__(
|
laser_codes: list[Optional[int]]
|
||||||
self,
|
|
||||||
package: Package,
|
custom_name: Optional[str]
|
||||||
aircraft_type: AircraftType,
|
|
||||||
flight_type: FlightType,
|
callsign: str = field(init=False)
|
||||||
units: List[FlyingUnit],
|
|
||||||
size: int,
|
#: Map of radio frequencies to their assigned radio and channel, if any.
|
||||||
friendly: bool,
|
frequency_to_channel_map: Dict[RadioFrequency, ChannelAssignment] = field(
|
||||||
departure_delay: timedelta,
|
init=False, default_factory=dict
|
||||||
departure: RunwayData,
|
)
|
||||||
arrival: RunwayData,
|
|
||||||
divert: Optional[RunwayData],
|
def __post_init__(self) -> None:
|
||||||
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
|
|
||||||
self.callsign = create_group_callsign_from_unit(self.units[0])
|
self.callsign = create_group_callsign_from_unit(self.units[0])
|
||||||
self.custom_name = custom_name
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def client_units(self) -> List[FlyingUnit]:
|
def client_units(self) -> List[FlyingUnit]:
|
||||||
@ -247,6 +225,7 @@ class AircraftConflictGenerator:
|
|||||||
game: Game,
|
game: Game,
|
||||||
radio_registry: RadioRegistry,
|
radio_registry: RadioRegistry,
|
||||||
tacan_registry: TacanRegistry,
|
tacan_registry: TacanRegistry,
|
||||||
|
laser_code_registry: LaserCodeRegistry,
|
||||||
unit_map: UnitMap,
|
unit_map: UnitMap,
|
||||||
air_support: AirSupport,
|
air_support: AirSupport,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -255,6 +234,7 @@ class AircraftConflictGenerator:
|
|||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.radio_registry = radio_registry
|
self.radio_registry = radio_registry
|
||||||
self.tacan_registy = tacan_registry
|
self.tacan_registy = tacan_registry
|
||||||
|
self.laser_code_registry = laser_code_registry
|
||||||
self.unit_map = unit_map
|
self.unit_map = unit_map
|
||||||
self.flights: List[FlightData] = []
|
self.flights: List[FlightData] = []
|
||||||
self.air_support = air_support
|
self.air_support = air_support
|
||||||
@ -361,6 +341,7 @@ class AircraftConflictGenerator:
|
|||||||
self._setup_payload(flight, group)
|
self._setup_payload(flight, group)
|
||||||
self._setup_livery(flight, group)
|
self._setup_livery(flight, group)
|
||||||
|
|
||||||
|
laser_codes = []
|
||||||
for unit, pilot in zip(group.units, flight.roster.pilots):
|
for unit, pilot in zip(group.units, flight.roster.pilots):
|
||||||
player = pilot is not None and pilot.player
|
player = pilot is not None and pilot.player
|
||||||
self.set_skill(unit, pilot, blue=flight.departure.captured)
|
self.set_skill(unit, pilot, blue=flight.departure.captured)
|
||||||
@ -368,6 +349,11 @@ class AircraftConflictGenerator:
|
|||||||
if player and group.late_activation:
|
if player and group.late_activation:
|
||||||
group.late_activation = False
|
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
|
# Set up F-14 Client to have pre-stored alignment
|
||||||
if unit_type is F_14B:
|
if unit_type is F_14B:
|
||||||
unit.set_property(F_14B.Properties.INSAlignmentStored.id, True)
|
unit.set_property(F_14B.Properties.INSAlignmentStored.id, True)
|
||||||
@ -423,6 +409,7 @@ class AircraftConflictGenerator:
|
|||||||
bingo_fuel=flight.flight_plan.bingo_fuel,
|
bingo_fuel=flight.flight_plan.bingo_fuel,
|
||||||
joker_fuel=flight.flight_plan.joker_fuel,
|
joker_fuel=flight.flight_plan.joker_fuel,
|
||||||
custom_name=flight.custom_name,
|
custom_name=flight.custom_name,
|
||||||
|
laser_codes=laser_codes,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,12 @@ class Loadout:
|
|||||||
def derive_custom(self, name: str) -> Loadout:
|
def derive_custom(self, name: str) -> Loadout:
|
||||||
return Loadout(name, self.pylons, self.date, is_custom=True)
|
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
|
@staticmethod
|
||||||
def _fallback_for(
|
def _fallback_for(
|
||||||
weapon: Weapon,
|
weapon: Weapon,
|
||||||
@ -79,9 +85,7 @@ class Loadout:
|
|||||||
def replace_lgbs_if_no_tgp(
|
def replace_lgbs_if_no_tgp(
|
||||||
self, unit_type: AircraftType, date: datetime.date
|
self, unit_type: AircraftType, date: datetime.date
|
||||||
) -> None:
|
) -> None:
|
||||||
for weapon in self.pylons.values():
|
if self.has_weapon_of_type(WeaponType.TGP):
|
||||||
if weapon is not None and weapon.weapon_group.type is WeaponType.TGP:
|
|
||||||
# Have a TGP. Nothing to do.
|
|
||||||
return
|
return
|
||||||
|
|
||||||
new_pylons = dict(self.pylons)
|
new_pylons = dict(self.pylons)
|
||||||
|
|||||||
@ -354,6 +354,12 @@ class BriefingPage(KneeboardPage):
|
|||||||
["Bingo", "Joker"],
|
["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)
|
writer.write(path)
|
||||||
|
|
||||||
def airfield_info_row(
|
def airfield_info_row(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user