diff --git a/changelog.md b/changelog.md index 3042b757..8a568560 100644 --- a/changelog.md +++ b/changelog.md @@ -30,6 +30,7 @@ * **[COMMs]** Ability to set a specific callsign to a flight. * **[Mission Generator]** Channel terrain fix on exclusion zones, sea zones and inclusion zones * **[Options]** Cheat-option for accessing Air Wing Config Dialog after campaign start +* **[Options]** Option to enable unlimited fuel for AI (player and non-player flights) ## Fixes * **[Mission Generation]** Anti-ship strikes should use "group attack" in their attack-task diff --git a/game/missiongenerator/aircraft/aircraftbehavior.py b/game/missiongenerator/aircraft/aircraftbehavior.py index 73e12e56..3bc5c6cb 100644 --- a/game/missiongenerator/aircraft/aircraftbehavior.py +++ b/game/missiongenerator/aircraft/aircraftbehavior.py @@ -26,6 +26,7 @@ from dcs.task import ( MainTask, PinpointStrike, AFAC, + SetUnlimitedFuelCommand, ) from dcs.unitgroup import FlyingGroup @@ -93,8 +94,18 @@ class AircraftBehavior: restrict_jettison: Optional[bool] = None, mission_uses_gun: bool = True, rtb_on_bingo: bool = True, + ai_unlimited_fuel: Optional[bool] = None, ) -> None: group.points[0].tasks.clear() + if ai_unlimited_fuel is None: + ai_unlimited_fuel = ( + flight.squadron.coalition.game.settings.ai_unlimited_fuel + ) + + # Activate AI unlimited fuel for all flights at startup + if ai_unlimited_fuel: + group.points[0].tasks.append(SetUnlimitedFuelCommand(True)) + group.points[0].tasks.append(OptReactOnThreat(react_on_threat)) if roe is not None: group.points[0].tasks.append(OptROE(roe)) diff --git a/game/missiongenerator/aircraft/waypoints/joinpoint.py b/game/missiongenerator/aircraft/waypoints/joinpoint.py index fa7b04e1..18a78568 100644 --- a/game/missiongenerator/aircraft/waypoints/joinpoint.py +++ b/game/missiongenerator/aircraft/waypoints/joinpoint.py @@ -9,16 +9,22 @@ from dcs.task import ( OptFormation, Targets, OptROE, + SetUnlimitedFuelCommand, ) from game.ato import FlightType from game.theater import NavalControlPoint from game.utils import nautical_miles, feet +from game.settings import Settings from .pydcswaypointbuilder import PydcsWaypointBuilder class JoinPointBuilder(PydcsWaypointBuilder): def add_tasks(self, waypoint: MovingPoint) -> None: + # Unlimited fuel option : disable at join. Must be first option to work. + if self.flight.squadron.coalition.game.settings.ai_unlimited_fuel: + waypoint.tasks.insert(0, SetUnlimitedFuelCommand(False)) + if self.flight.is_helo: waypoint.tasks.append(OptFormation.rotary_wedge()) else: diff --git a/game/missiongenerator/aircraft/waypoints/racetrack.py b/game/missiongenerator/aircraft/waypoints/racetrack.py index ef9237d4..62f52dd5 100644 --- a/game/missiongenerator/aircraft/waypoints/racetrack.py +++ b/game/missiongenerator/aircraft/waypoints/racetrack.py @@ -8,6 +8,7 @@ from dcs.task import ( OrbitAction, Tanker, Targets, + SetUnlimitedFuelCommand, ) from game.ato import FlightType @@ -20,6 +21,10 @@ class RaceTrackBuilder(PydcsWaypointBuilder): def add_tasks(self, waypoint: MovingPoint) -> None: flight_plan = self.flight.flight_plan + # Unlimited fuel option : disable at racetrack start. Must be first option to work. + if self.flight.squadron.coalition.game.settings.ai_unlimited_fuel: + waypoint.tasks.insert(0, SetUnlimitedFuelCommand(False)) + if not isinstance(flight_plan, PatrollingFlightPlan): flight_plan_type = flight_plan.__class__.__name__ logging.error( diff --git a/game/missiongenerator/aircraft/waypoints/racetrackend.py b/game/missiongenerator/aircraft/waypoints/racetrackend.py index c1744445..5a14d345 100644 --- a/game/missiongenerator/aircraft/waypoints/racetrackend.py +++ b/game/missiongenerator/aircraft/waypoints/racetrackend.py @@ -1,12 +1,20 @@ import logging from dcs.point import MovingPoint +from dcs.task import SetUnlimitedFuelCommand from game.ato.flightplans.patrolling import PatrollingFlightPlan from .pydcswaypointbuilder import PydcsWaypointBuilder class RaceTrackEndBuilder(PydcsWaypointBuilder): + def add_tasks(self, waypoint: MovingPoint) -> None: + flight_plan = self.flight.flight_plan + + # Unlimited fuel option : enable at racetrack end. Must be first option to work. + if self.flight.squadron.coalition.game.settings.ai_unlimited_fuel: + waypoint.tasks.insert(0, SetUnlimitedFuelCommand(True)) + def build(self) -> MovingPoint: waypoint = super().build() diff --git a/game/missiongenerator/aircraft/waypoints/splitpoint.py b/game/missiongenerator/aircraft/waypoints/splitpoint.py index 2bcb9bd1..334a85fc 100644 --- a/game/missiongenerator/aircraft/waypoints/splitpoint.py +++ b/game/missiongenerator/aircraft/waypoints/splitpoint.py @@ -1,11 +1,17 @@ from dcs.point import MovingPoint -from dcs.task import OptECMUsing, OptFormation, RunScript +from dcs.task import OptECMUsing, OptFormation, RunScript, SetUnlimitedFuelCommand + +from game.settings import Settings from .pydcswaypointbuilder import PydcsWaypointBuilder class SplitPointBuilder(PydcsWaypointBuilder): def add_tasks(self, waypoint: MovingPoint) -> None: + # Unlimited fuel option : enable at split. Must be first option to work. + if self.flight.squadron.coalition.game.settings.ai_unlimited_fuel: + waypoint.tasks.insert(0, SetUnlimitedFuelCommand(True)) + if 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, diff --git a/game/settings/settings.py b/game/settings/settings.py index 6193b188..bc57d99c 100644 --- a/game/settings/settings.py +++ b/game/settings/settings.py @@ -822,6 +822,16 @@ class Settings: ), ) + ai_unlimited_fuel: bool = boolean_option( + "AI flights have unlimited fuel", + MISSION_GENERATOR_PAGE, + GAMEPLAY_SECTION, + default=True, + detail=( + "AI aircraft have unlimited fuel applied at start, removed at join/racetrack start, and reapplied at split/racetrack end for applicable flights. " + ), + ) + # Performance perf_smoke_gen: bool = boolean_option( "Smoke visual effect on the front line",