mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Schedule SEAD with a one minute lead time.
This commit is contained in:
parent
205e4aa707
commit
4939faf5fa
@ -16,6 +16,7 @@ Saves from 2.5 are not compatible with 3.0.
|
|||||||
* **[Flight Planner]** Planned airspeed increased to 0.85 mach for supersonic airframes and 85% of max speed for subsonic.
|
* **[Flight Planner]** Planned airspeed increased to 0.85 mach for supersonic airframes and 85% of max speed for subsonic.
|
||||||
* **[Flight Planner]** Taxi time estimation for airfields increased from 5 minutes to 8 minutes.
|
* **[Flight Planner]** Taxi time estimation for airfields increased from 5 minutes to 8 minutes.
|
||||||
* **[Flight Planner]** Reduce expected error margin for flight plans from 10% to 5%.
|
* **[Flight Planner]** Reduce expected error margin for flight plans from 10% to 5%.
|
||||||
|
* **[Flight Planner]** SEAD flights are scheduled one minute ahead of the package's TOT so that they can suppress the site ahead of the strike.
|
||||||
* **[Payloads]** AI flights for most air to ground mission types (CAS excluded) will have their guns emptied to prevent strafing fully armed and operational battle stations. Gun-reliant airframes like A-10s and warbirds will keep their bullets.
|
* **[Payloads]** AI flights for most air to ground mission types (CAS excluded) will have their guns emptied to prevent strafing fully armed and operational battle stations. Gun-reliant airframes like A-10s and warbirds will keep their bullets.
|
||||||
* **[Kneeboard]** ATC table overflow alleviated by wrapping long airfield names and splitting ATC frequency and channel into separate rows.
|
* **[Kneeboard]** ATC table overflow alleviated by wrapping long airfield names and splitting ATC frequency and channel into separate rows.
|
||||||
* **[UI]** Added new web based map UI. This is mostly functional but many of the old display options are a WIP. Revert to the old map with --old-map.
|
* **[UI]** Added new web based map UI. This is mostly functional but many of the old display options are a WIP. Revert to the old map with --old-map.
|
||||||
|
|||||||
@ -10,14 +10,13 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
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 Iterator, List, Optional, Set, TYPE_CHECKING, Tuple
|
from typing import Iterator, List, Optional, Set, TYPE_CHECKING, Tuple
|
||||||
|
|
||||||
from dcs.planes import E_3A, E_2C, A_50, KJ_2000
|
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
|
from dcs.planes import E_3A, E_2C, A_50, KJ_2000
|
||||||
from dcs.unit import Unit
|
from dcs.unit import Unit
|
||||||
from shapely.geometry import Point as ShapelyPoint
|
from shapely.geometry import Point as ShapelyPoint
|
||||||
|
|
||||||
@ -125,6 +124,10 @@ class FlightPlan:
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tot(self) -> timedelta:
|
||||||
|
return self.package.time_over_target + self.tot_offset
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def bingo_fuel(self) -> int:
|
def bingo_fuel(self) -> int:
|
||||||
"""Bingo fuel value for the FlightPlan"""
|
"""Bingo fuel value for the FlightPlan"""
|
||||||
@ -217,10 +220,9 @@ class FlightPlan:
|
|||||||
if tot_waypoint is None:
|
if tot_waypoint is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
time = self.tot_for_waypoint(tot_waypoint)
|
time = self.tot
|
||||||
if time is None:
|
if time is None:
|
||||||
return None
|
return None
|
||||||
time += self.tot_offset
|
|
||||||
return time - self._travel_time_to_waypoint(tot_waypoint)
|
return time - self._travel_time_to_waypoint(tot_waypoint)
|
||||||
|
|
||||||
def startup_time(self) -> Optional[timedelta]:
|
def startup_time(self) -> Optional[timedelta]:
|
||||||
@ -520,7 +522,7 @@ class TarCapFlightPlan(PatrollingFlightPlan):
|
|||||||
start = self.package.escort_start_time
|
start = self.package.escort_start_time
|
||||||
if start is not None:
|
if start is not None:
|
||||||
return start + self.tot_offset
|
return start + self.tot_offset
|
||||||
return super().patrol_start_time + self.tot_offset
|
return self.tot
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def patrol_end_time(self) -> timedelta:
|
def patrol_end_time(self) -> timedelta:
|
||||||
@ -544,6 +546,7 @@ class StrikeFlightPlan(FormationFlightPlan):
|
|||||||
land: FlightWaypoint
|
land: FlightWaypoint
|
||||||
divert: Optional[FlightWaypoint]
|
divert: Optional[FlightWaypoint]
|
||||||
bullseye: FlightWaypoint
|
bullseye: FlightWaypoint
|
||||||
|
lead_time: timedelta = field(default_factory=timedelta)
|
||||||
|
|
||||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||||
yield self.takeoff
|
yield self.takeoff
|
||||||
@ -582,6 +585,13 @@ class StrikeFlightPlan(FormationFlightPlan):
|
|||||||
def tot_waypoint(self) -> FlightWaypoint:
|
def tot_waypoint(self) -> FlightWaypoint:
|
||||||
return self.targets[0]
|
return self.targets[0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tot_offset(self) -> timedelta:
|
||||||
|
try:
|
||||||
|
return -self.lead_time
|
||||||
|
except AttributeError:
|
||||||
|
return timedelta()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def target_area_waypoint(self) -> FlightWaypoint:
|
def target_area_waypoint(self) -> FlightWaypoint:
|
||||||
return FlightWaypoint(
|
return FlightWaypoint(
|
||||||
@ -626,7 +636,7 @@ class StrikeFlightPlan(FormationFlightPlan):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def ingress_time(self) -> timedelta:
|
def ingress_time(self) -> timedelta:
|
||||||
tot = self.package.time_over_target
|
tot = self.tot
|
||||||
travel_time = self.travel_time_between_waypoints(
|
travel_time = self.travel_time_between_waypoints(
|
||||||
self.ingress, self.target_area_waypoint
|
self.ingress, self.target_area_waypoint
|
||||||
)
|
)
|
||||||
@ -634,7 +644,7 @@ class StrikeFlightPlan(FormationFlightPlan):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def egress_time(self) -> timedelta:
|
def egress_time(self) -> timedelta:
|
||||||
tot = self.package.time_over_target
|
tot = self.tot
|
||||||
travel_time = self.travel_time_between_waypoints(
|
travel_time = self.travel_time_between_waypoints(
|
||||||
self.target_area_waypoint, self.egress
|
self.target_area_waypoint, self.egress
|
||||||
)
|
)
|
||||||
@ -646,7 +656,7 @@ class StrikeFlightPlan(FormationFlightPlan):
|
|||||||
elif waypoint == self.egress:
|
elif waypoint == self.egress:
|
||||||
return self.egress_time
|
return self.egress_time
|
||||||
elif waypoint in self.targets:
|
elif waypoint in self.targets:
|
||||||
return self.package.time_over_target
|
return self.tot
|
||||||
return super().tot_for_waypoint(waypoint)
|
return super().tot_for_waypoint(waypoint)
|
||||||
|
|
||||||
|
|
||||||
@ -691,7 +701,7 @@ class SweepFlightPlan(LoiterFlightPlan):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def sweep_end_time(self) -> timedelta:
|
def sweep_end_time(self) -> timedelta:
|
||||||
return self.package.time_over_target + self.tot_offset
|
return self.tot
|
||||||
|
|
||||||
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> Optional[timedelta]:
|
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> Optional[timedelta]:
|
||||||
if waypoint == self.sweep_start:
|
if waypoint == self.sweep_start:
|
||||||
@ -1513,7 +1523,11 @@ class FlightPlanBuilder:
|
|||||||
targets.append(StrikeTarget(location.name, target))
|
targets.append(StrikeTarget(location.name, target))
|
||||||
|
|
||||||
return self.strike_flightplan(
|
return self.strike_flightplan(
|
||||||
flight, location, FlightWaypointType.INGRESS_SEAD, targets
|
flight,
|
||||||
|
location,
|
||||||
|
FlightWaypointType.INGRESS_SEAD,
|
||||||
|
targets,
|
||||||
|
lead_time=timedelta(minutes=1),
|
||||||
)
|
)
|
||||||
|
|
||||||
def generate_escort(self, flight: Flight) -> StrikeFlightPlan:
|
def generate_escort(self, flight: Flight) -> StrikeFlightPlan:
|
||||||
@ -1691,6 +1705,7 @@ class FlightPlanBuilder:
|
|||||||
location: MissionTarget,
|
location: MissionTarget,
|
||||||
ingress_type: FlightWaypointType,
|
ingress_type: FlightWaypointType,
|
||||||
targets: Optional[List[StrikeTarget]] = None,
|
targets: Optional[List[StrikeTarget]] = None,
|
||||||
|
lead_time: timedelta = timedelta(),
|
||||||
) -> StrikeFlightPlan:
|
) -> StrikeFlightPlan:
|
||||||
assert self.package.waypoints is not None
|
assert self.package.waypoints is not None
|
||||||
builder = WaypointBuilder(flight, self.game, self.is_player, targets)
|
builder = WaypointBuilder(flight, self.game, self.is_player, targets)
|
||||||
@ -1730,6 +1745,7 @@ class FlightPlanBuilder:
|
|||||||
land=builder.land(flight.arrival),
|
land=builder.land(flight.arrival),
|
||||||
divert=builder.divert(flight.divert),
|
divert=builder.divert(flight.divert),
|
||||||
bullseye=builder.bullseye(),
|
bullseye=builder.bullseye(),
|
||||||
|
lead_time=lead_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _retreating_rendezvous_point(self, attack_transition: Point) -> Point:
|
def _retreating_rendezvous_point(self, attack_transition: Point) -> Point:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user