Improve AI SEAD capabilities

This commit is contained in:
Raffson 2023-04-15 20:44:57 +02:00
parent bf23ee4e8f
commit fad48ebaed
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
4 changed files with 48 additions and 8 deletions

View File

@ -6,6 +6,7 @@
* **[Options]** Ability to load & save your settings. * **[Options]** Ability to load & save your settings.
* **[UI]** Added fuel selector in flight's edit window. * **[UI]** Added fuel selector in flight's edit window.
* **[Plugins]** Expose Splash Damage's "game_messages" option and set its default to false. * **[Plugins]** Expose Splash Damage's "game_messages" option and set its default to false.
* **[Mission Generation]** Improved AI SEAD capabilities, allowing for mixed loadouts using Decoys, ARMs & ASMs.
## Fixes ## Fixes
* **[New Game Wizard]** Settings would not persist when going back to a previous page. * **[New Game Wizard]** Settings would not persist when going back to a previous page.

View File

@ -190,6 +190,10 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
ingress_type, self.package.waypoints.ingress, self.package.target ingress_type, self.package.waypoints.ingress, self.package.target
) )
initial = None
if ingress_type == FlightWaypointType.INGRESS_SEAD:
initial = builder.sead_search(self.package.target)
return FormationAttackLayout( return FormationAttackLayout(
departure=builder.takeoff(self.flight.departure), departure=builder.takeoff(self.flight.departure),
hold=hold, hold=hold,
@ -198,6 +202,7 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC):
), ),
join=join, join=join,
ingress=ingress, ingress=ingress,
initial=initial,
targets=target_waypoints, targets=target_waypoints,
split=split, split=split,
refuel=refuel, refuel=refuel,

View File

@ -290,12 +290,9 @@ class WaypointBuilder:
return self._target_area(f"STRIKE {target.name}", target) return self._target_area(f"STRIKE {target.name}", target)
def sead_area(self, target: MissionTarget) -> FlightWaypoint: def sead_area(self, target: MissionTarget) -> FlightWaypoint:
# Set flyover with ingress altitude to allow the flight to search and engage
# the target group at the ingress alt without suicide dive
return self._target_area( return self._target_area(
f"SEAD on {target.name}", f"SEAD on {target.name}",
target, target,
flyover=True,
altitude=self.doctrine.ingress_altitude, altitude=self.doctrine.ingress_altitude,
alt_type="BARO", alt_type="BARO",
) )
@ -316,8 +313,8 @@ class WaypointBuilder:
# plan. # plan.
return self._target_area(f"ASSAULT {target.name}", target) return self._target_area(f"ASSAULT {target.name}", target)
@staticmethod
def _target_area( def _target_area(
self,
name: str, name: str,
location: MissionTarget, location: MissionTarget,
flyover: bool = False, flyover: bool = False,
@ -425,6 +422,29 @@ class WaypointBuilder:
pretty_name="Orbit", pretty_name="Orbit",
) )
def sead_search(self, target: MissionTarget) -> FlightWaypoint:
"""Creates custom waypoint for AI SEAD flights
to avoid having them fly all the way to the SAM site.
Args:
target: Target information.
"""
# Use the threat range as offset distance to avoid flying all the way to the SAM site
assert self.flight.package.waypoints
ingress = self.flight.package.waypoints.ingress
threat_range = 1.1 * max([x.threat_range for x in target.strike_targets]).meters
hdg = target.position.heading_between_point(ingress)
hold = target.position.point_from_heading(hdg, threat_range)
return FlightWaypoint(
"SEAD Search",
FlightWaypointType.CUSTOM,
hold,
self.doctrine.ingress_altitude,
alt_type="BARO",
description="Anchor and search from this point",
pretty_name="SEAD Search",
)
@staticmethod @staticmethod
def escort_hold(start: Point, altitude: Distance) -> FlightWaypoint: def escort_hold(start: Point, altitude: Distance) -> FlightWaypoint:
"""Creates custom waypoint for escort flights that need to hold. """Creates custom waypoint for escort flights that need to hold.

View File

@ -7,6 +7,7 @@ from dcs.task import (
Expend, Expend,
OptECMUsing, OptECMUsing,
WeaponType as DcsWeaponType, WeaponType as DcsWeaponType,
OptRestrictAfterburner,
) )
from game.data.weapons import WeaponType from game.data.weapons import WeaponType
@ -29,6 +30,11 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
# Preemptively use ECM to better avoid getting swatted. # Preemptively use ECM to better avoid getting swatted.
ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfDetectedLockByRadar) ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfDetectedLockByRadar)
waypoint.tasks.append(ecm_option) waypoint.tasks.append(ecm_option)
# Avoid having AI burn all of its fuel while loitering until next weapon release
burn_restrict = OptRestrictAfterburner(True)
waypoint.tasks.append(burn_restrict)
for group in target.groups: for group in target.groups:
miz_group = self.mission.find_group(group.group_name) miz_group = self.mission.find_group(group.group_name)
if miz_group is None: if miz_group is None:
@ -43,7 +49,7 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
weapon_type=DcsWeaponType.Decoy, weapon_type=DcsWeaponType.Decoy,
group_attack=True, group_attack=True,
expend=Expend.All, expend=Expend.All,
altitude=waypoint.alt, altitude=round(waypoint.alt * 1.5), # 50% increase to force a climb
) )
waypoint.tasks.append(attack_task) waypoint.tasks.append(attack_task)
@ -54,8 +60,16 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
# when skynet is enabled and the Radar is not emitting. They dive # when skynet is enabled and the Radar is not emitting. They dive
# into the SAM instead of waiting for it to come alive # into the SAM instead of waiting for it to come alive
engage_task = EngageGroup(miz_group.id) engage_task = EngageGroup(miz_group.id)
engage_task.params["weaponType"] = DcsWeaponType.Guided.value engage_task.params["weaponType"] = DcsWeaponType.ARM.value
engage_task.params["groupAttack"] = True
engage_task.params["expend"] = Expend.All.value
waypoint.tasks.append(engage_task) waypoint.tasks.append(engage_task)
# Use other Air-to-Surface Missiles at last
attack_task = AttackGroup(
miz_group.id,
weapon_type=DcsWeaponType.ASM,
altitude=waypoint.alt, # flight loses alt with AB restriction
)
waypoint.tasks.append(attack_task)
burn_free = OptRestrictAfterburner(False)
waypoint.tasks.append(burn_free)