Improve STRIKE where possible

- Plan number of aircraft more accurately
- Fine-tuning ingress waypoint tasks
- Add lineup waypoint for STRIKE flights, 10NM in front of ingress on the same heading as the target
This commit is contained in:
Raffson 2023-07-15 22:25:56 +02:00
parent 092ef88cab
commit 9d63bcbf69
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
4 changed files with 22 additions and 6 deletions

View File

@ -10,7 +10,7 @@ from dcs import Point
from game.flightplan import HoldZoneGeometry from game.flightplan import HoldZoneGeometry
from game.theater import MissionTarget from game.theater import MissionTarget
from game.utils import Speed, meters from game.utils import Speed, meters, nautical_miles
from .flightplan import FlightPlan from .flightplan import FlightPlan
from .formation import FormationFlightPlan, FormationLayout from .formation import FormationFlightPlan, FormationLayout
from .ibuilder import IBuilder from .ibuilder import IBuilder
@ -134,6 +134,7 @@ class FormationAttackLayout(FormationLayout):
ingress: FlightWaypoint ingress: FlightWaypoint
targets: list[FlightWaypoint] targets: list[FlightWaypoint]
initial: Optional[FlightWaypoint] = None initial: Optional[FlightWaypoint] = None
lineup: Optional[FlightWaypoint] = None
def iter_waypoints(self) -> Iterator[FlightWaypoint]: def iter_waypoints(self) -> Iterator[FlightWaypoint]:
yield self.departure yield self.departure
@ -142,6 +143,8 @@ class FormationAttackLayout(FormationLayout):
yield from self.nav_to yield from self.nav_to
if self.join: if self.join:
yield self.join yield self.join
if self.lineup:
yield self.lineup
yield self.ingress yield self.ingress
if self.initial is not None: if self.initial is not None:
yield self.initial yield self.initial
@ -206,6 +209,12 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
elif ingress_type == FlightWaypointType.INGRESS_SEAD_SWEEP: elif ingress_type == FlightWaypointType.INGRESS_SEAD_SWEEP:
initial = builder.sead_sweep(self.package.target) initial = builder.sead_sweep(self.package.target)
lineup = None
if self.flight.flight_type == FlightType.STRIKE:
hdg = self.package.target.position.heading_between_point(ingress.position)
pos = ingress.position.point_from_heading(hdg, nautical_miles(10).meters)
lineup = builder.nav(pos, self.flight.coalition.doctrine.ingress_altitude)
return FormationAttackLayout( return FormationAttackLayout(
departure=builder.takeoff(self.flight.departure), departure=builder.takeoff(self.flight.departure),
hold=hold, hold=hold,
@ -215,6 +224,7 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
self.doctrine.ingress_altitude, self.doctrine.ingress_altitude,
), ),
join=join, join=join,
lineup=lineup,
ingress=ingress, ingress=ingress,
initial=initial, initial=initial,
targets=target_waypoints, targets=target_waypoints,

View File

@ -22,7 +22,7 @@ class PlanStrike(PackagePlanningTask[TheaterGroundObject]):
def propose_flights(self) -> None: def propose_flights(self) -> None:
tgt_count = self.target.alive_unit_count tgt_count = self.target.alive_unit_count
self.propose_flight(FlightType.STRIKE, min(4, (tgt_count // 2) + 1)) self.propose_flight(FlightType.STRIKE, min(4, (tgt_count // 2) + tgt_count % 2))
self.propose_common_escorts() self.propose_common_escorts()
if self.target.coalition.game.settings.autoplan_tankers_for_strike: if self.target.coalition.game.settings.autoplan_tankers_for_strike:
self.propose_flight(FlightType.REFUELING, 1) self.propose_flight(FlightType.REFUELING, 1)

View File

@ -16,7 +16,11 @@ class StrikeIngressBuilder(PydcsWaypointBuilder):
bomber_guided = self.group.units[0].unit_type in [B_1B, B_52H] bomber_guided = self.group.units[0].unit_type in [B_1B, B_52H]
waypoint.tasks.append(OptFormation.finger_four_open()) waypoint.tasks.append(OptFormation.finger_four_open())
if bomber_guided or not bomber: if bomber_guided or not bomber:
self.add_strike_tasks(waypoint, WeaponType.Guided) self.add_strike_tasks(waypoint, WeaponType.ASM)
waypoint.tasks.append(OptFormation.trail_open())
if bomber_guided or not bomber:
self.add_strike_tasks(waypoint, WeaponType.GuidedBombs)
waypoint.tasks.append(OptFormation.ww2_bomber_element_close()) waypoint.tasks.append(OptFormation.ww2_bomber_element_close())
self.add_bombing_tasks(waypoint) self.add_bombing_tasks(waypoint)
@ -49,6 +53,7 @@ class StrikeIngressBuilder(PydcsWaypointBuilder):
center, center,
weapon_type=WeaponType.Bombs, weapon_type=WeaponType.Bombs,
expend=Expend.All, expend=Expend.All,
group_attack=True,
altitude=waypoint.alt, altitude=waypoint.alt,
) )
waypoint.tasks.append(bombing) waypoint.tasks.append(bombing)
@ -56,12 +61,13 @@ class StrikeIngressBuilder(PydcsWaypointBuilder):
def add_strike_tasks( def add_strike_tasks(
self, waypoint: MovingPoint, weapon_type: WeaponType = WeaponType.Auto self, waypoint: MovingPoint, weapon_type: WeaponType = WeaponType.Auto
) -> None: ) -> None:
ga = True if self.flight.count > 1 else False
for target in self.waypoint.targets: for target in self.waypoint.targets:
bombing = Bombing(target.position, weapon_type=weapon_type, group_attack=ga) bombing = Bombing(target.position, weapon_type=weapon_type)
# If there is only one target, drop all ordnance in one pass. # If there is only one target, drop all ordnance in one pass.
if len(self.waypoint.targets) == 1: if len(self.waypoint.targets) == 1:
bombing.params["expend"] = Expend.All.value bombing.params["expend"] = Expend.All.value
elif target.is_static:
bombing.params["expend"] = Expend.Half.value
waypoint.tasks.append(bombing) waypoint.tasks.append(bombing)
waypoint.speed = mach(0.85, meters(waypoint.alt)).meters_per_second waypoint.speed = mach(0.85, meters(waypoint.alt)).meters_per_second

View File

@ -84,7 +84,7 @@ class TheaterUnit:
@property @property
def is_static(self) -> bool: def is_static(self) -> bool:
return issubclass(self.type, StaticType) return issubclass(self.type, StaticType) or isinstance(self, SceneryUnit)
@property @property
def is_vehicle(self) -> bool: def is_vehicle(self) -> bool: