diff --git a/game/ato/flightplans/formationattack.py b/game/ato/flightplans/formationattack.py index 7ca77236..8af05c1f 100644 --- a/game/ato/flightplans/formationattack.py +++ b/game/ato/flightplans/formationattack.py @@ -10,7 +10,7 @@ from dcs import Point from game.flightplan import HoldZoneGeometry from game.theater import MissionTarget -from game.utils import Speed, meters +from game.utils import Speed, meters, nautical_miles from .flightplan import FlightPlan from .formation import FormationFlightPlan, FormationLayout from .ibuilder import IBuilder @@ -134,6 +134,7 @@ class FormationAttackLayout(FormationLayout): ingress: FlightWaypoint targets: list[FlightWaypoint] initial: Optional[FlightWaypoint] = None + lineup: Optional[FlightWaypoint] = None def iter_waypoints(self) -> Iterator[FlightWaypoint]: yield self.departure @@ -142,6 +143,8 @@ class FormationAttackLayout(FormationLayout): yield from self.nav_to if self.join: yield self.join + if self.lineup: + yield self.lineup yield self.ingress if self.initial is not None: yield self.initial @@ -206,6 +209,12 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC): elif ingress_type == FlightWaypointType.INGRESS_SEAD_SWEEP: 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( departure=builder.takeoff(self.flight.departure), hold=hold, @@ -215,6 +224,7 @@ class FormationAttackBuilder(IBuilder[FlightPlanT, LayoutT], ABC): self.doctrine.ingress_altitude, ), join=join, + lineup=lineup, ingress=ingress, initial=initial, targets=target_waypoints, diff --git a/game/commander/tasks/primitive/strike.py b/game/commander/tasks/primitive/strike.py index cb537634..d38260d5 100644 --- a/game/commander/tasks/primitive/strike.py +++ b/game/commander/tasks/primitive/strike.py @@ -22,7 +22,7 @@ class PlanStrike(PackagePlanningTask[TheaterGroundObject]): def propose_flights(self) -> None: 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() if self.target.coalition.game.settings.autoplan_tankers_for_strike: self.propose_flight(FlightType.REFUELING, 1) diff --git a/game/missiongenerator/aircraft/waypoints/strikeingress.py b/game/missiongenerator/aircraft/waypoints/strikeingress.py index da73d0ee..0f9f5ab8 100644 --- a/game/missiongenerator/aircraft/waypoints/strikeingress.py +++ b/game/missiongenerator/aircraft/waypoints/strikeingress.py @@ -16,7 +16,11 @@ class StrikeIngressBuilder(PydcsWaypointBuilder): bomber_guided = self.group.units[0].unit_type in [B_1B, B_52H] waypoint.tasks.append(OptFormation.finger_four_open()) 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()) self.add_bombing_tasks(waypoint) @@ -49,6 +53,7 @@ class StrikeIngressBuilder(PydcsWaypointBuilder): center, weapon_type=WeaponType.Bombs, expend=Expend.All, + group_attack=True, altitude=waypoint.alt, ) waypoint.tasks.append(bombing) @@ -56,12 +61,13 @@ class StrikeIngressBuilder(PydcsWaypointBuilder): def add_strike_tasks( self, waypoint: MovingPoint, weapon_type: WeaponType = WeaponType.Auto ) -> None: - ga = True if self.flight.count > 1 else False 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 len(self.waypoint.targets) == 1: bombing.params["expend"] = Expend.All.value + elif target.is_static: + bombing.params["expend"] = Expend.Half.value waypoint.tasks.append(bombing) waypoint.speed = mach(0.85, meters(waypoint.alt)).meters_per_second diff --git a/game/theater/theatergroup.py b/game/theater/theatergroup.py index ddffe4bc..535fc99c 100644 --- a/game/theater/theatergroup.py +++ b/game/theater/theatergroup.py @@ -84,7 +84,7 @@ class TheaterUnit: @property def is_static(self) -> bool: - return issubclass(self.type, StaticType) + return issubclass(self.type, StaticType) or isinstance(self, SceneryUnit) @property def is_vehicle(self) -> bool: