Merge remote-tracking branch 'remotes/dcs-retribution/dcs-retribution/dev' into pretense-generator

This commit is contained in:
MetalStormGhost 2024-06-22 09:57:18 +03:00
commit b27141cb1e
44 changed files with 324 additions and 129 deletions

View File

@ -532,6 +532,15 @@ class AircraftType(UnitType[Type[FlyingType]]):
for task_name, priority in data.get("tasks", {}).items():
task_priorities[FlightType(task_name)] = priority
if (
FlightType.SEAD_SWEEP not in task_priorities
and FlightType.SEAD in task_priorities
):
task_priorities[FlightType.SEAD_SWEEP] = task_priorities[FlightType.SEAD]
cls._custom_weapon_injections(aircraft, data)
cls._user_weapon_injections(aircraft)
display_name = data.get("display_name", variant_id)
return AircraftType(
dcs_unit_type=aircraft,

View File

@ -402,6 +402,8 @@ class Faction:
self.remove_aircraft("VSN_F106B")
if not mod_settings.a6a_intruder:
self.remove_aircraft("VSN_A6A")
if not mod_settings.ea6b_prowler:
self.remove_aircraft("EA_6B")
if not mod_settings.jas39_gripen:
self.remove_aircraft("JAS39Gripen")
self.remove_aircraft("JAS39Gripen_BVR")

View File

@ -159,11 +159,13 @@ class MissionResultsProcessor:
captured.control_point.capture(
self.game, events, captured.captured_by_player
)
logging.info(f"Will run redeploy for {captured.control_point}")
self.redeploy_units(captured.control_point)
except Exception:
logging.exception(f"Could not process base capture {captured}")
for captured in debriefing.base_captures:
logging.info(f"Will run redeploy for {captured.control_point}")
self.redeploy_units(captured.control_point)
def record_carcasses(self, debriefing: Debriefing) -> None:
for destroyed_unit in debriefing.state_data.destroyed_statics:
self.game.add_destroyed_units(destroyed_unit)
@ -301,10 +303,6 @@ class MissionResultsProcessor:
""" "
Auto redeploy units to newly captured base
"""
ally_connected_cps = [
ocp for ocp in cp.connected_points if cp.captured == ocp.captured
]
enemy_connected_cps = [
ocp for ocp in cp.connected_points if cp.captured != ocp.captured
]
@ -314,28 +312,54 @@ class MissionResultsProcessor:
if len(enemy_connected_cps) == 0:
return
ally_connected_cps = [
ocp
for ocp in cp.transitive_connected_friendly_destinations()
if cp.captured == ocp.captured and ocp.base.total_armor
]
settings = cp.coalition.game.settings
factor = (
settings.frontline_reserves_factor
if cp.captured
else settings.frontline_reserves_factor_red
)
# From each ally cp, send reinforcements
for ally_cp in ally_connected_cps:
for ally_cp in sorted(
ally_connected_cps,
key=lambda x: len(
[cp for cp in x.connected_points if x.captured != cp.captured]
),
):
self.redeploy_between(cp, ally_cp)
if cp.base.total_armor > factor * cp.deployable_front_line_units:
break
def redeploy_between(self, destination: ControlPoint, source: ControlPoint) -> None:
total_units_redeployed = 0
moved_units = {}
if source.has_active_frontline or not destination.captured:
# If there are still active front lines to defend at the
# transferring CP we should not transfer all units.
#
# Opfor also does not transfer all of their units.
# TODO: Balance the CPs rather than moving half from everywhere.
move_factor = 0.5
else:
# Otherwise we can move everything.
move_factor = 1
settings = source.coalition.game.settings
reserves = max(
1,
settings.reserves_procurement_target
if source.captured
else settings.reserves_procurement_target_red,
)
total_units = source.base.total_armor
reserves_factor = (reserves - 1) / total_units # slight underestimation
source_frontline_count = len(
[cp for cp in source.connected_points if not source.is_friendly_to(cp)]
)
move_factor = max(0.0, 1 / (source_frontline_count + 1) - reserves_factor)
for frontline_unit, count in source.base.armor.items():
moved_units[frontline_unit] = int(count * move_factor)
total_units_redeployed = total_units_redeployed + int(count * move_factor)
moved_count = int(count * move_factor)
moved_units[frontline_unit] = moved_count
total_units_redeployed += moved_count
destination.base.commission_units(moved_units)
source.base.commit_losses(moved_units)

View File

@ -572,6 +572,23 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
connected.extend(cp.transitive_friendly_shipping_destinations(seen))
return connected
def transitive_connected_friendly_destinations(
self, seen: Optional[Set[ControlPoint]] = None
) -> List[ControlPoint]:
if seen is None:
seen = {self}
connected = []
for cp in set(self.connected_points + list(self.shipping_lanes.keys())):
if cp.captured != self.captured:
continue
if cp in seen:
continue
seen.add(cp)
connected.append(cp)
connected.extend(cp.transitive_connected_friendly_destinations(seen))
return connected
@property
def has_factory(self) -> bool:
for tgo in self.connected_objectives:

View File

@ -68,6 +68,7 @@ class ModSettings:
a4_skyhawk: bool = False
a6a_intruder: bool = False
a7e_corsair2: bool = False
ea6b_prowler: bool = False
f4bc_phantom: bool = False
f9f_panther: bool = False
f15d_baz: bool = False

View File

@ -2,6 +2,7 @@ from .SWPack import *
from .a4ec import *
from .a7e import *
from .a6a import *
from .ea6b import *
from .f9f import *
from .f100 import *
from .f104 import *

View File

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

View File

@ -0,0 +1,105 @@
from dcs import task
from dcs.planes import PlaneType
from dcs.weapons_data import Weapons
from game.modsupport import planemod
from pydcs_extensions.weapon_injector import inject_weapons
class WeaponsEA6B:
EA6B_AN_ALQ_99 = {
"clsid": "{EA6B_ANALQ991}",
"name": "EA6B AN-ALQ-99",
"weight": 435,
}
EA6B_AN_ALQ_99_ = {
"clsid": "{EA6B_ANALQ992}",
"name": "EA6B AN-ALQ-99",
"weight": 435,
}
inject_weapons(WeaponsEA6B)
@planemod
class EA_6B(PlaneType):
id = "EA_6B"
height = 4.57
width = 10.15
length = 17.98
fuel_max = 6994
max_speed = 1047.96
chaff = 30
flare = 30
charge_total = 60
chaff_charge_size = 1
flare_charge_size = 1
eplrs = True
radio_frequency = 250.5
livery_name = "EA_6B" # from type
class Pylon1:
LAU_118A___AGM_45B_Shrike_ARM = (1, Weapons.LAU_118A___AGM_45B_Shrike_ARM)
AGM_88C_HARM___High_Speed_Anti_Radiation_Missile_ = (
1,
Weapons.AGM_88C_HARM___High_Speed_Anti_Radiation_Missile_,
)
F_5_275Gal_Fuel_tank = (1, Weapons.F_5_275Gal_Fuel_tank)
EA6B_AN_ALQ_99 = (1, Weapons.EA6B_AN_ALQ_99)
# ERRR <CLEAN>
class Pylon2:
LAU_118A___AGM_45B_Shrike_ARM = (2, Weapons.LAU_118A___AGM_45B_Shrike_ARM)
AGM_88C_HARM___High_Speed_Anti_Radiation_Missile_ = (
2,
Weapons.AGM_88C_HARM___High_Speed_Anti_Radiation_Missile_,
)
F_5_275Gal_Fuel_tank = (2, Weapons.F_5_275Gal_Fuel_tank)
EA6B_AN_ALQ_99 = (2, Weapons.EA6B_AN_ALQ_99)
# ERRR <CLEAN>
class Pylon3:
F_5_275Gal_Fuel_tank = (3, Weapons.F_5_275Gal_Fuel_tank)
EA6B_AN_ALQ_99_ = (3, Weapons.EA6B_AN_ALQ_99_)
# ERRR <CLEAN>
class Pylon4:
LAU_118A___AGM_45B_Shrike_ARM = (4, Weapons.LAU_118A___AGM_45B_Shrike_ARM)
AGM_88C_HARM___High_Speed_Anti_Radiation_Missile_ = (
4,
Weapons.AGM_88C_HARM___High_Speed_Anti_Radiation_Missile_,
)
F_5_275Gal_Fuel_tank = (4, Weapons.F_5_275Gal_Fuel_tank)
EA6B_AN_ALQ_99 = (4, Weapons.EA6B_AN_ALQ_99)
# ERRR <CLEAN>
class Pylon5:
LAU_118A___AGM_45B_Shrike_ARM = (5, Weapons.LAU_118A___AGM_45B_Shrike_ARM)
AGM_88C_HARM___High_Speed_Anti_Radiation_Missile_ = (
5,
Weapons.AGM_88C_HARM___High_Speed_Anti_Radiation_Missile_,
)
F_5_275Gal_Fuel_tank = (5, Weapons.F_5_275Gal_Fuel_tank)
EA6B_AN_ALQ_99 = (5, Weapons.EA6B_AN_ALQ_99)
# ERRR <CLEAN>
pylons = {1, 2, 3, 4, 5}
tasks = [
task.Escort,
task.Reconnaissance,
task.GroundAttack,
task.CAS,
task.AFAC,
task.RunwayAttack,
task.AntishipStrike,
task.SEAD,
]
task_default = task.GroundAttack

View File

@ -324,6 +324,7 @@ def create_game(
a4_skyhawk=False,
a6a_intruder=False,
a7e_corsair2=False,
ea6b_prowler=False,
fa_18efg=False,
fa18ef_tanker=False,
f4bc_phantom=False,

View File

@ -19,6 +19,7 @@ from game.radio.RadioFrequencyContainer import RadioFrequencyContainer
from game.radio.TacanContainer import TacanContainer
from game.server import EventStream
from game.sim import GameUpdateEvents
from game.sim.missionresultsprocessor import MissionResultsProcessor
from game.theater import (
AMMO_DEPOT_FRONTLINE_UNIT_CONTRIBUTION,
ControlPoint,
@ -181,6 +182,8 @@ class QBaseMenu2(QDialog):
def cheat_capture(self) -> None:
events = GameUpdateEvents()
self.cp.capture(self.game_model.game, events, for_player=not self.cp.captured)
mrp = MissionResultsProcessor(self.game_model.game)
mrp.redeploy_units(self.cp)
# Reinitialized ground planners and the like. The ATO needs to be reset because
# missions planned against the flipped base are no longer valid.
self.game_model.game.initialize_turn(events)

View File

@ -92,6 +92,7 @@ class NewGameWizard(QtWidgets.QWizard):
a4_skyhawk=self.field("a4_skyhawk"),
a6a_intruder=self.field("a6a_intruder"),
a7e_corsair2=self.field("a7e_corsair2"),
ea6b_prowler=self.field("ea6b_prowler"),
f4bc_phantom=self.field("f4bc_phantom"),
f15d_baz=self.field("f15d_baz"),
f_15_idf=self.field("f_15_idf"),

View File

@ -94,6 +94,8 @@ class GeneratorOptions(QtWidgets.QWizardPage):
self.registerField("a6a_intruder", self.a6a_intruder)
self.a7e_corsair2 = QtWidgets.QCheckBox()
self.registerField("a7e_corsair2", self.a7e_corsair2)
self.ea6b_prowler = QtWidgets.QCheckBox()
self.registerField("ea6b_prowler", self.ea6b_prowler)
self.hercules = QtWidgets.QCheckBox()
self.registerField("hercules", self.hercules)
self.uh_60l = QtWidgets.QCheckBox()
@ -160,6 +162,7 @@ class GeneratorOptions(QtWidgets.QWizardPage):
("A-6A Intruder (v2.7.5.01)", self.a6a_intruder),
("A-7E Corsair II", self.a7e_corsair2),
("C-130J-30 Super Hercules (v6.8.2)", self.hercules),
("EA-6B Prowler (v2.9.4.102)", self.ea6b_prowler),
("F-100 Super Sabre (v2.7.18.30765 patch 20.10.22)", self.f100_supersabre),
("F-104 Starfighter (v2.7.11.222.01)", self.f104_starfighter),
("F-105 Thunderchief (v2.7.12.23x)", self.f105_thunderchief),
@ -225,6 +228,7 @@ class GeneratorOptions(QtWidgets.QWizardPage):
self.a4_skyhawk.setChecked(s.get("a4_skyhawk", False))
self.a6a_intruder.setChecked(s.get("a6a_intruder", False))
self.a7e_corsair2.setChecked(s.get("a7e_corsair2", False))
self.ea6b_prowler.setChecked(s.get("ea6b_prowler", False))
self.hercules.setChecked(s.get("hercules", False))
self.uh_60l.setChecked(s.get("uh_60l", False))
self.f4bc_phantom.setChecked(s.get("f4bc_phantom", False))

View File

@ -4,34 +4,35 @@ asgiref==3.8.1
atomicwrites==1.4.1
attrs==23.2.0
black==23.9.1
certifi==2024.2.2
certifi==2024.6.2
cfgv==3.4.0
click==8.1.7
colorama==0.4.6
distlib==0.3.8
Faker==24.14.0
fastapi==0.110.2
filelock==3.13.4
Faker==25.8.0
fastapi==0.111.0
filelock==3.15.1
h11==0.14.0
httptools==0.6.1
identify==2.5.36
idna==3.7
iniconfig==2.0.0
Jinja2==3.1.3
lupa==2.1
Jinja2==3.1.4
lupa==2.2
MarkupSafe==2.1.5
mypy==1.10.0
mypy-extensions==1.0.0
nodeenv==1.8.0
packaging==24.0
nodeenv==1.9.1
numpy==1.26.4
packaging==24.1
pathspec==0.12.1
pefile==2023.2.7
Pillow==10.3.0
platformdirs==4.2.1
platformdirs==4.2.2
pluggy==1.5.0
pre-commit==3.7.0
pydantic==2.7.1
pydantic-settings==2.2.1
pre-commit==3.7.1
pydantic==2.7.4
pydantic-settings==2.3.3
pydcs @ git+https://github.com/dcs-retribution/pydcs@4f4d3fd51dc14ad8e16e3bf6b130e8efc18dcabd
pyinstaller==5.13.2
pyinstaller-hooks-contrib==2024.0
@ -41,7 +42,7 @@ pyshp==2.3.1
PySide6==6.4.2
PySide6-Addons==6.4.2
PySide6-Essentials==6.4.2
pytest==8.1.2
pytest==8.2.2
pytest-cov==5.0.0
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
@ -59,11 +60,11 @@ toml==0.10.2
tomli==2.0.1
types-Jinja2==2.11.9
types-MarkupSafe==1.1.10
types-Pillow==10.2.0.20240423
types-Pillow==10.2.0.20240520
types-PyYAML==6.0.12.20240311
types-tabulate==0.9.0.20240106
typing_extensions==4.11.0
uvicorn==0.29.0
virtualenv==20.26.0
typing_extensions==4.12.2
uvicorn==0.30.1
virtualenv==20.26.2
watchgod==0.8.2
websockets==12.0

View File

@ -43,11 +43,6 @@ squadrons:
aircraft:
- AH-64D Apache Longbow
size: 4
- primary: CAS
secondary: any
aircraft:
- OH-58D(R) Kiowa Warrior
size: 4
- primary: Refueling
aircraft:
- KC-135 Stratotanker
@ -101,7 +96,12 @@ squadrons:
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
size: 18
size: 10
- primary: CAS
secondary: any
aircraft:
- OH-58D(R) Kiowa Warrior
size: 8
- primary: Air Assault
secondary: any
aircraft:

View File

@ -32,7 +32,7 @@ squadrons:
aircraft:
- C-130J-30 Super Hercules
- C-130
size: 8
size: 4
# Tel Nof
23:
- primary: SEAD
@ -53,20 +53,20 @@ squadrons:
secondary: any
aircraft:
- UH-1H Iroquois
size: 8
size: 4
# Hatzor
20:
- primary: BAI
secondary: any
aircraft:
- A-4E Skyhawk
- F-4E Phantom II
- F-4E-45MC Phantom II
size: 20
- primary: Strike
secondary: any
aircraft:
- A-4E Skyhawk
- F-4E Phantom II
- F-4E-45MC Phantom II
size: 20
# El Arish
29:
@ -83,7 +83,7 @@ squadrons:
secondary: any
aircraft:
- MiG-15bis Fagot
size: 8
size: 16
- primary: Air Assault
secondary: any
aircraft:
@ -91,50 +91,31 @@ squadrons:
size: 4
# Al Mansurah
14:
- primary: Escort
secondary:
- BAI
- BARCAP
- Escort
- Fighter sweep
- Intercept
- TARCAP
- primary: BARCAP
secondary: any
aircraft:
- MiG-21bis Fishbed-N
size: 20
size: 16
- primary: BAI
secondary: any
aircraft:
- MiG-19P Farmer-B
size: 20
size: 16
# Cairo West
18:
- primary: Strike
secondary: any
aircraft:
- Tu-16 Badger
size: 14
- primary: Escort
secondary: air-to-air
aircraft:
- MiG-21bis Fishbed-N
size: 16
# FARP
Port Tewfik Staging Area:
- primary: Transport
secondary: any
aircraft:
- Mi-8MTV2 Hip
size: 4
# Cairo West
18:
- primary: Strike
secondary:
- DEAD
- OCA/Runway
aircraft:
- Tu-16 Badger
size: 15
- primary: BARCAP
secondary:
- BAI
- BARCAP
- Escort
- Fighter sweep
- Intercept
- TARCAP
aircraft:
- MiG-21bis Fishbed-N
size: 20
# FARP
Port Tewfik Staging Area:
- primary: Air Assault
secondary: any
aircraft:
- Mi-8MTV2 Hip

View File

@ -36,6 +36,11 @@ squadrons:
aircraft:
- S-3B Tanker
size: 4
- primary: Air Assault
secondary: any
aircraft:
- UH-60A
size: 4
# Akrotiri
44:
- primary: Strike
@ -85,11 +90,6 @@ squadrons:
aircraft:
- OH-58D(R) Kiowa Warrior
size: 4
- primary: Air Assault
secondary: any
aircraft:
- UH-60A
size: 4
# Damascus
7:
- primary: Strike

View File

@ -0,0 +1,36 @@
local unitPayloads = {
["name"] = "EA_6B",
["payloads"] = {
[1] = {
["displayName"] = "Liberation SEAD",
["name"] = "Liberation SEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
["num"] = 1,
},
[2] = {
["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}",
["num"] = 2,
},
[3] = {
["CLSID"] = "{EA6B_ANALQ992}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}",
["num"] = 4,
},
[5] = {
["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}",
["num"] = 5,
},
},
["tasks"] = {
[1] = 11,
},
},
},
["unitType"] = "EA_6B",
}
return unitPayloads

View File

@ -13,6 +13,7 @@
"CH-53E",
"A-4E Skyhawk",
"A-7E Corsair II",
"EA-6B Prowler",
"F-14A Tomcat (AI)",
"F-14A Tomcat (Block 135-GR Late)",
"F-4B Phantom II",

View File

@ -16,6 +16,7 @@
"C-130J-30 Super Hercules",
"CH-47D",
"CH-53E",
"EA-6B Prowler",
"F-117A Nighthawk",
"F-14A Tomcat (AI)",
"F-14A Tomcat (Block 135-GR Late)",

View File

@ -26,21 +26,22 @@
"F-15E Strike Eagle (AI)",
"F-15E Strike Eagle (Suite 4+)",
"F-16CM Fighting Falcon (Block 50)",
"F-16D Fighting Falcon (Block 52+)",
"F-16D Fighting Falcon (Block 52)",
"F-16D Fighting Falcon (Block 50+)",
"F-16D Fighting Falcon (Block 50)",
"F-16D Fighting Falcon (Block 52+)",
"F-16D Fighting Falcon (Block 52)",
"F-16D Fighting Falcon (Block 50+)",
"F-16D Fighting Falcon (Block 50)",
"F-22A Raptor",
"F/A-18C Hornet (Lot 20)",
"F/A-18E Super Hornet",
"F/A-18F Super Hornet",
"EA-18G Growler",
"F/A-18E Super Hornet",
"F/A-18F Super Hornet",
"EA-6B Prowler",
"EA-18G Growler",
"OH-58D(R) Kiowa Warrior",
"S-3B Viking",
"SH-60B Seahawk",
"UH-1H Iroquois",
"UH-60A",
"UH-60L"
"UH-60A",
"UH-60L"
],
"awacs": [
"E-2C Hawkeye",

View File

@ -10,6 +10,7 @@
"AH-1W SuperCobra",
"A-4E Skyhawk",
"A-6A Intruder",
"EA-6B Prowler",
"A-7E Corsair II",
"F-14A Tomcat (AI)",
"F-14A Tomcat (Block 135-GR Late)",

View File

@ -8,6 +8,7 @@
],
"aircrafts": [
"F-14B Tomcat",
"EA-6B Prowler",
"F/A-18C Hornet (Lot 20)",
"F/A-18E Super Hornet",
"F/A-18F Super Hornet",

View File

@ -11,7 +11,8 @@
"F/A-18C Hornet (Lot 20)",
"F/A-18E Super Hornet",
"F/A-18F Super Hornet",
"EA-18G Growler",
"EA-18G Growler",
"EA-6B Prowler",
"AV-8B Harrier II Night Attack",
"AH-1W SuperCobra",
"S-3B Viking",

View File

@ -3,8 +3,7 @@ name: Australian Army
country: Australia
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- AUS Army Fictional
livery: AUS Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: German Army
country: Germany
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- DE Army Fictional
livery: DE Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Spanish Army
country: Spain
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- ES Army Fictional
livery: ES Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: French Army
country: France
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- FR Army Fictional
livery: FR Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Greek Army
country: Greece
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- GR Army Fictional
livery: GR Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Israeli Army
country: Israel
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- ISR Army Fictional
livery: ISR Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Japanese Army
country: Japan
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- JPN Army Fictional
livery: JPN Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Dutch Army
country: The Netherlands
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- NL Army Fictional
livery: NL Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Polish Army
country: Poland
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- PL Army Fictional
livery: PL Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Russian Army
country: Russia
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- RU Army Fictional
livery: RU Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Tunisian Army
country: Tunisia
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- TUN Army
livery: TUN Army
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: Taiwanese Army
country: Combined Joint Task Forces Blue
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- TWN Army Fictional
livery: TWN Army Fictional
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: British Army Air Corps Desert
country: UK
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- UK Army Fictional Desert
livery: UK Army Fictional Desert
mission_types:
- BAI
- CAS

View File

@ -3,8 +3,7 @@ name: British Army Air Corps
country: UK
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- UK Army Fictional
livery: UK Army Fictional
mission_types:
- BAI
- CAS

View File

@ -5,8 +5,7 @@ female_pilot_percentage: 10
country: USA
role: Light Attack and Scout Helicopter
aircraft: OH-58D(R) Kiowa Warrior
livery:
- US 3-17 B 937 Iraq
livery: US 3-17 B 937 Iraq
mission_types:
- BAI
- CAS

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,17 @@
carrier_capable: true
description:
"The Northrop Grumman EA-6B Prowler is a twin-engine, four-seat, mid-wing electronic-warfare \
\ aircraft derived from the A-6 Intruder airframe. The EA-6A was the initial electronic warfare \
\ version of the A-6 used by the United States Marine Corps and United States Navy. \
\ It was capable of carrying and firing anti-radiation missiles (ARMs), such as the AGM-88 HARM."
introduced: 1971
manufacturer: Northrop Grumman
origin: USA
price: 11
role: Carrier-based Electronic-warfare Aircraft
gunfighter: false
variants:
EA-6B Prowler: {}
tasks:
SEAD: 460
SEAD Escort: 460