mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Empty gun for AI missions that do not need a gun.
There is no "all but gun" RTB winchester option, so air to ground missions with mixed weapon types will insist on using all of their bullets after running out of missiles and bombs. Take away their bullets so they don't strafe a Tor. Exceptions are made for player flights and for airframes where the gun is essential like the A-10 or warbirds.
This commit is contained in:
parent
a789f58068
commit
69299d395c
@ -14,6 +14,7 @@ Saves from 2.5 are not compatible with 3.0.
|
||||
* **[Flight Planner]** AI strike flight plans now include the correct target actions for building groups.
|
||||
* **[Flight Planner]** Flight plans now include bullseye waypoints.
|
||||
* **[Flight Planner]** Differentiated SEAD and SEAD escort. SEAD is tasked with suppressing the package target, SEAD escort is tasked with protecting the package from all SAMs along its route.
|
||||
* **[Payloads]** AI flights for most air to ground mission types (CAS excluded) will have their guns emptied to prevent strafing fully armed and operational battle stations. Gun-reliant airframes like A-10s and warbirds will keep their bullets.
|
||||
* **[Kneeboard]** ATC table overflow alleviated by wrapping long airfield names and splitting ATC frequency and channel into separate rows.
|
||||
* **[UI]** Added new web based map UI. This is mostly functional but many of the old display options are a WIP. Revert to the old map with --old-map.
|
||||
* **[UI]** Campaigns generated for an older or newer version of the game will now be marked as incompatible. They can still be played, but bugs may be present.
|
||||
|
||||
36
game/db.py
36
game/db.py
@ -1603,3 +1603,39 @@ F_16C_50.Liveries = DefaultLiveries
|
||||
P_51D_30_NA.Liveries = DefaultLiveries
|
||||
Ju_88A4.Liveries = DefaultLiveries
|
||||
B_17G.Liveries = DefaultLiveries
|
||||
|
||||
# List of airframes that rely on their gun as a primary weapon. We confiscate bullets
|
||||
# from most AI air-to-ground missions since they aren't smart enough to RTB when they're
|
||||
# out of everything other than bullets (DCS does not have an all-but-gun winchester
|
||||
# option) and we don't want to be attacking fully functional Tors with a Vulcan.
|
||||
#
|
||||
# These airframes are the exceptions. They probably should be using their gun regardless
|
||||
# of the mission type.
|
||||
GUN_RELIANT_AIRFRAMES: List[Type[FlyingType]] = [
|
||||
AH_1W,
|
||||
AH_64A,
|
||||
AH_64D,
|
||||
A_10A,
|
||||
A_10C,
|
||||
A_10C_2,
|
||||
A_20G,
|
||||
Bf_109K_4,
|
||||
FW_190A8,
|
||||
FW_190D9,
|
||||
F_86F_Sabre,
|
||||
Ju_88A4,
|
||||
Ka_50,
|
||||
MiG_15bis,
|
||||
MiG_19P,
|
||||
Mi_24V,
|
||||
Mi_28N,
|
||||
P_47D_30,
|
||||
P_47D_30bl1,
|
||||
P_47D_40,
|
||||
P_51D,
|
||||
P_51D_30_NA,
|
||||
SpitfireLFMkIX,
|
||||
SpitfireLFMkIXCW,
|
||||
Su_25,
|
||||
Su_25T,
|
||||
]
|
||||
|
||||
@ -62,7 +62,6 @@ from dcs.task import (
|
||||
OptRestrictJettison,
|
||||
OrbitAction,
|
||||
RunwayAttack,
|
||||
SEAD,
|
||||
StartCommand,
|
||||
Targets,
|
||||
Transport,
|
||||
@ -78,6 +77,7 @@ from dcs.unittype import FlyingType, UnitType
|
||||
from game import db
|
||||
from game.data.cap_capabilities_db import GUNFIGHTERS
|
||||
from game.data.weapons import Pylon
|
||||
from game.db import GUN_RELIANT_AIRFRAMES
|
||||
from game.factions.faction import Faction
|
||||
from game.settings import Settings
|
||||
from game.theater.controlpoint import (
|
||||
@ -1155,12 +1155,23 @@ class AircraftConflictGenerator:
|
||||
raise RuntimeError(f"No reduced fuel case for type {unit_type}")
|
||||
|
||||
@staticmethod
|
||||
def flight_always_keeps_gun(flight: Flight) -> bool:
|
||||
# Never take bullets from players. They're smart enough to know when to use it
|
||||
# and when to RTB.
|
||||
if flight.client_count > 0:
|
||||
return True
|
||||
|
||||
return flight.unit_type in GUN_RELIANT_AIRFRAMES
|
||||
|
||||
def configure_behavior(
|
||||
self,
|
||||
flight: Flight,
|
||||
group: FlyingGroup,
|
||||
react_on_threat: Optional[OptReactOnThreat.Values] = None,
|
||||
roe: Optional[OptROE.Values] = None,
|
||||
rtb_winchester: Optional[OptRTBOnOutOfAmmo.Values] = None,
|
||||
restrict_jettison: Optional[bool] = None,
|
||||
mission_uses_gun: bool = True,
|
||||
) -> None:
|
||||
group.points[0].tasks.clear()
|
||||
if react_on_threat is not None:
|
||||
@ -1172,6 +1183,17 @@ class AircraftConflictGenerator:
|
||||
if rtb_winchester is not None:
|
||||
group.points[0].tasks.append(OptRTBOnOutOfAmmo(rtb_winchester))
|
||||
|
||||
# Confiscate the bullets of AI missions that do not rely on the gun. There is no
|
||||
# "all but gun" RTB winchester option, so air to ground missions with mixed
|
||||
# weapon types will insist on using all of their bullets after running out of
|
||||
# missiles and bombs. Take away their bullets so they don't strafe a Tor.
|
||||
#
|
||||
# Exceptions are made for player flights and for airframes where the gun is
|
||||
# essential like the A-10 or warbirds.
|
||||
if not mission_uses_gun and not self.flight_always_keeps_gun(flight):
|
||||
for unit in group.units:
|
||||
unit.gun = 0
|
||||
|
||||
group.points[0].tasks.append(OptRTBOnBingoFuel(True))
|
||||
# Do not restrict afterburner.
|
||||
# https://forums.eagle.ru/forum/english/digital-combat-simulator/dcs-world-2-5/bugs-and-problems-ai/ai-ad/7121294-ai-stuck-at-high-aoa-after-making-sharp-turn-if-afterburner-is-restricted
|
||||
@ -1197,7 +1219,7 @@ class AircraftConflictGenerator:
|
||||
else:
|
||||
ammo_type = OptRTBOnOutOfAmmo.Values.Cannon
|
||||
|
||||
self.configure_behavior(group, rtb_winchester=ammo_type)
|
||||
self.configure_behavior(flight, group, rtb_winchester=ammo_type)
|
||||
|
||||
def configure_sweep(
|
||||
self,
|
||||
@ -1214,7 +1236,7 @@ class AircraftConflictGenerator:
|
||||
else:
|
||||
ammo_type = OptRTBOnOutOfAmmo.Values.Cannon
|
||||
|
||||
self.configure_behavior(group, rtb_winchester=ammo_type)
|
||||
self.configure_behavior(flight, group, rtb_winchester=ammo_type)
|
||||
|
||||
def configure_cas(
|
||||
self,
|
||||
@ -1226,6 +1248,7 @@ class AircraftConflictGenerator:
|
||||
group.task = CAS.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.OpenFire,
|
||||
@ -1249,11 +1272,13 @@ class AircraftConflictGenerator:
|
||||
group.task = CAS.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.OpenFire,
|
||||
rtb_winchester=OptRTBOnOutOfAmmo.Values.All,
|
||||
restrict_jettison=True,
|
||||
mission_uses_gun=False,
|
||||
)
|
||||
|
||||
def configure_sead(
|
||||
@ -1269,6 +1294,7 @@ class AircraftConflictGenerator:
|
||||
group.task = CAS.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.OpenFire,
|
||||
@ -1276,6 +1302,7 @@ class AircraftConflictGenerator:
|
||||
# weapons for SEAD).
|
||||
rtb_winchester=OptRTBOnOutOfAmmo.Values.ASM,
|
||||
restrict_jettison=True,
|
||||
mission_uses_gun=False,
|
||||
)
|
||||
|
||||
def configure_strike(
|
||||
@ -1288,10 +1315,12 @@ class AircraftConflictGenerator:
|
||||
group.task = GroundAttack.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.OpenFire,
|
||||
restrict_jettison=True,
|
||||
mission_uses_gun=False,
|
||||
)
|
||||
|
||||
def configure_anti_ship(
|
||||
@ -1304,10 +1333,12 @@ class AircraftConflictGenerator:
|
||||
group.task = AntishipStrike.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.OpenFire,
|
||||
restrict_jettison=True,
|
||||
mission_uses_gun=False,
|
||||
)
|
||||
|
||||
def configure_runway_attack(
|
||||
@ -1320,10 +1351,12 @@ class AircraftConflictGenerator:
|
||||
group.task = RunwayAttack.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.OpenFire,
|
||||
restrict_jettison=True,
|
||||
mission_uses_gun=False,
|
||||
)
|
||||
|
||||
def configure_oca_strike(
|
||||
@ -1336,6 +1369,7 @@ class AircraftConflictGenerator:
|
||||
group.task = CAS.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.OpenFire,
|
||||
@ -1361,6 +1395,7 @@ class AircraftConflictGenerator:
|
||||
|
||||
# Awacs task action
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.WeaponHold,
|
||||
@ -1382,7 +1417,7 @@ class AircraftConflictGenerator:
|
||||
group.task = CAP.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
group, roe=OptROE.Values.OpenFire, restrict_jettison=True
|
||||
flight, group, roe=OptROE.Values.OpenFire, restrict_jettison=True
|
||||
)
|
||||
|
||||
def configure_sead_escort(
|
||||
@ -1398,12 +1433,14 @@ class AircraftConflictGenerator:
|
||||
group.task = CAS.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
roe=OptROE.Values.OpenFire,
|
||||
# ASM includes ARMs and TALDs (among other things, but those are the useful
|
||||
# weapons for SEAD).
|
||||
rtb_winchester=OptRTBOnOutOfAmmo.Values.ASM,
|
||||
restrict_jettison=True,
|
||||
mission_uses_gun=False,
|
||||
)
|
||||
|
||||
def configure_transport(
|
||||
@ -1416,6 +1453,7 @@ class AircraftConflictGenerator:
|
||||
group.task = Transport.name
|
||||
self._setup_group(group, package, flight, dynamic_runways)
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.WeaponHold,
|
||||
@ -1424,7 +1462,7 @@ class AircraftConflictGenerator:
|
||||
|
||||
def configure_unknown_task(self, group: FlyingGroup, flight: Flight) -> None:
|
||||
logging.error(f"Unhandled flight type: {flight.flight_type}")
|
||||
self.configure_behavior(group)
|
||||
self.configure_behavior(flight, group)
|
||||
|
||||
def setup_flight_group(
|
||||
self,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user