78 Commits

Author SHA1 Message Date
Raffson
dcf4da57b3 Update starlette + fastapi 2025-08-02 19:27:30 +02:00
Raffson
6f825db086 Update h11 2025-08-02 19:27:15 +02:00
Raffson
afa9122885 Bump electron to 28.3.2 2025-08-02 19:09:31 +02:00
Raffson
df8e09a1ad Update npm packages 2025-08-02 19:00:36 +02:00
Druss99
5d038e8247 Add support for Control Point Influence Zones (#540) 2025-08-02 18:47:55 +02:00
Xisco Lladó
ce70952ee0 New campaign Operation_syrian_shield (#544)
* New campaign Operation_syrian_shield

* removed author on player factions. Credited to 'Fuzzle'

* changed recommended factions to the easy way

* Update operation_syrian_shield.yaml

removed mission time, and squadrons start full

* Update operation_syrian_shield.yaml

better campaign description

* added better squadron descriptions

---------

Co-authored-by: Xisco <x.llado@hotelinking.com>
2025-08-02 18:30:15 +02:00
Drexyl
1d16aba678 Add Moose as base plugin (#522) 2025-08-02 18:28:36 +02:00
Revinl
f3156ab51a Northern Guardian campaign for the Germany map by Revinl (#545) 2025-08-02 16:27:52 +00:00
ingax01
ed9fa37341 Updated SU-30 weapon definitions to version v2.8.03 Beta + CWS 3.70 (#546) 2025-08-02 18:20:01 +02:00
Starfire13
12aa1ee287 Add sniper pod to Viper loadout (#549) 2025-08-02 18:15:07 +02:00
Druss99
7e755f1eb1 bump pydcs (#548) 2025-07-28 22:18:29 +02:00
Starfire13
3da1689767 Fixed typos in Tetrarch description (#542) 2025-07-21 16:53:02 +02:00
Raffson
0671e45dde Restore squadrons for Essex-transformed carriers 2025-07-20 12:36:48 +02:00
Drexyl
c15b4ac83f Essex as AircraftCarrier hack (#541) 2025-07-19 18:21:33 +00:00
Starfire13
f1eb514295 Crossing the Rubicon improved performance (#539) 2025-07-14 12:38:57 +02:00
Raffson
df8f1c4291 Fix some auto-rotate issues in exercise quasar 2025-07-13 19:19:09 +02:00
Raffson
c32525b542 Formatting -_- 2025-07-13 19:05:10 +02:00
Raffson
db14b691cc Make F4U-1D Carrier/LHA capable 2025-07-13 18:55:09 +02:00
Raffson
052a04ca05 Properly support Essex carrier 2025-07-13 18:41:20 +02:00
Raffson
ad100a1a17 Overrride WFMR-window's reject to properly reset game-state 2025-07-13 13:46:57 +02:00
Drexyl
4412a0fa91 Add Tornado F3 ADV (1.0) mod support 2025-07-13 13:35:53 +02:00
Starfire13
23a7add2f1 Add missing Apache and FC Tiger II to Blufor Late Cold War faction (#538) 2025-07-13 13:34:21 +02:00
Starfire13
040362b333 Add Viet Cong 1965 faction (#537) 2025-07-13 13:32:59 +02:00
Starfire13
4155afc69a Set performance to 3/3 for Crossing The Rubicon (#536)
Setting this to 3/3 for now as folks are having performance issues
2025-07-13 13:32:05 +02:00
Starfire13
cf84c03d8f Implements campaign inversion for 13 of Starfire's campaigns (#535) 2025-07-13 13:31:32 +02:00
Starfire13
336384cd74 Implement campaign inversion for Crossing the Rubicon (#534) 2025-07-13 13:30:27 +02:00
Druss99
da7d3a3f1a Fix S-3B unable to do OCA/Aircraft (#533) 2025-07-08 22:25:40 +00:00
Starfire13
1231cb145d Add Germany Cold War campaign (#530) 2025-07-09 00:16:50 +02:00
Drexyl
47488a0bdd F4U-1D Banner Image (#529) 2025-07-08 07:55:58 +02:00
Starfire13
015859e91e F4U-1D loadouts (#528) 2025-07-08 00:39:34 +02:00
Raffson
9c0d114085 Save compat fix for Sinai's renamed Palmahim to Palmachim 2025-07-06 22:40:23 +02:00
Raffson
f907356f93 Pydcs update for new Sinai airports + save-compat fix 2025-07-06 22:37:07 +02:00
Raffson
fcb610423b Update beacon-data 2025-07-06 22:12:32 +02:00
Raffson
3086f64e98 F4U-1D support except banner & payloads 2025-07-06 22:09:50 +02:00
Raffson
5592a834c9 Downgrade h11 to 0.14 2025-07-06 21:59:09 +02:00
Raffson
1e48affc1c Add Japanese WW2 ground units 2025-07-06 21:59:09 +02:00
Raffson
f27b6e28e0 Add support Essex 2025-07-06 21:58:59 +02:00
Raffson
d0ff271a79 Update pydcs for 2.9.17.12034 2025-07-06 19:31:05 +02:00
Cedric Menard
9a00a60cd4 Initial support for Germany Cold War (#518)
* Initial support of Germany Cold War terrain

* Updated with latest beacon import

* Updated changelog and ran black

* Fixed the GermanyCW landmap and naming scheme

* Temporarily changed the requirements for pydcs to my branch (will switch back when merged)

* Updated landmap for germanycw with even fewer exclusions

* Removed unnecessary changes

* Updated requirements to lastest pydcs

* Fixed naming issues for Germany

* Update pydcs to latest commit for GCW support

* Add landmap to game.theater.__init__

* Update requirements.txt

* Resolve PyCharm type-waring

* Updated pydcs and exclusion of germany

* Updated land and sea shapefiles for Germany Cold War with new map limits

---------

Co-authored-by: Raffson <Raffson@users.noreply.github.com>
2025-07-06 19:30:00 +02:00
MrPozor
5254ef3442 Fix #304: Waypoint numbers should start at 0 on map (#526) 2025-06-11 19:50:30 +02:00
MrPozor
fe8efbe905 Revert "Waypoint numbers should start at 0 on map. (#524)" (#525) 2025-06-10 21:28:14 +02:00
MrPozor
48040d7306 Waypoint numbers should start at 0 on map. (#524) 2025-06-09 22:58:15 +02:00
Raffson
f3ed25b5b2 Make EPLRS configurable
Resolves #517
2025-06-07 22:04:56 +02:00
Raffson
2d15db1932 Update h11 to 0.16.0 2025-06-07 19:40:19 +02:00
Raffson
1fa1f830d4 Update bug-report templates for v1.4.1 2025-06-07 19:33:05 +02:00
Raffson
0c0291fc5e Changelog for v1.4.1 2025-06-07 19:32:29 +02:00
Raffson
24c6b62ad4 Fix missing check in handle_ew_jamming w.r.t. plugin option 2025-06-07 19:23:36 +02:00
Starfire13
8c9343e0db Campaign inversion fix for Operation Vectron's Claw (#520) 2025-06-07 16:04:56 +02:00
Starfire13
a33da01af6 Blufor Late Cold War & Russia 1980 faction update (#521) 2025-06-07 16:03:40 +02:00
Starfire13
ce8ccb0227 Update README.md with correct link to preview builds page on the wiki (#519) 2025-05-30 13:10:07 +02:00
Drexyl
68a9dbd141 Update Grinnelli Designs F-22A Mod to 2.0.0 (May 2025) (#515) 2025-05-28 00:54:14 +02:00
Drexyl
4c3f0a82d9 Add EA-6B Prowler to ALQ-99 Jammer Pod (#516) 2025-05-28 00:48:55 +02:00
Starfire13
dc85287cd8 Add locales to Ukraine factions (#513)
Co-authored-by: Raffson <Raffson@users.noreply.github.com>
2025-05-24 15:48:38 +00:00
szcz13
65f4a2cf86 Added new and updated weapons CLSIDs and payloads for MiG-31BM mod (#514) 2025-05-24 17:38:16 +02:00
Druss99
02de6d325a Add invisible FOBs (#504)
Co-authored-by: Raffson <Raffson@users.noreply.github.com>
2025-05-18 17:50:47 +02:00
Druss99
7b16967641 Prevent saving packages with Escorts only (#509)
Fixes a bug that would later pop up when trying to calculate start-times...
Co-authored-by: Raffson <Raffson@users.noreply.github.com>
2025-05-17 15:58:35 +00:00
Starfire13
0e7ea0050f Add OCA-Aircraft to B-21's tasks (#510)
Co-authored-by: Raffson <Raffson@users.noreply.github.com>
2025-05-17 15:57:12 +00:00
Starfire13
ec0e64eaf4 Add Growler + Raptor squadrons to some campaigns (#505) 2025-05-17 17:55:41 +02:00
szcz13
b12169f180 Update for MiG-31BM v2.6 (#512)
* Add files via upload

* Add files via upload

* Update start_generator.py

* Update faction.py

* Update QNewGameWizard.py

* Update QGeneratorSettings.py

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Update MiG-31BM.lua

* Added SEAD Escort to MiG-31BM.yaml

* mig31bm.py fixed weapon injection

* Update mig31bm.py

formatted black

* Update faction.py

reformatted black

* Update start_generator.py

reformatted black

* Update __init__.py

* Update QGeneratorSettings.py

reformatted black

* added support for MiG-31BM mod

* Commit changes which can't seem to be discarded...

* Remove (presumably) accidentally copied file

* Remove unused imports

* Updated MiG-31BM mod version in QGeneratorSettings.py

* Added new Kh-31P missile to MiG-31BM mod

* Added new Kh-31P missile to MiG-31BM mod

* Updated MiG-31BM mod payloads for a new Kh-31P.lua

* Remove double entry

---------

Co-authored-by: Raffson <Raffson@users.noreply.github.com>
2025-05-17 15:55:05 +00:00
Raffson
3a5d0e831c Formatting -_- 2025-05-10 16:40:57 +02:00
Raffson
903a6c4d5f Update changelog 2025-05-07 20:12:03 +02:00
Raffson
e36f07a3ff Preference option to set up preferences on every start (#503) 2025-05-07 20:02:21 +02:00
Raffson
2d65a038ee Remove print statements 2025-05-06 17:24:29 +02:00
Raffson
09617adc56 Passive defense for non-air-to-air flights in package with jammer 2025-05-01 19:57:01 +02:00
Raffson
01832b6594 Add MPS-410 to weapons data 2025-05-01 19:41:02 +02:00
Raffson
30ad71f93b Refactor & improve EW-jamming setup in mission-generator 2025-05-01 17:22:46 +02:00
Raffson
4f8ce77e50 Add "has_built_in_ecm" field to AircraftType
To be used with EW-jamming script...
2025-05-01 17:21:52 +02:00
Raffson
464ece60da Save-compat fix w.r.t. renamed airfield 2025-04-21 21:24:32 +02:00
Raffson
cafaea897d Pydcs update for new Lappi airfields 2025-04-21 21:21:36 +02:00
Raffson
58820dd6c6 Update Lappi beacons 2025-04-21 21:18:29 +02:00
Starfire13
8e845e6a27 Add Tornado IDS to Blufor Late Cold War faction (#502)
Add missing Tornado IDS
2025-04-21 18:04:13 +02:00
Raffson
e1b55816e3 Update actions/checkout to v4 2025-04-20 23:21:00 +02:00
Raffson
e95661c6a2 Update actions/setup-node to v4 2025-04-20 23:17:23 +02:00
Raffson
c96e0d8f28 Update actions/setup-python to v5? 2025-04-20 23:14:52 +02:00
Raffson
dfb65facb5 Another attempt at fixing the pipeline -_- 2025-04-20 23:01:22 +02:00
Raffson
8c6ca4de5f Pin python version for black in lint.yml 2025-04-20 22:58:19 +02:00
Raffson
1c3dee2098 Pydcs data update 2025-04-19 17:49:21 +02:00
Raffson
170e432008 Preparations for v1.5.0 2025-04-14 21:34:17 +02:00
147 changed files with 289186 additions and 24749 deletions

View File

@@ -31,7 +31,7 @@ body:
If the bug was found in a test/development build, select "Test build" or "Development build"
and provide a link to the applicable build in the field below.
options:
- v1.3.1
- v1.4.1
- Test build
- type: input
attributes:

View File

@@ -39,7 +39,7 @@ body:
If the bug was found in a test/development build, select "Test build" or "Development build"
and provide a link to the applicable build in the field below.
options:
- 1.3.1
- 1.4.1
- Test build
- type: input
attributes:

View File

@@ -4,7 +4,7 @@ runs:
using: composite
steps:
- name: Set up Node
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: "16"
cache: npm

View File

@@ -4,7 +4,7 @@ runs:
using: composite
steps:
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip

View File

@@ -12,7 +12,7 @@ jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true

View File

@@ -7,8 +7,8 @@ jobs:
name: Black
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: psf/black@stable
with:
src: "."
@@ -18,7 +18,7 @@ jobs:
name: Type checking
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true

View File

@@ -14,7 +14,7 @@ jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true

View File

@@ -5,7 +5,7 @@ jobs:
name: Python tests
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true
@@ -24,7 +24,7 @@ jobs:
name: Typescript tests
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up JS environment
uses: ./.github/actions/setup-liberation-js

View File

@@ -68,7 +68,7 @@ Our plans for future releases can be found on our
[Projects page](https://github.com/dcs-retribution/dcs-retribution/projects).
Each planned release has a Project, and the page for that project has columns for to do,
in progress, and done. Items in the Done column are in the
[preview build](https://github.com/dcs-retribution/dcs-retribution/wiki/Betas)
[preview build](https://github.com/dcs-retribution/dcs-retribution/wiki/Preview-builds)
for that release. Items in the To do column are planned to be added to that release.
## Resources

View File

@@ -1,3 +1,24 @@
# Retribution v1.5.0
## Features/Improvements
* **[Campaigns]** Ability to define invisible FOBs
* **[Plugins]** Improvements to AI support for EW Script 2.0
* **[Config]** New preference setting to trigger the first-start window on every start (could help in scenarios multiple Retribution instances need to run concurrently)
* **[Modding]** Update Grinelli Designs F-22A Mod to 2.0.0 (May 2025)
* **[Campaign Design]** Added support for Germany Cold War terrain by Ugra Media
* **[Options]** New option to control EPLRS-task injection in mission generator
* **[Modding]** Add Tornado F3 ADV (v1.0, requires FC3 fix)
## Fixes
* **[Flight Plans]** Fixed a bug when a package was created with only escort flights
* **[Flight Plans]** Added AntiShipStrike as a fallback task for OCA/Aircraft to fix a bug where the S-3B could not do OCA/Aircraft
# Retribution v1.4.1 (hotfix)
## Fixes
* **[Plugins]** Avoid injecting jamming-tasks for player-controller aircraft when EW-Jamming plugin is disabled
# Retribution v1.4.0
## Features/Improvements

22917
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -66,7 +66,7 @@
"@types/leaflet": "^1.9.8",
"@types/redux-logger": "^3.0.13",
"@types/websocket": "^1.0.10",
"electron": "^22.3.27",
"electron": "^28.3.2",
"electron-is-dev": "^2.0.0",
"generate-license-file": "^2.0.0",
"identity-obj-proxy": "^3.0.0",

View File

@@ -60,7 +60,7 @@ const WaypointMarker = (props: WaypointMarkerProps) => {
useEffect(() => {
const waypoint = props.waypoint;
marker.current?.setTooltipContent(
`${props.number} ${waypoint.name}<br />` +
`${props.number-1} ${waypoint.name}<br />` +
`${waypoint.altitude_ft.toFixed()} ft ${waypoint.altitude_reference}<br />` +
waypoint.timing
);

View File

@@ -7,9 +7,9 @@
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = "DCS Retribution"
copyright = "2024, DCS Retribution Team"
copyright = "2025, DCS Retribution Team"
author = "DCS Retribution Team"
release = "1.4.0"
release = "1.5.0"
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

View File

@@ -16,6 +16,7 @@ from dcs.terrain import Airport
from dcs.unitgroup import PlaneGroup, ShipGroup, StaticGroup, VehicleGroup
from dcs.vehicles import AirDefence, Armor, MissilesSS, Unarmed
from game.controlpoint_influenceradius import ControlPointInfluenceRadius, point_in_zone
from game.point_with_heading import PointWithHeading
from game.positioned import Positioned
from game.profiling import logged_duration
@@ -24,6 +25,7 @@ from game.theater.controlpoint import (
Airfield,
Carrier,
ControlPoint,
ControlPointType,
Fob,
Lha,
OffMapSpawn,
@@ -53,6 +55,7 @@ class MizCampaignLoader:
FOB_UNIT_TYPE = Unarmed.SKP_11.id
FARP_HELIPADS_TYPE = ["Invisible FARP", "SINGLE_HELIPAD", "FARP"]
INVISIBLE_FOB_UNIT_TYPE = Unarmed.M_818.id
OFFSHORE_STRIKE_TARGET_UNIT_TYPE = Fortification.Oil_platform.id
SHIP_UNIT_TYPE = USS_Arleigh_Burke_IIa.id
@@ -166,6 +169,11 @@ class MizCampaignLoader:
if group.units[0].type == self.FOB_UNIT_TYPE:
yield group
def invisible_fobs(self, blue: bool) -> Iterator[VehicleGroup]:
for group in self.country(blue).vehicle_group:
if group.units[0].type == self.INVISIBLE_FOB_UNIT_TYPE:
yield group
@property
def ships(self) -> Iterator[ShipGroup]:
for group in self.red.ship_group:
@@ -272,6 +280,12 @@ class MizCampaignLoader:
def scenery(self) -> List[SceneryGroup]:
return SceneryGroup.from_trigger_zones(self.mission.triggers._zones)
@cached_property
def cp_influence_zones(self) -> List[ControlPointInfluenceRadius]:
return ControlPointInfluenceRadius.from_trigger_zones(
self.mission.triggers._zones
)
@cached_property
def control_points(self) -> dict[UUID, ControlPoint]:
control_points = {}
@@ -312,6 +326,24 @@ class MizCampaignLoader:
control_point.captured_invert = fob.late_activation
control_points[control_point.id] = control_point
for fob in self.invisible_fobs(blue):
ctld_zones = self.get_ctld_zones(fob.name)
control_point = Fob(
str(fob.name),
fob.position,
self.theater,
starts_blue=blue,
ctld_zones=ctld_zones,
is_invisible=True,
)
control_point.captured_invert = fob.late_activation
control_points[control_point.id] = control_point
if self.cp_influence_zones:
for cp in control_points.values():
for influence_radius in self.cp_influence_zones:
if cp.full_name == influence_radius.cp_name:
cp.influence_radius = influence_radius
return control_points
@property
@@ -471,7 +503,59 @@ class MizCampaignLoader:
def objective_info(
self, near: Positioned, allow_naval: bool = False
) -> Tuple[ControlPoint, Distance]:
closest = self.theater.closest_control_point(near.position, allow_naval)
zones_containing_point = [
z
for z in self.cp_influence_zones
if point_in_zone(z.zone_def, near.position)
]
# Ensure we only consider naval control points if allow_naval is True
candidates = [
self.theater.control_point_named(z.cp_name) for z in zones_containing_point
]
if not allow_naval:
candidates = [
cp
for cp in candidates
if cp.cptype
not in [
ControlPointType.AIRCRAFT_CARRIER_GROUP,
ControlPointType.LHA_GROUP,
]
]
if candidates:
closest = min(
candidates, key=lambda cp: cp.position.distance_to_point(near.position)
)
distance = meters(closest.position.distance_to_point(near.position))
return closest, distance
# If no zones contain the point, find the closest control point without an influence radius
if not allow_naval:
fallback_candidates = [
cp
for cp in self.theater.controlpoints
if cp.cptype
not in [
ControlPointType.AIRCRAFT_CARRIER_GROUP,
ControlPointType.LHA_GROUP,
]
]
else:
fallback_candidates = self.theater.controlpoints
fallback_candidates = [
cp for cp in fallback_candidates if not cp.influence_radius
]
if not fallback_candidates:
raise RuntimeError(
f"All control points have an influence zone but no zones contain {near} at {near.position}"
)
closest = min(
fallback_candidates,
key=lambda cp: cp.position.distance_to_point(near.position),
)
distance = meters(closest.position.distance_to_point(near.position))
return closest, distance

View File

@@ -0,0 +1,65 @@
from __future__ import annotations
from typing import Iterable, List, TYPE_CHECKING
from functools import cached_property
from dcs.mapping import Polygon
from dcs.triggers import TriggerZone, TriggerZoneCircular, TriggerZoneQuadPoint
from game.theater.theatergroundobject import NAME_BY_CATEGORY
if TYPE_CHECKING:
from dcs.mapping import Point
class ControlPointInfluenceRadiusError(RuntimeError):
"""Error for when there are insufficient conditions to create a ControlPointInfluenceRadius."""
pass
class ControlPointInfluenceRadius:
"""Store information about a scenery objective."""
def __init__(self, zone_def: TriggerZone, cp_name: str) -> None:
self.zone_def = zone_def
self.position = zone_def.position
self.cp_name = cp_name
@staticmethod
def from_trigger_zones(
trigger_zones: Iterable[TriggerZone],
) -> List[ControlPointInfluenceRadius]:
"""Define scenery objectives based on their encompassing blue/red circle."""
zone_definitions = []
cp_influence_zones = []
for zone in trigger_zones:
if ControlPointInfluenceRadius.is_red(zone):
zone_definitions.append(zone)
# For each objective definition.
for zone_def in zone_definitions:
if len(zone_def.properties) == 0:
raise ControlPointInfluenceRadiusError(
"Undefined ControlPointInfluenceRadius category in TriggerZone: "
+ zone_def.name
)
zone_def_cp_name = zone_def.properties[1].get("value")
cp_influence_zones.append(
ControlPointInfluenceRadius(zone_def, zone_def_cp_name)
)
return cp_influence_zones
@staticmethod
def is_red(zone: TriggerZone) -> bool:
# Red in RGB is [1 Red], [0 Green], [0 Blue]. Ignore the fourth position: Transparency.
return zone.color[1] == 1 and zone.color[2] == 0 and zone.color[3] == 0
def point_in_zone(zone: TriggerZone, pos: Point) -> bool:
if isinstance(zone, TriggerZoneCircular):
return zone.position.distance_to_point(pos) < zone.radius
elif isinstance(zone, TriggerZoneQuadPoint):
return Polygon(pos._terrain, zone.verticies).point_in_poly(pos)
raise RuntimeError(f"Invalid trigger-zone: {zone.name}")

View File

@@ -6,6 +6,7 @@ REQUIRED_BUILDINGS = [
"ammo",
"factory",
"fob",
"invisiblefob",
"oil",
]

View File

@@ -60,6 +60,7 @@ class GroupTask(Enum):
FARP = ("Farp", GroupRole.BUILDING)
FOB = ("FOB", GroupRole.BUILDING)
FUEL = ("Fuel", GroupRole.BUILDING)
INVISIBLE_FOB = ("InvisibleFOB", GroupRole.BUILDING)
OFFSHORE_STRIKE_TARGET = ("OffShoreStrikeTarget", GroupRole.BUILDING)
OIL = ("Oil", GroupRole.BUILDING)

View File

@@ -41,6 +41,8 @@ from game.radio.channels import (
WarthogChannelNamer,
PhantomChannelNamer,
KiowaChannelNamer,
ARC5RadioChannelAllocator,
ARC5ChannelNamer,
)
from game.utils import (
Distance,
@@ -94,6 +96,7 @@ class RadioConfig:
return None
allocator_type: Type[RadioChannelAllocator] = {
"SCR-522": SCR522RadioChannelAllocator,
"ARC-5": ARC5RadioChannelAllocator,
"common": CommonRadioChannelAllocator,
"farmer": FarmerRadioChannelAllocator,
"noop": NoOpChannelAllocator,
@@ -105,6 +108,7 @@ class RadioConfig:
def make_namer(cls, config: dict[str, Any]) -> Type[ChannelNamer]:
return {
"SCR-522": SCR522ChannelNamer,
"ARC-5": ARC5ChannelNamer,
"default": ChannelNamer,
"huey": HueyChannelNamer,
"mirage": MirageChannelNamer,
@@ -229,6 +233,10 @@ class AircraftType(UnitType[Type[FlyingType]]):
# when no TGP is mounted on any station.
has_built_in_target_pod: bool
# indicates if the aircraft has a built-in jammer allowing EWJamming to be used
# without the need for a jamming pod
has_built_in_ecm: bool
task_priorities: dict[FlightType, int]
laser_code_configs: list[LaserCodeConfig]
@@ -591,6 +599,7 @@ class AircraftType(UnitType[Type[FlyingType]]):
can_carry_crates=data.get("can_carry_crates", aircraft.helicopter),
task_priorities=task_priorities,
has_built_in_target_pod=data.get("has_built_in_target_pod", False),
has_built_in_ecm=data.get("has_built_in_ecm", False),
laser_code_configs=[
LaserCodeConfig.from_yaml(d) for d in data.get("laser_codes", [])
],

View File

@@ -865,6 +865,9 @@ class Faction:
# MiG-31BM
if not mod_settings.mig31bm_foxhound:
self.remove_aircraft("MiG-31BM")
# Tornado f.3 ADV (1.0)
if not mod_settings.tornado_adv:
self.remove_aircraft("Tornado_ADV")
def remove_aircraft(self, name: str) -> None:
for aircraft_set in [self.aircraft, self.awacs, self.tankers]:

View File

@@ -288,6 +288,8 @@ class BuildingLayout(TgoLayout):
@property
def category(self) -> str:
for task in self.tasks:
if task is GroupTask.INVISIBLE_FOB:
return "fob"
if task not in [GroupTask.STRIKE_TARGET, GroupTask.OFFSHORE_STRIKE_TARGET]:
return task.description.lower()
raise RuntimeError(f"Building Template {self.name} has no building category")

View File

@@ -192,7 +192,8 @@ class AircraftBehavior:
@staticmethod
def configure_eplrs(group: FlyingGroup[Any], flight: Flight) -> None:
if flight.unit_type.eplrs_capable:
eplrs_enabled = flight.coalition.game.settings.eplrs_enabled
if eplrs_enabled and flight.unit_type.eplrs_capable:
group.points[0].tasks.append(EPLRS(group.id))
def configure_cap(self, group: FlyingGroup[Any], flight: Flight) -> None:
@@ -306,7 +307,7 @@ class AircraftBehavior:
)
def configure_oca_strike(self, group: FlyingGroup[Any], flight: Flight) -> None:
self.configure_task(flight, group, CAS, [AFAC, SEAD])
self.configure_task(flight, group, CAS, [AFAC, SEAD, AntishipStrike])
self.configure_behavior(
flight,
group,

View File

@@ -13,6 +13,7 @@ from dcs.datalinks.datalink import DataLinkType
from dcs.datalinks.datalinkbase import DataLinkSettingsWithFlightLead
from dcs.datalinks.link16 import Link16Network, ViperLink16NetworkMemberLink
from dcs.mission import Mission
from dcs.task import RunScript
from dcs.terrain.terrain import NoParkingSlotError
from dcs.triggers import TriggerOnce, Event
from dcs.unit import Skill
@@ -341,16 +342,49 @@ class AircraftGenerator:
def _track_ewrj_flight(self, flight: Flight, group: FlyingGroup[Any]) -> None:
if not self.ewrj_package_dict.get(id(flight.package)):
self.ewrj_package_dict[id(flight.package)] = []
added = False
if (
flight.package.primary_flight
and flight is flight.package.primary_flight
or flight.client_count
not flight.flight_type.is_air_to_air
and any(
[
wpt
for wpt in group.points
if wpt.name in ["JOIN", "SPLIT", "RACETRACK START", "RACETRACK END"]
and any(
[
t
for t in wpt.tasks
if isinstance(t, RunScript)
and (
"Djamming" in t.params["action"]["params"]["command"]
or "EWjamm" in t.params["action"]["params"]["command"]
)
]
)
]
)
and (
not self.need_ecm
or flight.any_member_has_weapon_of_type(WeaponType.JAMMER)
or flight.squadron.aircraft.has_built_in_ecm
)
):
self.ewrj_package_dict[id(flight.package)].append(group)
added = True
if (
added
or not flight.flight_type.is_air_to_air
and self.ewrj_package_dict[id(flight.package)]
):
for f in flight.package.flights:
if f is flight or f.group_id == 0 or f.flight_type.is_air_to_air:
continue
g = self.mission.find_group_by_id(f.group_id)
if (
isinstance(g, FlyingGroup)
and g not in self.ewrj_package_dict[id(flight.package)]
):
self.ewrj_package_dict[id(flight.package)].append(g)
def _reserve_frequencies_and_tacan(self, ato: AirTaskingOrder) -> None:
for package in ato.packages:

View File

@@ -185,6 +185,8 @@ class FlightGroupConfigurator:
if not member.is_player:
return
settings = self.flight.coalition.game.settings
if not settings.plugin_option("ewrj"):
return
# Check if ecm_required option is enabled
jammer_required = settings.plugin_option("ewrj.ecm_required")
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)

View File

@@ -9,13 +9,10 @@ from dcs.task import (
OptFormation,
Targets,
SetUnlimitedFuelCommand,
RunScript,
OptReactOnThreat,
)
from game.ato import FlightType
from game.data.doctrine import Doctrine
from game.data.weapons import WeaponType
from game.theater import NavalControlPoint
from game.utils import nautical_miles, feet
from .pydcswaypointbuilder import PydcsWaypointBuilder
@@ -64,7 +61,12 @@ class JoinPointBuilder(PydcsWaypointBuilder):
FlightType.SEAD,
FlightType.SEAD_ESCORT,
]:
self.start_defensive_jamming(waypoint)
settings = self.flight.coalition.game.settings
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
self.offensive_jamming(waypoint, "start")
self.defensive_jamming(waypoint, "start")
if self.flight.flight_type == FlightType.SEAD_ESCORT:
self.handle_sead_escort(doctrine, waypoint)
# Let the AI use ECM to preemptively defend themselves.
@@ -104,28 +106,6 @@ class JoinPointBuilder(PydcsWaypointBuilder):
vertical_spacing=doctrine.sead_escort_spacing.feet,
)
def start_defensive_jamming(self, waypoint: MovingPoint) -> None:
# Start Defensive Jamming
settings = self.flight.coalition.game.settings
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
ecm_required = settings.plugin_option("ewrj.ecm_required")
has_jammer = False
for unit, member in zip(self.group.units, self.flight.iter_members()):
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)
if ecm_required and not has_jammer:
continue
if not member.is_player:
script_content = f'startDjamming("{unit.name}")'
start_jamming_script = RunScript(script_content)
waypoint.tasks.append(start_jamming_script)
has_jammer = True
if has_jammer:
passive_defense = OptReactOnThreat(
OptReactOnThreat.Values.PassiveDefense
)
waypoint.tasks.append(passive_defense)
def configure_escort_tasks(
self,
waypoint: MovingPoint,

View File

@@ -13,6 +13,7 @@ from game.ato import Flight, FlightWaypoint
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.starttype import StartType
from game.ato.traveltime import GroundSpeed
from game.data.weapons import WeaponType
from game.missiongenerator.missiondata import MissionData
from game.theater import MissionTarget, TheaterUnit, OffMapSpawn
@@ -157,3 +158,31 @@ class PydcsWaypointBuilder:
self.group.units[0].unit_type in (F_14A_135_GR, F_14B)
):
self.group.add_nav_target_point(self.waypoint.position, "IP")
def defensive_jamming(self, waypoint: MovingPoint, action: str) -> None:
# Explodes incoming missiles within the jamming bubble through the EW-Jamming script
settings = self.flight.coalition.game.settings
ecm_required = settings.plugin_option("ewrj.ecm_required")
for unit, member in zip(self.group.units, self.flight.iter_members()):
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)
built_in_jammer = self.flight.squadron.aircraft.has_built_in_ecm
if ecm_required and not (has_jammer or built_in_jammer):
continue
if not member.is_player:
script_content = f'{action}Djamming("{unit.name}")'
jamming_script = RunScript(script_content)
waypoint.tasks.append(jamming_script)
def offensive_jamming(self, waypoint: MovingPoint, action: str) -> None:
# Silences enemy radars through the EW-Jamming script
settings = self.flight.coalition.game.settings
ecm_required = settings.plugin_option("ewrj.ecm_required")
for unit, member in zip(self.group.units, self.flight.iter_members()):
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)
built_in_jammer = self.flight.squadron.aircraft.has_built_in_ecm
if ecm_required and not (has_jammer or built_in_jammer):
continue
if not member.is_player:
script_content = f'{action}EWjamm("{unit.name}")'
stop_jamming_script = RunScript(script_content)
waypoint.tasks.append(stop_jamming_script)

View File

@@ -9,8 +9,6 @@ from dcs.task import (
Tanker,
Targets,
SetUnlimitedFuelCommand,
RunScript,
OptReactOnThreat,
)
from game.ato import FlightType
@@ -40,21 +38,11 @@ class RaceTrackBuilder(PydcsWaypointBuilder):
)
return
if self.flight.flight_type == FlightType.AEWC:
# Start Offensive Jamming for all AWACS flights
settings = self.flight.coalition.game.settings
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
# all units in group are AWACS, no specific checks needed
for unit, member in zip(self.group.units, self.flight.iter_members()):
script_content = f'startEWjamm("{unit.name}")'
start_jamming_script = RunScript(script_content)
waypoint.tasks.append(start_jamming_script)
passive_defense = OptReactOnThreat(
OptReactOnThreat.Values.PassiveDefense
)
waypoint.tasks.append(passive_defense)
# Start Defensive Jamming for all flights
settings = self.flight.coalition.game.settings
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
self.defensive_jamming(waypoint, "start")
# NB: It's important that the engage task comes before the orbit task.
# Though they're on the same waypoint, if the orbit task comes first it

View File

@@ -3,8 +3,6 @@ import logging
from dcs.point import MovingPoint
from dcs.task import (
SetUnlimitedFuelCommand,
RunScript,
OptReactOnThreat,
)
from game.ato import FlightType
@@ -20,18 +18,11 @@ class RaceTrackEndBuilder(PydcsWaypointBuilder):
# Disable Offensive Jamming at Racetrack End
if self.flight.flight_type == FlightType.AEWC:
# Stop Offensive Jamming for all AWACS flights
# Stop Defensive Jamming for all AWACS flights
settings = self.flight.coalition.game.settings
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
# all units in group are AWACS, no specific checks needed
for unit, member in zip(self.group.units, self.flight.iter_members()):
script_content = f'stopEWjamming("{unit.name}")'
stop_jamming_script = RunScript(script_content)
waypoint.tasks.append(stop_jamming_script)
evade_fire = OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)
waypoint.tasks.append(evade_fire)
self.defensive_jamming(waypoint, "stop")
def build(self) -> MovingPoint:
waypoint = super().build()

View File

@@ -5,11 +5,9 @@ from dcs.task import (
SetUnlimitedFuelCommand,
SwitchWaypoint,
RunScript,
OptReactOnThreat,
)
from game.ato import FlightType
from game.data.weapons import WeaponType
from game.utils import knots
from .pydcswaypointbuilder import PydcsWaypointBuilder
@@ -55,22 +53,8 @@ class SplitPointBuilder(PydcsWaypointBuilder):
if self.flight.flight_type.is_escort_type:
index = len(self.group.points)
self.group.add_trigger_action(SwitchWaypoint(None, index))
self.stop_defensive_jamming(waypoint)
def stop_defensive_jamming(self, waypoint: MovingPoint) -> None:
# Stop Defensive Jamming
settings = self.flight.coalition.game.settings
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
for unit, member in zip(self.group.units, self.flight.iter_members()):
if settings.plugin_option("ewrj.ecm_required"):
ecm = WeaponType.JAMMER
if not member.loadout.has_weapon_of_type(ecm):
continue
if not member.is_player:
script_content = f'stopDjamming("{unit.name}")'
stop_jamming_script = RunScript(script_content)
waypoint.tasks.append(stop_jamming_script)
evaide_fire = OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)
waypoint.tasks.append(evaide_fire)
settings = self.flight.coalition.game.settings
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
if settings.plugins.get("ewrj") and ai_jammer:
self.offensive_jamming(waypoint, "stop")
self.defensive_jamming(waypoint, "stop")

View File

@@ -9,6 +9,7 @@ import dcs.lua
from dcs import Mission, Point
from dcs.coalition import Coalition
from dcs.countries import country_dict
from dcs.point import MovingPoint
from dcs.task import OptReactOnThreat
from dcs.terrain import Airport
from dcs.unit import Static
@@ -131,28 +132,42 @@ class MissionGenerator:
return self.unit_map
@staticmethod
def _configure_ewrj(gen: AircraftGenerator) -> None:
def _configure_react_to_threat_for_ew_jamming_packages(
gen: AircraftGenerator,
) -> None:
for groups in gen.ewrj_package_dict.values():
optrot = [
task
for task in groups[0].points[0].tasks
if isinstance(task, OptReactOnThreat)
][0]
assert isinstance(optrot, OptReactOnThreat)
if (
len(groups) == 1
and optrot.value != OptReactOnThreat.Values.PassiveDefense
):
# primary flight with no EWR-Jamming capability
continue
for group in groups:
tasks = group.points[0].tasks
for i in range(len(tasks)):
if isinstance(tasks[i], OptReactOnThreat):
tasks[i] = OptReactOnThreat(
OptReactOnThreat.Values.PassiveDefense
)
break
start_point = [
p for p in group.points if p.name in ["JOIN", "RACETRACK START"]
]
if not start_point:
sp = group.points[0]
else:
sp = start_point[0]
MissionGenerator.set_react_to_threat(
OptReactOnThreat.Values.PassiveDefense, sp
)
stop_point = [
p for p in group.points if p.name in ["SPLIT", "RACETRACK END"]
]
if not stop_point:
sp = group.points[0]
else:
sp = stop_point[0]
MissionGenerator.set_react_to_threat(
OptReactOnThreat.Values.EvadeFire, sp
)
@staticmethod
def set_react_to_threat(
optrot: OptReactOnThreat.Values, start_point: MovingPoint
) -> None:
tasks = start_point.tasks
for i in range(len(tasks)):
if isinstance(tasks[i], OptReactOnThreat):
tasks[i] = OptReactOnThreat(optrot)
return
tasks.append(OptReactOnThreat(optrot))
def setup_mission_coalitions(self) -> None:
self.mission.coalition["blue"] = Coalition(
@@ -291,7 +306,7 @@ class MissionGenerator:
flight.aircraft_type.assign_channels_for_flight(flight, self.mission_data)
if self.game.settings.plugins.get("ewrj"):
self._configure_ewrj(aircraft_generator)
self._configure_react_to_threat_for_ew_jamming_packages(aircraft_generator)
def generate_destroyed_units(self) -> None:
"""Add destroyed units to the Mission"""

View File

@@ -386,9 +386,9 @@ class GroundObjectGenerator:
)
self._register_theater_unit(unit, static_group.units[0])
@staticmethod
def enable_eplrs(group: VehicleGroup, unit_type: Type[VehicleType]) -> None:
if unit_type.eplrs:
def enable_eplrs(self, group: VehicleGroup, unit_type: Type[VehicleType]) -> None:
eplrs_enabled = self.game.settings.eplrs_enabled
if eplrs_enabled and unit_type.eplrs:
group.points[0].tasks.append(EPLRS(group.id))
def set_alarm_state(self, group: MovingGroup[Any]) -> None:

View File

@@ -108,6 +108,16 @@ class MigrationUnpickler(pickle.Unpickler):
elif name == "Bas_100":
from dcs.terrain.kola.airports import Vuojarvi
return Vuojarvi
elif name == "Alakourtti":
from dcs.terrain.kola.airports import Alakurtti
return Alakurtti
if module == "dcs.terrain.sinai.airports":
if name == "Borj_El_Arab_International_Airport":
from dcs.terrain.sinai.airports import Borg_El_Arab_International_Airport
return Borg_El_Arab_International_Airport
elif name == "Palmahim":
from dcs.terrain.sinai.airports import Palmachim
return Palmachim
if module == "dcs.terrain.syria.airports":
if name == "Amman":
from dcs.terrain.syria.airports import Marka

View File

@@ -219,6 +219,27 @@ class SCR522RadioChannelAllocator(RadioChannelAllocator):
return "SCR-522"
@dataclass(frozen=True)
class ARC5RadioChannelAllocator(RadioChannelAllocator):
"""Preset channel allocator for the ARC-5 WW2 radios. (4 channels)"""
def assign_channels_for_flight(
self, flight: FlightData, mission_data: MissionData
) -> None:
radio_id = 1
flight.assign_channel(radio_id, 1, flight.intra_flight_channel)
if flight.departure.atc is not None:
flight.assign_channel(radio_id, 2, flight.departure.atc)
if flight.arrival.atc is not None:
flight.assign_channel(radio_id, 3, flight.arrival.atc)
# TODO : Some GCI on Channel 4 ?
@classmethod
def name(cls) -> str:
return "ARC-5"
class ChannelNamer:
"""Base class allowing channel name customization per-aircraft.
@@ -376,6 +397,23 @@ class SCR522ChannelNamer(ChannelNamer):
return "SCR-522"
class ARC5ChannelNamer(ChannelNamer):
"""
Channel namer for F4U-1D Corsair
"""
@staticmethod
def channel_name(radio_id: int, channel_id: int) -> str:
if channel_id > 3:
return "?"
else:
return f"Channel " + "1234"[channel_id - 1]
@classmethod
def name(cls) -> str:
return "ARC-5"
class LegacyWarthogChannelNamer(ChannelNamer):
"""Channel namer for the legacy A-10C."""

View File

@@ -231,6 +231,15 @@ RADIOS: List[Radio] = [
# P-51 / P-47 Radio
# 4 preset channels (A/B/C/D)
Radio("SCR522", (RadioRange(MHz(100), MHz(156), kHz(25), Modulation.AM),)),
# F4U-1D Radio
# 4 preset channels (1/2/3/4)
Radio(
"ARC-5",
(
RadioRange(MHz(100), MHz(150), kHz(25), Modulation.AM),
RadioRange(MHz(220), MHz(390), kHz(25), Modulation.AM),
),
),
# JF-17 Radios should use AM
Radio("R&S M3AR VHF", (RadioRange(MHz(120), MHz(174), kHz(25), Modulation.AM),)),
Radio("R&S M3AR UHF", (RadioRange(MHz(225), MHz(400), kHz(25), Modulation.AM),)),

View File

@@ -49,7 +49,9 @@ class GameJs(BaseModel):
iads_network=IadsNetworkJs.from_network(game.theater.iads_network),
threat_zones=ThreatZoneContainerJs.for_game(game),
navmeshes=NavMeshesJs.from_game(game),
map_center=game.theater.terrain.map_view_default.position.latlng(),
map_center=LeafletPoint.from_latlng(
game.theater.terrain.map_view_default.position.latlng()
),
unculled_zones=UnculledZoneJs.from_game(game),
map_zones=MapZonesJs.from_game(game),
)

View File

@@ -19,6 +19,10 @@ class LeafletPoint(BaseModel):
title = "LatLng"
@staticmethod
def from_latlng(latlng: LatLng) -> LeafletPoint:
return LeafletPoint(lat=latlng.lat, lng=latlng.lng)
LeafletLine = list[LeafletPoint]

View File

@@ -816,6 +816,12 @@ class Settings:
GAMEPLAY_SECTION,
default=True,
)
eplrs_enabled: bool = boolean_option(
"Enable EPLRS",
MISSION_GENERATOR_PAGE,
GAMEPLAY_SECTION,
default=True,
)
generate_dark_kneeboard: bool = boolean_option(
"Generate dark kneeboard",
MISSION_GENERATOR_PAGE,

View File

@@ -2,5 +2,6 @@ from .base import *
from .conflicttheater import *
from .controlpoint import *
from .frontline import FrontLine
from .landmap import *
from .missiontarget import MissionTarget
from .theatergroundobject import SamGroundObject

View File

@@ -40,12 +40,14 @@ from dcs.ships import (
Stennis,
Type_071,
hms_invincible,
Essex,
)
from dcs.terrain.terrain import Airport, ParkingSlot
from dcs.unitgroup import ShipGroup, StaticGroup
from dcs.unittype import ShipType
from game.ato.closestairfields import ObjectiveDistanceCache
from game.controlpoint_influenceradius import ControlPointInfluenceRadius
from game.ground_forces.combat_stance import CombatStance
from game.point_with_heading import PointWithHeading
from game.runways import RunwayAssigner, RunwayData
@@ -377,6 +379,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
theater: ConflictTheater,
starts_blue: bool,
cptype: ControlPointType = ControlPointType.AIRBASE,
is_invisible: bool = False,
) -> None:
super().__init__(name, position)
self.id = uuid.uuid4()
@@ -384,6 +387,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
self.at = at
self.theater = theater
self.starts_blue = starts_blue
self.is_invisible = is_invisible
self.connected_objectives: List[TheaterGroundObject] = []
self.preset_locations = PresetLocations()
self.helipads: List[PointWithHeading] = []
@@ -414,6 +418,8 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
# Initialized late because ControlPoints are constructed before the game is.
self._front_line_db: Database[FrontLine] | None = None
self.influence_radius: ControlPointInfluenceRadius | None = None
def __repr__(self) -> str:
return f"<{self.__class__}: {self.name}>"
@@ -1207,6 +1213,7 @@ class Airfield(ControlPoint, CTLD):
theater: ConflictTheater,
starts_blue: bool,
ctld_zones: Optional[List[Tuple[Point, float]]] = None,
influence_zone: Optional[List[Tuple[Point, float]]] = None,
) -> None:
super().__init__(
airport.name,
@@ -1219,6 +1226,7 @@ class Airfield(ControlPoint, CTLD):
self.airport = airport
self._runway_status = RunwayStatus()
self.ctld_zones = ctld_zones
self.influence_zone = influence_zone
@property
def dcs_airport(self) -> Airport:
@@ -1426,6 +1434,7 @@ class NavalControlPoint(
CVN_72,
CVN_73,
CVN_75,
Essex,
]:
return True
return False
@@ -1506,6 +1515,11 @@ class Carrier(NavalControlPoint):
return "cv"
class EssexCarrier(Carrier):
def can_operate(self, aircraft: AircraftType) -> bool:
return aircraft.lha_capable
class Lha(NavalControlPoint):
def __init__(
self, name: str, at: Point, theater: ConflictTheater, starts_blue: bool
@@ -1618,12 +1632,16 @@ class Fob(ControlPoint, RadioFrequencyContainer, CTLD):
theater: ConflictTheater,
starts_blue: bool,
ctld_zones: Optional[List[Tuple[Point, float]]] = None,
is_invisible: bool = False,
influence_zone: Optional[List[Tuple[Point, float]]] = None,
) -> None:
super().__init__(
name, at, at, theater, starts_blue, cptype=ControlPointType.FOB
)
self.name = name
self.ctld_zones = ctld_zones
self.is_invisible = is_invisible
self.influence_zone = influence_zone
@property
def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]:

View File

@@ -12,6 +12,7 @@ from dcs.mission import Mission
from dcs.terrain.terrain import Terrain
from shapely import geometry, LineString
from shapely.geometry import MultiPolygon, Polygon
import shapely as shp
@dataclass(frozen=True)
@@ -28,6 +29,11 @@ class Landmap:
if not self.sea_zones.is_valid:
raise RuntimeError("Sea zones not valid")
# Generate Spatial Index using `prepare` to improve performance
shp.prepare(self.inclusion_zones)
shp.prepare(self.exclusion_zones)
shp.prepare(self.sea_zones)
@cached_property
def inclusion_zone_only(self) -> MultiPolygon:
return self.inclusion_zones - self.exclusion_zones - self.sea_zones

View File

@@ -13,7 +13,12 @@ from game import Game
from game.factions.faction import Faction
from game.naming import namegen
from game.scenery_group import SceneryGroup
from game.theater import PointWithHeading, PresetLocation, NavalControlPoint
from game.theater import (
PointWithHeading,
PresetLocation,
NavalControlPoint,
EssexCarrier,
)
from game.theater.theatergroundobject import (
BuildingGroundObject,
IadsBuildingGroundObject,
@@ -95,6 +100,7 @@ class ModSettings:
su15_flagon: bool = False
su30_flanker_h: bool = False
su57_felon: bool = False
tornado_adv: bool = False
frenchpack: bool = False
high_digit_sams: bool = False
ov10a_bronco: bool = False
@@ -296,7 +302,9 @@ class GenericCarrierGroundObjectGenerator(ControlPointGroundObjectGenerator):
if go.category in ["CARRIER", "LHA"]
][0]
groups = [
g for g in carrier_go.groups if "Carrier" in g.name or "LHA" in g.name
g
for g in carrier_go.groups
if "carrier" in g.name.lower() or "lha" in g.name.lower()
]
return groups[0].units[0]
@@ -319,6 +327,7 @@ class CarrierGroundObjectGenerator(GenericCarrierGroundObjectGenerator):
logging.error(f"{self.faction_name} has no access to AircraftCarrier")
return False
self.transform_to_essex_if_needed(unit_group)
self.generate_ground_object_from_group(
unit_group,
PresetLocation(
@@ -331,6 +340,25 @@ class CarrierGroundObjectGenerator(GenericCarrierGroundObjectGenerator):
self.apply_carrier_config()
return True
def transform_to_essex_if_needed(self, unit_group: ForceGroup) -> None:
classes = [u.unit_class for u in unit_group.units]
if any([c for c in classes if c == UnitClass.HELICOPTER_CARRIER]) and not any(
[c for c in classes if c == UnitClass.AIRCRAFT_CARRIER]
):
self.game.theater.controlpoints.remove(self.control_point)
sqdrns = self.control_point.squadrons
self.control_point = EssexCarrier(
self.control_point.name,
self.control_point.position,
self.game.theater,
self.control_point.starts_blue,
)
self.control_point.finish_init(self.game)
self.game.theater.controlpoints.append(self.control_point)
for sqdrn in sqdrns:
if sqdrn.aircraft.lha_capable:
sqdrn.location = self.control_point
class LhaGroundObjectGenerator(GenericCarrierGroundObjectGenerator):
def generate(self) -> bool:
@@ -586,14 +614,24 @@ class FobGroundObjectGenerator(AirbaseGroundObjectGenerator):
return False
def generate_fob(self) -> None:
self.generate_building_at(
GroupTask.FOB,
PresetLocation(
self.control_point.name,
self.control_point.position,
self.control_point.heading,
),
)
if self.control_point.is_invisible:
self.generate_building_at(
GroupTask.INVISIBLE_FOB,
PresetLocation(
self.control_point.name,
self.control_point.position,
self.control_point.heading,
),
)
else:
self.generate_building_at(
GroupTask.FOB,
PresetLocation(
self.control_point.name,
self.control_point.position,
self.control_point.heading,
),
)
class GroundObjectGenerator:

View File

@@ -20,6 +20,7 @@ from dcs.terrain import (
Kola,
Afghanistan,
Iraq,
GermanyColdWar,
)
from .conflicttheater import ConflictTheater, THEATER_RESOURCE_DIR
@@ -39,6 +40,7 @@ ALL_TERRAINS = [
Kola(),
Afghanistan(),
Iraq(),
GermanyColdWar(),
]
TERRAINS_BY_NAME = {t.name: t for t in ALL_TERRAINS}

View File

@@ -2,7 +2,7 @@ from pathlib import Path
MAJOR_VERSION = 1
MINOR_VERSION = 4
MINOR_VERSION = 5
MICRO_VERSION = 0

View File

@@ -41,6 +41,7 @@ from .chinesemilitaryassetspack import *
from .russianmilitaryassetspack import *
from .usamilitaryassetspack import *
from .ukrainemilitaryassetspack import *
from .tornado_adv import *
def load_mods() -> None:

View File

@@ -11,6 +11,111 @@ from pydcs_extensions.weapon_injector import inject_weapons
class F22AWeapons:
AIM_9XX = {"clsid": "{AIM-9XX}", "name": "AIM-9XX", "weight": 85}
AIM_120D = {"clsid": "{AIM-120D}", "name": "AIM-120D", "weight": 152}
AIM9X_BLKII_Sidewinder_IR_AAM = {
"clsid": "{AIM9X-BLKII}",
"name": "AIM9X-BLKII Sidewinder IR AAM",
"weight": 85.5,
}
LDTP_Fuel_tank_600_gal = {
"clsid": "{LDTP_FUEL_Tank}",
"name": "LDTP Fuel tank 600 gal",
"weight": 2045.8766885,
}
AIM_120C7___Active_Radar_AAM = {
"clsid": "{AIM-120C-7}",
"name": "AIM-120C7 - Active Radar AAM",
"weight": 161.48,
}
AIM_120C7___Active_Radar_AAM__IRST_POD = {
"clsid": "{AIM_120C-7_IRST_LEFT}",
"name": "AIM-120C7 - Active Radar AAM + IRST POD",
"weight": 266.48,
}
AIM_120C7___Active_Radar_AAM__IRST_POD_ = {
"clsid": "{AIM_120C-7_IRST_RIGHT}",
"name": "AIM-120C7 - Active Radar AAM + IRST POD",
"weight": 266.48,
}
AIM_120C8___Active_Radar_AAM = {
"clsid": "{AIM-120C-8}",
"name": "AIM-120C8 - Active Radar AAM",
"weight": 161.48,
}
AIM_120C8___Active_Radar_AAM__IRST_POD = {
"clsid": "{AIM_120C-8_IRST_LEFT}",
"name": "AIM-120C8 - Active Radar AAM + IRST POD",
"weight": 266.48,
}
AIM_120C8___Active_Radar_AAM__IRST_POD_ = {
"clsid": "{AIM_120C-8_IRST_RIGHT}",
"name": "AIM-120C8 - Active Radar AAM + IRST POD",
"weight": 266.48,
}
AIM_120D3___Active_Radar_AAM = {
"clsid": "{AIM-120D-3}",
"name": "AIM-120D3 - Active Radar AAM",
"weight": 165,
}
AIM_120D3___Active_Radar_AAM__IRST_POD = {
"clsid": "{AIM_120D-3_IRST_LEFT}",
"name": "AIM-120D3 - Active Radar AAM + IRST POD",
"weight": 270,
}
AIM_120D3___Active_Radar_AAM__IRST_POD_ = {
"clsid": "{AIM_120D-3_IRST_RIGHT}",
"name": "AIM-120D3 - Active Radar AAM + IRST POD",
"weight": 270,
}
AIM_260A___Active_Radar_AAM = {
"clsid": "{AIM-260A}",
"name": "AIM-260A - Active Radar AAM",
"weight": 160,
}
AIM_260A___Active_Radar_AAM__IRST_POD = {
"clsid": "{AIM_260A_IRST_LEFT}",
"name": "AIM-260A - Active Radar AAM + IRST POD",
"weight": 265,
}
AIM_260A___Active_Radar_AAM__IRST_POD_ = {
"clsid": "{AIM_260A_IRST_RIGHT}",
"name": "AIM-260A - Active Radar AAM + IRST POD",
"weight": 265,
}
_2x_AIM9X_BLKII_Sidewinder_IR_AAM = {
"clsid": "{LAU_115_2xAIM9X-II}",
"name": "2x AIM9X-BLKII Sidewinder IR AAM",
"weight": 221,
}
_2x_AIM_120C7___Active_Radar_AAM = {
"clsid": "{LAU_115_2xAIM-120C-7}",
"name": "2x AIM-120C7 - Active Radar AAM",
"weight": 372.96,
}
_2x_AIM_120C8___Active_Radar_AAM = {
"clsid": "{LAU_115_2xAIM-120C-8}",
"name": "2x AIM-120C8 - Active Radar AAM",
"weight": 372.96,
}
_2x_AIM_120D3___Active_Radar_AAM = {
"clsid": "{LAU_115_2xAIM-120D-3}",
"name": "2x AIM-120D3 - Active Radar AAM",
"weight": 380,
}
_2x_AIM_260A___Active_Radar_AAM = {
"clsid": "{LAU_115_2xAIM-260A}",
"name": "2x AIM-260A - Active Radar AAM",
"weight": 370,
}
IRST_Sensor_Pod = {
"clsid": "{IRST_SENSOR_Pod}",
"name": "IRST Sensor Pod",
"weight": 105,
}
Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM = {
"clsid": "{MAKO_A2A_C}",
"name": "Mako Multi-Mission Hypersonic Missile - Active Radar AAM",
"weight": 160,
}
inject_weapons(F22AWeapons)
@@ -23,7 +128,7 @@ class F_22A(PlaneType):
height = 4.88
width = 13.05
length = 19.1
fuel_max = 6103
fuel_max = 8200
max_speed = 2649.996
chaff = 120
flare = 120
@@ -46,31 +151,109 @@ class F_22A(PlaneType):
class Pylon1:
AIM_9X_Sidewinder_IR_AAM = (1, Weapons.AIM_9X_Sidewinder_IR_AAM)
AIM_9XX = (1, F22AWeapons.AIM_9XX)
AIM_9M_Sidewinder_IR_AAM = (1, Weapons.AIM_9M_Sidewinder_IR_AAM)
AIM9X_BLKII_Sidewinder_IR_AAM = (1, F22AWeapons.AIM9X_BLKII_Sidewinder_IR_AAM)
class Pylon2:
Fuel_tank_610_gal = (2, Weapons.Fuel_tank_610_gal)
LDTP_Fuel_tank_600_gal = (2, F22AWeapons.LDTP_Fuel_tank_600_gal)
AIM_9X_Sidewinder_IR_AAM = (2, Weapons.AIM_9X_Sidewinder_IR_AAM)
AIM_9M_Sidewinder_IR_AAM = (2, Weapons.AIM_9M_Sidewinder_IR_AAM)
AIM_120C_AMRAAM___Active_Radar_AAM = (
2,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
AIM_120B_AMRAAM___Active_Radar_AAM = (
2,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM = (2, F22AWeapons.AIM_120C7___Active_Radar_AAM)
AIM_120C8___Active_Radar_AAM = (2, F22AWeapons.AIM_120C8___Active_Radar_AAM)
AIM_120D3___Active_Radar_AAM = (2, F22AWeapons.AIM_120D3___Active_Radar_AAM)
# ERRR {LAU_115_2xAIM9X-II}}
_2x_AIM_120C7___Active_Radar_AAM = (
2,
F22AWeapons._2x_AIM_120C7___Active_Radar_AAM,
)
_2x_AIM_120C8___Active_Radar_AAM = (
2,
F22AWeapons._2x_AIM_120C8___Active_Radar_AAM,
)
_2x_AIM_120D3___Active_Radar_AAM = (
2,
F22AWeapons._2x_AIM_120D3___Active_Radar_AAM,
)
_2x_AIM_260A___Active_Radar_AAM = (
2,
F22AWeapons._2x_AIM_260A___Active_Radar_AAM,
)
class Pylon3:
AIM_120C_AMRAAM___Active_Radar_AAM = (
3,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
AIM_120D = (3, F22AWeapons.AIM_120D)
AIM_120B_AMRAAM___Active_Radar_AAM = (
3,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM = (3, F22AWeapons.AIM_120C7___Active_Radar_AAM)
AIM_120C8___Active_Radar_AAM = (3, F22AWeapons.AIM_120C8___Active_Radar_AAM)
AIM_120D3___Active_Radar_AAM = (3, F22AWeapons.AIM_120D3___Active_Radar_AAM)
AIM_260A___Active_Radar_AAM = (3, F22AWeapons.AIM_260A___Active_Radar_AAM)
class Pylon4:
IRST_Sensor_Pod = (4, F22AWeapons.IRST_Sensor_Pod)
AIM_120C_AMRAAM___Active_Radar_AAM = (
4,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
AIM_120D = (4, F22AWeapons.AIM_120D)
AIM_120B_AMRAAM___Active_Radar_AAM = (
4,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM = (4, F22AWeapons.AIM_120C7___Active_Radar_AAM)
AIM_120C8___Active_Radar_AAM = (4, F22AWeapons.AIM_120C8___Active_Radar_AAM)
AIM_120D3___Active_Radar_AAM = (4, F22AWeapons.AIM_120D3___Active_Radar_AAM)
AIM_260A___Active_Radar_AAM = (4, F22AWeapons.AIM_260A___Active_Radar_AAM)
Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM = (
4,
F22AWeapons.Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM__IRST_POD = (
4,
F22AWeapons.AIM_120C7___Active_Radar_AAM__IRST_POD,
)
AIM_120C8___Active_Radar_AAM__IRST_POD = (
4,
F22AWeapons.AIM_120C8___Active_Radar_AAM__IRST_POD,
)
AIM_120D3___Active_Radar_AAM__IRST_POD = (
4,
F22AWeapons.AIM_120D3___Active_Radar_AAM__IRST_POD,
)
AIM_260A___Active_Radar_AAM__IRST_POD = (
4,
F22AWeapons.AIM_260A___Active_Radar_AAM__IRST_POD,
)
class Pylon5:
AIM_120C_AMRAAM___Active_Radar_AAM = (
5,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
AIM_120D = (5, F22AWeapons.AIM_120D)
AIM_120B_AMRAAM___Active_Radar_AAM = (
5,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM = (5, F22AWeapons.AIM_120C7___Active_Radar_AAM)
AIM_120C8___Active_Radar_AAM = (5, F22AWeapons.AIM_120C8___Active_Radar_AAM)
AIM_120D3___Active_Radar_AAM = (5, F22AWeapons.AIM_120D3___Active_Radar_AAM)
AIM_260A___Active_Radar_AAM = (5, F22AWeapons.AIM_260A___Active_Radar_AAM)
Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM = (
5,
F22AWeapons.Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM,
)
class Pylon6:
Smokewinder___red = (6, Weapons.Smokewinder___red)
@@ -84,28 +267,109 @@ class F_22A(PlaneType):
7,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
AIM_120D = (7, F22AWeapons.AIM_120D)
AIM_120B_AMRAAM___Active_Radar_AAM = (
7,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM = (7, Weapons.AIM_120C7___Active_Radar_AAM)
AIM_120C8___Active_Radar_AAM = (7, Weapons.AIM_120C8___Active_Radar_AAM)
AIM_120D3___Active_Radar_AAM = (7, Weapons.AIM_120D3___Active_Radar_AAM)
AIM_260A___Active_Radar_AAM = (7, Weapons.AIM_260A___Active_Radar_AAM)
Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM = (
7,
Weapons.Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM,
)
class Pylon8:
IRST_Sensor_Pod = (8, F22AWeapons.IRST_Sensor_Pod)
AIM_120C_AMRAAM___Active_Radar_AAM = (
8,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
AIM_120D = (8, F22AWeapons.AIM_120D)
AIM_120B_AMRAAM___Active_Radar_AAM = (
8,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM = (8, Weapons.AIM_120C7___Active_Radar_AAM)
AIM_120C8___Active_Radar_AAM = (8, Weapons.AIM_120C8___Active_Radar_AAM)
AIM_120D3___Active_Radar_AAM = (8, Weapons.AIM_120D3___Active_Radar_AAM)
AIM_260A___Active_Radar_AAM = (8, Weapons.AIM_260A___Active_Radar_AAM)
Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM = (
8,
Weapons.Mako_Multi_Mission_Hypersonic_Missile___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM__IRST_POD_ = (
8,
Weapons.AIM_120C7___Active_Radar_AAM__IRST_POD_,
)
AIM_120C8___Active_Radar_AAM__IRST_POD_ = (
8,
Weapons.AIM_120C8___Active_Radar_AAM__IRST_POD_,
)
AIM_120D3___Active_Radar_AAM__IRST_POD_ = (
8,
Weapons.AIM_120D3___Active_Radar_AAM__IRST_POD_,
)
AIM_260A___Active_Radar_AAM__IRST_POD_ = (
8,
Weapons.AIM_260A___Active_Radar_AAM__IRST_POD_,
)
class Pylon9:
AIM_120C_AMRAAM___Active_Radar_AAM = (
9,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
AIM_120D = (9, F22AWeapons.AIM_120D)
AIM_120B_AMRAAM___Active_Radar_AAM = (
9,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM = (9, Weapons.AIM_120C7___Active_Radar_AAM)
AIM_120C8___Active_Radar_AAM = (9, Weapons.AIM_120C8___Active_Radar_AAM)
AIM_120D3___Active_Radar_AAM = (9, Weapons.AIM_120D3___Active_Radar_AAM)
AIM_260A___Active_Radar_AAM = (9, Weapons.AIM_260A___Active_Radar_AAM)
class Pylon10:
Fuel_tank_610_gal = (10, Weapons.Fuel_tank_610_gal)
LDTP_Fuel_tank_600_gal = (10, F22AWeapons.LDTP_Fuel_tank_600_gal)
AIM_9X_Sidewinder_IR_AAM = (10, Weapons.AIM_9X_Sidewinder_IR_AAM)
AIM_9M_Sidewinder_IR_AAM = (10, Weapons.AIM_9M_Sidewinder_IR_AAM)
AIM_120C_AMRAAM___Active_Radar_AAM = (
10,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
AIM_120B_AMRAAM___Active_Radar_AAM = (
10,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C7___Active_Radar_AAM = (10, Weapons.AIM_120C7___Active_Radar_AAM)
AIM_120C8___Active_Radar_AAM = (10, Weapons.AIM_120C8___Active_Radar_AAM)
AIM_120D3___Active_Radar_AAM = (10, Weapons.AIM_120D3___Active_Radar_AAM)
_2x_AIM9X_BLKII_Sidewinder_IR_AAM = (
10,
F22AWeapons._2x_AIM9X_BLKII_Sidewinder_IR_AAM,
)
_2x_AIM_120C7___Active_Radar_AAM = (
10,
F22AWeapons._2x_AIM_120C7___Active_Radar_AAM,
)
_2x_AIM_120C8___Active_Radar_AAM = (
10,
F22AWeapons._2x_AIM_120C8___Active_Radar_AAM,
)
_2x_AIM_120D3___Active_Radar_AAM = (
10,
F22AWeapons._2x_AIM_120D3___Active_Radar_AAM,
)
_2x_AIM_260A___Active_Radar_AAM = (
10,
F22AWeapons._2x_AIM_260A___Active_Radar_AAM,
)
class Pylon11:
AIM_9X_Sidewinder_IR_AAM = (11, Weapons.AIM_9X_Sidewinder_IR_AAM)
AIM_9XX = (11, F22AWeapons.AIM_9XX)
AIM_9M_Sidewinder_IR_AAM = (11, Weapons.AIM_9M_Sidewinder_IR_AAM)
AIM9X_BLKII_Sidewinder_IR_AAM = (11, F22AWeapons.AIM9X_BLKII_Sidewinder_IR_AAM)
pylons: Set[int] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}

View File

@@ -11,20 +11,30 @@ from pydcs_extensions.weapon_injector import inject_weapons
class WeaponsMiG31BM:
Vympel_R_33__AA_9_Amos_ = {
"clsid": "{R-33}",
"clsid": "{R-33_mig31bm}",
"name": "Vympel R-33 (AA-9 Amos)",
"weight": 490,
}
Vympel_R_33S__AA_9_Amos_ = {
"clsid": "{R-33S_mig31bm}",
"name": "Vympel R-33S (AA-9 Amos)",
"weight": 490,
}
Vympel_R_37M__AA_13_Axehead_ = {
"clsid": "{R-37M}",
"clsid": "{R-37M_mig31bm}",
"name": "Vympel R-37M (AA-13 Axehead)",
"weight": 600,
}
Vympel_R_37__AA_13_Axehead_ = {
"clsid": "{R-37}",
"clsid": "{R-37_mig31bm}",
"name": "Vympel R-37 (AA-13 Axehead)",
"weight": 600,
}
Kh_31P__AS_17_Krypton_ = {
"clsid": "{Kh-31_mig31bm}",
"name": "Kh-31P (AS-17 Krypton)",
"weight": 758,
}
inject_weapons(WeaponsMiG31BM)
@@ -57,6 +67,7 @@ class MiG_31BM(PlaneType):
R_77__AA_12_Adder____Active_Rdr = (2, Weapons.R_77__AA_12_Adder____Active_Rdr)
Vympel_R_37M__AA_13_Axehead_ = (2, WeaponsMiG31BM.Vympel_R_37M__AA_13_Axehead_)
Vympel_R_37__AA_13_Axehead_ = (2, WeaponsMiG31BM.Vympel_R_37__AA_13_Axehead_)
Vympel_R_33S__AA_9_Amos_ = (2, WeaponsMiG31BM.Vympel_R_33S__AA_9_Amos_)
Vympel_R_33__AA_9_Amos_ = (2, WeaponsMiG31BM.Vympel_R_33__AA_9_Amos_)
R_40RD__AA_6_Acrid____Semi_Act_Rdr = (
2,
@@ -77,29 +88,30 @@ class MiG_31BM(PlaneType):
)
Fuel_tank_3000L = (2, Weapons.Fuel_tank_3000L)
Fuel_tank_2000L = (2, Weapons.Fuel_tank_2000L)
Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr = (
2,
Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr,
)
Kh_31P__AS_17_Krypton_ = (2, WeaponsMiG31BM.Kh_31P__AS_17_Krypton_)
class Pylon3:
Vympel_R_37M__AA_13_Axehead_ = (3, WeaponsMiG31BM.Vympel_R_37M__AA_13_Axehead_)
Vympel_R_37__AA_13_Axehead_ = (3, WeaponsMiG31BM.Vympel_R_37__AA_13_Axehead_)
Vympel_R_33S__AA_9_Amos_ = (3, WeaponsMiG31BM.Vympel_R_33S__AA_9_Amos_)
Vympel_R_33__AA_9_Amos_ = (3, WeaponsMiG31BM.Vympel_R_33__AA_9_Amos_)
class Pylon4:
Vympel_R_37M__AA_13_Axehead_ = (4, WeaponsMiG31BM.Vympel_R_37M__AA_13_Axehead_)
Vympel_R_37__AA_13_Axehead_ = (4, WeaponsMiG31BM.Vympel_R_37__AA_13_Axehead_)
Vympel_R_33S__AA_9_Amos_ = (4, WeaponsMiG31BM.Vympel_R_33S__AA_9_Amos_)
Vympel_R_33__AA_9_Amos_ = (4, WeaponsMiG31BM.Vympel_R_33__AA_9_Amos_)
class Pylon5:
Vympel_R_37M__AA_13_Axehead_ = (5, WeaponsMiG31BM.Vympel_R_37M__AA_13_Axehead_)
Vympel_R_37__AA_13_Axehead_ = (5, WeaponsMiG31BM.Vympel_R_37__AA_13_Axehead_)
Vympel_R_33S__AA_9_Amos_ = (5, WeaponsMiG31BM.Vympel_R_33S__AA_9_Amos_)
Vympel_R_33__AA_9_Amos_ = (5, WeaponsMiG31BM.Vympel_R_33__AA_9_Amos_)
class Pylon6:
Vympel_R_37M__AA_13_Axehead_ = (6, WeaponsMiG31BM.Vympel_R_37M__AA_13_Axehead_)
Vympel_R_37__AA_13_Axehead_ = (6, WeaponsMiG31BM.Vympel_R_37__AA_13_Axehead_)
Vympel_R_33S__AA_9_Amos_ = (6, WeaponsMiG31BM.Vympel_R_33S__AA_9_Amos_)
Vympel_R_33__AA_9_Amos_ = (6, WeaponsMiG31BM.Vympel_R_33__AA_9_Amos_)
class Pylon7:
@@ -107,6 +119,7 @@ class MiG_31BM(PlaneType):
R_77__AA_12_Adder____Active_Rdr = (7, Weapons.R_77__AA_12_Adder____Active_Rdr)
Vympel_R_37M__AA_13_Axehead_ = (7, WeaponsMiG31BM.Vympel_R_37M__AA_13_Axehead_)
Vympel_R_37__AA_13_Axehead_ = (7, WeaponsMiG31BM.Vympel_R_37__AA_13_Axehead_)
Vympel_R_33S__AA_9_Amos_ = (7, WeaponsMiG31BM.Vympel_R_33S__AA_9_Amos_)
Vympel_R_33__AA_9_Amos_ = (7, WeaponsMiG31BM.Vympel_R_33__AA_9_Amos_)
R_40RD__AA_6_Acrid____Semi_Act_Rdr = (
7,
@@ -127,10 +140,7 @@ class MiG_31BM(PlaneType):
)
Fuel_tank_3000L = (7, Weapons.Fuel_tank_3000L)
Fuel_tank_2000L = (7, Weapons.Fuel_tank_2000L)
Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr = (
7,
Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr,
)
Kh_31P__AS_17_Krypton_ = (7, WeaponsMiG31BM.Kh_31P__AS_17_Krypton_)
class Pylon8:
R_73__AA_11_Archer____Infra_Red = (8, Weapons.R_73__AA_11_Archer____Infra_Red)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
from .tornado_adv import *

View File

@@ -0,0 +1,143 @@
from typing import Dict, List, Set, Any
from dcs import task
from dcs.planes import PlaneType
from dcs.unitpropertydescription import UnitPropertyDescription
from dcs.weapons_data import Weapons
from dcs.unitpropertydescription import UnitPropertyDescription
from game.modsupport import planemod
from pydcs_extensions.weapon_injector import inject_weapons
class WeaponsTORNADO_ADV:
Skyflash__Semi_Active_Radar_AAM_ = {
"clsid": "{Skflash1}",
"name": "Skyflash (Semi-Active Radar AAM)",
"weight": 194,
}
inject_weapons(WeaponsTORNADO_ADV)
@planemod
class Tornado_ADV(PlaneType):
id = "Tornado_ADV"
flyable = True
height = 5.7
width = 13.9
length = 16.7
fuel_max = 4660
max_speed = 2649.996
chaff = 90
flare = 45
charge_total = 180
chaff_charge_size = 1
flare_charge_size = 2
category = "Interceptor" # {78EFB7A2-FD52-4b57-A6A6-3BF0E1D6555F}
radio_frequency = 127.5
livery_name = "TORNADO_ADV" # from type
class Pylon1:
AIM_9P_Sidewinder_IR_AAM = (1, Weapons.AIM_9P_Sidewinder_IR_AAM)
AIM_9M_Sidewinder_IR_AAM = (1, Weapons.AIM_9M_Sidewinder_IR_AAM)
# ERRR {JAS39_ASRAAM}
AIM_9P5_Sidewinder_IR_AAM = (1, Weapons.AIM_9P5_Sidewinder_IR_AAM)
AIM_9L_Sidewinder_IR_AAM = (1, Weapons.AIM_9L_Sidewinder_IR_AAM)
class Pylon2:
Fuel_Tank_800_L__21_ = (2, Weapons.Fuel_Tank_800_L__21_)
class Pylon3:
AIM_9P_Sidewinder_IR_AAM = (3, Weapons.AIM_9P_Sidewinder_IR_AAM)
AIM_9M_Sidewinder_IR_AAM = (3, Weapons.AIM_9M_Sidewinder_IR_AAM)
# ERRR {JAS39_ASRAAM}
AIM_9P5_Sidewinder_IR_AAM = (3, Weapons.AIM_9P5_Sidewinder_IR_AAM)
AIM_9L_Sidewinder_IR_AAM = (3, Weapons.AIM_9L_Sidewinder_IR_AAM)
class Pylon5:
AIM_120B_AMRAAM___Active_Radar_AAM = (
5,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C_AMRAAM___Active_Radar_AAM = (
5,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
Skyflash__Semi_Active_Radar_AAM_ = (
5,
WeaponsTORNADO_ADV.Skyflash__Semi_Active_Radar_AAM_,
)
class Pylon6:
AIM_120B_AMRAAM___Active_Radar_AAM = (
6,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C_AMRAAM___Active_Radar_AAM = (
6,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
Skyflash__Semi_Active_Radar_AAM_ = (
6,
WeaponsTORNADO_ADV.Skyflash__Semi_Active_Radar_AAM_,
)
class Pylon7:
AIM_120B_AMRAAM___Active_Radar_AAM = (
7,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C_AMRAAM___Active_Radar_AAM = (
7,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
Skyflash__Semi_Active_Radar_AAM_ = (
7,
WeaponsTORNADO_ADV.Skyflash__Semi_Active_Radar_AAM_,
)
class Pylon8:
AIM_120B_AMRAAM___Active_Radar_AAM = (
8,
Weapons.AIM_120B_AMRAAM___Active_Radar_AAM,
)
AIM_120C_AMRAAM___Active_Radar_AAM = (
8,
Weapons.AIM_120C_AMRAAM___Active_Radar_AAM,
)
Skyflash__Semi_Active_Radar_AAM_ = (
8,
WeaponsTORNADO_ADV.Skyflash__Semi_Active_Radar_AAM_,
)
class Pylon10:
AIM_9P_Sidewinder_IR_AAM = (10, Weapons.AIM_9P_Sidewinder_IR_AAM)
AIM_9M_Sidewinder_IR_AAM = (10, Weapons.AIM_9M_Sidewinder_IR_AAM)
# ERRR {JAS39_ASRAAM}
AIM_9P5_Sidewinder_IR_AAM = (10, Weapons.AIM_9P5_Sidewinder_IR_AAM)
AIM_9L_Sidewinder_IR_AAM = (10, Weapons.AIM_9L_Sidewinder_IR_AAM)
class Pylon11:
Fuel_Tank_800_L__21_ = (11, Weapons.Fuel_Tank_800_L__21_)
class Pylon12:
AIM_9P_Sidewinder_IR_AAM = (12, Weapons.AIM_9P_Sidewinder_IR_AAM)
AIM_9M_Sidewinder_IR_AAM = (12, Weapons.AIM_9M_Sidewinder_IR_AAM)
# ERRR {JAS39_ASRAAM}
AIM_9P5_Sidewinder_IR_AAM = (12, Weapons.AIM_9P5_Sidewinder_IR_AAM)
AIM_9L_Sidewinder_IR_AAM = (12, Weapons.AIM_9L_Sidewinder_IR_AAM)
pylons: Set[int] = {1, 2, 3, 5, 6, 7, 8, 10, 11, 12}
tasks = [
task.CAP,
task.Escort,
task.FighterSweep,
task.Intercept,
task.Reconnaissance,
]
task_default = task.CAP

View File

@@ -690,9 +690,9 @@ class B_21(PlaneType):
GBU_31_8 = (1, Weapons.GBU_31_8)
B_1B_Mk_84_8 = (1, Weapons.B_1B_Mk_84_8)
GBU_31V3B_8 = (1, Weapons.GBU_31V3B_8)
_4_x_AGM_154C___JSOW_Unitary_BROACH = (
MPRL___4_x_AGM_154C___JSOW_Unitary_BROACH = (
1,
Weapons._4_x_AGM_154C___JSOW_Unitary_BROACH,
Weapons.MPRL___4_x_AGM_154C___JSOW_Unitary_BROACH,
)
_4_x_AGM_158B_JASSM_ER_ALCM = (1, Weapons._4_x_AGM_158B_JASSM_ER_ALCM)
_4_x_AGM_158C_LRASM_AShM = (1, Weapons._4_x_AGM_158C_LRASM_AShM)
@@ -712,9 +712,9 @@ class B_21(PlaneType):
GBU_31_8 = (2, Weapons.GBU_31_8)
B_1B_Mk_84_8 = (2, Weapons.B_1B_Mk_84_8)
GBU_31V3B_8 = (2, Weapons.GBU_31V3B_8)
_4_x_AGM_154C___JSOW_Unitary_BROACH = (
MPRL___4_x_AGM_154C___JSOW_Unitary_BROACH = (
2,
Weapons._4_x_AGM_154C___JSOW_Unitary_BROACH,
Weapons.MPRL___4_x_AGM_154C___JSOW_Unitary_BROACH,
)
_4_x_AGM_158B_JASSM_ER_ALCM = (2, Weapons._4_x_AGM_158B_JASSM_ER_ALCM)
_4_x_AGM_158C_LRASM_AShM = (2, Weapons._4_x_AGM_158C_LRASM_AShM)

View File

@@ -12,6 +12,7 @@ global __dcs_saved_game_directory
global __dcs_installation_directory
global __last_save_file
global __prefer_liberation_payloads
global __setup_preferences_on_every_start
global __server_port
@@ -26,6 +27,7 @@ def init():
global __last_save_file
global __ignore_empty_install_directory
global __prefer_liberation_payloads
global __setup_preferences_on_every_start
global __server_port
if PREFERENCES_PATH.exists():
@@ -42,20 +44,25 @@ def init():
__prefer_liberation_payloads = pref_data.get(
"prefer_liberation_payloads", False
)
__setup_preferences_on_every_start = pref_data.get(
"setup_preferences_on_every_start", False
)
__server_port = pref_data.get("server_port", 16880)
is_first_start = False
is_first_start = __setup_preferences_on_every_start
except (KeyError, json.JSONDecodeError):
__dcs_saved_game_directory = ""
__dcs_installation_directory = ""
__last_save_file = ""
__ignore_empty_install_directory = False
__prefer_liberation_payloads = False
__setup_preferences_on_every_start = False
__server_port = 16880
is_first_start = True
else:
__last_save_file = ""
__ignore_empty_install_directory = False
__prefer_liberation_payloads = False
__setup_preferences_on_every_start = False
__server_port = 16880
try:
__dcs_saved_game_directory = (
@@ -79,14 +86,22 @@ def init():
return is_first_start
def setup(saved_game_dir, install_dir, prefer_liberation_payloads, port):
def setup(
saved_game_dir,
install_dir,
prefer_liberation_payloads,
setup_preferences_on_every_start,
port,
):
global __dcs_saved_game_directory
global __dcs_installation_directory
global __prefer_liberation_payloads
global __setup_preferences_on_every_start
global __server_port
__dcs_saved_game_directory = saved_game_dir
__dcs_installation_directory = install_dir
__prefer_liberation_payloads = prefer_liberation_payloads
__setup_preferences_on_every_start = setup_preferences_on_every_start
__server_port = port
persistency.setup(saved_game_dir, prefer_liberation_payloads, port)
@@ -108,6 +123,7 @@ def save_config():
"last_save_file": __last_save_file,
"ignore_empty_install_directory": __ignore_empty_install_directory,
"prefer_liberation_payloads": __prefer_liberation_payloads,
"setup_preferences_on_every_start": __setup_preferences_on_every_start,
"server_port": __server_port,
}
PREFERENCES_PATH.parent.mkdir(exist_ok=True, parents=True)
@@ -130,6 +146,11 @@ def prefer_liberation_payloads():
return __prefer_liberation_payloads
def setup_preferences_on_every_start():
global __setup_preferences_on_every_start
return __setup_preferences_on_every_start
def server_port():
global __server_port
return __server_port

View File

@@ -238,6 +238,10 @@ class QWaitingForMissionResultWindow(QDialog):
self.sim_controller.debrief_current_state(Path(file[0]), force_end=True)
)
def reject(self):
self.reset_game_state()
super().reject()
def reset_game_state(self):
self.sim_controller.set_game(self.game)
events = GameUpdateEvents()

View File

@@ -177,6 +177,9 @@ class QPackageDialog(QDialog):
)
def on_save(self) -> None:
# TODO: Cache package start state and only update if valid
if not self.package_valid():
return
self.save_tot()
def save_tot(self) -> None:
@@ -280,6 +283,29 @@ class QPackageDialog(QDialog):
self.package_model.package.frequency = None
self.package_freq_text.setText("AUTO")
def package_valid(self) -> bool:
"""Validates the package before saving.
Returns:
True if the package is valid, False otherwise.
"""
# Validate the package has more than just escort flights but allow empty packages
if len(self.package_model.package.flights) == 0:
return True
if any(
flight.flight_type.name not in {"ESCORT", "SEAD_ESCORT"}
for flight in self.package_model.package.flights
):
return True
else:
QMessageBox.critical(
self,
"Invalid Package",
"Package cannot contain only escort flights.",
QMessageBox.StandardButton.Ok,
)
return False
class QNewPackageDialog(QPackageDialog):
"""Dialog window for creating a new package.
@@ -325,6 +351,8 @@ class QNewPackageDialog(QPackageDialog):
Empty packages may be created. They can be modified later, and will have
no effect if empty when the mission is generated.
"""
if not super().package_valid():
return
super().on_save()
self.ato_model.add_package(self.package_model.package)

View File

@@ -131,6 +131,7 @@ class NewGameWizard(QtWidgets.QWizard):
usamilitaryassetspack=self.field("usamilitaryassetspack"),
ukrainemilitaryassetspack=self.field("ukrainemilitaryassetspack"),
mig31bm_foxhound=self.field("mig31bm_foxhound"),
tornado_adv=self.field("tornado_adv"),
)
blue_faction = self.faction_selection_page.selected_blue_faction

View File

@@ -174,6 +174,8 @@ class GeneratorOptions(QtWidgets.QWizardPage):
self.registerField("ukrainemilitaryassetspack", self.ukrainemilitaryassetspack)
self.mig31bm_foxhound = QtWidgets.QCheckBox()
self.registerField("mig31bm_foxhound", self.mig31bm_foxhound)
self.tornado_adv = QtWidgets.QCheckBox()
self.registerField("tornado_adv", self.tornado_adv)
modHelpText = QtWidgets.QLabel(
"<p>Select the mods you have installed. If your chosen factions support them, you'll be able to use these mods in your campaign.</p>"
@@ -218,7 +220,7 @@ class GeneratorOptions(QtWidgets.QWizardPage):
("F-15D Baz (v1.0)", self.f15d_baz),
("F-15I Ra'am (v1.0 by IDF Mods Project)", self.f_15_idf),
("F-16I Sufa & F-16D (v3.6 by IDF Mods Project)", self.f_16_idf),
("F-22A Raptor (v3.0)", self.f22_raptor),
("F-22A Raptor (v2.0.0 released May 2025)", self.f22_raptor),
("F-4B/C Phantom II (2.8.7.204)", self.f4bc_phantom),
("F-84G Thunderjet (v2.5.7.01)", self.f84g_thunderjet),
("F9F Panther (v2.8.7.101)", self.f9f_panther),
@@ -228,7 +230,7 @@ class GeneratorOptions(QtWidgets.QWizardPage):
("High Digit SAMs", self.high_digit_sams),
("IDF Assets Pack (v1.1 by IDF Mods Project)", self.irondome),
("JAS 39 Gripen (v1.8.5-beta)", self.jas39_gripen),
("MiG-31BM (v2.0)", self.mig31bm_foxhound),
("MiG-31BM (v2.62)", self.mig31bm_foxhound),
("Mirage III (v2.5.7.01)", self.mirage_3),
("OH-6 Cayuse (v1.2)", self.oh_6),
("OH-6 Vietnam Asset Pack (v1.0)", self.oh_6_vietnamassetpack),
@@ -240,6 +242,7 @@ class GeneratorOptions(QtWidgets.QWizardPage):
("Su-30 Flanker-H (V2.7.73b)", self.su30_flanker_h),
("Su-57 Felon (build-04)", self.su57_felon),
("Super Étendard (v2.5.5)", self.super_etendard),
("Tornado F3 ADV (1.0)", self.tornado_adv),
("UH-60L Black Hawk (v1.3.1)", self.uh_60l),
("Vietnam War Vessels (v0.9.0 by TeTeT)", self.vietnamwarvessels),
]
@@ -323,3 +326,4 @@ class GeneratorOptions(QtWidgets.QWizardPage):
self.ukrainemilitaryassetspack.setChecked(
s.get("ukrainemilitaryassetspack", False)
)
self.tornado_adv.setChecked(s.get("tornado_adv", False))

View File

@@ -89,6 +89,5 @@ class QLiberationFirstStartWindow(QDialog):
self.setLayout(layout)
def apply(self):
print("Applying changes")
if self.preferences.apply():
self.close()

View File

@@ -47,6 +47,13 @@ class QLiberationPreferences(QFrame):
self.payloads_cb = QCheckBox()
self.payloads_cb.setChecked(self.prefer_liberation_payloads)
setup_on_startup = liberation_install.setup_preferences_on_every_start()
self.setup_preferences_on_every_start = (
setup_on_startup if setup_on_startup else False
)
self.setup_every_start_cb = QCheckBox()
self.setup_every_start_cb.setChecked(self.setup_preferences_on_every_start)
self.port = liberation_install.server_port()
self.port_input = QSpinBox()
@@ -92,12 +99,22 @@ class QLiberationPreferences(QFrame):
layout.addWidget(self.payloads_cb, 5, 1, alignment=Qt.AlignmentFlag.AlignRight)
layout.addWidget(
QLabel("<strong>Server port (restart required):</strong>"),
QLabel("<strong>Setup preferences on every start:</strong>"),
6,
0,
alignment=Qt.AlignmentFlag.AlignLeft,
)
layout.addWidget(self.port_input, 6, 1, alignment=Qt.AlignmentFlag.AlignRight)
layout.addWidget(
self.setup_every_start_cb, 6, 1, alignment=Qt.AlignmentFlag.AlignRight
)
layout.addWidget(
QLabel("<strong>Server port (restart required):</strong>"),
7,
0,
alignment=Qt.AlignmentFlag.AlignLeft,
)
layout.addWidget(self.port_input, 7, 1, alignment=Qt.AlignmentFlag.AlignRight)
self.port_input.setRange(1, 2**16 - 1)
self.port_input.setValue(self.port)
self.port_input.setStyleSheet("QSpinBox{ width: 50 }")
@@ -124,10 +141,10 @@ class QLiberationPreferences(QFrame):
self.edit_dcs_install_dir.setText(install_dir)
def apply(self):
print("Applying changes")
self.saved_game_dir = self.edit_saved_game_dir.text()
self.dcs_install_dir = self.edit_dcs_install_dir.text()
self.prefer_liberation_payloads = self.payloads_cb.isChecked()
self.setup_preferences_on_every_start = self.setup_every_start_cb.isChecked()
self.port = self.port_input.value()
set_theme_index(self.themeSelect.currentIndex())
@@ -188,6 +205,7 @@ class QLiberationPreferences(QFrame):
self.saved_game_dir,
self.dcs_install_dir,
self.prefer_liberation_payloads,
self.setup_preferences_on_every_start,
self.port,
)
liberation_install.save_config()

View File

@@ -29,7 +29,4 @@ class QLiberationPreferencesWindow(QDialog):
def apply(self):
if self.preferences.apply():
print("Closing")
self.close()
else:
print("Not Closing")

View File

@@ -10,9 +10,9 @@ click==8.1.8
colorama==0.4.6
distlib==0.3.9
Faker==37.0.2
fastapi==0.115.11
fastapi==0.116.1
filelock==3.18.0
h11==0.14.0
h11==0.16.0
httptools==0.6.4
identify==2.6.9
idna==3.10
@@ -33,7 +33,7 @@ pluggy==1.5.0
pre-commit==4.2.0
pydantic==2.11.0b2
pydantic-settings==2.8.1
pydcs @ git+https://github.com/dcs-retribution/pydcs@0b379cc6ac371032e32c4f6cb86999f96c5da748
pydcs @ git+https://github.com/dcs-retribution/pydcs@842fdf022e01f9b5f8695008bd4c9ab54c23d722
pyinstaller==5.13.2
pyinstaller-hooks-contrib==2024.0
pyparsing==3.2.1
@@ -52,7 +52,7 @@ Shapely==2.1.0rc1
shiboken6==6.4.2
six==1.17.0
sniffio==1.3.1
starlette==0.46.1
starlette==0.47.2
suntime==1.3.2
tabulate==0.9.0
text-unidecode==1.3

Binary file not shown.

View File

@@ -0,0 +1,199 @@
---
name: Germany - Northern Guardian
theater: GermanyCW
authors: Revi
recommended_player_faction: Blufor Current
recommended_enemy_faction: "[CH] Russia 2020"
description:
<p><strong>OPERATION NORTHERN GUARDIAN<strong><p>
<p>TO NATO Joint Operations Command FROM Combined NATO Task Force, Northeast Germany DATE 17 July 2027 SUBJECT SITREP 001 - Emerging Insurrection Threat, Northeast Germany (OPFOR Russian-Backed Separatists)<p>
<p><strong>1.SITUATION OVERVIEW<strong><p>
<p>Intelligence indicates a rapidly escalating hybrid threat in Northeast Germany, primarily within the historically restive regions bordering Poland, particularly around Mecklenburg-Vorpommern and portions of Brandenburg. Russian-backed separatist elements, leveraging pre-existing socio-economic grievances and disinformation campaigns, have begun to coalesce into organized armed groups. Their objectives appear to include the destabilization of the federal government, creation of a "Trans-Oder Republic," and ultimately, a land corridor facilitating direct Russian influence in the Baltic Sea region.<p>
<p><strong>Recent overt actions include<strong><p>
<p>07/15/27 Coordinated cyber-attacks against critical infrastructure (power grid, localized communications networks) in Stralsund and Greifswald, causing widespread disruption.<p>
<p>07/16/27 Armed seizure of a local police station in Anklam, followed by distribution of propaganda and seizure of small arms.<p>
<p>07/16/27 Unconfirmed reports of foreign "volunteers" and light armored vehicles (likely ex-Soviet stock) crossing the Polish border, facilitated by covert Russian Special Operations Forces (SOF).<p>
<p>07/17/27 Establishment of fortified checkpoints on key roads leading into and out of Rostock and Neubrandenburg.<p>
<p><strong>2.ENEMY FORCES (OPFOR)<strong><p>
<p>Composition Estimated 1,500-2,500 irregular fighters, organized into company-sized elements. Leadership appears to be a mix of local nationalist agitators and experienced foreign (likely Russian GRU/Wagner Group) operatives.
Capabilities Equipped with small arms, light machine guns, RPGs, and an increasing number of MANPADS. Limited access to anti-tank guided missiles (ATGM) and potentially, captured or supplied light armored vehicles (MT-LBs, old BTR variants). Growing indications of sophisticated electronic warfare (EW) capabilities, likely provided by Russian advisors.
Intentions Isolate key urban centers, disrupt NATO reinforcement efforts, and establish de facto control over territory to demand international recognition. Expect extensive use of asymmetric tactics, including IEDs, ambushes, and civilian shields.</p>
miz: Northern Guardian.miz
performance: 2
recommended_start_date: 2027-07-17
recommended_player_money: 500
recommended_enemy_money: 500
recommended_player_income_multiplier: 0.7
recommended_enemy_income_multiplier: 1
version: "10.7"
settings:
hercules: true
squadron_start_full: true
russianmilitaryassetspack: true
usamilitaryassetspack: true
swedishmilitaryassetspack: true
squadrons:
#Fassberg
11:
- primary: BAI
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
size: 6
- primary: DEAD
secondary: any
aircraft:
- 522nd FS
size: 8
- primary: Strike
secondary: air-to-air
aircraft:
- 335th FS
size: 4
- primary: Transport
secondary: any
aircraft:
- C-130J-30 Super Hercules
size: 2
#H FRG 04
56:
- primary: CAS
secondary: air-to-ground
aircraft:
- RNLAF Redskins 301 Sqn
size: 4
- primary: Air Assault
secondary: any
aircraft:
- CH-47F Block I
size: 2
#H FRG 12
64:
- primary: CAS
secondary: air-to-ground
aircraft:
- Ka-50 Hokum III
size: 4
#H FRG 17
95:
- primary: Armed Recon
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
size: 6
#H GDR 21
152:
- primary: Transport
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
size: 4
#H GDR 31
229:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
size: 4
#H GDR 30
146:
- primary: Air Assault
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
size: 2
- primary: Armed Recon
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
size: 2
#H GDR 13
91:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
size: 4
#H GDR 09
75:
- primary: Armed Recon
secondary: air-to-ground
aircraft:
- Mi-8MTV2 Hip
size: 4
#Peenemunde
25:
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-29S Fulcrum-C
size: 4
- primary: BAI
secondary: air-to-ground
aircraft:
- Su-25T Frogfoot
size: 4
- primary: BAI
secondary: any
aircraft:
- L-39ZA Albatros
size: 6
FOB Schwerin:
- primary: Armed Recon
secondary: air-to-ground
aircraft:
- German Army
size: 4
- primary: Armed Recon
secondary: air-to-ground
aircraft:
- A Company, 1-211th ARB
size: 2
FOB Fehmarn:
- primary: BAI
secondary: air-to-ground
aircraft:
- C Company, 2-159th ARB
size: 4
- primary: Transport
secondary: any
aircraft:
- CH-47F Block I
size: 2
FOB Schwaan:
- primary: Armed Recon
secondary: air-to-ground
aircraft:
- Ka-50 Hokum III
size: 6
Roadbase Usadel:
- primary: BAI
secondary: air-to-ground
aircraft:
- 36th FS
size: 1
- primary: BAI
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
size: 1
NLD-UK corridor:
- primary: AEW&C
aircraft:
- E-3A
size: 1
- primary: Refueling
aircraft:
- KC-135 Stratotanker
size: 1
- primary: BARCAP
secondary: air-to-air
aircraft:
- F-15C Eagle
size: 4

Binary file not shown.

View File

@@ -0,0 +1,227 @@
---
name: Germany - Crossing the Rubicon
theater: GermanyCW
authors: Starfire
recommended_player_faction: Blufor Late Cold War (80s)
recommended_enemy_faction: Russia 1980
description:
<p>In the summer of 1988, tensions simmering for decades finally ignite. Under the cover of pre-dawn darkness,
Soviet and Warsaw Pact forces surge across the inner German border, launching a full-scale invasion through
the Fulda Gap. For months, signs of a shift had been visible; escalating rhetoric, unusual troop movements, a
hardening of positions. However, few believed the Kremlin would truly abandon the uneasy balance that had held
since World War II. It was only when the tanks started rolling west that it became clear. The Soviet Union had
finally crossed its Rubicon. The battle for Europe had begun.</p><p>
NATO forces, stretched thin and caught in partial readiness, are thrown into a desperate defence. From bases
across West Germany, multi-national air assets scramble to blunt the assault. In the skies over Central Europe,
control is fleeting, and the cost of failure is all too high.</p>
miz: crossing_the_rubicon.miz
performance: 2
recommended_start_date: 1988-07-13
version: "10.7"
settings:
hercules: true
squadron_start_full: true
squadrons:
#Ramstein
165:
- primary: OCA/Runway
secondary: air-to-ground
aircraft:
- B-1B Lancer
size: 4
- primary: CAS
secondary: any
aircraft:
- A-10A Thunderbolt II
size: 8
- primary: Escort
secondary: air-to-air
aircraft:
- Mirage-F1EE
size: 8
- primary: SEAD Sweep
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
size: 8
#Spangdahlem
162:
- primary: TARCAP
secondary: air-to-air
aircraft:
- F-15C Eagle
size: 8
- primary: BAI
secondary: any
aircraft:
- F-4E-45MC Phantom II
size: 8
#Hahn
155:
- primary: Strike
secondary: any
aircraft:
- B-52H Stratofortress
size: 4
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
size: 8
- primary: SEAD Escort
secondary: any
aircraft:
- Tornado IDS
size: 8
#Frankfurt
163:
- primary: AEW&C
aircraft:
- E-3A
size: 2
- primary: Refueling
aircraft:
- KC-135 Stratotanker
size: 2
- primary: Transport
secondary: any
aircraft:
- C-130J-30 Super Hercules
- C-130
size: 4
#H FRG 20
143:
- primary: Air Assault
secondary: any
aircraft:
- UH-1H Iroquois
size: 4
#H FRG 09
61:
- primary: Escort
secondary: any
aircraft:
- OH-58D(R) Kiowa Warrior
size: 4
#H FRG 12
64:
- primary: Armed Recon
secondary: any
aircraft:
- AH-64D Apache Longbow
size: 4
#Carrier
Blue-CV:
- primary: Escort
secondary: any
aircraft:
- F-14A Tomcat (Block 135-GR Late)
size: 8
- primary: SEAD
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 8
- primary: Armed Recon
secondary: air-to-ground
aircraft:
- S-3B Viking
size: 8
- primary: AEW&C
aircraft:
- E-2C Hawkeye
size: 2
- primary: Refueling
aircraft:
- S-3B Tanker
size: 4
- primary: Air Assault
secondary: any
aircraft:
- UH-60A
size: 4
#Haina
161:
- primary: Escort
secondary: any
aircraft:
- Mi-24P Hind-F
size: 4
- primary: Air Assault
secondary: any
aircraft:
- Mi-8MTV2 Hip
size: 4
- primary: Armed Recon
secondary: air-to-ground
aircraft:
- Su-25 Frogfoot
size: 8
- primary: Escort
secondary: any
aircraft:
- MiG-23MLD Flogger-K
size: 8
- primary: SEAD Escort
secondary: any
aircraft:
- MiG-27K Flogger-J2
size: 8
#Sperenberg
101:
- primary: Strike
secondary: any
aircraft:
- Tu-95MS Bear-H
size: 8
- primary: OCA/Aircraft
secondary: any
aircraft:
- Tu-22M3 Backfire-C
size: 8
- primary: Escort
secondary: air-to-air
aircraft:
- Su-27 Flanker-B
size: 8
#Schonefeld
26:
- primary: AEW&C
aircraft:
- A-50
size: 1
- primary: Refueling
aircraft:
- IL-78M
size: 2
- primary: Transport
secondary: any
aircraft:
- AN-26B
size: 4
#Templin
15:
- primary: SEAD
secondary: any
aircraft:
- Su-24M Fencer-D
size: 8
- primary: BAI
secondary: air-to-ground
aircraft:
- MiG-21bis Fishbed-N
size: 8
#Wittstock:
1:
- primary: DEAD
secondary: air-to-ground
aircraft:
- Su-17M4 Fitter-K
size: 8
#Peenemunde
25:
- primary: BARCAP
secondary: any
aircraft:
- MiG-29A Fulcrum-A
size: 8

View File

@@ -35,6 +35,8 @@ performance: 2
recommended_start_date: 2025-09-01
version: "10.7"
settings:
fa_18efg: true
f22_raptor: true
hercules: true
squadron_start_full: true
squadrons:
@@ -43,7 +45,13 @@ squadrons:
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 24
size: 16
- primary: SEAD Escort
secondary: any
aircraft:
- EA-18G Growler
- F/A-18C Hornet (Lot 20)
size: 16
- primary: AEW&C
aircraft:
- E-2D Advanced Hawkeye
@@ -64,6 +72,12 @@ squadrons:
aircraft:
- F-15C Eagle
size: 12
- primary: TARCAP
secondary: any
aircraft:
- F-22A Raptor
- F-15C Eagle
size: 12
- primary: OCA/Runway
secondary: any
aircraft:

View File

@@ -20,6 +20,8 @@ recommended_start_date: 2011-02-24
version: "10.7"
settings:
chinesemilitaryassetspack: true
fa_18efg: true
f22_raptor: true
hercules: true
squadron_start_full: true
squadrons:
@@ -40,6 +42,7 @@ squadrons:
- primary: TARCAP
secondary: any
aircraft:
- F-22A Raptor
- F-15C Eagle
size: 16
- primary: Strike
@@ -64,16 +67,22 @@ squadrons:
aircraft:
- OH-58D(R) Kiowa Warrior
size: 2
- primary: DEAD
secondary: air-to-ground
- primary: SEAD
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 24
- primary: SEAD
secondary: air-to-ground
size: 16
- primary: SEAD Escort
secondary: any
aircraft:
- EA-18G Growler
- F/A-18C Hornet (Lot 20)
size: 16
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
size: 24
size: 20
- primary: AEW&C
aircraft:
- E-3A

View File

@@ -31,6 +31,8 @@ recommended_enemy_money: 0
recommended_player_income_multiplier: 0.2
recommended_enemy_income_multiplier: 0.2
settings:
fa_18efg: true
f22_raptor: true
hercules: true
squadron_start_full: true
version: "10.7"
@@ -40,7 +42,13 @@ squadrons:
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 40
size: 24
- primary: SEAD Escort
secondary: any
aircraft:
- EA-18G Growler
- F/A-18C Hornet (Lot 20)
size: 16
- primary: AEW&C
aircraft:
- E-2C Hawkeye
@@ -67,16 +75,17 @@ squadrons:
aircraft:
- CH-47F Block I
size: 4
- primary: TARCAP
secondary: any
aircraft:
- F-22A Raptor
- F-15C Eagle
size: 12
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
size: 20
- primary: Escort
secondary: air-to-air
aircraft:
- F-15C Eagle
size: 20
size: 16
#Al Dhafra AFB (251)
4:
- primary: Strike
@@ -93,6 +102,11 @@ squadrons:
aircraft:
- F-15E Strike Eagle (Suite 4+)
size: 16
- primary: Escort
secondary: air-to-air
aircraft:
- F-15C Eagle
size: 12
- primary: DEAD
secondary: air-to-ground
aircraft:

View File

@@ -19,6 +19,8 @@ performance: 2
recommended_start_date: 2019-12-23
version: "10.7"
settings:
fa_18efg: true
f22_raptor: true
hercules: true
squadron_start_full: true
squadrons:
@@ -27,7 +29,13 @@ squadrons:
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 24
size: 16
- primary: SEAD Escort
secondary: any
aircraft:
- EA-18G Growler
- F/A-18C Hornet (Lot 20)
size: 16
- primary: AEW&C
aircraft:
- E-2D Advanced Hawkeye
@@ -63,29 +71,35 @@ squadrons:
aircraft:
- F-15E Strike Eagle (Suite 4+)
size: 12
- primary: TARCAP
- primary: Escort
secondary: air-to-air
aircraft:
- F-15C Eagle
size: 20
size: 16
# Ramat David
30:
- primary: BAI
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
size: 8
- primary: TARCAP
secondary: any
aircraft:
- F-22A Raptor
- F-15C Eagle
size: 16
- primary: DEAD
secondary: any
aircraft:
- F-16CM Fighting Falcon (Block 50)
size: 28
- primary: CAS
size: 16
- primary: Armed Recon
secondary: any
aircraft:
- AH-64D Apache Longbow
size: 4
- primary: CAS
- primary: Armed Recon
secondary: any
aircraft:
- OH-58D(R) Kiowa Warrior

Binary file not shown.

View File

@@ -0,0 +1,183 @@
---
name: Syria - Operation Syrian Shield
theater: Syria
authors: Xisco
description:
<p>Isis forces are in a rush to retake Syrian territory along with oil fields. The US is trying to stop them. Caught by surprise, the US is trying to regroup and defend the country.</p>
<p>This is an small scenario. Blue players start with 500M but low on resources. Can not afford to lose much aircrafts. In the other side, the enemy has a lot of resources and can afford to lose some aircraft.</p>
<p>Front line is very close to the allied base. If the enemy takes the base, the game is over.</p>
recommended_player_faction: Bluefor Modern
recommended_enemy_faction: Syria 2012'ish
recommended_start_date: 2024-06-01
miz: operation_syrian_shield.miz
performance: 2
version: 10.7
advanced_iads: true
recommended_player_money: 900
recommended_enemy_money: 900
recommended_player_income_multiplier: 0.5
recommended_enemy_income_multiplier: 0.5
squadrons:
Blue CV:
# Hornet - VFA-11 "Red Rippers"
- primary: SEAD
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 6
# Hornet - VFA-136 "Knighthawks"
- primary: DEAD
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 4
# Hornet - VFA-81 "Sunliners"
- primary: DEAD
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 4
# VRC-40 Det.1
- primary: Refueling
aircraft:
- S-3B Tanker
size: 1
# VAW-126 "Seahawks"
- primary: AEW&C
aircraft:
- E-2C Hawkeye
size: 1
Blue LHA:
# VMM-261 “Raging Bulls”
- primary: BAI
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
size: 4
# Tiyas - 39
39:
- primary: TARCAP
secondary: air-to-air
aircraft:
- MiG-25PD Foxbat-E
size: 12
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-24M Fencer-D
size: 12
- primary: AEW&C
aircraft:
- A-50
size: 2
# Palmyra - 28
28:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
size: 4
- primary: BARCAP
secondary: air-to-air
aircraft:
- MiG-29A Fulcrum-A
- MiG-29S Fulcrum-C
size: 12
- primary: Refueling
aircraft:
- IL-78M
size: 2
- primary: Transport
aircraft:
- IL-76MD
size: 2
- primary: CAS
secondary: air-to-ground
aircraft:
- SA 342L Gazelle
size: 4
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-24M Fencer-D
- Su-34 Fullback
size: 6
# Shayrat - 36
36:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24P Hind-F
size: 4
- primary: Strike
secondary: air-to-ground
aircraft:
- Su-24M Fencer-D
- Su-34 Fullback
size: 6
30: # Ramat David
# 109th Squadron “The Valley Squadron”
- primary: BARCAP
aircraft:
- F-16CM Fighting Falcon (Block 50)
size: 4
# 190th Squadron “Magic Touch”
- primary: BAI
secondary: any
aircraft:
- AH-64D Apache Longbow
size: 2
# Unit 669 / 124th Squadron “Rolling Sword”
- primary: Air Assault
aircraft:
- UH-1H Iroquois
size: 2
# 100th ARW Detachment
- primary: Refueling
aircraft:
- KC-135 Stratotanker
size: 2
# 75th Fighter Squadron “Tiger Sharks”
- primary: CAS
aircraft:
- A-10C Thunderbolt II (Suite 7)
- A-10C Thunderbolt II (Suite 3)
- A-10A Thunderbolt II
size: 2
# 122nd Squadron “Nachshon”
- primary: AEW&C
aircraft:
- E-3A
size: 1
# Dier Ezzor - 42
42:
- primary: TARCAP
secondary: air-to-air
aircraft:
- MiG-23ML Flogger-G
- primary: BARCAP
secondary: any
aircraft:
- MiG-29A Fulcrum-A
- primary: Refueling
aircraft:
- IL-78M
size: 1
- primary: Transport
aircraft:
- IL-76MD
size: 1
- primary: AEW&C
aircraft:
- A-50
size: 1
- primary: Strike
secondary: air-to-ground
aircraft:
- Tu-22M3 Backfire-C
Siyah Brigade ground position:
- primary: CAS
secondary: air-to-ground
aircraft:
- Mi-24V Hind-E
size: 6

View File

@@ -27,6 +27,8 @@ performance: 1
recommended_start_date: 2008-08-08
version: "10.7"
settings:
fa_18efg: true
f22_raptor: true
hercules: true
squadron_start_full: true
squadrons:
@@ -36,11 +38,17 @@ squadrons:
aircraft:
- F-14B Tomcat
size: 16
- primary: SEAD Escort
secondary: any
aircraft:
- EA-18G Growler
- F/A-18C Hornet (Lot 20)
size: 16
- primary: SEAD
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 24
size: 16
- primary: BAI
secondary: air-to-ground
aircraft:
@@ -108,6 +116,12 @@ squadrons:
aircraft:
- F-15E Strike Eagle (Suite 4+)
size: 12
- primary: TARCAP
secondary: any
aircraft:
- F-22A Raptor
- F-15C Eagle
size: 16
- primary: Escort
secondary: any
aircraft:

View File

@@ -23,11 +23,13 @@ description:
but for the entire world, as the balance of power teeters on a knife's edge.</p>
miz: red_sea_rising.miz
performance: 1
recommended_start_date: 2003-01-11
recommended_start_date: 2005-01-11
version: "10.7"
settings:
usamilitaryassetspack: true
chinesemilitaryassetspack: true
fa_18efg: true
f22_raptor: true
hercules: true
squadron_start_full: true
squadrons:
@@ -37,7 +39,13 @@ squadrons:
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 24
size: 12
- primary: SEAD Escort
secondary: any
aircraft:
- EA-18G Growler
- F/A-18C Hornet (Lot 20)
size: 12
- primary: AEW&C
aircraft:
- E-2D Advanced Hawkeye
@@ -51,7 +59,7 @@ squadrons:
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
size: 16
size: 12
- primary: Escort
secondary: any
aircraft:
@@ -84,7 +92,7 @@ squadrons:
aircraft:
- "[CH] B-21"
- F-117A Nighthawk
size: 16
size: 12
#Tel Nof
23:
- primary: Escort
@@ -92,6 +100,12 @@ squadrons:
aircraft:
- F-15C Eagle
size: 12
- primary: TARCAP
secondary: any
aircraft:
- F-22A Raptor
- F-15C Eagle
size: 12
- primary: OCA/Runway
secondary: any
aircraft:
@@ -155,7 +169,7 @@ squadrons:
secondary: air-to-air
aircraft:
- Su-27 Flanker-B
size: 8
size: 12
#St Catherine
25:
- primary: CAS
@@ -215,7 +229,7 @@ squadrons:
secondary: air-to-air
aircraft:
- MiG-29S Fulcrum-C
size: 8
size: 12
#Opfor Carrier
Red CV-1:
- primary: BARCAP

View File

@@ -16,7 +16,7 @@ description:
The fate of Europe hangs in the balance, as this new offensive threatens to forever alter the geopolitical map.</p>
miz: the_anvil_of_war.miz
performance: 2
recommended_start_date: 2005-05-13
recommended_start_date: 2007-05-13
version: "10.7"
settings:
russianmilitaryassetspack: true
@@ -24,16 +24,23 @@ settings:
usamilitaryassetspack: true
swedishmilitaryassetspack: true
f22_raptor: true
fa_18efg: true
hercules: true
squadron_start_full: true
squadrons:
#Ownfor Carrier
Blue-CV:
- primary: SEAD Escort
secondary: any
aircraft:
- EA-18G Growler
- F/A-18C Hornet (Lot 20)
size: 16
- primary: SEAD
secondary: any
aircraft:
- F/A-18C Hornet (Lot 20)
size: 40
size: 24
- primary: AEW&C
aircraft:
- E-2D Advanced Hawkeye
@@ -255,4 +262,4 @@ squadrons:
- primary: AEW&C
aircraft:
- KJ-2000
size: 2
size: 2

File diff suppressed because it is too large Load Diff

View File

@@ -1,461 +1,243 @@
local unitPayloads = {
["name"] = "F-22A",
["payloads"] = {
[1] = {
["displayName"] = "Retribution Ferry",
["name"] = "Retribution Ferry",
["displayName"] = "Retribution Escort",
["name"] = "Retribution Escort",
["pylons"] = {
[1] = {
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
["num"] = 2,
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 1,
},
[2] = {
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
["num"] = 10,
},
[3] = {
["CLSID"] = "{AIM-9XX}",
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 11,
},
[4] = {
["CLSID"] = "{AIM-120D}",
[3] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 9,
},
[5] = {
["CLSID"] = "{AIM-120D}",
[4] = {
["CLSID"] = "{AIM_120D-3_IRST_RIGHT}",
["num"] = 8,
},
[6] = {
["CLSID"] = "{AIM-120D}",
[5] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 7,
},
[7] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[8] = {
["CLSID"] = "{AIM-120D}",
[6] = {
["CLSID"] = "{AIM_120D-3_IRST_LEFT}",
["num"] = 4,
},
[9] = {
["CLSID"] = "{AIM-120D}",
[7] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 3,
},
[10] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 1,
[8] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 10,
[2] = 11,
[3] = 18,
[4] = 15,
[1] = 11,
},
},
[2] = {
["name"] = "SEAD",
["name"] = "Retribution BARCAP",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
[2] = {
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 11,
},
[3] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 9,
},
[4] = {
["CLSID"] = "{AIM_120D-3_IRST_RIGHT}",
["num"] = 8,
},
[5] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 7,
},
[6] = {
["CLSID"] = "{AIM_120D-3_IRST_LEFT}",
["num"] = 4,
},
[7] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 3,
},
[8] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 11,
},
},
[3] = {
["name"] = "ANTISHIP",
["name"] = "Retribution Fighter Sweep",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
[2] = {
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 11,
},
[3] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 9,
},
[4] = {
["CLSID"] = "{AIM_120D-3_IRST_RIGHT}",
["num"] = 8,
},
[5] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 7,
},
[6] = {
["CLSID"] = "{AIM_120D-3_IRST_LEFT}",
["num"] = 4,
},
[7] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 3,
},
[8] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 11,
},
},
[4] = {
["name"] = "CAS",
["name"] = "Retribution TARCAP",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
[2] = {
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 11,
},
[3] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 9,
},
[4] = {
["CLSID"] = "{AIM_120D-3_IRST_RIGHT}",
["num"] = 8,
},
[5] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 7,
},
[6] = {
["CLSID"] = "{AIM_120D-3_IRST_LEFT}",
["num"] = 4,
},
[7] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 3,
},
[8] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 11,
},
},
[5] = {
["name"] = "BAI",
["name"] = "Retribution Intercept",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
[2] = {
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 11,
},
[3] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 9,
},
[4] = {
["CLSID"] = "{AIM_120D-3_IRST_RIGHT}",
["num"] = 8,
},
[5] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 7,
},
[6] = {
["CLSID"] = "{AIM_120D-3_IRST_LEFT}",
["num"] = 4,
},
[7] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 3,
},
[8] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 11,
},
},
[6] = {
["name"] = "DEAD",
["name"] = "Retribution Reconnaissance",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 11,
},
},
["tasks"] = {
[1] = 11,
},
},
[7] = {
["name"] = "INTERCEPT",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
["CLSID"] = "{AIM9X-BLKII}",
["num"] = 11,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 11,
},
},
["tasks"] = {
[1] = 11,
},
},
[8] = {
["name"] = "OCA",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["CLSID"] = "{AIM-120D-3}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
[4] = {
["CLSID"] = "{AIM_120D-3_IRST_RIGHT}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
[5] = {
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
[6] = {
["CLSID"] = "{AIM_120D-3_IRST_LEFT}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
[7] = {
["CLSID"] = "{AIM-120D-3}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 11,
},
},
["tasks"] = {
[1] = 11,
},
},
[9] = {
["name"] = "STRIKE",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["CLSID"] = "{MAKO_A2A_C}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 11,
},
},
["tasks"] = {
[1] = 11,
},
},
[10] = {
["name"] = "CAP",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 11,
},
[9] = {
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
["num"] = 10,
},
[10] = {
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
["num"] = 2,
},
},
["tasks"] = {
[1] = 11,
},
},
[11] = {
["name"] = "RUNWAY_ATTACK",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-120D}",
["num"] = 9,
},
[2] = {
["CLSID"] = "{AIM-120D}",
["num"] = 8,
},
[3] = {
["CLSID"] = "{AIM-120D}",
["num"] = 7,
},
[4] = {
["CLSID"] = "{AIM-120D}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{AIM-120D}",
["num"] = 4,
},
[6] = {
["CLSID"] = "{AIM-120D}",
["num"] = 3,
},
[7] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 1,
},
[8] = {
["CLSID"] = "{AIM-9XX}",
["num"] = 11,
},
},
["tasks"] = {
[1] = 11,

View File

@@ -0,0 +1,329 @@
local unitPayloads = {
["name"] = "F4U-1D",
["payloads"] = {
[1] = {
["displayName"] = "Retribution BARCAP",
["name"] = "Retribution BARCAP",
["pylons"] = {
[1] = {
["CLSID"] = "{150_USgal_Corsair_droptank_mk5}",
["num"] = 7,
},
[2] = {
["CLSID"] = "{150_USgal_Corsair_droptank_mk5}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 10,
},
},
[2] = {
["displayName"] = "Retribution TARCAP",
["name"] = "Retribution TARCAP",
["pylons"] = {
[1] = {
["CLSID"] = "{150_USgal_Corsair_droptank_mk5}",
["num"] = 7,
},
[2] = {
["CLSID"] = "{150_USgal_Corsair_droptank_mk5}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 10,
},
},
[3] = {
["displayName"] = "Retribution Anti-ship",
["name"] = "Retribution Anti-ship",
["pylons"] = {
[1] = {
["CLSID"] = "{ASM_N_2}",
["num"] = 6,
},
},
["tasks"] = {
[1] = 10,
},
},
[4] = {
["displayName"] = "Retribution Strike",
["name"] = "Retribution Strike",
["pylons"] = {
[1] = {
["CLSID"] = "{Tiny_Tim_Corsair_R}",
["num"] = 7,
},
[2] = {
["CLSID"] = "{Tiny_Tim_Corsair_L}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 10,
},
},
[5] = {
["displayName"] = "Retribution CAS",
["name"] = "Retribution CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 7,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPMedium",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM101A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM101A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 5,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPMedium",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM101A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM101A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
[3] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 11,
},
[4] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 1,
},
[5] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 10,
},
[6] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 2,
},
[7] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 9,
},
[8] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 3,
},
[9] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 8,
},
[10] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 4,
},
[11] = {
["CLSID"] = "{AN-M64}",
["num"] = 6,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPMedium",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM101A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM101A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
},
["tasks"] = {
[1] = 10,
},
},
[6] = {
["displayName"] = "Retribution BAI",
["name"] = "Retribution BAI",
["pylons"] = {
[1] = {
["CLSID"] = "{AN_M65}",
["num"] = 7,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPLarge",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM102A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM102A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
[2] = {
["CLSID"] = "{AN_M65}",
["num"] = 5,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPLarge",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM102A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM102A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
[3] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 9,
},
[4] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 3,
},
[5] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 8,
},
[6] = {
["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}",
["num"] = 4,
},
},
["tasks"] = {
[1] = 10,
},
},
[7] = {
["displayName"] = "Retribution Escort",
["name"] = "Retribution Escort",
["pylons"] = {
[1] = {
["CLSID"] = "{150_USgal_Corsair_droptank_mk5}",
["num"] = 7,
},
[2] = {
["CLSID"] = "{150_USgal_Corsair_droptank_mk5}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 10,
},
},
[8] = {
["displayName"] = "Retribution Fighter Sweep",
["name"] = "Retribution Fighter Sweep",
["pylons"] = {
[1] = {
["CLSID"] = "{150_USgal_Corsair_droptank_mk5}",
["num"] = 7,
},
[2] = {
["CLSID"] = "{150_USgal_Corsair_droptank_mk5}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 10,
},
},
[9] = {
["displayName"] = "Retribution OCA/Runway",
["name"] = "Retribution OCA/Runway",
["pylons"] = {
[1] = {
["CLSID"] = "{AN_M65}",
["num"] = 7,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPLarge",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM102A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM102A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
[2] = {
["CLSID"] = "{AN_M65}",
["num"] = 5,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPLarge",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM102A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM102A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
},
["tasks"] = {
},
},
[10] = {
["displayName"] = "Retribution OCA/Aircraft",
["name"] = "Retribution OCA/Aircraft",
["pylons"] = {
[1] = {
["CLSID"] = "{AN-M64}",
["num"] = 7,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPMedium",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM101A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM101A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
[2] = {
["CLSID"] = "{AN-M64}",
["num"] = 5,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPMedium",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM101A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM101A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
[3] = {
["CLSID"] = "{AN-M64}",
["num"] = 6,
["settings"] = {
["NFP_PRESID"] = "WWII_B_A_GPMedium",
["NFP_PRESVER"] = 1,
["NFP_fuze_type_nose"] = 1,
["NFP_fuze_type_tail"] = 1,
["function_delay_ctrl_ANM101A2"] = 0,
["function_delay_ctrl_ANM103A1"] = 0,
["vane_rev_threshold_ctrl_ANM101A2"] = 160,
["vane_rev_threshold_ctrl_FD_0_ANM103A1"] = 300,
},
},
},
["tasks"] = {
},
},
},
["tasks"] = {
},
["unitType"] = "F4U-1D",
}
return unitPayloads

View File

@@ -14,19 +14,19 @@ local unitPayloads = {
["num"] = 2,
},
[3] = {
["CLSID"] = "{R-37}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{R-37}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{R-37}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 5,
},
[6] = {
["CLSID"] = "{R-37}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 6,
},
[7] = {
@@ -51,19 +51,19 @@ local unitPayloads = {
["num"] = 1,
},
[2] = {
["CLSID"] = "{R-33}",
["CLSID"] = "{R-33_mig31bm}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{R-33}",
["CLSID"] = "{R-33_mig31bm}",
["num"] = 4,
},
[4] = {
["CLSID"] = "{R-33}",
["CLSID"] = "{R-33_mig31bm}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{R-33}",
["CLSID"] = "{R-33_mig31bm}",
["num"] = 6,
},
[6] = {
@@ -96,19 +96,19 @@ local unitPayloads = {
["num"] = 2,
},
[3] = {
["CLSID"] = "{R-37M}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{R-37M}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{R-37M}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 5,
},
[6] = {
["CLSID"] = "{R-37M}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 6,
},
[7] = {
@@ -129,11 +129,11 @@ local unitPayloads = {
["name"] = "Retribution SEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}",
["CLSID"] = "{Kh-31_mig31bm}",
["num"] = 7,
},
[2] = {
["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}",
["CLSID"] = "{Kh-31_mig31bm}",
["num"] = 2,
},
[3] = {
@@ -154,27 +154,27 @@ local unitPayloads = {
["name"] = "Retribution SEAD Escort",
["pylons"] = {
[1] = {
["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}",
["CLSID"] = "{Kh-31_mig31bm}",
["num"] = 7,
},
[2] = {
["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}",
["CLSID"] = "{Kh-31_mig31bm}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{R-37M}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{R-37M}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{R-37M}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 5,
},
[6] = {
["CLSID"] = "{R-37M}",
["CLSID"] = "{R-37M_mig31bm}",
["num"] = 6,
},
},

View File

@@ -0,0 +1,107 @@
local unitPayloads = {
["name"] = "Tornado_ADV",
["payloads"] = {
[1] = {
["name"] = "Retribution Escort",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-9P5}",
["num"] = 1,
},
[2] = {
["CLSID"] = "{PTB_800_MIG21}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AIM-9P5}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 7,
},
[7] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 8,
},
[8] = {
["CLSID"] = "{AIM-9P5}",
["num"] = 10,
},
[9] = {
["CLSID"] = "{PTB_800_MIG21}",
["num"] = 11,
},
[10] = {
["CLSID"] = "{AIM-9P5}",
["num"] = 12,
},
},
["tasks"] = {
[1] = 18,
[2] = 11,
[3] = 10,
},
},
[2] = {
["name"] = "Retribution BARCAP",
["pylons"] = {
[1] = {
["CLSID"] = "{AIM-9P5}",
["num"] = 1,
},
[2] = {
["CLSID"] = "{PTB_800_MIG21}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{AIM-9P5}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 5,
},
[5] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 6,
},
[6] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 7,
},
[7] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 8,
},
[8] = {
["CLSID"] = "{AIM-9P5}",
["num"] = 10,
},
[9] = {
["CLSID"] = "{PTB_800_MIG21}",
["num"] = 11,
},
[10] = {
["CLSID"] = "{AIM-9P5}",
["num"] = 12,
},
},
["tasks"] = {
[1] = 18,
[2] = 11,
[3] = 10,
},
},
},
["unitType"] = "Tornado_ADV",
}
return unitPayloads

File diff suppressed because it is too large Load Diff

View File

@@ -55,6 +55,20 @@
"hertz": 113000000,
"channel": 77
},
"airfield26_0": {
"name": "enontekio",
"callsign": "ET",
"beacon_type": 14,
"hertz": 111300000,
"channel": null
},
"airfield26_1": {
"name": "enontekio",
"callsign": "ET",
"beacon_type": 13,
"hertz": 111300000,
"channel": null
},
"airfield18_0": {
"name": "IVALO",
"callsign": "iv",
@@ -100,14 +114,14 @@
"airfield22_0": {
"name": "KITTILA",
"callsign": "KT",
"beacon_type": 13,
"beacon_type": 14,
"hertz": 111900000,
"channel": null
},
"airfield22_1": {
"name": "KITTILA",
"callsign": "KT",
"beacon_type": 14,
"beacon_type": 13,
"hertz": 111900000,
"channel": null
},
@@ -146,6 +160,27 @@
"hertz": null,
"channel": 28
},
"airfield24_0": {
"name": "alta",
"callsign": "AT",
"beacon_type": 13,
"hertz": 108900000,
"channel": null
},
"airfield24_1": {
"name": "alta",
"callsign": "AT",
"beacon_type": 14,
"hertz": 108900000,
"channel": null
},
"airfield24_2": {
"name": "alta",
"callsign": "ATA",
"beacon_type": 3,
"hertz": 117400000,
"channel": null
},
"airfield7_0": {
"name": "BODO",
"callsign": "BO",
@@ -161,7 +196,7 @@
"channel": 122
},
"airfield7_2": {
"name": "BODO-ILSTAD",
"name": "BODO",
"callsign": "BD",
"beacon_type": 14,
"hertz": 108700000,
@@ -191,16 +226,16 @@
"airfield21_0": {
"name": "BARDUFOSS",
"callsign": "BF",
"beacon_type": 13,
"beacon_type": 14,
"hertz": 108700000,
"channel": null
},
"airfield21_1": {
"name": "BARDUFOSS",
"callsign": "BF",
"beacon_type": 14,
"hertz": 108700000,
"channel": null
"callsign": "BDF",
"beacon_type": 3,
"hertz": 114200000,
"channel": 89
},
"airfield21_2": {
"name": "BARDUFOSS",
@@ -209,12 +244,33 @@
"hertz": 108700000,
"channel": null
},
"airfield21_3": {
"name": "BARDUFOSS",
"callsign": "BDF",
"airfield25_0": {
"name": "EVENES",
"callsign": "ev",
"beacon_type": 14,
"hertz": 108900000,
"channel": null
},
"airfield25_1": {
"name": "EVENES",
"callsign": "ev",
"beacon_type": 13,
"hertz": 108900000,
"channel": null
},
"airfield25_2": {
"name": "EVENES",
"callsign": "EVD",
"beacon_type": 3,
"hertz": 114200000,
"channel": 89
"hertz": 117350000,
"channel": null
},
"airfield25_3": {
"name": "EVS",
"callsign": "Evenes",
"beacon_type": 4,
"hertz": 134000000,
"channel": 73
},
"airfield14_0": {
"name": "KIRKENES",

View File

@@ -21,524 +21,489 @@
"channel": 99
},
"world_3": {
"name": "Damascus",
"callsign": "DAM",
"beacon_type": 3,
"hertz": 116000000,
"channel": 107
},
"world_4": {
"name": "Beirut",
"callsign": "BOD",
"beacon_type": 8,
"hertz": 351000,
"channel": 0
},
"world_5": {
"world_4": {
"name": "Asyut",
"callsign": "AST",
"beacon_type": 3,
"hertz": 117700000,
"channel": 124
},
"world_6": {
"world_5": {
"name": "Aqaba",
"callsign": "AQC",
"beacon_type": 8,
"hertz": 326000,
"channel": 0
},
"world_7": {
"name": "Mezze",
"callsign": "MEZ",
"beacon_type": 8,
"hertz": 358000,
"channel": 0
},
"world_8": {
"world_6": {
"name": "Kariatain",
"callsign": "KTN",
"beacon_type": 8,
"hertz": 373000,
"channel": 0
},
"world_9": {
"world_7": {
"name": "BasselAlAssad",
"callsign": "LTK",
"beacon_type": 3,
"hertz": 114800000,
"channel": 95
},
"world_10": {
"world_8": {
"name": "Taba",
"callsign": "TBA",
"beacon_type": 3,
"hertz": 114500000,
"channel": 92
},
"world_11": {
"world_9": {
"name": "Nuweibaa",
"callsign": "NWB",
"beacon_type": 8,
"hertz": 288000,
"channel": 0
},
"world_12": {
"world_10": {
"name": "Jerusalem",
"callsign": "IRM",
"beacon_type": 8,
"hertz": 336000,
"channel": 0
},
"world_13": {
"world_11": {
"name": "Almaza",
"callsign": "A",
"beacon_type": 8,
"hertz": 490000,
"channel": 0
},
"world_14": {
"world_12": {
"name": "Amman",
"callsign": "AMN",
"beacon_type": 3,
"hertz": 116300000,
"channel": 110
},
"world_15": {
"world_13": {
"name": "BenGurion",
"callsign": "BGN",
"beacon_type": 5,
"hertz": 113500000,
"channel": 82
},
"world_16": {
"world_14": {
"name": "Almaza",
"callsign": "MXR",
"beacon_type": 4,
"hertz": 116300000,
"channel": 110
},
"world_17": {
"world_15": {
"name": "Haifa",
"callsign": "HFA",
"beacon_type": 8,
"hertz": 323000,
"channel": 0
},
"world_18": {
"world_16": {
"name": "Aqaba",
"callsign": "AQ",
"beacon_type": 8,
"hertz": 404000,
"channel": 0
},
"world_19": {
"world_17": {
"name": "Alexandria",
"callsign": "AXD",
"beacon_type": 8,
"hertz": 403000,
"channel": 0
},
"world_20": {
"world_18": {
"name": "Baltim",
"callsign": "BLT",
"beacon_type": 3,
"hertz": 116900000,
"channel": 116
},
"world_21": {
"world_19": {
"name": "Turaif",
"callsign": "TRF",
"beacon_type": 3,
"hertz": 116100000,
"channel": 108
},
"world_22": {
"world_20": {
"name": "Wejh",
"callsign": "WEJ",
"beacon_type": 5,
"hertz": 113900000,
"channel": 86
},
"world_23": {
"world_21": {
"name": "Metzada",
"callsign": "MZD",
"beacon_type": 5,
"hertz": 115000000,
"channel": 97
},
"world_24": {
"world_22": {
"name": "RoshPina",
"callsign": "RPN",
"beacon_type": 8,
"hertz": 243000,
"channel": 0
},
"world_25": {
"world_23": {
"name": "Chekka",
"callsign": "CAK",
"beacon_type": 3,
"hertz": 116200000,
"channel": 109
},
"world_26": {
"world_24": {
"name": "QueenAlia",
"callsign": "QA",
"beacon_type": 8,
"hertz": 410000,
"channel": 0
},
"world_27": {
"world_25": {
"name": "October",
"callsign": "OCT",
"beacon_type": 8,
"hertz": 340000,
"channel": 0
},
"world_28": {
"world_26": {
"name": "PortSaid",
"callsign": "PSD",
"beacon_type": 3,
"hertz": 112700000,
"channel": 74
},
"world_29": {
"world_27": {
"name": "Alexandria",
"callsign": "NOZ",
"beacon_type": 3,
"hertz": 115900000,
"channel": 106
},
"world_30": {
"world_28": {
"name": "DeirZzor",
"callsign": "DRZ",
"beacon_type": 8,
"hertz": 295000,
"channel": 0
},
"world_31": {
"world_29": {
"name": "DeirZzor",
"callsign": "DRZ",
"beacon_type": 3,
"hertz": 117000000,
"channel": 117
},
"world_32": {
"world_30": {
"name": "Cairo",
"callsign": "ALI",
"beacon_type": 8,
"hertz": 310000,
"channel": 0
},
"world_33": {
"world_31": {
"name": "Al-Shigar",
"callsign": "ASH",
"beacon_type": 3,
"hertz": 112300000,
"channel": 70
},
"world_34": {
"world_32": {
"name": "Cairo",
"callsign": "MKT",
"beacon_type": 8,
"hertz": 317000,
"channel": 0
},
"world_35": {
"world_33": {
"name": "MarsaAlam",
"callsign": "MAK",
"beacon_type": 3,
"hertz": 115500000,
"channel": 102
},
"world_36": {
"world_34": {
"name": "Taba",
"callsign": "TBA",
"beacon_type": 8,
"hertz": 316000,
"channel": 0
},
"world_37": {
"world_35": {
"name": "Zofar",
"callsign": "ZFR",
"beacon_type": 3,
"hertz": 115600000,
"channel": 103
},
"world_38": {
"world_36": {
"name": "Natania",
"callsign": "NAT",
"beacon_type": 5,
"hertz": 112400000,
"channel": 71
},
"world_39": {
"world_37": {
"name": "Kariatain",
"callsign": "KTN",
"beacon_type": 3,
"hertz": 117700000,
"channel": 124
},
"world_40": {
"world_38": {
"name": "Herzlia",
"callsign": "HRZ",
"beacon_type": 8,
"hertz": 273000,
"channel": 0
},
"world_41": {
"world_39": {
"name": "Guriat",
"callsign": "GRY",
"beacon_type": 5,
"hertz": 114700000,
"channel": 94
},
"world_42": {
"world_40": {
"name": "Gaza",
"callsign": "GZA",
"beacon_type": 3,
"hertz": 113350000,
"channel": 80
},
"world_43": {
"world_41": {
"name": "Cairo",
"callsign": "CVO",
"beacon_type": 3,
"hertz": 115200000,
"channel": 99
},
"world_44": {
"world_42": {
"name": "ReneMouawad",
"callsign": "RA",
"beacon_type": 8,
"hertz": 450000,
"channel": 0
},
"world_45": {
"world_43": {
"name": "Amman",
"callsign": "JYO",
"beacon_type": 8,
"hertz": 391000,
"channel": 0
},
"world_46": {
"world_44": {
"name": "Aqaba",
"callsign": "AQA",
"beacon_type": 8,
"hertz": 418000,
"channel": 0
},
"world_47": {
"world_45": {
"name": "Cairo",
"callsign": "CAI",
"beacon_type": 3,
"hertz": 112500000,
"channel": 72
},
"world_48": {
"world_46": {
"name": "BasselAlAssad",
"callsign": "LTK",
"beacon_type": 8,
"hertz": 414000,
"channel": 0
},
"world_49": {
"world_47": {
"name": "QueenAlia(Locator)",
"callsign": "QL",
"beacon_type": 8,
"hertz": 307000,
"channel": 0
},
"world_50": {
"name": "Khaldeh",
"callsign": "KAD",
"beacon_type": 3,
"hertz": 112600000,
"channel": 73
},
"world_51": {
"world_48": {
"name": "ElDaba",
"callsign": "DBA",
"beacon_type": 3,
"hertz": 115700000,
"channel": 104
},
"world_52": {
"world_49": {
"name": "InnerBeacon",
"callsign": "D",
"beacon_type": 8,
"hertz": 273000,
"channel": 0
},
"world_53": {
"world_50": {
"name": "CairoWest",
"callsign": "BLA",
"beacon_type": 4,
"hertz": 116700000,
"channel": 114
},
"world_54": {
"world_51": {
"name": "Gaza",
"callsign": "RFH",
"beacon_type": 8,
"hertz": 380000,
"channel": 0
},
"world_55": {
"world_52": {
"name": "Palmyra",
"callsign": "PAL",
"beacon_type": 8,
"hertz": 337000,
"channel": 0
},
"world_56": {
"world_53": {
"name": "ElKharga",
"callsign": "KHG",
"beacon_type": 3,
"hertz": 113800000,
"channel": 85
},
"world_57": {
"world_54": {
"name": "Halaifa",
"callsign": "HLF",
"beacon_type": 3,
"hertz": 116700000,
"channel": 114
},
"world_58": {
"world_55": {
"name": "Aqaba",
"callsign": "AQB",
"beacon_type": 3,
"hertz": 113100000,
"channel": 78
},
"world_59": {
"world_56": {
"name": "Beirut",
"callsign": "BAB",
"beacon_type": 8,
"hertz": 312000,
"channel": 0
},
"world_60": {
"world_57": {
"name": "SidiBarrani",
"callsign": "BRN",
"beacon_type": 3,
"hertz": 116200000,
"channel": 109
},
"world_61": {
"world_58": {
"name": "Luxor",
"callsign": "LXR",
"beacon_type": 3,
"hertz": 114400000,
"channel": 91
},
"world_62": {
"world_59": {
"name": "Luxor",
"callsign": "LO",
"beacon_type": 8,
"hertz": 364000,
"channel": 0
},
"world_63": {
"world_60": {
"name": "Tabuk",
"callsign": "TBK",
"beacon_type": 5,
"hertz": 115700000,
"channel": 104
},
"world_64": {
"world_61": {
"name": "Tanf",
"callsign": "TAN",
"beacon_type": 3,
"hertz": 114000000,
"channel": 87
},
"world_65": {
"world_62": {
"name": "Qatraneh",
"callsign": "JYT",
"beacon_type": 8,
"hertz": 302000,
"channel": 0
},
"world_66": {
"world_63": {
"name": "BorgElArab",
"callsign": "DJ",
"beacon_type": 8,
"hertz": 563000,
"channel": 0
},
"world_67": {
"name": "Abyad",
"callsign": "ABD",
"beacon_type": 8,
"hertz": 264000,
"channel": 0
},
"world_68": {
"name": "Otaebe",
"callsign": "DAL",
"beacon_type": 8,
"hertz": 342000,
"channel": 0
},
"world_69": {
"world_64": {
"name": "Beer-Sheba",
"callsign": "BSA",
"beacon_type": 5,
"hertz": 114300000,
"channel": 90
},
"world_70": {
"world_65": {
"name": "Dakhla",
"callsign": "MB",
"beacon_type": 8,
"hertz": 387000,
"channel": 0
},
"world_71": {
"world_66": {
"name": "Eilot",
"callsign": "LOT",
"beacon_type": 3,
"hertz": 112000000,
"channel": 57
},
"world_72": {
"world_67": {
"name": "SharmElSheikh",
"callsign": "SKH",
"beacon_type": 8,
"hertz": 335000,
"channel": 0
},
"world_73": {
"world_68": {
"name": "RoshPina",
"callsign": "ROP",
"beacon_type": 3,
"hertz": 115300000,
"channel": 100
},
"world_74": {
"world_69": {
"name": "Ovda",
"callsign": "OVD",
"beacon_type": 5,
"hertz": 114100000,
"channel": 88
},
"world_75": {
"world_70": {
"name": "Qatraneh",
"callsign": "QTR",
"beacon_type": 3,
"hertz": 112900000,
"channel": 76
},
"world_76": {
"world_71": {
"name": "Fayoum",
"callsign": "FYM",
"beacon_type": 3,
"hertz": 117300000,
"channel": 120
},
"world_77": {
"world_72": {
"name": "SHG",
"callsign": "SHG",
"beacon_type": 3,
@@ -661,14 +626,14 @@
"name": "BilbeisAirBase",
"callsign": "BA",
"beacon_type": 14,
"hertz": 108600000,
"hertz": 108300000,
"channel": null
},
"airfield16_1": {
"name": "BilbeisAirBase",
"callsign": "BA",
"beacon_type": 13,
"hertz": 108600000,
"hertz": 108300000,
"channel": null
},
"airfield5_0": {
@@ -797,6 +762,55 @@
"hertz": 111500000,
"channel": null
},
"airfield48_0": {
"name": "",
"callsign": "IDA",
"beacon_type": 13,
"hertz": 109900000,
"channel": null
},
"airfield48_1": {
"name": "",
"callsign": "DAML",
"beacon_type": 13,
"hertz": 111100000,
"channel": null
},
"airfield48_2": {
"name": "",
"callsign": "DAML",
"beacon_type": 14,
"hertz": 111100000,
"channel": null
},
"airfield48_3": {
"name": "Damascus",
"callsign": "DAM",
"beacon_type": 3,
"hertz": 116000000,
"channel": 107
},
"airfield48_4": {
"name": "",
"callsign": "IDA",
"beacon_type": 14,
"hertz": 109900000,
"channel": null
},
"airfield48_5": {
"name": "Otaebe",
"callsign": "DAL",
"beacon_type": 8,
"hertz": 342000,
"channel": 0
},
"airfield48_6": {
"name": "Abyad",
"callsign": "ABD",
"beacon_type": 8,
"hertz": 264000,
"channel": 0
},
"airfield29_0": {
"name": "ElArish",
"callsign": "ARH",
@@ -902,6 +916,13 @@
"hertz": 113700000,
"channel": 55
},
"airfield49_0": {
"name": "Mezze",
"callsign": "MEZ",
"beacon_type": 8,
"hertz": 358000,
"channel": 0
},
"airfield8_0": {
"name": "Nevatim",
"callsign": "NEV",
@@ -937,6 +958,48 @@
"hertz": 109700000,
"channel": null
},
"airfield46_1": {
"name": "",
"callsign": "IBB",
"beacon_type": 13,
"hertz": 110100000,
"channel": null
},
"airfield46_3": {
"name": "",
"callsign": "IKK",
"beacon_type": 13,
"hertz": 110700000,
"channel": null
},
"airfield46_4": {
"name": "",
"callsign": "IBB",
"beacon_type": 14,
"hertz": 110100000,
"channel": null
},
"airfield46_5": {
"name": "KALDE",
"callsign": "KAD",
"beacon_type": 3,
"hertz": 112600000,
"channel": null
},
"airfield46_6": {
"name": "",
"callsign": "IKK",
"beacon_type": 14,
"hertz": 110700000,
"channel": null
},
"airfield50_0": {
"name": "RMTDVD",
"callsign": "RMD",
"beacon_type": 5,
"hertz": 113700000,
"channel": 84
},
"airfield9_0": {
"name": "Ramon",
"callsign": "RMN",
@@ -1014,6 +1077,41 @@
"hertz": 114200000,
"channel": 89
},
"airfield47_0": {
"name": "",
"callsign": "ITBK",
"beacon_type": 14,
"hertz": 109500000,
"channel": null
},
"airfield47_1": {
"name": "TABUK",
"callsign": "TBK",
"beacon_type": 1,
"hertz": 115700000,
"channel": 104
},
"airfield47_2": {
"name": "",
"callsign": "IPKA",
"beacon_type": 13,
"hertz": 111900000,
"channel": null
},
"airfield47_3": {
"name": "",
"callsign": "ITBK",
"beacon_type": 13,
"hertz": 109500000,
"channel": null
},
"airfield47_4": {
"name": "",
"callsign": "IPKS",
"beacon_type": 14,
"hertz": 111900000,
"channel": null
},
"airfield23_0": {
"name": "TelNof",
"callsign": "AKR",

View File

@@ -7,6 +7,7 @@
"A-20G Havoc",
"B-17G Flying Fortress",
"C-47 Skytrain",
"F4U-1D Corsair",
"P-47D-30 Thunderbolt (Early)",
"P-47D-30 Thunderbolt (Late)",
"P-47D-40 Thunderbolt",
@@ -48,14 +49,19 @@
],
"preset_groups": [
"Ally Flak",
"WW2LST"
"WW2LST",
"WW2Essex"
],
"naval_units": [
"USS Bennington (CV-20)"
],
"naval_units": [],
"requirements": {
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/"
},
"carrier_names": [],
"helicopter_carrier_names": [],
"helicopter_carrier_names": [
"USS Essex (CV-9)"
],
"has_jtac": false,
"doctrine": "ww2",
"building_set": "ww2ally",

View File

@@ -5,6 +5,9 @@
"description": "<p>Blufor 1980s late cold war faction featuring units from NATO and NATO-aligned nations.</p>",
"aircrafts": [
"A-10A Thunderbolt II",
"A-10C Thunderbolt II (Suite 3)",
"A-10C Thunderbolt II (Suite 7)",
"AH-64D Apache Longbow",
"A-4E Skyhawk",
"A-6A Intruder",
"A-7E Corsair II",
@@ -29,6 +32,7 @@
"F-4E Phantom II",
"F-4E-45MC Phantom II",
"F-5E Tiger II",
"F-5E Tiger II (FC)",
"OH-58D(R) Kiowa Warrior",
"Mi-8MTV2 Hip",
"MiG-21bis Fishbed-N",
@@ -37,10 +41,12 @@
"Mirage-F1CE",
"Mirage-F1C-200",
"Mirage-F1EE",
"Mirage 2000C",
"S-3B Viking",
"SA 342L Gazelle",
"SA 342M Gazelle",
"SH-60B Seahawk",
"Tornado IDS",
"UH-1H Iroquois",
"UH-60A",
"UH-60L"
@@ -51,7 +57,8 @@
],
"tankers": [
"KC-130",
"KC-135 Stratotanker"
"KC-135 Stratotanker",
"S-3B Tanker"
],
"frontline_units": [
"M113",
@@ -110,4 +117,4 @@
"has_jtac": true,
"jtac_unit": "MQ-9 Reaper",
"doctrine": "coldwar"
}
}

View File

@@ -13,19 +13,28 @@
"frontline_units": [
"8.8 cm Flak 18",
"Panzerkampfwagen IV Ausf. H",
"Sd.Kfz.251 \"Hanomag\""
"Sd.Kfz.251 \"Hanomag\"",
"Type 89 I Go Tank",
"AAA 25mm x 2 Type 94 Truck",
"Type 98 Ke Ni Tank",
"APC Type 98 So Da"
],
"artillery_units": [
"Mortar 2B11 120mm"
],
"logistics_units": [
"Truck Opel Blitz"
"Truck Opel Blitz",
"Truck Type 94"
],
"infantry_units": [
"Infantry AK-74 Rus"
],
"air_defense_units": [
"8.8 cm Flak 18"
"8.8 cm Flak 18",
"AAA 80mm Type 3 Flak",
"AAA 75mm Type 88 Flak",
"AAA 25mm x 2 Type 96",
"AAA 25mm x 2 Type 94 Truck"
],
"preset_groups": [],
"naval_units": [],

View File

@@ -7,6 +7,7 @@
"ru_RU"
],
"aircrafts": [
"An-26B",
"IL-76MD",
"Mi-24V Hind-E",
"Mi-24P Hind-F",

View File

@@ -3,6 +3,7 @@
"name": "Ukraine 2010",
"authors": "Khopa",
"description": "<p>Ukrainian army in the 2010s.</p>",
"locales": ["uk_UA"],
"aircrafts": [
"IL-76MD",
"L-39ZA Albatros",

Some files were not shown because too many files have changed in this diff Show More