Restored compatibility of the Pretense generator after the timedelta -> datetime change and other changes caused by the Liberation merge/sync.

This commit is contained in:
MetalStormGhost 2023-10-09 20:17:31 +03:00
parent b6449a7056
commit 85db8c908e
5 changed files with 102 additions and 49 deletions

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import random
from collections.abc import Iterator
from dataclasses import dataclass
from datetime import timedelta
from datetime import datetime
from typing import TYPE_CHECKING, Type
from game.utils import feet
@ -31,16 +31,20 @@ class PretenseCargoFlightPlan(StandardFlightPlan[FerryLayout]):
def tot_waypoint(self) -> FlightWaypoint:
return self.layout.arrival
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> timedelta | None:
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None:
# TOT planning isn't really useful for ferries. They're behind the front
# lines so no need to wait for escorts or for other missions to complete.
return None
def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> timedelta | None:
def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None:
return None
@property
def mission_departure_time(self) -> timedelta:
def mission_begin_on_station_time(self) -> datetime | None:
return None
@property
def mission_departure_time(self) -> datetime:
return self.package.time_over_target
@ -77,14 +81,14 @@ class Builder(IBuilder[PretenseCargoFlightPlan, FerryLayout]):
offmap_heading, PRETENSE_CARGO_FLIGHT_DISTANCE
)
altitude_is_agl = self.flight.unit_type.dcs_unit_type.helicopter
altitude_is_agl = self.flight.is_helo
altitude = (
feet(1500)
feet(self.coalition.game.settings.heli_cruise_alt_agl)
if altitude_is_agl
else self.flight.unit_type.preferred_patrol_altitude
)
builder = WaypointBuilder(self.flight, self.coalition)
builder = WaypointBuilder(self.flight)
ferry_layout = FerryLayout(
departure=builder.join(offmap_transport_spawn),
nav_to=builder.nav_path(
@ -101,8 +105,7 @@ class Builder(IBuilder[PretenseCargoFlightPlan, FerryLayout]):
ferry_layout.departure = builder.join(offmap_transport_spawn)
ferry_layout.nav_to.append(builder.join(offmap_transport_spawn))
ferry_layout.nav_from.append(builder.join(offmap_transport_spawn))
print(ferry_layout)
return ferry_layout
def build(self) -> PretenseCargoFlightPlan:
def build(self, dump_debug_info: bool = False) -> PretenseCargoFlightPlan:
return PretenseCargoFlightPlan(self.flight, self.layout())

View File

@ -395,7 +395,7 @@ class PretenseAircraftGenerator:
)
print(
f"Generated flight for {flight_type} flying {squadron.aircraft.name} at {squadron.location.name}"
f"Generated flight for {flight_type} flying {squadron.aircraft.display_name} at {squadron.location.name}"
)
ato.add_package(package)
return
@ -442,7 +442,7 @@ class PretenseAircraftGenerator:
divert=cp,
)
print(
f"Generated flight for {flight_type} flying {squadron.aircraft.name} at {squadron.location.name}"
f"Generated flight for {flight_type} flying {squadron.aircraft.display_name} at {squadron.location.name}"
)
package.add_flight(flight)
@ -483,7 +483,7 @@ class PretenseAircraftGenerator:
divert=cp,
)
print(
f"Generated flight for {flight_type} flying {squadron.aircraft.name} at {squadron.location.name}"
f"Generated flight for {flight_type} flying {squadron.aircraft.display_name} at {squadron.location.name}"
)
package.add_flight(flight)
@ -524,7 +524,7 @@ class PretenseAircraftGenerator:
divert=cp,
)
print(
f"Generated flight for {flight_type} flying {squadron.aircraft.name} at {squadron.location.name}"
f"Generated flight for {flight_type} flying {squadron.aircraft.display_name} at {squadron.location.name}"
)
package.add_flight(flight)
@ -582,11 +582,11 @@ class PretenseAircraftGenerator:
StartType.COLD,
divert=cp,
)
for roster_pilot in flight.roster.pilots:
if roster_pilot is not None:
roster_pilot.player = True
for roster_pilot in flight.roster.members:
if roster_pilot.pilot is not None:
roster_pilot.pilot.player = True
print(
f"Generated flight for {squadron.primary_task} flying {squadron.aircraft.name} at {squadron.location.name}. Pilot client count: {flight.client_count}"
f"Generated flight for {squadron.primary_task} flying {squadron.aircraft.display_name} at {squadron.location.name}. Pilot client count: {flight.client_count}"
)
package.add_flight(flight)
@ -720,7 +720,9 @@ class PretenseAircraftGenerator:
flight.departure, flight
)
logging.info(
f"Generating flight in {flight.coalition.faction.name} package {flight.squadron.aircraft} {flight.flight_type} for target: {package.target.name}, departure: {flight.from_cp.name}"
f"Generating flight in {flight.coalition.faction.name} package"
f" {flight.squadron.aircraft} {flight.flight_type} for target: {package.target.name},"
f" departure: {flight.departure.name}"
)
if flight.alive:
@ -761,45 +763,81 @@ class PretenseAircraftGenerator:
self.ground_spawns,
self.mission_data,
).create_flight_group()
if flight.flight_type == FlightType.CAS:
control_points_to_scan = (
list(self.game.theater.closest_opposing_control_points())
+ self.game.theater.controlpoints
)
if (
flight.flight_type == FlightType.CAS
or flight.flight_type == FlightType.TARCAP
):
for conflict in self.game.theater.conflicts():
flight.package.target = conflict
break
elif flight.flight_type == FlightType.BARCAP:
for cp in control_points_to_scan:
if cp.coalition != flight.coalition or cp == flight.departure:
continue
if flight.package.target != flight.departure:
break
for mission_target in cp.ground_objects:
flight.package.target = mission_target
break
elif (
flight.flight_type == FlightType.STRIKE
or flight.flight_type == FlightType.BAI
):
for cp in self.game.theater.closest_opposing_control_points():
if cp.coalition == flight.coalition:
for cp in control_points_to_scan:
if cp.coalition == flight.coalition or cp == flight.departure:
continue
if flight.package.target != flight.departure:
break
for mission_target in cp.ground_objects:
flight.package.target = mission_target
break
elif (
flight.flight_type == FlightType.OCA_RUNWAY
or flight.flight_type == FlightType.OCA_AIRCRAFT
):
for cp in self.game.theater.controlpoints:
if cp.coalition == flight.coalition or not isinstance(cp, Airfield):
for cp in control_points_to_scan:
if (
cp.coalition == flight.coalition
or not isinstance(cp, Airfield)
or cp == flight.departure
):
continue
flight.package.target = cp
elif flight.flight_type == FlightType.DEAD:
for cp in self.game.theater.controlpoints:
if cp.coalition == flight.coalition:
break
elif (
flight.flight_type == FlightType.DEAD
or flight.flight_type == FlightType.SEAD
):
for cp in control_points_to_scan:
if cp.coalition == flight.coalition or cp == flight.departure:
continue
if flight.package.target != flight.departure:
break
for ground_object in cp.ground_objects:
is_ewr = isinstance(ground_object, EwrGroundObject)
is_sam = isinstance(ground_object, SamGroundObject)
if is_ewr or is_sam:
flight.package.target = ground_object
break
elif flight.flight_type == FlightType.AIR_ASSAULT:
for cp in self.game.theater.closest_opposing_control_points():
if cp.coalition == flight.coalition:
for cp in control_points_to_scan:
if cp.coalition == flight.coalition or cp == flight.departure:
continue
if flight.is_hercules:
if cp.coalition == flight.coalition or not isinstance(cp, Airfield):
continue
flight.package.target = cp
break
now = self.game.conditions.start_time
flight.package.set_tot_asap(now)
logging.info(
f"Configuring flight {group.name} {flight.squadron.aircraft} {flight.flight_type}, number of players: {flight.client_count}"
@ -812,7 +850,6 @@ class PretenseAircraftGenerator:
self.time,
self.radio_registry,
self.tacan_registy,
self.laser_code_registry,
self.mission_data,
dynamic_runways,
self.use_client,
@ -832,7 +869,7 @@ class PretenseAircraftGenerator:
or flight.client_count
and (
not self.need_ecm
or flight.loadout.has_weapon_of_type(WeaponType.JAMMER)
or flight.any_member_has_weapon_of_type(WeaponType.JAMMER)
)
):
self.ewrj_package_dict[id(flight.package)].append(group)

View File

@ -3,14 +3,17 @@ from __future__ import annotations
from datetime import datetime
from typing import Any, Optional, TYPE_CHECKING
from dcs import Mission
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.data.weapons import Pylon
from game.lasercodes.lasercoderegistry import LaserCodeRegistry
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,
@ -37,7 +40,6 @@ class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
time: datetime,
radio_registry: RadioRegistry,
tacan_registry: TacanRegistry,
laser_code_registry: LaserCodeRegistry,
mission_data: MissionData,
dynamic_runways: dict[str, RunwayData],
use_client: bool,
@ -50,7 +52,6 @@ class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
time,
radio_registry,
tacan_registry,
laser_code_registry,
mission_data,
dynamic_runways,
use_client,
@ -63,7 +64,6 @@ class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
self.time = time
self.radio_registry = radio_registry
self.tacan_registry = tacan_registry
self.laser_code_registry = laser_code_registry
self.mission_data = mission_data
self.dynamic_runways = dynamic_runways
self.use_client = use_client
@ -72,12 +72,12 @@ class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
AircraftBehavior(self.flight.flight_type).apply_to(self.flight, self.group)
AircraftPainter(self.flight, self.group).apply_livery()
self.setup_props()
self.setup_payload()
self.setup_payloads()
self.setup_fuel()
flight_channel = self.setup_radios()
laser_codes: list[Optional[int]] = []
for unit, pilot in zip(self.group.units, self.flight.roster.pilots):
for unit, pilot in zip(self.group.units, self.flight.roster.members):
self.configure_flight_member(unit, pilot, laser_codes)
divert = None
@ -90,12 +90,21 @@ class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
self.flight,
self.group,
self.mission,
self.game.conditions.start_time,
self.time,
self.game.settings,
self.mission_data,
).create_waypoints()
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(
@ -105,7 +114,7 @@ class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
flight_type=self.flight.flight_type,
units=self.group.units,
size=len(self.group.units),
friendly=self.flight.from_cp.captured,
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
@ -116,21 +125,26 @@ class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
divert=divert,
waypoints=waypoints,
intra_flight_channel=flight_channel,
bingo_fuel=self.flight.flight_plan.bingo_fuel,
joker_fuel=self.flight.flight_plan.joker_fuel,
bingo_fuel=bingo_estimator.estimate_bingo(),
joker_fuel=bingo_estimator.estimate_joker(),
custom_name=self.flight.custom_name,
laser_codes=laser_codes,
)
def setup_payload(self) -> None:
for p in self.group.units:
p.pylons.clear()
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:
self.flight.loadout = self.flight.loadout.default_for_task_and_aircraft(
loadout = member.loadout.default_for_task_and_aircraft(
FlightType.SEAD_SWEEP, self.flight.unit_type.dcs_unit_type
)
loadout = self.flight.loadout
if self.game.settings.restrict_weapons_by_date:
loadout = loadout.degrade_for_date(self.flight.unit_type, self.game.date)
@ -138,4 +152,4 @@ class PretenseFlightGroupConfigurator(FlightGroupConfigurator):
if weapon is None:
continue
pylon = Pylon.for_aircraft(self.flight.unit_type, pylon_number)
pylon.equip(self.group, weapon)
pylon.equip(unit, weapon)

View File

@ -118,7 +118,7 @@ class PretenseFlightGroupSpawner(FlightGroupSpawner):
raise RuntimeError(
f"Cannot spawn fixed-wing aircraft at {cp} because of insufficient ground spawn slots."
)
pilot_count = len(self.flight.roster.pilots)
pilot_count = len(self.flight.roster.members)
if (
not is_heli
and self.flight.roster.player_count != pilot_count

View File

@ -148,7 +148,7 @@ class PretenseMissionGenerator(MissionGenerator):
player_cp = front_line.blue_cp
enemy_cp = front_line.red_cp
conflict = FrontLineConflictDescription.frontline_cas_conflict(
front_line, self.game.theater, self.game.settings
front_line, self.game.theater
)
# Generate frontline ops
player_gp = self.game.ground_planners[player_cp.id].units_per_cp[
@ -166,7 +166,6 @@ class PretenseMissionGenerator(MissionGenerator):
self.unit_map,
self.radio_registry,
self.mission_data,
self.laser_code_registry,
)
ground_conflict_gen.generate()