Compare commits

..

7 Commits

Author SHA1 Message Date
Dan Albert
2bdf9d3423 Black the pydcs extensions directory. 2021-04-11 13:55:29 -07:00
Dan Albert
0cd359f36b Black the resoureces directory. 2021-04-11 13:54:55 -07:00
Dan Albert
39bd6e3c10 Avoid warning in GitHub workflow.
(cherry picked from commit 4ec8994c38)
2021-04-11 13:37:16 -07:00
Dan Albert
ed89c49fd4 Add black workflow.
(cherry picked from commit 16b0dcad71)
2021-04-11 13:31:10 -07:00
Dan Albert
4000b42df2 Add pre-commit configuration for black.
To set up, run `pre-commit install`.

(cherry picked from commit 9c1265d50d)
2021-04-11 13:31:09 -07:00
Dan Albert
f73a68aeca Note the font crash fix in the changelog.
(cherry picked from commit cce736bc16)
2021-04-11 13:29:30 -07:00
Hanninho
7f8dae003f Force the basic layout engine when generating the kneeboard.
The libraqm backed layout engine causes crashes on some machines.

Fixes #531.

(cherry picked from commit 2a1127e637)
2021-04-11 13:25:32 -07:00
223 changed files with 5692 additions and 5368 deletions

View File

@@ -1,2 +0,0 @@
# Black
a47bef1f1336fd264d0b175f4421758339a30acb

View File

@@ -28,8 +28,7 @@ We will usually need more information for debugging. Include as much of the foll
- DCS Liberation save file (the `.liberation` file you save from the DCS Liberation window). By default these are located in your DCS saved games directory (`%USERPROFILE%/Saved Games/DCS`).
- The generated mission file (the `.miz` file that you load in DCS to play the turn). By default these are located in your missions directory (`%USERPROFILE%/Saved Games/DCS/Missions`).
- A tacview track file, especially when demonstrating an issue with AI behavior. By default these are located in your Tacview tracks directory (`%USERPROFILE%/Documents/Tacview`).
- The state.json file from the finished mission when the problem is related to results processing. By default these are located in your Liberation install directory.
- A tacview track file, especially when demonstrating an issue with AI behavior. By default these are locaed in your Tacview tracks directory (`%USERPROFILE%/Documents/Tacview`).
**Version information (please complete the following information):**
- DCS Liberation [e.g. 2.3.1]:

1
.gitignore vendored
View File

@@ -11,7 +11,6 @@ a.py
resources/tools/a.miz
# User-specific stuff
.idea/
.env
/kneeboards
/liberation_preferences.json

View File

@@ -1,51 +1,9 @@
# 2.5.1
## Features/Improvements
* **[UI]** Engagement ranges are now displayed by default.
* **[UI]** Engagement range display generalized to work for all patrolling flight plans (BARCAP, TARCAP, and CAS).
* **[Flight Planner]** Front lines no longer project threat zones to avoid pushing BARCAPs back so much. TARCAPs will be forcibly planned but strike packages will not route around front lines even if it is reasonable to do so.
# 2.4.4
## Fixes
* **[Campaigns]** EWRs associated with a base will now only be generated near the base.
* **[Flight Planner]** Fixed error when generating AEW&C flight plans in campaigns with no front lines.
# 2.5.0
Saves from 2.4 are not compatible with 2.5.
## Features/Improvements
* **[Engine]** DCS 2.7 Support
* **[UI]** Improved FOB menu, added a custom banner, and do not display aircraft recruitment menu
* **[Flight Planner]** Added AEW&C missions. (by siKruger)
* **[Kneeboard]** Added dark kneeboard option (by GvonH)
* **[Campaigns]** Multiple EWR sites may now be generated, and EWR sites may be generated outside bases (by SnappyComebacks)
* **[Mission Generation]** Cloudy and rainy (but not thunderstorm) weather will use the cloud presets from DCS 2.7.
* **[Plugins]** Added LotATC export plugin (by drsoran)
* **[Plugins]** Added Splash Damage Plugin (by Wheelijoe)
* **[Loadouts]** Replaced Litening with ATFLIR for all default F/A-18C loadouts.
## Fixes
* **[Flight Planner]** Front lines now project threat zones, so TARCAP/escorts will not be pruned for flights near the front. Packages may also route around the front line when practical.
* **[Flight Planner]** Fixed error when planning BAI at SAMs with dead subgroups.
* **[Flight Planner]** Mig-19 was not allowed for CAS roles fixed
* **[Flight Planner]** Increased size of navigation planning area to avoid plannign failures with distant waypoints.
* **[Flight Planner]** Fixed UI refresh when unchecking the "default loadout" box in the loadout editor.
* **[Objective names]** Fixed typos in objective name : ARMADILLLO -> ARMADILLO (by SnappyComebacks)
* **[Payloads]** F-86 Sabre was missing a custom payload
* **[Payloads]** Added GAR-8 period restrictions (by Mustang-25)
* **[Campaign]** Date now progresses.
* **[Campaign]** Added game over message when a coalition runs out of functioning airbases.
* **[Mission Generation]** Fixed "invalid face handle" error in kneeboard generation that occurred on some machines.
## Regressions
* **[Mod Support]** Stopped support for 2.5.5 Rafale Mode, and removed factions that were using it
* **[Mod Support]** Su-57 mod support might be out of date
# 2.4.3
## Features/Improvements
@@ -56,6 +14,7 @@ Saves from 2.4 are not compatible with 2.5.
* **[Mods]** Updated C-130J mod data to version 6.4
* **[Mods]** Updated F-22A mod to latest version
* **[Payload]** Mirage-2000C : Added Eclair counter measures pod to all default loadouts
# 2.4.2

View File

@@ -2,21 +2,20 @@ from dcs.vehicles import AirDefence
AAA_UNITS = [
AirDefence.SPAAA_Gepard,
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish,
AirDefence.SPAAA_Vulcan_M163,
AirDefence.AAA_ZU_23_Closed_Emplacement,
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.AAA_Vulcan_M163,
AirDefence.AAA_ZU_23_Closed,
AirDefence.AAA_ZU_23_Emplacement,
AirDefence.SPAAA_ZU_23_2_Mounted_Ural_375,
AirDefence.AAA_ZU_23_Closed_Emplacement_Insurgent,
AirDefence.SPAAA_ZU_23_2_Insurgent_Mounted_Ural_375,
AirDefence.AAA_ZU_23_on_Ural_375,
AirDefence.AAA_ZU_23_Insurgent_Closed,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375,
AirDefence.AAA_ZU_23_Insurgent,
AirDefence.AAA_8_8cm_Flak_18,
AirDefence.AAA_Flak_38_20mm,
AirDefence.AAA_Flak_38,
AirDefence.AAA_8_8cm_Flak_36,
AirDefence.AAA_8_8cm_Flak_37,
AirDefence.AAA_Flak_Vierling_38_Quad_20mm,
AirDefence.AAA_SP_Kdo_G_40,
AirDefence.AAA_Flak_Vierling_38,
AirDefence.AAA_Kdo_G_40,
AirDefence.AAA_8_8cm_Flak_41,
AirDefence.AAA_40mm_Bofors,
AirDefence.AAA_S_60_57mm,
AirDefence.AAA_Bofors_40mm,
]

View File

@@ -1,6 +1,6 @@
from dcs.ships import (
Battlecruiser_1144_2_Pyotr_Velikiy,
Cruiser_1164_Moskva,
CGN_1144_2_Pyotr_Velikiy,
CG_1164_Moskva,
CVN_70_Carl_Vinson,
CVN_71_Theodore_Roosevelt,
CVN_72_Abraham_Lincoln,
@@ -8,63 +8,63 @@ from dcs.ships import (
CVN_74_John_C__Stennis,
CV_1143_5_Admiral_Kuznetsov,
CV_1143_5_Admiral_Kuznetsov_2017,
Frigate_11540_Neustrashimy,
Corvette_1124_4_Grisha,
Frigate_1135M_Rezky,
Corvette_1241_1_Molniya,
FFG_11540_Neustrashimy,
FFL_1124_4_Grisha,
FF_1135M_Rezky,
FSG_1241_1MP_Molniya,
LHA_1_Tarawa,
FFG_Oliver_Hazzard_Perry,
CG_Ticonderoga,
Oliver_Hazzard_Perry_class,
Ticonderoga_class,
Type_052B_Destroyer,
Type_052C_Destroyer,
Type_054A_Frigate,
DDG_Arleigh_Burke_IIa,
USS_Arleigh_Burke_IIa,
)
from dcs.vehicles import AirDefence
UNITS_WITH_RADAR = [
# Radars
AirDefence.SAM_SA_15_Tor_Gauntlet,
AirDefence.SAM_SA_11_Buk_Gadfly_C2,
AirDefence.SAM_Patriot_CR__AMG_AN_MRC_137,
AirDefence.SAM_Patriot_ECS,
AirDefence.SAM_SA_15_Tor_9A331,
AirDefence.SAM_SA_11_Buk_CC_9S470M1,
AirDefence.SAM_Patriot_AMG_AN_MRC_137,
AirDefence.SAM_Patriot_ECS_AN_MSQ_104,
AirDefence.SPAAA_Gepard,
AirDefence.SPAAA_Vulcan_M163,
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish,
AirDefence.AAA_Vulcan_M163,
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.EWR_1L13,
AirDefence.SAM_SA_6_Kub_Long_Track_STR,
AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR,
AirDefence.SAM_SA_10_S_300_Grumble_Clam_Shell_SR,
AirDefence.SAM_SA_6_Kub_STR_9S91,
AirDefence.SAM_SA_10_S_300PS_TR_30N6,
AirDefence.SAM_SA_10_S_300PS_SR_5N66M,
AirDefence.EWR_55G6,
AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR,
AirDefence.SAM_SA_11_Buk_Gadfly_Snow_Drift_SR,
AirDefence.MCC_SR_Sborka_Dog_Ear_SR,
AirDefence.SAM_Hawk_TR__AN_MPQ_46,
AirDefence.SAM_Hawk_SR__AN_MPQ_50,
AirDefence.SAM_Patriot_STR,
AirDefence.SAM_SA_10_S_300PS_SR_64H6E,
AirDefence.SAM_SA_11_Buk_SR_9S18M1,
AirDefence.CP_9S80M1_Sborka,
AirDefence.SAM_Hawk_TR_AN_MPQ_46,
AirDefence.SAM_Hawk_SR_AN_MPQ_50,
AirDefence.SAM_Patriot_STR_AN_MPQ_53,
AirDefence.SAM_Hawk_CWAR_AN_MPQ_55,
AirDefence.SAM_P19_Flat_Face_SR__SA_2_3,
AirDefence.SAM_SR_P_19,
AirDefence.SAM_Roland_EWR,
AirDefence.SAM_SA_3_S_125_Low_Blow_TR,
AirDefence.SAM_SA_2_S_75_Fan_Song_TR,
AirDefence.SAM_SA_3_S_125_TR_SNR,
AirDefence.SAM_SA_2_TR_SNR_75_Fan_Song,
AirDefence.HQ_7_Self_Propelled_STR,
# Ships
CVN_70_Carl_Vinson,
FFG_Oliver_Hazzard_Perry,
CG_Ticonderoga,
Corvette_1124_4_Grisha,
Oliver_Hazzard_Perry_class,
Ticonderoga_class,
FFL_1124_4_Grisha,
CV_1143_5_Admiral_Kuznetsov,
Corvette_1241_1_Molniya,
Cruiser_1164_Moskva,
Frigate_11540_Neustrashimy,
Battlecruiser_1144_2_Pyotr_Velikiy,
Frigate_1135M_Rezky,
FSG_1241_1MP_Molniya,
CG_1164_Moskva,
FFG_11540_Neustrashimy,
CGN_1144_2_Pyotr_Velikiy,
FF_1135M_Rezky,
CV_1143_5_Admiral_Kuznetsov_2017,
CVN_74_John_C__Stennis,
CVN_71_Theodore_Roosevelt,
CVN_72_Abraham_Lincoln,
CVN_73_George_Washington,
DDG_Arleigh_Burke_IIa,
USS_Arleigh_Burke_IIa,
LHA_1_Tarawa,
Type_052B_Destroyer,
Type_054A_Frigate,

File diff suppressed because it is too large Load Diff

View File

@@ -51,6 +51,7 @@ from dcs.planes import (
F_117A,
F_14A_135_GR,
F_14B,
F_111F,
F_15C,
F_15E,
F_16A,
@@ -115,8 +116,8 @@ from dcs.planes import (
I_16,
)
from dcs.ships import (
Boat_Armed_Hi_speed,
Bulker_Yakushev,
Armed_speedboat,
Bulk_cargo_ship_Yakushev,
CVN_71_Theodore_Roosevelt,
CVN_72_Abraham_Lincoln,
CVN_73_George_Washington,
@@ -124,7 +125,7 @@ from dcs.ships import (
CVN_75_Harry_S__Truman,
CV_1143_5_Admiral_Kuznetsov,
CV_1143_5_Admiral_Kuznetsov_2017,
Cargo_Ivanov,
Dry_cargo_ship_Ivanov,
LHA_1_Tarawa,
Tanker_Elnya_160,
ship_map,
@@ -173,6 +174,7 @@ from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.f22a.f22a import F_22A
from pydcs_extensions.hercules.hercules import Hercules
from pydcs_extensions.mb339.mb339 import MB_339PAN
from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M, Rafale_B
from pydcs_extensions.su57.su57 import Su_57
UNITINFOTEXT_PATH = Path("./resources/units/unit_info_text.json")
@@ -180,6 +182,9 @@ UNITINFOTEXT_PATH = Path("./resources/units/unit_info_text.json")
plane_map["A-4E-C"] = A_4E_C
plane_map["F-22A"] = F_22A
plane_map["MB-339PAN"] = MB_339PAN
plane_map["Rafale_M"] = Rafale_M
plane_map["Rafale_A_S"] = Rafale_A_S
plane_map["Rafale_B"] = Rafale_B
plane_map["Su-57"] = Su_57
plane_map["Hercules"] = Hercules
@@ -355,7 +360,7 @@ x_map = {
}
from this example `Identifier` should be used (which may or may not include category of the unit and dot + underscore characters).
For example, player accessible Hornet is called `FA_18C_hornet`, and MANPAD Igla is called `AirDefence.MANPADS_SA_18_Igla_S_Grouse`
For example, player accessible Hornet is called `FA_18C_hornet`, and MANPAD Igla is called `AirDefence.SAM_SA_18_Igla_S_MANPADS`
"""
# This should probably be much higher, but the AI doesn't rollover their budget
@@ -448,6 +453,7 @@ PRICES = {
Tu_160: 50,
Tu_22M3: 40,
Tu_95MS: 35,
F_111F: 21,
# special
IL_76MD: 30,
An_26B: 25,
@@ -475,11 +481,15 @@ PRICES = {
MQ_9_Reaper: 12,
RQ_1A_Predator: 6,
WingLoong_I: 6,
# Modded
Rafale_M: 26,
Rafale_A_S: 26,
Rafale_B: 26,
# armor
Armor.APC_MTLB: 4,
Artillery.Grad_MRL_FDDM__FC: 4,
Armor.IFV_BRDM_2: 6,
Armor.APC_BTR_RD: 6,
Armor.FDDM_Grad: 4,
Armor.ARV_BRDM_2: 6,
Armor.ARV_BTR_RD: 6,
Armor.APC_BTR_80: 8,
Armor.APC_BTR_82A: 10,
Armor.MBT_T_55: 18,
@@ -493,149 +503,147 @@ PRICES = {
Armor.IFV_BMP_3: 18,
Armor.ZBD_04A: 12,
Armor.ZTZ_96B: 30,
Armor.APC_Cobra__Scout: 4,
Armor.APC_Cobra: 4,
Armor.APC_M113: 6,
Armor.APC_HMMWV__Scout: 2,
Armor.ATGM_HMMWV: 8,
Armor.APC_M1043_HMMWV_Armament: 2,
Armor.ATGM_M1045_HMMWV_TOW: 8,
Armor.IFV_M2A2_Bradley: 12,
Armor.IFV_M1126_Stryker_ICV: 10,
Armor.SPG_Stryker_MGS: 14,
Armor.ATGM_Stryker: 12,
Armor.APC_M1126_Stryker_ICV: 10,
Armor.SPG_M1128_Stryker_MGS: 14,
Armor.ATGM_M1134_Stryker: 12,
Armor.MBT_M60A3_Patton: 16,
Armor.MBT_M1A2_Abrams: 25,
Armor.MBT_Leclerc: 25,
Armor.MBT_Leopard_1A3: 20,
Armor.MBT_Leopard_2: 25,
Armor.MBT_Merkava_IV: 25,
Armor.APC_TPz_Fuchs: 5,
Armor.MBT_Merkava_Mk__4: 25,
Armor.TPz_Fuchs: 5,
Armor.MBT_Challenger_II: 25,
Armor.IFV_Marder: 10,
Armor.IFV_Warrior: 10,
Armor.IFV_MCV_80: 10,
Armor.IFV_LAV_25: 7,
Artillery.MLRS_M270_227mm: 55,
Artillery.SPH_M109_Paladin_155mm: 25,
Artillery.SPH_2S9_Nona_120mm_M: 12,
Artillery.SPH_2S1_Gvozdika_122mm: 18,
Artillery.SPH_2S3_Akatsia_152mm: 24,
Artillery.SPH_2S19_Msta_152mm: 30,
Artillery.MLRS_BM_21_Grad_122mm: 15,
Artillery.MLRS_BM_27_Uragan_220mm: 50,
Artillery.MLRS_9A52_Smerch_HE_300mm: 40,
Artillery.Mortar_2B11_120mm: 4,
Artillery.SPH_Dana_vz77_152mm: 26,
Artillery.PLZ_05: 25,
Unarmed.LUV_UAZ_469_Jeep: 3,
Unarmed.Truck_Ural_375: 3,
Artillery.MLRS_M270: 55,
Artillery.SPH_M109_Paladin: 25,
Artillery.SPH_2S9_Nona: 12,
Artillery.SPH_2S1_Gvozdika: 18,
Artillery.SPH_2S3_Akatsia: 24,
Artillery.SPH_2S19_Msta: 30,
Artillery.MLRS_BM_21_Grad: 15,
Artillery.MLRS_9K57_Uragan_BM_27: 50,
Artillery.MLRS_9A52_Smerch: 40,
Artillery._2B11_mortar: 4,
Artillery.SpGH_Dana: 26,
Unarmed.Transport_UAZ_469: 3,
Unarmed.Transport_Ural_375: 3,
Infantry.Infantry_M4: 1,
Infantry.Infantry_AK_74: 1,
Unarmed.Truck_M818_6x6: 3,
Infantry.Soldier_AK: 1,
Unarmed.Transport_M818: 3,
# WW2
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G: 24,
Armor.MT_PzIV_H: 16,
Armor.MT_Pz_Kpfw_IV_Ausf_H: 16,
Armor.HT_Pz_Kpfw_VI_Tiger_I: 24,
Armor.HT_Pz_Kpfw_VI_Ausf__B_Tiger_II: 26,
Armor.SPG_Jagdpanther_G1: 18,
Armor.SPG_Jagdpanzer_IV: 11,
Armor.SPG_Sd_Kfz_184_Elefant: 18,
Armor.APC_Sd_Kfz_251_Halftrack: 4,
Armor.IFV_Sd_Kfz_234_2_Puma: 8,
Armor.TD_Jagdpanther_G1: 18,
Armor.TD_Jagdpanzer_IV: 11,
Armor.Sd_Kfz_184_Elefant: 18,
Armor.APC_Sd_Kfz_251: 4,
Armor.AC_Sd_Kfz_234_2_Puma: 8,
Armor.MT_M4_Sherman: 12,
Armor.MT_M4A4_Sherman_Firefly: 16,
Armor.CT_Cromwell_IV: 12,
Unarmed.Carrier_M30_Cargo: 2,
Armor.APC_M2A1_Halftrack: 4,
Armor.M30_Cargo_Carrier: 2,
Armor.APC_M2A1: 4,
Armor.CT_Centaur_IV: 10,
Armor.HIT_Churchill_VII: 16,
Armor.Car_M8_Greyhound_Armored: 8,
Armor.SPG_M10_GMC: 14,
Armor.SPG_StuG_III_Ausf__G: 12,
Armor.SPG_StuG_IV: 14,
Artillery.SPG_M12_GMC_155mm: 10,
Artillery.SPG_Sturmpanzer_IV_Brummbar: 10,
Armor.Car_Daimler_Armored: 8,
Armor.LAC_M8_Greyhound: 8,
Armor.TD_M10_GMC: 14,
Armor.StuG_III_Ausf__G: 12,
Armor.StuG_IV: 14,
Artillery.M12_GMC: 10,
Artillery.Sturmpanzer_IV_Brummbär: 10,
Armor.Daimler_Armoured_Car: 8,
Armor.LT_Mk_VII_Tetrarch: 8,
Unarmed.Tractor_M4_Hi_Speed: 2,
Armor.M4_Tractor: 2,
# ship
CV_1143_5_Admiral_Kuznetsov: 100,
CVN_74_John_C__Stennis: 100,
LHA_1_Tarawa: 50,
Bulker_Yakushev: 10,
Boat_Armed_Hi_speed: 10,
Cargo_Ivanov: 10,
Bulk_cargo_ship_Yakushev: 10,
Armed_speedboat: 10,
Dry_cargo_ship_Ivanov: 10,
Tanker_Elnya_160: 10,
# Air Defence units
AirDefence.SAM_SA_19_Tunguska_Grison: 30,
AirDefence.SAM_SA_6_Kub_Gainful_TEL: 20,
AirDefence.SAM_SA_3_S_125_Goa_LN: 6,
AirDefence.SAM_SA_11_Buk_Gadfly_Fire_Dome_TEL: 30,
AirDefence.SAM_SA_11_Buk_Gadfly_C2: 25,
AirDefence.SAM_SA_11_Buk_Gadfly_Snow_Drift_SR: 28,
AirDefence.SAM_SA_8_Osa_Gecko_TEL: 28,
AirDefence.SAM_SA_15_Tor_Gauntlet: 40,
AirDefence.SAM_SA_13_Strela_10M3_Gopher_TEL: 16,
AirDefence.SAM_SA_9_Strela_1_Gaskin_TEL: 12,
AirDefence.SAM_SA_19_Tunguska_2S6: 30,
AirDefence.SAM_SA_6_Kub_LN_2P25: 20,
AirDefence.SAM_SA_3_S_125_LN_5P73: 6,
AirDefence.SAM_SA_11_Buk_LN_9A310M1: 30,
AirDefence.SAM_SA_11_Buk_CC_9S470M1: 25,
AirDefence.SAM_SA_11_Buk_SR_9S18M1: 28,
AirDefence.SAM_SA_8_Osa_9A33: 28,
AirDefence.SAM_SA_15_Tor_9A331: 40,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3: 16,
AirDefence.SAM_SA_9_Strela_1_9P31: 12,
AirDefence.SAM_SA_8_Osa_LD_9T217: 22,
AirDefence.SAM_Patriot_CR__AMG_AN_MRC_137: 35,
AirDefence.SAM_Patriot_ECS: 30,
AirDefence.SAM_Patriot_AMG_AN_MRC_137: 35,
AirDefence.SAM_Patriot_ECS_AN_MSQ_104: 30,
AirDefence.SPAAA_Gepard: 24,
AirDefence.SAM_Hawk_Generator__PCP: 14,
AirDefence.SPAAA_Vulcan_M163: 10,
AirDefence.SAM_Hawk_PCP: 14,
AirDefence.AAA_Vulcan_M163: 10,
AirDefence.SAM_Hawk_LN_M192: 8,
AirDefence.SAM_Chaparral_M48: 16,
AirDefence.SAM_Linebacker___Bradley_M6: 18,
AirDefence.SAM_Patriot_LN: 15,
AirDefence.SAM_Avenger__Stinger: 20,
AirDefence.SAM_Linebacker_M6: 18,
AirDefence.SAM_Patriot_LN_M901: 15,
AirDefence.SAM_Avenger_M1097: 20,
AirDefence.SAM_Patriot_EPP_III: 15,
AirDefence.SAM_Patriot_C2_ICC: 18,
AirDefence.SAM_Patriot_ICC: 18,
AirDefence.SAM_Roland_ADS: 12,
AirDefence.MANPADS_Stinger: 6,
AirDefence.MANPADS_Stinger_C2_Desert: 4,
AirDefence.MANPADS_Stinger_C2: 4,
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish: 10,
AirDefence.SPAAA_ZSU_57_2: 12,
AirDefence.AAA_ZU_23_Closed_Emplacement: 6,
AirDefence.Stinger_MANPADS: 6,
AirDefence.SAM_Stinger_comm_dsr: 4,
AirDefence.SAM_Stinger_comm: 4,
AirDefence.SPAAA_ZSU_23_4_Shilka: 10,
AirDefence.AAA_ZSU_57_2: 12,
AirDefence.AAA_ZU_23_Closed: 6,
AirDefence.AAA_ZU_23_Emplacement: 6,
AirDefence.SPAAA_ZU_23_2_Mounted_Ural_375: 7,
AirDefence.AAA_ZU_23_Closed_Emplacement_Insurgent: 6,
AirDefence.SPAAA_ZU_23_2_Insurgent_Mounted_Ural_375: 7,
AirDefence.AAA_ZU_23_on_Ural_375: 7,
AirDefence.AAA_ZU_23_Insurgent_Closed: 6,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375: 7,
AirDefence.AAA_ZU_23_Insurgent: 6,
AirDefence.MANPADS_SA_18_Igla_Grouse: 10,
AirDefence.MANPADS_SA_18_Igla_Grouse_C2: 8,
AirDefence.MANPADS_SA_18_Igla_S_Grouse: 12,
AirDefence.MANPADS_SA_18_Igla_S_Grouse_C2: 8,
AirDefence.SAM_SA_18_Igla_MANPADS: 10,
AirDefence.SAM_SA_18_Igla_comm: 8,
AirDefence.SAM_SA_18_Igla_S_MANPADS: 12,
AirDefence.SAM_SA_18_Igla_S_comm: 8,
AirDefence.EWR_1L13: 30,
AirDefence.SAM_SA_6_Kub_Long_Track_STR: 22,
AirDefence.SAM_SA_6_Kub_STR_9S91: 22,
AirDefence.EWR_55G6: 30,
AirDefence.MCC_SR_Sborka_Dog_Ear_SR: 10,
AirDefence.SAM_Hawk_TR__AN_MPQ_46: 14,
AirDefence.SAM_Hawk_SR__AN_MPQ_50: 18,
AirDefence.SAM_Patriot_STR: 22,
AirDefence.CP_9S80M1_Sborka: 10,
AirDefence.SAM_Hawk_TR_AN_MPQ_46: 14,
AirDefence.SAM_Hawk_SR_AN_MPQ_50: 18,
AirDefence.SAM_Patriot_STR_AN_MPQ_53: 22,
AirDefence.SAM_Hawk_CWAR_AN_MPQ_55: 20,
AirDefence.SAM_P19_Flat_Face_SR__SA_2_3: 14,
AirDefence.SAM_SR_P_19: 14,
AirDefence.SAM_Roland_EWR: 16,
AirDefence.SAM_SA_3_S_125_Low_Blow_TR: 14,
AirDefence.SAM_SA_2_S_75_Guideline_LN: 8,
AirDefence.SAM_SA_2_S_75_Fan_Song_TR: 12,
AirDefence.SAM_Rapier_LN: 6,
AirDefence.SAM_Rapier_Tracker: 6,
AirDefence.SAM_Rapier_Blindfire_TR: 8,
AirDefence.SAM_SA_3_S_125_TR_SNR: 14,
AirDefence.SAM_SA_2_LN_SM_90: 8,
AirDefence.SAM_SA_2_TR_SNR_75_Fan_Song: 12,
AirDefence.Rapier_FSA_Launcher: 6,
AirDefence.Rapier_FSA_Optical_Tracker: 6,
AirDefence.Rapier_FSA_Blindfire_Tracker: 8,
AirDefence.HQ_7_Self_Propelled_LN: 20,
AirDefence.HQ_7_Self_Propelled_STR: 24,
AirDefence.AAA_8_8cm_Flak_18: 6,
AirDefence.AAA_Flak_38_20mm: 6,
AirDefence.AAA_Flak_38: 6,
AirDefence.AAA_8_8cm_Flak_36: 8,
AirDefence.AAA_8_8cm_Flak_37: 9,
AirDefence.AAA_Flak_Vierling_38_Quad_20mm: 5,
AirDefence.AAA_SP_Kdo_G_40: 8,
AirDefence.SL_Flakscheinwerfer_37: 4,
AirDefence.PU_Maschinensatz_33: 10,
AirDefence.AAA_Flak_Vierling_38: 5,
AirDefence.AAA_Kdo_G_40: 8,
AirDefence.Flak_Searchlight_37: 4,
AirDefence.Maschinensatz_33: 10,
AirDefence.AAA_8_8cm_Flak_41: 10,
AirDefence.EWR_FuMG_401_Freya_LZ: 25,
AirDefence.AAA_40mm_Bofors: 8,
AirDefence.AAA_S_60_57mm: 8,
AirDefence.AAA_Bofors_40mm: 8,
AirDefence.AAA_M1_37mm: 7,
AirDefence.AAA_M45_Quadmount_HB_12_7mm: 4,
AirDefence.AAA_QF_3_7: 10,
AirDefence.AAA_M45_Quadmount: 4,
AirDefence.AA_gun_QF_3_7: 10,
# FRENCH PACK MOD
frenchpack.AMX_10RCR: 10,
frenchpack.AMX_10RCR_SEPAR: 12,
@@ -666,12 +674,12 @@ PRICES = {
frenchpack.DIM__TOYOTA_DESERT: 2,
frenchpack.DIM__KAMIKAZE: 6,
# SA-10
AirDefence.SAM_SA_10_S_300_Grumble_C2: 18,
AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR: 24,
AirDefence.SAM_SA_10_S_300_Grumble_Clam_Shell_SR: 30,
AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR: 30,
AirDefence.SAM_SA_10_S_300_Grumble_TEL_C: 22,
AirDefence.SAM_SA_10_S_300_Grumble_TEL_D: 22,
AirDefence.SAM_SA_10_S_300PS_CP_54K6: 18,
AirDefence.SAM_SA_10_S_300PS_TR_30N6: 24,
AirDefence.SAM_SA_10_S_300PS_SR_5N66M: 30,
AirDefence.SAM_SA_10_S_300PS_SR_64H6E: 30,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: 22,
AirDefence.SAM_SA_10_S_300PS_LN_5P85D: 22,
# High digit sams mod
highdigitsams.AAA_SON_9_Fire_Can: 8,
highdigitsams.AAA_100mm_KS_19: 10,
@@ -764,6 +772,7 @@ UNIT_BY_TASK = {
SpitfireLFMkIXCW,
SpitfireLFMkIX,
A_4E_C,
Rafale_M,
SA342Mistral,
],
CAS: [
@@ -777,6 +786,7 @@ UNIT_BY_TASK = {
A_10C_2,
A_20G,
B_17G,
F_111F,
B_1B,
B_52H,
F_117A,
@@ -797,6 +807,8 @@ UNIT_BY_TASK = {
P_47D_30bl1,
P_47D_40,
RQ_1A_Predator,
Rafale_A_S,
Rafale_B,
S_3B,
SA342L,
SA342M,
@@ -832,18 +844,18 @@ UNIT_BY_TASK = {
Armor.APC_MTLB,
Armor.APC_MTLB,
Armor.APC_MTLB,
Artillery.Grad_MRL_FDDM__FC,
Artillery.Grad_MRL_FDDM__FC,
Artillery.Grad_MRL_FDDM__FC,
Artillery.Grad_MRL_FDDM__FC,
Artillery.Grad_MRL_FDDM__FC,
Armor.IFV_BRDM_2,
Armor.IFV_BRDM_2,
Armor.IFV_BRDM_2,
Armor.APC_BTR_RD,
Armor.APC_BTR_RD,
Armor.APC_BTR_RD,
Armor.APC_BTR_RD,
Armor.FDDM_Grad,
Armor.FDDM_Grad,
Armor.FDDM_Grad,
Armor.FDDM_Grad,
Armor.FDDM_Grad,
Armor.ARV_BRDM_2,
Armor.ARV_BRDM_2,
Armor.ARV_BRDM_2,
Armor.ARV_BTR_RD,
Armor.ARV_BTR_RD,
Armor.ARV_BTR_RD,
Armor.ARV_BTR_RD,
Armor.APC_BTR_80,
Armor.APC_BTR_80,
Armor.APC_BTR_80,
@@ -873,33 +885,33 @@ UNIT_BY_TASK = {
Armor.MBT_T_80U,
Armor.MBT_T_90,
Armor.ZTZ_96B,
Armor.APC_Cobra__Scout,
Armor.APC_Cobra__Scout,
Armor.APC_Cobra__Scout,
Armor.APC_Cobra__Scout,
Armor.APC_Cobra,
Armor.APC_Cobra,
Armor.APC_Cobra,
Armor.APC_Cobra,
Armor.APC_M113,
Armor.APC_M113,
Armor.APC_M113,
Armor.APC_M113,
Armor.APC_TPz_Fuchs,
Armor.APC_TPz_Fuchs,
Armor.APC_TPz_Fuchs,
Armor.APC_TPz_Fuchs,
Armor.ATGM_HMMWV,
Armor.ATGM_HMMWV,
Armor.APC_HMMWV__Scout,
Armor.APC_HMMWV__Scout,
Armor.TPz_Fuchs,
Armor.TPz_Fuchs,
Armor.TPz_Fuchs,
Armor.TPz_Fuchs,
Armor.ATGM_M1045_HMMWV_TOW,
Armor.ATGM_M1045_HMMWV_TOW,
Armor.APC_M1043_HMMWV_Armament,
Armor.APC_M1043_HMMWV_Armament,
Armor.IFV_M2A2_Bradley,
Armor.IFV_M2A2_Bradley,
Armor.ATGM_Stryker,
Armor.ATGM_Stryker,
Armor.IFV_M1126_Stryker_ICV,
Armor.IFV_M1126_Stryker_ICV,
Armor.IFV_M1126_Stryker_ICV,
Armor.SPG_Stryker_MGS,
Armor.IFV_Warrior,
Armor.IFV_Warrior,
Armor.IFV_Warrior,
Armor.ATGM_M1134_Stryker,
Armor.ATGM_M1134_Stryker,
Armor.APC_M1126_Stryker_ICV,
Armor.APC_M1126_Stryker_ICV,
Armor.APC_M1126_Stryker_ICV,
Armor.SPG_M1128_Stryker_MGS,
Armor.IFV_MCV_80,
Armor.IFV_MCV_80,
Armor.IFV_MCV_80,
Armor.IFV_LAV_25,
Armor.IFV_LAV_25,
Armor.IFV_Marder,
@@ -915,94 +927,92 @@ UNIT_BY_TASK = {
Armor.MBT_Leclerc,
Armor.MBT_Leopard_2,
Armor.MBT_Challenger_II,
Armor.MBT_Merkava_IV,
Armor.MBT_Merkava_Mk__4,
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G,
Armor.MT_PzIV_H,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
Armor.HT_Pz_Kpfw_VI_Tiger_I,
Armor.HT_Pz_Kpfw_VI_Ausf__B_Tiger_II,
Armor.APC_Sd_Kfz_251_Halftrack,
Armor.APC_Sd_Kfz_251_Halftrack,
Armor.APC_Sd_Kfz_251_Halftrack,
Armor.APC_Sd_Kfz_251_Halftrack,
Armor.IFV_Sd_Kfz_234_2_Puma,
Armor.IFV_Sd_Kfz_234_2_Puma,
Armor.APC_Sd_Kfz_251,
Armor.APC_Sd_Kfz_251,
Armor.APC_Sd_Kfz_251,
Armor.APC_Sd_Kfz_251,
Armor.AC_Sd_Kfz_234_2_Puma,
Armor.AC_Sd_Kfz_234_2_Puma,
Armor.MT_M4_Sherman,
Armor.MT_M4A4_Sherman_Firefly,
Armor.CT_Cromwell_IV,
Unarmed.Carrier_M30_Cargo,
Unarmed.Carrier_M30_Cargo,
Armor.APC_M2A1_Halftrack,
Armor.APC_M2A1_Halftrack,
Armor.APC_M2A1_Halftrack,
Armor.APC_M2A1_Halftrack,
Armor.M30_Cargo_Carrier,
Armor.M30_Cargo_Carrier,
Armor.APC_M2A1,
Armor.APC_M2A1,
Armor.APC_M2A1,
Armor.APC_M2A1,
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G,
Armor.MT_PzIV_H,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
Armor.HT_Pz_Kpfw_VI_Tiger_I,
Armor.HT_Pz_Kpfw_VI_Ausf__B_Tiger_II,
Armor.SPG_Jagdpanther_G1,
Armor.SPG_Jagdpanzer_IV,
Armor.SPG_Sd_Kfz_184_Elefant,
Armor.APC_Sd_Kfz_251_Halftrack,
Armor.IFV_Sd_Kfz_234_2_Puma,
Armor.TD_Jagdpanther_G1,
Armor.TD_Jagdpanzer_IV,
Armor.Sd_Kfz_184_Elefant,
Armor.APC_Sd_Kfz_251,
Armor.AC_Sd_Kfz_234_2_Puma,
Armor.MT_M4_Sherman,
Armor.MT_M4A4_Sherman_Firefly,
Armor.CT_Cromwell_IV,
Unarmed.Carrier_M30_Cargo,
Unarmed.Carrier_M30_Cargo,
Unarmed.Carrier_M30_Cargo,
Armor.APC_M2A1_Halftrack,
Armor.APC_M2A1_Halftrack,
Armor.M30_Cargo_Carrier,
Armor.M30_Cargo_Carrier,
Armor.M30_Cargo_Carrier,
Armor.APC_M2A1,
Armor.APC_M2A1,
Armor.CT_Centaur_IV,
Armor.CT_Centaur_IV,
Armor.HIT_Churchill_VII,
Armor.Car_M8_Greyhound_Armored,
Armor.Car_M8_Greyhound_Armored,
Armor.SPG_M10_GMC,
Armor.SPG_M10_GMC,
Armor.SPG_StuG_III_Ausf__G,
Armor.SPG_StuG_IV,
Artillery.SPG_M12_GMC_155mm,
Artillery.SPG_Sturmpanzer_IV_Brummbar,
Armor.Car_Daimler_Armored,
Armor.LAC_M8_Greyhound,
Armor.LAC_M8_Greyhound,
Armor.TD_M10_GMC,
Armor.TD_M10_GMC,
Armor.StuG_III_Ausf__G,
Armor.StuG_IV,
Artillery.M12_GMC,
Artillery.Sturmpanzer_IV_Brummbär,
Armor.Daimler_Armoured_Car,
Armor.LT_Mk_VII_Tetrarch,
Artillery.MLRS_M270_227mm,
Artillery.SPH_M109_Paladin_155mm,
Artillery.SPH_2S9_Nona_120mm_M,
Artillery.SPH_2S1_Gvozdika_122mm,
Artillery.SPH_2S3_Akatsia_152mm,
Artillery.SPH_2S19_Msta_152mm,
Artillery.MLRS_BM_21_Grad_122mm,
Artillery.MLRS_BM_21_Grad_122mm,
Artillery.MLRS_BM_27_Uragan_220mm,
Artillery.MLRS_9A52_Smerch_HE_300mm,
Artillery.SPH_Dana_vz77_152mm,
Artillery.PLZ_05,
Artillery.SPG_M12_GMC_155mm,
Artillery.SPG_Sturmpanzer_IV_Brummbar,
AirDefence.SPAAA_ZU_23_2_Mounted_Ural_375,
AirDefence.SPAAA_ZU_23_2_Insurgent_Mounted_Ural_375,
AirDefence.SPAAA_ZSU_57_2,
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish,
AirDefence.SAM_SA_8_Osa_Gecko_TEL,
AirDefence.SAM_SA_9_Strela_1_Gaskin_TEL,
AirDefence.SAM_SA_13_Strela_10M3_Gopher_TEL,
AirDefence.SAM_SA_15_Tor_Gauntlet,
AirDefence.SAM_SA_19_Tunguska_Grison,
Artillery.MLRS_M270,
Artillery.SPH_M109_Paladin,
Artillery.SPH_2S9_Nona,
Artillery.SPH_2S1_Gvozdika,
Artillery.SPH_2S3_Akatsia,
Artillery.SPH_2S19_Msta,
Artillery.MLRS_BM_21_Grad,
Artillery.MLRS_BM_21_Grad,
Artillery.MLRS_9K57_Uragan_BM_27,
Artillery.MLRS_9A52_Smerch,
Artillery.SpGH_Dana,
Artillery.M12_GMC,
Artillery.Sturmpanzer_IV_Brummbär,
AirDefence.AAA_ZU_23_on_Ural_375,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375,
AirDefence.AAA_ZSU_57_2,
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.SAM_SA_9_Strela_1_9P31,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3,
AirDefence.SAM_SA_15_Tor_9A331,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SPAAA_Gepard,
AirDefence.SPAAA_Vulcan_M163,
AirDefence.SAM_Linebacker___Bradley_M6,
AirDefence.AAA_Vulcan_M163,
AirDefence.SAM_Linebacker_M6,
AirDefence.SAM_Chaparral_M48,
AirDefence.SAM_Avenger__Stinger,
AirDefence.SAM_Avenger_M1097,
AirDefence.SAM_Roland_ADS,
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.AAA_8_8cm_Flak_18,
AirDefence.AAA_8_8cm_Flak_36,
AirDefence.AAA_8_8cm_Flak_37,
AirDefence.AAA_8_8cm_Flak_41,
AirDefence.AAA_40mm_Bofors,
AirDefence.AAA_S_60_57mm,
AirDefence.AAA_Bofors_40mm,
AirDefence.AAA_M1_37mm,
AirDefence.AAA_QF_3_7,
AirDefence.AA_gun_QF_3_7,
frenchpack.DIM__TOYOTA_BLUE,
frenchpack.DIM__TOYOTA_DESERT,
frenchpack.DIM__TOYOTA_GREEN,
@@ -1027,13 +1037,13 @@ UNIT_BY_TASK = {
],
AirDefence: [],
Reconnaissance: [
Unarmed.Truck_M818_6x6,
Unarmed.Truck_Ural_375,
Unarmed.LUV_UAZ_469_Jeep,
Unarmed.Transport_M818,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
],
Nothing: [
Infantry.Infantry_M4,
Infantry.Infantry_AK_74,
Infantry.Soldier_AK,
],
Embarking: [],
Carriage: [
@@ -1042,10 +1052,10 @@ UNIT_BY_TASK = {
CV_1143_5_Admiral_Kuznetsov,
],
CargoTransportation: [
Cargo_Ivanov,
Bulker_Yakushev,
Dry_cargo_ship_Ivanov,
Bulk_cargo_ship_Yakushev,
Tanker_Elnya_160,
Boat_Armed_Hi_speed,
Armed_speedboat,
],
}
@@ -1053,41 +1063,41 @@ UNIT_BY_TASK = {
Units from AirDefense category of UNIT_BY_TASK that will be removed from use if "No SAM" option is checked at the start of the game
"""
SAM_BAN = [
AirDefence.SAM_Linebacker___Bradley_M6,
AirDefence.SAM_SA_9_Strela_1_Gaskin_TEL,
AirDefence.SAM_SA_8_Osa_Gecko_TEL,
AirDefence.SAM_SA_19_Tunguska_Grison,
AirDefence.SAM_SA_6_Kub_Gainful_TEL,
AirDefence.SAM_SA_8_Osa_Gecko_TEL,
AirDefence.SAM_SA_3_S_125_Goa_LN,
AirDefence.SAM_Hawk_Generator__PCP,
AirDefence.SAM_SA_2_S_75_Guideline_LN,
AirDefence.SAM_SA_11_Buk_Gadfly_Fire_Dome_TEL,
AirDefence.SAM_Linebacker_M6,
AirDefence.SAM_SA_9_Strela_1_9P31,
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_SA_2_LN_SM_90,
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
]
"""
Used to convert SAM site parts to the corresponding site
"""
SAM_CONVERT = {
AirDefence.SAM_P19_Flat_Face_SR__SA_2_3: AirDefence.SAM_SA_3_S_125_Goa_LN,
AirDefence.SAM_SA_3_S_125_Low_Blow_TR: AirDefence.SAM_SA_3_S_125_Goa_LN,
AirDefence.SAM_SA_3_S_125_Goa_LN: AirDefence.SAM_SA_3_S_125_Goa_LN,
AirDefence.SAM_SA_6_Kub_Gainful_TEL: AirDefence.SAM_SA_6_Kub_Gainful_TEL,
AirDefence.SAM_SA_6_Kub_Long_Track_STR: AirDefence.SAM_SA_6_Kub_Gainful_TEL,
AirDefence.SAM_SA_10_S_300_Grumble_TEL_C: AirDefence.SAM_SA_10_S_300_Grumble_TEL_C,
AirDefence.SAM_SA_10_S_300_Grumble_Clam_Shell_SR: AirDefence.SAM_SA_10_S_300_Grumble_TEL_C,
AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR: AirDefence.SAM_SA_10_S_300_Grumble_TEL_C,
AirDefence.SAM_SA_10_S_300_Grumble_C2: AirDefence.SAM_SA_10_S_300_Grumble_TEL_C,
AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR: AirDefence.SAM_SA_10_S_300_Grumble_C2,
AirDefence.SAM_Hawk_TR__AN_MPQ_46: AirDefence.SAM_Hawk_Generator__PCP,
AirDefence.SAM_Hawk_SR__AN_MPQ_50: AirDefence.SAM_Hawk_Generator__PCP,
AirDefence.SAM_Hawk_LN_M192: AirDefence.SAM_Hawk_Generator__PCP,
AirDefence.SAM_SR_P_19: AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_SA_3_S_125_TR_SNR: AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_SA_3_S_125_LN_5P73: AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_SA_6_Kub_LN_2P25: AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_6_Kub_STR_9S91: AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
AirDefence.SAM_SA_10_S_300PS_SR_5N66M: AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
AirDefence.SAM_SA_10_S_300PS_TR_30N6: AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
AirDefence.SAM_SA_10_S_300PS_CP_54K6: AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
AirDefence.SAM_SA_10_S_300PS_SR_64H6E: AirDefence.SAM_SA_10_S_300PS_CP_54K6,
AirDefence.SAM_Hawk_TR_AN_MPQ_46: AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Hawk_SR_AN_MPQ_50: AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Hawk_LN_M192: AirDefence.SAM_Hawk_PCP,
"except": {
# this radar is shared between the two S300's. if we attempt to find a SAM site at a base and can't find one
# model, we can safely assume the other was deployed
# well, perhaps not safely, but we'll make the assumption anyway :p
AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR: AirDefence.SAM_SA_10_S_300_Grumble_C2,
AirDefence.SAM_P19_Flat_Face_SR__SA_2_3: AirDefence.SAM_SA_2_S_75_Guideline_LN,
AirDefence.SAM_SA_10_S_300PS_TR_30N6: AirDefence.SAM_SA_10_S_300PS_CP_54K6,
AirDefence.SAM_SR_P_19: AirDefence.SAM_SA_2_LN_SM_90,
},
}
@@ -1148,7 +1158,6 @@ COMMON_OVERRIDE = {
Escort: "CAP",
RunwayAttack: "RUNWAY_ATTACK",
FighterSweep: "CAP",
AWACS: "AEW&C",
}
"""
@@ -1217,6 +1226,7 @@ PLANE_PAYLOAD_OVERRIDES: Dict[Type[PlaneType], Dict[Type[Task], str]] = {
F_14A_135_GR: COMMON_OVERRIDE,
F_14B: COMMON_OVERRIDE,
F_15C: COMMON_OVERRIDE,
F_111F: COMMON_OVERRIDE,
F_22A: COMMON_OVERRIDE,
F_16C_50: COMMON_OVERRIDE,
JF_17: COMMON_OVERRIDE,
@@ -1269,6 +1279,9 @@ PLANE_PAYLOAD_OVERRIDES: Dict[Type[PlaneType], Dict[Type[Task], str]] = {
A_20G: COMMON_OVERRIDE,
A_4E_C: COMMON_OVERRIDE,
MB_339PAN: COMMON_OVERRIDE,
Rafale_M: COMMON_OVERRIDE,
Rafale_A_S: COMMON_OVERRIDE,
Rafale_B: COMMON_OVERRIDE,
OH_58D: COMMON_OVERRIDE,
F_16A: COMMON_OVERRIDE,
MQ_9_Reaper: COMMON_OVERRIDE,
@@ -1279,7 +1292,6 @@ PLANE_PAYLOAD_OVERRIDES: Dict[Type[PlaneType], Dict[Type[Task], str]] = {
AH_64A: COMMON_OVERRIDE,
SH_60B: COMMON_OVERRIDE,
Hercules: COMMON_OVERRIDE,
F_86F_Sabre: COMMON_OVERRIDE,
Su_25TM: {
SEAD: "Kh-31P*2_Kh-25ML*4_R-73*2_L-081_MPS410",
},
@@ -1363,8 +1375,8 @@ CARRIER_CAPABLE = [
AV8BNA,
Su_33,
A_4E_C,
Rafale_M,
S_3B,
E_2C,
UH_1H,
Mi_8MT,
Ka_50,
@@ -1420,8 +1432,6 @@ def upgrade_to_supercarrier(unit, name: str):
return CVN_73_George_Washington
elif name == "CVN-75 Harry S. Truman":
return CVN_75_Harry_S__Truman
elif name == "Carrier Strike Group 8":
return CVN_75_Harry_S__Truman
else:
return CVN_71_Theodore_Roosevelt
elif unit == CV_1143_5_Admiral_Kuznetsov:
@@ -1447,9 +1457,9 @@ def find_unittype(for_task: Task, country_name: str) -> List[Type[UnitType]]:
MANPADS: List[VehicleType] = [
AirDefence.MANPADS_SA_18_Igla_Grouse,
AirDefence.MANPADS_SA_18_Igla_S_Grouse,
AirDefence.MANPADS_Stinger,
AirDefence.SAM_SA_18_Igla_MANPADS,
AirDefence.SAM_SA_18_Igla_S_MANPADS,
AirDefence.Stinger_MANPADS,
]
INFANTRY: List[VehicleType] = [
@@ -1458,28 +1468,28 @@ INFANTRY: List[VehicleType] = [
Infantry.Paratrooper_AKS,
Infantry.Paratrooper_AKS,
Infantry.Paratrooper_AKS,
Infantry.Infantry_RPG,
Infantry.Soldier_RPG,
Infantry.Infantry_M4,
Infantry.Infantry_M4,
Infantry.Infantry_M4,
Infantry.Infantry_M4,
Infantry.Infantry_M4,
Infantry.Infantry_M249,
Artillery.Mortar_2B11_120mm,
Infantry.Infantry_AK_74,
Infantry.Infantry_AK_74,
Infantry.Infantry_AK_74,
Infantry.Infantry_AK_74,
Infantry.Infantry_AK_74,
Infantry.Soldier_M249,
Artillery._2B11_mortar,
Infantry.Soldier_AK,
Infantry.Soldier_AK,
Infantry.Soldier_AK,
Infantry.Soldier_AK,
Infantry.Soldier_AK,
Infantry.Paratrooper_RPG_16,
Infantry.Infantry_M4_Georgia,
Infantry.Infantry_M4_Georgia,
Infantry.Infantry_M4_Georgia,
Infantry.Infantry_M4_Georgia,
Infantry.Infantry_AK_74_Rus,
Infantry.Infantry_AK_74_Rus,
Infantry.Infantry_AK_74_Rus,
Infantry.Infantry_AK_74_Rus,
Infantry.Georgian_soldier_with_M4,
Infantry.Georgian_soldier_with_M4,
Infantry.Georgian_soldier_with_M4,
Infantry.Georgian_soldier_with_M4,
Infantry.Infantry_Soldier_Rus,
Infantry.Infantry_Soldier_Rus,
Infantry.Infantry_Soldier_Rus,
Infantry.Infantry_Soldier_Rus,
Infantry.Infantry_SMLE_No_4_Mk_1,
Infantry.Infantry_SMLE_No_4_Mk_1,
Infantry.Infantry_SMLE_No_4_Mk_1,
@@ -1490,9 +1500,9 @@ INFANTRY: List[VehicleType] = [
Infantry.Infantry_M1_Garand,
Infantry.Infantry_M1_Garand,
Infantry.Infantry_M1_Garand,
Infantry.Insurgent_AK_74,
Infantry.Insurgent_AK_74,
Infantry.Insurgent_AK_74,
Infantry.Infantry_Soldier_Insurgents,
Infantry.Infantry_Soldier_Insurgents,
Infantry.Infantry_Soldier_Insurgents,
]
@@ -1521,7 +1531,7 @@ def unit_get_expanded_info(country_name: str, unit_type, request_type: str) -> s
default_value = None
faction_value = None
with UNITINFOTEXT_PATH.open("r", encoding="utf-8") as fdata:
data = json.load(fdata)
data = json.load(fdata, encoding="utf-8")
type_exists = data.get(original_name)
if type_exists is not None:
for faction in type_exists:

View File

@@ -70,9 +70,6 @@ class Faction:
# Possible Missile site generators for this faction
missiles: List[str] = field(default_factory=list)
# Possible costal site generators for this faction
coastal_defenses: List[str] = field(default_factory=list)
# Required mods or asset packs
requirements: Dict[str, str] = field(default_factory=dict)
@@ -103,9 +100,6 @@ class Faction:
# How many missiles group should we try to generate per CP on startup for this faction
missiles_group_count: int = field(default=1)
# How many coastal group should we try to generate per CP on startup for this faction
coastal_group_count: int = field(default=1)
# Whether this faction has JTAC access
has_jtac: bool = field(default=False)
@@ -168,7 +162,6 @@ class Faction:
faction.air_defenses.extend(json.get("shorads", []))
faction.missiles = json.get("missiles", [])
faction.coastal_defenses = json.get("coastal_defenses", [])
faction.requirements = json.get("requirements", {})
faction.carrier_names = json.get("carrier_names", [])
@@ -186,7 +179,6 @@ class Faction:
faction.jtac_unit = None
faction.navy_group_count = int(json.get("navy_group_count", 1))
faction.missiles_group_count = int(json.get("missiles_group_count", 0))
faction.coastal_group_count = int(json.get("coastal_group_count", 0))
# Load doctrine
doctrine = json.get("doctrine", "modern")

View File

@@ -31,7 +31,7 @@ class FactionLoader:
for f in files:
try:
with f.open("r", encoding="utf-8") as fdata:
data = json.load(fdata)
data = json.load(fdata, encoding="utf-8")
factions[data["name"]] = Faction.from_json(data)
logging.info("Loaded faction : " + str(f))
except Exception:

View File

@@ -96,7 +96,6 @@ class Game:
self.enemy_name = enemy_name
self.enemy_country = db.FACTIONS[enemy_name].country
self.turn = 0
# NB: This is the *start* date. It is never updated.
self.date = date(start_date.year, start_date.month, start_date.day)
self.game_stats = GameStats()
self.game_stats.update(self)
@@ -153,7 +152,7 @@ class Game:
def generate_conditions(self) -> Conditions:
return Conditions.generate(
self.theater, self.current_day, self.current_turn_time_of_day, self.settings
self.theater, self.date, self.current_turn_time_of_day, self.settings
)
def sanitize_sides(self):
@@ -284,18 +283,11 @@ class Game:
persistency.autosave(self)
def check_win_loss(self):
player_airbases = {
cp for cp in self.theater.player_points() if cp.runway_is_operational()
}
if not player_airbases:
captured_states = {i.captured for i in self.theater.controlpoints}
if True not in captured_states:
return TurnState.LOSS
enemy_airbases = {
cp for cp in self.theater.enemy_points() if cp.runway_is_operational()
}
if not enemy_airbases:
if False not in captured_states:
return TurnState.WIN
return TurnState.CONTINUE
def initialize_turn(self) -> None:

View File

@@ -21,10 +21,6 @@ from game.threatzones import ThreatZones
from game.utils import nautical_miles
class NavMeshError(RuntimeError):
pass
class NavMeshPoly:
def __init__(self, ident: int, poly: Polygon, threatened: bool) -> None:
self.ident = ident
@@ -129,7 +125,7 @@ class NavMesh:
path.append(current.world_point)
previous = came_from[current]
if previous is None:
raise NavMeshError(
raise RuntimeError(
f"Could not reconstruct path to {destination} from {origin}"
)
current = previous
@@ -144,12 +140,10 @@ class NavMesh:
def shortest_path(self, origin: Point, destination: Point) -> List[Point]:
origin_poly = self.localize(origin)
if origin_poly is None:
raise NavMeshError(f"Origin point {origin} is outside the navmesh")
raise ValueError(f"Origin point {origin} is outside the navmesh")
destination_poly = self.localize(destination)
if destination_poly is None:
raise NavMeshError(
f"Destination point {destination} is outside the navmesh"
)
raise ValueError(f"Origin point {destination} is outside the navmesh")
return self._shortest_path(
NavPoint(self.dcs_to_shapely_point(origin), origin_poly),
@@ -209,7 +203,7 @@ class NavMesh:
# threatened airbases at the map edges have room to retreat from the
# threat without running off the navmesh.
return box(*LineString(points).bounds).buffer(
nautical_miles(200).meters, resolution=1
nautical_miles(100).meters, resolution=1
)
@staticmethod

View File

@@ -166,7 +166,6 @@ class Operation:
airgen: AircraftConflictGenerator,
):
"""Generates subscribed MissionInfoGenerator objects (currently kneeboards and briefings)"""
gens: List[MissionInfoGenerator] = [
KneeboardGenerator(cls.current_mission, cls.game),
BriefingGenerator(cls.current_mission, cls.game),
@@ -178,8 +177,9 @@ class Operation:
for tanker in airsupportgen.air_support.tankers:
gen.add_tanker(tanker)
for aewc in airsupportgen.air_support.awacs:
gen.add_awacs(aewc)
if cls.player_awacs_enabled:
for awacs in airsupportgen.air_support.awacs:
gen.add_awacs(awacs)
for jtac in jtacs:
gen.add_jtac(jtac)
@@ -378,9 +378,7 @@ class Operation:
cls.game,
cls.radio_registry,
cls.unit_map,
air_support=cls.airsupportgen.air_support,
)
cls.airgen.clear_parking_slots()
cls.airgen.generate_flights(
@@ -446,8 +444,6 @@ class Operation:
"AWACs": {},
"JTACs": {},
"TargetPoints": {},
"RedAA": {},
"BlueAA": {},
} # type: ignore
for tanker in airsupportgen.air_support.tankers:
@@ -505,26 +501,6 @@ class Operation:
},
}
for cp in cls.game.theater.controlpoints:
for ground_object in cp.ground_objects:
if ground_object.might_have_aa and not ground_object.is_dead:
for g in ground_object.groups:
threat_range = ground_object.threat_range(g)
if not threat_range:
continue
faction = "BlueAA" if cp.captured else "RedAA"
luaData[faction][g.name] = {
"name": ground_object.name,
"range": threat_range.meters,
"position": {
"x": ground_object.position.x,
"y": ground_object.position.y,
},
}
# set a LUA table with data from Liberation that we want to set
# at the moment it contains Liberation's install path, and an overridable definition for the JTACAutoLase function
# later, we'll add data about the units and points having been generated, in order to facilitate the configuration of the plugin lua scripts
@@ -617,33 +593,7 @@ class Operation:
-- list the aircraft carriers generated by Liberation
-- dcsLiberation.Carriers = {}
-- list the Red AA generated by Liberation
dcsLiberation.RedAA = {
"""
for key in luaData["RedAA"]:
data = luaData["RedAA"][key]
name = data["name"]
radius = data["range"]
positionX = data["position"]["x"]
positionY = data["position"]["y"]
lua += f" {{dcsGroupName='{key}', name='{name}', range='{radius}', positionX='{positionX}', positionY='{positionY}' }}, \n"
lua += "}"
lua += """
-- list the Blue AA generated by Liberation
dcsLiberation.BlueAA = {
"""
for key in luaData["BlueAA"]:
data = luaData["BlueAA"][key]
name = data["name"]
radius = data["range"]
positionX = data["position"]["x"]
positionY = data["position"]["y"]
lua += f" {{dcsGroupName='{key}', name='{name}', range='{radius}', positionX='{positionX}', positionY='{positionY}' }}, \n"
lua += "}"
lua += """
-- later, we'll add more data to the table
"""

View File

@@ -1,15 +0,0 @@
from dcs import Point
class PointWithHeading(Point):
def __init__(self):
super(PointWithHeading, self).__init__(0, 0)
self.heading = 0
@staticmethod
def from_point(point: Point, heading: int):
p = PointWithHeading()
p.x = point.x
p.y = point.y
p.heading = heading
return p

View File

@@ -30,8 +30,6 @@ class Settings:
automate_front_line_reinforcements: bool = False
automate_aircraft_reinforcements: bool = False
restrict_weapons_by_date: bool = False
disable_legacy_aewc: bool = False
generate_dark_kneeboard: bool = False
# Performance oriented
perf_red_alert_state: bool = True

View File

@@ -4,7 +4,7 @@ import math
import typing
from typing import Dict, Type
from dcs.task import AWACS, CAP, CAS, Embarking, PinpointStrike, Task
from dcs.task import CAP, CAS, Embarking, PinpointStrike, Task
from dcs.unittype import FlyingType, UnitType, VehicleType
from dcs.vehicles import AirDefence, Armor
@@ -147,12 +147,7 @@ class Base:
for_task = db.unit_task(unit_type)
target_dict = None
if (
for_task == AWACS
or for_task == CAS
or for_task == CAP
or for_task == Embarking
):
if for_task == CAS or for_task == CAP or for_task == Embarking:
target_dict = self.aircraft
elif for_task == PinpointStrike:
target_dict = self.armor

View File

@@ -23,7 +23,7 @@ from dcs.planes import F_15C
from dcs.ships import (
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
DDG_Arleigh_Burke_IIa,
USS_Arleigh_Burke_IIa,
)
from dcs.statics import Fortification
from dcs.terrain import (
@@ -55,7 +55,6 @@ from .controlpoint import (
Fob,
)
from .landmap import Landmap, load_landmap, poly_contains
from ..point_with_heading import PointWithHeading
from ..utils import Distance, meters, nautical_miles
Numeric = Union[int, float]
@@ -93,33 +92,30 @@ class MizCampaignLoader:
LHA_UNIT_TYPE = LHA_1_Tarawa.id
FRONT_LINE_UNIT_TYPE = Armor.APC_M113.id
FOB_UNIT_TYPE = Unarmed.Truck_SKP_11_Mobile_ATC.id
FARP_HELIPAD = "SINGLE_HELIPAD"
FOB_UNIT_TYPE = Unarmed.CP_SKP_11_ATC_Mobile_Command_Post.id
EWR_UNIT_TYPE = AirDefence.EWR_55G6.id
SAM_UNIT_TYPE = AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR.id
GARRISON_UNIT_TYPE = AirDefence.SAM_SA_19_Tunguska_Grison.id
SAM_UNIT_TYPE = AirDefence.SAM_SA_10_S_300PS_SR_64H6E.id
GARRISON_UNIT_TYPE = AirDefence.SAM_SA_19_Tunguska_2S6.id
OFFSHORE_STRIKE_TARGET_UNIT_TYPE = Fortification.Oil_platform.id
SHIP_UNIT_TYPE = DDG_Arleigh_Burke_IIa.id
MISSILE_SITE_UNIT_TYPE = MissilesSS.SSM_SS_1C_Scud_B.id
COASTAL_DEFENSE_UNIT_TYPE = MissilesSS.AShM_SS_N_2_Silkworm.id
SHIP_UNIT_TYPE = USS_Arleigh_Burke_IIa.id
MISSILE_SITE_UNIT_TYPE = MissilesSS.SRBM_SS_1C_Scud_B_9K72_LN_9P117M.id
COASTAL_DEFENSE_UNIT_TYPE = MissilesSS.SS_N_2_Silkworm.id
# Multiple options for the required SAMs so campaign designers can more
# accurately see the coverage of their IADS for the expected type.
REQUIRED_LONG_RANGE_SAM_UNIT_TYPES = {
AirDefence.SAM_Patriot_LN.id,
AirDefence.SAM_SA_10_S_300_Grumble_TEL_C.id,
AirDefence.SAM_SA_10_S_300_Grumble_TEL_D.id,
AirDefence.SAM_Patriot_LN_M901.id,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C.id,
AirDefence.SAM_SA_10_S_300PS_LN_5P85D.id,
}
REQUIRED_MEDIUM_RANGE_SAM_UNIT_TYPES = {
AirDefence.SAM_Hawk_LN_M192.id,
AirDefence.SAM_SA_2_S_75_Guideline_LN.id,
AirDefence.SAM_SA_3_S_125_Goa_LN.id,
AirDefence.SAM_SA_2_LN_SM_90.id,
AirDefence.SAM_SA_3_S_125_LN_5P73.id,
}
REQUIRED_EWR_UNIT_TYPE = AirDefence.EWR_1L13.id
BASE_DEFENSE_RADIUS = nautical_miles(2)
def __init__(self, miz: Path, theater: ConflictTheater) -> None:
@@ -249,18 +245,6 @@ class MizCampaignLoader:
if group.units[0].type in self.REQUIRED_MEDIUM_RANGE_SAM_UNIT_TYPES:
yield group
@property
def required_ewrs(self) -> Iterator[VehicleGroup]:
for group in self.red.vehicle_group:
if group.units[0].type in self.REQUIRED_EWR_UNIT_TYPE:
yield group
@property
def helipads(self) -> Iterator[StaticGroup]:
for group in self.blue.static_group:
if group.units[0].type == self.FARP_HELIPAD:
yield group
@cached_property
def control_points(self) -> Dict[int, ControlPoint]:
control_points = {}
@@ -286,7 +270,7 @@ class MizCampaignLoader:
control_point.captured_invert = group.late_activation
control_points[control_point.id] = control_point
for group in self.lhas(blue):
# TODO: Name the LHA.db
# TODO: Name the LHA.
control_point = Lha("lha", group.position, next(self.control_point_id))
control_point.captured = blue
control_point.captured_invert = group.late_activation
@@ -345,81 +329,44 @@ class MizCampaignLoader:
for group in self.garrisons:
closest, distance = self.objective_info(group)
if distance < self.BASE_DEFENSE_RADIUS:
closest.preset_locations.base_garrisons.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.base_garrisons.append(group.position)
else:
logging.warning(f"Found garrison unit too far from base: {group.name}")
for group in self.sams:
closest, distance = self.objective_info(group)
if distance < self.BASE_DEFENSE_RADIUS:
closest.preset_locations.base_air_defense.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.base_air_defense.append(group.position)
else:
closest.preset_locations.strike_locations.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.strike_locations.append(group.position)
for group in self.ewrs:
closest, distance = self.objective_info(group)
if distance < self.BASE_DEFENSE_RADIUS:
closest.preset_locations.base_ewrs.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
else:
closest.preset_locations.ewrs.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.ewrs.append(group.position)
for group in self.offshore_strike_targets:
closest, distance = self.objective_info(group)
closest.preset_locations.offshore_strike_locations.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.offshore_strike_locations.append(group.position)
for group in self.ships:
closest, distance = self.objective_info(group)
closest.preset_locations.ships.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.ships.append(group.position)
for group in self.missile_sites:
closest, distance = self.objective_info(group)
closest.preset_locations.missile_sites.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.missile_sites.append(group.position)
for group in self.coastal_defenses:
closest, distance = self.objective_info(group)
closest.preset_locations.coastal_defenses.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.coastal_defenses.append(group.position)
for group in self.required_long_range_sams:
closest, distance = self.objective_info(group)
closest.preset_locations.required_long_range_sams.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.required_long_range_sams.append(group.position)
for group in self.required_medium_range_sams:
closest, distance = self.objective_info(group)
closest.preset_locations.required_medium_range_sams.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
for group in self.required_ewrs:
closest, distance = self.objective_info(group)
closest.preset_locations.required_ewrs.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
for group in self.helipads:
closest, distance = self.objective_info(group)
closest.helipads.append(
PointWithHeading.from_point(group.position, group.units[0].heading)
)
closest.preset_locations.required_medium_range_sams.append(group.position)
def populate_theater(self) -> None:
for control_point in self.control_points.values():
@@ -730,8 +677,8 @@ class PersianGulfTheater(ConflictTheater):
terrain = persiangulf.PersianGulf()
overview_image = "persiangulf.gif"
reference_points = (
ReferencePoint(persiangulf.Jiroft.position, Point(1692, 1343)),
ReferencePoint(persiangulf.Liwa_AFB.position, Point(358, 3238)),
ReferencePoint(persiangulf.Jiroft_Airport.position, Point(1692, 1343)),
ReferencePoint(persiangulf.Liwa_Airbase.position, Point(358, 3238)),
)
landmap = load_landmap("resources\\gulflandmap.p")
daytime_map = {
@@ -864,7 +811,6 @@ class FrontLine(MissionTarget):
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
yield from [
FlightType.CAS,
FlightType.AEWC,
# TODO: FlightType.TROOP_TRANSPORT
# TODO: FlightType.EVAC
]

View File

@@ -4,6 +4,7 @@ import heapq
import itertools
import logging
import random
import re
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from enum import Enum
@@ -27,7 +28,6 @@ from gen.ground_forces.combat_stance import CombatStance
from gen.runways import RunwayAssigner, RunwayData
from .base import Base
from .missiontarget import MissionTarget
from game.point_with_heading import PointWithHeading
from .theatergroundobject import (
BaseDefenseGroundObject,
EwrGroundObject,
@@ -63,7 +63,6 @@ class LocationType(Enum):
BaseAirDefense = "base air defense"
Coastal = "coastal defense"
Ewr = "EWR"
BaseEwr = "Base EWR"
Garrison = "garrison"
MissileSite = "missile site"
OffshoreStrikeTarget = "offshore strike target"
@@ -78,44 +77,38 @@ class PresetLocations:
"""Defines the preset locations loaded from the campaign mission file."""
#: Locations used for spawning ground defenses for bases.
base_garrisons: List[PointWithHeading] = field(default_factory=list)
base_garrisons: List[Point] = field(default_factory=list)
#: Locations used for spawning air defenses for bases. Used by SAMs, AAA,
#: and SHORADs.
base_air_defense: List[PointWithHeading] = field(default_factory=list)
base_air_defense: List[Point] = field(default_factory=list)
#: Locations used by EWRs.
ewrs: List[PointWithHeading] = field(default_factory=list)
#: Locations used by Base EWRs.
base_ewrs: List[PointWithHeading] = field(default_factory=list)
ewrs: List[Point] = field(default_factory=list)
#: Locations used by non-carrier ships. Carriers and LHAs are not random.
ships: List[PointWithHeading] = field(default_factory=list)
ships: List[Point] = field(default_factory=list)
#: Locations used by coastal defenses.
coastal_defenses: List[PointWithHeading] = field(default_factory=list)
coastal_defenses: List[Point] = field(default_factory=list)
#: Locations used by ground based strike objectives.
strike_locations: List[PointWithHeading] = field(default_factory=list)
strike_locations: List[Point] = field(default_factory=list)
#: Locations used by offshore strike objectives.
offshore_strike_locations: List[PointWithHeading] = field(default_factory=list)
offshore_strike_locations: List[Point] = field(default_factory=list)
#: Locations used by missile sites like scuds and V-2s.
missile_sites: List[PointWithHeading] = field(default_factory=list)
missile_sites: List[Point] = field(default_factory=list)
#: Locations of long range SAMs which should always be spawned.
required_long_range_sams: List[PointWithHeading] = field(default_factory=list)
required_long_range_sams: List[Point] = field(default_factory=list)
#: Locations of medium range SAMs which should always be spawned.
required_medium_range_sams: List[PointWithHeading] = field(default_factory=list)
#: Locations of EWRs which should always be spawned.
required_ewrs: List[PointWithHeading] = field(default_factory=list)
required_medium_range_sams: List[Point] = field(default_factory=list)
@staticmethod
def _random_from(points: List[PointWithHeading]) -> Optional[PointWithHeading]:
def _random_from(points: List[Point]) -> Optional[Point]:
"""Finds, removes, and returns a random position from the given list."""
if not points:
return None
@@ -123,7 +116,7 @@ class PresetLocations:
points.remove(point)
return point
def random_for(self, location_type: LocationType) -> Optional[PointWithHeading]:
def random_for(self, location_type: LocationType) -> Optional[Point]:
"""Returns a position suitable for the given location type.
The location, if found, will be claimed by the caller and not available
@@ -135,8 +128,6 @@ class PresetLocations:
return self._random_from(self.coastal_defenses)
if location_type == LocationType.Ewr:
return self._random_from(self.ewrs)
if location_type == LocationType.BaseEwr:
return self._random_from(self.base_ewrs)
if location_type == LocationType.Garrison:
return self._random_from(self.base_garrisons)
if location_type == LocationType.MissileSite:
@@ -259,7 +250,6 @@ class ControlPoint(MissionTarget, ABC):
self.connected_objectives: List[TheaterGroundObject] = []
self.base_defenses: List[BaseDefenseGroundObject] = []
self.preset_locations = PresetLocations()
self.helipads: List[PointWithHeading] = []
# TODO: Should be Airbase specific.
self.size = size
@@ -396,19 +386,18 @@ class ControlPoint(MissionTarget, ABC):
# TODO: Should be Airbase specific.
def clear_base_defenses(self) -> None:
for base_defense in self.base_defenses:
p = PointWithHeading.from_point(base_defense.position, base_defense.heading)
if isinstance(base_defense, EwrGroundObject):
self.preset_locations.base_ewrs.append(p)
self.preset_locations.ewrs.append(base_defense.position)
elif isinstance(base_defense, SamGroundObject):
self.preset_locations.base_air_defense.append(p)
self.preset_locations.base_air_defense.append(base_defense.position)
elif isinstance(base_defense, VehicleGroupGroundObject):
self.preset_locations.base_garrisons.append(p)
self.preset_locations.base_garrisons.append(base_defense.position)
else:
logging.error(
"Could not determine preset location type for "
f"{base_defense}. Assuming garrison type."
)
self.preset_locations.base_garrisons.append(p)
self.preset_locations.base_garrisons.append(base_defense.position)
self.base_defenses = []
def capture_equipment(self, game: Game) -> None:
@@ -644,15 +633,6 @@ class ControlPoint(MissionTarget, ABC):
def income_per_turn(self) -> int:
return 0
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
if self.is_friendly(for_player):
yield from [
FlightType.AEWC,
]
yield from super().mission_types(for_player)
@property
def has_active_frontline(self) -> bool:
return any(not c.is_friendly(self.captured) for c in self.connected_points)

View File

@@ -13,7 +13,7 @@ from dcs.vehicles import AirDefence
from game import Game, db
from game.factions.faction import Faction
from game.theater import Carrier, Lha, LocationType, PointWithHeading
from game.theater import Carrier, Lha, LocationType
from game.theater.theatergroundobject import (
BuildingGroundObject,
CarrierGroundObject,
@@ -23,11 +23,9 @@ from game.theater.theatergroundobject import (
SamGroundObject,
ShipGroundObject,
VehicleGroupGroundObject,
CoastalSiteGroundObject,
)
from game.version import VERSION
from gen import namegen
from gen.coastal.coastal_group_generator import generate_coastal_group
from gen.defenses.armor_group_generator import generate_armor_group
from gen.fleet.ship_group_generator import (
generate_carrier_group,
@@ -37,8 +35,10 @@ from gen.fleet.ship_group_generator import (
from gen.locations.preset_location_finder import MizDataLocationFinder
from gen.missiles.missiles_group_generator import generate_missile_group
from gen.sam.airdefensegroupgenerator import AirDefenseRange
from gen.sam.sam_group_generator import generate_anti_air_group
from gen.sam.ewr_group_generator import generate_ewr_group
from gen.sam.sam_group_generator import (
generate_anti_air_group,
generate_ewr_group,
)
from . import (
ConflictTheater,
ControlPoint,
@@ -148,13 +148,13 @@ class LocationFinder:
game.theater.terrain.name, control_point.full_name
)
def location_for(self, location_type: LocationType) -> Optional[PointWithHeading]:
def location_for(self, location_type: LocationType) -> Optional[Point]:
position = self.control_point.preset_locations.random_for(location_type)
if position is not None:
return position
logging.warning(
f"No campaign location for %s Mat %s",
f"No campaign location for %s at %s",
location_type.value,
self.control_point,
)
@@ -178,7 +178,7 @@ class LocationFinder:
)
return None
def random_from_miz_data(self, offshore: bool) -> Optional[PointWithHeading]:
def random_from_miz_data(self, offshore: bool) -> Optional[Point]:
if offshore:
locations = self.miz_data.offshore_locations
else:
@@ -186,18 +186,11 @@ class LocationFinder:
if self.miz_data.offshore_locations:
preset = random.choice(locations)
locations.remove(preset)
return PointWithHeading.from_point(preset.position, preset.heading)
return preset.position
return None
def random_position(
self, location_type: LocationType
) -> Optional[PointWithHeading]:
def random_position(self, location_type: LocationType) -> Optional[Point]:
# TODO: Flesh out preset locations so we never hit this case.
if location_type == LocationType.Coastal:
# No coastal locations generated randomly
return None
logging.warning(
"Falling back to random location for %s at %s",
location_type.value,
@@ -257,7 +250,7 @@ class LocationFinder:
on_ground: bool,
is_base_defense: bool,
avoid_others: bool,
) -> Optional[PointWithHeading]:
) -> Optional[Point]:
"""
Find a valid ground object location
:param on_ground: Whether it should be on ground or on sea (True = on
@@ -270,7 +263,7 @@ class LocationFinder:
near = self.control_point.position
others = self.control_point.ground_objects
def is_valid(point: Optional[PointWithHeading]) -> bool:
def is_valid(point: Optional[Point]) -> bool:
if point is None:
return False
@@ -301,9 +294,7 @@ class LocationFinder:
for _ in range(300):
# Check if on land or sea
p = PointWithHeading.from_point(
near.random_point_within(max_range, min_range), random.randint(0, 360)
)
p = near.random_point_within(max_range, min_range)
if is_valid(p):
return p
return None
@@ -455,18 +446,14 @@ class BaseDefenseGenerator:
self.generate_base_defenses()
def generate_ewr(self) -> None:
position = self.location_finder.location_for(LocationType.BaseEwr)
position = self.location_finder.location_for(LocationType.Ewr)
if position is None:
return
group_id = self.game.next_group_id()
g = EwrGroundObject(
namegen.random_objective_name(),
group_id,
position,
self.control_point,
True,
namegen.random_objective_name(), group_id, position, self.control_point
)
group = generate_ewr_group(self.game, g, self.faction)
@@ -603,15 +590,11 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
if self.faction.missiles:
self.generate_missile_sites()
if self.faction.coastal_defenses:
self.generate_coastal_sites()
return True
def generate_ground_points(self) -> None:
"""Generate ground objects and AA sites for the control point."""
skip_sams = self.generate_required_aa()
skip_ewrs = self.generate_required_ewr()
if self.control_point.is_global:
return
@@ -628,12 +611,6 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
skip_sams -= 1
else:
self.generate_aa_site()
# 1 in 4 additional objectives are EWR.
elif random.randint(0, 3) == 0:
if skip_ewrs > 0:
skip_ewrs -= 1
else:
self.generate_ewr_site()
else:
self.generate_ground_point()
@@ -665,17 +642,6 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
presets.required_medium_range_sams
)
def generate_required_ewr(self) -> int:
"""Generates the EWR sites that are required by the campaign.
Returns:
The number of EWR sites that were generated.
"""
presets = self.control_point.preset_locations
for position in presets.required_ewrs:
self.generate_ewr_at(position)
return len(presets.required_ewrs)
def generate_ground_point(self) -> None:
try:
category = random.choice(self.faction.building_set)
@@ -753,33 +719,6 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
g.groups = groups
self.control_point.connected_objectives.append(g)
def generate_ewr_site(self) -> None:
position = self.location_finder.location_for(LocationType.Ewr)
if position is None:
return
self.generate_ewr_at(position)
def generate_ewr_at(self, position: Point) -> None:
group_id = self.game.next_group_id()
g = EwrGroundObject(
namegen.random_objective_name(),
group_id,
position,
self.control_point,
for_airbase=False,
)
group = generate_ewr_group(self.game, g, self.faction)
if group is None:
logging.error(
"Could not generate ewr group for %s at %s",
g.name,
self.control_point,
)
return
g.groups = [group]
self.control_point.connected_objectives.append(g)
def generate_missile_sites(self) -> None:
for i in range(self.faction.missiles_group_count):
self.generate_missile_site()
@@ -801,31 +740,6 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
self.control_point.connected_objectives.append(g)
return
def generate_coastal_sites(self) -> None:
for i in range(self.faction.coastal_group_count):
self.generate_coastal_site()
def generate_coastal_site(self) -> None:
position = self.location_finder.location_for(LocationType.Coastal)
if position is None:
return
group_id = self.game.next_group_id()
g = CoastalSiteGroundObject(
namegen.random_objective_name(),
group_id,
position,
self.control_point,
position.heading,
)
group = generate_coastal_group(self.game, g, self.faction_name)
g.groups = []
if group is not None:
g.groups.append(group)
self.control_point.connected_objectives.append(g)
return
class FobGroundObjectGenerator(AirbaseGroundObjectGenerator):
def generate(self) -> bool:

View File

@@ -344,28 +344,6 @@ class MissileSiteGroundObject(TheaterGroundObject):
)
class CoastalSiteGroundObject(TheaterGroundObject):
def __init__(
self,
name: str,
group_id: int,
position: Point,
control_point: ControlPoint,
heading,
) -> None:
super().__init__(
name=name,
category="aa",
group_id=group_id,
position=position,
heading=heading,
control_point=control_point,
dcs_identifier="AA",
airbase_group=False,
sea_object=False,
)
class BaseDefenseGroundObject(TheaterGroundObject):
"""Base type for all base defenses."""
@@ -442,12 +420,7 @@ class VehicleGroupGroundObject(BaseDefenseGroundObject):
class EwrGroundObject(BaseDefenseGroundObject):
def __init__(
self,
name: str,
group_id: int,
position: Point,
control_point: ControlPoint,
for_airbase: bool,
self, name: str, group_id: int, position: Point, control_point: ControlPoint
) -> None:
super().__init__(
name=name,
@@ -457,7 +430,7 @@ class EwrGroundObject(BaseDefenseGroundObject):
heading=0,
control_point=control_point,
dcs_identifier="EWR",
airbase_group=for_airbase,
airbase_group=True,
sea_object=False,
)

View File

@@ -15,7 +15,6 @@ from shapely.ops import nearest_points, unary_union
from game.theater import ControlPoint
from game.utils import Distance, meters, nautical_miles
from gen import Conflict
from gen.flights.closestairfields import ObjectiveDistanceCache
from gen.flights.flight import Flight
@@ -132,7 +131,7 @@ class ThreatZones:
zone belongs to the player, it is the zone that will be avoided by
the enemy and vice versa.
"""
air_threats = []
airbases = []
air_defenses = []
for control_point in game.theater.controlpoints:
if control_point.captured != player:
@@ -140,7 +139,7 @@ class ThreatZones:
if control_point.runway_is_operational():
point = ShapelyPoint(control_point.position.x, control_point.position.y)
cap_threat_range = cls.barcap_threat_range(game, control_point)
air_threats.append(point.buffer(cap_threat_range.meters))
airbases.append(point.buffer(cap_threat_range.meters))
for tgo in control_point.ground_objects:
for group in tgo.groups:
@@ -153,7 +152,7 @@ class ThreatZones:
air_defenses.append(threat_zone)
return cls(
airbases=unary_union(air_threats), air_defenses=unary_union(air_defenses)
airbases=unary_union(airbases), air_defenses=unary_union(air_defenses)
)
@staticmethod

View File

@@ -2,7 +2,7 @@ from pathlib import Path
def _build_version_string() -> str:
components = ["2.5"]
components = ["2.4.4"]
build_number_path = Path("resources/buildnumber")
if build_number_path.exists():
with build_number_path.open("r") as build_number_file:

View File

@@ -3,12 +3,11 @@ from __future__ import annotations
import datetime
import logging
import random
from dataclasses import dataclass, field
from dataclasses import dataclass
from enum import Enum
from typing import Optional, TYPE_CHECKING
from dcs.cloud_presets import Clouds as PydcsClouds
from dcs.weather import CloudPreset, Weather as PydcsWeather, Wind
from dcs.weather import Weather as PydcsWeather, Wind
from game.settings import Settings
from game.utils import Distance, meters
@@ -37,23 +36,6 @@ class Clouds:
density: int
thickness: int
precipitation: PydcsWeather.Preceptions
preset: Optional[CloudPreset] = field(default=None)
@classmethod
def random_preset(cls, rain: bool) -> Clouds:
clouds = (p.value for p in PydcsClouds)
if rain:
presets = [p for p in clouds if "Rain" in p.name]
else:
presets = [p for p in clouds if "Rain" not in p.name]
preset = random.choice(presets)
return Clouds(
base=random.randint(preset.min_base, preset.max_base),
density=0,
thickness=0,
precipitation=PydcsWeather.Preceptions.None_,
preset=preset,
)
@dataclass(frozen=True)
@@ -119,11 +101,12 @@ class ClearSkies(Weather):
class Cloudy(Weather):
def generate_clouds(self) -> Optional[Clouds]:
return Clouds.random_preset(rain=False)
def generate_fog(self) -> Optional[Fog]:
# DCS 2.7 says to not use fog with the cloud presets.
return None
return Clouds(
base=self.random_cloud_base(),
density=random.randint(1, 8),
thickness=self.random_cloud_thickness(),
precipitation=PydcsWeather.Preceptions.None_,
)
def generate_wind(self) -> WindConditions:
return self.random_wind(0, 4)
@@ -131,11 +114,12 @@ class Cloudy(Weather):
class Raining(Weather):
def generate_clouds(self) -> Optional[Clouds]:
return Clouds.random_preset(rain=True)
def generate_fog(self) -> Optional[Fog]:
# DCS 2.7 says to not use fog with the cloud presets.
return None
return Clouds(
base=self.random_cloud_base(),
density=random.randint(5, 8),
thickness=self.random_cloud_thickness(),
precipitation=PydcsWeather.Preceptions.Rain,
)
def generate_wind(self) -> WindConditions:
return self.random_wind(0, 6)

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
import logging
import random
from dataclasses import dataclass, field
from dataclasses import dataclass
from datetime import timedelta
from functools import cached_property
from typing import Dict, List, Optional, TYPE_CHECKING, Type, Union
@@ -41,7 +41,6 @@ from dcs.planes import (
)
from dcs.point import MovingPoint, PointAction
from dcs.task import (
AWACS,
AntishipStrike,
AttackGroup,
Bombing,
@@ -67,8 +66,6 @@ from dcs.task import (
Targets,
Task,
WeaponType,
AWACSTaskAction,
SetFrequencyCommand,
)
from dcs.terrain.terrain import Airport, NoParkingSlotError
from dcs.triggers import Event, TriggerOnce, TriggerRule
@@ -90,8 +87,10 @@ from game.theater.controlpoint import (
from game.theater.theatergroundobject import TheaterGroundObject
from game.unitmap import UnitMap
from game.utils import Distance, meters, nautical_miles
from gen.airsupportgen import AirSupport
from gen.ato import AirTaskingOrder, Package
from gen.callsigns import create_group_callsign_from_unit
from gen.conflictgen import FRONTLINE_LENGTH
from gen.flights.flight import (
Flight,
FlightType,
@@ -105,12 +104,9 @@ from .flights.flightplan import (
LoiterFlightPlan,
PatrollingFlightPlan,
SweepFlightPlan,
AwacsFlightPlan,
)
from .flights.traveltime import GroundSpeed, TotEstimator
from .naming import namegen
from .airsupportgen import AirSupport, AwacsInfo
from .callsigns import callsign_for_support_unit
if TYPE_CHECKING:
from game import Game
@@ -138,7 +134,6 @@ TARGET_WAYPOINTS = (
FlightWaypointType.TARGET_SHIP,
)
# TODO: Get radio information for all the special cases.
def get_fallback_channel(unit_type: UnitType) -> RadioFrequency:
if unit_type in helicopter_map.values() and unit_type != UH_1H:
@@ -323,7 +318,6 @@ class FlightData:
intra_flight_channel: RadioFrequency,
bingo_fuel: Optional[int],
joker_fuel: Optional[int],
custom_name: Optional[str],
) -> None:
self.package = package
self.country = country
@@ -341,7 +335,6 @@ class FlightData:
self.bingo_fuel = bingo_fuel
self.joker_fuel = joker_fuel
self.callsign = create_group_callsign_from_unit(self.units[0])
self.custom_name = custom_name
@property
def client_units(self) -> List[FlyingUnit]:
@@ -676,7 +669,6 @@ class AircraftConflictGenerator:
game: Game,
radio_registry: RadioRegistry,
unit_map: UnitMap,
air_support: AirSupport,
) -> None:
self.m = mission
self.game = game
@@ -684,7 +676,6 @@ class AircraftConflictGenerator:
self.radio_registry = radio_registry
self.unit_map = unit_map
self.flights: List[FlightData] = []
self.air_support = air_support
@cached_property
def use_client(self) -> bool:
@@ -799,10 +790,7 @@ class AircraftConflictGenerator:
OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)
)
if flight.flight_type == FlightType.AEWC:
channel = self.radio_registry.alloc_uhf()
else:
channel = self.get_intra_flight_channel(unit_type)
channel = self.get_intra_flight_channel(unit_type)
group.set_frequency(channel.mhz)
divert = None
@@ -831,7 +819,6 @@ class AircraftConflictGenerator:
intra_flight_channel=channel,
bingo_fuel=flight.flight_plan.bingo_fuel,
joker_fuel=flight.flight_plan.joker_fuel,
custom_name=flight.custom_name,
)
)
@@ -839,20 +826,6 @@ class AircraftConflictGenerator:
if unit_type in [Su_33, C_101EB, C_101CC]:
self.set_reduced_fuel(flight, group, unit_type)
if isinstance(flight.flight_plan, AwacsFlightPlan):
callsign = callsign_for_support_unit(group)
self.air_support.awacs.append(
AwacsInfo(
dcsGroupName=str(group.name),
callsign=callsign,
freq=channel,
depature_location=flight.departure.name,
end_time=flight.flight_plan.mission_departure_time,
start_time=flight.flight_plan.mission_start_time,
)
)
def _generate_at_airport(
self,
name: str,
@@ -1377,33 +1350,6 @@ class AircraftConflictGenerator:
restrict_jettison=True,
)
def configure_awacs(
self,
group: FlyingGroup,
package: Package,
flight: Flight,
dynamic_runways: Dict[str, RunwayData],
) -> None:
group.task = AWACS.name
if not isinstance(flight.flight_plan, AwacsFlightPlan):
logging.error(
f"Cannot configure AEW&C tasks for {flight} because it does not have an AEW&C flight plan."
)
return
self._setup_group(group, AWACS, package, flight, dynamic_runways)
# Awacs task action
self.configure_behavior(
group,
react_on_threat=OptReactOnThreat.Values.EvadeFire,
roe=OptROE.Values.WeaponHold,
restrict_jettison=True,
)
group.points[0].tasks.append(AWACSTaskAction())
def configure_escort(
self,
group: FlyingGroup,
@@ -1440,8 +1386,6 @@ class AircraftConflictGenerator:
self.configure_cap(group, package, flight, dynamic_runways)
elif flight_type == FlightType.SWEEP:
self.configure_sweep(group, package, flight, dynamic_runways)
elif flight_type == FlightType.AEWC:
self.configure_awacs(group, package, flight, dynamic_runways)
elif flight_type in [FlightType.CAS, FlightType.BAI]:
self.configure_cas(group, package, flight, dynamic_runways)
elif flight_type == FlightType.DEAD:

View File

@@ -383,8 +383,8 @@ AIRFIELD_DATA = {
"31": ("IVZ", MHz(108, 750)),
},
),
# PERSIAN GULF MAP
"Liwa AFB": AirfieldData(
# TODO : PERSIAN GULF MAP
"Liwa Airbase": AirfieldData(
theater="Persian Gulf",
icao="OMLW",
elevation=400,
@@ -394,7 +394,7 @@ AIRFIELD_DATA = {
vor=("OMLW", MHz(117, 400)),
atc=AtcData(MHz(4, 225), MHz(39, 350), MHz(119, 300), MHz(250, 950)),
),
"Al Dhafra AFB": AirfieldData(
"Al Dhafra AB": AirfieldData(
theater="Persian Gulf",
icao="OMAM",
elevation=52,
@@ -402,50 +402,50 @@ AIRFIELD_DATA = {
tacan=TacanChannel(96, TacanBand.X),
tacan_callsign="MA",
vor=("MA", MHz(114, 900)),
atc=AtcData(MHz(4, 300), MHz(39, 500), MHz(126, 500), MHz(251, 100)),
atc=AtcData(MHz(4, 250), MHz(39, 400), MHz(126, 500), MHz(251, 000)),
ils={
"13": ("MMA", MHz(111, 100)),
"31": ("IMA", MHz(109, 100)),
},
),
"Al-Bateen": AirfieldData(
"Al-Bateen Airport": AirfieldData(
theater="Persian Gulf",
icao="OMAD",
elevation=11,
runway_length=6808,
vor=("ALB", MHz(114, 0)),
atc=AtcData(MHz(4, 75), MHz(39, 50), MHz(119, 900), MHz(250, 600)),
atc=AtcData(MHz(4, 25), MHz(38, 950), MHz(119, 900), MHz(250, 550)),
),
"Sas Al Nakheel": AirfieldData(
"Sas Al Nakheel Airport": AirfieldData(
theater="Persian Gulf",
icao="OMNK",
elevation=9,
runway_length=5387,
vor=("SAS", MHz(128, 930)),
atc=AtcData(MHz(4, 0), MHz(38, 900), MHz(128, 900), MHz(250, 450)),
atc=AtcData(MHz(3, 975), MHz(38, 850), MHz(128, 900), MHz(250, 450)),
),
"Abu Dhabi Intl": AirfieldData(
"Abu Dhabi International Airport": AirfieldData(
theater="Persian Gulf",
icao="OMAA",
elevation=91,
runway_length=12817,
vor=("ADV", MHz(114, 250)),
atc=AtcData(MHz(4, 50), MHz(39, 0), MHz(119, 200), MHz(250, 550)),
atc=AtcData(MHz(4, 000), MHz(38, 900), MHz(119, 200), MHz(250, 500)),
),
"Al Ain Intl": AirfieldData(
"Al Ain International Airport": AirfieldData(
theater="Persian Gulf",
icao="OMAL",
elevation=813,
runway_length=11267,
vor=("ALN", MHz(112, 600)),
atc=AtcData(MHz(4, 125), MHz(39, 150), MHz(119, 850), MHz(250, 700)),
atc=AtcData(MHz(4, 75), MHz(39, 50), MHz(119, 850), MHz(250, 650)),
),
"Al Maktoum Intl": AirfieldData(
theater="Persian Gulf",
icao="OMDW",
elevation=123,
runway_length=11500,
atc=AtcData(MHz(4, 350), MHz(39, 600), MHz(118, 600), MHz(251, 200)),
atc=AtcData(MHz(4, 300), MHz(39, 500), MHz(118, 650), MHz(251, 100)),
ils={
"30": ("IJWA", MHz(109, 750)),
"12": ("IMA", MHz(111, 750)),
@@ -458,7 +458,7 @@ AIRFIELD_DATA = {
runway_length=11865,
tacan=TacanChannel(99, TacanBand.X),
tacan_callsign="MIN",
atc=AtcData(MHz(3, 800), MHz(38, 500), MHz(118, 550), MHz(250, 100)),
atc=AtcData(MHz(3, 800), MHz(38, 500), MHz(121, 800), MHz(250, 100)),
ils={
"27": ("IMNR", MHz(110, 750)),
"9": ("IMNW", MHz(110, 700)),
@@ -469,7 +469,7 @@ AIRFIELD_DATA = {
icao="OMDB",
elevation=16,
runway_length=11018,
atc=AtcData(MHz(4, 325), MHz(39, 550), MHz(118, 750), MHz(251, 150)),
atc=AtcData(MHz(4, 275), MHz(39, 450), MHz(118, 750), MHz(251, 50)),
ils={
"30": ("IDBL", MHz(110, 900)),
"12": ("IDBR", MHz(110, 100)),
@@ -480,7 +480,7 @@ AIRFIELD_DATA = {
icao="OMSJ",
elevation=98,
runway_length=10535,
atc=AtcData(MHz(3, 850), MHz(38, 600), MHz(118, 600), MHz(250, 200)),
atc=AtcData(MHz(3, 850), MHz(38, 600), MHz(118, 600), MHz(252, 200)),
ils={
"30": ("ISHW", MHz(111, 950)),
"12": ("ISRE", MHz(108, 550)),
@@ -492,18 +492,18 @@ AIRFIELD_DATA = {
elevation=60,
runway_length=9437,
vor=("FJV", MHz(113, 800)),
atc=AtcData(MHz(4, 375), MHz(39, 650), MHz(124, 600), MHz(251, 250)),
atc=AtcData(MHz(4, 325), MHz(39, 550), MHz(124, 600), MHz(251, 150)),
ils={
"29": ("IFJR", MHz(111, 500)),
},
),
"Ras Al Khaimah Intl": AirfieldData(
"Ras AL Khaimah": AirfieldData(
theater="Persian Gulf",
icao="OMRK",
elevation=70,
runway_length=8406,
vor=("OMRK", MHz(113, 600)),
atc=AtcData(MHz(4, 200), MHz(39, 300), MHz(121, 600), MHz(250, 900)),
atc=AtcData(MHz(4, 150), MHz(39, 200), MHz(121, 600), MHz(250, 800)),
),
"Khasab": AirfieldData(
theater="Persian Gulf",
@@ -516,11 +516,7 @@ AIRFIELD_DATA = {
},
),
"Sir Abu Nuayr": AirfieldData(
theater="Persian Gulf",
icao="OMSN",
elevation=25,
runway_length=2229,
atc=AtcData(MHz(3, 900), MHz(38, 700), MHz(118, 0), MHz(250, 800)),
theater="Persian Gulf", icao="OMSN", elevation=25, runway_length=2229
),
"Sirri Island": AirfieldData(
theater="Persian Gulf",
@@ -530,7 +526,7 @@ AIRFIELD_DATA = {
vor=("SIR", MHz(113, 750)),
atc=AtcData(MHz(3, 875), MHz(38, 650), MHz(135, 50), MHz(250, 250)),
),
"Abu Musa Island": AirfieldData(
"Abu Musa Island Airport": AirfieldData(
theater="Persian Gulf",
icao="OIBA",
elevation=16,
@@ -559,13 +555,13 @@ AIRFIELD_DATA = {
vor=("KHM", MHz(117, 100)),
atc=AtcData(MHz(3, 825), MHz(38, 550), MHz(118, 50), MHz(250, 150)),
),
"Bandar-e-Jask": AirfieldData(
"Bandar-e-Jask airfield": AirfieldData(
theater="Persian Gulf",
icao="OIZJ",
elevation=26,
runway_length=6842,
vor=("KHM", MHz(116, 300)),
atc=AtcData(MHz(4, 25), MHz(38, 950), MHz(118, 150), MHz(250, 500)),
atc=AtcData(MHz(3, 825), MHz(38, 550), MHz(118, 50), MHz(250, 150)),
),
"Bandar Lengeh": AirfieldData(
theater="Persian Gulf",
@@ -573,26 +569,26 @@ AIRFIELD_DATA = {
elevation=80,
runway_length=7625,
vor=("LEN", MHz(114, 800)),
atc=AtcData(MHz(4, 275), MHz(39, 450), MHz(121, 700), MHz(251, 50)),
atc=AtcData(MHz(4, 225), MHz(39, 350), MHz(121, 700), MHz(250, 950)),
),
"Kish Intl": AirfieldData(
"Kish International Airport": AirfieldData(
theater="Persian Gulf",
icao="OIBK",
elevation=114,
runway_length=10617,
tacan=TacanChannel(112, TacanBand.X),
tacan_callsign="KIH",
atc=AtcData(MHz(4, 100), MHz(39, 100), MHz(121, 650), MHz(250, 650)),
atc=AtcData(MHz(4, 50), MHz(39, 000), MHz(121, 650), MHz(250, 600)),
),
"Lavan Island": AirfieldData(
"Lavan Island Airport": AirfieldData(
theater="Persian Gulf",
icao="OIBV",
elevation=75,
runway_length=8234,
vor=("LVA", MHz(116, 850)),
atc=AtcData(MHz(4, 150), MHz(39, 200), MHz(128, 550), MHz(250, 750)),
atc=AtcData(MHz(4, 100), MHz(39, 100), MHz(128, 550), MHz(250, 700)),
),
"Lar": AirfieldData(
"Lar Airbase": AirfieldData(
theater="Persian Gulf",
icao="OISL",
elevation=2635,
@@ -607,7 +603,7 @@ AIRFIELD_DATA = {
runway_length=7300,
tacan=TacanChannel(47, TacanBand.X),
tacan_callsign="HDR",
atc=AtcData(MHz(4, 400), MHz(39, 700), MHz(123, 150), MHz(251, 300)),
atc=AtcData(MHz(4, 350), MHz(39, 600), MHz(123, 150), MHz(251, 200)),
ils={
"8": ("IBHD", MHz(108, 900)),
},
@@ -620,19 +616,19 @@ AIRFIELD_DATA = {
tacan=TacanChannel(78, TacanBand.X),
tacan_callsign="BND",
vor=("BND", MHz(117, 200)),
atc=AtcData(MHz(4, 250), MHz(39, 401), MHz(118, 100), MHz(251, 0)),
atc=AtcData(MHz(4, 200), MHz(39, 300), MHz(118, 100), MHz(250, 900)),
ils={
"21": ("IBND", MHz(333, 800)),
},
),
"Jiroft": AirfieldData(
"Jiroft Airport": AirfieldData(
theater="Persian Gulf",
icao="OIKJ",
elevation=2664,
runway_length=9160,
atc=AtcData(MHz(4, 125), MHz(39, 120), MHz(136, 0), MHz(250, 750)),
),
"Kerman": AirfieldData(
"Kerman Airport": AirfieldData(
theater="Persian Gulf",
icao="OIKK",
elevation=5746,
@@ -640,9 +636,9 @@ AIRFIELD_DATA = {
tacan=TacanChannel(97, TacanBand.X),
tacan_callsign="KER",
vor=("KER", MHz(112, 0)),
atc=AtcData(MHz(3, 925), MHz(38, 750), MHz(118, 250), MHz(250, 300)),
atc=AtcData(MHz(3, 900), MHz(38, 700), MHz(118, 250), MHz(250, 300)),
),
"Shiraz Intl": AirfieldData(
"Shiraz International Airport": AirfieldData(
theater="Persian Gulf",
icao="OISS",
elevation=4878,
@@ -650,7 +646,7 @@ AIRFIELD_DATA = {
tacan=TacanChannel(94, TacanBand.X),
tacan_callsign="SYZ1",
vor=("SYZ", MHz(112, 0)),
atc=AtcData(MHz(3, 950), MHz(38, 800), MHz(121, 900), MHz(250, 350)),
atc=AtcData(MHz(3, 925), MHz(38, 750), MHz(121, 900), MHz(250, 350)),
),
# Syria Map
"Adana Sakirpasa": AirfieldData(
@@ -659,7 +655,7 @@ AIRFIELD_DATA = {
elevation=55,
runway_length=8115,
vor=("ADA", MHz(112, 700)),
atc=AtcData(MHz(4, 275), MHz(39, 450), MHz(121, 100), MHz(251, 0)),
atc=AtcData(MHz(4, 225), MHz(39, 350), MHz(121, 100), MHz(250, 900)),
ils={
"05": ("IADA", MHz(108, 700)),
},
@@ -672,7 +668,7 @@ AIRFIELD_DATA = {
tacan=TacanChannel(21, TacanBand.X),
tacan_callsign="DAN",
vor=("DAN", MHz(108, 400)),
atc=AtcData(MHz(3, 900), MHz(38, 700), MHz(122, 100), MHz(360, 100)),
atc=AtcData(MHz(3, 850), MHz(38, 600), MHz(129, 400), MHz(360, 100)),
ils={
"50": ("IDAN", MHz(109, 300)),
"23": ("DANM", MHz(111, 700)),
@@ -683,7 +679,7 @@ AIRFIELD_DATA = {
icao="OS71",
elevation=1614,
runway_length=4648,
atc=AtcData(MHz(4, 175), MHz(39, 250), MHz(120, 600), MHz(250, 800)),
atc=AtcData(MHz(4, 125), MHz(39, 150), MHz(120, 600), MHz(250, 700)),
),
"Hatay": AirfieldData(
theater="Syria",
@@ -691,7 +687,7 @@ AIRFIELD_DATA = {
elevation=253,
runway_length=9052,
vor=("HTY", MHz(112, 500)),
atc=AtcData(MHz(3, 875), MHz(38, 650), MHz(128, 500), MHz(250, 250)),
atc=AtcData(MHz(3, 825), MHz(38, 550), MHz(128, 500), MHz(250, 150)),
ils={
"22": ("IHTY", MHz(108, 150)),
"04": ("IHAT", MHz(108, 900)),
@@ -702,21 +698,25 @@ AIRFIELD_DATA = {
icao="OS66",
elevation=1200,
runway_length=6662,
atc=AtcData(MHz(4, 325), MHz(39, 550), MHz(120, 500), MHz(251, 100)),
atc=AtcData(MHz(4, 275), MHz(39, 450), MHz(120, 500), MHz(251)),
),
"Aleppo": AirfieldData(
theater="Syria",
icao="OSAP",
elevation=1253,
runway_length=8332,
atc=AtcData(MHz(4, 200), MHz(39, 300), MHz(119, 100), MHz(250, 850)),
atc=AtcData(MHz(4, 150), MHz(39, 200), MHz(119, 100), MHz(250, 750)),
ils={
"50": ("IDAN", MHz(109, 300)),
"23": ("DANM", MHz(111, 700)),
},
),
"Jirah": AirfieldData(
theater="Syria",
icao="OS62",
elevation=1170,
runway_length=9090,
atc=AtcData(MHz(3, 925), MHz(38, 750), MHz(118, 100), MHz(250, 300)),
atc=AtcData(MHz(3, 875), MHz(38, 650), MHz(118, 100), MHz(250, 200)),
),
"Taftanaz": AirfieldData(
theater="Syria",
@@ -729,14 +729,14 @@ AIRFIELD_DATA = {
icao="OS59",
elevation=1083,
runway_length=9036,
atc=AtcData(MHz(4, 500), MHz(39, 900), MHz(122, 800), MHz(251, 450)),
atc=AtcData(MHz(4, 350), MHz(39, 600), MHz(118, 500), MHz(251, 150)),
),
"Abu al-Dahur": AirfieldData(
theater="Syria",
icao="OS57",
elevation=820,
runway_length=8728,
atc=AtcData(MHz(4, 0), MHz(38, 900), MHz(122, 200), MHz(250, 450)),
atc=AtcData(MHz(3, 950), MHz(38, 800), MHz(122, 200), MHz(250, 350)),
),
"Bassel Al-Assad": AirfieldData(
theater="Syria",
@@ -744,7 +744,7 @@ AIRFIELD_DATA = {
elevation=93,
runway_length=7305,
vor=("LTK", MHz(114, 800)),
atc=AtcData(MHz(4, 50), MHz(39, 0), MHz(118, 100), MHz(250, 550)),
atc=AtcData(MHz(4), MHz(38, 900), MHz(118, 100), MHz(250, 450)),
ils={
"17": ("IBA", MHz(109, 100)),
},
@@ -754,28 +754,28 @@ AIRFIELD_DATA = {
icao="OS58",
elevation=983,
runway_length=7957,
atc=AtcData(MHz(3, 850), MHz(38, 600), MHz(118, 50), MHz(250, 200)),
atc=AtcData(MHz(3, 800), MHz(38, 500), MHz(118, 50), MHz(250, 100)),
),
"Rene Mouawad": AirfieldData(
theater="Syria",
icao="OLKA",
elevation=14,
runway_length=8614,
atc=AtcData(MHz(4, 375), MHz(39, 650), MHz(121, 0), MHz(251, 200)),
atc=AtcData(MHz(4, 325), MHz(39, 550), MHz(129, 500), MHz(251, 100)),
),
"Al Quasayr": AirfieldData(
theater="Syria",
icao="OS70",
elevation=1729,
runway_length=8585,
atc=AtcData(MHz(4, 550), MHz(40, 0), MHz(119, 200), MHz(251, 550)),
atc=AtcData(MHz(4, 400), MHz(39, 700), MHz(119, 200), MHz(251, 250)),
),
"Palmyra": AirfieldData(
theater="Syria",
icao="OSPR",
elevation=1267,
runway_length=8704,
atc=AtcData(MHz(4, 225), MHz(39, 350), MHz(121, 900), MHz(250, 900)),
atc=AtcData(MHz(4, 175), MHz(39, 250), MHz(121, 900), MHz(250, 800)),
),
"Wujah Al Hajar": AirfieldData(
theater="Syria",
@@ -783,14 +783,14 @@ AIRFIELD_DATA = {
elevation=619,
runway_length=4717,
vor=("CAK", MHz(116, 200)),
atc=AtcData(MHz(4, 575), MHz(40, 50), MHz(121, 500), MHz(251, 600)),
atc=AtcData(MHz(4, 425), MHz(39, 750), MHz(121, 500), MHz(251, 300)),
),
"An Nasiriyah": AirfieldData(
theater="Syria",
icao="OS64",
elevation=2746,
runway_length=8172,
atc=AtcData(MHz(4, 600), MHz(40, 100), MHz(122, 300), MHz(251, 650)),
atc=AtcData(MHz(4, 450), MHz(39, 800), MHz(122, 300), MHz(251, 350)),
),
"Rayak": AirfieldData(
theater="Syria",
@@ -798,7 +798,7 @@ AIRFIELD_DATA = {
elevation=2934,
runway_length=8699,
vor=("HTY", MHz(124, 400)),
atc=AtcData(MHz(4, 350), MHz(39, 600), MHz(124, 400), MHz(251, 150)),
atc=AtcData(MHz(4, 300), MHz(39, 500), MHz(124, 400), MHz(251, 50)),
),
"Beirut-Rafic Hariri": AirfieldData(
theater="Syria",
@@ -806,7 +806,7 @@ AIRFIELD_DATA = {
elevation=39,
runway_length=9463,
vor=("KAD", MHz(112, 600)),
atc=AtcData(MHz(4, 675), MHz(40, 250), MHz(118, 900), MHz(251, 800)),
atc=AtcData(MHz(4, 475), MHz(39, 850), MHz(118, 900), MHz(251, 400)),
ils={
"17": ("BIL", MHz(109, 500)),
},
@@ -816,32 +816,32 @@ AIRFIELD_DATA = {
icao="OS61",
elevation=2066,
runway_length=8902,
atc=AtcData(MHz(4, 750), MHz(40, 400), MHz(120, 300), MHz(251, 950)),
atc=AtcData(MHz(4, 550), MHz(40), MHz(120, 300), MHz(251, 550)),
),
"Marj as Sultan North": AirfieldData(
theater="Syria",
elevation=2007,
runway_length=268,
atc=AtcData(MHz(4, 75), MHz(38, 50), MHz(122, 700), MHz(250, 600)),
atc=AtcData(MHz(4, 25), MHz(38, 950), MHz(122, 700), MHz(250, 500)),
),
"Marj as Sultan South": AirfieldData(
theater="Syria",
elevation=2007,
runway_length=166,
atc=AtcData(MHz(4, 725), MHz(40, 350), MHz(122, 900), MHz(251, 900)),
atc=AtcData(MHz(4, 525), MHz(39, 950), MHz(122, 900), MHz(251, 500)),
),
"Mezzeh": AirfieldData(
theater="Syria",
icao="OS67",
elevation=2355,
runway_length=7522,
atc=AtcData(MHz(4, 150), MHz(39, 200), MHz(120, 700), MHz(250, 750)),
atc=AtcData(MHz(4, 100), MHz(39, 100), MHz(120, 700), MHz(250, 650)),
),
"Qabr as Sitt": AirfieldData(
theater="Syria",
elevation=2134,
runway_length=489,
atc=AtcData(MHz(4, 250), MHz(39, 400), MHz(122, 600), MHz(250, 950)),
atc=AtcData(MHz(4, 200), MHz(39, 300), MHz(122, 600), MHz(250, 850)),
),
"Damascus": AirfieldData(
theater="Syria",
@@ -849,7 +849,7 @@ AIRFIELD_DATA = {
elevation=2007,
runway_length=11423,
vor=("DAM", MHz(116)),
atc=AtcData(MHz(4, 700), MHz(40, 300), MHz(118, 500), MHz(251, 850)),
atc=AtcData(MHz(4, 500), MHz(39, 900), MHz(118, 500), MHz(251, 450)),
ils={
"24": ("IDA", MHz(109, 900)),
},
@@ -859,42 +859,42 @@ AIRFIELD_DATA = {
icao="OS63",
elevation=2160,
runway_length=7576,
atc=AtcData(MHz(4, 100), MHz(39, 100), MHz(120, 800), MHz(250, 6550)),
atc=AtcData(MHz(4, 50), MHz(39), MHz(120, 800), MHz(250, 550)),
),
"Kiryat Shmona": AirfieldData(
theater="Syria",
icao="LLKS",
elevation=328,
runway_length=3258,
atc=AtcData(MHz(4, 25), MHz(38, 950), MHz(118, 400), MHz(250, 500)),
atc=AtcData(MHz(3, 975), MHz(38, 850), MHz(118, 400), MHz(250, 400)),
),
"Khalkhalah": AirfieldData(
theater="Syria",
icao="OS69",
elevation=2337,
runway_length=8248,
atc=AtcData(MHz(3, 950), MHz(38, 800), MHz(122, 500), MHz(250, 350)),
atc=AtcData(MHz(3, 900), MHz(38, 700), MHz(122, 500), MHz(250, 250)),
),
"Haifa": AirfieldData(
theater="Syria",
icao="LLHA",
elevation=19,
runway_length=3253,
atc=AtcData(MHz(3, 825), MHz(38, 550), MHz(127, 800), MHz(250, 150)),
atc=AtcData(MHz(3, 775), MHz(38, 450), MHz(127, 800), MHz(250, 50)),
),
"Ramat David": AirfieldData(
theater="Syria",
icao="LLRD",
elevation=105,
runway_length=7037,
atc=AtcData(MHz(4, 300), MHz(39, 500), MHz(118, 600), MHz(251, 50)),
atc=AtcData(MHz(4, 250), MHz(39, 400), MHz(118, 600), MHz(250, 950)),
),
"Megiddo": AirfieldData(
theater="Syria",
icao="LLMG",
elevation=180,
runway_length=6098,
atc=AtcData(MHz(4, 125), MHz(39, 150), MHz(119, 900), MHz(250, 700)),
atc=AtcData(MHz(4, 75), MHz(39, 50), MHz(119, 900), MHz(250, 600)),
),
"Eyn Shemer": AirfieldData(
theater="Syria",
@@ -908,66 +908,7 @@ AIRFIELD_DATA = {
icao="OJMF",
elevation=2204,
runway_length=8595,
atc=AtcData(MHz(3, 975), MHz(38, 850), MHz(118, 300), MHz(250, 400)),
),
"Tha'lah": AirfieldData(
theater="Syria",
icao="OS60",
elevation=2381,
runway_length=8025,
atc=AtcData(MHz(4, 650), MHz(40, 200), MHz(122, 400), MHz(251, 750)),
),
"Shayrat": AirfieldData(
theater="Syria",
icao="OS60",
elevation=2637,
runway_length=8553,
atc=AtcData(MHz(4, 450), MHz(39, 800), MHz(122, 200), MHz(251, 350)),
),
"Tiyas": AirfieldData(
theater="Syria",
icao="OS72",
elevation=1797,
runway_length=9420,
atc=AtcData(MHz(4, 525), MHz(39, 950), MHz(120, 500), MHz(251, 500)),
),
"Rosh Pina": AirfieldData(
theater="Syria",
icao="LLIB",
elevation=865,
runway_length=2711,
atc=AtcData(MHz(4, 400), MHz(39, 700), MHz(118, 450), MHz(251, 250)),
),
"Sayqal": AirfieldData(
theater="Syria",
icao="OS68",
elevation=2273,
runway_length=8536,
atc=AtcData(MHz(4, 425), MHz(39, 750), MHz(120, 400), MHz(251, 300)),
),
"H4": AirfieldData(
theater="Syria",
icao="OJHR",
elevation=2257,
runway_length=7179,
atc=AtcData(MHz(3, 800), MHz(38, 500), MHz(120, 400), MHz(250, 100)),
),
"Naqoura": AirfieldData(
theater="Syria",
icao="",
elevation=378,
runway_length=0,
atc=AtcData(MHz(4, 625), MHz(40, 150), MHz(122, 000), MHz(251, 700)),
),
"Gaziantep": AirfieldData(
theater="Syria",
icao="LTAJ",
elevation=2287,
runway_length=8871,
atc=AtcData(MHz(3, 775), MHz(38, 450), MHz(120, 100), MHz(250, 50)),
ils={
"28": ("IGNP", MHz(109, 10)),
},
atc=AtcData(MHz(3, 925), MHz(38, 750), MHz(118, 300), MHz(250, 300)),
),
# NTTR
"Mina Airport 3Q0": AirfieldData(
@@ -1363,73 +1304,55 @@ AIRFIELD_DATA = {
"Detling": AirfieldData(
theater="Channel",
elevation=623,
runway_length=3482,
atc=AtcData(MHz(4, 50), MHz(118, 600), MHz(39, 0), MHz(250, 600)),
runway_length=2557,
atc=AtcData(MHz(3, 950), MHz(118, 400), MHz(38, 800), MHz(250, 400)),
),
"High Halden": AirfieldData(
theater="Channel",
elevation=104,
runway_length=3296,
atc=AtcData(MHz(3, 800), MHz(118, 100), MHz(38, 500), MHz(250, 100)),
atc=AtcData(MHz(3, 750), MHz(118, 800), MHz(38, 400), MHz(250, 0)),
),
"Lympne": AirfieldData(
theater="Channel",
elevation=351,
runway_length=3054,
atc=AtcData(MHz(4, 25), MHz(118, 550), MHz(38, 950), MHz(250, 550)),
runway_length=2548,
atc=AtcData(MHz(3, 925), MHz(118, 350), MHz(38, 750), MHz(250, 350)),
),
"Hawkinge": AirfieldData(
theater="Channel",
elevation=524,
runway_length=3013,
atc=AtcData(MHz(4, 0), MHz(118, 500), MHz(38, 900), MHz(250, 500)),
atc=AtcData(MHz(3, 900), MHz(118, 300), MHz(38, 700), MHz(250, 300)),
),
"Manston": AirfieldData(
theater="Channel",
elevation=160,
runway_length=8626,
atc=AtcData(MHz(3, 975), MHz(118, 250), MHz(38, 650), MHz(250, 250)),
atc=AtcData(MHz(3, 875), MHz(118, 250), MHz(38, 650), MHz(250, 250)),
),
"Dunkirk Mardyck": AirfieldData(
theater="Channel",
elevation=16,
runway_length=1737,
atc=AtcData(MHz(3, 950), MHz(118, 450), MHz(38, 850), MHz(250, 450)),
atc=AtcData(MHz(3, 850), MHz(118, 200), MHz(38, 600), MHz(250, 200)),
),
"Saint Omer Longuenesse": AirfieldData(
theater="Channel",
elevation=219,
runway_length=1929,
atc=AtcData(MHz(3, 925), MHz(118, 350), MHz(38, 750), MHz(250, 350)),
atc=AtcData(MHz(3, 825), MHz(118, 150), MHz(38, 550), MHz(250, 150)),
),
"Merville Calonne": AirfieldData(
theater="Channel",
elevation=52,
runway_length=7580,
atc=AtcData(MHz(3, 900), MHz(118, 300), MHz(38, 700), MHz(250, 300)),
atc=AtcData(MHz(3, 800), MHz(118, 100), MHz(38, 500), MHz(250, 100)),
),
"Abbeville Drucat": AirfieldData(
theater="Channel",
elevation=183,
runway_length=4726,
atc=AtcData(MHz(3, 875), MHz(118, 250), MHz(38, 650), MHz(250, 250)),
),
"Eastchurch": AirfieldData(
theater="Channel",
elevation=30,
runway_length=2983,
atc=AtcData(MHz(3, 775), MHz(118, 50), MHz(38, 450), MHz(250, 50)),
),
"Headcorn": AirfieldData(
theater="Channel",
elevation=114,
runway_length=3680,
atc=AtcData(MHz(3, 825), MHz(118, 150), MHz(38, 550), MHz(250, 150)),
),
"Biggin Hill": AirfieldData(
theater="Channel",
elevation=552,
runway_length=3953,
atc=AtcData(MHz(3, 850), MHz(118, 200), MHz(38, 600), MHz(250, 200)),
),
}

View File

@@ -1,7 +1,6 @@
import logging
from dataclasses import dataclass, field
from datetime import timedelta
from typing import List, Type, Tuple, Optional
from typing import List, Type, Tuple
from dcs.mission import Mission, StartType
from dcs.planes import IL_78M, KC130, KC135MPRS, KC_135
@@ -22,7 +21,6 @@ from .conflictgen import Conflict
from .radios import RadioFrequency, RadioRegistry
from .tacan import TacanBand, TacanChannel, TacanRegistry
TANKER_DISTANCE = 15000
TANKER_ALT = 4572
TANKER_HEADING_OFFSET = 45
@@ -38,9 +36,6 @@ class AwacsInfo:
dcsGroupName: str
callsign: str
freq: RadioFrequency
depature_location: Optional[str]
start_time: Optional[timedelta]
end_time: Optional[timedelta]
@dataclass
@@ -168,41 +163,37 @@ class AirSupportConflictGenerator:
TankerInfo(str(tanker_group.name), callsign, variant, freq, tacan)
)
if not self.game.settings.disable_legacy_aewc:
possible_awacs = db.find_unittype(AWACS, self.conflict.attackers_side)
possible_awacs = db.find_unittype(AWACS, self.conflict.attackers_side)
if len(possible_awacs) > 0:
awacs_unit = possible_awacs[0]
freq = self.radio_registry.alloc_uhf()
if len(possible_awacs) > 0:
awacs_unit = possible_awacs[0]
freq = self.radio_registry.alloc_uhf()
awacs_flight = self.mission.awacs_flight(
country=self.mission.country(self.game.player_country),
name=namegen.next_awacs_name(
self.mission.country(self.game.player_country)
),
plane_type=awacs_unit,
altitude=AWACS_ALT,
airport=None,
position=self.conflict.position.random_point_within(
AWACS_DISTANCE, AWACS_DISTANCE
),
frequency=freq.mhz,
start_type=StartType.Warm,
awacs_flight = self.mission.awacs_flight(
country=self.mission.country(self.game.player_country),
name=namegen.next_awacs_name(
self.mission.country(self.game.player_country)
),
plane_type=awacs_unit,
altitude=AWACS_ALT,
airport=None,
position=self.conflict.position.random_point_within(
AWACS_DISTANCE, AWACS_DISTANCE
),
frequency=freq.mhz,
start_type=StartType.Warm,
)
awacs_flight.set_frequency(freq.mhz)
awacs_flight.points[0].tasks.append(SetInvisibleCommand(True))
awacs_flight.points[0].tasks.append(SetImmortalCommand(True))
self.air_support.awacs.append(
AwacsInfo(
str(awacs_flight.name),
callsign_for_support_unit(awacs_flight),
freq,
)
awacs_flight.set_frequency(freq.mhz)
awacs_flight.points[0].tasks.append(SetInvisibleCommand(True))
awacs_flight.points[0].tasks.append(SetImmortalCommand(True))
self.air_support.awacs.append(
AwacsInfo(
dcsGroupName=str(awacs_flight.name),
callsign=callsign_for_support_unit(awacs_flight),
freq=freq,
depature_location=None,
start_time=None,
end_time=None,
)
)
else:
logging.warning("No AWACS for faction")
)
else:
logging.warning("No AWACS for faction")

View File

@@ -175,7 +175,6 @@ class Package:
FlightType.SEAD,
FlightType.TARCAP,
FlightType.BARCAP,
FlightType.AEWC,
FlightType.SWEEP,
FlightType.ESCORT,
]

View File

@@ -20,7 +20,6 @@ from .ground_forces.combat_stance import CombatStance
from .radios import RadioFrequency
from .runways import RunwayData
if TYPE_CHECKING:
from game import Game

View File

@@ -1,31 +0,0 @@
import logging
import random
from game import db
from gen.coastal.silkworm import SilkwormGenerator
COASTAL_MAP = {
"SilkwormGenerator": SilkwormGenerator,
}
def generate_coastal_group(game, ground_object, faction_name: str):
"""
This generate a coastal defenses group
:return: Nothing, but put the group reference inside the ground object
"""
faction = db.FACTIONS[faction_name]
if len(faction.coastal_defenses) > 0:
generators = faction.coastal_defenses
if len(generators) > 0:
gen = random.choice(generators)
if gen in COASTAL_MAP.keys():
generator = COASTAL_MAP[gen](game, ground_object, faction)
generator.generate()
return generator.get_generated_group()
else:
logging.info(
"Unable to generate missile group, generator : "
+ str(gen)
+ "does not exists"
)
return None

View File

@@ -1,58 +0,0 @@
from dcs.vehicles import MissilesSS, Unarmed, AirDefence
from gen.sam.group_generator import GroupGenerator
class SilkwormGenerator(GroupGenerator):
def __init__(self, game, ground_object, faction):
super(SilkwormGenerator, self).__init__(game, ground_object)
self.faction = faction
def generate(self):
positions = self.get_circular_position(5, launcher_distance=120, coverage=180)
self.add_unit(
MissilesSS.AShM_Silkworm_SR,
"SR#0",
self.position.x,
self.position.y,
self.heading,
)
# Launchers
for i, p in enumerate(positions):
self.add_unit(
MissilesSS.AShM_SS_N_2_Silkworm,
"Missile#" + str(i),
p[0],
p[1],
self.heading,
)
# Commander
self.add_unit(
Unarmed.Truck_KAMAZ_43101,
"KAMAZ#0",
self.position.x - 35,
self.position.y - 20,
self.heading,
)
# Shorad
self.add_unit(
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish,
"SHILKA#0",
self.position.x - 55,
self.position.y - 38,
self.heading,
)
# Shorad 2
self.add_unit(
AirDefence.SAM_SA_9_Strela_1_Gaskin_TEL,
"STRELA#0",
self.position.x + 200,
self.position.y + 15,
90,
)

View File

@@ -17,7 +17,6 @@ class EnvironmentGenerator:
self.mission.weather.clouds_thickness = clouds.thickness
self.mission.weather.clouds_density = clouds.density
self.mission.weather.clouds_iprecptns = clouds.precipitation
self.mission.weather.clouds_preset = clouds.preset
def set_fog(self, fog: Optional[Fog]) -> None:
if fog is None:

View File

@@ -2,122 +2,50 @@ import random
from gen.sam.group_generator import ShipGroupGenerator
from dcs.ships import DDG_Arleigh_Burke_IIa, CG_Ticonderoga
class CarrierGroupGenerator(ShipGroupGenerator):
def generate(self):
# Carrier Strike Group 8
if self.faction.carrier_names[0] == "Carrier Strike Group 8":
# Add carrier
if len(self.faction.aircraft_carrier) > 0:
carrier_type = random.choice(self.faction.aircraft_carrier)
self.add_unit(
carrier_type,
"CVN-75 Harry S. Truman",
self.position.x,
self.position.y,
self.heading,
carrier_type, "Carrier", self.position.x, self.position.y, self.heading
)
# Add Arleigh Burke escort
self.add_unit(
DDG_Arleigh_Burke_IIa,
"USS Ramage",
self.position.x + 6482,
self.position.y + 6667,
self.heading,
)
self.add_unit(
DDG_Arleigh_Burke_IIa,
"USS Mitscher",
self.position.x - 7963,
self.position.y + 7037,
self.heading,
)
self.add_unit(
DDG_Arleigh_Burke_IIa,
"USS Forrest Sherman",
self.position.x - 7408,
self.position.y - 7408,
self.heading,
)
self.add_unit(
DDG_Arleigh_Burke_IIa,
"USS Lassen",
self.position.x + 8704,
self.position.y - 6296,
self.heading,
)
# Add Ticonderoga escort
if self.heading >= 180:
self.add_unit(
CG_Ticonderoga,
"USS Hué City",
self.position.x + 2222,
self.position.y - 3333,
self.heading,
)
else:
self.add_unit(
CG_Ticonderoga,
"USS Hué City",
self.position.x - 3333,
self.position.y + 2222,
self.heading,
)
self.get_generated_group().points[0].speed = 20
##################################################################################################
# Add carrier for normal generation
else:
if len(self.faction.aircraft_carrier) > 0:
carrier_type = random.choice(self.faction.aircraft_carrier)
self.add_unit(
carrier_type,
"Carrier",
self.position.x,
self.position.y,
self.heading,
)
else:
return
return
# Add destroyers escort
if len(self.faction.destroyers) > 0:
dd_type = random.choice(self.faction.destroyers)
self.add_unit(
dd_type,
"DD1",
self.position.x + 2500,
self.position.y + 4500,
self.heading,
)
self.add_unit(
dd_type,
"DD2",
self.position.x + 2500,
self.position.y - 4500,
self.heading,
)
# Add destroyers escort
if len(self.faction.destroyers) > 0:
dd_type = random.choice(self.faction.destroyers)
self.add_unit(
dd_type,
"DD1",
self.position.x + 2500,
self.position.y + 4500,
self.heading,
)
self.add_unit(
dd_type,
"DD2",
self.position.x + 2500,
self.position.y - 4500,
self.heading,
)
self.add_unit(
dd_type,
"DD3",
self.position.x + 4500,
self.position.y + 8500,
self.heading,
)
self.add_unit(
dd_type,
"DD4",
self.position.x + 4500,
self.position.y - 8500,
self.heading,
)
self.add_unit(
dd_type,
"DD3",
self.position.x + 4500,
self.position.y + 8500,
self.heading,
)
self.add_unit(
dd_type,
"DD4",
self.position.x + 4500,
self.position.y - 8500,
self.heading,
)
self.get_generated_group().points[0].speed = 20
self.get_generated_group().points[0].speed = 20

View File

@@ -6,7 +6,7 @@ from game.theater.theatergroundobject import TheaterGroundObject
from gen.sam.group_generator import ShipGroupGenerator
from dcs.unittype import ShipType
from dcs.ships import FFG_Oliver_Hazzard_Perry, DDG_Arleigh_Burke_IIa
from dcs.ships import Oliver_Hazzard_Perry_class, USS_Arleigh_Burke_IIa
if TYPE_CHECKING:
from game.game import Game
@@ -46,7 +46,7 @@ class OliverHazardPerryGroupGenerator(DDGroupGenerator):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(OliverHazardPerryGroupGenerator, self).__init__(
game, ground_object, faction, FFG_Oliver_Hazzard_Perry
game, ground_object, faction, Oliver_Hazzard_Perry_class
)
@@ -55,5 +55,5 @@ class ArleighBurkeGroupGenerator(DDGroupGenerator):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(ArleighBurkeGroupGenerator, self).__init__(
game, ground_object, faction, DDG_Arleigh_Burke_IIa
game, ground_object, faction, USS_Arleigh_Burke_IIa
)

View File

@@ -3,13 +3,13 @@ import random
from typing import TYPE_CHECKING
from dcs.ships import (
Corvette_1124_4_Grisha,
Corvette_1241_1_Molniya,
Frigate_11540_Neustrashimy,
Frigate_1135M_Rezky,
Cruiser_1164_Moskva,
SSK_877V_Kilo,
SSK_641B_Tango,
FFL_1124_4_Grisha,
FSG_1241_1MP_Molniya,
FFG_11540_Neustrashimy,
FF_1135M_Rezky,
CG_1164_Moskva,
SSK_877,
SSK_641B,
)
from gen.fleet.dd_group import DDGroupGenerator
@@ -37,9 +37,7 @@ class RussianNavyGroupGenerator(ShipGroupGenerator):
include_frigate = True
if include_frigate:
frigate_type = random.choice(
[Corvette_1124_4_Grisha, Corvette_1241_1_Molniya]
)
frigate_type = random.choice([FFL_1124_4_Grisha, FSG_1241_1MP_Molniya])
self.add_unit(
frigate_type,
"FF1",
@@ -56,7 +54,7 @@ class RussianNavyGroupGenerator(ShipGroupGenerator):
)
if include_dd:
dd_type = random.choice([Frigate_11540_Neustrashimy, Frigate_1135M_Rezky])
dd_type = random.choice([FFG_11540_Neustrashimy, FF_1135M_Rezky])
self.add_unit(
dd_type,
"DD1",
@@ -76,11 +74,7 @@ class RussianNavyGroupGenerator(ShipGroupGenerator):
# Only include the Moskva for now, the Pyotry Velikiy is an unkillable monster.
# See https://github.com/Khopa/dcs_liberation/issues/567
self.add_unit(
Cruiser_1164_Moskva,
"CC1",
self.position.x,
self.position.y,
self.heading,
CG_1164_Moskva, "CC1", self.position.x, self.position.y, self.heading
)
self.get_generated_group().points[0].speed = 20
@@ -91,7 +85,7 @@ class GrishaGroupGenerator(DDGroupGenerator):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(GrishaGroupGenerator, self).__init__(
game, ground_object, faction, Corvette_1124_4_Grisha
game, ground_object, faction, FFL_1124_4_Grisha
)
@@ -100,7 +94,7 @@ class MolniyaGroupGenerator(DDGroupGenerator):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(MolniyaGroupGenerator, self).__init__(
game, ground_object, faction, Corvette_1241_1_Molniya
game, ground_object, faction, FSG_1241_1MP_Molniya
)
@@ -109,7 +103,7 @@ class KiloSubGroupGenerator(DDGroupGenerator):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(KiloSubGroupGenerator, self).__init__(
game, ground_object, faction, SSK_877V_Kilo
game, ground_object, faction, SSK_877
)
@@ -118,5 +112,5 @@ class TangoSubGroupGenerator(DDGroupGenerator):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(TangoSubGroupGenerator, self).__init__(
game, ground_object, faction, SSK_641B_Tango
game, ground_object, faction, SSK_641B
)

View File

@@ -1,6 +1,6 @@
import random
from dcs.ships import Boat_Schnellboot_type_S130
from dcs.ships import Schnellboot_type_S130
from gen.sam.group_generator import ShipGroupGenerator
@@ -10,7 +10,7 @@ class SchnellbootGroupGenerator(ShipGroupGenerator):
for i in range(random.randint(2, 4)):
self.add_unit(
Boat_Schnellboot_type_S130,
Schnellboot_type_S130,
"Schnellboot" + str(i),
self.position.x + i * random.randint(100, 250),
self.position.y + (random.randint(100, 200) - 100),

View File

@@ -47,7 +47,6 @@ def generate_ship_group(game, ground_object, faction_name: str):
gen = random.choice(faction.navy_generators)
if gen in SHIP_MAP.keys():
generator = SHIP_MAP[gen](game, ground_object, faction)
print(generator.position)
generator.generate()
return generator.get_generated_group()
else:

View File

@@ -1,6 +1,6 @@
import random
from dcs.ships import U_boat_VIIC_U_flak
from dcs.ships import Uboat_VIIC_U_flak
from gen.sam.group_generator import ShipGroupGenerator
@@ -10,7 +10,7 @@ class UBoatGroupGenerator(ShipGroupGenerator):
for i in range(random.randint(1, 4)):
self.add_unit(
U_boat_VIIC_U_flak,
Uboat_VIIC_U_flak,
"Uboat" + str(i),
self.position.x + i * random.randint(100, 250),
self.position.y + (random.randint(100, 200) - 100),

View File

@@ -450,32 +450,6 @@ class ObjectiveFinder:
c for c in self.game.theater.controlpoints if c.is_friendly(self.is_player)
)
def farthest_friendly_control_point(self) -> Optional[ControlPoint]:
"""
Iterates over all friendly control points and find the one farthest away from the frontline
BUT! prefer Cvs. Everybody likes CVs!
"""
from_frontline = 0
cp = None
first_friendly_cp = None
for c in self.game.theater.controlpoints:
if c.is_friendly(self.is_player):
if first_friendly_cp is None:
first_friendly_cp = c
if c.is_carrier:
return c
if c.has_active_frontline:
if c.distance_to(self.front_lines().__next__()) > from_frontline:
from_frontline = c.distance_to(self.front_lines().__next__())
cp = c
# If no frontlines on the map, return the first friendly cp
if cp is None:
return first_friendly_cp
else:
return cp
def enemy_control_points(self) -> Iterator[ControlPoint]:
"""Iterates over all enemy control points."""
return (
@@ -533,7 +507,6 @@ class CoalitionMissionPlanner:
MAX_OCA_RANGE = nautical_miles(150)
MAX_SEAD_RANGE = nautical_miles(150)
MAX_STRIKE_RANGE = nautical_miles(150)
MAX_AWEC_RANGE = nautical_miles(200)
def __init__(self, game: Game, is_player: bool) -> None:
self.game = game
@@ -553,14 +526,6 @@ class CoalitionMissionPlanner:
ensure that they can be planned again next turn even if all aircraft are
eliminated this turn.
"""
# Find farthest, friendly CP for AEWC
cp = self.objective_finder.farthest_friendly_control_point()
if cp is not None:
yield ProposedMission(
cp, [ProposedFlight(FlightType.AEWC, 1, self.MAX_AWEC_RANGE)]
)
# Find friendly CPs within 100 nmi from an enemy airfield, plan CAP.
for cp in self.objective_finder.vulnerable_control_points():
# Plan three rounds of CAP to give ~90 minutes coverage. Spacing
@@ -590,23 +555,9 @@ class CoalitionMissionPlanner:
front_line,
[
ProposedFlight(FlightType.CAS, 2, self.MAX_CAS_RANGE),
# This is *not* an escort because front lines don't create a threat
# zone. Generating threat zones from front lines causes the front
# line to push back BARCAPs as it gets closer to the base. While
# front lines do have the same problem of potentially pulling
# BARCAPs off bases to engage a front line TARCAP, that's probably
# the one time where we do want that.
#
# TODO: Use intercepts and extra TARCAPs to cover bases near fronts.
# We don't have intercept missions yet so this isn't something we
# can do today, but we should probably return to having the front
# line project a threat zone (so that strike missions will route
# around it) and instead *not plan* a BARCAP at bases near the
# front, since there isn't a place to put a barrier. Instead, the
# aircraft that would have been a BARCAP could be used as additional
# interceptors and TARCAPs which will defend the base but won't be
# trying to avoid front line contacts.
ProposedFlight(FlightType.TARCAP, 2, self.MAX_CAP_RANGE),
ProposedFlight(
FlightType.TARCAP, 2, self.MAX_CAP_RANGE, EscortType.AirToAir
),
],
)

View File

@@ -12,8 +12,8 @@ from dcs.helicopters import (
OH_58D,
SA342L,
SA342M,
SH_60B,
UH_1H,
SH_60B,
)
from dcs.planes import (
AJS37,
@@ -22,14 +22,11 @@ from dcs.planes import (
A_10C,
A_10C_2,
A_20G,
A_50,
B_17G,
B_1B,
B_52H,
Bf_109K_4,
C_101CC,
E_2C,
E_3A,
FA_18C_hornet,
FW_190A8,
FW_190D9,
@@ -43,11 +40,9 @@ from dcs.planes import (
F_4E,
F_5E_3,
F_86F_Sabre,
I_16,
JF_17,
J_11A,
Ju_88A4,
KJ_2000,
L_39ZA,
MQ_9_Reaper,
M_2000C,
@@ -59,6 +54,7 @@ from dcs.planes import (
MiG_27K,
MiG_29A,
MiG_29G,
MiG_29K,
MiG_29S,
MiG_31,
Mirage_2000_5,
@@ -92,11 +88,13 @@ from dcs.planes import (
from dcs.unittype import FlyingType
from gen.flights.flight import FlightType
from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.f22a.f22a import F_22A
from pydcs_extensions.hercules.hercules import Hercules
from pydcs_extensions.mb339.mb339 import MB_339PAN
from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M, Rafale_B
from pydcs_extensions.su57.su57 import Su_57
from pydcs_extensions.hercules.hercules import Hercules
# All aircraft lists are in priority order. Aircraft higher in the list will be
# preferred over those lower in the list.
@@ -113,12 +111,14 @@ CAP_CAPABLE = [
F_14B,
F_14A_135_GR,
MiG_25PD,
Rafale_M,
Su_33,
Su_30,
Su_27,
J_11A,
F_15C,
MiG_29S,
MiG_29K,
MiG_29G,
MiG_29A,
F_16C_50,
@@ -155,8 +155,8 @@ CAP_CAPABLE = [
# Used for CAS (Close air support) and BAI (Battlefield Interdiction)
CAS_CAPABLE = [
A_10C_2,
B_1B,
A_10C,
B_1B,
F_14B,
F_14A_135_GR,
Su_25TM,
@@ -165,6 +165,8 @@ CAS_CAPABLE = [
F_15E,
F_16C_50,
FA_18C_hornet,
Rafale_A_S,
Rafale_B,
Tornado_GR4,
Tornado_IDS,
JF_17,
@@ -178,7 +180,6 @@ CAS_CAPABLE = [
S_3B,
Su_34,
Su_30,
MiG_19P,
MiG_29S,
MiG_27K,
MiG_29A,
@@ -226,6 +227,8 @@ SEAD_CAPABLE = [
Tornado_IDS,
Su_25T,
Su_25TM,
Rafale_A_S,
Rafale_B,
F_4E,
A_4E_C,
AV8BNA,
@@ -273,6 +276,8 @@ STRIKE_CAPABLE = [
Tu_22M3,
F_15E,
AJS37,
Rafale_A_S,
Rafale_B,
Tornado_GR4,
F_16C_50,
FA_18C_hornet,
@@ -291,6 +296,7 @@ STRIKE_CAPABLE = [
Su_30,
Su_27,
MiG_29S,
MiG_29K,
MiG_29G,
MiG_29A,
JF_17,
@@ -327,6 +333,8 @@ ANTISHIP_CAPABLE = [
AJS37,
Tu_22M3,
FA_18C_hornet,
Rafale_A_S,
Rafale_B,
Su_24M,
Su_17M4,
JF_17,
@@ -361,13 +369,6 @@ TRANSPORT_CAPABLE = [
DRONES = [MQ_9_Reaper, RQ_1A_Predator, WingLoong_I]
AEWC_CAPABLE = [
E_3A,
E_2C,
A_50,
KJ_2000,
]
def aircraft_for_task(task: FlightType) -> List[Type[FlyingType]]:
cap_missions = (FlightType.BARCAP, FlightType.TARCAP)
@@ -391,8 +392,6 @@ def aircraft_for_task(task: FlightType) -> List[Type[FlyingType]]:
return STRIKE_CAPABLE
elif task == FlightType.ESCORT:
return CAP_CAPABLE
elif task == FlightType.AEWC:
return AEWC_CAPABLE
else:
logging.error(f"Unplannable flight type: {task}")
return []

View File

@@ -20,15 +20,6 @@ if TYPE_CHECKING:
class FlightType(Enum):
"""Enumeration of mission types.
The value of each enumeration is the name that will be shown in the UI.
These values are persisted to the save game as well since they are a part of
each flight and thus a part of the ATO, so changing these values will break
save compat.
"""
TARCAP = "TARCAP"
BARCAP = "BARCAP"
CAS = "CAS"
@@ -42,7 +33,6 @@ class FlightType(Enum):
SWEEP = "Fighter sweep"
OCA_RUNWAY = "OCA/Runway"
OCA_AIRCRAFT = "OCA/Aircraft"
AEWC = "AEW&C"
def __str__(self) -> str:
return self.value

View File

@@ -15,8 +15,6 @@ from datetime import timedelta
from functools import cached_property
from typing import Iterator, List, Optional, Set, TYPE_CHECKING, Tuple
from dcs.planes import E_3A, E_2C, A_50, KJ_2000
from dcs.mapping import Point
from dcs.unit import Unit
from shapely.geometry import Point as ShapelyPoint
@@ -31,7 +29,7 @@ from game.theater import (
TheaterGroundObject,
)
from game.theater.theatergroundobject import EwrGroundObject
from game.utils import Distance, Speed, feet, meters, nautical_miles
from game.utils import Distance, Speed, meters, nautical_miles
from .closestairfields import ObjectiveDistanceCache
from .flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
from .traveltime import GroundSpeed, TravelTime
@@ -280,11 +278,11 @@ class LoiterFlightPlan(FlightPlan):
travel_time = super().travel_time_between_waypoints(a, b)
if a != self.hold:
return travel_time
return travel_time + self.hold_duration
@property
def mission_departure_time(self) -> timedelta:
raise NotImplementedError
try:
return travel_time + self.hold_duration
except AttributeError:
# Save compat for 2.3.
return travel_time + timedelta(minutes=5)
@dataclass(frozen=True)
@@ -696,45 +694,6 @@ class SweepFlightPlan(LoiterFlightPlan):
return self.sweep_end_time
@dataclass(frozen=True)
class AwacsFlightPlan(LoiterFlightPlan):
takeoff: FlightWaypoint
nav_to: List[FlightWaypoint]
nav_from: List[FlightWaypoint]
land: FlightWaypoint
divert: Optional[FlightWaypoint]
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
yield self.takeoff
yield from self.nav_to
yield self.hold
yield from self.nav_from
yield self.land
if self.divert is not None:
yield self.divert
@property
def mission_start_time(self) -> Optional[timedelta]:
return self.takeoff_time()
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> Optional[timedelta]:
if waypoint == self.hold:
return self.package.time_over_target
return None
@property
def tot_waypoint(self) -> Optional[FlightWaypoint]:
return self.hold
@property
def push_time(self) -> timedelta:
return self.package.time_over_target + self.hold_duration
@property
def mission_departure_time(self) -> timedelta:
return self.push_time
@dataclass(frozen=True)
class CustomFlightPlan(FlightPlan):
custom_waypoints: List[FlightWaypoint]
@@ -800,17 +759,7 @@ class FlightPlanBuilder:
raise RuntimeError("Flight must be a part of the package")
if self.package.waypoints is None:
self.regenerate_package_waypoints()
from game.navmesh import NavMeshError
try:
flight.flight_plan = self.generate_flight_plan(flight, custom_targets)
except NavMeshError as ex:
color = "blue" if self.is_player else "red"
raise PlanningError(
f"Could not plan {color} {flight.flight_type.value} from "
f"{flight.departure} to {flight.package.target}"
) from ex
flight.flight_plan = self.generate_flight_plan(flight, custom_targets)
def generate_flight_plan(
self, flight: Flight, custom_targets: Optional[List[Unit]]
@@ -841,8 +790,6 @@ class FlightPlanBuilder:
return self.generate_sweep(flight)
elif task == FlightType.TARCAP:
return self.generate_tarcap(flight)
elif task == FlightType.AEWC:
return self.generate_aewc(flight)
raise PlanningError(f"{task} flight plan generation not implemented")
def regenerate_package_waypoints(self) -> None:
@@ -973,47 +920,6 @@ class FlightPlanBuilder:
flight, location, FlightWaypointType.INGRESS_STRIKE, targets
)
def generate_aewc(self, flight: Flight) -> AwacsFlightPlan:
"""Generate a AWACS flight at a given location.
Args:
flight: The flight to generate the flight plan for.
"""
location = self.package.target
start = self.aewc_orbit(location)
# As high as possible to maximize detection and on-station time.
if flight.unit_type == E_2C:
patrol_alt = feet(30000)
elif flight.unit_type == E_3A:
patrol_alt = feet(35000)
elif flight.unit_type == A_50:
patrol_alt = feet(33000)
elif flight.unit_type == KJ_2000:
patrol_alt = feet(40000)
else:
patrol_alt = feet(25000)
builder = WaypointBuilder(flight, self.game, self.is_player)
start = builder.orbit(start, patrol_alt)
return AwacsFlightPlan(
package=self.package,
flight=flight,
takeoff=builder.takeoff(flight.departure),
nav_to=builder.nav_path(
flight.departure.position, start.position, patrol_alt
),
nav_from=builder.nav_path(
start.position, flight.arrival.position, patrol_alt
),
land=builder.land(flight.arrival),
divert=builder.divert(flight.divert),
hold=start,
hold_duration=timedelta(hours=4),
)
def generate_bai(self, flight: Flight) -> StrikeFlightPlan:
"""Generates a BAI flight plan.
@@ -1027,8 +933,7 @@ class FlightPlanBuilder:
targets: List[StrikeTarget] = []
for group in location.groups:
if group.units:
targets.append(StrikeTarget(f"{group.name} at {location.name}", group))
targets.append(StrikeTarget(f"{group.name} at {location.name}", group))
return self.strike_flightplan(
flight, location, FlightWaypointType.INGRESS_BAI, targets
@@ -1197,22 +1102,6 @@ class FlightPlanBuilder:
start = end.point_from_heading(heading - 180, diameter)
return start, end
def aewc_orbit(self, location: MissionTarget) -> Point:
# in threat zone
if self.threat_zones.threatened(location.position):
# Borderpoint
closest_boundary = self.threat_zones.closest_boundary(location.position)
# Heading + Distance to border point
heading = location.position.heading_between_point(closest_boundary)
distance = location.position.distance_to_point(closest_boundary)
return location.position.point_from_heading(heading, distance)
# this Part is fine. No threat zone, just use our point
else:
return location.position
def racetrack_for_frontline(
self, origin: Point, front_line: FrontLine
) -> Tuple[Point, Point]:

View File

@@ -14,7 +14,7 @@ from typing import (
from dcs.mapping import Point
from dcs.unit import Unit
from dcs.unitgroup import Group, VehicleGroup
from dcs.unitgroup import VehicleGroup
if TYPE_CHECKING:
from game import Game
@@ -32,7 +32,7 @@ from .flight import Flight, FlightWaypoint, FlightWaypointType
@dataclass(frozen=True)
class StrikeTarget:
name: str
target: Union[VehicleGroup, TheaterGroundObject, Unit, Group]
target: Union[VehicleGroup, TheaterGroundObject, Unit]
class WaypointBuilder:
@@ -161,10 +161,8 @@ class WaypointBuilder:
FlightWaypointType.JOIN,
position.x,
position.y,
meters(80) if self.is_helo else self.doctrine.ingress_altitude,
meters(500) if self.is_helo else self.doctrine.ingress_altitude,
)
if self.is_helo:
waypoint.alt_type = "RADIO"
waypoint.pretty_name = "Join"
waypoint.description = "Rendezvous with package"
waypoint.name = "JOIN"
@@ -175,10 +173,8 @@ class WaypointBuilder:
FlightWaypointType.SPLIT,
position.x,
position.y,
meters(80) if self.is_helo else self.doctrine.ingress_altitude,
meters(500) if self.is_helo else self.doctrine.ingress_altitude,
)
if self.is_helo:
waypoint.alt_type = "RADIO"
waypoint.pretty_name = "Split"
waypoint.description = "Depart from package"
waypoint.name = "SPLIT"
@@ -194,10 +190,8 @@ class WaypointBuilder:
ingress_type,
position.x,
position.y,
meters(50) if self.is_helo else self.doctrine.ingress_altitude,
meters(500) if self.is_helo else self.doctrine.ingress_altitude,
)
if self.is_helo:
waypoint.alt_type = "RADIO"
waypoint.pretty_name = "INGRESS on " + objective.name
waypoint.description = "INGRESS on " + objective.name
waypoint.name = "INGRESS"
@@ -210,10 +204,8 @@ class WaypointBuilder:
FlightWaypointType.EGRESS,
position.x,
position.y,
meters(50) if self.is_helo else self.doctrine.ingress_altitude,
meters(500) if self.is_helo else self.doctrine.ingress_altitude,
)
if self.is_helo:
waypoint.alt_type = "RADIO"
waypoint.pretty_name = "EGRESS from " + target.name
waypoint.description = "EGRESS from " + target.name
waypoint.name = "EGRESS"
@@ -294,7 +286,7 @@ class WaypointBuilder:
FlightWaypointType.CAS,
position.x,
position.y,
meters(50) if self.is_helo else meters(1000),
meters(500) if self.is_helo else meters(1000),
)
waypoint.alt_type = "RADIO"
waypoint.description = "Provide CAS"
@@ -349,21 +341,6 @@ class WaypointBuilder:
self.race_track_end(end, altitude),
)
@staticmethod
def orbit(start: Point, altitude: Distance) -> FlightWaypoint:
"""Creates an circular orbit point.
Args:
start: Position of the waypoint.
altitude: Altitude of the racetrack.
"""
waypoint = FlightWaypoint(FlightWaypointType.LOITER, start.x, start.y, altitude)
waypoint.name = "ORBIT"
waypoint.description = "Anchor and hold at this point"
waypoint.pretty_name = "Orbit"
return waypoint
@staticmethod
def sweep_start(position: Point, altitude: Distance) -> FlightWaypoint:
"""Creates a sweep start waypoint.
@@ -430,10 +407,8 @@ class WaypointBuilder:
FlightWaypointType.TARGET_GROUP_LOC,
target.position.x,
target.position.y,
meters(50) if self.is_helo else self.doctrine.ingress_altitude,
meters(500) if self.is_helo else self.doctrine.ingress_altitude,
)
if self.is_helo:
waypoint.alt_type = "RADIO"
waypoint.name = "TARGET"
waypoint.description = "Escort the package"
waypoint.pretty_name = "Target area"

View File

@@ -14,16 +14,16 @@ TYPE_TANKS = [
Armor.MBT_Challenger_II,
Armor.MBT_M1A2_Abrams,
Armor.MBT_M60A3_Patton,
Armor.MBT_Merkava_IV,
Armor.MBT_Merkava_Mk__4,
Armor.ZTZ_96B,
# WW2
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G,
Armor.MT_PzIV_H,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
Armor.HT_Pz_Kpfw_VI_Tiger_I,
Armor.HT_Pz_Kpfw_VI_Ausf__B_Tiger_II,
Armor.MT_M4_Sherman,
Armor.MT_M4A4_Sherman_Firefly,
Armor.SPG_StuG_IV,
Armor.StuG_IV,
Armor.CT_Centaur_IV,
Armor.CT_Cromwell_IV,
Armor.HIT_Churchill_VII,
@@ -40,14 +40,14 @@ TYPE_TANKS = [
]
TYPE_ATGM = [
Armor.ATGM_HMMWV,
Armor.ATGM_Stryker,
Armor.ATGM_M1045_HMMWV_TOW,
Armor.ATGM_M1134_Stryker,
Armor.IFV_BMP_2,
# WW2 (Tank Destroyers)
Unarmed.Carrier_M30_Cargo,
Armor.SPG_Jagdpanzer_IV,
Armor.SPG_Jagdpanther_G1,
Armor.SPG_M10_GMC,
Armor.M30_Cargo_Carrier,
Armor.TD_Jagdpanzer_IV,
Armor.TD_Jagdpanther_G1,
Armor.TD_M10_GMC,
# Mods
frenchpack.VBAE_CRAB_MMP,
frenchpack.VAB_MEPHISTO,
@@ -59,17 +59,17 @@ TYPE_IFV = [
Armor.IFV_BMP_2,
Armor.IFV_BMP_1,
Armor.IFV_Marder,
Armor.IFV_Warrior,
Armor.IFV_MCV_80,
Armor.IFV_LAV_25,
Armor.SPG_Stryker_MGS,
Armor.IFV_Sd_Kfz_234_2_Puma,
Armor.SPG_M1128_Stryker_MGS,
Armor.AC_Sd_Kfz_234_2_Puma,
Armor.IFV_M2A2_Bradley,
Armor.IFV_BMD_1,
Armor.ZBD_04A,
# WW2
Armor.IFV_Sd_Kfz_234_2_Puma,
Armor.Car_M8_Greyhound_Armored,
Armor.Car_Daimler_Armored,
Armor.AC_Sd_Kfz_234_2_Puma,
Armor.LAC_M8_Greyhound,
Armor.Daimler_Armoured_Car,
# Mods
frenchpack.ERC_90,
frenchpack.VBAE_CRAB,
@@ -77,23 +77,23 @@ TYPE_IFV = [
]
TYPE_APC = [
Armor.APC_HMMWV__Scout,
Armor.IFV_M1126_Stryker_ICV,
Armor.APC_M1043_HMMWV_Armament,
Armor.APC_M1126_Stryker_ICV,
Armor.APC_M113,
Armor.APC_BTR_80,
Armor.APC_BTR_82A,
Armor.APC_MTLB,
Armor.APC_M2A1_Halftrack,
Armor.APC_Cobra__Scout,
Armor.APC_Sd_Kfz_251_Halftrack,
Armor.APC_AAV_7_Amphibious,
Armor.APC_TPz_Fuchs,
Armor.IFV_BRDM_2,
Armor.APC_BTR_RD,
Artillery.Grad_MRL_FDDM__FC,
Armor.APC_M2A1,
Armor.APC_Cobra,
Armor.APC_Sd_Kfz_251,
Armor.APC_AAV_7,
Armor.TPz_Fuchs,
Armor.ARV_BRDM_2,
Armor.ARV_BTR_RD,
Armor.FDDM_Grad,
# WW2
Armor.APC_M2A1_Halftrack,
Armor.APC_Sd_Kfz_251_Halftrack,
Armor.APC_M2A1,
Armor.APC_Sd_Kfz_251,
# Mods
frenchpack.VAB__50,
frenchpack.VBL__50,
@@ -101,82 +101,80 @@ TYPE_APC = [
]
TYPE_ARTILLERY = [
Artillery.MLRS_9A52_Smerch_HE_300mm,
Artillery.SPH_2S1_Gvozdika_122mm,
Artillery.SPH_2S3_Akatsia_152mm,
Artillery.MLRS_BM_21_Grad_122mm,
Artillery.MLRS_BM_27_Uragan_220mm,
Artillery.SPH_M109_Paladin_155mm,
Artillery.MLRS_M270_227mm,
Artillery.SPH_2S9_Nona_120mm_M,
Artillery.SPH_Dana_vz77_152mm,
Artillery.PLZ_05,
Artillery.SPH_2S19_Msta_152mm,
Artillery.MLRS_9A52_Smerch_CM_300mm,
Artillery.MLRS_9A52_Smerch,
Artillery.SPH_2S1_Gvozdika,
Artillery.SPH_2S3_Akatsia,
Artillery.MLRS_BM_21_Grad,
Artillery.MLRS_9K57_Uragan_BM_27,
Artillery.SPH_M109_Paladin,
Artillery.MLRS_M270,
Artillery.SPH_2S9_Nona,
Artillery.SpGH_Dana,
Artillery.SPH_2S19_Msta,
Artillery.MLRS_FDDM,
# WW2
Artillery.SPG_Sturmpanzer_IV_Brummbar,
Artillery.SPG_M12_GMC_155mm,
Artillery.Sturmpanzer_IV_Brummbär,
Artillery.M12_GMC,
]
TYPE_LOGI = [
Unarmed.Truck_M818_6x6,
Unarmed.Truck_KAMAZ_43101,
Unarmed.Truck_Ural_375,
Unarmed.Truck_GAZ_66,
Unarmed.Truck_GAZ_3307,
Unarmed.Truck_GAZ_3308,
Unarmed.Truck_Ural_4320_31_Arm_d,
Unarmed.Truck_Ural_4320T,
Unarmed.Truck_Opel_Blitz,
Unarmed.LUV_Kubelwagen_82,
Unarmed.Carrier_Sd_Kfz_7_Tractor,
Unarmed.LUV_Kettenrad,
Unarmed.Car_Willys_Jeep,
Unarmed.LUV_Land_Rover_109,
Unarmed.Truck_Land_Rover_101_FC,
Unarmed.Transport_M818,
Unarmed.Transport_KAMAZ_43101,
Unarmed.Transport_Ural_375,
Unarmed.Transport_GAZ_66,
Unarmed.Transport_GAZ_3307,
Unarmed.Transport_GAZ_3308,
Unarmed.Transport_Ural_4320_31_Armored,
Unarmed.Transport_Ural_4320T,
Unarmed.Blitz_3_6_6700A,
Unarmed.belwagen_82,
Unarmed.Sd_Kfz_7,
Unarmed.Sd_Kfz_2,
Unarmed.Willys_MB,
Unarmed.Land_Rover_109_S3,
Unarmed.Land_Rover_101_FC,
# Mods
frenchpack.VBL,
frenchpack.VAB,
]
TYPE_INFANTRY = [
Infantry.Insurgent_AK_74,
Infantry.Infantry_AK_74,
Infantry.Infantry_Soldier_Insurgents,
Infantry.Soldier_AK,
Infantry.Infantry_M1_Garand,
Infantry.Infantry_Mauser_98,
Infantry.Infantry_SMLE_No_4_Mk_1,
Infantry.Infantry_M4_Georgia,
Infantry.Infantry_AK_74_Rus,
Infantry.Georgian_soldier_with_M4,
Infantry.Infantry_Soldier_Rus,
Infantry.Paratrooper_AKS,
Infantry.Paratrooper_RPG_16,
Infantry.Infantry_M249,
Infantry.Soldier_M249,
Infantry.Infantry_M4,
Infantry.Infantry_RPG,
Infantry.Soldier_RPG,
]
TYPE_SHORAD = [
AirDefence.SPAAA_ZU_23_2_Mounted_Ural_375,
AirDefence.SPAAA_ZU_23_2_Insurgent_Mounted_Ural_375,
AirDefence.SPAAA_ZSU_57_2,
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish,
AirDefence.SAM_SA_8_Osa_Gecko_TEL,
AirDefence.SAM_SA_9_Strela_1_Gaskin_TEL,
AirDefence.SAM_SA_13_Strela_10M3_Gopher_TEL,
AirDefence.SAM_SA_15_Tor_Gauntlet,
AirDefence.SAM_SA_19_Tunguska_Grison,
AirDefence.AAA_ZU_23_on_Ural_375,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375,
AirDefence.AAA_ZSU_57_2,
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.SAM_SA_9_Strela_1_9P31,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3,
AirDefence.SAM_SA_15_Tor_9A331,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SPAAA_Gepard,
AirDefence.SPAAA_Vulcan_M163,
AirDefence.SAM_Linebacker___Bradley_M6,
AirDefence.AAA_Vulcan_M163,
AirDefence.SAM_Linebacker_M6,
AirDefence.SAM_Chaparral_M48,
AirDefence.SAM_Avenger__Stinger,
AirDefence.SAM_Avenger_M1097,
AirDefence.SAM_Roland_ADS,
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.AAA_8_8cm_Flak_18,
AirDefence.AAA_8_8cm_Flak_36,
AirDefence.AAA_8_8cm_Flak_37,
AirDefence.AAA_8_8cm_Flak_41,
AirDefence.AAA_40mm_Bofors,
AirDefence.AAA_S_60_57mm,
AirDefence.AAA_Bofors_40mm,
AirDefence.AAA_M1_37mm,
AirDefence.AAA_QF_3_7,
AirDefence.AA_gun_QF_3_7,
]

View File

@@ -11,10 +11,9 @@ import logging
import random
from typing import Dict, Iterator, Optional, TYPE_CHECKING, Type, List
from dcs import Mission, Point, unitgroup
from dcs import Mission, Point
from dcs.country import Country
from dcs.point import StaticPoint
from dcs.statics import fortification_map, warehouse_map, Warehouse
from dcs.statics import fortification_map, warehouse_map
from dcs.task import (
ActivateBeaconCommand,
ActivateICLSCommand,
@@ -22,7 +21,7 @@ from dcs.task import (
OptAlarmState,
FireAtPoint,
)
from dcs.unit import Ship, Unit, Vehicle, SingleHeliPad, Static
from dcs.unit import Ship, Unit, Vehicle
from dcs.unitgroup import Group, ShipGroup, StaticGroup, VehicleGroup
from dcs.unittype import StaticType, UnitType
from dcs.vehicles import vehicle_map
@@ -48,6 +47,7 @@ from .tacan import TacanBand, TacanChannel, TacanRegistry
if TYPE_CHECKING:
from game import Game
FARP_FRONTLINE_DISTANCE = 10000
AA_CP_MIN_DISTANCE = 40000
@@ -402,23 +402,20 @@ class CarrierGenerator(GenericCarrierGenerator):
def tacan_callsign(self) -> str:
# TODO: Assign these properly.
if self.control_point.name == "Carrier Strike Group 8":
return "TRU"
else:
return random.choice(
[
"STE",
"CVN",
"CVH",
"CCV",
"ACC",
"ARC",
"GER",
"ABR",
"LIN",
"TRU",
]
)
return random.choice(
[
"STE",
"CVN",
"CVH",
"CCV",
"ACC",
"ARC",
"GER",
"ABR",
"LIN",
"TRU",
]
)
class LhaGenerator(GenericCarrierGenerator):
@@ -477,48 +474,6 @@ class ShipObjectGenerator(GenericGroundObjectGenerator):
self._register_unit_group(group_def, group)
class HelipadGenerator:
"""
Generates helipads for given control point
"""
def __init__(
self,
mission: Mission,
cp: ControlPoint,
game: Game,
radio_registry: RadioRegistry,
tacan_registry: TacanRegistry,
):
self.m = mission
self.cp = cp
self.game = game
self.radio_registry = radio_registry
self.tacan_registry = tacan_registry
def generate(self) -> None:
if self.cp.captured:
country_name = self.game.player_country
else:
country_name = self.game.enemy_country
country = self.m.country(country_name)
for i, helipad in enumerate(self.cp.helipads):
name = self.cp.name + "_helipad_" + str(i)
logging.info("Generating helipad : " + name)
pad = SingleHeliPad(name=self.m.string(name + "_unit"))
pad.position = Point(helipad.x, helipad.y)
pad.heading = helipad.heading
# pad.heliport_frequency = self.radio_registry.alloc_uhf() TODO : alloc radio & callsign
sg = unitgroup.StaticGroup(self.m.next_group_id(), self.m.string(name))
sg.add_unit(pad)
sp = StaticPoint()
sp.position = pad.position
sg.add_point(sp)
country.add_static_group(sg)
class GroundObjectsGenerator:
"""Creates DCS groups and statics for the theater during mission generation.
@@ -552,10 +507,6 @@ class GroundObjectsGenerator:
country_name = self.game.enemy_country
country = self.m.country(country_name)
HelipadGenerator(
self.m, cp, self.game, self.radio_registry, self.tacan_registry
).generate()
for ground_object in cp.ground_objects:
if isinstance(ground_object, BuildingGroundObject):
generator = BuildingSiteGenerator(

View File

@@ -41,7 +41,6 @@ from .flights.flight import FlightWaypoint, FlightWaypointType
from .radios import RadioFrequency
from .runways import RunwayData
if TYPE_CHECKING:
from game import Game
@@ -49,16 +48,8 @@ if TYPE_CHECKING:
class KneeboardPageWriter:
"""Creates kneeboard images."""
def __init__(
self, page_margin: int = 24, line_spacing: int = 12, dark_theme: bool = False
) -> None:
if dark_theme:
self.foreground_fill = (215, 200, 200)
self.background_fill = (10, 5, 5)
else:
self.foreground_fill = (15, 15, 15)
self.background_fill = (255, 252, 252)
self.image = Image.new("RGB", (768, 1024), self.background_fill)
def __init__(self, page_margin: int = 24, line_spacing: int = 12) -> None:
self.image = Image.new("RGB", (768, 1024), (0xFF, 0xFF, 0xFF))
# These font sizes create a relatively full page for current sorties. If
# we start generating more complicated flight plans, or start including
# more information in the comm ladder (the latter of which we should
@@ -96,10 +87,10 @@ class KneeboardPageWriter:
self.y += height + self.line_spacing
def title(self, title: str) -> None:
self.text(title, font=self.title_font, fill=self.foreground_fill)
self.text(title, font=self.title_font)
def heading(self, text: str) -> None:
self.text(text, font=self.heading_font, fill=self.foreground_fill)
self.text(text, font=self.heading_font)
def table(
self, cells: List[List[str]], headers: Optional[List[str]] = None
@@ -107,7 +98,7 @@ class KneeboardPageWriter:
if headers is None:
headers = []
table = tabulate(cells, headers=headers, numalign="right")
self.text(table, font=self.table_font, fill=self.foreground_fill)
self.text(table, font=self.table_font)
def write(self, path: Path) -> None:
self.image.save(path)
@@ -254,7 +245,6 @@ class BriefingPage(KneeboardPage):
tankers: List[TankerInfo],
jtacs: List[JtacInfo],
start_time: datetime.datetime,
dark_kneeboard: bool,
) -> None:
self.flight = flight
self.comms = list(comms)
@@ -262,16 +252,11 @@ class BriefingPage(KneeboardPage):
self.tankers = tankers
self.jtacs = jtacs
self.start_time = start_time
self.dark_kneeboard = dark_kneeboard
self.comms.append(CommInfo("Flight", self.flight.intra_flight_channel))
def write(self, path: Path) -> None:
writer = KneeboardPageWriter(dark_theme=self.dark_kneeboard)
if self.flight.custom_name is not None:
custom_name_title = ' ("{}")'.format(self.flight.custom_name)
else:
custom_name_title = ""
writer.title(f"{self.flight.callsign} Mission Info{custom_name_title}")
writer = KneeboardPageWriter()
writer.title(f"{self.flight.callsign} Mission Info")
# TODO: Handle carriers.
writer.heading("Airfield Info")
@@ -304,34 +289,6 @@ class BriefingPage(KneeboardPage):
["Bingo", "Joker"],
)
# AEW&C
writer.heading("AEW&C")
aewc_ladder = []
for single_aewc in self.awacs:
if single_aewc.depature_location is None:
dep = "-"
arr = "-"
else:
dep = self._format_time(single_aewc.start_time)
arr = self._format_time(single_aewc.end_time)
aewc_ladder.append(
[
str(single_aewc.callsign),
str(single_aewc.freq),
str(single_aewc.depature_location),
str(dep),
str(arr),
]
)
writer.table(
aewc_ladder,
headers=["Callsign", "FREQ", "Depature", "ETD", "ETA"],
)
# Package Section
writer.heading("Comm ladder")
comm_ladder = []
@@ -340,6 +297,10 @@ class BriefingPage(KneeboardPage):
[comm.name, "", "", "", self.format_frequency(comm.freq)]
)
for a in self.awacs:
comm_ladder.append(
[a.callsign, "AWACS", "", "", self.format_frequency(a.freq)]
)
for tanker in self.tankers:
comm_ladder.append(
[
@@ -408,21 +369,12 @@ class BriefingPage(KneeboardPage):
channel_name = namer.channel_name(channel.radio_id, channel.channel)
return f"{channel_name} {frequency}"
def _format_time(self, time: Optional[datetime.timedelta]) -> str:
if time is None:
return ""
local_time = self.start_time + time
return local_time.strftime(f"%H:%M:%S")
class KneeboardGenerator(MissionInfoGenerator):
"""Creates kneeboard pages for each client flight in the mission."""
def __init__(self, mission: Mission, game: "Game") -> None:
super().__init__(mission, game)
self.dark_kneeboard = self.game.settings.generate_dark_kneeboard and (
self.mission.start_time.hour > 19 or self.mission.start_time.hour < 7
)
def generate(self) -> None:
"""Generates a kneeboard per client flight."""
@@ -466,6 +418,5 @@ class KneeboardGenerator(MissionInfoGenerator):
self.tankers,
self.jtacs,
self.mission.start_time,
self.dark_kneeboard,
),
]

View File

@@ -9,7 +9,7 @@ from gen.locations.preset_locations import PresetLocation
class PresetControlPointLocations:
"""A repository of preset locations for a given control point"""
# List of possible ashore locations to generate objects (Represented in miz file by an APC_AAV_7_Amphibious)
# List of possible ashore locations to generate objects (Represented in miz file by an APC_AAV_7)
ashore_locations: List[PresetLocation] = field(default_factory=list)
# List of possible offshore locations to generate ship groups (Represented in miz file by an Oliver Hazard Perry)

View File

@@ -44,7 +44,7 @@ class MizDataLocationFinder:
for ship_group in m.country("USA").ship_group:
if (
len(ship_group.units) > 0
and ship_group.units[0].type == ships.FFG_Oliver_Hazzard_Perry.id
and ship_group.units[0].type == ships.Oliver_Hazzard_Perry_class.id
):
offshore_locations.append(
PresetLocation(
@@ -68,8 +68,7 @@ class MizDataLocationFinder:
for vehicle_group in m.country("Iran").vehicle_group:
if (
len(vehicle_group.units) > 0
and vehicle_group.units[0].type
== MissilesSS.AShM_SS_N_2_Silkworm.id
and vehicle_group.units[0].type == MissilesSS.SS_N_2_Silkworm.id
):
antiship_locations.append(
PresetLocation(

View File

@@ -9,7 +9,7 @@ MISSILES_MAP = {"V1GroupGenerator": V1GroupGenerator, "ScudGenerator": ScudGener
def generate_missile_group(game, ground_object, faction_name: str):
"""
This generate a missiles group
This generate a ship group
:return: Nothing, but put the group reference inside the ground object
"""
faction = db.FACTIONS[faction_name]

View File

@@ -14,21 +14,21 @@ class ScudGenerator(GroupGenerator):
# Scuds
self.add_unit(
MissilesSS.SSM_SS_1C_Scud_B,
MissilesSS.SRBM_SS_1C_Scud_B_9K72_LN_9P117M,
"V1#0",
self.position.x,
self.position.y + random.randint(1, 8),
self.heading,
)
self.add_unit(
MissilesSS.SSM_SS_1C_Scud_B,
MissilesSS.SRBM_SS_1C_Scud_B_9K72_LN_9P117M,
"V1#1",
self.position.x + 50,
self.position.y + random.randint(1, 8),
self.heading,
)
self.add_unit(
MissilesSS.SSM_SS_1C_Scud_B,
MissilesSS.SRBM_SS_1C_Scud_B_9K72_LN_9P117M,
"V1#2",
self.position.x + 100,
self.position.y + random.randint(1, 8),
@@ -37,7 +37,7 @@ class ScudGenerator(GroupGenerator):
# Commander
self.add_unit(
Unarmed.LUV_UAZ_469_Jeep,
Unarmed.Transport_UAZ_469,
"Kubel#0",
self.position.x - 35,
self.position.y - 20,
@@ -46,7 +46,7 @@ class ScudGenerator(GroupGenerator):
# Shorad
self.add_unit(
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish,
AirDefence.SPAAA_ZSU_23_4_Shilka,
"SHILKA#0",
self.position.x - 55,
self.position.y - 38,
@@ -54,7 +54,7 @@ class ScudGenerator(GroupGenerator):
)
self.add_unit(
AirDefence.SAM_SA_9_Strela_1_Gaskin_TEL,
AirDefence.SAM_SA_9_Strela_1_9P31,
"STRELA#0",
self.position.x + 200,
self.position.y + 15,

View File

@@ -14,21 +14,21 @@ class V1GroupGenerator(GroupGenerator):
# Ramps
self.add_unit(
MissilesSS.SSM_V_1_Launcher,
MissilesSS.V_1_ramp,
"V1#0",
self.position.x,
self.position.y + random.randint(1, 8),
self.heading,
)
self.add_unit(
MissilesSS.SSM_V_1_Launcher,
MissilesSS.V_1_ramp,
"V1#1",
self.position.x + 50,
self.position.y + random.randint(1, 8),
self.heading,
)
self.add_unit(
MissilesSS.SSM_V_1_Launcher,
MissilesSS.V_1_ramp,
"V1#2",
self.position.x + 100,
self.position.y + random.randint(1, 8),
@@ -37,7 +37,7 @@ class V1GroupGenerator(GroupGenerator):
# Commander
self.add_unit(
Unarmed.LUV_Kubelwagen_82,
Unarmed.belwagen_82,
"Kubel#0",
self.position.x - 35,
self.position.y - 20,
@@ -46,7 +46,7 @@ class V1GroupGenerator(GroupGenerator):
# Self defense flak
flak_unit = random.choice(
[AirDefence.AAA_Flak_Vierling_38_Quad_20mm, AirDefence.AAA_Flak_38_20mm]
[AirDefence.AAA_Flak_Vierling_38, AirDefence.AAA_Flak_38]
)
self.add_unit(
@@ -58,7 +58,7 @@ class V1GroupGenerator(GroupGenerator):
)
self.add_unit(
Unarmed.Truck_Opel_Blitz,
Unarmed.Blitz_3_6_6700A,
"Blitz#0",
self.position.x + 200,
self.position.y + 15,

View File

@@ -61,7 +61,7 @@ ANIMALS = [
"MAMBA",
"DOLPHIN",
"PHEASANT",
"ARMADILLO",
"ARMADILLLO",
"RACOON",
"ZEBRA",
"COW",

View File

@@ -27,7 +27,7 @@ class BoforsGenerator(AirDefenseGroupGenerator):
for j in range(grid_y):
index = index + 1
self.add_unit(
AirDefence.AAA_40mm_Bofors,
AirDefence.AAA_Bofors_40mm,
"AAA#" + str(index),
self.position.x + spacing * i,
self.position.y + spacing * j,

View File

@@ -8,12 +8,12 @@ from gen.sam.airdefensegroupgenerator import (
)
GFLAK = [
AirDefence.AAA_Flak_Vierling_38_Quad_20mm,
AirDefence.AAA_Flak_Vierling_38,
AirDefence.AAA_8_8cm_Flak_18,
AirDefence.AAA_8_8cm_Flak_36,
AirDefence.AAA_8_8cm_Flak_37,
AirDefence.AAA_8_8cm_Flak_41,
AirDefence.AAA_Flak_38_20mm,
AirDefence.AAA_Flak_38,
]
@@ -53,7 +53,7 @@ class FlakGenerator(AirDefenseGroupGenerator):
search_pos = self.get_circular_position(random.randint(2, 3), 80)
for index, pos in enumerate(search_pos):
self.add_unit(
AirDefence.SL_Flakscheinwerfer_37,
AirDefence.Flak_Searchlight_37,
"SearchLight#" + str(index),
pos[0],
pos[1],
@@ -62,14 +62,14 @@ class FlakGenerator(AirDefenseGroupGenerator):
# Support
self.add_unit(
AirDefence.PU_Maschinensatz_33,
AirDefence.Maschinensatz_33,
"MC33#",
self.position.x - 20,
self.position.y - 20,
self.heading,
)
self.add_unit(
AirDefence.AAA_SP_Kdo_G_40,
AirDefence.AAA_Kdo_G_40,
"KDO#",
self.position.x - 25,
self.position.y - 20,
@@ -78,7 +78,7 @@ class FlakGenerator(AirDefenseGroupGenerator):
# Commander
self.add_unit(
Unarmed.LUV_Kubelwagen_82,
Unarmed.belwagen_82,
"Kubel#",
self.position.x - 35,
self.position.y - 20,
@@ -89,7 +89,7 @@ class FlakGenerator(AirDefenseGroupGenerator):
for i in range(int(max(1, grid_x / 2))):
for j in range(int(max(1, grid_x / 2))):
self.add_unit(
Unarmed.Truck_Opel_Blitz,
Unarmed.Blitz_3_6_6700A,
"BLITZ#" + str(index),
self.position.x + 125 + 15 * i + random.randint(1, 5),
self.position.y + 15 * j + random.randint(1, 5),

View File

@@ -34,7 +34,7 @@ class Flak18Generator(AirDefenseGroupGenerator):
# Add a commander truck
self.add_unit(
Unarmed.Truck_Opel_Blitz,
Unarmed.Blitz_3_6_6700A,
"Blitz#",
self.position.x - 35,
self.position.y - 20,

View File

@@ -21,7 +21,7 @@ class AllyWW2FlakGenerator(AirDefenseGroupGenerator):
positions = self.get_circular_position(4, launcher_distance=30, coverage=360)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.AAA_QF_3_7,
AirDefence.AA_gun_QF_3_7,
"AA#" + str(i),
position[0],
position[1],
@@ -41,7 +41,7 @@ class AllyWW2FlakGenerator(AirDefenseGroupGenerator):
positions = self.get_circular_position(8, launcher_distance=90, coverage=360)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.AAA_M45_Quadmount_HB_12_7mm,
AirDefence.AAA_M45_Quadmount,
"AA#" + str(12 + i),
position[0],
position[1],
@@ -50,28 +50,28 @@ class AllyWW2FlakGenerator(AirDefenseGroupGenerator):
# Add a commander truck
self.add_unit(
Unarmed.Car_Willys_Jeep,
Unarmed.Willys_MB,
"CMD#1",
self.position.x,
self.position.y - 20,
random.randint(0, 360),
)
self.add_unit(
Unarmed.Carrier_M30_Cargo,
Armor.M30_Cargo_Carrier,
"LOG#1",
self.position.x,
self.position.y + 20,
random.randint(0, 360),
)
self.add_unit(
Unarmed.Tractor_M4_Hi_Speed,
Armor.M4_Tractor,
"LOG#2",
self.position.x + 20,
self.position.y,
random.randint(0, 360),
)
self.add_unit(
Unarmed.Truck_Bedford,
Unarmed.Bedford_MWD,
"LOG#3",
self.position.x - 20,
self.position.y,

View File

@@ -21,7 +21,7 @@ class ZSU57Generator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SPAAA_ZSU_57_2,
AirDefence.AAA_ZSU_57_2,
"SPAA#" + str(i),
position[0],
position[1],

View File

@@ -27,7 +27,7 @@ class ZU23InsurgentGenerator(AirDefenseGroupGenerator):
for j in range(grid_y):
index = index + 1
self.add_unit(
AirDefence.AAA_ZU_23_Closed_Emplacement_Insurgent,
AirDefence.AAA_ZU_23_Insurgent_Closed,
"AAA#" + str(index),
self.position.x + spacing * i,
self.position.y + spacing * j,

View File

@@ -12,13 +12,13 @@ from gen.sam.group_generator import GroupGenerator
class EarlyColdWarFlakGenerator(AirDefenseGroupGenerator):
"""
This generator attempt to mimic an early cold-war era flak AAA site.
The Flak 18 88mm is used as the main long range gun, S-60 is used as a mid range gun and 2 Bofors 40mm guns provide short range protection.
The Flak 18 88mm is used as the main long range gun and 2 Bofors 40mm guns provide short range protection.
This does not include search lights and telemeter computer (Kdo.G 40) because these are paid units only available in WW2 asset pack
"""
name = "Early Cold War Flak Site"
price = 74
price = 58
def generate(self):
@@ -37,41 +37,25 @@ class EarlyColdWarFlakGenerator(AirDefenseGroupGenerator):
self.heading,
)
# Medium range guns
# Short range guns
self.add_unit(
AirDefence.AAA_S_60_57mm,
AirDefence.AAA_Bofors_40mm,
"SHO#1",
self.position.x - 40,
self.position.y - 40,
self.heading + 180,
),
self.add_unit(
AirDefence.AAA_S_60_57mm,
AirDefence.AAA_Bofors_40mm,
"SHO#2",
self.position.x + spacing * 2 + 40,
self.position.y + spacing + 40,
self.heading,
),
# Short range guns
self.add_unit(
AirDefence.AAA_ZU_23_Closed_Emplacement,
"SHO#3",
self.position.x - 80,
self.position.y - 40,
self.heading + 180,
),
self.add_unit(
AirDefence.AAA_ZU_23_Closed_Emplacement,
"SHO#4",
self.position.x + spacing * 2 + 80,
self.position.y + spacing + 40,
self.heading,
),
# Add a truck
self.add_unit(
Unarmed.Truck_KAMAZ_43101,
Unarmed.Transport_KAMAZ_43101,
"Truck#",
self.position.x - 60,
self.position.y - 20,
@@ -86,7 +70,7 @@ class EarlyColdWarFlakGenerator(AirDefenseGroupGenerator):
class ColdWarFlakGenerator(AirDefenseGroupGenerator):
"""
This generator attempt to mimic a cold-war era flak AAA site.
The Flak 18 88mm is used as the main long range gun, 2 S-60 57mm gun improve mid range firepower, while 2 Zu-23 guns even provide short range protection.
The Flak 18 88mm is used as the main long range gun while 2 Zu-23 guns provide short range protection.
The site is also fitted with a P-19 radar for early detection.
"""
@@ -110,41 +94,25 @@ class ColdWarFlakGenerator(AirDefenseGroupGenerator):
self.heading,
)
# Medium range guns
# Short range guns
self.add_unit(
AirDefence.AAA_S_60_57mm,
AirDefence.AAA_ZU_23_Closed,
"SHO#1",
self.position.x - 40,
self.position.y - 40,
self.heading + 180,
),
self.add_unit(
AirDefence.AAA_S_60_57mm,
AirDefence.AAA_ZU_23_Closed,
"SHO#2",
self.position.x + spacing * 2 + 40,
self.position.y + spacing + 40,
self.heading,
),
# Short range guns
self.add_unit(
AirDefence.AAA_ZU_23_Closed_Emplacement,
"SHO#3",
self.position.x - 80,
self.position.y - 40,
self.heading + 180,
),
self.add_unit(
AirDefence.AAA_ZU_23_Closed_Emplacement,
"SHO#4",
self.position.x + spacing * 2 + 80,
self.position.y + spacing + 40,
self.heading,
),
# Add a P19 Radar for EWR
self.add_unit(
AirDefence.SAM_P19_Flat_Face_SR__SA_2_3,
AirDefence.SAM_SR_P_19,
"SR#0",
self.position.x - 60,
self.position.y - 20,

View File

@@ -1,63 +0,0 @@
import random
from typing import List, Optional, Type
from dcs.unitgroup import VehicleGroup
from game import Game
from game.factions.faction import Faction
from game.theater.theatergroundobject import EwrGroundObject
from gen.sam.ewrs import (
BigBirdGenerator,
BoxSpringGenerator,
DogEarGenerator,
FlatFaceGenerator,
HawkEwrGenerator,
PatriotEwrGenerator,
RolandEwrGenerator,
SnowDriftGenerator,
StraightFlushGenerator,
TallRackGenerator,
)
from gen.sam.group_generator import GroupGenerator
EWR_MAP = {
"BoxSpringGenerator": BoxSpringGenerator,
"TallRackGenerator": TallRackGenerator,
"DogEarGenerator": DogEarGenerator,
"RolandEwrGenerator": RolandEwrGenerator,
"FlatFaceGenerator": FlatFaceGenerator,
"PatriotEwrGenerator": PatriotEwrGenerator,
"BigBirdGenerator": BigBirdGenerator,
"SnowDriftGenerator": SnowDriftGenerator,
"StraightFlushGenerator": StraightFlushGenerator,
"HawkEwrGenerator": HawkEwrGenerator,
}
def get_faction_possible_ewrs_generator(
faction: Faction,
) -> List[Type[GroupGenerator]]:
"""
Return the list of possible EWR generators for the given faction
:param faction: Faction name to search units for
"""
return [EWR_MAP[s] for s in faction.ewrs]
def generate_ewr_group(
game: Game, ground_object: EwrGroundObject, faction: Faction
) -> Optional[VehicleGroup]:
"""Generates an early warning radar group.
:param game: The Game.
:param ground_object: The ground object which will own the EWR group.
:param faction: Owner faction.
:return: The generated group, or None if one could not be generated.
"""
generators = get_faction_possible_ewrs_generator(faction)
if len(generators) > 0:
generator_class = random.choice(generators)
generator = generator_class(game, ground_object)
generator.generate()
return generator.get_generated_group()
return None

View File

@@ -33,7 +33,7 @@ class DogEarGenerator(EwrGenerator):
This is the SA-8 search radar, but used as an early warning radar.
"""
unit_type = AirDefence.MCC_SR_Sborka_Dog_Ear_SR
unit_type = AirDefence.CP_9S80M1_Sborka
class RolandEwrGenerator(EwrGenerator):
@@ -51,7 +51,7 @@ class FlatFaceGenerator(EwrGenerator):
This is the SA-3 search radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_P19_Flat_Face_SR__SA_2_3
unit_type = AirDefence.SAM_SR_P_19
class PatriotEwrGenerator(EwrGenerator):
@@ -60,7 +60,7 @@ class PatriotEwrGenerator(EwrGenerator):
This is the Patriot search/track radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_Patriot_STR
unit_type = AirDefence.SAM_Patriot_STR_AN_MPQ_53
class BigBirdGenerator(EwrGenerator):
@@ -69,7 +69,7 @@ class BigBirdGenerator(EwrGenerator):
This is the SA-10 track radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR
unit_type = AirDefence.SAM_SA_10_S_300PS_SR_64H6E
class SnowDriftGenerator(EwrGenerator):
@@ -78,7 +78,7 @@ class SnowDriftGenerator(EwrGenerator):
This is the SA-11 search radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_SA_11_Buk_Gadfly_Snow_Drift_SR
unit_type = AirDefence.SAM_SA_11_Buk_SR_9S18M1
class StraightFlushGenerator(EwrGenerator):
@@ -87,7 +87,7 @@ class StraightFlushGenerator(EwrGenerator):
This is the SA-6 search/track radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_SA_6_Kub_Long_Track_STR
unit_type = AirDefence.SAM_SA_6_Kub_STR_9S91
class HawkEwrGenerator(EwrGenerator):
@@ -96,4 +96,4 @@ class HawkEwrGenerator(EwrGenerator):
This is the Hawk search radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_Hawk_SR__AN_MPQ_50
unit_type = AirDefence.SAM_Hawk_SR_AN_MPQ_50

View File

@@ -28,7 +28,7 @@ class FreyaGenerator(AirDefenseGroupGenerator):
positions = self.get_circular_position(4, launcher_distance=50, coverage=360)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.AAA_Flak_Vierling_38_Quad_20mm,
AirDefence.AAA_Flak_Vierling_38,
"AA#" + str(i),
position[0],
position[1],
@@ -47,37 +47,37 @@ class FreyaGenerator(AirDefenseGroupGenerator):
# Command/Logi
self.add_unit(
Unarmed.LUV_Kubelwagen_82,
Unarmed.belwagen_82,
"Kubel#1",
self.position.x - 20,
self.position.y - 20,
self.heading,
)
self.add_unit(
Unarmed.Carrier_Sd_Kfz_7_Tractor,
Unarmed.Sd_Kfz_7,
"Sdkfz#1",
self.position.x + 20,
self.position.y + 22,
self.heading,
)
self.add_unit(
Unarmed.LUV_Kettenrad,
Unarmed.Sd_Kfz_2,
"Sdkfz#2",
self.position.x - 22,
self.position.y + 20,
self.heading,
)
# PU_Maschinensatz_33 and Kdo.g 40 Telemeter
# Maschinensatz_33 and Kdo.g 40 Telemeter
self.add_unit(
AirDefence.PU_Maschinensatz_33,
AirDefence.Maschinensatz_33,
"Energy#1",
self.position.x + 20,
self.position.y - 20,
self.heading,
)
self.add_unit(
AirDefence.AAA_SP_Kdo_G_40,
AirDefence.AAA_Kdo_G_40,
"Telemeter#1",
self.position.x + 20,
self.position.y - 10,

View File

@@ -20,7 +20,7 @@ class AvengerGenerator(AirDefenseGroupGenerator):
num_launchers = random.randint(2, 3)
self.add_unit(
Unarmed.Truck_M818_6x6,
Unarmed.Transport_M818,
"TRUCK",
self.position.x,
self.position.y,
@@ -31,7 +31,7 @@ class AvengerGenerator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_Avenger__Stinger,
AirDefence.SAM_Avenger_M1097,
"SPAA#" + str(i),
position[0],
position[1],

View File

@@ -20,7 +20,7 @@ class ChaparralGenerator(AirDefenseGroupGenerator):
num_launchers = random.randint(2, 4)
self.add_unit(
Unarmed.Truck_M818_6x6,
Unarmed.Transport_M818,
"TRUCK",
self.position.x,
self.position.y,

View File

@@ -33,7 +33,7 @@ class GepardGenerator(AirDefenseGroupGenerator):
self.heading,
)
self.add_unit(
Unarmed.Truck_M818_6x6,
Unarmed.Transport_M818,
"TRUCK",
self.position.x + 80,
self.position.y,

View File

@@ -6,6 +6,7 @@ from dcs.vehicles import AirDefence
from game import Game
from game.factions.faction import Faction
from game.theater import TheaterGroundObject
from game.theater.theatergroundobject import SamGroundObject
from gen.sam.aaa_bofors import BoforsGenerator
from gen.sam.aaa_flak import FlakGenerator
@@ -22,7 +23,20 @@ from gen.sam.cold_war_flak import (
ColdWarFlakGenerator,
EarlyColdWarFlakGenerator,
)
from gen.sam.ewrs import (
BigBirdGenerator,
BoxSpringGenerator,
DogEarGenerator,
FlatFaceGenerator,
HawkEwrGenerator,
PatriotEwrGenerator,
RolandEwrGenerator,
SnowDriftGenerator,
StraightFlushGenerator,
TallRackGenerator,
)
from gen.sam.freya_ewr import FreyaGenerator
from gen.sam.group_generator import GroupGenerator
from gen.sam.sam_avenger import AvengerGenerator
from gen.sam.sam_chaparral import ChaparralGenerator
from gen.sam.sam_gepard import GepardGenerator
@@ -105,39 +119,52 @@ SAM_MAP: Dict[str, Type[AirDefenseGroupGenerator]] = {
SAM_PRICES = {
AirDefence.SAM_Hawk_Generator__PCP: 35,
AirDefence.SAM_Hawk_PCP: 35,
AirDefence.AAA_ZU_23_Emplacement: 10,
AirDefence.AAA_ZU_23_Closed_Emplacement: 10,
AirDefence.SPAAA_ZU_23_2_Mounted_Ural_375: 10,
AirDefence.SPAAA_ZU_23_2_Insurgent_Mounted_Ural_375: 10,
AirDefence.AAA_ZU_23_Closed_Emplacement_Insurgent: 10,
AirDefence.AAA_ZU_23_Closed: 10,
AirDefence.AAA_ZU_23_on_Ural_375: 10,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375: 10,
AirDefence.AAA_ZU_23_Insurgent_Closed: 10,
AirDefence.AAA_ZU_23_Insurgent: 10,
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish: 10,
AirDefence.SPAAA_Vulcan_M163: 15,
AirDefence.SAM_Linebacker___Bradley_M6: 20,
AirDefence.SAM_Rapier_LN: 20,
AirDefence.SAM_Avenger__Stinger: 22,
AirDefence.SPAAA_ZSU_23_4_Shilka: 10,
AirDefence.AAA_Vulcan_M163: 15,
AirDefence.SAM_Linebacker_M6: 20,
AirDefence.Rapier_FSA_Launcher: 20,
AirDefence.SAM_Avenger_M1097: 22,
AirDefence.SPAAA_Gepard: 24,
AirDefence.SAM_Roland_ADS: 40,
AirDefence.SAM_Patriot_LN: 85,
AirDefence.SAM_Patriot_LN_M901: 85,
AirDefence.SAM_Patriot_EPP_III: 85,
AirDefence.SAM_Chaparral_M48: 25,
AirDefence.AAA_40mm_Bofors: 15,
AirDefence.AAA_Bofors_40mm: 15,
AirDefence.AAA_8_8cm_Flak_36: 15,
AirDefence.SAM_SA_2_S_75_Guideline_LN: 30,
AirDefence.SAM_SA_3_S_125_Goa_LN: 35,
AirDefence.SAM_SA_6_Kub_Gainful_TEL: 45,
AirDefence.SAM_SA_8_Osa_Gecko_TEL: 30,
AirDefence.SAM_SA_9_Strela_1_Gaskin_TEL: 25,
AirDefence.SAM_SA_10_S_300_Grumble_TEL_C: 80,
AirDefence.SAM_SA_10_S_300_Grumble_C2: 80,
AirDefence.SAM_SA_11_Buk_Gadfly_Fire_Dome_TEL: 60,
AirDefence.SAM_SA_13_Strela_10M3_Gopher_TEL: 30,
AirDefence.SAM_SA_15_Tor_Gauntlet: 40,
AirDefence.SAM_SA_19_Tunguska_Grison: 35,
AirDefence.SAM_SA_2_LN_SM_90: 30,
AirDefence.SAM_SA_3_S_125_LN_5P73: 35,
AirDefence.SAM_SA_6_Kub_LN_2P25: 45,
AirDefence.SAM_SA_8_Osa_9A33: 30,
AirDefence.SAM_SA_9_Strela_1_9P31: 25,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: 80,
AirDefence.SAM_SA_10_S_300PS_CP_54K6: 80,
AirDefence.SAM_SA_11_Buk_LN_9A310M1: 60,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3: 30,
AirDefence.SAM_SA_15_Tor_9A331: 40,
AirDefence.SAM_SA_19_Tunguska_2S6: 35,
AirDefence.HQ_7_Self_Propelled_LN: 35,
}
EWR_MAP = {
"BoxSpringGenerator": BoxSpringGenerator,
"TallRackGenerator": TallRackGenerator,
"DogEarGenerator": DogEarGenerator,
"RolandEwrGenerator": RolandEwrGenerator,
"FlatFaceGenerator": FlatFaceGenerator,
"PatriotEwrGenerator": PatriotEwrGenerator,
"BigBirdGenerator": BigBirdGenerator,
"SnowDriftGenerator": SnowDriftGenerator,
"StraightFlushGenerator": StraightFlushGenerator,
"HawkEwrGenerator": HawkEwrGenerator,
}
def get_faction_possible_sams_generator(
faction: Faction,
@@ -149,6 +176,14 @@ def get_faction_possible_sams_generator(
return [SAM_MAP[s] for s in faction.air_defenses]
def get_faction_possible_ewrs_generator(faction: Faction) -> List[Type[GroupGenerator]]:
"""
Return the list of possible SAM generator for the given faction
:param faction: Faction name to search units for
"""
return [EWR_MAP[s] for s in faction.ewrs]
def _generate_anti_air_from(
generators: Sequence[Type[AirDefenseGroupGenerator]],
game: Game,
@@ -201,3 +236,22 @@ def generate_anti_air_group(
if groups:
return groups
return []
def generate_ewr_group(
game: Game, ground_object: TheaterGroundObject, faction: Faction
) -> Optional[VehicleGroup]:
"""Generates an early warning radar group.
:param game: The Game.
:param ground_object: The ground object which will own the EWR group.
:param faction: Owner faction.
:return: The generated group, or None if one could not be generated.
"""
generators = get_faction_possible_ewrs_generator(faction)
if len(generators) > 0:
generator_class = random.choice(generators)
generator = generator_class(game, ground_object)
generator.generate()
return generator.get_generated_group()
return None

View File

@@ -19,21 +19,21 @@ class HawkGenerator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_Hawk_SR__AN_MPQ_50,
AirDefence.SAM_Hawk_SR_AN_MPQ_50,
"SR",
self.position.x + 20,
self.position.y,
self.heading,
)
self.add_unit(
AirDefence.SAM_Hawk_Generator__PCP,
AirDefence.SAM_Hawk_PCP,
"PCP",
self.position.x,
self.position.y,
self.heading,
)
self.add_unit(
AirDefence.SAM_Hawk_TR__AN_MPQ_46,
AirDefence.SAM_Hawk_TR_AN_MPQ_46,
"TR",
self.position.x + 40,
self.position.y,
@@ -44,7 +44,7 @@ class HawkGenerator(AirDefenseGroupGenerator):
aa_group = self.add_auxiliary_group("AA")
self.add_unit_to_group(
aa_group,
AirDefence.SPAAA_Vulcan_M163,
AirDefence.AAA_Vulcan_M163,
"AAA",
self.position + Point(20, 30),
self.heading,

View File

@@ -37,14 +37,14 @@ class HQ7Generator(AirDefenseGroupGenerator):
aa_group = self.add_auxiliary_group("AA")
self.add_unit_to_group(
aa_group,
AirDefence.SPAAA_ZU_23_2_Mounted_Ural_375,
AirDefence.AAA_ZU_23_on_Ural_375,
"AAA1",
self.position + Point(20, 30),
self.heading,
)
self.add_unit_to_group(
aa_group,
AirDefence.SPAAA_ZU_23_2_Mounted_Ural_375,
AirDefence.AAA_ZU_23_on_Ural_375,
"AAA2",
self.position - Point(20, 30),
self.heading,

View File

@@ -20,7 +20,7 @@ class LinebackerGenerator(AirDefenseGroupGenerator):
num_launchers = random.randint(2, 4)
self.add_unit(
Unarmed.Truck_M818_6x6,
Unarmed.Transport_M818,
"TRUCK",
self.position.x,
self.position.y,
@@ -31,7 +31,7 @@ class LinebackerGenerator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_Linebacker___Bradley_M6,
AirDefence.SAM_Linebacker_M6,
"M6#" + str(i),
position[0],
position[1],

View File

@@ -20,28 +20,28 @@ class PatriotGenerator(AirDefenseGroupGenerator):
def generate(self):
# Command Post
self.add_unit(
AirDefence.SAM_Patriot_STR,
AirDefence.SAM_Patriot_STR_AN_MPQ_53,
"STR",
self.position.x + 30,
self.position.y + 30,
self.heading,
)
self.add_unit(
AirDefence.SAM_Patriot_CR__AMG_AN_MRC_137,
AirDefence.SAM_Patriot_AMG_AN_MRC_137,
"MRC",
self.position.x,
self.position.y,
self.heading,
)
self.add_unit(
AirDefence.SAM_Patriot_ECS,
AirDefence.SAM_Patriot_ECS_AN_MSQ_104,
"MSQ",
self.position.x + 30,
self.position.y,
self.heading,
)
self.add_unit(
AirDefence.SAM_Patriot_C2_ICC,
AirDefence.SAM_Patriot_ICC,
"ICC",
self.position.x + 60,
self.position.y,
@@ -61,7 +61,7 @@ class PatriotGenerator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_Patriot_LN,
AirDefence.SAM_Patriot_LN_M901,
"LN#" + str(i),
position[0],
position[1],
@@ -76,11 +76,7 @@ class PatriotGenerator(AirDefenseGroupGenerator):
)
for i, (x, y, heading) in enumerate(positions):
self.add_unit_to_group(
aa_group,
AirDefence.SPAAA_Vulcan_M163,
f"SPAAA#{i}",
Point(x, y),
heading,
aa_group, AirDefence.AAA_Vulcan_M163, f"SPAAA#{i}", Point(x, y), heading
)
@classmethod

View File

@@ -18,14 +18,14 @@ class RapierGenerator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_Rapier_Blindfire_TR,
AirDefence.Rapier_FSA_Blindfire_Tracker,
"BT",
self.position.x,
self.position.y,
self.heading,
)
self.add_unit(
AirDefence.SAM_Rapier_Tracker,
AirDefence.Rapier_FSA_Optical_Tracker,
"OT",
self.position.x + 20,
self.position.y,
@@ -39,7 +39,7 @@ class RapierGenerator(AirDefenseGroupGenerator):
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_Rapier_LN,
AirDefence.Rapier_FSA_Launcher,
"LN#" + str(i),
position[0],
position[1],

View File

@@ -30,7 +30,7 @@ class RolandGenerator(AirDefenseGroupGenerator):
self.heading,
)
self.add_unit(
Unarmed.Truck_M818_6x6,
Unarmed.Transport_M818,
"TRUCK",
self.position.x + 80,
self.position.y,

View File

@@ -1,6 +1,7 @@
import random
from dcs.mapping import Point
from dcs.unittype import VehicleType
from dcs.vehicles import AirDefence
from game import Game
@@ -17,18 +18,18 @@ class SA10Generator(AirDefenseGroupGenerator):
This generate a SA-10 group
"""
name = "SA-10/S-300PS Battery - With ZSU-23"
name = "SA-10/S-300PS Battery"
price = 550
def __init__(self, game: Game, ground_object: SamGroundObject):
super().__init__(game, ground_object)
self.sr1 = AirDefence.SAM_SA_10_S_300_Grumble_Clam_Shell_SR
self.sr2 = AirDefence.SAM_SA_10_S_300_Grumble_Big_Bird_SR
self.cp = AirDefence.SAM_SA_10_S_300_Grumble_C2
self.tr1 = AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR
self.tr2 = AirDefence.SAM_SA_10_S_300_Grumble_Flap_Lid_TR
self.ln1 = AirDefence.SAM_SA_10_S_300_Grumble_TEL_C
self.ln2 = AirDefence.SAM_SA_10_S_300_Grumble_TEL_D
self.sr1 = AirDefence.SAM_SA_10_S_300PS_SR_5N66M
self.sr2 = AirDefence.SAM_SA_10_S_300PS_SR_64H6E
self.cp = AirDefence.SAM_SA_10_S_300PS_CP_54K6
self.tr1 = AirDefence.SAM_SA_10_S_300PS_TR_30N6
self.tr2 = AirDefence.SAM_SA_10_S_300PS_TR_30N6
self.ln1 = AirDefence.SAM_SA_10_S_300PS_LN_5P85C
self.ln2 = AirDefence.SAM_SA_10_S_300PS_LN_5P85D
def generate(self):
# Search Radar
@@ -84,7 +85,7 @@ class SA10Generator(AirDefenseGroupGenerator):
for i, (x, y, heading) in enumerate(positions):
self.add_unit_to_group(
aa_group,
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish,
AirDefence.SPAAA_ZSU_23_4_Shilka,
f"AA#{i}",
Point(x, y),
heading,
@@ -92,10 +93,6 @@ class SA10Generator(AirDefenseGroupGenerator):
class Tier2SA10Generator(SA10Generator):
name = "SA-10/S-300PS Battery - With SA-15 PD"
price = 650
def generate_defensive_groups(self) -> None:
# Create AAA the way the main group does.
super().generate_defensive_groups()
@@ -109,7 +106,7 @@ class Tier2SA10Generator(SA10Generator):
for i, (x, y, heading) in enumerate(positions):
self.add_unit_to_group(
pd_group,
AirDefence.SAM_SA_15_Tor_Gauntlet,
AirDefence.SAM_SA_15_Tor_9A331,
f"PD#{i}",
Point(x, y),
heading,
@@ -117,10 +114,6 @@ class Tier2SA10Generator(SA10Generator):
class Tier3SA10Generator(SA10Generator):
name = "SA-10/S-300PS Battery - With SA-15 PD & SA-19 SHORAD"
price = 750
def generate_defensive_groups(self) -> None:
# AAA for defending against close targets.
aa_group = self.add_auxiliary_group("AA")
@@ -131,7 +124,7 @@ class Tier3SA10Generator(SA10Generator):
for i, (x, y, heading) in enumerate(positions):
self.add_unit_to_group(
aa_group,
AirDefence.SAM_SA_19_Tunguska_Grison,
AirDefence.SAM_SA_19_Tunguska_2S6,
f"AA#{i}",
Point(x, y),
heading,
@@ -146,7 +139,7 @@ class Tier3SA10Generator(SA10Generator):
for i, (x, y, heading) in enumerate(positions):
self.add_unit_to_group(
pd_group,
AirDefence.SAM_SA_15_Tor_Gauntlet,
AirDefence.SAM_SA_15_Tor_9A331,
f"PD#{i}",
Point(x, y),
heading,

View File

@@ -18,14 +18,14 @@ class SA11Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_SA_11_Buk_Gadfly_Snow_Drift_SR,
AirDefence.SAM_SA_11_Buk_SR_9S18M1,
"SR",
self.position.x + 20,
self.position.y,
self.heading,
)
self.add_unit(
AirDefence.SAM_SA_11_Buk_Gadfly_C2,
AirDefence.SAM_SA_11_Buk_CC_9S470M1,
"CC",
self.position.x,
self.position.y,
@@ -39,7 +39,7 @@ class SA11Generator(AirDefenseGroupGenerator):
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_SA_11_Buk_Gadfly_Fire_Dome_TEL,
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
"LN#" + str(i),
position[0],
position[1],

View File

@@ -18,14 +18,14 @@ class SA13Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
Unarmed.LUV_UAZ_469_Jeep,
Unarmed.Transport_UAZ_469,
"UAZ",
self.position.x,
self.position.y,
self.heading,
)
self.add_unit(
Unarmed.Truck_KAMAZ_43101,
Unarmed.Transport_KAMAZ_43101,
"TRUCK",
self.position.x + 40,
self.position.y,
@@ -38,7 +38,7 @@ class SA13Generator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_SA_13_Strela_10M3_Gopher_TEL,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3,
"LN#" + str(i),
position[0],
position[1],

View File

@@ -16,21 +16,21 @@ class SA15Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_SA_15_Tor_Gauntlet,
AirDefence.SAM_SA_15_Tor_9A331,
"ADS",
self.position.x,
self.position.y,
self.heading,
)
self.add_unit(
Unarmed.LUV_UAZ_469_Jeep,
Unarmed.Transport_UAZ_469,
"EWR",
self.position.x + 40,
self.position.y,
self.heading,
)
self.add_unit(
Unarmed.Truck_KAMAZ_43101,
Unarmed.Transport_KAMAZ_43101,
"TRUCK",
self.position.x + 80,
self.position.y,

View File

@@ -17,14 +17,14 @@ class SA17Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_SA_11_Buk_Gadfly_Snow_Drift_SR,
AirDefence.SAM_SA_11_Buk_SR_9S18M1,
"SR",
self.position.x + 20,
self.position.y,
self.heading,
)
self.add_unit(
AirDefence.SAM_SA_11_Buk_Gadfly_C2,
AirDefence.SAM_SA_11_Buk_CC_9S470M1,
"CC",
self.position.x,
self.position.y,

View File

@@ -21,7 +21,7 @@ class SA19Generator(AirDefenseGroupGenerator):
if num_launchers == 1:
self.add_unit(
AirDefence.SAM_SA_19_Tunguska_Grison,
AirDefence.SAM_SA_19_Tunguska_2S6,
"LN#0",
self.position.x,
self.position.y,
@@ -33,7 +33,7 @@ class SA19Generator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_SA_19_Tunguska_Grison,
AirDefence.SAM_SA_19_Tunguska_2S6,
"LN#" + str(i),
position[0],
position[1],

View File

@@ -18,14 +18,10 @@ class SA2Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_P19_Flat_Face_SR__SA_2_3,
"SR",
self.position.x,
self.position.y,
self.heading,
AirDefence.SAM_SR_P_19, "SR", self.position.x, self.position.y, self.heading
)
self.add_unit(
AirDefence.SAM_SA_2_S_75_Fan_Song_TR,
AirDefence.SAM_SA_2_TR_SNR_75_Fan_Song,
"TR",
self.position.x + 20,
self.position.y,
@@ -39,7 +35,7 @@ class SA2Generator(AirDefenseGroupGenerator):
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_SA_2_S_75_Guideline_LN,
AirDefence.SAM_SA_2_LN_SM_90,
"LN#" + str(i),
position[0],
position[1],

View File

@@ -18,14 +18,10 @@ class SA3Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_P19_Flat_Face_SR__SA_2_3,
"SR",
self.position.x,
self.position.y,
self.heading,
AirDefence.SAM_SR_P_19, "SR", self.position.x, self.position.y, self.heading
)
self.add_unit(
AirDefence.SAM_SA_3_S_125_Low_Blow_TR,
AirDefence.SAM_SA_3_S_125_TR_SNR,
"TR",
self.position.x + 20,
self.position.y,
@@ -39,7 +35,7 @@ class SA3Generator(AirDefenseGroupGenerator):
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_SA_3_S_125_Goa_LN,
AirDefence.SAM_SA_3_S_125_LN_5P73,
"LN#" + str(i),
position[0],
position[1],

View File

@@ -18,7 +18,7 @@ class SA6Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_SA_6_Kub_Long_Track_STR,
AirDefence.SAM_SA_6_Kub_STR_9S91,
"STR",
self.position.x,
self.position.y,
@@ -32,7 +32,7 @@ class SA6Generator(AirDefenseGroupGenerator):
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_SA_6_Kub_Gainful_TEL,
AirDefence.SAM_SA_6_Kub_LN_2P25,
"LN#" + str(i),
position[0],
position[1],

View File

@@ -16,7 +16,7 @@ class SA8Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SAM_SA_8_Osa_Gecko_TEL,
AirDefence.SAM_SA_8_Osa_9A33,
"OSA",
self.position.x,
self.position.y,

View File

@@ -18,14 +18,14 @@ class SA9Generator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
Unarmed.LUV_UAZ_469_Jeep,
Unarmed.Transport_UAZ_469,
"UAZ",
self.position.x,
self.position.y,
self.heading,
)
self.add_unit(
Unarmed.Truck_KAMAZ_43101,
Unarmed.Transport_KAMAZ_43101,
"TRUCK",
self.position.x + 40,
self.position.y,
@@ -38,7 +38,7 @@ class SA9Generator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SAM_SA_9_Strela_1_Gaskin_TEL,
AirDefence.SAM_SA_9_Strela_1_9P31,
"LN#" + str(i),
position[0],
position[1],

View File

@@ -18,7 +18,7 @@ class VulcanGenerator(AirDefenseGroupGenerator):
def generate(self):
self.add_unit(
AirDefence.SPAAA_Vulcan_M163,
AirDefence.AAA_Vulcan_M163,
"SPAAA",
self.position.x,
self.position.y,
@@ -26,14 +26,14 @@ class VulcanGenerator(AirDefenseGroupGenerator):
)
if random.randint(0, 1) == 1:
self.add_unit(
AirDefence.SPAAA_Vulcan_M163,
AirDefence.AAA_Vulcan_M163,
"SPAAA2",
self.position.x,
self.position.y,
self.heading,
)
self.add_unit(
Unarmed.Truck_M818_6x6,
Unarmed.Transport_M818,
"TRUCK",
self.position.x + 80,
self.position.y,

View File

@@ -24,7 +24,7 @@ class ZSU23Generator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SPAAA_ZSU_23_4_Shilka_Gun_Dish,
AirDefence.SPAAA_ZSU_23_4_Shilka,
"SPAA#" + str(i),
position[0],
position[1],

View File

@@ -27,7 +27,7 @@ class ZU23Generator(AirDefenseGroupGenerator):
for j in range(grid_y):
index = index + 1
self.add_unit(
AirDefence.AAA_ZU_23_Closed_Emplacement,
AirDefence.AAA_ZU_23_Closed,
"AAA#" + str(index),
self.position.x + spacing * i,
self.position.y + spacing * j,

View File

@@ -24,7 +24,7 @@ class ZU23UralGenerator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SPAAA_ZU_23_2_Mounted_Ural_375,
AirDefence.AAA_ZU_23_on_Ural_375,
"SPAA#" + str(i),
position[0],
position[1],

View File

@@ -24,7 +24,7 @@ class ZU23UralInsurgentGenerator(AirDefenseGroupGenerator):
)
for i, position in enumerate(positions):
self.add_unit(
AirDefence.SPAAA_ZU_23_2_Insurgent_Mounted_Ural_375,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375,
"SPAA#" + str(i),
position[0],
position[1],

2
pydcs

Submodule pydcs updated: cd14f0a049...42de2ec352

View File

@@ -409,27 +409,7 @@ class WeaponsA4EC:
"name": "Mk-83 *3 (TER)",
"weight": 1388.6,
}
_3_LAU_61 = ({"clsid": "{TER,LAU-61*3}", "name": "3*LAU-61", "weight": 98},)
Fuel_Tank_150_gallons__EMPTY_ = {
"clsid": "{DFT-150gal_EMPTY}",
"name": "Fuel_Tank_150_gallons__EMPTY",
"weight": 61.688512,
}
Fuel_Tank_300_gallons__EMPTY_ = {
"clsid": "{DFT-300gal_EMPTY}",
"name": "Fuel_Tank_300_gallons__EMPTY",
"weight": 83.007336,
}
Fuel_Tank_300_gallons__EMPTY__ = {
"clsid": "{DFT-300gal_LR_EMPTY}",
"name": "Fuel_Tank_300_gallons__EMPTY",
"weight": 90.264808,
}
Fuel_Tank_400_gallons__EMPTY_ = {
"clsid": "{DFT-400gal_EMPTY}",
"name": "Fuel_Tank_400_gallons__EMPTY",
"weight": 108.86208,
}
_3_LAU_61 = {"clsid": "{TER,LAU-61*3}", "name": "3*LAU-61", "weight": 98}
class A_4E_C(PlaneType):
@@ -850,511 +830,278 @@ class A_4E_C(PlaneType):
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Pylon1:
LAU_7_with_AIM_9B_Sidewinder_IR_AAM = (
1,
Weapons.LAU_7_with_AIM_9B_Sidewinder_IR_AAM,
)
LAU_7_with_AIM_9P_Sidewinder_IR_AAM = (
1,
Weapons.LAU_7_with_AIM_9P_Sidewinder_IR_AAM,
)
LAU_7_with_AIM_9P5_Sidewinder_IR_AAM = (
1,
Weapons.LAU_7_with_AIM_9P5_Sidewinder_IR_AAM,
)
LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG = (
1,
Weapons.LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
1,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
1,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
1,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
1,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
1,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
1,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
AGM_45A_Shrike_ARM = (1, Weapons.AGM_45A_Shrike_ARM)
# ERRR {AGM12_B}
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
1,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,
)
Mk_81___250lb_GP_Bomb_LD = (1, Weapons.Mk_81___250lb_GP_Bomb_LD)
Mk_81SE = (1, WeaponsA4EC.Mk_81SE)
Mk_82___500lb_GP_Bomb_LD = (1, Weapons.Mk_82___500lb_GP_Bomb_LD)
Mk_82_Snakeye___500lb_GP_Bomb_HD = (
1,
Weapons.Mk_82_Snakeye___500lb_GP_Bomb_HD,
)
Mk_77_mod_1 = (1, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1___100lb_GP_Bomb_LD = (1, Weapons.AN_M30A1___100lb_GP_Bomb_LD)
AN_M57___250lb_GP_Bomb_LD = (1, Weapons.AN_M57___250lb_GP_Bomb_LD)
AN_M64___500lb_GP_Bomb_LD = (1, Weapons.AN_M64___500lb_GP_Bomb_LD)
AN_M81 = (1, WeaponsA4EC.AN_M81)
AN_M88 = (1, WeaponsA4EC.AN_M88)
LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M257__Para_Illum = (
1,
Weapons.LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M257__Para_Illum,
)
Smokewinder___red = (1, Weapons.Smokewinder___red)
Smokewinder___green = (1, Weapons.Smokewinder___green)
Smokewinder___blue = (1, Weapons.Smokewinder___blue)
Smokewinder___white = (1, Weapons.Smokewinder___white)
Smokewinder___yellow = (1, Weapons.Smokewinder___yellow)
Smokewinder___orange = (1, Weapons.Smokewinder___orange)
SUU_25_x_8_LUU_2___Target_Marker_Flares = (
1,
Weapons.SUU_25_x_8_LUU_2___Target_Marker_Flares,
)
class Pylon1:
LAU_10___4_ZUNI_MK_71 = (1, Weapons.LAU_10___4_ZUNI_MK_71)
LAU_3___19_FFAR_M156_WP = (1, Weapons.LAU_3___19_FFAR_M156_WP)
LAU_3___19_FFAR_Mk1_HE = (1, Weapons.LAU_3___19_FFAR_Mk1_HE)
LAU_3___19_FFAR_Mk5_HEAT = (1, Weapons.LAU_3___19_FFAR_Mk5_HEAT)
LAU_68___7_FFAR_M156_WP = (1, Weapons.LAU_68___7_FFAR_M156_WP)
LAU_68___7_FFAR_Mk1_HE = (1, Weapons.LAU_68___7_FFAR_Mk1_HE)
LAU_68___7_FFAR_Mk5_HEAT = (1, Weapons.LAU_68___7_FFAR_Mk5_HEAT)
AGM_45A = (1, Weapons.AGM_45A)
# ERRR {AGM12_B}
Mk_20 = (1, Weapons.Mk_20)
Mk_81 = (1, Weapons.Mk_81)
Mk_81SE = (1, WeaponsA4EC.Mk_81SE)
Mk_82 = (1, Weapons.Mk_82)
Mk_82_SnakeEye = (1, Weapons.Mk_82_SnakeEye)
Mk_77_mod_1 = (1, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1 = (1, Weapons.AN_M30A1)
AN_M57 = (1, Weapons.AN_M57)
AN_M64 = (1, Weapons.AN_M64)
AN_M81 = (1, WeaponsA4EC.AN_M81)
AN_M88 = (1, WeaponsA4EC.AN_M88)
LAU_68___7_2_75__rockets_M257__Parachute_illumination_ = (
1,
Weapons.LAU_68___7_2_75__rockets_M257__Parachute_illumination_,
)
Smokewinder___red = (1, Weapons.Smokewinder___red)
Smokewinder___green = (1, Weapons.Smokewinder___green)
Smokewinder___blue = (1, Weapons.Smokewinder___blue)
Smokewinder___white = (1, Weapons.Smokewinder___white)
Smokewinder___yellow = (1, Weapons.Smokewinder___yellow)
Smokewinder___orange = (1, Weapons.Smokewinder___orange)
# ERRR <CLEAN>
# ERRR <CLEAN>
class Pylon2:
Fuel_Tank_300_gallons_ = (2, WeaponsA4EC.Fuel_Tank_300_gallons_)
Fuel_Tank_300_gallons__EMPTY__ = (
2,
WeaponsA4EC.Fuel_Tank_300_gallons__EMPTY__,
)
Fuel_Tank_150_gallons = (2, WeaponsA4EC.Fuel_Tank_150_gallons)
Fuel_Tank_150_gallons__EMPTY_ = (
2,
WeaponsA4EC.Fuel_Tank_150_gallons__EMPTY_,
)
LAU_7_with_AIM_9B_Sidewinder_IR_AAM = (
2,
Weapons.LAU_7_with_AIM_9B_Sidewinder_IR_AAM,
)
LAU_7_with_AIM_9P_Sidewinder_IR_AAM = (
2,
Weapons.LAU_7_with_AIM_9P_Sidewinder_IR_AAM,
)
LAU_7_with_AIM_9P5_Sidewinder_IR_AAM = (
2,
Weapons.LAU_7_with_AIM_9P5_Sidewinder_IR_AAM,
)
LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG = (
2,
Weapons.LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG,
)
LAU_10_2___4_ZUNI_MK_71_ = (2, WeaponsA4EC.LAU_10_2___4_ZUNI_MK_71_)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
2,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
2,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
2,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
LAU_3_2___19_FFAR_M156_WP_ = (2, WeaponsA4EC.LAU_3_2___19_FFAR_M156_WP_)
LAU_3_2___19_FFAR_Mk1_HE_ = (2, WeaponsA4EC.LAU_3_2___19_FFAR_Mk1_HE_)
LAU_3_2___19_FFAR_Mk5_HEAT_ = (2, WeaponsA4EC.LAU_3_2___19_FFAR_Mk5_HEAT_)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
2,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
2,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
2,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
LAU_68_2___7_FFAR_M156_WP_ = (2, WeaponsA4EC.LAU_68_2___7_FFAR_M156_WP_)
LAU_68_2___7_FFAR_Mk1_HE_ = (2, WeaponsA4EC.LAU_68_2___7_FFAR_Mk1_HE_)
LAU_68_2___7_FFAR_Mk5_HEAT_ = (2, WeaponsA4EC.LAU_68_2___7_FFAR_Mk5_HEAT_)
AGM_45A_Shrike_ARM = (2, Weapons.AGM_45A_Shrike_ARM)
# ERRR {AGM12_C}
# ERRR {AGM12_B}
AGM_62_Walleye_II___Guided_Weapon_Mk_5__TV_Guided_ = (
2,
Weapons.AGM_62_Walleye_II___Guided_Weapon_Mk_5__TV_Guided_,
)
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
2,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,
)
Mk_81___250lb_GP_Bomb_LD = (2, Weapons.Mk_81___250lb_GP_Bomb_LD)
Mk_81SE = (2, WeaponsA4EC.Mk_81SE)
Mk_82___500lb_GP_Bomb_LD = (2, Weapons.Mk_82___500lb_GP_Bomb_LD)
Mk_82_Snakeye___500lb_GP_Bomb_HD = (
2,
Weapons.Mk_82_Snakeye___500lb_GP_Bomb_HD,
)
Mk_83___1000lb_GP_Bomb_LD = (2, Weapons.Mk_83___1000lb_GP_Bomb_LD)
Mk_84___2000lb_GP_Bomb_LD = (2, Weapons.Mk_84___2000lb_GP_Bomb_LD)
M117___750lb_GP_Bomb_LD = (2, Weapons.M117___750lb_GP_Bomb_LD)
Mk_77_mod_0 = (2, WeaponsA4EC.Mk_77_mod_0)
Mk_77_mod_1 = (2, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1___100lb_GP_Bomb_LD = (2, Weapons.AN_M30A1___100lb_GP_Bomb_LD)
AN_M57___250lb_GP_Bomb_LD = (2, Weapons.AN_M57___250lb_GP_Bomb_LD)
AN_M64___500lb_GP_Bomb_LD = (2, Weapons.AN_M64___500lb_GP_Bomb_LD)
AN_M65___1000lb_GP_Bomb_LD = (2, Weapons.AN_M65___1000lb_GP_Bomb_LD)
AN_M81 = (2, WeaponsA4EC.AN_M81)
AN_M88 = (2, WeaponsA4EC.AN_M88)
CBU_1_A = (2, WeaponsA4EC.CBU_1_A)
CBU_2_A = (2, WeaponsA4EC.CBU_2_A)
CBU_2B_A = (2, WeaponsA4EC.CBU_2B_A)
CBU_1_A__2 = (2, WeaponsA4EC.CBU_1_A__2)
CBU_2_A__2 = (2, WeaponsA4EC.CBU_2_A__2)
CBU_2B_A__2 = (2, WeaponsA4EC.CBU_2B_A__2)
Mk_20__2__TER_ = (2, WeaponsA4EC.Mk_20__2__TER_)
Mk_81__5__MER_ = (2, WeaponsA4EC.Mk_81__5__MER_)
Mk_81SE__5__MER_ = (2, WeaponsA4EC.Mk_81SE__5__MER_)
Mk_82__2__TER_ = (2, WeaponsA4EC.Mk_82__2__TER_)
Mk_82_Snakeye__2__TER_ = (2, WeaponsA4EC.Mk_82_Snakeye__2__TER_)
AN_M57__5__MER_ = (2, WeaponsA4EC.AN_M57__5__MER_)
AN_M57__2__TER_ = (2, WeaponsA4EC.AN_M57__2__TER_)
AN_M81__5__MER_ = (2, WeaponsA4EC.AN_M81__5__MER_)
AN_M88__5__MER_ = (2, WeaponsA4EC.AN_M88__5__MER_)
Mk4_HIPEG = (2, WeaponsA4EC.Mk4_HIPEG)
Smokewinder___red = (2, Weapons.Smokewinder___red)
Smokewinder___green = (2, Weapons.Smokewinder___green)
Smokewinder___blue = (2, Weapons.Smokewinder___blue)
Smokewinder___white = (2, Weapons.Smokewinder___white)
Smokewinder___yellow = (2, Weapons.Smokewinder___yellow)
Smokewinder___orange = (2, Weapons.Smokewinder___orange)
SUU_25_x_8_LUU_2___Target_Marker_Flares = (
2,
Weapons.SUU_25_x_8_LUU_2___Target_Marker_Flares,
)
class Pylon2:
Fuel_Tank_300_gallons_ = (2, WeaponsA4EC.Fuel_Tank_300_gallons_)
Fuel_Tank_150_gallons = (2, WeaponsA4EC.Fuel_Tank_150_gallons)
LAU_7_GAR_8_Sidewinder_IR_AAM = (2, Weapons.LAU_7_GAR_8_Sidewinder_IR_AAM)
LAU_7_AIM_9P_Sidewinder_IR_AAM = (2, Weapons.LAU_7_AIM_9P_Sidewinder_IR_AAM)
LAU_7_AIM_9P5_Sidewinder_IR_AAM = (2, Weapons.LAU_7_AIM_9P5_Sidewinder_IR_AAM)
LAU_10___4_ZUNI_MK_71 = (2, Weapons.LAU_10___4_ZUNI_MK_71)
LAU_10_2___4_ZUNI_MK_71_ = (2, WeaponsA4EC.LAU_10_2___4_ZUNI_MK_71_)
LAU_3___19_FFAR_M156_WP = (2, Weapons.LAU_3___19_FFAR_M156_WP)
LAU_3___19_FFAR_Mk1_HE = (2, Weapons.LAU_3___19_FFAR_Mk1_HE)
LAU_3___19_FFAR_Mk5_HEAT = (2, Weapons.LAU_3___19_FFAR_Mk5_HEAT)
LAU_3_2___19_FFAR_M156_WP_ = (2, WeaponsA4EC.LAU_3_2___19_FFAR_M156_WP_)
LAU_3_2___19_FFAR_Mk1_HE_ = (2, WeaponsA4EC.LAU_3_2___19_FFAR_Mk1_HE_)
LAU_3_2___19_FFAR_Mk5_HEAT_ = (2, WeaponsA4EC.LAU_3_2___19_FFAR_Mk5_HEAT_)
LAU_68___7_FFAR_M156_WP = (2, Weapons.LAU_68___7_FFAR_M156_WP)
LAU_68___7_FFAR_Mk1_HE = (2, Weapons.LAU_68___7_FFAR_Mk1_HE)
LAU_68___7_FFAR_Mk5_HEAT = (2, Weapons.LAU_68___7_FFAR_Mk5_HEAT)
LAU_68_2___7_FFAR_M156_WP_ = (2, WeaponsA4EC.LAU_68_2___7_FFAR_M156_WP_)
LAU_68_2___7_FFAR_Mk1_HE_ = (2, WeaponsA4EC.LAU_68_2___7_FFAR_Mk1_HE_)
LAU_68_2___7_FFAR_Mk5_HEAT_ = (2, WeaponsA4EC.LAU_68_2___7_FFAR_Mk5_HEAT_)
AGM_45A = (2, Weapons.AGM_45A)
# ERRR {AGM12_C}
# ERRR {AGM12_B}
AGM_62 = (2, Weapons.AGM_62)
Mk_20 = (2, Weapons.Mk_20)
Mk_81 = (2, Weapons.Mk_81)
Mk_81SE = (2, WeaponsA4EC.Mk_81SE)
Mk_82 = (2, Weapons.Mk_82)
Mk_82_SnakeEye = (2, Weapons.Mk_82_SnakeEye)
Mk_83 = (2, Weapons.Mk_83)
Mk_84 = (2, Weapons.Mk_84)
M117 = (2, Weapons.M117)
Mk_77_mod_0 = (2, WeaponsA4EC.Mk_77_mod_0)
Mk_77_mod_1 = (2, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1 = (2, Weapons.AN_M30A1)
AN_M57 = (2, Weapons.AN_M57)
AN_M64 = (2, Weapons.AN_M64)
AN_M65 = (2, Weapons.AN_M65)
AN_M81 = (2, WeaponsA4EC.AN_M81)
AN_M88 = (2, WeaponsA4EC.AN_M88)
CBU_1_A = (2, WeaponsA4EC.CBU_1_A)
CBU_2_A = (2, WeaponsA4EC.CBU_2_A)
CBU_2B_A = (2, WeaponsA4EC.CBU_2B_A)
CBU_1_A__2 = (2, WeaponsA4EC.CBU_1_A__2)
CBU_2_A__2 = (2, WeaponsA4EC.CBU_2_A__2)
CBU_2B_A__2 = (2, WeaponsA4EC.CBU_2B_A__2)
Mk_20__2__TER_ = (2, WeaponsA4EC.Mk_20__2__TER_)
Mk_81__5__MER_ = (2, WeaponsA4EC.Mk_81__5__MER_)
Mk_81SE__5__MER_ = (2, WeaponsA4EC.Mk_81SE__5__MER_)
Mk_82__2__TER_ = (2, WeaponsA4EC.Mk_82__2__TER_)
Mk_82_Snakeye__2__TER_ = (2, WeaponsA4EC.Mk_82_Snakeye__2__TER_)
AN_M57__5__MER_ = (2, WeaponsA4EC.AN_M57__5__MER_)
AN_M57__2__TER_ = (2, WeaponsA4EC.AN_M57__2__TER_)
AN_M81__5__MER_ = (2, WeaponsA4EC.AN_M81__5__MER_)
AN_M88__5__MER_ = (2, WeaponsA4EC.AN_M88__5__MER_)
Mk4_HIPEG = (2, WeaponsA4EC.Mk4_HIPEG)
Smokewinder___red = (2, Weapons.Smokewinder___red)
Smokewinder___green = (2, Weapons.Smokewinder___green)
Smokewinder___blue = (2, Weapons.Smokewinder___blue)
Smokewinder___white = (2, Weapons.Smokewinder___white)
Smokewinder___yellow = (2, Weapons.Smokewinder___yellow)
Smokewinder___orange = (2, Weapons.Smokewinder___orange)
# ERRR <CLEAN>
# ERRR <CLEAN>
class Pylon3:
Fuel_Tank_400_gallons = (3, WeaponsA4EC.Fuel_Tank_400_gallons)
Fuel_Tank_300_gallons = (3, WeaponsA4EC.Fuel_Tank_300_gallons)
Fuel_Tank_150_gallons = (3, WeaponsA4EC.Fuel_Tank_150_gallons)
Fuel_Tank_400_gallons__EMPTY_ = (
3,
WeaponsA4EC.Fuel_Tank_400_gallons__EMPTY_,
)
Fuel_Tank_300_gallons__EMPTY_ = (
3,
WeaponsA4EC.Fuel_Tank_300_gallons__EMPTY_,
)
Fuel_Tank_150_gallons__EMPTY_ = (
3,
WeaponsA4EC.Fuel_Tank_150_gallons__EMPTY_,
)
# ERRR {3*LAU-61}
BRU_42_with_3_x_LAU_68_pods___21_x_2_75_Hydra__UnGd_Rkts_Mk5__HEAT = (
3,
Weapons.BRU_42_with_3_x_LAU_68_pods___21_x_2_75_Hydra__UnGd_Rkts_Mk5__HEAT,
)
LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG = (
3,
Weapons.LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG,
)
LAU_10_2___4_ZUNI_MK_71 = (3, WeaponsA4EC.LAU_10_2___4_ZUNI_MK_71)
LAU_10_3___4_ZUNI_MK_71 = (3, WeaponsA4EC.LAU_10_3___4_ZUNI_MK_71)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
3,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
3,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
3,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
LAU_3_2___19_FFAR_M156_WP = (3, WeaponsA4EC.LAU_3_2___19_FFAR_M156_WP)
LAU_3_2___19_FFAR_Mk1_HE = (3, WeaponsA4EC.LAU_3_2___19_FFAR_Mk1_HE)
LAU_3_2___19_FFAR_Mk5_HEAT = (3, WeaponsA4EC.LAU_3_2___19_FFAR_Mk5_HEAT)
LAU_3_3___19_FFAR_M156_WP = (3, WeaponsA4EC.LAU_3_3___19_FFAR_M156_WP)
LAU_3_3___19_FFAR_Mk1_HE = (3, WeaponsA4EC.LAU_3_3___19_FFAR_Mk1_HE)
LAU_3_3___19_FFAR_Mk5_HEAT = (3, WeaponsA4EC.LAU_3_3___19_FFAR_Mk5_HEAT)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
3,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
3,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
3,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
LAU_68_2___7_FFAR_M156_WP = (3, WeaponsA4EC.LAU_68_2___7_FFAR_M156_WP)
LAU_68_2___7_FFAR_Mk1_HE = (3, WeaponsA4EC.LAU_68_2___7_FFAR_Mk1_HE)
LAU_68_2___7_FFAR_Mk5_HEAT = (3, WeaponsA4EC.LAU_68_2___7_FFAR_Mk5_HEAT)
LAU_68_3___7_FFAR_M156_WP = (3, WeaponsA4EC.LAU_68_3___7_FFAR_M156_WP)
LAU_68_3___7_FFAR_Mk1_HE = (3, WeaponsA4EC.LAU_68_3___7_FFAR_Mk1_HE)
LAU_68_3___7_FFAR_Mk5_HEAT = (3, WeaponsA4EC.LAU_68_3___7_FFAR_Mk5_HEAT)
# ERRR {AGM12_B}
AGM_62_Walleye_II___Guided_Weapon_Mk_5__TV_Guided_ = (
3,
Weapons.AGM_62_Walleye_II___Guided_Weapon_Mk_5__TV_Guided_,
)
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
3,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,
)
Mk_81___250lb_GP_Bomb_LD = (3, Weapons.Mk_81___250lb_GP_Bomb_LD)
Mk_81SE = (3, WeaponsA4EC.Mk_81SE)
Mk_82___500lb_GP_Bomb_LD = (3, Weapons.Mk_82___500lb_GP_Bomb_LD)
Mk_82_Snakeye___500lb_GP_Bomb_HD = (
3,
Weapons.Mk_82_Snakeye___500lb_GP_Bomb_HD,
)
Mk_83___1000lb_GP_Bomb_LD = (3, Weapons.Mk_83___1000lb_GP_Bomb_LD)
Mk_84___2000lb_GP_Bomb_LD = (3, Weapons.Mk_84___2000lb_GP_Bomb_LD)
M117___750lb_GP_Bomb_LD = (3, Weapons.M117___750lb_GP_Bomb_LD)
Mk_77_mod_0 = (3, WeaponsA4EC.Mk_77_mod_0)
Mk_77_mod_1 = (3, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1___100lb_GP_Bomb_LD = (3, Weapons.AN_M30A1___100lb_GP_Bomb_LD)
AN_M57___250lb_GP_Bomb_LD = (3, Weapons.AN_M57___250lb_GP_Bomb_LD)
AN_M64___500lb_GP_Bomb_LD = (3, Weapons.AN_M64___500lb_GP_Bomb_LD)
AN_M65___1000lb_GP_Bomb_LD = (3, Weapons.AN_M65___1000lb_GP_Bomb_LD)
AN_M66A2 = (3, WeaponsA4EC.AN_M66A2)
AN_M81 = (3, WeaponsA4EC.AN_M81)
AN_M88 = (3, WeaponsA4EC.AN_M88)
Mk_20__3__TER_ = (3, WeaponsA4EC.Mk_20__3__TER_)
Mk_20__2__TER___ = (3, WeaponsA4EC.Mk_20__2__TER___)
Mk_81__6__MER_ = (3, WeaponsA4EC.Mk_81__6__MER_)
Mk_81SE__6__MER_ = (3, WeaponsA4EC.Mk_81SE__6__MER_)
Mk_82__6__MER_ = (3, WeaponsA4EC.Mk_82__6__MER_)
Mk_82__4__MER_ = (3, WeaponsA4EC.Mk_82__4__MER_)
Mk_82__3__TER_ = (3, WeaponsA4EC.Mk_82__3__TER_)
Mk_82_Snakeye__6__MER_ = (3, WeaponsA4EC.Mk_82_Snakeye__6__MER_)
Mk_82_Snakeye__4__MER_ = (3, WeaponsA4EC.Mk_82_Snakeye__4__MER_)
Mk_82_Snakeye__3__TER_ = (3, WeaponsA4EC.Mk_82_Snakeye__3__TER_)
Mk_83__3__TER_ = (3, WeaponsA4EC.Mk_83__3__TER_)
Mk_83__2__TER_ = (3, WeaponsA4EC.Mk_83__2__TER_)
Mk_77_mod_1__2__TER___ = (3, WeaponsA4EC.Mk_77_mod_1__2__TER___)
AN_M57__6__MER_ = (3, WeaponsA4EC.AN_M57__6__MER_)
AN_M57__3__TER_ = (3, WeaponsA4EC.AN_M57__3__TER_)
AN_M81__6__MER_ = (3, WeaponsA4EC.AN_M81__6__MER_)
AN_M88__6__MER_ = (3, WeaponsA4EC.AN_M88__6__MER_)
Mk4_HIPEG = (3, WeaponsA4EC.Mk4_HIPEG)
Smokewinder___red = (3, Weapons.Smokewinder___red)
Smokewinder___green = (3, Weapons.Smokewinder___green)
Smokewinder___blue = (3, Weapons.Smokewinder___blue)
Smokewinder___white = (3, Weapons.Smokewinder___white)
Smokewinder___yellow = (3, Weapons.Smokewinder___yellow)
Smokewinder___orange = (3, Weapons.Smokewinder___orange)
SUU_25_x_8_LUU_2___Target_Marker_Flares = (
3,
Weapons.SUU_25_x_8_LUU_2___Target_Marker_Flares,
)
class Pylon3:
Fuel_Tank_400_gallons = (3, WeaponsA4EC.Fuel_Tank_400_gallons)
Fuel_Tank_300_gallons = (3, WeaponsA4EC.Fuel_Tank_300_gallons)
Fuel_Tank_150_gallons = (3, WeaponsA4EC.Fuel_Tank_150_gallons)
D_704_Refueling_Pod = (3, WeaponsA4EC.D_704_Refueling_Pod)
# ERRR {3*LAU-61}
LAU_68_3___7_2_75__rockets_MK5__HE_ = (
3,
Weapons.LAU_68_3___7_2_75__rockets_MK5__HE_,
)
LAU_10___4_ZUNI_MK_71 = (3, Weapons.LAU_10___4_ZUNI_MK_71)
LAU_10_2___4_ZUNI_MK_71 = (3, WeaponsA4EC.LAU_10_2___4_ZUNI_MK_71)
LAU_10_3___4_ZUNI_MK_71 = (3, WeaponsA4EC.LAU_10_3___4_ZUNI_MK_71)
LAU_3___19_FFAR_M156_WP = (3, Weapons.LAU_3___19_FFAR_M156_WP)
LAU_3___19_FFAR_Mk1_HE = (3, Weapons.LAU_3___19_FFAR_Mk1_HE)
LAU_3___19_FFAR_Mk5_HEAT = (3, Weapons.LAU_3___19_FFAR_Mk5_HEAT)
LAU_3_2___19_FFAR_M156_WP = (3, WeaponsA4EC.LAU_3_2___19_FFAR_M156_WP)
LAU_3_2___19_FFAR_Mk1_HE = (3, WeaponsA4EC.LAU_3_2___19_FFAR_Mk1_HE)
LAU_3_2___19_FFAR_Mk5_HEAT = (3, WeaponsA4EC.LAU_3_2___19_FFAR_Mk5_HEAT)
LAU_3_3___19_FFAR_M156_WP = (3, WeaponsA4EC.LAU_3_3___19_FFAR_M156_WP)
LAU_3_3___19_FFAR_Mk1_HE = (3, WeaponsA4EC.LAU_3_3___19_FFAR_Mk1_HE)
LAU_3_3___19_FFAR_Mk5_HEAT = (3, WeaponsA4EC.LAU_3_3___19_FFAR_Mk5_HEAT)
LAU_68___7_FFAR_M156_WP = (3, Weapons.LAU_68___7_FFAR_M156_WP)
LAU_68___7_FFAR_Mk1_HE = (3, Weapons.LAU_68___7_FFAR_Mk1_HE)
LAU_68___7_FFAR_Mk5_HEAT = (3, Weapons.LAU_68___7_FFAR_Mk5_HEAT)
LAU_68_2___7_FFAR_M156_WP = (3, WeaponsA4EC.LAU_68_2___7_FFAR_M156_WP)
LAU_68_2___7_FFAR_Mk1_HE = (3, WeaponsA4EC.LAU_68_2___7_FFAR_Mk1_HE)
LAU_68_2___7_FFAR_Mk5_HEAT = (3, WeaponsA4EC.LAU_68_2___7_FFAR_Mk5_HEAT)
LAU_68_3___7_FFAR_M156_WP = (3, WeaponsA4EC.LAU_68_3___7_FFAR_M156_WP)
LAU_68_3___7_FFAR_Mk1_HE = (3, WeaponsA4EC.LAU_68_3___7_FFAR_Mk1_HE)
LAU_68_3___7_FFAR_Mk5_HEAT = (3, WeaponsA4EC.LAU_68_3___7_FFAR_Mk5_HEAT)
# ERRR {AGM12_B}
AGM_62 = (3, Weapons.AGM_62)
Mk_20 = (3, Weapons.Mk_20)
Mk_81 = (3, Weapons.Mk_81)
Mk_81SE = (3, WeaponsA4EC.Mk_81SE)
Mk_82 = (3, Weapons.Mk_82)
Mk_82_SnakeEye = (3, Weapons.Mk_82_SnakeEye)
Mk_83 = (3, Weapons.Mk_83)
Mk_84 = (3, Weapons.Mk_84)
M117 = (3, Weapons.M117)
Mk_77_mod_0 = (3, WeaponsA4EC.Mk_77_mod_0)
Mk_77_mod_1 = (3, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1 = (3, Weapons.AN_M30A1)
AN_M57 = (3, Weapons.AN_M57)
AN_M64 = (3, Weapons.AN_M64)
AN_M65 = (3, Weapons.AN_M65)
AN_M66A2 = (3, WeaponsA4EC.AN_M66A2)
AN_M81 = (3, WeaponsA4EC.AN_M81)
AN_M88 = (3, WeaponsA4EC.AN_M88)
Mk_20__3__TER_ = (3, WeaponsA4EC.Mk_20__3__TER_)
Mk_20__2__TER___ = (3, WeaponsA4EC.Mk_20__2__TER___)
Mk_81__6__MER_ = (3, WeaponsA4EC.Mk_81__6__MER_)
Mk_81SE__6__MER_ = (3, WeaponsA4EC.Mk_81SE__6__MER_)
Mk_82__6__MER_ = (3, WeaponsA4EC.Mk_82__6__MER_)
Mk_82__4__MER_ = (3, WeaponsA4EC.Mk_82__4__MER_)
Mk_82__3__TER_ = (3, WeaponsA4EC.Mk_82__3__TER_)
Mk_82_Snakeye__6__MER_ = (3, WeaponsA4EC.Mk_82_Snakeye__6__MER_)
Mk_82_Snakeye__4__MER_ = (3, WeaponsA4EC.Mk_82_Snakeye__4__MER_)
Mk_82_Snakeye__3__TER_ = (3, WeaponsA4EC.Mk_82_Snakeye__3__TER_)
Mk_83__3__TER_ = (3, WeaponsA4EC.Mk_83__3__TER_)
Mk_83__2__TER_ = (3, WeaponsA4EC.Mk_83__2__TER_)
Mk_77_mod_1__2__TER___ = (3, WeaponsA4EC.Mk_77_mod_1__2__TER___)
AN_M57__6__MER_ = (3, WeaponsA4EC.AN_M57__6__MER_)
AN_M57__3__TER_ = (3, WeaponsA4EC.AN_M57__3__TER_)
AN_M81__6__MER_ = (3, WeaponsA4EC.AN_M81__6__MER_)
AN_M88__6__MER_ = (3, WeaponsA4EC.AN_M88__6__MER_)
Mk4_HIPEG = (3, WeaponsA4EC.Mk4_HIPEG)
Smokewinder___red = (3, Weapons.Smokewinder___red)
Smokewinder___green = (3, Weapons.Smokewinder___green)
Smokewinder___blue = (3, Weapons.Smokewinder___blue)
Smokewinder___white = (3, Weapons.Smokewinder___white)
Smokewinder___yellow = (3, Weapons.Smokewinder___yellow)
Smokewinder___orange = (3, Weapons.Smokewinder___orange)
# ERRR <CLEAN>
# ERRR <CLEAN>
class Pylon4:
Fuel_Tank_300_gallons_ = (4, WeaponsA4EC.Fuel_Tank_300_gallons_)
Fuel_Tank_300_gallons__EMPTY__ = (
4,
WeaponsA4EC.Fuel_Tank_300_gallons__EMPTY__,
)
Fuel_Tank_150_gallons = (4, WeaponsA4EC.Fuel_Tank_150_gallons)
Fuel_Tank_150_gallons__EMPTY_ = (
4,
WeaponsA4EC.Fuel_Tank_150_gallons__EMPTY_,
)
LAU_7_with_AIM_9B_Sidewinder_IR_AAM = (
4,
Weapons.LAU_7_with_AIM_9B_Sidewinder_IR_AAM,
)
LAU_7_with_AIM_9P_Sidewinder_IR_AAM = (
4,
Weapons.LAU_7_with_AIM_9P_Sidewinder_IR_AAM,
)
LAU_7_with_AIM_9P5_Sidewinder_IR_AAM = (
4,
Weapons.LAU_7_with_AIM_9P5_Sidewinder_IR_AAM,
)
LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG = (
4,
Weapons.LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG,
)
LAU_10_2___4_ZUNI_MK_71__ = (4, WeaponsA4EC.LAU_10_2___4_ZUNI_MK_71__)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
4,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
4,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
4,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
LAU_3_2___19_FFAR_M156_WP__ = (4, WeaponsA4EC.LAU_3_2___19_FFAR_M156_WP__)
LAU_3_2___19_FFAR_Mk1_HE__ = (4, WeaponsA4EC.LAU_3_2___19_FFAR_Mk1_HE__)
LAU_3_2___19_FFAR_Mk5_HEAT__ = (4, WeaponsA4EC.LAU_3_2___19_FFAR_Mk5_HEAT__)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
4,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
4,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
4,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
LAU_68_2___7_FFAR_M156_WP__ = (4, WeaponsA4EC.LAU_68_2___7_FFAR_M156_WP__)
LAU_68_2___7_FFAR_Mk1_HE__ = (4, WeaponsA4EC.LAU_68_2___7_FFAR_Mk1_HE__)
LAU_68_2___7_FFAR_Mk5_HEAT__ = (4, WeaponsA4EC.LAU_68_2___7_FFAR_Mk5_HEAT__)
AGM_45A_Shrike_ARM = (4, Weapons.AGM_45A_Shrike_ARM)
# ERRR {AGM12_C}
# ERRR {AGM12_B}
AGM_62_Walleye_II___Guided_Weapon_Mk_5__TV_Guided_ = (
4,
Weapons.AGM_62_Walleye_II___Guided_Weapon_Mk_5__TV_Guided_,
)
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
4,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,
)
Mk_81___250lb_GP_Bomb_LD = (4, Weapons.Mk_81___250lb_GP_Bomb_LD)
Mk_81SE = (4, WeaponsA4EC.Mk_81SE)
Mk_82___500lb_GP_Bomb_LD = (4, Weapons.Mk_82___500lb_GP_Bomb_LD)
Mk_82_Snakeye___500lb_GP_Bomb_HD = (
4,
Weapons.Mk_82_Snakeye___500lb_GP_Bomb_HD,
)
Mk_83___1000lb_GP_Bomb_LD = (4, Weapons.Mk_83___1000lb_GP_Bomb_LD)
Mk_84___2000lb_GP_Bomb_LD = (4, Weapons.Mk_84___2000lb_GP_Bomb_LD)
M117___750lb_GP_Bomb_LD = (4, Weapons.M117___750lb_GP_Bomb_LD)
Mk_77_mod_0 = (4, WeaponsA4EC.Mk_77_mod_0)
Mk_77_mod_1 = (4, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1___100lb_GP_Bomb_LD = (4, Weapons.AN_M30A1___100lb_GP_Bomb_LD)
AN_M57___250lb_GP_Bomb_LD = (4, Weapons.AN_M57___250lb_GP_Bomb_LD)
AN_M64___500lb_GP_Bomb_LD = (4, Weapons.AN_M64___500lb_GP_Bomb_LD)
AN_M65___1000lb_GP_Bomb_LD = (4, Weapons.AN_M65___1000lb_GP_Bomb_LD)
AN_M81 = (4, WeaponsA4EC.AN_M81)
AN_M88 = (4, WeaponsA4EC.AN_M88)
CBU_1_A = (4, WeaponsA4EC.CBU_1_A)
CBU_2_A = (4, WeaponsA4EC.CBU_2_A)
CBU_2B_A = (4, WeaponsA4EC.CBU_2B_A)
CBU_1_A__2_ = (4, WeaponsA4EC.CBU_1_A__2_)
CBU_2_A__2_ = (4, WeaponsA4EC.CBU_2_A__2_)
CBU_2B_A__2_ = (4, WeaponsA4EC.CBU_2B_A__2_)
Mk_20__2__TER__ = (4, WeaponsA4EC.Mk_20__2__TER__)
Mk_81__5__MER__ = (4, WeaponsA4EC.Mk_81__5__MER__)
Mk_81SE__5__MER__ = (4, WeaponsA4EC.Mk_81SE__5__MER__)
Mk_82__2__TER__ = (4, WeaponsA4EC.Mk_82__2__TER__)
Mk_82_Snakeye__2__TER__ = (4, WeaponsA4EC.Mk_82_Snakeye__2__TER__)
AN_M57__5__MER__ = (4, WeaponsA4EC.AN_M57__5__MER__)
AN_M57__2__TER__ = (4, WeaponsA4EC.AN_M57__2__TER__)
AN_M81__5__MER__ = (4, WeaponsA4EC.AN_M81__5__MER__)
AN_M88__5__MER__ = (4, WeaponsA4EC.AN_M88__5__MER__)
Mk4_HIPEG = (4, WeaponsA4EC.Mk4_HIPEG)
Smokewinder___red = (4, Weapons.Smokewinder___red)
Smokewinder___green = (4, Weapons.Smokewinder___green)
Smokewinder___blue = (4, Weapons.Smokewinder___blue)
Smokewinder___white = (4, Weapons.Smokewinder___white)
Smokewinder___yellow = (4, Weapons.Smokewinder___yellow)
Smokewinder___orange = (4, Weapons.Smokewinder___orange)
SUU_25_x_8_LUU_2___Target_Marker_Flares = (
4,
Weapons.SUU_25_x_8_LUU_2___Target_Marker_Flares,
)
class Pylon4:
Fuel_Tank_300_gallons_ = (4, WeaponsA4EC.Fuel_Tank_300_gallons_)
Fuel_Tank_150_gallons = (4, WeaponsA4EC.Fuel_Tank_150_gallons)
LAU_7_GAR_8_Sidewinder_IR_AAM = (4, Weapons.LAU_7_GAR_8_Sidewinder_IR_AAM)
LAU_7_AIM_9P_Sidewinder_IR_AAM = (4, Weapons.LAU_7_AIM_9P_Sidewinder_IR_AAM)
LAU_7_AIM_9P5_Sidewinder_IR_AAM = (4, Weapons.LAU_7_AIM_9P5_Sidewinder_IR_AAM)
LAU_10___4_ZUNI_MK_71 = (4, Weapons.LAU_10___4_ZUNI_MK_71)
LAU_10_2___4_ZUNI_MK_71__ = (4, WeaponsA4EC.LAU_10_2___4_ZUNI_MK_71__)
LAU_3___19_FFAR_M156_WP = (4, Weapons.LAU_3___19_FFAR_M156_WP)
LAU_3___19_FFAR_Mk1_HE = (4, Weapons.LAU_3___19_FFAR_Mk1_HE)
LAU_3___19_FFAR_Mk5_HEAT = (4, Weapons.LAU_3___19_FFAR_Mk5_HEAT)
LAU_3_2___19_FFAR_M156_WP__ = (4, WeaponsA4EC.LAU_3_2___19_FFAR_M156_WP__)
LAU_3_2___19_FFAR_Mk1_HE__ = (4, WeaponsA4EC.LAU_3_2___19_FFAR_Mk1_HE__)
LAU_3_2___19_FFAR_Mk5_HEAT__ = (4, WeaponsA4EC.LAU_3_2___19_FFAR_Mk5_HEAT__)
LAU_68___7_FFAR_M156_WP = (4, Weapons.LAU_68___7_FFAR_M156_WP)
LAU_68___7_FFAR_Mk1_HE = (4, Weapons.LAU_68___7_FFAR_Mk1_HE)
LAU_68___7_FFAR_Mk5_HEAT = (4, Weapons.LAU_68___7_FFAR_Mk5_HEAT)
LAU_68_2___7_FFAR_M156_WP__ = (4, WeaponsA4EC.LAU_68_2___7_FFAR_M156_WP__)
LAU_68_2___7_FFAR_Mk1_HE__ = (4, WeaponsA4EC.LAU_68_2___7_FFAR_Mk1_HE__)
LAU_68_2___7_FFAR_Mk5_HEAT__ = (4, WeaponsA4EC.LAU_68_2___7_FFAR_Mk5_HEAT__)
AGM_45A = (4, Weapons.AGM_45A)
# ERRR {AGM12_C}
# ERRR {AGM12_B}
AGM_62 = (4, Weapons.AGM_62)
Mk_20 = (4, Weapons.Mk_20)
Mk_81 = (4, Weapons.Mk_81)
Mk_81SE = (4, WeaponsA4EC.Mk_81SE)
Mk_82 = (4, Weapons.Mk_82)
Mk_82_SnakeEye = (4, Weapons.Mk_82_SnakeEye)
Mk_83 = (4, Weapons.Mk_83)
Mk_84 = (4, Weapons.Mk_84)
M117 = (4, Weapons.M117)
Mk_77_mod_0 = (4, WeaponsA4EC.Mk_77_mod_0)
Mk_77_mod_1 = (4, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1 = (4, Weapons.AN_M30A1)
AN_M57 = (4, Weapons.AN_M57)
AN_M64 = (4, Weapons.AN_M64)
AN_M65 = (4, Weapons.AN_M65)
AN_M81 = (4, WeaponsA4EC.AN_M81)
AN_M88 = (4, WeaponsA4EC.AN_M88)
CBU_1_A = (4, WeaponsA4EC.CBU_1_A)
CBU_2_A = (4, WeaponsA4EC.CBU_2_A)
CBU_2B_A = (4, WeaponsA4EC.CBU_2B_A)
CBU_1_A__2_ = (4, WeaponsA4EC.CBU_1_A__2_)
CBU_2_A__2_ = (4, WeaponsA4EC.CBU_2_A__2_)
CBU_2B_A__2_ = (4, WeaponsA4EC.CBU_2B_A__2_)
Mk_20__2__TER__ = (4, WeaponsA4EC.Mk_20__2__TER__)
Mk_81__5__MER__ = (4, WeaponsA4EC.Mk_81__5__MER__)
Mk_81SE__5__MER__ = (4, WeaponsA4EC.Mk_81SE__5__MER__)
Mk_82__2__TER__ = (4, WeaponsA4EC.Mk_82__2__TER__)
Mk_82_Snakeye__2__TER__ = (4, WeaponsA4EC.Mk_82_Snakeye__2__TER__)
AN_M57__5__MER__ = (4, WeaponsA4EC.AN_M57__5__MER__)
AN_M57__2__TER__ = (4, WeaponsA4EC.AN_M57__2__TER__)
AN_M81__5__MER__ = (4, WeaponsA4EC.AN_M81__5__MER__)
AN_M88__5__MER__ = (4, WeaponsA4EC.AN_M88__5__MER__)
Mk4_HIPEG = (4, WeaponsA4EC.Mk4_HIPEG)
Smokewinder___red = (4, Weapons.Smokewinder___red)
Smokewinder___green = (4, Weapons.Smokewinder___green)
Smokewinder___blue = (4, Weapons.Smokewinder___blue)
Smokewinder___white = (4, Weapons.Smokewinder___white)
Smokewinder___yellow = (4, Weapons.Smokewinder___yellow)
Smokewinder___orange = (4, Weapons.Smokewinder___orange)
# ERRR <CLEAN>
# ERRR <CLEAN>
class Pylon5:
LAU_7_with_AIM_9B_Sidewinder_IR_AAM = (
5,
Weapons.LAU_7_with_AIM_9B_Sidewinder_IR_AAM,
)
LAU_7_with_AIM_9P_Sidewinder_IR_AAM = (
5,
Weapons.LAU_7_with_AIM_9P_Sidewinder_IR_AAM,
)
LAU_7_with_AIM_9P5_Sidewinder_IR_AAM = (
5,
Weapons.LAU_7_with_AIM_9P5_Sidewinder_IR_AAM,
)
LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG = (
5,
Weapons.LAU_10_pod___4_x_127mm_ZUNI__UnGd_Rkts_Mk71__HE_FRAG,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
5,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
5,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
5,
Weapons.LAU_3_pod___19_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos = (
5,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_M156__Wht_Phos,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE = (
5,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk1__HE,
)
LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT = (
5,
Weapons.LAU_68_pod___7_x_2_75_FFAR__UnGd_Rkts_Mk5__HEAT,
)
AGM_45A_Shrike_ARM = (5, Weapons.AGM_45A_Shrike_ARM)
# ERRR {AGM12_B}
Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets = (
5,
Weapons.Mk_20_Rockeye___490lbs_CBU__247_x_HEAT_Bomblets,
)
Mk_81___250lb_GP_Bomb_LD = (5, Weapons.Mk_81___250lb_GP_Bomb_LD)
Mk_81SE = (5, WeaponsA4EC.Mk_81SE)
Mk_82___500lb_GP_Bomb_LD = (5, Weapons.Mk_82___500lb_GP_Bomb_LD)
Mk_82_Snakeye___500lb_GP_Bomb_HD = (
5,
Weapons.Mk_82_Snakeye___500lb_GP_Bomb_HD,
)
Mk_77_mod_1 = (5, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1___100lb_GP_Bomb_LD = (5, Weapons.AN_M30A1___100lb_GP_Bomb_LD)
AN_M57___250lb_GP_Bomb_LD = (5, Weapons.AN_M57___250lb_GP_Bomb_LD)
AN_M64___500lb_GP_Bomb_LD = (5, Weapons.AN_M64___500lb_GP_Bomb_LD)
AN_M81 = (5, WeaponsA4EC.AN_M81)
AN_M88 = (5, WeaponsA4EC.AN_M88)
LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M257__Para_Illum = (
5,
Weapons.LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M257__Para_Illum,
)
Smokewinder___red = (5, Weapons.Smokewinder___red)
Smokewinder___green = (5, Weapons.Smokewinder___green)
Smokewinder___blue = (5, Weapons.Smokewinder___blue)
Smokewinder___white = (5, Weapons.Smokewinder___white)
Smokewinder___yellow = (5, Weapons.Smokewinder___yellow)
Smokewinder___orange = (5, Weapons.Smokewinder___orange)
SUU_25_x_8_LUU_2___Target_Marker_Flares = (
5,
Weapons.SUU_25_x_8_LUU_2___Target_Marker_Flares,
)
class Pylon5:
LAU_10___4_ZUNI_MK_71 = (5, Weapons.LAU_10___4_ZUNI_MK_71)
LAU_3___19_FFAR_M156_WP = (5, Weapons.LAU_3___19_FFAR_M156_WP)
LAU_3___19_FFAR_Mk1_HE = (5, Weapons.LAU_3___19_FFAR_Mk1_HE)
LAU_3___19_FFAR_Mk5_HEAT = (5, Weapons.LAU_3___19_FFAR_Mk5_HEAT)
LAU_68___7_FFAR_M156_WP = (5, Weapons.LAU_68___7_FFAR_M156_WP)
LAU_68___7_FFAR_Mk1_HE = (5, Weapons.LAU_68___7_FFAR_Mk1_HE)
LAU_68___7_FFAR_Mk5_HEAT = (5, Weapons.LAU_68___7_FFAR_Mk5_HEAT)
AGM_45A = (5, Weapons.AGM_45A)
# ERRR {AGM12_B}
Mk_20 = (5, Weapons.Mk_20)
Mk_81 = (5, Weapons.Mk_81)
Mk_81SE = (5, WeaponsA4EC.Mk_81SE)
Mk_82 = (5, Weapons.Mk_82)
Mk_82_SnakeEye = (5, Weapons.Mk_82_SnakeEye)
Mk_77_mod_1 = (5, WeaponsA4EC.Mk_77_mod_1)
AN_M30A1 = (5, Weapons.AN_M30A1)
AN_M57 = (5, Weapons.AN_M57)
AN_M64 = (5, Weapons.AN_M64)
AN_M81 = (5, WeaponsA4EC.AN_M81)
AN_M88 = (5, WeaponsA4EC.AN_M88)
LAU_68___7_2_75__rockets_M257__Parachute_illumination_ = (
5,
Weapons.LAU_68___7_2_75__rockets_M257__Parachute_illumination_,
)
Smokewinder___red = (5, Weapons.Smokewinder___red)
Smokewinder___green = (5, Weapons.Smokewinder___green)
Smokewinder___blue = (5, Weapons.Smokewinder___blue)
Smokewinder___white = (5, Weapons.Smokewinder___white)
Smokewinder___yellow = (5, Weapons.Smokewinder___yellow)
Smokewinder___orange = (5, Weapons.Smokewinder___orange)
# ERRR <CLEAN>

View File

@@ -1766,15 +1766,15 @@ class F_22A(PlaneType):
Fuel_tank_610_gal = (2, Weapons.Fuel_tank_610_gal)
class Pylon3:
AIM_120C = (3, Weapons.AIM_120C_5_AMRAAM___Active_Rdr_AAM)
AIM_120C = (3, Weapons.AIM_120C)
AIM_120D = (3, F22AWeapons.AIM_120D)
class Pylon4:
AIM_120C = (4, Weapons.AIM_120C_5_AMRAAM___Active_Rdr_AAM)
AIM_120C = (4, Weapons.AIM_120C)
AIM_120D = (4, F22AWeapons.AIM_120D)
class Pylon5:
AIM_120C = (5, Weapons.AIM_120C_5_AMRAAM___Active_Rdr_AAM)
AIM_120C = (5, Weapons.AIM_120C)
AIM_120D = (5, F22AWeapons.AIM_120D)
class Pylon6:
@@ -1785,15 +1785,15 @@ class F_22A(PlaneType):
Smokewinder___yellow = (6, Weapons.Smokewinder___yellow)
class Pylon7:
AIM_120C = (7, Weapons.AIM_120C_5_AMRAAM___Active_Rdr_AAM)
AIM_120C = (7, Weapons.AIM_120C)
AIM_120D = (7, F22AWeapons.AIM_120D)
class Pylon8:
AIM_120C = (8, Weapons.AIM_120C_5_AMRAAM___Active_Rdr_AAM)
AIM_120C = (8, Weapons.AIM_120C)
AIM_120D = (8, F22AWeapons.AIM_120D)
class Pylon9:
AIM_120C = (9, Weapons.AIM_120C_5_AMRAAM___Active_Rdr_AAM)
AIM_120C = (9, Weapons.AIM_120C)
AIM_120D = (9, F22AWeapons.AIM_120D)
class Pylon10:

View File

@@ -1056,7 +1056,7 @@ class Hercules(PlaneType):
class Pylon2:
LAU_68___7_2_75__rockets_M257__Parachute_illumination_ = (
2,
Weapons.LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M257__Para_Illum,
Weapons.LAU_68___7_2_75__rockets_M257__Parachute_illumination_,
)
Smokewinder___red = (2, Weapons.Smokewinder___red)
Smokewinder___green = (2, Weapons.Smokewinder___green)
@@ -1064,13 +1064,13 @@ class Hercules(PlaneType):
Smokewinder___white = (2, Weapons.Smokewinder___white)
Smokewinder___yellow = (2, Weapons.Smokewinder___yellow)
Smokewinder___orange = (2, Weapons.Smokewinder___orange)
MER_6_Mk_82 = (2, Weapons.MER6_with_6_x_Mk_82___500lb_GP_Bombs_LD)
MER_6_Mk_82 = (2, Weapons.MER_6_Mk_82)
Herc_Ext_Fuel_Tank = (2, HerculesWeapons.Herc_Ext_Fuel_Tank)
class Pylon3:
LAU_68___7_2_75__rockets_M257__Parachute_illumination_ = (
3,
Weapons.LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M257__Para_Illum,
Weapons.LAU_68___7_2_75__rockets_M257__Parachute_illumination_,
)
Smokewinder___red = (3, Weapons.Smokewinder___red)
Smokewinder___green = (3, Weapons.Smokewinder___green)
@@ -1078,13 +1078,13 @@ class Hercules(PlaneType):
Smokewinder___white = (3, Weapons.Smokewinder___white)
Smokewinder___yellow = (3, Weapons.Smokewinder___yellow)
Smokewinder___orange = (3, Weapons.Smokewinder___orange)
MER_6_Mk_82 = (3, Weapons.MER6_with_6_x_Mk_82___500lb_GP_Bombs_LD)
MER_6_Mk_82 = (3, Weapons.MER_6_Mk_82)
Herc_Ext_Fuel_Tank = (3, HerculesWeapons.Herc_Ext_Fuel_Tank)
class Pylon4:
LAU_68___7_2_75__rockets_M257__Parachute_illumination_ = (
4,
Weapons.LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M257__Para_Illum,
Weapons.LAU_68___7_2_75__rockets_M257__Parachute_illumination_,
)
Smokewinder___red = (4, Weapons.Smokewinder___red)
Smokewinder___green = (4, Weapons.Smokewinder___green)
@@ -1092,13 +1092,13 @@ class Hercules(PlaneType):
Smokewinder___white = (4, Weapons.Smokewinder___white)
Smokewinder___yellow = (4, Weapons.Smokewinder___yellow)
Smokewinder___orange = (4, Weapons.Smokewinder___orange)
MER_6_Mk_82 = (4, Weapons.MER6_with_6_x_Mk_82___500lb_GP_Bombs_LD)
MER_6_Mk_82 = (4, Weapons.MER_6_Mk_82)
Herc_Ext_Fuel_Tank = (4, HerculesWeapons.Herc_Ext_Fuel_Tank)
class Pylon5:
LAU_68___7_2_75__rockets_M257__Parachute_illumination_ = (
5,
Weapons.LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M257__Para_Illum,
Weapons.LAU_68___7_2_75__rockets_M257__Parachute_illumination_,
)
Smokewinder___red = (5, Weapons.Smokewinder___red)
Smokewinder___green = (5, Weapons.Smokewinder___green)
@@ -1106,7 +1106,7 @@ class Hercules(PlaneType):
Smokewinder___white = (5, Weapons.Smokewinder___white)
Smokewinder___yellow = (5, Weapons.Smokewinder___yellow)
Smokewinder___orange = (5, Weapons.Smokewinder___orange)
MER_6_Mk_82 = (5, Weapons.MER6_with_6_x_Mk_82___500lb_GP_Bombs_LD)
MER_6_Mk_82 = (5, Weapons.MER_6_Mk_82)
Herc_Ext_Fuel_Tank = (5, HerculesWeapons.Herc_Ext_Fuel_Tank)
class Pylon6:

View File

@@ -3,12 +3,16 @@ from pydcs_extensions.f22a.f22a import F_22A
from pydcs_extensions.hercules.hercules import Hercules
from pydcs_extensions.highdigitsams import highdigitsams
from pydcs_extensions.mb339.mb339 import MB_339PAN
from pydcs_extensions.rafale.rafale import Rafale_M, Rafale_A_S, Rafale_B
from pydcs_extensions.su57.su57 import Su_57
import pydcs_extensions.frenchpack.frenchpack as frenchpack
MODDED_AIRPLANES = [
A_4E_C,
MB_339PAN,
Rafale_A_S,
Rafale_M,
Rafale_B,
Su_57,
F_22A,
Hercules,

File diff suppressed because it is too large Load Diff

View File

@@ -1511,7 +1511,7 @@ class Su_57(PlaneType):
_15 = "15"
class Pylon1:
R_73__AA_11_Archer____Infra_Red = (1, Weapons.R_73__AA_11_Archer____Infra_Red)
R_73 = (1, Weapons.R_73)
RVV_AE = (1, Su57Weapons.RVV_AE)
RVV_M = (1, Su57Weapons.RVV_M)
Smoke_Generator___red = (1, Weapons.Smoke_Generator___red)
@@ -1522,26 +1522,33 @@ class Su_57(PlaneType):
Smoke_Generator___orange = (1, Weapons.Smoke_Generator___orange)
class Pylon2:
R_27R__AA_10_Alamo_A____Semi_Act_Rdr = (
2,
Weapons.R_27R__AA_10_Alamo_A____Semi_Act_Rdr,
)
R_27ER__AA_10_Alamo_C____Semi_Act_Extended_Range = (
2,
Weapons.R_27ER__AA_10_Alamo_C____Semi_Act_Extended_Range,
)
R_27T = (2, Weapons.R_27T__AA_10_Alamo_B____Infra_Red)
R_27ET__AA_10_Alamo_D____IR_Extended_Range = (
2,
Weapons.R_27ET__AA_10_Alamo_D____IR_Extended_Range,
)
R_77__AA_12_Adder____Active_Rdr = (2, Weapons.R_77__AA_12_Adder____Active_Rdr)
R_73__AA_11_Archer____Infra_Red = (2, Weapons.R_73__AA_11_Archer____Infra_Red)
Kh_31P = (2, Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr)
Kh_31A = (2, Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr)
Kh_29L = (2, Weapons.Kh_29L__AS_14_Kedge____657kg__ASM__Semi_Act_Laser)
Kh_29T = (2, Weapons.Kh_29T__AS_14_Kedge____670kg__ASM__TV_Guided)
Kh_59M = (2, Weapons.Kh_59M__AS_18_Kazoo____930kg__ASM__IN)
R_27R = (2, Weapons.R_27R)
R_27ER = (2, Weapons.R_27ER)
R_27T = (2, Weapons.R_27T)
R_27ET = (2, Weapons.R_27ET)
R_77 = (2, Weapons.R_77)
R_73 = (2, Weapons.R_73)
Kh_31P = (2, Weapons.Kh_31P)
Kh_31A = (2, Weapons.Kh_31A)
Kh_29L = (2, Weapons.Kh_29L)
Kh_29T = (2, Weapons.Kh_29T)
Kh_59M = (2, Weapons.Kh_59M)
MER_6_FAB_100 = (2, Weapons.MER_6_FAB_100)
B_8M1___20_S_8KOM = (2, Weapons.B_8M1___20_S_8KOM)
B_13L___5_S_13_OF = (2, Weapons.B_13L___5_S_13_OF)
S_25_OFM = (2, Weapons.S_25_OFM)
BetAB_500 = (2, Weapons.BetAB_500)
KMGU_2___96_AO_2_5RT = (2, Weapons.KMGU_2___96_AO_2_5RT)
KMGU_2___96_PTAB_2_5KO = (2, Weapons.KMGU_2___96_PTAB_2_5KO)
FAB_250 = (2, Weapons.FAB_250)
RBK_250_PTAB_2_5M = (2, Weapons.RBK_250_PTAB_2_5M)
FAB_500_M62 = (2, Weapons.FAB_500_M62)
RBK_500_255_PTAB_10_5 = (2, Weapons.RBK_500_255_PTAB_10_5)
KAB_500L = (2, Weapons.KAB_500L)
KAB_500kr = (2, Weapons.KAB_500kr)
FAB_1500_M54 = (2, Weapons.FAB_1500_M54)
KAB_1500L = (2, Weapons.KAB_1500L)
MER_6_FAB_250 = (2, Weapons.MER_6_FAB_250)
RVV_BD = (2, Su57Weapons.RVV_BD)
RVV_AE = (2, Su57Weapons.RVV_AE)
RVV_M = (2, Su57Weapons.RVV_M)
@@ -1558,7 +1565,7 @@ class Su_57(PlaneType):
Smoke_Generator___orange = (2, Weapons.Smoke_Generator___orange)
class Pylon3:
R_73__AA_11_Archer____Infra_Red = (3, Weapons.R_73__AA_11_Archer____Infra_Red)
R_73 = (3, Weapons.R_73)
Smoke_Generator___red = (3, Weapons.Smoke_Generator___red)
Smoke_Generator___green = (3, Weapons.Smoke_Generator___green)
Smoke_Generator___blue = (3, Weapons.Smoke_Generator___blue)
@@ -1567,29 +1574,33 @@ class Su_57(PlaneType):
Smoke_Generator___orange = (3, Weapons.Smoke_Generator___orange)
class Pylon4:
R_27R__AA_10_Alamo_A____Semi_Act_Rdr = (
4,
Weapons.R_27R__AA_10_Alamo_A____Semi_Act_Rdr,
)
R_27ER__AA_10_Alamo_C____Semi_Act_Extended_Range = (
4,
Weapons.R_27ER__AA_10_Alamo_C____Semi_Act_Extended_Range,
)
R_27T__AA_10_Alamo_B____Infra_Red = (
4,
Weapons.R_27T__AA_10_Alamo_B____Infra_Red,
)
R_27ET__AA_10_Alamo_D____IR_Extended_Range = (
4,
Weapons.R_27ET__AA_10_Alamo_D____IR_Extended_Range,
)
R_77__AA_12_Adder____Active_Rdr = (4, Weapons.R_77__AA_12_Adder____Active_Rdr)
R_73__AA_11_Archer____Infra_Red = (4, Weapons.R_73__AA_11_Archer____Infra_Red)
Kh_31P = (4, Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr)
Kh_31A = (4, Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr)
Kh_29L = (4, Weapons.Kh_29L__AS_14_Kedge____657kg__ASM__Semi_Act_Laser)
Kh_29T = (4, Weapons.Kh_29T__AS_14_Kedge____670kg__ASM__TV_Guided)
Kh_59M = (4, Weapons.Kh_59M__AS_18_Kazoo____930kg__ASM__IN)
R_27R = (4, Weapons.R_27R)
R_27ER = (4, Weapons.R_27ER)
R_27T = (4, Weapons.R_27T)
R_27ET = (4, Weapons.R_27ET)
R_77 = (4, Weapons.R_77)
R_73 = (4, Weapons.R_73)
Kh_31P = (4, Weapons.Kh_31P)
Kh_31A = (4, Weapons.Kh_31A)
Kh_29L = (4, Weapons.Kh_29L)
Kh_29T = (4, Weapons.Kh_29T)
Kh_59M = (4, Weapons.Kh_59M)
MER_6_FAB_100 = (4, Weapons.MER_6_FAB_100)
B_8M1___20_S_8KOM = (4, Weapons.B_8M1___20_S_8KOM)
B_13L___5_S_13_OF = (4, Weapons.B_13L___5_S_13_OF)
S_25_OFM = (4, Weapons.S_25_OFM)
BetAB_500 = (4, Weapons.BetAB_500)
KMGU_2___96_AO_2_5RT = (4, Weapons.KMGU_2___96_AO_2_5RT)
KMGU_2___96_PTAB_2_5KO = (4, Weapons.KMGU_2___96_PTAB_2_5KO)
FAB_250 = (4, Weapons.FAB_250)
RBK_250_PTAB_2_5M = (4, Weapons.RBK_250_PTAB_2_5M)
FAB_500_M62 = (4, Weapons.FAB_500_M62)
RBK_500_255_PTAB_10_5 = (4, Weapons.RBK_500_255_PTAB_10_5)
KAB_500L = (4, Weapons.KAB_500L)
KAB_500kr = (4, Weapons.KAB_500kr)
FAB_1500_M54 = (4, Weapons.FAB_1500_M54)
KAB_1500L = (4, Weapons.KAB_1500L)
MER_6_FAB_250 = (4, Weapons.MER_6_FAB_250)
RVV_BD = (4, Su57Weapons.RVV_BD)
RVV_AE = (4, Su57Weapons.RVV_AE)
RVV_M = (4, Su57Weapons.RVV_M)
@@ -1599,50 +1610,57 @@ class Su_57(PlaneType):
Kh_59MK2 = (4, Su57Weapons.Kh_59MK2)
class Pylon5:
R_77__AA_12_Adder____Active_Rdr = (5, Weapons.R_77__AA_12_Adder____Active_Rdr)
R_77 = (5, Weapons.R_77)
RVV_AE = (5, Su57Weapons.RVV_AE)
RVV_M = (5, Su57Weapons.RVV_M)
Kh_59MK2 = (5, Su57Weapons.Kh_59MK2)
class Pylon6:
R_77__AA_12_Adder____Active_Rdr = (6, Weapons.R_77__AA_12_Adder____Active_Rdr)
R_77 = (6, Weapons.R_77)
RVV_AE = (6, Su57Weapons.RVV_AE)
RVV_M = (6, Su57Weapons.RVV_M)
Kh_59MK2 = (6, Su57Weapons.Kh_59MK2)
class Pylon7:
R_77__AA_12_Adder____Active_Rdr = (7, Weapons.R_77__AA_12_Adder____Active_Rdr)
R_77 = (7, Weapons.R_77)
RVV_AE = (7, Su57Weapons.RVV_AE)
RVV_M = (7, Su57Weapons.RVV_M)
Kh_59MK2 = (7, Su57Weapons.Kh_59MK2)
class Pylon8:
R_77__AA_12_Adder____Active_Rdr = (8, Weapons.R_77__AA_12_Adder____Active_Rdr)
R_77 = (8, Weapons.R_77)
RVV_AE = (8, Su57Weapons.RVV_AE)
RVV_M = (8, Su57Weapons.RVV_M)
Kh_59MK2 = (8, Su57Weapons.Kh_59MK2)
class Pylon9:
R_27R__AA_10_Alamo_A____Semi_Act_Rdr = (
9,
Weapons.R_27R__AA_10_Alamo_A____Semi_Act_Rdr,
)
R_27ER__AA_10_Alamo_C____Semi_Act_Extended_Range = (
9,
Weapons.R_27ER__AA_10_Alamo_C____Semi_Act_Extended_Range,
)
R_27T = (9, Weapons.R_27T__AA_10_Alamo_B____Infra_Red)
R_27ET__AA_10_Alamo_D____IR_Extended_Range = (
9,
Weapons.R_27ET__AA_10_Alamo_D____IR_Extended_Range,
)
R_77__AA_12_Adder____Active_Rdr = (9, Weapons.R_77__AA_12_Adder____Active_Rdr)
R_73__AA_11_Archer____Infra_Red = (9, Weapons.R_73__AA_11_Archer____Infra_Red)
Kh_31P = (9, Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr)
Kh_31A = (9, Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr)
Kh_29L = (9, Weapons.Kh_29L__AS_14_Kedge____657kg__ASM__Semi_Act_Laser)
Kh_29T = (9, Weapons.Kh_29T__AS_14_Kedge____670kg__ASM__TV_Guided)
Kh_59M = (9, Weapons.Kh_59M__AS_18_Kazoo____930kg__ASM__IN)
R_27R = (9, Weapons.R_27R)
R_27ER = (9, Weapons.R_27ER)
R_27T = (9, Weapons.R_27T)
R_27ET = (9, Weapons.R_27ET)
R_77 = (9, Weapons.R_77)
R_73 = (9, Weapons.R_73)
Kh_31P = (9, Weapons.Kh_31P)
Kh_31A = (9, Weapons.Kh_31A)
Kh_29L = (9, Weapons.Kh_29L)
Kh_29T = (9, Weapons.Kh_29T)
Kh_59M = (9, Weapons.Kh_59M)
MER_6_FAB_100 = (9, Weapons.MER_6_FAB_100)
B_8M1___20_S_8KOM = (9, Weapons.B_8M1___20_S_8KOM)
B_13L___5_S_13_OF = (9, Weapons.B_13L___5_S_13_OF)
S_25_OFM = (9, Weapons.S_25_OFM)
BetAB_500 = (9, Weapons.BetAB_500)
KMGU_2___96_AO_2_5RT = (9, Weapons.KMGU_2___96_AO_2_5RT)
KMGU_2___96_PTAB_2_5KO = (9, Weapons.KMGU_2___96_PTAB_2_5KO)
FAB_250 = (9, Weapons.FAB_250)
RBK_250_PTAB_2_5M = (9, Weapons.RBK_250_PTAB_2_5M)
FAB_500_M62 = (9, Weapons.FAB_500_M62)
RBK_500_255_PTAB_10_5 = (9, Weapons.RBK_500_255_PTAB_10_5)
KAB_500L = (9, Weapons.KAB_500L)
KAB_500kr = (9, Weapons.KAB_500kr)
FAB_1500_M54 = (9, Weapons.FAB_1500_M54)
KAB_1500L = (9, Weapons.KAB_1500L)
MER_6_FAB_250 = (9, Weapons.MER_6_FAB_250)
RVV_BD = (9, Su57Weapons.RVV_BD)
RVV_AE = (9, Su57Weapons.RVV_AE)
RVV_M = (9, Su57Weapons.RVV_M)
@@ -1652,7 +1670,7 @@ class Su_57(PlaneType):
Kh_59MK2 = (9, Su57Weapons.Kh_59MK2)
class Pylon10:
R_73__AA_11_Archer____Infra_Red = (10, Weapons.R_73__AA_11_Archer____Infra_Red)
R_73 = (10, Weapons.R_73)
Smoke_Generator___red = (10, Weapons.Smoke_Generator___red)
Smoke_Generator___green = (10, Weapons.Smoke_Generator___green)
Smoke_Generator___blue = (10, Weapons.Smoke_Generator___blue)
@@ -1661,26 +1679,33 @@ class Su_57(PlaneType):
Smoke_Generator___orange = (10, Weapons.Smoke_Generator___orange)
class Pylon11:
R_27R__AA_10_Alamo_A____Semi_Act_Rdr = (
11,
Weapons.R_27R__AA_10_Alamo_A____Semi_Act_Rdr,
)
R_27ER__AA_10_Alamo_C____Semi_Act_Extended_Range = (
11,
Weapons.R_27ER__AA_10_Alamo_C____Semi_Act_Extended_Range,
)
R_27T = (11, Weapons.R_27T__AA_10_Alamo_B____Infra_Red)
R_27ET__AA_10_Alamo_D____IR_Extended_Range = (
11,
Weapons.R_27ET__AA_10_Alamo_D____IR_Extended_Range,
)
R_77__AA_12_Adder____Active_Rdr = (11, Weapons.R_77__AA_12_Adder____Active_Rdr)
R_73__AA_11_Archer____Infra_Red = (11, Weapons.R_73__AA_11_Archer____Infra_Red)
Kh_31P = (11, Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr)
Kh_31A = (11, Weapons.Kh_31P__AS_17_Krypton____600kg__ARM__IN__Pas_Rdr)
Kh_29L = (11, Weapons.Kh_29L__AS_14_Kedge____657kg__ASM__Semi_Act_Laser)
Kh_29T = (11, Weapons.Kh_29T__AS_14_Kedge____670kg__ASM__TV_Guided)
Kh_59M = (11, Weapons.Kh_59M__AS_18_Kazoo____930kg__ASM__IN)
R_27R = (11, Weapons.R_27R)
R_27ER = (11, Weapons.R_27ER)
R_27T = (11, Weapons.R_27T)
R_27ET = (11, Weapons.R_27ET)
R_77 = (11, Weapons.R_77)
R_73 = (11, Weapons.R_73)
Kh_31P = (11, Weapons.Kh_31P)
Kh_31A = (11, Weapons.Kh_31A)
Kh_29L = (11, Weapons.Kh_29L)
Kh_29T = (11, Weapons.Kh_29T)
Kh_59M = (11, Weapons.Kh_59M)
MER_6_FAB_100 = (11, Weapons.MER_6_FAB_100)
B_8M1___20_S_8KOM = (11, Weapons.B_8M1___20_S_8KOM)
B_13L___5_S_13_OF = (11, Weapons.B_13L___5_S_13_OF)
S_25_OFM = (11, Weapons.S_25_OFM)
BetAB_500 = (11, Weapons.BetAB_500)
KMGU_2___96_AO_2_5RT = (11, Weapons.KMGU_2___96_AO_2_5RT)
KMGU_2___96_PTAB_2_5KO = (11, Weapons.KMGU_2___96_PTAB_2_5KO)
FAB_250 = (11, Weapons.FAB_250)
RBK_250_PTAB_2_5M = (11, Weapons.RBK_250_PTAB_2_5M)
FAB_500_M62 = (11, Weapons.FAB_500_M62)
RBK_500_255_PTAB_10_5 = (11, Weapons.RBK_500_255_PTAB_10_5)
KAB_500L = (11, Weapons.KAB_500L)
KAB_500kr = (11, Weapons.KAB_500kr)
FAB_1500_M54 = (11, Weapons.FAB_1500_M54)
KAB_1500L = (11, Weapons.KAB_1500L)
MER_6_FAB_250 = (11, Weapons.MER_6_FAB_250)
# ERRR {R-33}
RVV_BD = (11, Su57Weapons.RVV_BD)
RVV_AE = (11, Su57Weapons.RVV_AE)
@@ -1698,7 +1723,7 @@ class Su_57(PlaneType):
Kh_59MK2 = (11, Su57Weapons.Kh_59MK2)
class Pylon12:
R_73__AA_11_Archer____Infra_Red = (12, Weapons.R_73__AA_11_Archer____Infra_Red)
R_73 = (12, Weapons.R_73)
RVV_AE = (12, Su57Weapons.RVV_AE)
RVV_M = (12, Su57Weapons.RVV_M)
Smoke_Generator___red = (12, Weapons.Smoke_Generator___red)

View File

@@ -103,9 +103,7 @@ class DisplayOptions:
waypoint_info = DisplayRule("Waypoint Information", True)
culling = DisplayRule("Display Culling Zones", False)
actual_frontline_pos = DisplayRule("Display Actual Frontline Location", False)
patrol_engagement_range = DisplayRule(
"Display selected patrol engagement range", True
)
barcap_commit_range = DisplayRule("Display selected BARCAP commit range", False)
flight_paths = FlightPathOptions()
blue_threat_zones = ThreatZoneOptions("Blue")
red_threat_zones = ThreatZoneOptions("Red")

View File

@@ -147,16 +147,12 @@ def load_icons():
"./resources/ui/ground_assets/" + category + "_blue.png"
)
ICONS["destroyed"] = QPixmap("./resources/ui/ground_assets/destroyed.png")
ICONS["EWR"] = QPixmap("./resources/ui/ground_assets/ewr.png")
ICONS["EWR_blue"] = QPixmap("./resources/ui/ground_assets/ewr_blue.png")
ICONS["ship"] = QPixmap("./resources/ui/ground_assets/ship.png")
ICONS["ship_blue"] = QPixmap("./resources/ui/ground_assets/ship_blue.png")
ICONS["missile"] = QPixmap("./resources/ui/ground_assets/missile.png")
ICONS["missile_blue"] = QPixmap("./resources/ui/ground_assets/missile_blue.png")
ICONS["nothreat"] = QPixmap("./resources/ui/ground_assets/nothreat.png")
ICONS["nothreat_blue"] = QPixmap("./resources/ui/ground_assets/nothreat_blue.png")
ICONS["coastal"] = QPixmap("./resources/ui/ground_assets/coastal.png")
ICONS["coastal_blue"] = QPixmap("./resources/ui/ground_assets/coastal_blue.png")
ICONS["Generator"] = QPixmap(
"./resources/ui/misc/" + get_theme_icons() + "/generator.png"

View File

@@ -7,7 +7,7 @@ from PySide2.QtWidgets import (
QLabel,
QVBoxLayout,
)
from dcs.weather import CloudPreset, Weather as PydcsWeather
from dcs.weather import Weather as PydcsWeather
import qt_ui.uiconstants as CONST
from game.utils import mps
@@ -162,7 +162,7 @@ class QWeatherWidget(QGroupBox):
self.turn = turn
self.conditions = conditions
self.update_forecast()
self.updateForecast()
self.updateWinds()
def updateWinds(self):
@@ -186,76 +186,55 @@ class QWeatherWidget(QGroupBox):
self.windFL26SpeedLabel.setText(f"{int(windFL26Speed.knots)}kts")
self.windFL26DirLabel.setText(f"{windFL26Dir}º")
def update_forecast_from_preset(self, preset: CloudPreset) -> None:
self.forecastFog.setText("No fog")
if "Rain" in preset.name:
self.forecastRain.setText("Rain")
self.update_forecast_icons("rain")
else:
self.forecastRain.setText("No rain")
self.update_forecast_icons("partly-cloudy")
# We get a description like the following for the cloud preset.
#
# 09 ##Two Layer Broken/Scattered \nMETAR:BKN 7.5/10 SCT 20/22 FEW41
#
# The second line is probably interesting but doesn't fit into the widget
# currently, so for now just extract the first line.
self.forecastClouds.setText(preset.description.splitlines()[0].split("##")[1])
def update_forecast(self):
def updateForecast(self):
"""Updates the Forecast Text and icon with the current conditions wind info."""
if (
self.conditions.weather.clouds
and self.conditions.weather.clouds.preset is not None
):
self.update_forecast_from_preset(self.conditions.weather.clouds.preset)
return
icon = []
if self.conditions.weather.clouds is None:
cloud_density = 0
cloudDensity = 0
precipitation = None
else:
cloud_density = self.conditions.weather.clouds.density
cloudDensity = self.conditions.weather.clouds.density
precipitation = self.conditions.weather.clouds.precipitation
if not cloud_density:
fog = self.conditions.weather.fog or None
is_night = self.conditions.time_of_day == TimeOfDay.Night
time = "night" if is_night else "day"
if cloudDensity <= 0:
self.forecastClouds.setText("Sunny")
weather_type = "clear"
elif cloud_density < 3:
icon = [time, "clear"]
if cloudDensity > 0 and cloudDensity < 3:
self.forecastClouds.setText("Partly Cloudy")
weather_type = "partly-cloudy"
elif cloud_density < 5:
icon = [time, "partly-cloudy"]
if cloudDensity >= 3 and cloudDensity < 5:
self.forecastClouds.setText("Mostly Cloudy")
weather_type = "partly-cloudy"
else:
icon = [time, "partly-cloudy"]
if cloudDensity >= 5:
self.forecastClouds.setText("Totally Cloudy")
weather_type = "partly-cloudy"
icon = [time, "partly-cloudy"]
if precipitation == PydcsWeather.Preceptions.Rain:
self.forecastRain.setText("Rain")
weather_type = "rain"
icon = [time, "rain"]
elif precipitation == PydcsWeather.Preceptions.Thunderstorm:
self.forecastRain.setText("Thunderstorm")
weather_type = "thunderstorm"
else:
self.forecastRain.setText("No rain")
icon = [time, "thunderstorm"]
if not self.conditions.weather.fog is not None:
else:
self.forecastRain.setText("No Rain")
if not fog:
self.forecastFog.setText("No fog")
else:
visibility = round(self.conditions.weather.fog.visibility.nautical_miles, 1)
visibility = round(fog.visibility.nautical_miles, 1)
self.forecastFog.setText(f"Fog vis: {visibility}nm")
if cloud_density > 1:
weather_type = "cloudy-fog"
else:
weather_type = "fog"
icon = [time, ("cloudy" if cloudDensity > 1 else None), "fog"]
self.update_forecast_icons(weather_type)
def update_forecast_icons(self, weather_type: str) -> None:
time = "night" if self.conditions.time_of_day == TimeOfDay.Night else "day"
icon_key = f"Weather_{time}-{weather_type}"
icon_key = "Weather_{}".format("-".join(filter(None.__ne__, icon)))
icon = CONST.ICONS.get(icon_key) or CONST.ICONS["Weather_night-partly-cloudy"]
self.weather_icon.setPixmap(icon)

View File

@@ -90,12 +90,6 @@ class QAircraftTypeSelector(QComboBox):
f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}",
userData=aircraft,
)
elif mission_type in [FlightType.AEWC]:
if aircraft in gen.flights.ai_flight_planner_db.AEWC_CAPABLE:
self.addItem(
f"{db.unit_get_expanded_info(self.country, aircraft, 'name')}",
userData=aircraft,
)
current_aircraft_index = self.findData(current_aircraft)
if current_aircraft_index != -1:
self.setCurrentIndex(current_aircraft_index)

View File

@@ -58,8 +58,6 @@ from gen.flights.flightplan import (
FlightPlan,
FlightPlanBuilder,
InvalidObjectiveLocation,
PatrollingFlightPlan,
TarCapFlightPlan,
)
from gen.flights.traveltime import TotEstimator
from qt_ui.displayoptions import DisplayOptions, ThreatZoneOptions
@@ -497,7 +495,6 @@ class QLiberationMap(QGraphicsView):
package = Package(target)
flight = Flight(
package,
self.game.player_country if player else self.game.enemy_country,
F_16C_50,
2,
task,
@@ -723,11 +720,13 @@ class QLiberationMap(QGraphicsView):
)
prev_pos = tuple(new_pos)
if selected and DisplayOptions.patrol_engagement_range:
self.draw_patrol_commit_range(scene, flight)
if selected and DisplayOptions.barcap_commit_range:
self.draw_barcap_commit_range(scene, flight)
def draw_patrol_commit_range(self, scene: QGraphicsScene, flight: Flight) -> None:
if not isinstance(flight.flight_plan, PatrollingFlightPlan):
def draw_barcap_commit_range(self, scene: QGraphicsScene, flight: Flight) -> None:
if flight.flight_type is not FlightType.BARCAP:
return
if not isinstance(flight.flight_plan, BarCapFlightPlan):
return
start = flight.flight_plan.patrol_start
end = flight.flight_plan.patrol_end

View File

@@ -9,10 +9,7 @@ from game import Game
from game.data.building_data import FORTIFICATION_BUILDINGS
from game.db import REWARDS
from game.theater import ControlPoint, TheaterGroundObject
from game.theater.theatergroundobject import (
MissileSiteGroundObject,
CoastalSiteGroundObject,
)
from game.theater.theatergroundobject import MissileSiteGroundObject
from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu
from .QMapObject import QMapObject
from ...displayoptions import DisplayOptions
@@ -88,8 +85,6 @@ class QMapGroundObject(QMapObject):
cat = "ship"
if isinstance(self.ground_object, MissileSiteGroundObject):
cat = "missile"
if isinstance(self.ground_object, CoastalSiteGroundObject):
cat = "coastal"
rect = QRect(
option.rect.x() + 2,

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