From 7e7a1dce7bf0a9d92d4e56d97f906b3468483175 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Thu, 20 May 2021 23:55:24 -0700 Subject: [PATCH 001/122] Fix icons for dead SAMs showing as damaged. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1099 --- resources/ui/map/map.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/ui/map/map.js b/resources/ui/map/map.js index 1b421520..3e1056b2 100644 --- a/resources/ui/map/map.js +++ b/resources/ui/map/map.js @@ -403,10 +403,10 @@ class TheaterGroundObject { icon() { let state; - if (this.tgo.category == "aa" && !this.samIsThreat()) { - state = UnitState.Damaged; - } else if (this.tgo.dead) { + if (this.tgo.dead) { state = UnitState.Destroyed; + } else if (this.tgo.category == "aa" && !this.samIsThreat()) { + state = UnitState.Damaged; } else { state = UnitState.Alive; } From 40720f9949325c82e82083b4d164a23814a2da67 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 21 May 2021 17:53:13 -0700 Subject: [PATCH 002/122] Fix convoy spawn point from Tabqa to Jirah. The current spawn point is a disonnected road network according to the map, so the convoy will never start moving because they have no route to the destination. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1101 --- resources/campaigns/inherent_resolve.miz | Bin 57464 -> 59137 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/campaigns/inherent_resolve.miz b/resources/campaigns/inherent_resolve.miz index 5f3ac702c67e2a26eb17ffceae1d7c83e865518a..b46c43a3e4aab5f9347e805050ba95a33fbf1015 100644 GIT binary patch literal 59137 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 literal 57464 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 R{R053``zQ9DpLo$zX6UR)ocI& From df4dabf68f530811ca2b331a4f6b1eada5549d2b Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 21 May 2021 17:59:19 -0700 Subject: [PATCH 003/122] Add an LHA to Abu Dhabi. --- resources/campaigns/battle_of_abu_dhabi.miz | Bin 44592 -> 44783 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/campaigns/battle_of_abu_dhabi.miz b/resources/campaigns/battle_of_abu_dhabi.miz index 51e5370308500ecfe37d9dba80f5e3c5b54669ed..a31881ef9d52d1c5cc3eb323c9bd0afbf5c01a35 100644 GIT binary patch literal 44783 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 H0s#I84hD!< literal 44592 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 From f8cb9e2bd393e9a07374ef1ced15c8862ee9c975 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 21 May 2021 19:13:32 -0700 Subject: [PATCH 004/122] Update Inherent Resolve to use non-random TGOs. Also adds Ramat David to blue. --- resources/campaigns/inherent_resolve.json | 4 ++-- resources/campaigns/inherent_resolve.miz | Bin 59137 -> 51127 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/campaigns/inherent_resolve.json b/resources/campaigns/inherent_resolve.json index 256216a4..be1e9930 100644 --- a/resources/campaigns/inherent_resolve.json +++ b/resources/campaigns/inherent_resolve.json @@ -5,7 +5,7 @@ "recommended_player_faction": "USA 2005", "recommended_enemy_faction": "Insurgents (Hard)", "description": "

In this scenario, you start from Jordan, and have to fight your way through eastern Syria.

", - "version": 4, + "version": "4.2", "miz": "inherent_resolve.miz", - "performance": 1 + "performance": 2 } \ No newline at end of file diff --git a/resources/campaigns/inherent_resolve.miz b/resources/campaigns/inherent_resolve.miz index b46c43a3e4aab5f9347e805050ba95a33fbf1015..92e615125092476bb44bf5b9e45cd37718becfca 100644 GIT binary patch delta 35605 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 delta 43469 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 Date: Fri, 21 May 2021 21:43:02 -0700 Subject: [PATCH 005/122] Add icons for CPs. --- game/theater/controlpoint.py | 25 +++++++ qt_ui/widgets/map/mapmodel.py | 7 ++ .../ui/ground_assets/airfield_blue_alive.svg | 1 + .../ground_assets/airfield_blue_damaged.svg | 1 + .../ground_assets/airfield_blue_destroyed.svg | 1 + .../ui/ground_assets/airfield_red_alive.svg | 1 + .../ui/ground_assets/airfield_red_damaged.svg | 1 + .../ground_assets/airfield_red_destroyed.svg | 1 + resources/ui/ground_assets/cv_blue_alive.svg | 1 + .../ui/ground_assets/cv_blue_damaged.svg | 1 + .../ui/ground_assets/cv_blue_destination.svg | 1 + .../ui/ground_assets/cv_blue_destroyed.svg | 1 + resources/ui/ground_assets/cv_red_alive.svg | 1 + resources/ui/ground_assets/cv_red_damaged.svg | 1 + .../ui/ground_assets/cv_red_destination.svg | 1 + .../ui/ground_assets/cv_red_destroyed.svg | 1 + resources/ui/ground_assets/lha_blue_alive.svg | 1 + .../ui/ground_assets/lha_blue_damaged.svg | 1 + .../ui/ground_assets/lha_blue_destination.svg | 1 + .../ui/ground_assets/lha_blue_destroyed.svg | 1 + resources/ui/ground_assets/lha_red_alive.svg | 1 + .../ui/ground_assets/lha_red_damaged.svg | 1 + .../ui/ground_assets/lha_red_destination.svg | 1 + .../ui/ground_assets/lha_red_destroyed.svg | 1 + resources/ui/map/map.js | 75 +++++++++++++------ 25 files changed, 105 insertions(+), 24 deletions(-) create mode 100644 resources/ui/ground_assets/airfield_blue_alive.svg create mode 100644 resources/ui/ground_assets/airfield_blue_damaged.svg create mode 100644 resources/ui/ground_assets/airfield_blue_destroyed.svg create mode 100644 resources/ui/ground_assets/airfield_red_alive.svg create mode 100644 resources/ui/ground_assets/airfield_red_damaged.svg create mode 100644 resources/ui/ground_assets/airfield_red_destroyed.svg create mode 100644 resources/ui/ground_assets/cv_blue_alive.svg create mode 100644 resources/ui/ground_assets/cv_blue_damaged.svg create mode 100644 resources/ui/ground_assets/cv_blue_destination.svg create mode 100644 resources/ui/ground_assets/cv_blue_destroyed.svg create mode 100644 resources/ui/ground_assets/cv_red_alive.svg create mode 100644 resources/ui/ground_assets/cv_red_damaged.svg create mode 100644 resources/ui/ground_assets/cv_red_destination.svg create mode 100644 resources/ui/ground_assets/cv_red_destroyed.svg create mode 100644 resources/ui/ground_assets/lha_blue_alive.svg create mode 100644 resources/ui/ground_assets/lha_blue_damaged.svg create mode 100644 resources/ui/ground_assets/lha_blue_destination.svg create mode 100644 resources/ui/ground_assets/lha_blue_destroyed.svg create mode 100644 resources/ui/ground_assets/lha_red_alive.svg create mode 100644 resources/ui/ground_assets/lha_red_damaged.svg create mode 100644 resources/ui/ground_assets/lha_red_destination.svg create mode 100644 resources/ui/ground_assets/lha_red_destroyed.svg diff --git a/game/theater/controlpoint.py b/game/theater/controlpoint.py index f2e96a88..341df02e 100644 --- a/game/theater/controlpoint.py +++ b/game/theater/controlpoint.py @@ -786,6 +786,11 @@ class ControlPoint(MissionTarget, ABC): def strike_targets(self) -> List[Union[MissionTarget, Unit]]: return [] + @property + @abstractmethod + def category(self) -> str: + ... + class Airfield(ControlPoint): def __init__( @@ -863,6 +868,10 @@ class Airfield(ControlPoint): def income_per_turn(self) -> int: return 20 + @property + def category(self) -> str: + return "airfield" + class NavalControlPoint(ControlPoint, ABC): @property @@ -956,6 +965,10 @@ class Carrier(NavalControlPoint): def total_aircraft_parking(self) -> int: return 90 + @property + def category(self) -> str: + return "cv" + class Lha(NavalControlPoint): def __init__(self, name: str, at: Point, cp_id: int): @@ -986,6 +999,10 @@ class Lha(NavalControlPoint): def total_aircraft_parking(self) -> int: return 20 + @property + def category(self) -> str: + return "lha" + class OffMapSpawn(ControlPoint): def runway_is_operational(self) -> bool: @@ -1036,6 +1053,10 @@ class OffMapSpawn(ControlPoint): def can_deploy_ground_units(self) -> bool: return False + @property + def category(self) -> str: + return "offmap" + class Fob(ControlPoint): def __init__(self, name: str, at: Point, cp_id: int): @@ -1100,3 +1121,7 @@ class Fob(ControlPoint): @property def income_per_turn(self) -> int: return 10 + + @property + def category(self) -> str: + return "fob" diff --git a/qt_ui/widgets/map/mapmodel.py b/qt_ui/widgets/map/mapmodel.py index bdb379d3..4f82f533 100644 --- a/qt_ui/widgets/map/mapmodel.py +++ b/qt_ui/widgets/map/mapmodel.py @@ -19,6 +19,8 @@ from game.theater import ( TheaterGroundObject, FrontLine, LatLon, + Airfield, + Carrier, ) from game.transfers import MultiGroupTransport, TransportMap from game.utils import meters, nautical_miles @@ -63,6 +65,7 @@ class ControlPointJs(QObject): positionChanged = Signal() mobileChanged = Signal() destinationChanged = Signal(list) + categoryChanged = Signal() def __init__( self, @@ -84,6 +87,10 @@ class ControlPointJs(QObject): def blue(self) -> bool: return self.control_point.captured + @Property(str, notify=categoryChanged) + def category(self) -> str: + return self.control_point.category + @Property(list, notify=positionChanged) def position(self) -> LeafletLatLon: ll = self.theater.point_to_ll(self.control_point.position) diff --git a/resources/ui/ground_assets/airfield_blue_alive.svg b/resources/ui/ground_assets/airfield_blue_alive.svg new file mode 100644 index 00000000..dcc9a38e --- /dev/null +++ b/resources/ui/ground_assets/airfield_blue_alive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/airfield_blue_damaged.svg b/resources/ui/ground_assets/airfield_blue_damaged.svg new file mode 100644 index 00000000..107f6b62 --- /dev/null +++ b/resources/ui/ground_assets/airfield_blue_damaged.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/airfield_blue_destroyed.svg b/resources/ui/ground_assets/airfield_blue_destroyed.svg new file mode 100644 index 00000000..7d49ff30 --- /dev/null +++ b/resources/ui/ground_assets/airfield_blue_destroyed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/airfield_red_alive.svg b/resources/ui/ground_assets/airfield_red_alive.svg new file mode 100644 index 00000000..1b481dd0 --- /dev/null +++ b/resources/ui/ground_assets/airfield_red_alive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/airfield_red_damaged.svg b/resources/ui/ground_assets/airfield_red_damaged.svg new file mode 100644 index 00000000..39693c44 --- /dev/null +++ b/resources/ui/ground_assets/airfield_red_damaged.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/airfield_red_destroyed.svg b/resources/ui/ground_assets/airfield_red_destroyed.svg new file mode 100644 index 00000000..1a2303a1 --- /dev/null +++ b/resources/ui/ground_assets/airfield_red_destroyed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/cv_blue_alive.svg b/resources/ui/ground_assets/cv_blue_alive.svg new file mode 100644 index 00000000..4ae3a57c --- /dev/null +++ b/resources/ui/ground_assets/cv_blue_alive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/cv_blue_damaged.svg b/resources/ui/ground_assets/cv_blue_damaged.svg new file mode 100644 index 00000000..33b0c0bb --- /dev/null +++ b/resources/ui/ground_assets/cv_blue_damaged.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/cv_blue_destination.svg b/resources/ui/ground_assets/cv_blue_destination.svg new file mode 100644 index 00000000..9e4ae54f --- /dev/null +++ b/resources/ui/ground_assets/cv_blue_destination.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/cv_blue_destroyed.svg b/resources/ui/ground_assets/cv_blue_destroyed.svg new file mode 100644 index 00000000..55ef5cc2 --- /dev/null +++ b/resources/ui/ground_assets/cv_blue_destroyed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/cv_red_alive.svg b/resources/ui/ground_assets/cv_red_alive.svg new file mode 100644 index 00000000..b71d1366 --- /dev/null +++ b/resources/ui/ground_assets/cv_red_alive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/cv_red_damaged.svg b/resources/ui/ground_assets/cv_red_damaged.svg new file mode 100644 index 00000000..22e50f5f --- /dev/null +++ b/resources/ui/ground_assets/cv_red_damaged.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/cv_red_destination.svg b/resources/ui/ground_assets/cv_red_destination.svg new file mode 100644 index 00000000..3e92f8e3 --- /dev/null +++ b/resources/ui/ground_assets/cv_red_destination.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/cv_red_destroyed.svg b/resources/ui/ground_assets/cv_red_destroyed.svg new file mode 100644 index 00000000..b8a8e243 --- /dev/null +++ b/resources/ui/ground_assets/cv_red_destroyed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/ui/ground_assets/lha_blue_alive.svg b/resources/ui/ground_assets/lha_blue_alive.svg new file mode 100644 index 00000000..e01cc213 --- /dev/null +++ b/resources/ui/ground_assets/lha_blue_alive.svg @@ -0,0 +1 @@ +LHA \ No newline at end of file diff --git a/resources/ui/ground_assets/lha_blue_damaged.svg b/resources/ui/ground_assets/lha_blue_damaged.svg new file mode 100644 index 00000000..4aeffeeb --- /dev/null +++ b/resources/ui/ground_assets/lha_blue_damaged.svg @@ -0,0 +1 @@ +LHA \ No newline at end of file diff --git a/resources/ui/ground_assets/lha_blue_destination.svg b/resources/ui/ground_assets/lha_blue_destination.svg new file mode 100644 index 00000000..ff80f36a --- /dev/null +++ b/resources/ui/ground_assets/lha_blue_destination.svg @@ -0,0 +1 @@ +LHA \ No newline at end of file diff --git a/resources/ui/ground_assets/lha_blue_destroyed.svg b/resources/ui/ground_assets/lha_blue_destroyed.svg new file mode 100644 index 00000000..2d0092c3 --- /dev/null +++ b/resources/ui/ground_assets/lha_blue_destroyed.svg @@ -0,0 +1 @@ +LHA \ No newline at end of file diff --git a/resources/ui/ground_assets/lha_red_alive.svg b/resources/ui/ground_assets/lha_red_alive.svg new file mode 100644 index 00000000..f3960157 --- /dev/null +++ b/resources/ui/ground_assets/lha_red_alive.svg @@ -0,0 +1 @@ +LHA \ No newline at end of file diff --git a/resources/ui/ground_assets/lha_red_damaged.svg b/resources/ui/ground_assets/lha_red_damaged.svg new file mode 100644 index 00000000..4c3c6aa3 --- /dev/null +++ b/resources/ui/ground_assets/lha_red_damaged.svg @@ -0,0 +1 @@ +LHA \ No newline at end of file diff --git a/resources/ui/ground_assets/lha_red_destination.svg b/resources/ui/ground_assets/lha_red_destination.svg new file mode 100644 index 00000000..9ef1411b --- /dev/null +++ b/resources/ui/ground_assets/lha_red_destination.svg @@ -0,0 +1 @@ +LHA \ No newline at end of file diff --git a/resources/ui/ground_assets/lha_red_destroyed.svg b/resources/ui/ground_assets/lha_red_destroyed.svg new file mode 100644 index 00000000..87ff95ac --- /dev/null +++ b/resources/ui/ground_assets/lha_red_destroyed.svg @@ -0,0 +1 @@ +LHA \ No newline at end of file diff --git a/resources/ui/map/map.js b/resources/ui/map/map.js index 3e1056b2..a68c5716 100644 --- a/resources/ui/map/map.js +++ b/resources/ui/map/map.js @@ -45,6 +45,49 @@ const UnitState = Object.freeze({ Destroyed: "destroyed", }); +class CpIcons { + constructor() { + this.icons = {}; + for (const player of [true, false]) { + this.icons[player] = {}; + for (const state of Object.values(UnitState)) { + this.icons[player][state] = { + airfield: this.loadIcon("airfield", player, state), + cv: this.loadIcon("cv", player, state), + fob: this.loadLegacyIcon(player), + lha: this.loadIcon("lha", player, state), + offmap: this.loadLegacyIcon(player), + }; + } + } + } + + icon(category, player, state) { + return this.icons[player][state][category]; + } + + loadIcon(category, player, state) { + const color = player ? "blue" : "red"; + return new L.Icon({ + iconUrl: `../ground_assets/${category}_${color}_${state}.svg`, + iconSize: [32, 32], + }); + } + + loadLegacyIcon(player) { + const color = player ? "blue" : "red"; + return new L.Icon({ + iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-${color}.png`, + shadowUrl: + "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png", + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowSize: [41, 41], + }); + } +} + class TgoIcons { constructor() { this.icons = {}; @@ -84,26 +127,7 @@ class TgoIcons { } const Icons = Object.freeze({ - BlueControlPoint: new L.Icon({ - iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-blue.png`, - shadowUrl: - "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png", - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - shadowSize: [41, 41], - }), - - RedControlPoint: new L.Icon({ - iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png`, - shadowUrl: - "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png", - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - shadowSize: [41, 41], - }), - + ControlPoints: new CpIcons(), Objectives: new TgoIcons(), }); @@ -212,10 +236,13 @@ class ControlPoint { } icon() { - if (this.cp.blue) { - return Icons.BlueControlPoint; - } - return Icons.RedControlPoint; + // TODO: Runway status. + // https://github.com/dcs-liberation/dcs_liberation/issues/1105 + return Icons.ControlPoints.icon( + this.cp.category, + this.cp.blue, + UnitState.Alive + ); } hasDestination() { From 90dca9072e79337b5f3797769511a750aadbb1d0 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 01:02:42 -0700 Subject: [PATCH 006/122] Change default mission duration to 60 minutes. This seems like it works better for the number of missions we usually frag, plus the fact that players will almost always choose an ASAP package. --- game/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/settings.py b/game/settings.py index cda2bc79..c853b513 100644 --- a/game/settings.py +++ b/game/settings.py @@ -27,7 +27,7 @@ class Settings: default_start_type: str = "Cold" # Mission specific - desired_player_mission_duration: timedelta = timedelta(minutes=90) + desired_player_mission_duration: timedelta = timedelta(minutes=60) # Campaign management automate_runway_repair: bool = False From 2ca0edf5fdb47e399bd284fca8ee10ae6c2584ac Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 01:09:43 -0700 Subject: [PATCH 007/122] Increase estimate for airfield ground ops. 5 minutes is pretty optimistic at most airfields. --- gen/flights/flightplan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/flights/flightplan.py b/gen/flights/flightplan.py index b18d8a91..14bc6601 100644 --- a/gen/flights/flightplan.py +++ b/gen/flights/flightplan.py @@ -243,7 +243,7 @@ class FlightPlan: if self.flight.from_cp.is_fleet: return timedelta(minutes=2) else: - return timedelta(minutes=5) + return timedelta(minutes=8) @property def mission_departure_time(self) -> timedelta: From 59e03434e4d4be929e2282a4edabca5338604396 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 01:10:23 -0700 Subject: [PATCH 008/122] Increase flight speeds to mach 0.85 or 85% of max. Everyone seems a bit slow, generally. 0.85 is probably a better cruise speed for supersonic jets and 85% of max is probably fine for subsonic. --- gen/flights/traveltime.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gen/flights/traveltime.py b/gen/flights/traveltime.py index 6b6f0463..2fa05690 100644 --- a/gen/flights/traveltime.py +++ b/gen/flights/traveltime.py @@ -36,16 +36,16 @@ class GroundSpeed: # DCS's max speed is in kph at 0 MSL. max_speed = kph(flight.unit_type.max_speed) if max_speed > SPEED_OF_SOUND_AT_SEA_LEVEL: - # Aircraft is supersonic. Limit to mach 0.8 to conserve fuel and + # Aircraft is supersonic. Limit to mach 0.85 to conserve fuel and # account for heavily loaded jets. - return mach(0.8, altitude) + return mach(0.85, altitude) # For subsonic aircraft, assume the aircraft can reasonably perform at # 80% of its maximum, and that it can maintain the same mach at altitude # as it can at sea level. This probably isn't great assumption, but # might. be sufficient given the wiggle room. We can come up with # another heuristic if needed. - cruise_mach = max_speed.mach() * 0.8 + cruise_mach = max_speed.mach() * 0.85 return mach(cruise_mach, altitude) From e332bff36289149fd088cbd7a27e97c2640e62da Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 01:11:28 -0700 Subject: [PATCH 009/122] Decrease error margin on TOT planning. Everyone seems to do pretty okay generally, with the exception of estimating ground ops time, which I've also increased (and is a non-issue for runway/air start defaults). --- gen/flights/traveltime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/flights/traveltime.py b/gen/flights/traveltime.py index 2fa05690..6b787f95 100644 --- a/gen/flights/traveltime.py +++ b/gen/flights/traveltime.py @@ -52,7 +52,7 @@ class GroundSpeed: class TravelTime: @staticmethod def between_points(a: Point, b: Point, speed: Speed) -> timedelta: - error_factor = 1.1 + error_factor = 1.05 distance = meters(a.distance_to_point(b)) return timedelta(hours=distance.nautical_miles / speed.knots * error_factor) From b6154b273c23d1ddedf32c2f25a4d76d9392c28b Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 14:19:49 -0700 Subject: [PATCH 010/122] Differentiate SEAD and SEAD escorts. SEAD suppresses the package's target. SEAD escort protects the package from any SAM threat along its flight path. --- changelog.md | 1 + game/theater/controlpoint.py | 2 +- game/theater/missiontarget.py | 2 +- game/theater/theatergroundobject.py | 1 + gen/aircraft.py | 60 +++++++++++++++++++++-------- gen/flights/ai_flight_planner.py | 14 ++++--- gen/flights/ai_flight_planner_db.py | 2 + gen/flights/flight.py | 36 +++++++++++++++++ gen/flights/flightplan.py | 2 + gen/flights/waypointbuilder.py | 5 ++- 10 files changed, 100 insertions(+), 25 deletions(-) diff --git a/changelog.md b/changelog.md index b0f8e3c9..7f3a60aa 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,7 @@ Saves from 2.5 are not compatible with 3.0. * **[Campaign AI]** Fix purchase of aircraft by priority (the faction's list was being used as the priority list rather than the game's). * **[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. * **[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. diff --git a/game/theater/controlpoint.py b/game/theater/controlpoint.py index 341df02e..ad9f4ec1 100644 --- a/game/theater/controlpoint.py +++ b/game/theater/controlpoint.py @@ -1100,7 +1100,7 @@ class Fob(ControlPoint): FlightType.STRIKE, FlightType.SWEEP, FlightType.ESCORT, - FlightType.SEAD, + FlightType.SEAD_ESCORT, ] @property diff --git a/game/theater/missiontarget.py b/game/theater/missiontarget.py index 197de586..ea426603 100644 --- a/game/theater/missiontarget.py +++ b/game/theater/missiontarget.py @@ -37,7 +37,7 @@ class MissionTarget: yield from [ FlightType.ESCORT, FlightType.TARCAP, - FlightType.SEAD, + FlightType.SEAD_ESCORT, FlightType.SWEEP, # TODO: FlightType.ELINT, # TODO: FlightType.EWAR, diff --git a/game/theater/theatergroundobject.py b/game/theater/theatergroundobject.py index 18131a42..2ff05114 100644 --- a/game/theater/theatergroundobject.py +++ b/game/theater/theatergroundobject.py @@ -452,6 +452,7 @@ class SamGroundObject(BaseDefenseGroundObject): if not self.is_friendly(for_player): yield FlightType.DEAD + yield FlightType.SEAD yield from super().mission_types(for_player) @property diff --git a/gen/aircraft.py b/gen/aircraft.py index b170c5c2..c7b7a17a 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -67,6 +67,7 @@ from dcs.task import ( Targets, Transport, WeaponType, + TargetType, ) from dcs.terrain.terrain import Airport, NoParkingSlotError from dcs.triggers import Event, TriggerOnce, TriggerRule @@ -1379,6 +1380,22 @@ class AircraftConflictGenerator: group, roe=OptROE.Values.OpenFire, restrict_jettison=True ) + def configure_sead_escort( + self, + group: FlyingGroup, + package: Package, + flight: Flight, + dynamic_runways: Dict[str, RunwayData], + ) -> None: + group.task = SEAD.name + self._setup_group(group, package, flight, dynamic_runways) + self.configure_behavior( + group, + roe=OptROE.Values.OpenFire, + rtb_winchester=OptRTBOnOutOfAmmo.Values.Guided, + restrict_jettison=True, + ) + def configure_transport( self, group: FlyingGroup, @@ -1423,6 +1440,8 @@ class AircraftConflictGenerator: self.configure_dead(group, package, flight, dynamic_runways) elif flight_type == FlightType.SEAD: self.configure_sead(group, package, flight, dynamic_runways) + elif flight_type == FlightType.SEAD_ESCORT: + self.configure_sead_escort(group, package, flight, dynamic_runways) elif flight_type == FlightType.STRIKE: self.configure_strike(group, package, flight, dynamic_runways) elif flight_type == FlightType.ANTISHIP: @@ -1802,18 +1821,16 @@ class SeadIngressBuilder(PydcsWaypointBuilder): if isinstance(target_group, TheaterGroundObject): tgroup = self.mission.find_group(target_group.group_name) if tgroup is not None: - waypoint.add_task( - EngageTargetsInZone( - position=tgroup.position, - radius=int(nautical_miles(30).meters), - targets=[ - Targets.All.GroundUnits.AirDefence, - ], - ) - ) + task = AttackGroup(tgroup.id, weapon_type=WeaponType.Guided) + task.params["expend"] = "All" + task.params["attackQtyLimit"] = False + task.params["directionEnabled"] = False + task.params["altitudeEnabled"] = False + task.params["groupAttack"] = True + waypoint.tasks.append(task) else: logging.error( - f"Could not find group for DEAD mission {target_group.group_name}" + f"Could not find group for SEAD mission {target_group.group_name}" ) self.register_special_waypoints(self.waypoint.targets) return waypoint @@ -1889,11 +1906,23 @@ class JoinPointBuilder(PydcsWaypointBuilder): def build(self) -> MovingPoint: waypoint = super().build() if self.flight.flight_type == FlightType.ESCORT: - self.configure_escort_tasks(waypoint) + self.configure_escort_tasks( + waypoint, + [ + Targets.All.Air.Planes.Fighters, + Targets.All.Air.Planes.MultiroleFighters, + ], + ) + elif self.flight.flight_type == FlightType.SEAD_ESCORT: + self.configure_escort_tasks( + waypoint, [Targets.All.GroundUnits.AirDefence.AAA.SAMRelated] + ) return waypoint @staticmethod - def configure_escort_tasks(waypoint: MovingPoint) -> None: + def configure_escort_tasks( + waypoint: MovingPoint, target_types: List[Type[TargetType]] + ) -> None: # Ideally we would use the escort mission type and escort task to have # the AI automatically but the AI only escorts AI flights while they are # traveling between waypoints. When an AI flight performs an attack @@ -1919,16 +1948,13 @@ class JoinPointBuilder(PydcsWaypointBuilder): # for the target area that is set to end on a flag flip that occurs when # the strike aircraft finish their attack task. # - # https://forums.eagle.ru/forum/english/digital-combat-simulator/dcs-world-2-5/bugs-and-problems-ai/ai-ad/250183-task-follow-and-escort-temporarily-aborted + # https://forums.eagle.ru/topic/251798-options-for-alternate-ai-escort-behavior waypoint.add_task( ControlledTask( EngageTargets( # TODO: From doctrine. max_distance=int(nautical_miles(30).meters), - targets=[ - Targets.All.Air.Planes.Fighters, - Targets.All.Air.Planes.MultiroleFighters, - ], + targets=target_types, ) ) ) diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 2cd658d5..f8bb3905 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -635,6 +635,7 @@ class CoalitionMissionPlanner: sam, [ ProposedFlight(FlightType.DEAD, 2, self.MAX_SEAD_RANGE), + ProposedFlight(FlightType.SEAD, 2, self.MAX_SEAD_RANGE), # TODO: Max escort range. ProposedFlight( FlightType.ESCORT, 2, self.MAX_SEAD_RANGE, EscortType.AirToAir @@ -665,7 +666,7 @@ class CoalitionMissionPlanner: FlightType.ESCORT, 2, self.MAX_BAI_RANGE, EscortType.AirToAir ), ProposedFlight( - FlightType.SEAD, 2, self.MAX_BAI_RANGE, EscortType.Sead + FlightType.SEAD_ESCORT, 2, self.MAX_BAI_RANGE, EscortType.Sead ), ], ) @@ -680,7 +681,7 @@ class CoalitionMissionPlanner: FlightType.ESCORT, 2, self.MAX_BAI_RANGE, EscortType.AirToAir ), ProposedFlight( - FlightType.SEAD, 2, self.MAX_BAI_RANGE, EscortType.Sead + FlightType.SEAD_ESCORT, 2, self.MAX_BAI_RANGE, EscortType.Sead ), ], ) @@ -710,7 +711,7 @@ class CoalitionMissionPlanner: FlightType.ESCORT, 2, self.MAX_BAI_RANGE, EscortType.AirToAir ), ProposedFlight( - FlightType.SEAD, 2, self.MAX_OCA_RANGE, EscortType.Sead + FlightType.SEAD_ESCORT, 2, self.MAX_OCA_RANGE, EscortType.Sead ), ], ) @@ -732,7 +733,7 @@ class CoalitionMissionPlanner: FlightType.ESCORT, 2, self.MAX_OCA_RANGE, EscortType.AirToAir ), ProposedFlight( - FlightType.SEAD, 2, self.MAX_OCA_RANGE, EscortType.Sead + FlightType.SEAD_ESCORT, 2, self.MAX_OCA_RANGE, EscortType.Sead ), ] ) @@ -749,7 +750,10 @@ class CoalitionMissionPlanner: FlightType.ESCORT, 2, self.MAX_STRIKE_RANGE, EscortType.AirToAir ), ProposedFlight( - FlightType.SEAD, 2, self.MAX_STRIKE_RANGE, EscortType.Sead + FlightType.SEAD_ESCORT, + 2, + self.MAX_STRIKE_RANGE, + EscortType.Sead, ), ], ) diff --git a/gen/flights/ai_flight_planner_db.py b/gen/flights/ai_flight_planner_db.py index 730d4722..2c476b14 100644 --- a/gen/flights/ai_flight_planner_db.py +++ b/gen/flights/ai_flight_planner_db.py @@ -405,6 +405,8 @@ def aircraft_for_task(task: FlightType) -> List[Type[FlyingType]]: return CAS_CAPABLE elif task == FlightType.SEAD: return SEAD_CAPABLE + elif task == FlightType.SEAD_ESCORT: + return SEAD_CAPABLE elif task == FlightType.DEAD: return DEAD_CAPABLE elif task == FlightType.OCA_AIRCRAFT: diff --git a/gen/flights/flight.py b/gen/flights/flight.py index d5f95862..b9ea8bce 100644 --- a/gen/flights/flight.py +++ b/gen/flights/flight.py @@ -28,6 +28,27 @@ class FlightType(Enum): These values are persisted to the save game as well since they are a part of each flight and thus a part of the ATO, so changing these values will break save compat. + + When adding new mission types to this list, you will also need to update: + + * flightplan.py: Add waypoint population in generate_flight_plan. Add a new flight + plan type if necessary, though most are a subclass of StrikeFlightPlan. + * aircraft.py: Add a configuration method and call it in setup_flight_group. This is + responsible for configuring waypoint 0 actions like setting ROE, threat reaction, + and mission abort parameters (winchester, bingo, etc). + * Implementations of MissionTarget.mission_types: A mission type can only be planned + against compatible targets. The mission_types method of each target class defines + which missions may target it. + * ai_flight_planner_db.py: Add the new mission type to aircraft_for_task that + returns the list of compatible aircraft in order of preference. + + You may also need to update: + + * flight.py: Add a new waypoint type if necessary. Most mission types will need + these, as aircraft.py uses the ingress point type to specialize AI tasks, and non- + strike-like missions will need more specialized control. + * ai_flight_planner.py: Use the new mission type in propose_missions so the AI will + plan the new mission type. """ TARCAP = "TARCAP" @@ -45,12 +66,27 @@ class FlightType(Enum): OCA_AIRCRAFT = "OCA/Aircraft" AEWC = "AEW&C" TRANSPORT = "Transport" + SEAD_ESCORT = "SEAD Escort" def __str__(self) -> str: return self.value class FlightWaypointType(Enum): + """Enumeration of waypoint types. + + The value of the enum has no meaning but should remain stable to prevent breaking + save game compatibility. + + When adding a new waypoint type, you will also need to update: + + * waypointbuilder.py: Add a builder to simplify construction of the new waypoint + type unless the new waypoint type will be a parameter to an existing builder + method (such as how escort ingress waypoints work). + * aircraft.py: Associate AI actions with the new waypoint type by subclassing + PydcsWaypointBuilder and using it in PydcsWaypointBuilder.for_waypoint. + """ + TAKEOFF = 0 # Take off point ASCEND_POINT = 1 # Ascension point after take off PATROL = 2 # Patrol point diff --git a/gen/flights/flightplan.py b/gen/flights/flightplan.py index 14bc6601..5e6bc886 100644 --- a/gen/flights/flightplan.py +++ b/gen/flights/flightplan.py @@ -890,6 +890,8 @@ class FlightPlanBuilder: return self.generate_runway_attack(flight) elif task == FlightType.SEAD: return self.generate_sead(flight, custom_targets) + elif task == FlightType.SEAD_ESCORT: + return self.generate_escort(flight) elif task == FlightType.STRIKE: return self.generate_strike(flight) elif task == FlightType.SWEEP: diff --git a/gen/flights/waypointbuilder.py b/gen/flights/waypointbuilder.py index 670cdc01..f8380897 100644 --- a/gen/flights/waypointbuilder.py +++ b/gen/flights/waypointbuilder.py @@ -423,7 +423,10 @@ class WaypointBuilder: return self.sweep_start(start, altitude), self.sweep_end(end, altitude) def escort( - self, ingress: Point, target: MissionTarget, egress: Point + self, + ingress: Point, + target: MissionTarget, + egress: Point, ) -> Tuple[FlightWaypoint, FlightWaypoint, FlightWaypoint]: """Creates the waypoints needed to escort the package. From 3a08944c9925943e84f6d4f0ee767a86018c4918 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 14:27:30 -0700 Subject: [PATCH 011/122] Use the CAS DCS type for SEAD so F-14s can do it. The CAS task type appears to be a superset of the SEAD task in every way. Larger task variety as well as larger aircraft pool. --- gen/aircraft.py | 10 ++++++++-- gen/flights/ai_flight_planner_db.py | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/gen/aircraft.py b/gen/aircraft.py index c7b7a17a..1156d737 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -1263,7 +1263,10 @@ class AircraftConflictGenerator: flight: Flight, dynamic_runways: Dict[str, RunwayData], ) -> None: - group.task = SEAD.name + # CAS is able to perform all the same tasks as SEAD using a superset of the + # available aircraft, and F-14s are not able to be SEAD despite having TALDs. + # https://forums.eagle.ru/topic/272112-cannot-assign-f-14-to-sead/ + group.task = CAS.name self._setup_group(group, package, flight, dynamic_runways) self.configure_behavior( group, @@ -1387,7 +1390,10 @@ class AircraftConflictGenerator: flight: Flight, dynamic_runways: Dict[str, RunwayData], ) -> None: - group.task = SEAD.name + # CAS is able to perform all the same tasks as SEAD using a superset of the + # available aircraft, and F-14s are not able to be SEAD despite having TALDs. + # https://forums.eagle.ru/topic/272112-cannot-assign-f-14-to-sead/ + group.task = CAS.name self._setup_group(group, package, flight, dynamic_runways) self.configure_behavior( group, diff --git a/gen/flights/ai_flight_planner_db.py b/gen/flights/ai_flight_planner_db.py index 2c476b14..b8438a9c 100644 --- a/gen/flights/ai_flight_planner_db.py +++ b/gen/flights/ai_flight_planner_db.py @@ -230,7 +230,7 @@ CAS_CAPABLE = [ ] -# Aircraft used for SEAD tasks. Must be capable of the SEAD DCS task. +# Aircraft used for SEAD and SEAD Escort tasks. Must be capable of the CAS DCS task. SEAD_CAPABLE = [ JF_17, F_16C_50, @@ -240,6 +240,8 @@ SEAD_CAPABLE = [ Su_25TM, F_4E, A_4E_C, + F_14B, + F_14A_135_GR, AV8BNA, Su_24M, Su_17M4, From 57fe5c04ecf28e48dd40a1fb914f6d99378cdf6f Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 14:56:18 -0700 Subject: [PATCH 012/122] Improve DEAD mission planning. We don't need to include a SEAD flight in missions against EWRs or SAMs that no longer have a radar. Also plan DEAD missions against air defenses that have no radars. Previously we would never finish killing launcher only sites (which cannot defend any more, but are cheaper to return to working order than a fully destroyed site) nor would we plan DEAD against IR SAMs or AAA. --- game/theater/theatergroundobject.py | 2 +- gen/flights/ai_flight_planner.py | 52 +++++++++++++---------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/game/theater/theatergroundobject.py b/game/theater/theatergroundobject.py index 2ff05114..7675b256 100644 --- a/game/theater/theatergroundobject.py +++ b/game/theater/theatergroundobject.py @@ -137,7 +137,7 @@ class TheaterGroundObject(MissionTarget): return False @property - def has_radar(self) -> bool: + def has_alive_radar(self) -> bool: """Returns True if the ground object contains a unit with radar.""" for group in self.groups: for unit in group.units: diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index f8bb3905..92c55470 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -17,6 +17,7 @@ from typing import ( TYPE_CHECKING, Tuple, Type, + TypeVar, ) from dcs.unittype import FlyingType @@ -41,7 +42,6 @@ from game.theater.theatergroundobject import ( ) from game.transfers import CargoShip, Convoy from game.utils import Distance, nautical_miles -from gen import Conflict from gen.ato import Package from gen.flights.ai_flight_planner_db import aircraft_for_task from gen.flights.closestairfields import ( @@ -253,6 +253,9 @@ class PackageBuilder: self.package.remove_flight(flight) +MissionTargetType = TypeVar("MissionTargetType", bound=MissionTarget) + + class ObjectiveFinder: """Identifies potential objectives for the mission planner.""" @@ -264,11 +267,8 @@ class ObjectiveFinder: self.game = game self.is_player = is_player - def enemy_sams(self) -> Iterator[TheaterGroundObject]: + def enemy_air_defenses(self) -> Iterator[TheaterGroundObject]: """Iterates over all enemy SAM sites.""" - # Control points might have the same ground object several times, for - # some reason. - found_targets: Set[str] = set() for cp in self.enemy_control_points(): for ground_object in cp.ground_objects: is_ewr = isinstance(ground_object, EwrGroundObject) @@ -279,26 +279,19 @@ class ObjectiveFinder: if ground_object.is_dead: continue - if ground_object.name in found_targets: - continue - - if not ground_object.has_radar: - continue - # TODO: Yield in order of most threatening. # Need to sort in order of how close their defensive range comes # to friendly assets. To do that we need to add effective range # information to the database. yield ground_object - found_targets.add(ground_object.name) - def threatening_sams(self) -> Iterator[MissionTarget]: + def threatening_air_defenses(self) -> Iterator[TheaterGroundObject]: """Iterates over enemy SAMs in threat range of friendly control points. SAM sites are sorted by their closest proximity to any friendly control point (airfield or fleet). """ - return self._targets_by_range(self.enemy_sams()) + return self._targets_by_range(self.enemy_air_defenses()) def enemy_vehicle_groups(self) -> Iterator[VehicleGroupGroundObject]: """Iterates over all enemy vehicle groups.""" @@ -340,9 +333,9 @@ class ObjectiveFinder: return self._targets_by_range(self.enemy_ships()) def _targets_by_range( - self, targets: Iterable[MissionTarget] - ) -> Iterator[MissionTarget]: - target_ranges: List[Tuple[MissionTarget, int]] = [] + self, targets: Iterable[MissionTargetType] + ) -> Iterator[MissionTargetType]: + target_ranges: List[Tuple[MissionTargetType, int]] = [] for target in targets: ranges: List[int] = [] for cp in self.friendly_control_points(): @@ -630,18 +623,21 @@ class CoalitionMissionPlanner: # or objects, plan DEAD. # Find enemy SAM sites with ranges that extend to within 50 nmi of # friendly CPs, front, lines, or objects, plan DEAD. - for sam in self.objective_finder.threatening_sams(): - yield ProposedMission( - sam, - [ - ProposedFlight(FlightType.DEAD, 2, self.MAX_SEAD_RANGE), - ProposedFlight(FlightType.SEAD, 2, self.MAX_SEAD_RANGE), - # TODO: Max escort range. - ProposedFlight( - FlightType.ESCORT, 2, self.MAX_SEAD_RANGE, EscortType.AirToAir - ), - ], + for sam in self.objective_finder.threatening_air_defenses(): + flights = [ProposedFlight(FlightType.DEAD, 2, self.MAX_SEAD_RANGE)] + + # Only include SEAD against SAMs that still have emitters. No need to + # suppress an EWR, and SEAD isn't useful against a SAM that no longer has a + # radar. + if isinstance(sam, SamGroundObject) and sam.has_alive_radar: + flights.append(ProposedFlight(FlightType.SEAD, 2, self.MAX_SEAD_RANGE)) + # TODO: Max escort range. + flights.append( + ProposedFlight( + FlightType.ESCORT, 2, self.MAX_SEAD_RANGE, EscortType.AirToAir + ) ) + yield ProposedMission(sam, flights) # These will only rarely get planned. When a convoy is travelling multiple legs, # they're targetable after the first leg. The reason for this is that From ba2157cc431e6f74f2a314039d790915b1dc0c10 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 15:09:10 -0700 Subject: [PATCH 013/122] Tweak winchester behavior for SEAD escort. They can't suppress air defenses after running out of TALDs or ARMs. --- gen/aircraft.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gen/aircraft.py b/gen/aircraft.py index 1156d737..77c32e8a 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -1272,6 +1272,8 @@ class AircraftConflictGenerator: group, react_on_threat=OptReactOnThreat.Values.EvadeFire, 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, ) @@ -1398,7 +1400,9 @@ class AircraftConflictGenerator: self.configure_behavior( group, roe=OptROE.Values.OpenFire, - rtb_winchester=OptRTBOnOutOfAmmo.Values.Guided, + # ASM includes ARMs and TALDs (among other things, but those are the useful + # weapons for SEAD). + rtb_winchester=OptRTBOnOutOfAmmo.Values.ASM, restrict_jettison=True, ) From f68935735d436385a0821e1168a8726c7dba8ebb Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 15:36:56 -0700 Subject: [PATCH 014/122] Correct radar detection. This list includede units without radars and also missed units with radars. Stop curating the list and just query the unit type. --- game/data/radar_db.py | 72 ------------------- game/theater/theatergroundobject.py | 15 ++-- .../combos/QSEADTargetSelectionComboBox.py | 20 +++--- 3 files changed, 19 insertions(+), 88 deletions(-) delete mode 100644 game/data/radar_db.py diff --git a/game/data/radar_db.py b/game/data/radar_db.py deleted file mode 100644 index a8bec9b4..00000000 --- a/game/data/radar_db.py +++ /dev/null @@ -1,72 +0,0 @@ -from dcs.ships import ( - Battlecruiser_1144_2_Pyotr_Velikiy, - Cruiser_1164_Moskva, - CVN_70_Carl_Vinson, - CVN_71_Theodore_Roosevelt, - CVN_72_Abraham_Lincoln, - CVN_73_George_Washington, - CVN_74_John_C__Stennis, - CV_1143_5_Admiral_Kuznetsov, - CV_1143_5_Admiral_Kuznetsov_2017, - Frigate_11540_Neustrashimy, - Corvette_1124_4_Grisha, - Frigate_1135M_Rezky, - Corvette_1241_1_Molniya, - LHA_1_Tarawa, - FFG_Oliver_Hazzard_Perry, - CG_Ticonderoga, - Type_052B_Destroyer, - Type_052C_Destroyer, - Type_054A_Frigate, - DDG_Arleigh_Burke_IIa, -) -from dcs.vehicles import AirDefence - -UNITS_WITH_RADAR = [ - # Radars - AirDefence.SAM_SA_15_Tor_Gauntlet, - AirDefence.SAM_SA_11_Buk_Gadfly_C2, - AirDefence.SAM_Patriot_CR__AMG_AN_MRC_137, - AirDefence.SAM_Patriot_ECS, - AirDefence.SPAAA_Gepard, - AirDefence.SPAAA_Vulcan_M163, - AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish, - AirDefence.EWR_1L13, - AirDefence.SAM_SA_6_Kub_Straight_Flush_STR, - AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR, - AirDefence.SAM_SA_10_S_300_Grumble_Clam_Shell_SR, - AirDefence.EWR_55G6, - AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR, - AirDefence.SAM_SA_11_Buk_Gadfly_Snow_Drift_SR, - AirDefence.MCC_SR_Sborka_Dog_Ear_SR, - AirDefence.SAM_Hawk_TR__AN_MPQ_46, - AirDefence.SAM_Hawk_SR__AN_MPQ_50, - AirDefence.SAM_Patriot_STR, - AirDefence.SAM_Hawk_CWAR_AN_MPQ_55, - AirDefence.SAM_P19_Flat_Face_SR__SA_2_3, - AirDefence.SAM_Roland_EWR, - AirDefence.SAM_SA_3_S_125_Low_Blow_TR, - AirDefence.SAM_SA_2_S_75_Fan_Song_TR, - AirDefence.HQ_7_Self_Propelled_STR, - # Ships - CVN_70_Carl_Vinson, - FFG_Oliver_Hazzard_Perry, - CG_Ticonderoga, - Corvette_1124_4_Grisha, - CV_1143_5_Admiral_Kuznetsov, - Corvette_1241_1_Molniya, - Cruiser_1164_Moskva, - Frigate_11540_Neustrashimy, - Battlecruiser_1144_2_Pyotr_Velikiy, - Frigate_1135M_Rezky, - CV_1143_5_Admiral_Kuznetsov_2017, - CVN_74_John_C__Stennis, - CVN_71_Theodore_Roosevelt, - CVN_72_Abraham_Lincoln, - CVN_73_George_Washington, - DDG_Arleigh_Burke_IIa, - LHA_1_Tarawa, - Type_052B_Destroyer, - Type_054A_Frigate, - Type_052C_Destroyer, -] diff --git a/game/theater/theatergroundobject.py b/game/theater/theatergroundobject.py index 7675b256..29a7355b 100644 --- a/game/theater/theatergroundobject.py +++ b/game/theater/theatergroundobject.py @@ -10,7 +10,6 @@ from dcs.unit import Unit from dcs.unitgroup import Group from .. import db -from ..data.radar_db import UNITS_WITH_RADAR from ..utils import Distance, meters if TYPE_CHECKING: @@ -141,7 +140,15 @@ class TheaterGroundObject(MissionTarget): """Returns True if the ground object contains a unit with radar.""" for group in self.groups: for unit in group.units: - if db.unit_type_from_name(unit.type) in UNITS_WITH_RADAR: + unit_type = db.unit_type_from_name(unit.type) + if unit_type is None: + logging.error(f"Unknown unit type {unit.type}") + continue + + # Some units in pydcs have detection_range/threat_range defined, but + # explicitly set to None. Others do not define it at all. + unit_range = getattr(unit_type, "detection_range", None) + if unit_range is not None: return True return False @@ -156,8 +163,8 @@ class TheaterGroundObject(MissionTarget): logging.error(f"Unknown unit type {u.type}") continue - # Some units in pydcs have detection_range/threat_range defined, - # but explicitly set to None. + # Some units in pydcs have detection_range/threat_range defined, but + # explicitly set to None. Others do not define it at all. unit_range = getattr(unit, range_type, None) if unit_range is not None: max_range = max(max_range, meters(unit_range)) diff --git a/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py b/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py index 3cd46bf9..1353bf1c 100644 --- a/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py +++ b/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py @@ -1,7 +1,6 @@ from PySide2.QtGui import QStandardItem, QStandardItemModel from game import Game -from game.data.radar_db import UNITS_WITH_RADAR from gen import db from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox @@ -45,21 +44,18 @@ class QSEADTargetSelectionComboBox(QFilteredComboBox): for g in cp.ground_objects: radars = [] - detection_range = 0 + max_detection_range = 0 threat_range = 0 if g.dcs_identifier == "AA": for group in g.groups: for u in group.units: utype = db.unit_type_from_name(u.type) - - if utype in UNITS_WITH_RADAR: - if ( - hasattr(utype, "detection_range") - and utype.detection_range > 1000 - ): - if utype.detection_range > detection_range: - detection_range = utype.detection_range - radars.append(u) + detection_range = getattr(utype, "detection_range", 0) + if detection_range > 1000: + max_detection_range = max( + detection_range, max_detection_range + ) + radars.append(u) if hasattr(utype, "threat_range"): if utype.threat_range > threat_range: @@ -81,7 +77,7 @@ class QSEADTargetSelectionComboBox(QFilteredComboBox): tgt_info.radars = radars tgt_info.location = g tgt_info.threat_range = threat_range - tgt_info.detection_range = detection_range + tgt_info.detection_range = max_detection_range i = add_model_item(i, model, tgt_info) self.setModel(model) From a789f58068aeaabbc88abad7540e31b90c1884ff Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 15:37:31 -0700 Subject: [PATCH 015/122] Allow SEAD escorts against broken SAMs and EWRs. --- gen/flights/ai_flight_planner.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 92c55470..5105bf56 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -629,8 +629,22 @@ class CoalitionMissionPlanner: # Only include SEAD against SAMs that still have emitters. No need to # suppress an EWR, and SEAD isn't useful against a SAM that no longer has a # radar. + # + # For SAMs without radar and EWRs, we still want a SEAD escort if needed. + # + # Note that there is a quirk here: we should potentially be included a SEAD + # escort *and* SEAD when the target is a radar SAM but the flight path is + # also threatened by SAMs. We don't want to include a SEAD escort if the + # package is *only* threatened by the target though. Could be improved, but + # needs a decent refactor to the escort planning to do so. if isinstance(sam, SamGroundObject) and sam.has_alive_radar: flights.append(ProposedFlight(FlightType.SEAD, 2, self.MAX_SEAD_RANGE)) + else: + flights.append( + ProposedFlight( + FlightType.SEAD_ESCORT, 2, self.MAX_SEAD_RANGE, EscortType.Sead + ) + ) # TODO: Max escort range. flights.append( ProposedFlight( From 69299d395cff56ae842927e215f1b8b14175937e Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 16:14:20 -0700 Subject: [PATCH 016/122] 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. --- changelog.md | 1 + game/db.py | 36 ++++++++++++++++++++++++++++++++++++ gen/aircraft.py | 48 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index 7f3a60aa..c9c6f08f 100644 --- a/changelog.md +++ b/changelog.md @@ -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. diff --git a/game/db.py b/game/db.py index 2f297cbf..662abb04 100644 --- a/game/db.py +++ b/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, +] diff --git a/gen/aircraft.py b/gen/aircraft.py index 77c32e8a..360faa97 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -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, From fc5664263179868eaffea21a9efea25532470890 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 16:15:29 -0700 Subject: [PATCH 017/122] Fix default mission length in the UI too. --- qt_ui/windows/newgame/QNewGameWizard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt_ui/windows/newgame/QNewGameWizard.py b/qt_ui/windows/newgame/QNewGameWizard.py index 6cd28379..cd08a4a0 100644 --- a/qt_ui/windows/newgame/QNewGameWizard.py +++ b/qt_ui/windows/newgame/QNewGameWizard.py @@ -32,7 +32,7 @@ jinja_env = Environment( ) DEFAULT_BUDGET = 2000 -DEFAULT_MISSION_LENGTH: timedelta = timedelta(minutes=90) +DEFAULT_MISSION_LENGTH: timedelta = timedelta(minutes=60) class NewGameWizard(QtWidgets.QWizard): From bcdefda0db9ffeaf6e4be52cfd7a9d8eeca30a37 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 16:36:57 -0700 Subject: [PATCH 018/122] Make the F-15E CAS loadout less empty. --- resources/customized_payloads/F-15E.lua | 79 +++++++++++++++---------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/resources/customized_payloads/F-15E.lua b/resources/customized_payloads/F-15E.lua index 77955c5f..2f71ae0f 100644 --- a/resources/customized_payloads/F-15E.lua +++ b/resources/customized_payloads/F-15E.lua @@ -2,71 +2,88 @@ local unitPayloads = { ["name"] = "F-15E", ["payloads"] = { [1] = { - ["name"] = "CAS", + ["displayName"] = "Liberation CAS", + ["name"] = "Liberation CAS", ["pylons"] = { [1] = { - ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}", - ["num"] = 1, + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 18, }, [2] = { + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 2, + }, + [3] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 1, + }, + [4] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", ["num"] = 3, }, - [3] = { - ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}", - ["num"] = 4, - }, - [4] = { - ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}", - ["num"] = 6, - }, [5] = { - ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}", - ["num"] = 7, + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 17, }, [6] = { - ["CLSID"] = "{GBU-38}", - ["num"] = 9, + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 19, }, [7] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}", ["num"] = 10, }, [8] = { - ["CLSID"] = "{GBU-38}", + ["CLSID"] = "{CBU_105}", ["num"] = 11, }, [9] = { - ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}", - ["num"] = 13, + ["CLSID"] = "{CBU_105}", + ["num"] = 9, }, [10] = { - ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}", - ["num"] = 14, + ["CLSID"] = "{CBU_105}", + ["num"] = 8, }, [11] = { - ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}", - ["num"] = 16, + ["CLSID"] = "{CBU_105}", + ["num"] = 7, }, [12] = { - ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}", - ["num"] = 19, + ["CLSID"] = "{CBU_105}", + ["num"] = 12, }, [13] = { - ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", - ["num"] = 17, + ["CLSID"] = "{CBU_105}", + ["num"] = 13, }, [14] = { - ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", - ["num"] = 18, + ["CLSID"] = "{Mk82AIR}", + ["num"] = 6, }, [15] = { - ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", - ["num"] = 2, + ["CLSID"] = "{Mk82AIR}", + ["num"] = 5, + }, + [16] = { + ["CLSID"] = "{Mk82AIR}", + ["num"] = 4, + }, + [17] = { + ["CLSID"] = "{Mk82AIR}", + ["num"] = 14, + }, + [18] = { + ["CLSID"] = "{Mk82AIR}", + ["num"] = 15, + }, + [19] = { + ["CLSID"] = "{Mk82AIR}", + ["num"] = 16, }, }, ["tasks"] = { - [1] = 32, + [1] = 31, }, }, [2] = { From 7223ae327a982767cfbaeb1d577b064104967cf8 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 16:44:34 -0700 Subject: [PATCH 019/122] Add DEAD loadout for the F-16. --- resources/customized_payloads/F-16C_50.lua | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/resources/customized_payloads/F-16C_50.lua b/resources/customized_payloads/F-16C_50.lua index 285bccf3..9557e30c 100644 --- a/resources/customized_payloads/F-16C_50.lua +++ b/resources/customized_payloads/F-16C_50.lua @@ -220,6 +220,55 @@ local unitPayloads = { ["tasks"] = { }, }, + [6] = { + ["displayName"] = "Liberation DEAD", + ["name"] = "Liberation DEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 2, + }, + [3] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 9, + }, + [4] = { + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 8, + }, + [5] = { + ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}", + ["num"] = 7, + }, + [6] = { + ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}", + ["num"] = 6, + }, + [7] = { + ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}", + ["num"] = 3, + }, + [8] = { + ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}", + ["num"] = 4, + }, + [9] = { + ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}", + ["num"] = 11, + }, + [10] = { + ["CLSID"] = "", + ["num"] = 5, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, }, ["unitType"] = "F-16C_50", } From 1b624e7e6fc2246170c64250c595df4dde3b4831 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 16:31:20 -0700 Subject: [PATCH 020/122] Remove center tank for F-16 loadouts. --- resources/customized_payloads/F-16C_50.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/customized_payloads/F-16C_50.lua b/resources/customized_payloads/F-16C_50.lua index 9557e30c..8d9b3fbf 100644 --- a/resources/customized_payloads/F-16C_50.lua +++ b/resources/customized_payloads/F-16C_50.lua @@ -5,7 +5,7 @@ local unitPayloads = { ["name"] = "CAS", ["pylons"] = { [1] = { - ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}", + ["CLSID"] = "", ["num"] = 5, }, [2] = { @@ -80,7 +80,7 @@ local unitPayloads = { ["num"] = 11, }, [8] = { - ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}", + ["CLSID"] = "", ["num"] = 5, }, }, @@ -91,7 +91,7 @@ local unitPayloads = { ["name"] = "CAP", ["pylons"] = { [1] = { - ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}", + ["CLSID"] = "", ["num"] = 5, }, [2] = { @@ -166,7 +166,7 @@ local unitPayloads = { ["num"] = 1, }, [9] = { - ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}", + ["CLSID"] = "", ["num"] = 5, }, [10] = { @@ -197,7 +197,7 @@ local unitPayloads = { ["num"] = 3, }, [5] = { - ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}", + ["CLSID"] = "", ["num"] = 5, }, [6] = { From 1087069277dde9e84392d8e3d81485a6ac286b39 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 16:48:39 -0700 Subject: [PATCH 021/122] Fix F-14 SEAD/DEAD loadouts. The AI doesn't use mixed loadouts effectively (only the TALDs get used and the flight returns home with a full bomb load): https://forums.eagle.ru/topic/271941-ai-rtbs-after-firing-decoys-despite-full-load-of-bombs/ This makes the SEAD loadout TALDs only and the DEAD loadout bombs only. --- .../customized_payloads/F-14A-135-GR.lua | 197 +++++++++--------- resources/customized_payloads/F-14B.lua | 148 ++++++++----- 2 files changed, 196 insertions(+), 149 deletions(-) diff --git a/resources/customized_payloads/F-14A-135-GR.lua b/resources/customized_payloads/F-14A-135-GR.lua index 9926af41..e50d9798 100644 --- a/resources/customized_payloads/F-14A-135-GR.lua +++ b/resources/customized_payloads/F-14A-135-GR.lua @@ -98,102 +98,6 @@ local unitPayloads = { }, }, [3] = { - ["name"] = "SEAD", - ["pylons"] = { - [1] = { - ["CLSID"] = "{LAU-138 wtip - AIM-9M}", - ["num"] = 10, - }, - [2] = { - ["CLSID"] = "{LAU-138 wtip - AIM-9M}", - ["num"] = 1, - }, - [3] = { - ["CLSID"] = "{SHOULDER AIM_54C_Mk47 R}", - ["num"] = 9, - }, - [4] = { - ["CLSID"] = "{SHOULDER AIM_54C_Mk47 L}", - ["num"] = 2, - }, - [5] = { - ["CLSID"] = "{F14-300gal}", - ["num"] = 8, - }, - [6] = { - ["CLSID"] = "{F14-300gal}", - ["num"] = 3, - }, - [7] = { - ["CLSID"] = "{BRU3242_ADM141}", - ["num"] = 7, - }, - [8] = { - ["CLSID"] = "{BRU3242_ADM141}", - ["num"] = 4, - }, - [9] = { - ["CLSID"] = "{BRU3242_ADM141}", - ["num"] = 6, - }, - [10] = { - ["CLSID"] = "{BRU3242_ADM141}", - ["num"] = 5, - }, - }, - ["tasks"] = { - [1] = 10, - }, - }, - [4] = { - ["name"] = "DEAD", - ["pylons"] = { - [1] = { - ["CLSID"] = "{LAU-138 wtip - AIM-9M}", - ["num"] = 10, - }, - [2] = { - ["CLSID"] = "{LAU-138 wtip - AIM-9M}", - ["num"] = 1, - }, - [3] = { - ["CLSID"] = "{F14-LANTIRN-TP}", - ["num"] = 9, - }, - [4] = { - ["CLSID"] = "{PHXBRU3242_2*LAU10 LS}", - ["num"] = 2, - }, - [5] = { - ["CLSID"] = "{F14-300gal}", - ["num"] = 8, - }, - [6] = { - ["CLSID"] = "{F14-300gal}", - ["num"] = 3, - }, - [7] = { - ["CLSID"] = "{BRU-32 GBU-12}", - ["num"] = 7, - }, - [8] = { - ["CLSID"] = "{BRU-32 GBU-12}", - ["num"] = 4, - }, - [9] = { - ["CLSID"] = "{BRU-32 GBU-12}", - ["num"] = 6, - }, - [10] = { - ["CLSID"] = "{BRU-32 GBU-12}", - ["num"] = 5, - }, - }, - ["tasks"] = { - [1] = 10, - }, - }, - [5] = { ["name"] = "STRIKE", ["pylons"] = { [1] = { @@ -241,7 +145,7 @@ local unitPayloads = { [1] = 10, }, }, - [6] = { + [4] = { ["name"] = "BAI", ["pylons"] = { [1] = { @@ -289,7 +193,7 @@ local unitPayloads = { [1] = 10, }, }, - [7] = { + [5] = { ["name"] = "ANTISHIP", ["pylons"] = { [1] = { @@ -337,6 +241,103 @@ local unitPayloads = { [1] = 10, }, }, + [6] = { + ["name"] = "Liberation DEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{LAU-138 wtip - AIM-9M}", + ["num"] = 10, + }, + [2] = { + ["CLSID"] = "{LAU-138 wtip - AIM-9M}", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "{SHOULDER AIM_54C_Mk47 L}", + ["num"] = 2, + }, + [4] = { + ["CLSID"] = "{SHOULDER AIM_54C_Mk47 R}", + ["num"] = 9, + }, + [5] = { + ["CLSID"] = "{F14-300gal}", + ["num"] = 8, + }, + [6] = { + ["CLSID"] = "{F14-300gal}", + ["num"] = 3, + }, + [7] = { + ["CLSID"] = "{MAK79_MK82 4}", + ["num"] = 7, + }, + [8] = { + ["CLSID"] = "{MAK79_MK82 3R}", + ["num"] = 6, + }, + [9] = { + ["CLSID"] = "{MAK79_MK82 3L}", + ["num"] = 5, + }, + [10] = { + ["CLSID"] = "{MAK79_MK82 4}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, + [7] = { + ["displayName"] = "Liberation SEAD", + ["name"] = "Liberation SEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{LAU-138 wtip - AIM-9M}", + ["num"] = 10, + }, + [2] = { + ["CLSID"] = "{LAU-138 wtip - AIM-9M}", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "{SHOULDER AIM_54C_Mk47 L}", + ["num"] = 2, + }, + [4] = { + ["CLSID"] = "{SHOULDER AIM_54C_Mk47 R}", + ["num"] = 9, + }, + [5] = { + ["CLSID"] = "{F14-300gal}", + ["num"] = 8, + }, + [6] = { + ["CLSID"] = "{F14-300gal}", + ["num"] = 3, + }, + [7] = { + ["CLSID"] = "{BRU3242_ADM141}", + ["num"] = 7, + }, + [8] = { + ["CLSID"] = "{BRU3242_ADM141}", + ["num"] = 6, + }, + [9] = { + ["CLSID"] = "{BRU3242_ADM141}", + ["num"] = 5, + }, + [10] = { + ["CLSID"] = "{BRU3242_ADM141}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, }, ["unitType"] = "F-14A-135-GR", } diff --git a/resources/customized_payloads/F-14B.lua b/resources/customized_payloads/F-14B.lua index 64cccde5..83391742 100644 --- a/resources/customized_payloads/F-14B.lua +++ b/resources/customized_payloads/F-14B.lua @@ -155,57 +155,6 @@ local unitPayloads = { }, }, [4] = { - ["name"] = "SEAD", - ["pylons"] = { - [1] = { - ["CLSID"] = "{LAU-138 wtip - AIM-9M}", - ["num"] = 10, - }, - [2] = { - ["CLSID"] = "{SHOULDER AIM_54C_Mk47 R}", - ["num"] = 9, - }, - [3] = { - ["CLSID"] = "{F14-300gal}", - ["num"] = 8, - }, - [4] = { - ["CLSID"] = "{BRU3242_ADM141}", - ["num"] = 7, - }, - [5] = { - ["CLSID"] = "{BRU-32 GBU-12}", - ["num"] = 6, - }, - [6] = { - ["CLSID"] = "{BRU-32 GBU-12}", - ["num"] = 5, - }, - [7] = { - ["CLSID"] = "{BRU3242_ADM141}", - ["num"] = 4, - }, - [8] = { - ["CLSID"] = "{F14-300gal}", - ["num"] = 3, - }, - [9] = { - ["CLSID"] = "{SHOULDER AIM_54C_Mk47 L}", - ["num"] = 2, - }, - [10] = { - ["CLSID"] = "{LAU-138 wtip - AIM-9M}", - ["num"] = 1, - }, - }, - ["tasks"] = { - [1] = 10, - [2] = 11, - [3] = 18, - [4] = 19, - }, - }, - [5] = { ["name"] = "ANTISHIP", ["pylons"] = { [1] = { @@ -256,6 +205,103 @@ local unitPayloads = { [4] = 19, }, }, + [5] = { + ["name"] = "Liberation DEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{LAU-138 wtip - AIM-9M}", + ["num"] = 10, + }, + [2] = { + ["CLSID"] = "{LAU-138 wtip - AIM-9M}", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "{SHOULDER AIM_54C_Mk47 L}", + ["num"] = 2, + }, + [4] = { + ["CLSID"] = "{SHOULDER AIM_54C_Mk47 R}", + ["num"] = 9, + }, + [5] = { + ["CLSID"] = "{F14-300gal}", + ["num"] = 8, + }, + [6] = { + ["CLSID"] = "{F14-300gal}", + ["num"] = 3, + }, + [7] = { + ["CLSID"] = "{MAK79_MK82 4}", + ["num"] = 7, + }, + [8] = { + ["CLSID"] = "{MAK79_MK82 3R}", + ["num"] = 6, + }, + [9] = { + ["CLSID"] = "{MAK79_MK82 3L}", + ["num"] = 5, + }, + [10] = { + ["CLSID"] = "{MAK79_MK82 4}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, + [6] = { + ["displayName"] = "Liberation SEAD", + ["name"] = "Liberation SEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{LAU-138 wtip - AIM-9M}", + ["num"] = 10, + }, + [2] = { + ["CLSID"] = "{LAU-138 wtip - AIM-9M}", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "{SHOULDER AIM_54C_Mk47 L}", + ["num"] = 2, + }, + [4] = { + ["CLSID"] = "{SHOULDER AIM_54C_Mk47 R}", + ["num"] = 9, + }, + [5] = { + ["CLSID"] = "{F14-300gal}", + ["num"] = 8, + }, + [6] = { + ["CLSID"] = "{F14-300gal}", + ["num"] = 3, + }, + [7] = { + ["CLSID"] = "{BRU3242_ADM141}", + ["num"] = 7, + }, + [8] = { + ["CLSID"] = "{BRU3242_ADM141}", + ["num"] = 6, + }, + [9] = { + ["CLSID"] = "{BRU3242_ADM141}", + ["num"] = 5, + }, + [10] = { + ["CLSID"] = "{BRU3242_ADM141}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, }, ["unitType"] = "F-14B", } From 16fff8d87a1fd184cbc31851bf16f2e83ab608e6 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 16:51:27 -0700 Subject: [PATCH 022/122] Fall back to SEAD loadout for SEAD escort. These usually do not need to differ. --- gen/flights/loadouts.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gen/flights/loadouts.py b/gen/flights/loadouts.py index c9ae20c4..bc19fa71 100644 --- a/gen/flights/loadouts.py +++ b/gen/flights/loadouts.py @@ -106,6 +106,9 @@ class Loadout: } for flight_type, names in legacy_names.items(): loadout_names[flight_type].extend(names) + # A SEAD escort typically does not need a different loadout than a regular + # SEAD flight, so fall back to SEAD if needed. + loadout_names[FlightType.SEAD_ESCORT].extend(loadout_names[FlightType.SEAD]) yield from loadout_names[flight.flight_type] @classmethod From 2df17c32cd37e8eaa32054eae18b47a7a99b7984 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 17:05:53 -0700 Subject: [PATCH 023/122] Clean up aircraft selector. --- qt_ui/widgets/combos/QAircraftTypeSelector.py | 76 +++---------------- .../windows/mission/flight/QFlightCreator.py | 2 +- 2 files changed, 11 insertions(+), 67 deletions(-) diff --git a/qt_ui/widgets/combos/QAircraftTypeSelector.py b/qt_ui/widgets/combos/QAircraftTypeSelector.py index e5919b3c..b7949aa2 100644 --- a/qt_ui/widgets/combos/QAircraftTypeSelector.py +++ b/qt_ui/widgets/combos/QAircraftTypeSelector.py @@ -2,15 +2,12 @@ from typing import Iterable, Type from PySide2.QtWidgets import QComboBox - from dcs.unittype import FlyingType +from game import db +from gen.flights.ai_flight_planner_db import aircraft_for_task from gen.flights.flight import FlightType -import gen.flights.ai_flight_planner_db - -from game import Game, db - class QAircraftTypeSelector(QComboBox): """Combo box for selecting among the given aircraft types.""" @@ -19,77 +16,24 @@ class QAircraftTypeSelector(QComboBox): self, aircraft_types: Iterable[Type[FlyingType]], country: str, - mission_type: str, + mission_type: FlightType, ) -> None: super().__init__() self.model().sort(0) self.setSizeAdjustPolicy(self.AdjustToContents) self.country = country - self.updateItems(mission_type, aircraft_types) + self.update_items(mission_type, aircraft_types) - def updateItems(self, mission_type: str, aircraft_types): + def update_items(self, mission_type: FlightType, aircraft_types): current_aircraft = self.currentData() self.clear() for aircraft in aircraft_types: - if mission_type in [ - FlightType.BARCAP, - FlightType.ESCORT, - FlightType.INTERCEPTION, - FlightType.SWEEP, - FlightType.TARCAP, - ]: - if aircraft in gen.flights.ai_flight_planner_db.CAP_CAPABLE: - self.addItem( - f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", - userData=aircraft, - ) - elif mission_type in [ - FlightType.CAS, - FlightType.BAI, - FlightType.OCA_AIRCRAFT, - ]: - if aircraft in gen.flights.ai_flight_planner_db.CAS_CAPABLE: - self.addItem( - f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", - userData=aircraft, - ) - elif mission_type in [FlightType.SEAD]: - if aircraft in gen.flights.ai_flight_planner_db.SEAD_CAPABLE: - self.addItem( - f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", - userData=aircraft, - ) - elif mission_type in [FlightType.DEAD]: - if aircraft in gen.flights.ai_flight_planner_db.DEAD_CAPABLE: - self.addItem( - f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", - userData=aircraft, - ) - elif mission_type in [FlightType.STRIKE]: - if aircraft in gen.flights.ai_flight_planner_db.STRIKE_CAPABLE: - self.addItem( - f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", - userData=aircraft, - ) - elif mission_type in [FlightType.ANTISHIP]: - if aircraft in gen.flights.ai_flight_planner_db.ANTISHIP_CAPABLE: - self.addItem( - f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", - userData=aircraft, - ) - elif mission_type in [FlightType.OCA_RUNWAY]: - if aircraft in gen.flights.ai_flight_planner_db.RUNWAY_ATTACK_CAPABLE: - self.addItem( - f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", - userData=aircraft, - ) - elif mission_type in [FlightType.AEWC]: - if aircraft in gen.flights.ai_flight_planner_db.AEWC_CAPABLE: - self.addItem( - f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", - userData=aircraft, - ) + if aircraft in aircraft_for_task(mission_type): + self.addItem( + f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}", + userData=aircraft, + ) current_aircraft_index = self.findData(current_aircraft) if current_aircraft_index != -1: self.setCurrentIndex(current_aircraft_index) diff --git a/qt_ui/windows/mission/flight/QFlightCreator.py b/qt_ui/windows/mission/flight/QFlightCreator.py index f4aa743c..bf388e36 100644 --- a/qt_ui/windows/mission/flight/QFlightCreator.py +++ b/qt_ui/windows/mission/flight/QFlightCreator.py @@ -211,7 +211,7 @@ class QFlightCreator(QDialog): self.restore_start_type = None def on_task_changed(self) -> None: - self.aircraft_selector.updateItems( + self.aircraft_selector.update_items( self.task_selector.currentData(), self.game.aircraft_inventory.available_types_for_player, ) From 2f6ab6d2b03bcac3ebad5d694fa6db422c26c72b Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 17:06:09 -0700 Subject: [PATCH 024/122] Update Hornet loadouts, add DEAD loadout. --- .../customized_payloads/FA-18C_hornet.lua | 67 ++++++++++++++----- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/resources/customized_payloads/FA-18C_hornet.lua b/resources/customized_payloads/FA-18C_hornet.lua index f3020cef..64b8fb5a 100644 --- a/resources/customized_payloads/FA-18C_hornet.lua +++ b/resources/customized_payloads/FA-18C_hornet.lua @@ -206,15 +206,16 @@ local unitPayloads = { }, }, [6] = { - ["name"] = "SEAD", + ["displayName"] = "Liberation SEAD", + ["name"] = "Liberation SEAD", ["pylons"] = { [1] = { - ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}", - ["num"] = 7, + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 9, }, [2] = { - ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}", - ["num"] = 8, + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 1, }, [3] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", @@ -226,27 +227,23 @@ local unitPayloads = { }, [5] = { ["CLSID"] = "{FPU_8A_FUEL_TANK}", - ["num"] = 5, + ["num"] = 3, }, [6] = { - ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}", - ["num"] = 3, + ["CLSID"] = "{FPU_8A_FUEL_TANK}", + ["num"] = 7, }, [7] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}", ["num"] = 2, }, [8] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 1, - }, - [9] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 9, + ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}", + ["num"] = 8, }, }, ["tasks"] = { - [1] = 11, + [1] = 29, }, }, [7] = { @@ -293,6 +290,46 @@ local unitPayloads = { [1] = 34, }, }, + [8] = { + ["name"] = "Liberation DEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 9, + }, + [2] = { + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 6, + }, + [4] = { + ["CLSID"] = "{FPU_8A_FUEL_TANK}", + ["num"] = 7, + }, + [5] = { + ["CLSID"] = "{FPU_8A_FUEL_TANK}", + ["num"] = 3, + }, + [6] = { + ["CLSID"] = "{BRU55_2*AGM-154A}", + ["num"] = 8, + }, + [7] = { + ["CLSID"] = "{BRU55_2*AGM-154A}", + ["num"] = 2, + }, + [8] = { + ["CLSID"] = "{AN_ASQ_228}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + }, + }, }, ["tasks"] = { }, From 43cd9bce67709dd59eb6c18d8f7236ab57d5cfd6 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 19:13:57 -0700 Subject: [PATCH 025/122] Fix cargo ship locations in Abu Dhabi. Apparently these ships have a > 32ft draft and these ports are shallow. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1104 --- resources/campaigns/battle_of_abu_dhabi.miz | Bin 44783 -> 44795 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/campaigns/battle_of_abu_dhabi.miz b/resources/campaigns/battle_of_abu_dhabi.miz index a31881ef9d52d1c5cc3eb323c9bd0afbf5c01a35..2af6ab2f9594560a35f19f1b0995113dd4b00a99 100644 GIT binary patch delta 26287 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̴FiZ@Fg_3S56g=e!#oYLr2PHwhpVD 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 bHqoq11hpeEwM-CIGjX(x1~a(yUhw|_eSp!- delta 26307 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 B^mhON From c3802e5a3725fe81e55b772a71420340d8e06e6b Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 19:35:56 -0700 Subject: [PATCH 026/122] Make UI created packages ASAP by default. --- qt_ui/windows/mission/QPackageDialog.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qt_ui/windows/mission/QPackageDialog.py b/qt_ui/windows/mission/QPackageDialog.py index 444fc33b..ef915f8c 100644 --- a/qt_ui/windows/mission/QPackageDialog.py +++ b/qt_ui/windows/mission/QPackageDialog.py @@ -215,7 +215,9 @@ class QNewPackageDialog(QPackageDialog): self, game_model: GameModel, model: AtoModel, target: MissionTarget, parent=None ) -> None: super().__init__( - game_model, PackageModel(Package(target), game_model), parent=parent + game_model, + PackageModel(Package(target, auto_asap=True), game_model), + parent=parent, ) self.ato_model = model From 7450a6b7ebb34dd426584fb6d08d3b78b31b31db Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 20:12:56 -0700 Subject: [PATCH 027/122] Configure more loadout fallbacks. --- gen/flights/loadouts.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/gen/flights/loadouts.py b/gen/flights/loadouts.py index bc19fa71..2cfb70d9 100644 --- a/gen/flights/loadouts.py +++ b/gen/flights/loadouts.py @@ -90,25 +90,33 @@ class Loadout: # etc. loadout_names = {t: [f"Liberation {t.value}"] for t in FlightType} legacy_names = { - FlightType.TARCAP: ("CAP HEAVY", "CAP"), - FlightType.BARCAP: ("CAP HEAVY", "CAP"), + FlightType.TARCAP: ("CAP HEAVY", "CAP", "Liberation BARCAP"), + FlightType.BARCAP: ("CAP HEAVY", "CAP", "Liberation TARCAP"), FlightType.CAS: ("CAS MAVERICK F", "CAS"), - FlightType.INTERCEPTION: ("CAP HEAVY", "CAP"), FlightType.STRIKE: ("STRIKE",), FlightType.ANTISHIP: ("ANTISHIP",), FlightType.SEAD: ("SEAD",), - FlightType.DEAD: ("SEAD",), - FlightType.ESCORT: ("CAP HEAVY", "CAP"), - FlightType.BAI: ("BAI", "CAS MAVERICK F", "CAS"), - FlightType.SWEEP: ("CAP HEAVY", "CAP"), - FlightType.OCA_RUNWAY: ("RUNWAY_ATTACK", "RUNWAY_STRIKE", "STRIKE"), - FlightType.OCA_AIRCRAFT: ("OCA", "CAS MAVERICK F", "CAS"), + FlightType.BAI: ("BAI",), + FlightType.OCA_RUNWAY: ("RUNWAY_ATTACK", "RUNWAY_STRIKE"), + FlightType.OCA_AIRCRAFT: ("OCA",), } for flight_type, names in legacy_names.items(): loadout_names[flight_type].extend(names) # A SEAD escort typically does not need a different loadout than a regular # SEAD flight, so fall back to SEAD if needed. loadout_names[FlightType.SEAD_ESCORT].extend(loadout_names[FlightType.SEAD]) + # Sweep and escort can fall back to TARCAP. + loadout_names[FlightType.ESCORT].extend(loadout_names[FlightType.TARCAP]) + loadout_names[FlightType.SWEEP].extend(loadout_names[FlightType.TARCAP]) + # Intercept can fall back to BARCAP. + loadout_names[FlightType.INTERCEPTION].extend(loadout_names[FlightType.BARCAP]) + # OCA/Aircraft falls back to BAI, which falls back to CAS. + loadout_names[FlightType.BAI].extend(loadout_names[FlightType.CAS]) + loadout_names[FlightType.OCA_AIRCRAFT].extend(loadout_names[FlightType.BAI]) + # DEAD also falls back to BAI. + loadout_names[FlightType.DEAD].extend(loadout_names[FlightType.BAI]) + # OCA/Runway falls back to Strike + loadout_names[FlightType.OCA_RUNWAY].extend(loadout_names[FlightType.STRIKE]) yield from loadout_names[flight.flight_type] @classmethod From 98e0be6be9884b6b01a27595033a4bf409a2f820 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 01:10:29 -0700 Subject: [PATCH 028/122] Revert "Correct radar detection." We need this after all, but we do need to audit the list. Will follow up with that fix. https://github.com/dcs-liberation/dcs_liberation/issues/1109 This reverts commit f68935735d436385a0821e1168a8726c7dba8ebb. --- game/data/radar_db.py | 72 +++++++++++++++++++ game/theater/theatergroundobject.py | 15 ++-- .../combos/QSEADTargetSelectionComboBox.py | 20 +++--- 3 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 game/data/radar_db.py diff --git a/game/data/radar_db.py b/game/data/radar_db.py new file mode 100644 index 00000000..a8bec9b4 --- /dev/null +++ b/game/data/radar_db.py @@ -0,0 +1,72 @@ +from dcs.ships import ( + Battlecruiser_1144_2_Pyotr_Velikiy, + Cruiser_1164_Moskva, + CVN_70_Carl_Vinson, + CVN_71_Theodore_Roosevelt, + CVN_72_Abraham_Lincoln, + CVN_73_George_Washington, + CVN_74_John_C__Stennis, + CV_1143_5_Admiral_Kuznetsov, + CV_1143_5_Admiral_Kuznetsov_2017, + Frigate_11540_Neustrashimy, + Corvette_1124_4_Grisha, + Frigate_1135M_Rezky, + Corvette_1241_1_Molniya, + LHA_1_Tarawa, + FFG_Oliver_Hazzard_Perry, + CG_Ticonderoga, + Type_052B_Destroyer, + Type_052C_Destroyer, + Type_054A_Frigate, + DDG_Arleigh_Burke_IIa, +) +from dcs.vehicles import AirDefence + +UNITS_WITH_RADAR = [ + # Radars + AirDefence.SAM_SA_15_Tor_Gauntlet, + AirDefence.SAM_SA_11_Buk_Gadfly_C2, + AirDefence.SAM_Patriot_CR__AMG_AN_MRC_137, + AirDefence.SAM_Patriot_ECS, + AirDefence.SPAAA_Gepard, + AirDefence.SPAAA_Vulcan_M163, + AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish, + AirDefence.EWR_1L13, + AirDefence.SAM_SA_6_Kub_Straight_Flush_STR, + AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR, + AirDefence.SAM_SA_10_S_300_Grumble_Clam_Shell_SR, + AirDefence.EWR_55G6, + AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR, + AirDefence.SAM_SA_11_Buk_Gadfly_Snow_Drift_SR, + AirDefence.MCC_SR_Sborka_Dog_Ear_SR, + AirDefence.SAM_Hawk_TR__AN_MPQ_46, + AirDefence.SAM_Hawk_SR__AN_MPQ_50, + AirDefence.SAM_Patriot_STR, + AirDefence.SAM_Hawk_CWAR_AN_MPQ_55, + AirDefence.SAM_P19_Flat_Face_SR__SA_2_3, + AirDefence.SAM_Roland_EWR, + AirDefence.SAM_SA_3_S_125_Low_Blow_TR, + AirDefence.SAM_SA_2_S_75_Fan_Song_TR, + AirDefence.HQ_7_Self_Propelled_STR, + # Ships + CVN_70_Carl_Vinson, + FFG_Oliver_Hazzard_Perry, + CG_Ticonderoga, + Corvette_1124_4_Grisha, + CV_1143_5_Admiral_Kuznetsov, + Corvette_1241_1_Molniya, + Cruiser_1164_Moskva, + Frigate_11540_Neustrashimy, + Battlecruiser_1144_2_Pyotr_Velikiy, + Frigate_1135M_Rezky, + CV_1143_5_Admiral_Kuznetsov_2017, + CVN_74_John_C__Stennis, + CVN_71_Theodore_Roosevelt, + CVN_72_Abraham_Lincoln, + CVN_73_George_Washington, + DDG_Arleigh_Burke_IIa, + LHA_1_Tarawa, + Type_052B_Destroyer, + Type_054A_Frigate, + Type_052C_Destroyer, +] diff --git a/game/theater/theatergroundobject.py b/game/theater/theatergroundobject.py index 29a7355b..7675b256 100644 --- a/game/theater/theatergroundobject.py +++ b/game/theater/theatergroundobject.py @@ -10,6 +10,7 @@ from dcs.unit import Unit from dcs.unitgroup import Group from .. import db +from ..data.radar_db import UNITS_WITH_RADAR from ..utils import Distance, meters if TYPE_CHECKING: @@ -140,15 +141,7 @@ class TheaterGroundObject(MissionTarget): """Returns True if the ground object contains a unit with radar.""" for group in self.groups: for unit in group.units: - unit_type = db.unit_type_from_name(unit.type) - if unit_type is None: - logging.error(f"Unknown unit type {unit.type}") - continue - - # Some units in pydcs have detection_range/threat_range defined, but - # explicitly set to None. Others do not define it at all. - unit_range = getattr(unit_type, "detection_range", None) - if unit_range is not None: + if db.unit_type_from_name(unit.type) in UNITS_WITH_RADAR: return True return False @@ -163,8 +156,8 @@ class TheaterGroundObject(MissionTarget): logging.error(f"Unknown unit type {u.type}") continue - # Some units in pydcs have detection_range/threat_range defined, but - # explicitly set to None. Others do not define it at all. + # Some units in pydcs have detection_range/threat_range defined, + # but explicitly set to None. unit_range = getattr(unit, range_type, None) if unit_range is not None: max_range = max(max_range, meters(unit_range)) diff --git a/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py b/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py index 1353bf1c..3cd46bf9 100644 --- a/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py +++ b/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py @@ -1,6 +1,7 @@ from PySide2.QtGui import QStandardItem, QStandardItemModel from game import Game +from game.data.radar_db import UNITS_WITH_RADAR from gen import db from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox @@ -44,18 +45,21 @@ class QSEADTargetSelectionComboBox(QFilteredComboBox): for g in cp.ground_objects: radars = [] - max_detection_range = 0 + detection_range = 0 threat_range = 0 if g.dcs_identifier == "AA": for group in g.groups: for u in group.units: utype = db.unit_type_from_name(u.type) - detection_range = getattr(utype, "detection_range", 0) - if detection_range > 1000: - max_detection_range = max( - detection_range, max_detection_range - ) - radars.append(u) + + if utype in UNITS_WITH_RADAR: + if ( + hasattr(utype, "detection_range") + and utype.detection_range > 1000 + ): + if utype.detection_range > detection_range: + detection_range = utype.detection_range + radars.append(u) if hasattr(utype, "threat_range"): if utype.threat_range > threat_range: @@ -77,7 +81,7 @@ class QSEADTargetSelectionComboBox(QFilteredComboBox): tgt_info.radars = radars tgt_info.location = g tgt_info.threat_range = threat_range - tgt_info.detection_range = max_detection_range + tgt_info.detection_range = detection_range i = add_model_item(i, model, tgt_info) self.setModel(model) From 5e68dbe1ca946363338304e55a6096d8d4abda14 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 01:20:01 -0700 Subject: [PATCH 029/122] Correct the list of units with radars. Probably. https://github.com/dcs-liberation/dcs_liberation/issues/1109 --- game/data/radar_db.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/game/data/radar_db.py b/game/data/radar_db.py index a8bec9b4..22891b8a 100644 --- a/game/data/radar_db.py +++ b/game/data/radar_db.py @@ -24,12 +24,13 @@ from dcs.vehicles import AirDefence UNITS_WITH_RADAR = [ # Radars + AirDefence.SAM_SA_19_Tunguska_Grison, + AirDefence.SAM_SA_11_Buk_Gadfly_Fire_Dome_TEL, + AirDefence.SAM_SA_8_Osa_Gecko_TEL, AirDefence.SAM_SA_15_Tor_Gauntlet, - AirDefence.SAM_SA_11_Buk_Gadfly_C2, - AirDefence.SAM_Patriot_CR__AMG_AN_MRC_137, - AirDefence.SAM_Patriot_ECS, AirDefence.SPAAA_Gepard, AirDefence.SPAAA_Vulcan_M163, + AirDefence.SAM_Roland_ADS, AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish, AirDefence.EWR_1L13, AirDefence.SAM_SA_6_Kub_Straight_Flush_STR, @@ -47,7 +48,11 @@ UNITS_WITH_RADAR = [ AirDefence.SAM_Roland_EWR, AirDefence.SAM_SA_3_S_125_Low_Blow_TR, AirDefence.SAM_SA_2_S_75_Fan_Song_TR, + AirDefence.SAM_Rapier_Blindfire_TR, + AirDefence.HQ_7_Self_Propelled_LN, AirDefence.HQ_7_Self_Propelled_STR, + AirDefence.EWR_FuMG_401_Freya_LZ, + AirDefence.EWR_FuSe_65_Würzburg_Riese, # Ships CVN_70_Carl_Vinson, FFG_Oliver_Hazzard_Perry, From eae0d6be9468f273c90f1a39e2b793865cde09c4 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 12:24:52 -0700 Subject: [PATCH 030/122] Add threat zone drawing for the new map. https://github.com/dcs-liberation/dcs_liberation/issues/1097 --- qt_ui/widgets/map/mapmodel.py | 101 ++++++++++++++++++++++++++++++++-- resources/ui/map/map.js | 89 +++++++++++++++++++++++++----- 2 files changed, 172 insertions(+), 18 deletions(-) diff --git a/qt_ui/widgets/map/mapmodel.py b/qt_ui/widgets/map/mapmodel.py index 4f82f533..27d2474e 100644 --- a/qt_ui/widgets/map/mapmodel.py +++ b/qt_ui/widgets/map/mapmodel.py @@ -2,13 +2,13 @@ from __future__ import annotations import logging from datetime import timedelta -from typing import List, Optional, Tuple +from typing import List, Optional, Tuple, Union from PySide2.QtCore import Property, QObject, Signal, Slot from dcs import Point from dcs.unit import Unit from dcs.vehicles import vehicle_map -from shapely.geometry import LineString, Point as ShapelyPoint, Polygon +from shapely.geometry import LineString, Point as ShapelyPoint, Polygon, MultiPolygon from game import Game, db from game.factions.faction import Faction @@ -19,9 +19,8 @@ from game.theater import ( TheaterGroundObject, FrontLine, LatLon, - Airfield, - Carrier, ) +from game.threatzones import ThreatZones from game.transfers import MultiGroupTransport, TransportMap from game.utils import meters, nautical_miles from gen.ato import AirTaskingOrder @@ -519,7 +518,7 @@ class FlightJs(QObject): return self._selected @Property(list, notify=commitBoundaryChanged) - def commitBoundary(self) -> Optional[List[LeafletLatLon]]: + def commitBoundary(self) -> List[LeafletLatLon]: if not isinstance(self.flight.flight_plan, PatrollingFlightPlan): return [] start = self.flight.flight_plan.patrol_start @@ -535,6 +534,75 @@ class FlightJs(QObject): return shapely_poly_to_leaflet_points(bubble, self.theater) +class ThreatZonesJs(QObject): + fullChanged = Signal() + aircraftChanged = Signal() + airDefensesChanged = Signal() + + def __init__( + self, + full: List[List[LeafletLatLon]], + aircraft: List[List[LeafletLatLon]], + air_defenses: List[List[LeafletLatLon]], + ) -> None: + super().__init__() + self._full = full + self._aircraft = aircraft + self._air_defenses = air_defenses + + @Property(list, notify=fullChanged) + def full(self) -> List[List[LeafletLatLon]]: + return self._full + + @Property(list, notify=aircraftChanged) + def aircraft(self) -> List[List[LeafletLatLon]]: + return self._aircraft + + @Property(list, notify=airDefensesChanged) + def airDefenses(self) -> List[List[LeafletLatLon]]: + return self._air_defenses + + @staticmethod + def polys_to_leaflet( + poly: Union[Polygon, MultiPolygon], theater: ConflictTheater + ) -> List[List[LeafletLatLon]]: + if isinstance(poly, MultiPolygon): + polys = poly.geoms + else: + polys = [poly] + return [shapely_poly_to_leaflet_points(poly, theater) for poly in polys] + + @classmethod + def from_zones(cls, zones: ThreatZones, theater: ConflictTheater) -> ThreatZonesJs: + return ThreatZonesJs( + cls.polys_to_leaflet(zones.all, theater), + cls.polys_to_leaflet(zones.airbases, theater), + cls.polys_to_leaflet(zones.air_defenses, theater), + ) + + @classmethod + def empty(cls) -> ThreatZonesJs: + return ThreatZonesJs([], [], []) + + +class ThreatZoneContainerJs(QObject): + blueChanged = Signal() + redChanged = Signal() + + def __init__(self, blue: ThreatZonesJs, red: ThreatZonesJs) -> None: + super().__init__() + self._blue = blue + self._red = red + + @Property(ThreatZonesJs, notify=blueChanged) + def blue(self) -> ThreatZonesJs: + return self._blue + + @Property(ThreatZonesJs, notify=redChanged) + def red(self) -> ThreatZonesJs: + return self._red + + class MapModel(QObject): cleared = Signal() @@ -544,6 +612,7 @@ class MapModel(QObject): supplyRoutesChanged = Signal() flightsChanged = Signal() frontLinesChanged = Signal() + threatZonesChanged = Signal() def __init__(self, game_model: GameModel) -> None: super().__init__() @@ -554,6 +623,9 @@ class MapModel(QObject): self._supply_routes = [] self._flights = [] self._front_lines = [] + self._threat_zones = ThreatZoneContainerJs( + ThreatZonesJs.empty(), ThreatZonesJs.empty() + ) self._selected_flight_index: Optional[Tuple[int, int]] = None GameUpdateSignal.get_instance().game_loaded.connect(self.on_game_load) GameUpdateSignal.get_instance().flight_paths_changed.connect(self.reset_atos) @@ -571,6 +643,9 @@ class MapModel(QObject): self._ground_objects = [] self._flights = [] self._front_lines = [] + self._threat_zones = ThreatZoneContainerJs( + ThreatZonesJs.empty(), ThreatZonesJs.empty() + ) self.cleared.emit() def set_package_selection(self, index: int) -> None: @@ -614,6 +689,7 @@ class MapModel(QObject): self.reset_routes() self.reset_atos() self.reset_front_lines() + self.reset_threat_zones() def on_game_load(self, game: Optional[Game]) -> None: if game is not None: @@ -737,6 +813,21 @@ class MapModel(QObject): def frontLines(self) -> List[FrontLineJs]: return self._front_lines + def reset_threat_zones(self) -> None: + self._threat_zones = ThreatZoneContainerJs( + ThreatZonesJs.from_zones( + self.game.threat_zone_for(player=True), self.game.theater + ), + ThreatZonesJs.from_zones( + self.game.threat_zone_for(player=False), self.game.theater + ), + ) + self.threatZonesChanged.emit() + + @Property(ThreatZoneContainerJs, notify=threatZonesChanged) + def threatZones(self) -> ThreatZoneContainerJs: + return self._threat_zones + @property def game(self) -> Game: if self.game_model.game is None: diff --git a/resources/ui/map/map.js b/resources/ui/map/map.js index a68c5716..a6d29c6c 100644 --- a/resources/ui/map/map.js +++ b/resources/ui/map/map.js @@ -1,15 +1,3 @@ -/* - * TODO: - * - * - Culling - * - Threat zones - * - Navmeshes - * - Time of day/weather themeing - * - Exclusion zones - * - "Actual" front line - * - Debug flight plan drawing - */ - const Colors = Object.freeze({ Blue: "#0084ff", Red: "#c85050", @@ -172,6 +160,14 @@ const redFlightPlansLayer = L.layerGroup(); const selectedFlightPlansLayer = L.layerGroup(); const allFlightPlansLayer = L.layerGroup(); +const blueFullThreatZones = L.layerGroup(); +const blueAircraftThreatZones = L.layerGroup(); +const blueAirDefenseThreatZones = L.layerGroup(); + +const redFullThreatZones = L.layerGroup(); +const redAircraftThreatZones = L.layerGroup(); +const redAirDefenseThreatZones = L.layerGroup(); + L.control .groupedLayers( baseLayers, @@ -197,8 +193,27 @@ L.control "Show all red": redFlightPlansLayer, "Show all": allFlightPlansLayer, }, + "Blue Threat Zones": { + Hide: L.layerGroup().addTo(map), + Full: blueFullThreatZones, + Aircraft: blueAircraftThreatZones, + "Air Defenses": blueAirDefenseThreatZones, + }, + "Red Threat Zones": { + Hide: L.layerGroup().addTo(map), + Full: redFullThreatZones, + Aircraft: redAircraftThreatZones, + "Air Defenses": redAirDefenseThreatZones, + }, }, - { collapsed: false, exclusiveGroups: ["Flight Plans"] } + { + collapsed: false, + exclusiveGroups: [ + "Flight Plans", + "Blue Threat Zones", + "Red Threat Zones", + ], + } ) .addTo(map); @@ -213,6 +228,7 @@ new QWebChannel(qt.webChannelTransport, function (channel) { game.supplyRoutesChanged.connect(drawSupplyRoutes); game.frontLinesChanged.connect(drawFrontLines); game.flightsChanged.connect(drawFlightPlans); + game.threatZonesChanged.connect(drawThreatZones); }); function recenterMap(center) { @@ -702,6 +718,52 @@ function drawFlightPlans() { } } +function _drawThreatZones(zones, layer, player) { + const color = player ? Colors.Blue : Colors.Red; + for (const zone of zones) { + L.polyline(zone, { + color: color, + weight: 1, + fill: true, + fillOpacity: 0.4, + noClip: true, + }).addTo(layer); + } +} + +function drawThreatZones() { + blueFullThreatZones.clearLayers(); + blueAircraftThreatZones.clearLayers(); + blueAirDefenseThreatZones.clearLayers(); + redFullThreatZones.clearLayers(); + redAircraftThreatZones.clearLayers(); + redAirDefenseThreatZones.clearLayers(); + + _drawThreatZones(game.threatZones.blue.full, blueFullThreatZones, true); + _drawThreatZones( + game.threatZones.blue.aircraft, + blueAircraftThreatZones, + true + ); + _drawThreatZones( + game.threatZones.blue.airDefenses, + blueAirDefenseThreatZones, + true + ); + + _drawThreatZones(game.threatZones.red.full, redFullThreatZones, false); + _drawThreatZones( + game.threatZones.red.aircraft, + redAircraftThreatZones, + false + ); + _drawThreatZones( + game.threatZones.red.airDefenses, + redAirDefenseThreatZones, + false + ); +} + function drawInitialMap() { recenterMap(game.mapCenter); drawControlPoints(); @@ -709,6 +771,7 @@ function drawInitialMap() { drawSupplyRoutes(); drawFrontLines(); drawFlightPlans(); + drawThreatZones(); } function clearAllLayers() { From ddd6e7d18f22de5471d5b9beb322fa81b9dea9bc Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 11:28:43 -0700 Subject: [PATCH 031/122] Improve detection of functional radar SAMs. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1109 --- game/data/radar_db.py | 35 +++++++++++++++++++-- game/theater/theatergroundobject.py | 49 +++++++++++++++++++++++------ game/threatzones.py | 30 ++++++++++++++++-- gen/flights/ai_flight_planner.py | 2 +- qt_ui/widgets/map/mapmodel.py | 10 +++++- resources/ui/map/map.js | 16 ++++++++++ 6 files changed, 126 insertions(+), 16 deletions(-) diff --git a/game/data/radar_db.py b/game/data/radar_db.py index 22891b8a..9bd384af 100644 --- a/game/data/radar_db.py +++ b/game/data/radar_db.py @@ -22,7 +22,38 @@ from dcs.ships import ( ) from dcs.vehicles import AirDefence -UNITS_WITH_RADAR = [ +TELARS = { + AirDefence.SAM_SA_19_Tunguska_Grison, + AirDefence.SAM_SA_11_Buk_Gadfly_Fire_Dome_TEL, + AirDefence.SAM_SA_8_Osa_Gecko_TEL, + AirDefence.SAM_SA_15_Tor_Gauntlet, + AirDefence.SAM_Roland_ADS, +} + +TRACK_RADARS = { + AirDefence.SAM_SA_6_Kub_Straight_Flush_STR, + AirDefence.SAM_SA_3_S_125_Low_Blow_TR, + AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR, + AirDefence.SAM_Hawk_TR__AN_MPQ_46, + AirDefence.SAM_Patriot_STR, + AirDefence.SAM_SA_2_S_75_Fan_Song_TR, + AirDefence.SAM_Rapier_Blindfire_TR, + AirDefence.HQ_7_Self_Propelled_STR, +} + +LAUNCHER_TRACKER_PAIRS = { + AirDefence.SAM_SA_6_Kub_Gainful_TEL: AirDefence.SAM_SA_6_Kub_Straight_Flush_STR, + AirDefence.SAM_SA_3_S_125_Goa_LN: AirDefence.SAM_SA_3_S_125_Low_Blow_TR, + AirDefence.SAM_SA_10_S_300_Grumble_TEL_D: AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR, + AirDefence.SAM_SA_10_S_300_Grumble_TEL_C: AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR, + AirDefence.SAM_Hawk_LN_M192: AirDefence.SAM_Hawk_TR__AN_MPQ_46, + AirDefence.SAM_Patriot_LN: AirDefence.SAM_Patriot_STR, + AirDefence.SAM_SA_2_S_75_Guideline_LN: AirDefence.SAM_SA_2_S_75_Fan_Song_TR, + AirDefence.SAM_Rapier_LN: AirDefence.SAM_Rapier_Blindfire_TR, + AirDefence.HQ_7_Self_Propelled_LN: AirDefence.HQ_7_Self_Propelled_STR, +} + +UNITS_WITH_RADAR = { # Radars AirDefence.SAM_SA_19_Tunguska_Grison, AirDefence.SAM_SA_11_Buk_Gadfly_Fire_Dome_TEL, @@ -74,4 +105,4 @@ UNITS_WITH_RADAR = [ Type_052B_Destroyer, Type_054A_Frigate, Type_052C_Destroyer, -] +} diff --git a/game/theater/theatergroundobject.py b/game/theater/theatergroundobject.py index 7675b256..00e3953d 100644 --- a/game/theater/theatergroundobject.py +++ b/game/theater/theatergroundobject.py @@ -8,9 +8,15 @@ from dcs.mapping import Point from dcs.triggers import TriggerZone from dcs.unit import Unit from dcs.unitgroup import Group +from dcs.unittype import VehicleType from .. import db -from ..data.radar_db import UNITS_WITH_RADAR +from ..data.radar_db import ( + UNITS_WITH_RADAR, + TRACK_RADARS, + TELARS, + LAUNCHER_TRACKER_PAIRS, +) from ..utils import Distance, meters if TYPE_CHECKING: @@ -166,14 +172,7 @@ class TheaterGroundObject(MissionTarget): def detection_range(self, group: Group) -> Distance: return self._max_range_of_type(group, "detection_range") - def threat_range(self, group: Group) -> Distance: - if not self.detection_range(group): - # For simple SAMs like shilkas, the unit has both a threat and - # detection range. For complex sites like SA-2s, the launcher has a - # threat range and the search/track radars have detection ranges. If - # the site has no detection range it has no radars and can't fire, - # so it's not actually a threat even if it still has launchers. - return meters(0) + def threat_range(self, group: Group, radar_only: bool = False) -> Distance: return self._max_range_of_type(group, "threat_range") @property @@ -459,6 +458,38 @@ class SamGroundObject(BaseDefenseGroundObject): def might_have_aa(self) -> bool: return True + def threat_range(self, group: Group, radar_only: bool = False) -> Distance: + max_non_radar = meters(0) + live_trs = set() + max_telar_range = meters(0) + launchers = set() + for unit in group.units: + unit_type = db.unit_type_from_name(unit.type) + if unit_type is None or not issubclass(unit_type, VehicleType): + continue + if unit_type in TRACK_RADARS: + live_trs.add(unit_type) + elif unit_type in TELARS: + max_telar_range = max( + max_telar_range, meters(getattr(unit_type, "threat_range", 0)) + ) + elif unit_type in LAUNCHER_TRACKER_PAIRS: + launchers.add(unit_type) + else: + max_non_radar = max( + max_non_radar, meters(getattr(unit_type, "threat_range", 0)) + ) + max_tel_range = meters(0) + for launcher in launchers: + if LAUNCHER_TRACKER_PAIRS[launcher] in live_trs: + max_tel_range = max( + max_tel_range, meters(getattr(launcher, "threat_range")) + ) + if radar_only: + return max(max_tel_range, max_telar_range) + else: + return max(max_tel_range, max_telar_range, max_non_radar) + class VehicleGroupGroundObject(BaseDefenseGroundObject): def __init__( diff --git a/game/threatzones.py b/game/threatzones.py index e4ad0c39..571e7082 100644 --- a/game/threatzones.py +++ b/game/threatzones.py @@ -15,7 +15,6 @@ from shapely.ops import nearest_points, unary_union from game.theater import ControlPoint from game.utils import Distance, meters, nautical_miles -from gen import Conflict from gen.flights.closestairfields import ObjectiveDistanceCache from gen.flights.flight import Flight @@ -27,9 +26,12 @@ ThreatPoly = Union[MultiPolygon, Polygon] class ThreatZones: - def __init__(self, airbases: ThreatPoly, air_defenses: ThreatPoly) -> None: + def __init__( + self, airbases: ThreatPoly, air_defenses: ThreatPoly, radar_sam_threats + ) -> None: self.airbases = airbases self.air_defenses = air_defenses + self.radar_sam_threats = radar_sam_threats self.all = unary_union([airbases, air_defenses]) def closest_boundary(self, point: DcsPoint) -> DcsPoint: @@ -83,6 +85,20 @@ class ThreatZones: LineString((self.dcs_to_shapely_point(p.position) for p in flight.points)) ) + @singledispatchmethod + def threatened_by_radar_sam(self, target) -> bool: + raise NotImplementedError + + @threatened_by_radar_sam.register + def _threatened_by_radar_sam_geom(self, position: BaseGeometry) -> bool: + return self.radar_sam_threats.intersects(position) + + @threatened_by_radar_sam.register + def _threatened_by_radar_sam_flight(self, flight: Flight) -> bool: + return self.threatened_by_radar_sam( + LineString((self.dcs_to_shapely_point(p.position) for p in flight.points)) + ) + @classmethod def closest_enemy_airbase( cls, location: ControlPoint, max_distance: Distance @@ -134,6 +150,7 @@ class ThreatZones: """ air_threats = [] air_defenses = [] + radar_sam_threats = [] for control_point in game.theater.controlpoints: if control_point.captured != player: continue @@ -151,9 +168,16 @@ class ThreatZones: point = ShapelyPoint(tgo.position.x, tgo.position.y) threat_zone = point.buffer(threat_range.meters) air_defenses.append(threat_zone) + radar_threat_range = tgo.threat_range(group, radar_only=True) + if radar_threat_range > nautical_miles(3): + point = ShapelyPoint(tgo.position.x, tgo.position.y) + threat_zone = point.buffer(threat_range.meters) + radar_sam_threats.append(threat_zone) return cls( - airbases=unary_union(air_threats), air_defenses=unary_union(air_defenses) + airbases=unary_union(air_threats), + air_defenses=unary_union(air_defenses), + radar_sam_threats=unary_union(radar_sam_threats), ) @staticmethod diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 5105bf56..3b06481c 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -833,7 +833,7 @@ class CoalitionMissionPlanner: for flight in builder.package.flights: if self.threat_zones.threatened_by_aircraft(flight): threats[EscortType.AirToAir] = True - if self.threat_zones.threatened_by_air_defense(flight): + if self.threat_zones.threatened_by_radar_sam(flight): threats[EscortType.Sead] = True return threats diff --git a/qt_ui/widgets/map/mapmodel.py b/qt_ui/widgets/map/mapmodel.py index 27d2474e..7b6e7bc5 100644 --- a/qt_ui/widgets/map/mapmodel.py +++ b/qt_ui/widgets/map/mapmodel.py @@ -538,17 +538,20 @@ class ThreatZonesJs(QObject): fullChanged = Signal() aircraftChanged = Signal() airDefensesChanged = Signal() + radarSamsChanged = Signal() def __init__( self, full: List[List[LeafletLatLon]], aircraft: List[List[LeafletLatLon]], air_defenses: List[List[LeafletLatLon]], + radar_sams: List[List[LeafletLatLon]], ) -> None: super().__init__() self._full = full self._aircraft = aircraft self._air_defenses = air_defenses + self._radar_sams = radar_sams @Property(list, notify=fullChanged) def full(self) -> List[List[LeafletLatLon]]: @@ -562,6 +565,10 @@ class ThreatZonesJs(QObject): def airDefenses(self) -> List[List[LeafletLatLon]]: return self._air_defenses + @Property(list, notify=radarSamsChanged) + def radarSams(self) -> List[List[LeafletLatLon]]: + return self._radar_sams + @staticmethod def polys_to_leaflet( poly: Union[Polygon, MultiPolygon], theater: ConflictTheater @@ -578,11 +585,12 @@ class ThreatZonesJs(QObject): cls.polys_to_leaflet(zones.all, theater), cls.polys_to_leaflet(zones.airbases, theater), cls.polys_to_leaflet(zones.air_defenses, theater), + cls.polys_to_leaflet(zones.radar_sam_threats, theater), ) @classmethod def empty(cls) -> ThreatZonesJs: - return ThreatZonesJs([], [], []) + return ThreatZonesJs([], [], [], []) class ThreatZoneContainerJs(QObject): diff --git a/resources/ui/map/map.js b/resources/ui/map/map.js index a6d29c6c..8a508a3a 100644 --- a/resources/ui/map/map.js +++ b/resources/ui/map/map.js @@ -163,10 +163,12 @@ const allFlightPlansLayer = L.layerGroup(); const blueFullThreatZones = L.layerGroup(); const blueAircraftThreatZones = L.layerGroup(); const blueAirDefenseThreatZones = L.layerGroup(); +const blueRadarSamThreatZones = L.layerGroup(); const redFullThreatZones = L.layerGroup(); const redAircraftThreatZones = L.layerGroup(); const redAirDefenseThreatZones = L.layerGroup(); +const redRadarSamThreatZones = L.layerGroup(); L.control .groupedLayers( @@ -198,12 +200,14 @@ L.control Full: blueFullThreatZones, Aircraft: blueAircraftThreatZones, "Air Defenses": blueAirDefenseThreatZones, + "Radar SAMs": blueRadarSamThreatZones, }, "Red Threat Zones": { Hide: L.layerGroup().addTo(map), Full: redFullThreatZones, Aircraft: redAircraftThreatZones, "Air Defenses": redAirDefenseThreatZones, + "Radar SAMs": redRadarSamThreatZones, }, }, { @@ -735,9 +739,11 @@ function drawThreatZones() { blueFullThreatZones.clearLayers(); blueAircraftThreatZones.clearLayers(); blueAirDefenseThreatZones.clearLayers(); + blueRadarSamThreatZones.clearLayers(); redFullThreatZones.clearLayers(); redAircraftThreatZones.clearLayers(); redAirDefenseThreatZones.clearLayers(); + redRadarSamThreatZones.clearLayers(); _drawThreatZones(game.threatZones.blue.full, blueFullThreatZones, true); _drawThreatZones( @@ -750,6 +756,11 @@ function drawThreatZones() { blueAirDefenseThreatZones, true ); + _drawThreatZones( + game.threatZones.blue.radarSams, + blueRadarSamThreatZones, + true + ); _drawThreatZones(game.threatZones.red.full, redFullThreatZones, false); _drawThreatZones( @@ -762,6 +773,11 @@ function drawThreatZones() { redAirDefenseThreatZones, false ); + _drawThreatZones( + game.threatZones.red.radarSams, + redRadarSamThreatZones, + false + ); } function drawInitialMap() { From eedb5c26a9cb7480e6f22c3c7a7bf49b9912f8ec Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 12:58:16 -0700 Subject: [PATCH 032/122] Ignore non-escorted regions when planning escorts. We shouldn't consider the non-escorted parts of the flight path when checking for threats to determine if escorts should be used or not, since escorts can't help in those areas anyway. This was causing escorts to be overly requested since the bullseye is now a part of the "flight plan", but could have also triggered for divert waypoints, or for aircraft taking off in a retreat from a threatened location. --- game/threatzones.py | 18 ++++++++++++++++-- gen/flights/ai_flight_planner.py | 8 ++++++-- gen/flights/flightplan.py | 18 ++++++++++++++---- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/game/threatzones.py b/game/threatzones.py index 571e7082..475517d6 100644 --- a/game/threatzones.py +++ b/game/threatzones.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import singledispatchmethod -from typing import Optional, TYPE_CHECKING, Union +from typing import Optional, TYPE_CHECKING, Union, Iterable from dcs.mapping import Point as DcsPoint from shapely.geometry import ( @@ -16,7 +16,7 @@ from shapely.ops import nearest_points, unary_union from game.theater import ControlPoint from game.utils import Distance, meters, nautical_miles from gen.flights.closestairfields import ObjectiveDistanceCache -from gen.flights.flight import Flight +from gen.flights.flight import Flight, FlightWaypoint if TYPE_CHECKING: from game import Game @@ -71,6 +71,13 @@ class ThreatZones: LineString((self.dcs_to_shapely_point(p.position) for p in flight.points)) ) + def waypoints_threatened_by_aircraft( + self, waypoints: Iterable[FlightWaypoint] + ) -> bool: + return self.threatened_by_aircraft( + LineString((self.dcs_to_shapely_point(p.position) for p in waypoints)) + ) + @singledispatchmethod def threatened_by_air_defense(self, target) -> bool: raise NotImplementedError @@ -99,6 +106,13 @@ class ThreatZones: LineString((self.dcs_to_shapely_point(p.position) for p in flight.points)) ) + def waypoints_threatened_by_radar_sam( + self, waypoints: Iterable[FlightWaypoint] + ) -> bool: + return self.threatened_by_radar_sam( + LineString((self.dcs_to_shapely_point(p.position) for p in waypoints)) + ) + @classmethod def closest_enemy_airbase( cls, location: ControlPoint, max_distance: Distance diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 3b06481c..027230ed 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -831,9 +831,13 @@ class CoalitionMissionPlanner: def check_needed_escorts(self, builder: PackageBuilder) -> Dict[EscortType, bool]: threats = defaultdict(bool) for flight in builder.package.flights: - if self.threat_zones.threatened_by_aircraft(flight): + if self.threat_zones.waypoints_threatened_by_aircraft( + flight.flight_plan.escorted_waypoints() + ): threats[EscortType.AirToAir] = True - if self.threat_zones.threatened_by_radar_sam(flight): + if self.threat_zones.waypoints_threatened_by_radar_sam( + list(flight.flight_plan.escorted_waypoints()) + ): threats[EscortType.Sead] = True return threats diff --git a/gen/flights/flightplan.py b/gen/flights/flightplan.py index 5e6bc886..c2779e3f 100644 --- a/gen/flights/flightplan.py +++ b/gen/flights/flightplan.py @@ -198,6 +198,20 @@ class FlightPlan: def dismiss_escort_at(self) -> Optional[FlightWaypoint]: return None + def escorted_waypoints(self) -> Iterator[FlightWaypoint]: + begin = self.request_escort_at() + end = self.dismiss_escort_at() + if begin is None or end is None: + return + escorting = False + for waypoint in self.waypoints: + if waypoint == begin: + escorting = True + if escorting: + yield waypoint + if waypoint == end: + return + def takeoff_time(self) -> Optional[timedelta]: tot_waypoint = self.tot_waypoint if tot_waypoint is None: @@ -600,10 +614,6 @@ class StrikeFlightPlan(FormationFlightPlan): ) return total - @property - def mission_speed(self) -> Speed: - return GroundSpeed.for_flight(self.flight, self.ingress.alt) - @property def join_time(self) -> timedelta: travel_time = self.travel_time_between_waypoints(self.join, self.ingress) From d788b286aa4434f6409bd5934cdc0e6dd5678f24 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 13:03:18 -0700 Subject: [PATCH 033/122] Remove unused UI classes. --- .../combos/QSEADTargetSelectionComboBox.py | 87 ------------------- qt_ui/widgets/views/QSeadTargetInfoView.py | 33 ------- 2 files changed, 120 deletions(-) delete mode 100644 qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py delete mode 100644 qt_ui/widgets/views/QSeadTargetInfoView.py diff --git a/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py b/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py deleted file mode 100644 index 3cd46bf9..00000000 --- a/qt_ui/widgets/combos/QSEADTargetSelectionComboBox.py +++ /dev/null @@ -1,87 +0,0 @@ -from PySide2.QtGui import QStandardItem, QStandardItemModel - -from game import Game -from game.data.radar_db import UNITS_WITH_RADAR -from gen import db -from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox - - -class SEADTargetInfo: - def __init__(self): - self.name = "" - self.location = None - self.radars = [] - self.threat_range = 0 - self.detection_range = 0 - - -class QSEADTargetSelectionComboBox(QFilteredComboBox): - def __init__(self, game: Game, parent=None): - super(QSEADTargetSelectionComboBox, self).__init__(parent) - self.game = game - self.find_possible_sead_targets() - - def get_selected_target(self) -> SEADTargetInfo: - n = self.currentText() - for target in self.targets: - if target.name == n: - return target - - def find_possible_sead_targets(self): - - self.targets = [] - i = 0 - model = QStandardItemModel() - - def add_model_item(i, model, target): - item = QStandardItem(target.name) - model.setItem(i, 0, item) - self.targets.append(target) - return i + 1 - - for cp in self.game.theater.controlpoints: - if cp.captured: - continue - for g in cp.ground_objects: - - radars = [] - detection_range = 0 - threat_range = 0 - if g.dcs_identifier == "AA": - for group in g.groups: - for u in group.units: - utype = db.unit_type_from_name(u.type) - - if utype in UNITS_WITH_RADAR: - if ( - hasattr(utype, "detection_range") - and utype.detection_range > 1000 - ): - if utype.detection_range > detection_range: - detection_range = utype.detection_range - radars.append(u) - - if hasattr(utype, "threat_range"): - if utype.threat_range > threat_range: - threat_range = utype.threat_range - if len(radars) > 0: - tgt_info = SEADTargetInfo() - tgt_info.name = ( - g.obj_name - + " [" - + ",".join( - [db.unit_type_from_name(u.type).id for u in radars] - ) - + " ]" - ) - if len(tgt_info.name) > 25: - tgt_info.name = ( - g.obj_name + " [" + str(len(radars)) + " units]" - ) - tgt_info.radars = radars - tgt_info.location = g - tgt_info.threat_range = threat_range - tgt_info.detection_range = detection_range - i = add_model_item(i, model, tgt_info) - - self.setModel(model) diff --git a/qt_ui/widgets/views/QSeadTargetInfoView.py b/qt_ui/widgets/views/QSeadTargetInfoView.py deleted file mode 100644 index 0fc40b22..00000000 --- a/qt_ui/widgets/views/QSeadTargetInfoView.py +++ /dev/null @@ -1,33 +0,0 @@ -from PySide2.QtGui import QStandardItemModel, QStandardItem -from PySide2.QtWidgets import QGroupBox, QVBoxLayout, QListView, QAbstractItemView - -from qt_ui.widgets.combos.QSEADTargetSelectionComboBox import SEADTargetInfo - - -class QSeadTargetInfoView(QGroupBox): - """ - UI Component to display info about a sead target - """ - - def __init__(self, sead_target_infos: SEADTargetInfo): - if sead_target_infos is None: - sead_target_infos = SEADTargetInfo() - super(QSeadTargetInfoView, self).__init__("Target : " + sead_target_infos.name) - self.sead_target_infos = sead_target_infos - self.radar_list = QListView() - self.init_ui() - - def init_ui(self): - layout = QVBoxLayout(self) - layout.setSpacing(0) - layout.addWidget(self.radar_list) - self.setLayout(layout) - - def setTarget(self, target: SEADTargetInfo): - self.setTitle(target.name) - self.sead_target_infos = target - radar_list_model = QStandardItemModel() - self.radar_list.setSelectionMode(QAbstractItemView.NoSelection) - for r in self.sead_target_infos.radars: - radar_list_model.appendRow(QStandardItem(r.type)) - self.radar_list.setModel(radar_list_model) From a4fbcd2d02278f335e8833909c1c47e963c00b20 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 18:15:01 -0700 Subject: [PATCH 034/122] Update pydcs for loadout loading fix. --- gen/flights/loadouts.py | 2 +- pydcs | 2 +- qt_ui/main.py | 39 +++++++++++++++++++++++---------------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/gen/flights/loadouts.py b/gen/flights/loadouts.py index 2cfb70d9..845f7751 100644 --- a/gen/flights/loadouts.py +++ b/gen/flights/loadouts.py @@ -62,7 +62,7 @@ class Loadout: # "tasks": List (as a dict) of task IDs the payload is used by. # } payloads = flight.unit_type.load_payloads() - for payload in payloads["payloads"].values(): + for payload in payloads.values(): name = payload["name"] pylons = payload["pylons"] yield Loadout( diff --git a/pydcs b/pydcs index 4972988c..53632aa7 160000 --- a/pydcs +++ b/pydcs @@ -1 +1 @@ -Subproject commit 4972988c978f2057e7aa06919c4de71ee9a06ea5 +Subproject commit 53632aa7a8749c67eba371aaea95bfef73f43cdc diff --git a/qt_ui/main.py b/qt_ui/main.py index 686f2b8c..a8fcde91 100644 --- a/qt_ui/main.py +++ b/qt_ui/main.py @@ -6,7 +6,7 @@ from datetime import datetime from pathlib import Path from typing import Optional -import dcs +from dcs.payloads import PayloadDirectories from PySide2 import QtWidgets from PySide2.QtGui import QPixmap from PySide2.QtWidgets import QApplication, QSplashScreen @@ -36,6 +36,27 @@ from qt_ui.windows.preferences.QLiberationFirstStartWindow import ( ) +THIS_DIR = Path(__file__).parent + + +def inject_custom_payloads() -> None: + dev_payloads = THIS_DIR.parent / "resources/customized_payloads" + # The packaged release rearranges the file locations, so the release has the + # customized payloads in a different location. + release_payloads = THIS_DIR / "resources/customized_payloads" + if dev_payloads.exists(): + payloads = dev_payloads + elif release_payloads.exists(): + payloads = release_payloads + else: + raise RuntimeError( + f"Could not find customized payloads at {release_payloads} or " + f"{dev_payloads}. Aircraft will have no payloads." + ) + # We configure these as fallbacks so that the user's payloads override ours. + PayloadDirectories.set_fallback(payloads) + + def run_ui(game: Optional[Game], new_map: bool) -> None: os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" # Potential fix for 4K screens app = QApplication(sys.argv) @@ -48,21 +69,7 @@ def run_ui(game: Optional[Game], new_map: bool) -> None: logging.info("Loading stylesheet: %s", liberation_theme.get_theme_css_file()) app.setStyleSheet(stylesheet.read()) - # Inject custom payload in pydcs framework - custom_payloads = os.path.join( - os.path.dirname(os.path.realpath(__file__)), - "..\\resources\\customized_payloads", - ) - if os.path.exists(custom_payloads): - dcs.unittype.FlyingType.payload_dirs.append(custom_payloads) - else: - # For release version the path is different. - custom_payloads = os.path.join( - os.path.dirname(os.path.realpath(__file__)), - "resources\\customized_payloads", - ) - if os.path.exists(custom_payloads): - dcs.unittype.FlyingType.payload_dirs.append(custom_payloads) + inject_custom_payloads() first_start = liberation_install.init() if first_start: From 1d7b0c9b1758d3174972ca1afc0bf7a24957452a Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sat, 22 May 2021 18:15:25 -0700 Subject: [PATCH 035/122] Tweak F/A-18 BARCAP and CAS loadouts. Add bags to each. CAS only gets one but that should be plenty for only four Mavericks. CAP gets two. --- .../customized_payloads/FA-18C_hornet.lua | 142 +++++++----------- 1 file changed, 51 insertions(+), 91 deletions(-) diff --git a/resources/customized_payloads/FA-18C_hornet.lua b/resources/customized_payloads/FA-18C_hornet.lua index 64b8fb5a..3865947f 100644 --- a/resources/customized_payloads/FA-18C_hornet.lua +++ b/resources/customized_payloads/FA-18C_hornet.lua @@ -2,39 +2,39 @@ local unitPayloads = { ["name"] = "FA-18C_hornet", ["payloads"] = { [1] = { - ["name"] = "CAS MAVERICK F", + ["name"] = "Liberation BARCAP", ["pylons"] = { [1] = { - ["CLSID"] = "LAU_117_AGM_65F", - ["num"] = 7, + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 9, }, [2] = { - ["CLSID"] = "LAU_117_AGM_65F", - ["num"] = 8, - }, - [3] = { - ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", - ["num"] = 6, - }, - [4] = { - ["CLSID"] = "{AN_ASQ_228}", - ["num"] = 4, - }, - [5] = { - ["CLSID"] = "LAU_117_AGM_65F", - ["num"] = 3, - }, - [6] = { - ["CLSID"] = "LAU_117_AGM_65F", - ["num"] = 2, - }, - [7] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", ["num"] = 1, }, + [3] = { + ["CLSID"] = "{FPU_8A_FUEL_TANK}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{FPU_8A_FUEL_TANK}", + ["num"] = 7, + }, + [5] = { + ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C", + ["num"] = 8, + }, + [6] = { + ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C", + ["num"] = 2, + }, + [7] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 6, + }, [8] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 9, + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 4, }, }, ["tasks"] = { @@ -42,90 +42,50 @@ local unitPayloads = { }, }, [2] = { - ["name"] = "CAS MAVERICK E", + ["name"] = "Liberation CAS", ["pylons"] = { [1] = { - ["CLSID"] = "{F16A4DE0-116C-4A71-97F0-2CF85B0313EC}", - ["num"] = 7, + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 9, }, [2] = { - ["CLSID"] = "{F16A4DE0-116C-4A71-97F0-2CF85B0313EC}", - ["num"] = 8, + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 1, }, [3] = { - ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", - ["num"] = 6, + ["CLSID"] = "LAU_117_AGM_65F", + ["num"] = 2, }, [4] = { + ["CLSID"] = "LAU_117_AGM_65F", + ["num"] = 8, + }, + [5] = { + ["CLSID"] = "LAU_117_AGM_65F", + ["num"] = 7, + }, + [6] = { + ["CLSID"] = "LAU_117_AGM_65F", + ["num"] = 3, + }, + [7] = { ["CLSID"] = "{AN_ASQ_228}", ["num"] = 4, }, - [5] = { - ["CLSID"] = "{F16A4DE0-116C-4A71-97F0-2CF85B0313EC}", - ["num"] = 3, - }, - [6] = { - ["CLSID"] = "{F16A4DE0-116C-4A71-97F0-2CF85B0313EC}", - ["num"] = 2, - }, - [7] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 1, - }, [8] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 9, - }, - }, - ["tasks"] = { - [1] = 11, - }, - }, - [3] = { - ["name"] = "CAP HEAVY", - ["pylons"] = { - [1] = { - ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C", - ["num"] = 7, - }, - [2] = { - ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C", - ["num"] = 8, - }, - [3] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", ["num"] = 6, }, - [4] = { - ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", - ["num"] = 4, - }, - [5] = { + [9] = { ["CLSID"] = "{FPU_8A_FUEL_TANK}", ["num"] = 5, }, - [6] = { - ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C", - ["num"] = 3, - }, - [7] = { - ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C", - ["num"] = 2, - }, - [8] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 1, - }, - [9] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 9, - }, }, ["tasks"] = { - [1] = 11, + [1] = 31, }, }, - [4] = { + [3] = { ["name"] = "STRIKE", ["pylons"] = { [1] = { @@ -165,7 +125,7 @@ local unitPayloads = { [1] = 11, }, }, - [5] = { + [4] = { ["name"] = "ANTISHIP", ["pylons"] = { [1] = { @@ -205,7 +165,7 @@ local unitPayloads = { [1] = 11, }, }, - [6] = { + [5] = { ["displayName"] = "Liberation SEAD", ["name"] = "Liberation SEAD", ["pylons"] = { @@ -246,7 +206,7 @@ local unitPayloads = { [1] = 29, }, }, - [7] = { + [6] = { ["name"] = "RUNWAY_ATTACK", ["pylons"] = { [1] = { @@ -290,7 +250,7 @@ local unitPayloads = { [1] = 34, }, }, - [8] = { + [7] = { ["name"] = "Liberation DEAD", ["pylons"] = { [1] = { From fa321c7ddc14908a0d271384fdccb7b67cda1852 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 13:15:42 -0700 Subject: [PATCH 036/122] Don't plan SEAD when only a search radar remains. --- game/theater/theatergroundobject.py | 9 ++++----- gen/flights/ai_flight_planner.py | 7 ++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/game/theater/theatergroundobject.py b/game/theater/theatergroundobject.py index 00e3953d..1d1f0ffc 100644 --- a/game/theater/theatergroundobject.py +++ b/game/theater/theatergroundobject.py @@ -143,12 +143,11 @@ class TheaterGroundObject(MissionTarget): return False @property - def has_alive_radar(self) -> bool: - """Returns True if the ground object contains a unit with radar.""" + def has_live_radar_sam(self) -> bool: + """Returns True if the ground object contains a unit with working radar SAM.""" for group in self.groups: - for unit in group.units: - if db.unit_type_from_name(unit.type) in UNITS_WITH_RADAR: - return True + if self.threat_range(group, radar_only=True): + return True return False def _max_range_of_type(self, group: Group, range_type: str) -> Distance: diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 027230ed..91c50e5d 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -628,16 +628,17 @@ class CoalitionMissionPlanner: # Only include SEAD against SAMs that still have emitters. No need to # suppress an EWR, and SEAD isn't useful against a SAM that no longer has a - # radar. + # working track radar. # - # For SAMs without radar and EWRs, we still want a SEAD escort if needed. + # For SAMs without track radars and EWRs, we still want a SEAD escort if + # needed. # # Note that there is a quirk here: we should potentially be included a SEAD # escort *and* SEAD when the target is a radar SAM but the flight path is # also threatened by SAMs. We don't want to include a SEAD escort if the # package is *only* threatened by the target though. Could be improved, but # needs a decent refactor to the escort planning to do so. - if isinstance(sam, SamGroundObject) and sam.has_alive_radar: + if sam.has_live_radar_sam: flights.append(ProposedFlight(FlightType.SEAD, 2, self.MAX_SEAD_RANGE)) else: flights.append( From 2ea0bccd250e58edde031a68c94ae4b20bc3006a Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 14:44:24 -0700 Subject: [PATCH 037/122] Hide dead opfor objectives. These are just clutter. --- resources/ui/map/map.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/resources/ui/map/map.js b/resources/ui/map/map.js index 8a508a3a..caf6d9fa 100644 --- a/resources/ui/map/map.js +++ b/resources/ui/map/map.js @@ -488,6 +488,13 @@ class TheaterGroundObject { } draw() { + if (!this.tgo.blue && this.tgo.dead) { + // Don't bother drawing dead opfor TGOs. Blue is worth showing because + // some of them can be repaired, but the player can't interact with dead + // red things so there's no point in showing them. + return; + } + L.marker(this.tgo.position, { icon: this.icon() }) .bindTooltip(`${this.tgo.name}
${this.tgo.units.join("
")}`) .on("click", () => this.tgo.showInfoDialog()) From 31eba975fd2260a8fff8e2e3046f9550a879d5b8 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 15:00:27 -0700 Subject: [PATCH 038/122] Note flight planner changes. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1106 --- changelog.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index c9c6f08f..d67f466f 100644 --- a/changelog.md +++ b/changelog.md @@ -8,12 +8,15 @@ Saves from 2.5 are not compatible with 3.0. * **[Campaign]** Ground units can no longer be sold. To move units to a new location, transfer them. * **[Campaign]** Ground units must now be recruited at a base with a factory and transferred to their destination. When buying units in the UI, the purchase will automatically be fulfilled at the closest factory, and a transfer will be created on the next turn. * **[Campaign]** Non-control point FOBs will no longer spawn. -* **[Campaign AI]** Every 30 minutes the AI will plan a CAP, so players can customize their mission better. * **[Campaign AI]** AI now considers Ju-88s for CAS, strike, and DEAD missions. * **[Campaign AI]** Fix purchase of aircraft by priority (the faction's list was being used as the priority list rather than the game's). +* **[Flight Planner]** Desired mission length is now configurable (defaults to 60 minutes). A BARCAP will be planned every 30 minutes. Other packages will simply have their takeoffs spread out or compressed such that the last flight will take off around the mission end time. * **[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. +* **[Flight Planner]** Planned airspeed increased to 0.85 mach for supersonic airframes and 85% of max speed for subsonic. +* **[Flight Planner]** Taxi time estimation for airfields increased from 5 minutes to 8 minutes. +* **[Flight Planner]** Reduce expected error margin for flight plans from 10% to 5%. * **[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. From 188f871bc846941dd320c9e469f74dbf2c39d9ea Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 15:01:10 -0700 Subject: [PATCH 039/122] Remove errant whitespace. --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index d67f466f..5468512d 100644 --- a/changelog.md +++ b/changelog.md @@ -16,7 +16,7 @@ Saves from 2.5 are not compatible with 3.0. * **[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. * **[Flight Planner]** Planned airspeed increased to 0.85 mach for supersonic airframes and 85% of max speed for subsonic. * **[Flight Planner]** Taxi time estimation for airfields increased from 5 minutes to 8 minutes. -* **[Flight Planner]** Reduce expected error margin for flight plans from 10% to 5%. +* **[Flight Planner]** Reduce expected error margin for flight plans from 10% to 5%. * **[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. From c7edba5120ae4b36141cd97bcce9e6f529c1d020 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 15:36:22 -0700 Subject: [PATCH 040/122] Add TGO-specific layers. This also splits the main and debug controls because the main list was getting too long. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1069 --- resources/ui/map/map.js | 60 ++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/resources/ui/map/map.js b/resources/ui/map/map.js index caf6d9fa..a645fa0c 100644 --- a/resources/ui/map/map.js +++ b/resources/ui/map/map.js @@ -131,7 +131,10 @@ function formatLatLng(latLng) { return `${lat}°${ns} ${lng}°${ew}`; } -const map = L.map("map", { doubleClickZoom: false }).setView([0, 0], 3); +const map = L.map("map", { + doubleClickZoom: false, + zoomControl: false, +}).setView([0, 0], 3); L.control.scale({ maxWidth: 200 }).addTo(map); // https://esri.github.io/esri-leaflet/api-reference/layers/basemap-layer.html @@ -146,6 +149,9 @@ defaultBaseMap.addTo(map); // Enabled by default, so addTo(map). const controlPointsLayer = L.layerGroup().addTo(map); +const airDefensesLayer = L.layerGroup().addTo(map); +const factoriesLayer = L.layerGroup().addTo(map); +const shipsLayer = L.layerGroup().addTo(map); const groundObjectsLayer = L.layerGroup().addTo(map); const supplyRoutesLayer = L.layerGroup().addTo(map); const frontLinesLayer = L.layerGroup().addTo(map); @@ -170,13 +176,21 @@ const redAircraftThreatZones = L.layerGroup(); const redAirDefenseThreatZones = L.layerGroup(); const redRadarSamThreatZones = L.layerGroup(); +// Main map controls. These are the ones that we expect users to interact with. +// These are always open, which unfortunately means that the scroll bar will not +// appear if the menu doesn't fit. This fits in the smallest window size we +// allow, but may need to start auto-collapsing it (or fix the plugin to add a +// scrollbar when non-collapsing) if it gets much larger. L.control .groupedLayers( baseLayers, { "Points of Interest": { "Control points": controlPointsLayer, - "Ground objects": groundObjectsLayer, + "Air defenses": airDefensesLayer, + Factories: factoriesLayer, + Ships: shipsLayer, + "Other ground objects": groundObjectsLayer, "Supply routes": supplyRoutesLayer, "Front lines": frontLinesLayer, }, @@ -195,6 +209,21 @@ L.control "Show all red": redFlightPlansLayer, "Show all": allFlightPlansLayer, }, + }, + { + collapsed: false, + exclusiveGroups: ["Flight Plans"], + groupCheckboxes: true, + } + ) + .addTo(map); + +// Debug map controls. Hover over to open. Not something most users will want or +// need to interact with. +L.control + .groupedLayers( + null, + { "Blue Threat Zones": { Hide: L.layerGroup().addTo(map), Full: blueFullThreatZones, @@ -211,12 +240,9 @@ L.control }, }, { - collapsed: false, - exclusiveGroups: [ - "Flight Plans", - "Blue Threat Zones", - "Red Threat Zones", - ], + position: "topleft", + exclusiveGroups: ["Blue Threat Zones", "Red Threat Zones"], + groupCheckboxes: true, } ) .addTo(map); @@ -460,6 +486,19 @@ class TheaterGroundObject { return Icons.Objectives.icon(this.tgo.category, this.tgo.blue, state); } + layer() { + switch (this.tgo.category) { + case "aa": + return airDefensesLayer; + case "factory": + return factoriesLayer; + case "ship": + return shipsLayer; + default: + return groundObjectsLayer; + } + } + drawSamThreats() { const detectionLayer = this.tgo.blue ? blueSamDetectionLayer @@ -499,12 +538,15 @@ class TheaterGroundObject { .bindTooltip(`${this.tgo.name}
${this.tgo.units.join("
")}`) .on("click", () => this.tgo.showInfoDialog()) .on("contextmenu", () => this.tgo.showPackageDialog()) - .addTo(groundObjectsLayer); + .addTo(this.layer()); this.drawSamThreats(); } } function drawGroundObjects() { + airDefensesLayer.clearLayers(); + factoriesLayer.clearLayers(); + shipsLayer.clearLayers(); groundObjectsLayer.clearLayers(); blueSamDetectionLayer.clearLayers(); redSamDetectionLayer.clearLayers(); From d15ef63182ed99cf570670d6b2c34165744228a8 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 17:12:22 -0700 Subject: [PATCH 041/122] Remove unused method of ControlPoint. --- game/theater/controlpoint.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/game/theater/controlpoint.py b/game/theater/controlpoint.py index ad9f4ec1..ef4eed07 100644 --- a/game/theater/controlpoint.py +++ b/game/theater/controlpoint.py @@ -442,11 +442,6 @@ class ControlPoint(MissionTarget, ABC): """ ... - # TODO: Should be Airbase specific. - def connect(self, to: ControlPoint) -> None: - self.connected_points.append(to) - self.stances[to.id] = CombatStance.DEFENSIVE - def convoy_origin_for(self, destination: ControlPoint) -> Point: return self.convoy_route_to(destination)[0] From 7934463a5369e2da3cdf2aae102a0b21cc0a18fa Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 17:11:16 -0700 Subject: [PATCH 042/122] Add base capture cheat to the new UI. We don't have a context menu yet, so just add it to the base menu. https://github.com/dcs-liberation/dcs_liberation/issues/1108 --- qt_ui/windows/basemenu/QBaseMenu2.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/qt_ui/windows/basemenu/QBaseMenu2.py b/qt_ui/windows/basemenu/QBaseMenu2.py index bca80104..448e89e4 100644 --- a/qt_ui/windows/basemenu/QBaseMenu2.py +++ b/qt_ui/windows/basemenu/QBaseMenu2.py @@ -95,6 +95,12 @@ class QBaseMenu2(QDialog): bottom_row.addWidget(transfer_button) transfer_button.clicked.connect(self.open_transfer_dialog) + if self.cheat_capturable: + capture_button = QPushButton("CHEAT: Capture") + capture_button.setProperty("style", "btn-danger") + bottom_row.addWidget(capture_button) + capture_button.clicked.connect(self.cheat_capture) + self.budget_display = QLabel( QRecruitBehaviour.BUDGET_FORMAT.format(self.game_model.game.budget) ) @@ -104,6 +110,26 @@ class QBaseMenu2(QDialog): GameUpdateSignal.get_instance().budgetupdated.connect(self.update_budget) self.setLayout(main_layout) + @property + def cheat_capturable(self) -> bool: + if not self.game_model.game.settings.enable_base_capture_cheat: + return False + if self.cp.captured: + return False + + for connected in self.cp.connected_points: + if connected.captured: + return True + return False + + def cheat_capture(self) -> None: + self.cp.capture(self.game_model.game, for_player=True) + # Reinitialized ground planners and the like. The ATO needs to be reset because + # missions planned against the flipped base are no longer valid. + self.game_model.game.reset_ato() + self.game_model.game.initialize_turn() + GameUpdateSignal.get_instance().updateGame(self.game_model.game) + @property def has_transfer_destinations(self) -> bool: return self.game_model.game.transit_network_for( From 62b743025a5c872092988069f05a61cbaae86cbe Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 23 May 2021 17:12:49 -0700 Subject: [PATCH 043/122] Fix supply route clobbering, make immutable. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1083 --- game/theater/controlpoint.py | 31 +++++++++++++++++++++++-------- game/theater/frontline.py | 2 +- game/transfers.py | 14 ++++++++++++-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/game/theater/controlpoint.py b/game/theater/controlpoint.py index ef4eed07..cec70fc0 100644 --- a/game/theater/controlpoint.py +++ b/game/theater/controlpoint.py @@ -8,7 +8,20 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, field from enum import Enum from functools import total_ordering -from typing import Any, Dict, Iterator, List, Optional, Set, TYPE_CHECKING, Type, Union +from typing import ( + Any, + Dict, + Iterator, + List, + Optional, + Set, + TYPE_CHECKING, + Type, + Union, + Sequence, + Iterable, + Tuple, +) from dcs.mapping import Point from dcs.ships import ( @@ -306,8 +319,8 @@ class ControlPoint(MissionTarget, ABC): # TODO: Should be Airbase specific. self.has_frontline = has_frontline self.connected_points: List[ControlPoint] = [] - self.convoy_routes: Dict[ControlPoint, List[Point]] = {} - self.shipping_lanes: Dict[ControlPoint, List[Point]] = {} + self.convoy_routes: Dict[ControlPoint, Tuple[Point, ...]] = {} + self.shipping_lanes: Dict[ControlPoint, Tuple[Point, ...]] = {} self.base: Base = Base() self.cptype = cptype # TODO: Should be Airbase specific. @@ -445,16 +458,18 @@ class ControlPoint(MissionTarget, ABC): def convoy_origin_for(self, destination: ControlPoint) -> Point: return self.convoy_route_to(destination)[0] - def convoy_route_to(self, destination: ControlPoint) -> List[Point]: + def convoy_route_to(self, destination: ControlPoint) -> Sequence[Point]: return self.convoy_routes[destination] - def create_convoy_route(self, to: ControlPoint, waypoints: List[Point]) -> None: + def create_convoy_route(self, to: ControlPoint, waypoints: Iterable[Point]) -> None: self.connected_points.append(to) self.stances[to.id] = CombatStance.DEFENSIVE - self.convoy_routes[to] = waypoints + self.convoy_routes[to] = tuple(waypoints) - def create_shipping_lane(self, to: ControlPoint, waypoints: List[Point]) -> None: - self.shipping_lanes[to] = waypoints + def create_shipping_lane( + self, to: ControlPoint, waypoints: Iterable[Point] + ) -> None: + self.shipping_lanes[to] = tuple(waypoints) @abstractmethod def runway_is_operational(self) -> bool: diff --git a/game/theater/frontline.py b/game/theater/frontline.py index 97ef6a9b..225980d1 100644 --- a/game/theater/frontline.py +++ b/game/theater/frontline.py @@ -52,7 +52,7 @@ class FrontLine(MissionTarget): self.blue_cp = blue_point self.red_cp = red_point try: - route = blue_point.convoy_route_to(red_point) + route = list(blue_point.convoy_route_to(red_point)) except KeyError: # Some campaigns are air only and the mission generator currently relies on # *some* "front line" being drawn between these two. In this case there will diff --git a/game/transfers.py b/game/transfers.py index b531fce4..4bdff773 100644 --- a/game/transfers.py +++ b/game/transfers.py @@ -4,7 +4,17 @@ import logging from collections import defaultdict from dataclasses import dataclass, field from functools import singledispatchmethod -from typing import Dict, Generic, Iterator, List, Optional, TYPE_CHECKING, Type, TypeVar +from typing import ( + Dict, + Generic, + Iterator, + List, + Optional, + TYPE_CHECKING, + Type, + TypeVar, + Sequence, +) from dcs.mapping import Point from dcs.unittype import FlyingType, VehicleType @@ -363,7 +373,7 @@ class CargoShip(MultiGroupTransport): yield from super().mission_types(for_player) @property - def route(self) -> List[Point]: + def route(self) -> Sequence[Point]: return self.origin.shipping_lanes[self.destination] def description(self) -> str: From e8f326ebce830c0aad9849b80e9dcbf588c2b95c Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 24 May 2021 14:35:22 -0700 Subject: [PATCH 044/122] Update Skynet to 2.1.0. --- changelog.md | 1 + .../skynetiads/skynet-iads-compiled.lua | 162 ++++++++++++++++-- 2 files changed, 153 insertions(+), 10 deletions(-) diff --git a/changelog.md b/changelog.md index 5468512d..a1a38a7e 100644 --- a/changelog.md +++ b/changelog.md @@ -29,6 +29,7 @@ Saves from 2.5 are not compatible with 3.0. * **[Modding]** Can now install custom factions to /Liberation/Factions instead of the Liberation install directory. * **[Performance Settings]** Added a settings to lower the number of smoke effects generated on frontlines. Lowered default settings for frontline smoke generators, so less smoke should be generated by default. * **[Configuration]** Liberation preferences (DCS install and save game location) are now saved to `%LOCALAPPDATA%/DCSLiberation` to prevent needing to reconfigure each new install. +* **[Skynet]** Updated to 2.1.0. ## Fixes diff --git a/resources/plugins/skynetiads/skynet-iads-compiled.lua b/resources/plugins/skynetiads/skynet-iads-compiled.lua index 7b7939a4..b13f1bb5 100644 --- a/resources/plugins/skynetiads/skynet-iads-compiled.lua +++ b/resources/plugins/skynetiads/skynet-iads-compiled.lua @@ -1,4 +1,4 @@ -env.info("--- SKYNET VERSION: 2.0.1 | BUILD TIME: 04.01.2021 0706Z ---") +env.info("--- SKYNET VERSION: 2.1.0 | BUILD TIME: 27.03.2021 2125Z ---") do --this file contains the required units per sam type samTypesDB = { @@ -387,6 +387,20 @@ end do -- this file contains the definitions for the HightDigitSAMSs: https://github.com/Auranis/HighDigitSAMs +--EW radars used in multiple SAM systems: + +s300PMU164N6Esr = { + ['name'] = { + ['NATO'] = 'Big Bird', + }, +} + +s300PMU140B6MDsr = { + ['name'] = { + ['NATO'] = 'Clam Shell', + }, +} + --[[ units in SA-10 group Gargoyle: 2020-12-10 18:27:27.050 INFO SCRIPTING: S-300PMU1 54K6 cp 2020-12-10 18:27:27.050 INFO SCRIPTING: S-300PMU1 5P85CE ln @@ -399,21 +413,36 @@ do samTypesDB['S-300PMU1'] = { ['type'] = 'complex', ['searchRadar'] = { - ['S-300PMU1 40B6MD sr'] = { + ['S-300PMU1 40B6MD sr'] = s300PMU140B6MDsr, + ['S-300PMU1 64N6E sr'] = s300PMU164N6Esr, + + ['S-300PS 40B6MD sr'] = { ['name'] = { - ['NATO'] = 'Clam Shell', + ['NATO'] = '', }, }, - ['S-300PMU1 64N6E sr'] = { + ['S-300PS 64H6E sr'] = { ['name'] = { - ['NATO'] = 'Big Bird', + ['NATO'] = '', }, }, }, ['trackingRadar'] = { ['S-300PMU1 40B6M tr'] = { + ['name'] = { + ['NATO'] = 'Grave Stone', + }, }, ['S-300PMU1 30N6E tr'] = { + ['name'] = { + ['NATO'] = 'Flap Lid', + }, + + }, + ['S-300PS 40B6M tr'] = { + ['name'] = { + ['NATO'] = '', + }, }, }, ['misc'] = { @@ -441,10 +470,6 @@ samTypesDB['S-300PMU1'] = { 2020-12-11 16:40:52.072 INFO SCRIPTING: S-300VM 9S32ME tr 2020-12-11 16:40:52.072 INFO SCRIPTING: S-300VM 9S457ME cp -According to wikipedia: -dem 9A83-Startfahrzeug die Bezeichnung SA-12A Gladiator zu geben; das größere 9A82-Startfahrzeug erhielt die Bezeichnung SA-12B Giant. -9A83ME -> SA-23A Gladiator -9A82ME -> SA-23B Giant ]]-- samTypesDB['S-300VM'] = { ['type'] = 'complex', @@ -476,7 +501,7 @@ samTypesDB['S-300VM'] = { }, }, ['name'] = { - ['NATO'] = 'SA-23 Gladiator/Giant' + ['NATO'] = 'SA-23 Antey-2500' }, ['harm_detection_chance'] = 90 } @@ -494,6 +519,9 @@ samTypesDB['S-300PS'] = { ['type'] = 'complex', ['searchRadar'] = { ['S-300PS SA-10B 40B6MD MAST sr'] = { + ['name'] = { + ['NATO'] = 'Clam Shell', + }, }, ['S-300PS 64H6E TRAILER sr'] = { }, @@ -503,6 +531,12 @@ samTypesDB['S-300PS'] = { }, ['S-300PS SA-10B 40B6M MAST tr'] = { }, + ['S-300PS 40B6M tr'] = { + }, + ['S-300PMU1 40B6M tr'] = { + }, + ['S-300PMU1 30N6E tr'] = { + }, }, ['misc'] = { ['S-300PS SA-10B 54K6 cp'] = { @@ -546,6 +580,9 @@ samTypesDB['Buk-M2'] = { ['type'] = 'complex', ['searchRadar'] = { ['SA-11 Buk SR 9S18M1'] = { + ['name'] = { + ['NATO'] = 'Snow Drift', + }, }, }, ['launchers'] = { @@ -581,6 +618,106 @@ New launcher for the SA-2 complex: HQ_2_Guideline_LN local s125launchers = samTypesDB['S-75']['launchers'] s125launchers['HQ_2_Guideline_LN'] = {} +--[[ +SA-12 Gladiator / Giant: +2021-03-19 21:24:22.620 INFO SCRIPTING: S-300V 9S15 sr +2021-03-19 21:24:22.620 INFO SCRIPTING: S-300V 9S19 sr +2021-03-19 21:24:22.620 INFO SCRIPTING: S-300V 9S32 tr +2021-03-19 21:24:22.620 INFO SCRIPTING: S-300V 9S457 cp +2021-03-19 21:24:22.620 INFO SCRIPTING: S-300V 9A83 ln +2021-03-19 21:24:22.620 INFO SCRIPTING: S-300V 9A82 ln +--]] +samTypesDB['S-300V'] = { + ['type'] = 'complex', + ['searchRadar'] = { + ['S-300V 9S15 sr'] = { + ['name'] = { + ['NATO'] = 'Bill Board', + }, + }, + ['S-300V 9S19 sr'] = { + ['name'] = { + ['NATO'] = 'High Screen', + }, + }, + }, + ['trackingRadar'] = { + ['S-300V 9S32 tr'] = { + ['NATO'] = 'Grill Pan', + }, + }, + ['misc'] = { + ['S-300V 9S457 cp'] = { + ['required'] = true, + }, + }, + ['launchers'] = { + ['S-300V 9A83 ln'] = { + }, + ['S-300V 9A82 ln'] = { + }, + }, + ['name'] = { + ['NATO'] = 'SA-12 Gladiator/Giant' + }, + ['harm_detection_chance'] = 90 +} + +--[[ +SA-20B Gargoyle B: + +2021-03-25 19:15:02.135 INFO SCRIPTING: S-300PMU2 64H6E2 sr +2021-03-25 19:15:02.135 INFO SCRIPTING: S-300PMU2 92H6E tr +2021-03-25 19:15:02.135 INFO SCRIPTING: S-300PMU2 5P85SE2 ln +2021-03-25 19:15:02.135 INFO SCRIPTING: S-300PMU2 54K6E2 cp +--]] + +samTypesDB['S-300PMU2'] = { + ['type'] = 'complex', + ['searchRadar'] = { + ['S-300PMU2 64H6E2 sr'] = { + ['name'] = { + ['NATO'] = '', + }, + }, + ['S-300PMU1 40B6MD sr'] = s300PMU140B6MDsr, + ['S-300PMU1 64N6E sr'] = s300PMU164N6Esr, + + ['S-300PS 40B6MD sr'] = { + ['name'] = { + ['NATO'] = '', + }, + }, + ['S-300PS 64H6E sr'] = { + ['name'] = { + ['NATO'] = '', + }, + }, + }, + ['trackingRadar'] = { + ['S-300PMU2 92H6E tr'] = { + }, + ['S-300PS 40B6M tr'] = { + }, + ['S-300PMU1 40B6M tr'] = { + }, + ['S-300PMU1 30N6E tr'] = { + }, + }, + ['misc'] = { + ['S-300PMU2 54K6E2 cp'] = { + ['required'] = true, + }, + }, + ['launchers'] = { + ['S-300PMU2 5P85SE2 ln'] = { + }, + }, + ['name'] = { + ['NATO'] = 'SA-20B Gargoyle B' + }, + ['harm_detection_chance'] = 90 +} end @@ -2545,6 +2682,10 @@ end function SkynetIADSAbstractRadarElement.finishHarmDefence(self) mist.removeFunction(self.harmSilenceID) self.harmSilenceID = nil + + if ( self:getAutonomousState() == true ) then + self:goAutonomous() + end end function SkynetIADSAbstractRadarElement:getDetectedTargets() @@ -2869,6 +3010,7 @@ function SkynetIADSEWRadar:setupElements() for typeName, dataType in pairs(SkynetIADS.database) do for entry, unitData in pairs(dataType) do if entry == 'searchRadar' then + --buildSingleUnit checks to make sure the EW radar is defined in the Skynet database. If it is not, self.searchRadars will be 0 so no ew radar will be added self:buildSingleUnit(unit, SkynetIADSSAMSearchRadar, self.searchRadars, unitData) if #self.searchRadars > 0 then local harmDetection = dataType['harm_detection_chance'] From b7b3b358161736c7bf5c4c817248ff5601b2fb1f Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 24 May 2021 16:45:21 -0700 Subject: [PATCH 045/122] Make some waypoint types undraggable. None of these (takeoff, landing, divert, bullseye, precise target locations) can be usefully moved, so prevent it. --- gen/flights/flight.py | 2 +- qt_ui/widgets/map/mapmodel.py | 10 ++++++++++ resources/ui/map/map.js | 37 +++++++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/gen/flights/flight.py b/gen/flights/flight.py index b9ea8bce..698e1bce 100644 --- a/gen/flights/flight.py +++ b/gen/flights/flight.py @@ -101,7 +101,7 @@ class FlightWaypointType(Enum): LANDING_POINT = 11 # Should land there TARGET_POINT = 12 # A target building or static object, position TARGET_GROUP_LOC = 13 # A target group approximate location - TARGET_SHIP = 14 # A target ship known location + TARGET_SHIP = 14 # Unused. CUSTOM = 15 # User waypoint (no specific behaviour) JOIN = 16 SPLIT = 17 diff --git a/qt_ui/widgets/map/mapmodel.py b/qt_ui/widgets/map/mapmodel.py index 7b6e7bc5..a176c155 100644 --- a/qt_ui/widgets/map/mapmodel.py +++ b/qt_ui/widgets/map/mapmodel.py @@ -379,7 +379,9 @@ class WaypointJs(QObject): altitudeReferenceChanged = Signal() nameChanged = Signal() timingChanged = Signal() + isTargetPointChanged = Signal() isTakeoffChanged = Signal() + isLandingChanged = Signal() isDivertChanged = Signal() isBullseyeChanged = Signal() @@ -438,10 +440,18 @@ class WaypointJs(QObject): return "" return f"{prefix} T+{timedelta(seconds=int(time.total_seconds()))}" + @Property(bool, notify=isTargetPointChanged) + def isTargetPoint(self) -> bool: + return self.waypoint.waypoint_type is FlightWaypointType.TARGET_POINT + @Property(bool, notify=isTakeoffChanged) def isTakeoff(self) -> bool: return self.waypoint.waypoint_type is FlightWaypointType.TAKEOFF + @Property(bool, notify=isLandingChanged) + def isLanding(self) -> bool: + return self.waypoint.waypoint_type is FlightWaypointType.LANDING_POINT + @Property(bool, notify=isDivertChanged) def isDivert(self) -> bool: return self.waypoint.waypoint_type is FlightWaypointType.DIVERT diff --git a/resources/ui/map/map.js b/resources/ui/map/map.js index a645fa0c..d97c369e 100644 --- a/resources/ui/map/map.js +++ b/resources/ui/map/map.js @@ -615,7 +615,40 @@ class Waypoint { // We don't need a marker for the departure waypoint (and it's likely // coincident with the landing waypoint, so hard to see). We do want to draw // the path from it though. - return !this.waypoint.isTakeoff; + // + // We also don't need the landing waypoint since we'll be drawing that path + // as well and it's clear what it is, and only obscured the CP icon. + // + // The divert waypoint also obscures the CP. We don't draw the path to it, + // but it can be seen in the flight settings page so it's not really a + // problem to exclude it. + // + // Bullseye ought to be (but currently isn't) drawn *once* rather than as a + // flight waypoint. + return !( + this.waypoint.isTakeoff || + this.waypoint.isLanding || + this.waypoint.isDivert || + this.waypoint.isBullseye + ); + } + + draggable() { + // Target *points* are the exact location of a unit, whereas the target area + // is only the center of the objective. Allow moving the latter since its + // exact location isn't very important. + // + // Landing, and divert should be changed in the flight settings UI, takeoff + // cannot be changed because that's where the plane is. + // + // Moving the bullseye reference only makes it wrong. + return !( + this.waypoint.isTargetPoint || + this.waypoint.isTakeoff || + this.waypoint.isLanding || + this.waypoint.isDivert || + this.waypoint.isBullseye + ); } description(dragging) { @@ -639,7 +672,7 @@ class Waypoint { makeMarker() { const zoom = map.getZoom(); - return L.marker(this.waypoint.position, { draggable: true }) + return L.marker(this.waypoint.position, { draggable: this.draggable() }) .bindTooltip(this.description(), { permanent: zoom >= SHOW_WAYPOINT_INFO_AT_ZOOM, }) From 970f2c25dd3e7fc87e8ae29d345664859bee8580 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 24 May 2021 16:49:31 -0700 Subject: [PATCH 046/122] Fix loadout reset when disabling custom loadouts. --- qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py b/qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py index 8262e2b4..364220ba 100644 --- a/qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py +++ b/qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py @@ -49,5 +49,5 @@ class QFlightPayloadTab(QFrame): if use_custom: self.flight.loadout = self.flight.loadout.derive_custom("Custom") else: - self.flight.loadout = Loadout.default_for(self.flight) + self.flight.loadout = self.loadout_selector.currentData() self.payload_editor.reset_pylons() From 305d1f05235e6c8da1ddefe36767d19f9e3b55cd Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 24 May 2021 16:57:36 -0700 Subject: [PATCH 047/122] Reset non-custom loadout when changing task. --- qt_ui/windows/mission/flight/QFlightPlanner.py | 1 + qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py | 3 +++ .../windows/mission/flight/waypoints/QFlightWaypointTab.py | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/qt_ui/windows/mission/flight/QFlightPlanner.py b/qt_ui/windows/mission/flight/QFlightPlanner.py index 0c1b9e03..695e1575 100644 --- a/qt_ui/windows/mission/flight/QFlightPlanner.py +++ b/qt_ui/windows/mission/flight/QFlightPlanner.py @@ -19,6 +19,7 @@ class QFlightPlanner(QTabWidget): ) self.payload_tab = QFlightPayloadTab(flight, game) self.waypoint_tab = QFlightWaypointTab(game, package_model.package, flight) + self.waypoint_tab.loadout_changed.connect(self.payload_tab.reload_from_flight) self.addTab(self.general_settings_tab, "General Flight settings") self.addTab(self.payload_tab, "Payload") self.addTab(self.waypoint_tab, "Waypoints") diff --git a/qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py b/qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py index 364220ba..17ca1cca 100644 --- a/qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py +++ b/qt_ui/windows/mission/flight/payload/QFlightPayloadTab.py @@ -40,6 +40,9 @@ class QFlightPayloadTab(QFrame): self.setLayout(layout) + def reload_from_flight(self) -> None: + self.loadout_selector.setCurrentText(self.flight.loadout.name) + def on_new_loadout(self, index: int) -> None: self.flight.loadout = self.loadout_selector.itemData(index) self.payload_editor.reset_pylons() diff --git a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py index 95ede450..b38ab146 100644 --- a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py +++ b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointTab.py @@ -20,6 +20,7 @@ from gen.flights.flightplan import ( PlanningError, StrikeFlightPlan, ) +from gen.flights.loadouts import Loadout from qt_ui.windows.mission.flight.waypoints.QFlightWaypointList import ( QFlightWaypointList, ) @@ -29,6 +30,8 @@ from qt_ui.windows.mission.flight.waypoints.QPredefinedWaypointSelectionWindow i class QFlightWaypointTab(QFrame): + loadout_changed = Signal() + def __init__(self, game: Game, package: Package, flight: Flight): super(QFlightWaypointTab, self).__init__() self.game = game @@ -161,6 +164,9 @@ class QFlightWaypointTab(QFrame): QMessageBox.critical( self, "Could not recreate flight", str(ex), QMessageBox.Ok ) + if not self.flight.loadout.is_custom: + self.flight.loadout = Loadout.default_for(self.flight) + self.loadout_changed.emit() self.flight_waypoint_list.update_list() self.on_change() From c255aee3b9f1cb38bfb50e92f25c98763872cba7 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 24 May 2021 17:21:33 -0700 Subject: [PATCH 048/122] Make default AEW&C missions ASAP. --- changelog.md | 1 + gen/flights/ai_flight_planner.py | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index a1a38a7e..64dbc3c4 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,7 @@ Saves from 2.5 are not compatible with 3.0. * **[Campaign]** Non-control point FOBs will no longer spawn. * **[Campaign AI]** AI now considers Ju-88s for CAS, strike, and DEAD missions. * **[Campaign AI]** Fix purchase of aircraft by priority (the faction's list was being used as the priority list rather than the game's). +* **[Campaign AI]** AI planned AEW&C missions will now be scheduled ASAP. * **[Flight Planner]** Desired mission length is now configurable (defaults to 60 minutes). A BARCAP will be planned every 30 minutes. Other packages will simply have their takeoffs spread out or compressed such that the last flight will take off around the mission end time. * **[Flight Planner]** AI strike flight plans now include the correct target actions for building groups. * **[Flight Planner]** Flight plans now include bullseye waypoints. diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 91c50e5d..726381f9 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -109,6 +109,8 @@ class ProposedMission: #: The proposed flights that are required for the mission. flights: List[ProposedFlight] + asap: bool = field(default=False) + def __str__(self) -> str: flights = ", ".join([str(f) for f in self.flights]) return f"{self.location.name}: {flights}" @@ -183,11 +185,12 @@ class PackageBuilder: is_player: bool, package_country: str, start_type: str, + asap: bool, ) -> None: self.closest_airfields = closest_airfields self.is_player = is_player self.package_country = package_country - self.package = Package(location) + self.package = Package(location, auto_asap=asap) self.allocator = AircraftAllocator( closest_airfields, global_inventory, is_player ) @@ -571,7 +574,10 @@ class CoalitionMissionPlanner: cp = self.objective_finder.farthest_friendly_control_point() if cp is not None: yield ProposedMission( - cp, [ProposedFlight(FlightType.AEWC, 1, self.MAX_AWEC_RANGE)] + cp, + [ProposedFlight(FlightType.AEWC, 1, self.MAX_AWEC_RANGE)], + # Supports all the early CAP flights, so should be in the air ASAP. + asap=True, ) # Find friendly CPs within 100 nmi from an enemy airfield, plan CAP. @@ -857,6 +863,7 @@ class CoalitionMissionPlanner: self.is_player, package_country, self.game.settings.default_start_type, + mission.asap, ) # Attempt to plan all the main elements of the mission first. Escorts @@ -975,7 +982,7 @@ class CoalitionMissionPlanner: logging.error(f"Could not determine mission end time for {package}") continue previous_cap_end_time[package.target] = departure_time - else: + elif not package.auto_asap: # But other packages should be spread out a bit. Note that take # times are delayed, but all aircraft will become active at # mission start. This makes it more worthwhile to attack enemy From f2bd7300aaafe4a15d8cf203c5f584129942a626 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 24 May 2021 18:06:47 -0700 Subject: [PATCH 049/122] Improve precision of kneeboard lat/lon. DMS with decimal seconds is what the hornet uses for PP targest. In the future we'll want to make this aircraft specific (and potentially user preference for jets like the A-10 that can handle both L/L and MGRS). --- game/theater/latlon.py | 25 ++++++++++++++++++++++++- gen/kneeboard.py | 14 ++++++++------ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/game/theater/latlon.py b/game/theater/latlon.py index dde2e442..b819e30f 100644 --- a/game/theater/latlon.py +++ b/game/theater/latlon.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import List +from typing import List, Tuple @dataclass(frozen=True) @@ -9,3 +9,26 @@ class LatLon: def as_list(self) -> List[float]: return [self.latitude, self.longitude] + + @staticmethod + def _components(dimension: float) -> Tuple[int, int, float]: + degrees = int(dimension) + minutes = int(dimension * 60 % 60) + seconds = dimension * 3600 % 60 + return degrees, minutes, seconds + + def _format_component( + self, dimension: float, hemispheres: Tuple[str, str], seconds_precision: int + ) -> str: + hemisphere = hemispheres[0] if dimension >= 0 else hemispheres[1] + degrees, minutes, seconds = self._components(dimension) + return f"{degrees}°{minutes:02}'{seconds:02.{seconds_precision}f}\"{hemisphere}" + + def format_dms(self, include_decimal_seconds: bool = False) -> str: + precision = 2 if include_decimal_seconds else 0 + return " ".join( + [ + self._format_component(self.latitude, ("N", "S"), precision), + self._format_component(self.longitude, ("E", "W"), precision), + ] + ) diff --git a/gen/kneeboard.py b/gen/kneeboard.py index e28ded01..71544a26 100644 --- a/gen/kneeboard.py +++ b/gen/kneeboard.py @@ -36,7 +36,7 @@ from dcs.unittype import FlyingType from tabulate import tabulate from game.data.alic import AlicCodes -from game.db import find_unittype, unit_type_from_name +from game.db import unit_type_from_name from game.theater import ConflictTheater, TheaterGroundObject, LatLon from game.theater.bullseye import Bullseye from game.utils import meters @@ -298,9 +298,7 @@ class BriefingPage(KneeboardPage): headers=["#", "Action", "Alt", "Dist", "GSPD", "Time", "Departure"], ) - writer.text( - f"Bullseye: {self.format_ll(self.bullseye.to_lat_lon(self.theater))}" - ) + writer.text(f"Bullseye: {self.bullseye.to_lat_lon(self.theater).format_dms()}") writer.table( [ @@ -507,7 +505,7 @@ class SeadTaskPage(KneeboardPage): ll = self.theater.point_to_ll(unit.position) unit_type = unit_type_from_name(unit.type) name = unit.name if unit_type is None else unit_type.name - return [name, self.alic_for(unit), self.format_ll(ll)] + return [name, self.alic_for(unit), ll.format_dms(include_decimal_seconds=True)] class StrikeTaskPage(KneeboardPage): @@ -546,7 +544,11 @@ class StrikeTaskPage(KneeboardPage): def target_info_row(self, target: NumberedWaypoint) -> List[str]: ll = self.theater.point_to_ll(target.waypoint.position) - return [str(target.number), target.waypoint.pretty_name, self.format_ll(ll)] + return [ + str(target.number), + target.waypoint.pretty_name, + ll.format_dms(include_decimal_seconds=True), + ] class KneeboardGenerator(MissionInfoGenerator): From e94657875ffc21eeaa5d5c82636ab57bbc896e9e Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 24 May 2021 18:20:19 -0700 Subject: [PATCH 050/122] Reselect same row after deleting waypoint. --- .../windows/mission/flight/waypoints/QFlightWaypointList.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py index b9ba7444..d541deba 100644 --- a/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py +++ b/qt_ui/windows/mission/flight/waypoints/QFlightWaypointList.py @@ -31,6 +31,9 @@ class QFlightWaypointList(QTableView): ) def update_list(self): + # We need to keep just the row and rebuild the index later because the + # QModelIndex will not be valid after the model is cleared. + current_index = self.currentIndex().row() self.model.clear() self.model.setHorizontalHeaderLabels(["Name", "Alt", "TOT/DEPART"]) @@ -39,7 +42,7 @@ class QFlightWaypointList(QTableView): for row, waypoint in enumerate(waypoints): self.add_waypoint_row(row, self.flight, waypoint) self.selectionModel().setCurrentIndex( - self.indexAt(QPoint(1, 1)), QItemSelectionModel.Select + self.model.index(current_index, 0), QItemSelectionModel.Select ) self.resizeColumnsToContents() total_column_width = self.verticalHeader().width() + self.lineWidth() From d15bfaac76d19e0ab55f9c133703ea98d78a0cb7 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 24 May 2021 19:26:03 -0700 Subject: [PATCH 051/122] Fix group targeting for multi-group TGOs. AI flights were only getting a single Attack Group task against multi- group TGOs (currently only a small group of SAMs like the SA-10, I believe), so the AI would never attack the point defense SA-15 or AAA groups. --- changelog.md | 5 ++- gen/aircraft.py | 111 +++++++++++++++++++++++++++--------------------- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/changelog.md b/changelog.md index 64dbc3c4..08dab6c1 100644 --- a/changelog.md +++ b/changelog.md @@ -9,10 +9,8 @@ Saves from 2.5 are not compatible with 3.0. * **[Campaign]** Ground units must now be recruited at a base with a factory and transferred to their destination. When buying units in the UI, the purchase will automatically be fulfilled at the closest factory, and a transfer will be created on the next turn. * **[Campaign]** Non-control point FOBs will no longer spawn. * **[Campaign AI]** AI now considers Ju-88s for CAS, strike, and DEAD missions. -* **[Campaign AI]** Fix purchase of aircraft by priority (the faction's list was being used as the priority list rather than the game's). * **[Campaign AI]** AI planned AEW&C missions will now be scheduled ASAP. * **[Flight Planner]** Desired mission length is now configurable (defaults to 60 minutes). A BARCAP will be planned every 30 minutes. Other packages will simply have their takeoffs spread out or compressed such that the last flight will take off around the mission end time. -* **[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. * **[Flight Planner]** Planned airspeed increased to 0.85 mach for supersonic airframes and 85% of max speed for subsonic. @@ -34,10 +32,13 @@ Saves from 2.5 are not compatible with 3.0. ## Fixes +* **[Campaign AI]** Fix purchase of aircraft by priority (the faction's list was being used as the priority list rather than the game's). * **[Campaign AI]** Fixed bug causing AI to over-purchase cheap aircraft. * **[Campaign AI]** Auto planner will no longer attempt to plan missions for which the faction has no compatible aircraft. * **[Campaign AI]** Stop purchasing aircraft after the first unaffordable package to attempt to complete more packages rather than filling airfields with cheap escorts that will never be used. * **[Campaign]** Fixed bug where offshore strike locations were being used to spawn ship objectives. +* **[Flight Planner]** AI strike flight plans now include the correct target actions for building groups. +* **[Flight Planner]** AI BAI/DEAD/SEAD flights now have tasks to attack all groups at the target location, not just the primary group (for multi-group SAM sites). # 2.5.1 diff --git a/gen/aircraft.py b/gen/aircraft.py index 360faa97..8d87f22b 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -1737,29 +1737,32 @@ class BaiIngressBuilder(PydcsWaypointBuilder): waypoint = super().build() # TODO: Add common "UnitGroupTarget" base type. - target_group = self.package.target - if isinstance(target_group, TheaterGroundObject): - group_name = target_group.group_name - elif isinstance(target_group, MultiGroupTransport): - group_name = target_group.name + group_names = [] + target = self.package.target + if isinstance(target, TheaterGroundObject): + for group in target.groups: + group_names.append(group.name) + elif isinstance(target, MultiGroupTransport): + group_names.append(target.name) else: logging.error( "Unexpected target type for BAI mission: %s", - target_group.__class__.__name__, + target.__class__.__name__, ) return waypoint - group = self.mission.find_group(group_name) - if group is None: - logging.error("Could not find group for BAI mission %s", group_name) - return waypoint + for group_name in group_names: + group = self.mission.find_group(group_name) + if group is None: + logging.error("Could not find group for BAI mission %s", group_name) + continue - task = AttackGroup(group.id, weapon_type=WeaponType.Auto) - task.params["attackQtyLimit"] = False - task.params["directionEnabled"] = False - task.params["altitudeEnabled"] = False - task.params["groupAttack"] = True - waypoint.tasks.append(task) + task = AttackGroup(group.id, weapon_type=WeaponType.Auto) + task.params["attackQtyLimit"] = False + task.params["directionEnabled"] = False + task.params["altitudeEnabled"] = False + task.params["groupAttack"] = True + waypoint.tasks.append(task) return waypoint @@ -1796,23 +1799,29 @@ class CasIngressBuilder(PydcsWaypointBuilder): class DeadIngressBuilder(PydcsWaypointBuilder): def build(self) -> MovingPoint: waypoint = super().build() - - target_group = self.package.target - if isinstance(target_group, TheaterGroundObject): - tgroup = self.mission.find_group(target_group.group_name) - if tgroup is not None: - task = AttackGroup(tgroup.id, weapon_type=WeaponType.Auto) - task.params["expend"] = "All" - task.params["attackQtyLimit"] = False - task.params["directionEnabled"] = False - task.params["altitudeEnabled"] = False - task.params["groupAttack"] = True - waypoint.tasks.append(task) - else: - logging.error( - f"Could not find group for DEAD mission {target_group.group_name}" - ) self.register_special_waypoints(self.waypoint.targets) + + target = self.package.target + if not isinstance(target, TheaterGroundObject): + logging.error( + "Unexpected target type for DEAD mission: %s", + target.__class__.__name__, + ) + return waypoint + + for group in target.groups: + miz_group = self.mission.find_group(group.name) + if miz_group is None: + logging.error(f"Could not find group for DEAD mission {group.name}") + continue + + task = AttackGroup(miz_group.id, weapon_type=WeaponType.Auto) + task.params["expend"] = "All" + task.params["attackQtyLimit"] = False + task.params["directionEnabled"] = False + task.params["altitudeEnabled"] = False + task.params["groupAttack"] = True + waypoint.tasks.append(task) return waypoint @@ -1864,23 +1873,29 @@ class OcaRunwayIngressBuilder(PydcsWaypointBuilder): class SeadIngressBuilder(PydcsWaypointBuilder): def build(self) -> MovingPoint: waypoint = super().build() - - target_group = self.package.target - if isinstance(target_group, TheaterGroundObject): - tgroup = self.mission.find_group(target_group.group_name) - if tgroup is not None: - task = AttackGroup(tgroup.id, weapon_type=WeaponType.Guided) - task.params["expend"] = "All" - task.params["attackQtyLimit"] = False - task.params["directionEnabled"] = False - task.params["altitudeEnabled"] = False - task.params["groupAttack"] = True - waypoint.tasks.append(task) - else: - logging.error( - f"Could not find group for SEAD mission {target_group.group_name}" - ) self.register_special_waypoints(self.waypoint.targets) + + target = self.package.target + if not isinstance(target, TheaterGroundObject): + logging.error( + "Unexpected target type for SEAD mission: %s", + target.__class__.__name__, + ) + return waypoint + + for group in target.groups: + miz_group = self.mission.find_group(group.name) + if miz_group is None: + logging.error(f"Could not find group for SEAD mission {group.name}") + continue + + task = AttackGroup(miz_group.id, weapon_type=WeaponType.Guided) + task.params["expend"] = "All" + task.params["attackQtyLimit"] = False + task.params["directionEnabled"] = False + task.params["altitudeEnabled"] = False + task.params["groupAttack"] = True + waypoint.tasks.append(task) return waypoint From c37a5b2405005dcdf864574e73b26b20c0e99caa Mon Sep 17 00:00:00 2001 From: bgreman <47828384+bgreman@users.noreply.github.com> Date: Mon, 24 May 2021 23:43:33 -0400 Subject: [PATCH 052/122] Prevent empty transfers. Disables the 'create transfer order' button in the unit transfer dialog if no units are actually selected for transfer (including when the dialog is first loaded). --- qt_ui/windows/basemenu/NewUnitTransferDialog.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/qt_ui/windows/basemenu/NewUnitTransferDialog.py b/qt_ui/windows/basemenu/NewUnitTransferDialog.py index 50c44572..5b58cc4f 100644 --- a/qt_ui/windows/basemenu/NewUnitTransferDialog.py +++ b/qt_ui/windows/basemenu/NewUnitTransferDialog.py @@ -4,7 +4,7 @@ import logging from collections import defaultdict from typing import Callable, Dict, Type -from PySide2.QtCore import Qt +from PySide2.QtCore import Qt, Signal from PySide2.QtWidgets import ( QComboBox, QDialog, @@ -153,6 +153,8 @@ class TransferControls(QGroupBox): class ScrollingUnitTransferGrid(QFrame): + transfer_quantity_changed = Signal() + def __init__(self, cp: ControlPoint, game_model: GameModel) -> None: super().__init__() self.cp = cp @@ -229,6 +231,7 @@ class ScrollingUnitTransferGrid(QFrame): origin_inventory -= 1 controls.set_quantity(self.transfers[unit_type]) origin_inventory_label.setText(str(origin_inventory)) + self.transfer_quantity_changed.emit() def decrease(controls: TransferControls): nonlocal origin_inventory @@ -240,6 +243,7 @@ class ScrollingUnitTransferGrid(QFrame): origin_inventory += 1 controls.set_quantity(self.transfers[unit_type]) origin_inventory_label.setText(str(origin_inventory)) + self.transfer_quantity_changed.emit() transfer_controls = TransferControls("->", increase, "<-", decrease) @@ -276,11 +280,15 @@ class NewUnitTransferDialog(QDialog): layout.addLayout(self.dest_panel) self.transfer_panel = ScrollingUnitTransferGrid(origin, game_model) + self.transfer_panel.transfer_quantity_changed.connect( + self.on_transfer_quantity_changed + ) layout.addWidget(self.transfer_panel) self.submit_button = QPushButton("Create Transfer Order", parent=self) self.submit_button.clicked.connect(self.on_submit) self.submit_button.setProperty("style", "start-button") + self.submit_button.setDisabled(True) layout.addWidget(self.submit_button) def on_submit(self) -> None: @@ -303,3 +311,7 @@ class NewUnitTransferDialog(QDialog): ) self.game_model.transfer_model.new_transfer(transfer) self.close() + + def on_transfer_quantity_changed(self) -> None: + has_transfer_items = any(self.transfer_panel.transfers.values()) + self.submit_button.setDisabled(not has_transfer_items) From 48f26cb181980603c6ffbe37588119bc02732264 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 25 May 2021 00:13:49 -0700 Subject: [PATCH 053/122] Fix Bandar Abbas airfield data. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1114 --- gen/airfields.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen/airfields.py b/gen/airfields.py index da3c53d2..d7c1ea75 100644 --- a/gen/airfields.py +++ b/gen/airfields.py @@ -620,9 +620,9 @@ AIRFIELD_DATA = { tacan=TacanChannel(78, TacanBand.X), tacan_callsign="BND", vor=("BND", MHz(117, 200)), - atc=AtcData(MHz(4, 250), MHz(39, 401), MHz(118, 100), MHz(251, 0)), + atc=AtcData(MHz(4, 250), MHz(39, 400), MHz(118, 100), MHz(251, 0)), ils={ - "21": ("IBND", MHz(333, 800)), + "21": ("IBND", MHz(109, 900)), }, ), "Jiroft": AirfieldData( From d242079a745e95946cf9966157a444f18986d666 Mon Sep 17 00:00:00 2001 From: Brock Greman Date: Tue, 25 May 2021 16:06:11 -0400 Subject: [PATCH 054/122] Making Sweep flight types have appropriate aircraft --- gen/flights/ai_flight_planner_db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/flights/ai_flight_planner_db.py b/gen/flights/ai_flight_planner_db.py index b8438a9c..f0c94171 100644 --- a/gen/flights/ai_flight_planner_db.py +++ b/gen/flights/ai_flight_planner_db.py @@ -396,7 +396,7 @@ AEWC_CAPABLE = [ def aircraft_for_task(task: FlightType) -> List[Type[FlyingType]]: - cap_missions = (FlightType.BARCAP, FlightType.TARCAP) + cap_missions = (FlightType.BARCAP, FlightType.TARCAP, FlightType.SWEEP) if task in cap_missions: return CAP_CAPABLE elif task == FlightType.ANTISHIP: From e6e31fd2346155fff21567ba8c78b7fa6cb01a37 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 25 May 2021 14:23:00 -0700 Subject: [PATCH 055/122] Actually ASAP the ASAP packages. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1117 --- gen/flights/ai_flight_planner.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 726381f9..c37bec94 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -982,7 +982,9 @@ class CoalitionMissionPlanner: logging.error(f"Could not determine mission end time for {package}") continue previous_cap_end_time[package.target] = departure_time - elif not package.auto_asap: + elif package.auto_asap: + package.set_tot_asap() + else: # But other packages should be spread out a bit. Note that take # times are delayed, but all aircraft will become active at # mission start. This makes it more worthwhile to attack enemy From de9651533f4f92ecf4ee2accc9069d953f262ea0 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 25 May 2021 18:46:41 -0700 Subject: [PATCH 056/122] Load map.js explicitly from canvas.html. Without this it's hard to get to map.js in the debug tools since Chrome doesn't know about the anonymous js. Probably improves logging too. --- qt_ui/widgets/map/QLiberationMap.py | 5 ----- resources/ui/map/canvas.html | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/qt_ui/widgets/map/QLiberationMap.py b/qt_ui/widgets/map/QLiberationMap.py index 315920a1..8bf66b27 100644 --- a/qt_ui/widgets/map/QLiberationMap.py +++ b/qt_ui/widgets/map/QLiberationMap.py @@ -167,11 +167,6 @@ class LeafletMap(QWebEngineView, LiberationMap): ) self.setPage(self.page) - self.loadFinished.connect(self.load_finished) - - def load_finished(self) -> None: - self.page.runJavaScript(Path("resources/ui/map/map.js").read_text()) - def set_game(self, game: Optional[Game]) -> None: if game is None: self.map_model.clear() diff --git a/resources/ui/map/canvas.html b/resources/ui/map/canvas.html index 84fcb831..42830fe8 100644 --- a/resources/ui/map/canvas.html +++ b/resources/ui/map/canvas.html @@ -24,6 +24,7 @@ integrity="sha384-XAr1poM2RCR9/QQFki7ylrGSdmvYE0NuHghuRuxb/k9zJQA53y6qR5te5jJRZlcL" crossorigin=""> +