diff --git a/changelog.md b/changelog.md index f8cc9747..7d386723 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,7 @@ Saves from 5.x are not compatible with 6.0. * **[Campaign]** Add option to manually add and remove squadrons and different aircraft type in the new game wizard / air wing configuration dialog. * **[Mission Generation]** Added an option to fast-forward mission generation until the point of first contact (WIP). * **[Mission Generation]** Add Option to enforce the Easy Communication setting for the mission +* **[Flight Planning]** Added preset formations for different flight types at hold, join, ingress, and split waypoints. Air to Air flights will tend toward line-abreast and spread-four formations. Air to ground flights will tend towards trail formation. * **[Flight Planning]** Added the ability to plan tankers for recovery on package flights. AI does not plan. * **[Flight Planning]** Air to Ground flights now have ECM enabled on lock at the join point, and SEAD/DEAD also have ECM enabled on detection and lock at ingress. * **[Flight Planning]** AWACS flightplan changed from orbit to a racetrack to reduce data link disconnects which were caused by blind spots as a result of the bank angle. diff --git a/game/missiongenerator/aircraft/waypoints/baiingress.py b/game/missiongenerator/aircraft/waypoints/baiingress.py index e4c8273c..b757b651 100644 --- a/game/missiongenerator/aircraft/waypoints/baiingress.py +++ b/game/missiongenerator/aircraft/waypoints/baiingress.py @@ -1,7 +1,7 @@ import logging from dcs.point import MovingPoint -from dcs.task import AttackGroup, WeaponType +from dcs.task import AttackGroup, OptFormation, WeaponType from game.theater import NavalControlPoint, TheaterGroundObject from game.transfers import MultiGroupTransport @@ -39,3 +39,5 @@ class BaiIngressBuilder(PydcsWaypointBuilder): task.params["altitudeEnabled"] = False task.params["groupAttack"] = True waypoint.tasks.append(task) + + waypoint.tasks.append(OptFormation.trail_open()) diff --git a/game/missiongenerator/aircraft/waypoints/holdpoint.py b/game/missiongenerator/aircraft/waypoints/holdpoint.py index 2046a78f..bb566a05 100644 --- a/game/missiongenerator/aircraft/waypoints/holdpoint.py +++ b/game/missiongenerator/aircraft/waypoints/holdpoint.py @@ -1,7 +1,7 @@ import logging from dcs.point import MovingPoint -from dcs.task import ControlledTask, OrbitAction +from dcs.task import ControlledTask, OptFormation, OrbitAction from gen.flights.flightplan import LoiterFlightPlan from .pydcswaypointbuilder import PydcsWaypointBuilder @@ -26,3 +26,4 @@ class HoldPointBuilder(PydcsWaypointBuilder): int((push_time - self.elapsed_mission_time).total_seconds()) ) waypoint.add_task(loiter) + waypoint.add_task(OptFormation.finger_four_close()) diff --git a/game/missiongenerator/aircraft/waypoints/joinpoint.py b/game/missiongenerator/aircraft/waypoints/joinpoint.py index 7e7ebb8a..59fe56ab 100644 --- a/game/missiongenerator/aircraft/waypoints/joinpoint.py +++ b/game/missiongenerator/aircraft/waypoints/joinpoint.py @@ -1,7 +1,14 @@ from typing import List, Type from dcs.point import MovingPoint -from dcs.task import ControlledTask, EngageTargets, OptECMUsing, TargetType, Targets +from dcs.task import ( + ControlledTask, + EngageTargets, + OptECMUsing, + OptFormation, + TargetType, + Targets, +) from game.ato import FlightType from game.utils import nautical_miles @@ -19,6 +26,11 @@ class JoinPointBuilder(PydcsWaypointBuilder): ], ) + if self.flight.count < 4: + waypoint.tasks.append(OptFormation.line_abreast_open()) + else: + waypoint.tasks.append(OptFormation.spread_four_open()) + elif self.flight.flight_type == FlightType.SEAD_ESCORT: self.configure_escort_tasks( waypoint, [Targets.All.GroundUnits.AirDefence.AAA.SAMRelated] @@ -28,6 +40,11 @@ class JoinPointBuilder(PydcsWaypointBuilder): ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfDetectedLockByRadar) waypoint.tasks.append(ecm_option) + if self.flight.count < 4: + waypoint.tasks.append(OptFormation.line_abreast_open()) + else: + waypoint.tasks.append(OptFormation.spread_four_open()) + elif not self.flight.flight_type.is_air_to_air: # Capture any non A/A type to avoid issues with SPJs that use the primary radar such as the F/A-18C. # You can bully them with STT to not be able to fire radar guided missiles at you, @@ -37,6 +54,8 @@ class JoinPointBuilder(PydcsWaypointBuilder): ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfOnlyLockByRadar) waypoint.tasks.append(ecm_option) + waypoint.tasks.append(OptFormation.finger_four_open()) + @staticmethod def configure_escort_tasks( waypoint: MovingPoint, target_types: List[Type[TargetType]] diff --git a/game/missiongenerator/aircraft/waypoints/ocarunwayingress.py b/game/missiongenerator/aircraft/waypoints/ocarunwayingress.py index c7416c00..204de148 100644 --- a/game/missiongenerator/aircraft/waypoints/ocarunwayingress.py +++ b/game/missiongenerator/aircraft/waypoints/ocarunwayingress.py @@ -1,7 +1,7 @@ import logging from dcs.point import MovingPoint -from dcs.task import BombingRunway +from dcs.task import BombingRunway, OptFormation from game.theater import Airfield from .pydcswaypointbuilder import PydcsWaypointBuilder @@ -20,3 +20,4 @@ class OcaRunwayIngressBuilder(PydcsWaypointBuilder): waypoint.tasks.append( BombingRunway(airport_id=target.airport.id, group_attack=True) ) + waypoint.tasks.append(OptFormation.trail_open()) diff --git a/game/missiongenerator/aircraft/waypoints/splitpoint.py b/game/missiongenerator/aircraft/waypoints/splitpoint.py index 1ec079d3..82e06558 100644 --- a/game/missiongenerator/aircraft/waypoints/splitpoint.py +++ b/game/missiongenerator/aircraft/waypoints/splitpoint.py @@ -1,5 +1,5 @@ from dcs.point import MovingPoint -from dcs.task import OptECMUsing +from dcs.task import OptECMUsing, OptFormation from .pydcswaypointbuilder import PydcsWaypointBuilder @@ -15,3 +15,5 @@ class SplitPointBuilder(PydcsWaypointBuilder): # Let the AI use ECM to defend themselves. ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfOnlyLockByRadar) waypoint.tasks.append(ecm_option) + + waypoint.tasks.append(OptFormation.finger_four_close()) diff --git a/game/missiongenerator/aircraft/waypoints/strikeingress.py b/game/missiongenerator/aircraft/waypoints/strikeingress.py index fbc19ca5..ff5dd95b 100644 --- a/game/missiongenerator/aircraft/waypoints/strikeingress.py +++ b/game/missiongenerator/aircraft/waypoints/strikeingress.py @@ -1,7 +1,7 @@ from dcs import Point from dcs.planes import B_17G, B_52H, Tu_22M3 from dcs.point import MovingPoint -from dcs.task import Bombing, WeaponType +from dcs.task import Bombing, OptFormation, WeaponType from .pydcswaypointbuilder import PydcsWaypointBuilder @@ -13,6 +13,8 @@ class StrikeIngressBuilder(PydcsWaypointBuilder): else: self.add_strike_tasks(waypoint) + waypoint.tasks.append(OptFormation.trail_open()) + def add_bombing_tasks(self, waypoint: MovingPoint) -> None: targets = self.waypoint.targets if not targets: diff --git a/game/missiongenerator/aircraft/waypoints/sweepingress.py b/game/missiongenerator/aircraft/waypoints/sweepingress.py index 5b0d632e..bf6af578 100644 --- a/game/missiongenerator/aircraft/waypoints/sweepingress.py +++ b/game/missiongenerator/aircraft/waypoints/sweepingress.py @@ -1,7 +1,7 @@ import logging from dcs.point import MovingPoint -from dcs.task import EngageTargets, Targets +from dcs.task import EngageTargets, OptFormation, Targets from game.utils import nautical_miles from gen.flights.flightplan import SweepFlightPlan @@ -27,3 +27,8 @@ class SweepIngressBuilder(PydcsWaypointBuilder): ], ) ) + + if self.flight.count < 4: + waypoint.tasks.append(OptFormation.line_abreast_open()) + else: + waypoint.tasks.append(OptFormation.spread_four_open()) diff --git a/requirements.txt b/requirements.txt index df583698..6b57d361 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,7 +26,7 @@ Pillow==9.0.0 pluggy==0.13.1 pre-commit==2.10.1 py==1.10.0 --e git+https://github.com/pydcs/dcs@5d1f581b260fdc6091744ab927a58cdee586e681#egg=pydcs +-e git+https://github.com/pydcs/dcs@5a2abc26f79772837d445c28d6354accd3b76122#egg=pydcs pyinstaller==4.3 pyinstaller-hooks-contrib==2021.1 pyparsing==2.4.7