dcs-retribution/game/pretense/pretenseflightgroupconfigurator.py
Druss99 dd7e4c908e
Recovery tanker support (#429)
* fix conflict

* squash bugs and reuse patrol layout

* fix tanker tacan and formatting

* fix unlimited fuel option

* update pretense for tanker changes

* reuse refueling flight plan and bugfix for sunken carrier

changelog

* remove unitmap dependency

* formatting and more unit map removal

* more formatting

* typing and black

* keep tanker out of clouds

* fix if there are no clouds

* better cloud handling

* groundwork for recovery task

* remove changes to game/commander

* Finishing up recovery tankers

---------

Co-authored-by: Raffson <Raffson@users.noreply.github.com>
2024-12-23 04:39:10 +00:00

186 lines
6.4 KiB
Python

from __future__ import annotations
from datetime import datetime
from typing import Any, Optional, TYPE_CHECKING
from dcs import Mission, Point
from dcs.flyingunit import FlyingUnit
from dcs.unitgroup import FlyingGroup
from game.ato import Flight, FlightType
from game.ato.flightmember import FlightMember
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flightwaypointtype import FlightWaypointType
from game.data.weapons import Pylon
from game.missiongenerator.aircraft.aircraftbehavior import AircraftBehavior
from game.missiongenerator.aircraft.aircraftpainter import AircraftPainter
from game.missiongenerator.aircraft.bingoestimator import BingoEstimator
from game.missiongenerator.aircraft.flightdata import FlightData
from game.missiongenerator.aircraft.flightgroupconfigurator import (
FlightGroupConfigurator,
)
from game.missiongenerator.aircraft.waypoints import WaypointGenerator
from game.missiongenerator.aircraft.waypoints.pydcswaypointbuilder import (
PydcsWaypointBuilder,
)
from game.missiongenerator.missiondata import MissionData
from game.radio.datalink import DataLinkRegistry
from game.radio.radios import RadioRegistry
from game.radio.tacan import (
TacanRegistry,
)
from game.runways import RunwayData
if TYPE_CHECKING:
from game import Game
class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
def __init__(
self,
flight: Flight,
group: FlyingGroup[Any],
game: Game,
mission: Mission,
time: datetime,
radio_registry: RadioRegistry,
tacan_registry: TacanRegistry,
datalink_registry: DataLinkRegistry,
mission_data: MissionData,
dynamic_runways: dict[str, RunwayData],
use_client: bool,
) -> None:
super().__init__(
flight,
group,
game,
mission,
time,
radio_registry,
tacan_registry,
datalink_registry,
mission_data,
dynamic_runways,
use_client,
)
self.flight = flight
self.group = group
self.game = game
self.mission = mission
self.time = time
self.radio_registry = radio_registry
self.tacan_registry = tacan_registry
self.datalink_registry = datalink_registry
self.mission_data = mission_data
self.dynamic_runways = dynamic_runways
self.use_client = use_client
def configure(self) -> FlightData:
flight_channel = self.setup_radios()
AircraftBehavior(self.flight.flight_type, self.mission_data).apply_to(
self.flight, self.group
)
AircraftPainter(self.flight, self.group).apply_livery()
self.setup_props()
self.setup_payloads()
self.setup_fuel()
laser_codes: list[Optional[int]] = []
for unit, pilot in zip(self.group.units, self.flight.roster.members):
self.configure_flight_member(unit, pilot, laser_codes)
divert = None
if self.flight.divert is not None:
divert = self.flight.divert.active_runway(
self.game.theater, self.game.conditions, self.dynamic_runways
)
mission_start_time, waypoints = WaypointGenerator(
self.flight,
self.group,
self.mission,
self.time,
self.game.settings,
self.mission_data,
).create_waypoints()
if self.flight.client_count >= 1:
waypoints = waypoints[:1]
self.group.points = self.group.points[:1]
for cp in self.game.theater.controlpoints:
PydcsWaypointBuilder(
FlightWaypoint(
name=cp.full_name,
waypoint_type=FlightWaypointType.NAV,
position=cp.position,
alt_type="RADIO",
control_point=cp,
),
self.group,
self.flight,
self.mission,
self.time,
self.mission_data,
).build()
divert_position: Point | None = None
if self.flight.divert is not None:
divert_position = self.flight.divert.position
bingo_estimator = BingoEstimator(
self.flight.unit_type.fuel_consumption,
self.flight.arrival.position,
divert_position,
self.flight.flight_plan.waypoints,
)
self.group.uncontrolled = False
return FlightData(
package=self.flight.package,
aircraft_type=self.flight.unit_type,
squadron=self.flight.squadron,
flight_type=self.flight.flight_type,
units=self.group.units,
size=len(self.group.units),
friendly=self.flight.departure.captured,
departure_delay=mission_start_time,
departure=self.flight.departure.active_runway(
self.game.theater, self.game.conditions, self.dynamic_runways
),
arrival=self.flight.arrival.active_runway(
self.game.theater, self.game.conditions, self.dynamic_runways
),
divert=divert,
waypoints=waypoints,
intra_flight_channel=flight_channel,
bingo_fuel=bingo_estimator.estimate_bingo(),
joker_fuel=bingo_estimator.estimate_joker(),
custom_name=self.flight.custom_name,
laser_codes=laser_codes,
)
def setup_payloads(self) -> None:
for unit, member in zip(self.group.units, self.flight.iter_members()):
self.setup_payload(unit, member)
def setup_payload(self, unit: FlyingUnit, member: FlightMember) -> None:
unit.pylons.clear()
loadout = member.loadout
if self.flight.flight_type == FlightType.SEAD:
loadout = member.loadout.default_for_task_and_aircraft(
FlightType.SEAD_SWEEP, self.flight.unit_type.dcs_unit_type
)
if self.game.settings.restrict_weapons_by_date:
loadout = loadout.degrade_for_date(self.flight.unit_type, self.game.date)
for pylon_number, weapon in loadout.pylons.items():
if weapon is None:
continue
pylon = Pylon.for_aircraft(self.flight.unit_type, pylon_number)
pylon.equip(unit, weapon)