mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Recovery tanker follow up (#2659)
Fix timing issues for RecoveryTankerFlightPlan. AEWC and Refueling can be planned on LHA.
This commit is contained in:
parent
22503d4e95
commit
0fd0f0e7c0
@ -15,6 +15,7 @@ Saves from 6.0.0 are compatible with 6.1.0
|
||||
* **[Engine]** Support for DCS 2.8.1.34437.
|
||||
* **[Factions]** Defaulted bluefor modern to use Georgian and Ukrainian liveries for Russian aircraft.
|
||||
* **[Factions]** Added Peru.
|
||||
* **[Flight Planning]** AEW&C and Refueling flights are now plannable on LHA carriers.
|
||||
* **[Flight Planning]** Refueling flights planned on aircraft carriers will act as a recovery tanker for the carrier.
|
||||
* **[Loadouts]** Adjusted F-15E loadouts.
|
||||
* **[Mission Generation]** The previous turn will now be saved as last_turn.liberation when submitting mission results. This is often essential for debugging bug reports. **Include this file in the bug report whenever it is available.**
|
||||
|
||||
@ -3,8 +3,7 @@ from __future__ import annotations
|
||||
from typing import Any, TYPE_CHECKING, Type
|
||||
|
||||
from game.ato import FlightType
|
||||
from game.ato.flightplans.shiprecoverytanker import RecoveryTankerFlightPlan
|
||||
from game.theater.controlpoint import Carrier
|
||||
from game.theater.controlpoint import NavalControlPoint
|
||||
from .aewc import AewcFlightPlan
|
||||
from .airassault import AirAssaultFlightPlan
|
||||
from .airlift import AirliftFlightPlan
|
||||
@ -21,6 +20,7 @@ from .ocarunway import OcaRunwayFlightPlan
|
||||
from .packagerefueling import PackageRefuelingFlightPlan
|
||||
from .planningerror import PlanningError
|
||||
from .sead import SeadFlightPlan
|
||||
from .shiprecoverytanker import RecoveryTankerFlightPlan
|
||||
from .strike import StrikeFlightPlan
|
||||
from .sweep import SweepFlightPlan
|
||||
from .tarcap import TarCapFlightPlan
|
||||
@ -37,7 +37,7 @@ class FlightPlanBuilderTypes:
|
||||
if flight.flight_type is FlightType.REFUELING:
|
||||
target = flight.package.target
|
||||
if target.is_friendly(flight.squadron.player) and isinstance(
|
||||
target, Carrier
|
||||
target, NavalControlPoint
|
||||
):
|
||||
return RecoveryTankerFlightPlan.builder_type()
|
||||
if target.is_friendly(flight.squadron.player) or isinstance(
|
||||
|
||||
@ -8,7 +8,6 @@ from game.ato.flightplans.ibuilder import IBuilder
|
||||
from game.ato.flightplans.standard import StandardLayout
|
||||
from game.ato.flightplans.waypointbuilder import WaypointBuilder
|
||||
from game.ato.flightwaypoint import FlightWaypoint
|
||||
from game.utils import feet
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@ -39,7 +38,7 @@ class RecoveryTankerFlightPlan(StandardFlightPlan[RecoveryTankerLayout]):
|
||||
|
||||
@property
|
||||
def mission_departure_time(self) -> timedelta:
|
||||
return timedelta(hours=2)
|
||||
return self.patrol_end_time
|
||||
|
||||
@property
|
||||
def patrol_start_time(self) -> timedelta:
|
||||
@ -47,7 +46,7 @@ class RecoveryTankerFlightPlan(StandardFlightPlan[RecoveryTankerLayout]):
|
||||
|
||||
@property
|
||||
def patrol_end_time(self) -> timedelta:
|
||||
return self.tot + self.mission_departure_time
|
||||
return self.tot + timedelta(hours=2)
|
||||
|
||||
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> timedelta | None:
|
||||
if waypoint == self.tot_waypoint:
|
||||
@ -56,28 +55,33 @@ class RecoveryTankerFlightPlan(StandardFlightPlan[RecoveryTankerLayout]):
|
||||
|
||||
def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> timedelta | None:
|
||||
if waypoint == self.tot_waypoint:
|
||||
return self.tot + self.mission_departure_time
|
||||
return self.mission_departure_time
|
||||
return None
|
||||
|
||||
|
||||
class Builder(IBuilder[RecoveryTankerFlightPlan, RecoveryTankerLayout]):
|
||||
def layout(self) -> RecoveryTankerLayout:
|
||||
|
||||
# TODO: Propagate the ship position.
|
||||
ship = self.package.target.position
|
||||
|
||||
builder = WaypointBuilder(self.flight, self.coalition)
|
||||
|
||||
recovery = builder.recovery_tanker(ship)
|
||||
# TODO: Propagate the ship position to the Tanker's TOT,
|
||||
# so that we minimize the tanker's need to catch up to the carrier.
|
||||
recovery_ship = self.package.target.position
|
||||
recovery_tanker = builder.recovery_tanker(recovery_ship)
|
||||
|
||||
# We don't have per aircraft cruise altitudes, so just reuse patrol altitude?
|
||||
tanker_type = self.flight.unit_type
|
||||
altitude = tanker_type.preferred_patrol_altitude
|
||||
nav_cruise_altitude = tanker_type.preferred_patrol_altitude
|
||||
|
||||
return RecoveryTankerLayout(
|
||||
departure=builder.takeoff(self.flight.departure),
|
||||
nav_to=builder.nav_path(self.flight.departure.position, ship, altitude),
|
||||
nav_from=builder.nav_path(ship, self.flight.arrival.position, altitude),
|
||||
recovery_ship=recovery,
|
||||
nav_to=builder.nav_path(
|
||||
self.flight.departure.position, recovery_ship, nav_cruise_altitude
|
||||
),
|
||||
nav_from=builder.nav_path(
|
||||
recovery_ship, self.flight.arrival.position, nav_cruise_altitude
|
||||
),
|
||||
recovery_ship=recovery_tanker,
|
||||
arrival=builder.land(self.flight.arrival),
|
||||
divert=builder.divert(self.flight.divert),
|
||||
bullseye=builder.bullseye(),
|
||||
|
||||
@ -2,24 +2,27 @@ from dcs.point import MovingPoint
|
||||
from dcs.task import ActivateBeaconCommand, RecoveryTanker
|
||||
|
||||
from game.ato import FlightType
|
||||
from game.missiongenerator.missiondata import TankerInfo
|
||||
from game.utils import feet, knots
|
||||
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
||||
|
||||
|
||||
class RecoveryTankerBuilder(PydcsWaypointBuilder):
|
||||
def add_tasks(self, waypoint: MovingPoint) -> None:
|
||||
if self.flight.flight_type == FlightType.REFUELING:
|
||||
group_id = self._get_carrier_group_id()
|
||||
speed = knots(250).meters_per_second
|
||||
altitude = feet(6000).meters
|
||||
# Last waypoint has index of 1.
|
||||
last_waypoint = 2
|
||||
recovery_tanker = RecoveryTanker(group_id, speed, altitude, last_waypoint)
|
||||
|
||||
waypoint.add_task(recovery_tanker)
|
||||
assert self.flight.flight_type == FlightType.REFUELING
|
||||
group_id = self._get_carrier_group_id()
|
||||
speed = knots(250).meters_per_second
|
||||
altitude = feet(6000).meters
|
||||
|
||||
self.configure_tanker_tacan(waypoint)
|
||||
# Last waypoint has index of 1.
|
||||
# Give the tanker a end condition of the last carrier waypoint.
|
||||
# If the carrier ever gets more than one waypoint this approach needs to change.
|
||||
last_waypoint = 2
|
||||
recovery_tanker = RecoveryTanker(group_id, speed, altitude, last_waypoint)
|
||||
|
||||
waypoint.add_task(recovery_tanker)
|
||||
|
||||
self.configure_tanker_tacan(waypoint)
|
||||
|
||||
def _get_carrier_group_id(self) -> int:
|
||||
name = self.package.target.name
|
||||
|
||||
@ -1177,6 +1177,8 @@ class NavalControlPoint(ControlPoint, ABC):
|
||||
|
||||
if self.is_friendly(for_player):
|
||||
yield from [
|
||||
FlightType.AEWC,
|
||||
FlightType.REFUELING,
|
||||
# TODO: FlightType.INTERCEPTION
|
||||
# TODO: Buddy tanking for the A-4?
|
||||
# TODO: Rescue chopper?
|
||||
@ -1272,8 +1274,7 @@ class Carrier(NavalControlPoint):
|
||||
yield from super().mission_types(for_player)
|
||||
if self.is_friendly(for_player):
|
||||
yield from [
|
||||
FlightType.AEWC,
|
||||
FlightType.REFUELING,
|
||||
# Nothing yet.
|
||||
]
|
||||
|
||||
def capture(self, game: Game, events: GameUpdateEvents, for_player: bool) -> None:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user