diff --git a/changelog.md b/changelog.md index bd9891a8..7d17b7f7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,27 @@ +# 2.1.0 + +## Features/Improvements : + +* **[Campaign Generator]** Added Syria map +* **[Campaign Generator]** Added 5 campaigns for the Syria map +* **[Campaign Generator]** Added 2 small scale campaign for Persian Gulf map +* **[Units/Factions]** Added factions for Syria map : Syria 2011, Arab Armies 1982, 1973, 1968, 1948, Israel 1982, 1973, 1948 +* **[Base Menu]** Budget is visible in recruitment menu. (Thanks to Github contributor root0fall) +* **[Misc]** Added error message in mission when the state file can not be written +* **[Units/Factions]** China, Pakistan, UAE will now use the new WingLoong drone as JTAC instead of the MQ-9 Reaper +* **[Units/Factions]** Minor changes to Syria 2011 and Turkey 2005 factions +* **[UI]** Version number is shown in about dialog + +## Fixed issues : + +* **[Mission Generator]** Caucasus terrain improvement on exclusions zone (added forests between Vaziani and Beslan to exclusion zones) +* **[Mission Generator]** The first unit of every base defenses group could not be controlled with Combined Arms. +* **[Mission Generator]** Reduced generated helicopter altitude for CAS missions +* **[Mission Generator]** F-16C default CAS payload was asymmetric, fixed. +* **[Mission Generator]** AH-1W couldn't be bought, and added default payloads. +* **[UI/UX]** Fixed Mi-28N missing thumbnail +* **[UI/UX]** Fixed list of flights not refreshing when changing the mission departure (T+). + # 2.0.11 ## Features/Improvements : @@ -42,7 +66,7 @@ * **[Mission Generator]** The briefing will now contain the carrier ATC frequency * **[Mission Generator]** The briefing contains a small situation update. * **[Mission Generator]** Previously destroyed units are visible in the mission. (And added a performance settings to disable this behaviour) -* **[Mission Generator]** Basic JTAC on Frontlines +* **[Mission Generator]*c* Basic JTAC on Frontlines * **[Campaign Generator]** Added Tarawa in caucasus campaigns * **[Campaign Generator]** Tuned the various existing campaign parameters * **[Campaign Generator]** Added small campaign : "Russia" on Caucasus Theater diff --git a/game/db.py b/game/db.py index 81193426..9c91cbda 100644 --- a/game/db.py +++ b/game/db.py @@ -27,6 +27,8 @@ from game.factions.germany_1990 import Germany_1990 from game.factions.insurgent import Insurgent from game.factions.insurgent_modded import Insurgent_modded from game.factions.iran_2015 import Iran_2015 +from game.factions.israel_1948 import Israel_1948 +from game.factions.israel_1973 import Israel_1973, Israel_1973_NO_WW2_UNITS, Israel_1982 from game.factions.israel_2000 import Israel_2000 from game.factions.italy_1990 import Italy_1990 from game.factions.italy_1990_mb339 import Italy_1990_MB339 @@ -45,6 +47,7 @@ from game.factions.russia_1990 import Russia_1990 from game.factions.russia_2010 import Russia_2010 from game.factions.spain_1990 import Spain_1990 from game.factions.sweden_1990 import Sweden_1990 +from game.factions.syria import Syria_2011, Syria_1967, Syria_1967_WW2_Weapons, Syria_1973, Arab_Armies_1948, Syria_1982 from game.factions.turkey_2005 import Turkey_2005 from game.factions.uae_2005 import UAE_2005 from game.factions.uk_1944 import UK_1944 @@ -140,6 +143,7 @@ PRICES = { MiG_29A: 18, MiG_29S: 20, MiG_29G: 18, + MiG_25PD: 20, MiG_31: 30, J_11A: 26, JF_17: 20, @@ -171,6 +175,7 @@ PRICES = { F_15C: 22, F_15E: 24, F_16C_50: 20, + F_16A: 14, F_14B: 24, Tornado_IDS: 20, Tornado_GR4: 20, @@ -208,18 +213,18 @@ PRICES = { B_1B: 50, # special - IL_76MD: 13, - An_26B: 13, - An_30M: 13, - Yak_40: 13, - S_3B_Tanker: 13, - IL_78M: 13, - KC_135: 13, - KC130: 13, + IL_76MD: 30, + An_26B: 25, + An_30M: 25, + Yak_40: 25, + S_3B_Tanker: 20, + IL_78M: 25, + KC_135: 25, + KC130: 25, - A_50: 8, - E_3A: 8, - C_130: 8, + A_50: 50, + E_3A: 50, + C_130: 25, # WW2 P_51D_30_NA: 18, @@ -227,6 +232,11 @@ PRICES = { P_47D_30: 18, B_17G: 30, + # Drones + MQ_9_Reaper: 12, + RQ_1A_Predator: 6, + WingLoong_I: 6, + # Modded Rafale_M: 26, Rafale_A_S: 26, @@ -390,17 +400,19 @@ Following tasks are present: UNIT_BY_TASK = { CAP: [ F_5E_3, - MiG_23MLD, Su_27, Su_33, MiG_19P, MiG_21Bis, + MiG_23MLD, + MiG_25PD, MiG_29A, MiG_29S, MiG_31, FA_18C_hornet, F_15C, F_14B, + F_16A, F_16C_50, M_2000C, Mirage_2000_5, @@ -457,7 +469,11 @@ UNIT_BY_TASK = { Ju_88A4, B_17G, MB_339PAN, - Rafale_A_S + Rafale_A_S, + WingLoong_I, + MQ_9_Reaper, + RQ_1A_Predator, + AH_1W ], Transport: [ IL_76MD, @@ -767,6 +783,16 @@ FACTIONS = { "Italy 1990 (With MB339)": Italy_1990_MB339, "Israel 2000": Israel_2000, + "Israel 1982": Israel_1982, + "Israel 1973 (WW2 Pack)": Israel_1973, + "Israel 1973": Israel_1973_NO_WW2_UNITS, + "Israel 1948": Israel_1948, + + "Arab Armies 1982": Syria_1982, + "Arab Armies 1973": Syria_1973, + "Arab Armies 1967 (WW2 Pack)": Syria_1967_WW2_Weapons, + "Arab Armies 1967": Syria_1967, + "Arab League 1948": Arab_Armies_1948, "China 2010": China_2010, @@ -788,6 +814,9 @@ FACTIONS = { "Libya 2011": Libya_2011, + "Syria 2011": Syria_2011, + + "Pakistan 2015": Pakistan_2015, "Iran 2015": Iran_2015, @@ -925,6 +954,11 @@ PLANE_PAYLOAD_OVERRIDES = { Rafale_M: COMMON_OVERRIDE, Rafale_A_S: COMMON_OVERRIDE, OH_58D: COMMON_OVERRIDE, + F_16A: COMMON_OVERRIDE, + MQ_9_Reaper: COMMON_OVERRIDE, + RQ_1A_Predator: COMMON_OVERRIDE, + WingLoong_I: COMMON_OVERRIDE, + AH_1W: COMMON_OVERRIDE, AH_64D:{ CAS: "AGM-114K*16" @@ -982,7 +1016,11 @@ TIME_PERIODS = { "Modern - Summer [2010]": datetime(2010, 6, 1), "Modern - Fall [2010]": datetime(2010, 10, 1), "Georgian War [2008]": datetime(2008, 8, 7), - "Syrian War [2011]": datetime(2011, 8, 7), + "Syrian War [2011]": datetime(2011, 3, 15), + "6 days war [1967]": datetime(1967, 6, 5), + "Yom Kippour War [1973]": datetime(1973, 10, 6), + "Lebanon War [1982]": datetime(1982, 6, 6), + "Arab-Israeli War [1948]": datetime(1948, 5, 15), } REWARDS = { @@ -1030,6 +1068,7 @@ LHA_CAPABLE = [ SA342Mistral ] + """ ---------- END OF CONFIGURATION SECTION """ diff --git a/game/factions/china_2010.py b/game/factions/china_2010.py index b13faec4..148fdbd0 100644 --- a/game/factions/china_2010.py +++ b/game/factions/china_2010.py @@ -23,6 +23,7 @@ China_2010 = { A_50, Mi_8MT, + Mi_28N, AirDefence.SAM_SA_10_S_300PS_LN_5P85C, # Standing as HQ-9+ AirDefence.SAM_SA_6_Kub_LN_2P25, @@ -73,5 +74,7 @@ China_2010 = { "002 Shandong", ], "boat":[ "Type54GroupGenerator" - ], "has_jtac": True + ], + "has_jtac": True, + "jtac_unit": WingLoong_I } \ No newline at end of file diff --git a/game/factions/germany_1944.py b/game/factions/germany_1944.py index f5f95669..9123b350 100644 --- a/game/factions/germany_1944.py +++ b/game/factions/germany_1944.py @@ -32,7 +32,9 @@ Germany_1944 = { Infantry.Infantry_Mauser_98, AirDefence.AAA_8_8cm_Flak_36, - ], + ],"requirements":{ + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, "shorad": [ AirDefence.AAA_8_8cm_Flak_36, ], diff --git a/game/factions/germany_1944_easy.py b/game/factions/germany_1944_easy.py index 6e4474bb..b79d45f0 100644 --- a/game/factions/germany_1944_easy.py +++ b/game/factions/germany_1944_easy.py @@ -25,7 +25,9 @@ Germany_1944_Easy = { Infantry.Infantry_Mauser_98, AirDefence.AAA_8_8cm_Flak_36, - ], + ],"requirements":{ + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, "shorad":[ AirDefence.AAA_8_8cm_Flak_36, ], diff --git a/game/factions/insurgent.py b/game/factions/insurgent.py index 93e0bc32..d94603c6 100644 --- a/game/factions/insurgent.py +++ b/game/factions/insurgent.py @@ -12,11 +12,13 @@ Insurgent = { AirDefence.AAA_ZU_23_Insurgent_on_Ural_375, Armor.APC_Cobra, + Armor.APC_MTLB, + Armor.ARV_BRDM_2, Unarmed.Transport_Ural_375, Unarmed.Transport_UAZ_469, - Infantry.Soldier_AK, Infantry.Infantry_Soldier_Insurgents, + Infantry.Soldier_RPG, Bulk_cargo_ship_Yakushev, Dry_cargo_ship_Ivanov, diff --git a/game/factions/israel_1948.py b/game/factions/israel_1948.py new file mode 100644 index 00000000..ffa57fcb --- /dev/null +++ b/game/factions/israel_1948.py @@ -0,0 +1,33 @@ +from dcs.planes import * +from dcs.ships import * +from dcs.vehicles import * + +Israel_1948 = { + "country": "Israel", + "side": "blue", + "units":[ + SpitfireLFMkIXCW, + SpitfireLFMkIX, + P_51D, + P_51D_30_NA, + Bf_109K_4, # Standing as Avia S-199 + B_17G, + + Armor.MT_M4A4_Sherman_Firefly, + Armor.APC_M2A1, + Armor.MT_M4_Sherman, + Armor.LAC_M8_Greyhound, + + Unarmed.Transport_M818, + Infantry.Infantry_SMLE_No_4_Mk_1, + + AirDefence.AAA_Bofors_40mm, + Armed_speedboat, + ],"requirements":{ + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, + "shorad": [ + AirDefence.AAA_Bofors_40mm + ], "boat": [ + ], "has_jtac": False +} \ No newline at end of file diff --git a/game/factions/israel_1973.py b/game/factions/israel_1973.py new file mode 100644 index 00000000..00624ec9 --- /dev/null +++ b/game/factions/israel_1973.py @@ -0,0 +1,112 @@ +from dcs.helicopters import * +from dcs.planes import * +from dcs.ships import * +from dcs.vehicles import * + +from pydcs_extensions.a4ec.a4ec import A_4E_C + +Israel_1973 = { + "country": "Israel", + "side": "blue", + "units":[ + F_4E, + A_4E_C, + + KC_135, + KC130, + C_130, + E_3A, + + UH_1H, + + Armor.MT_M4A4_Sherman_Firefly, + Armor.APC_M2A1, + Armor.MBT_M60A3_Patton, + Armor.APC_M113, + + Unarmed.Transport_M818, + Infantry.Infantry_M4, + + AirDefence.SAM_Hawk_PCP, + AirDefence.AAA_Bofors_40mm, + AirDefence.SAM_Chaparral_M48, + + Armed_speedboat, + ], "requirements": { + "Community A-4E": "https://heclak.github.io/community-a4e-c/", + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, "shorad": [ + AirDefence.SAM_Chaparral_M48, + AirDefence.AAA_Bofors_40mm + ], "boat": [ + ], "has_jtac": True +} + +Israel_1973_NO_WW2_UNITS = { + "country": "Israel", + "side": "blue", + "units":[ + F_4E, + A_4E_C, + + KC_135, + KC130, + C_130, + E_3A, + + UH_1H, + + Armor.MBT_M60A3_Patton, + Armor.APC_M113, + + Unarmed.Transport_M818, + Infantry.Infantry_M4, + + AirDefence.SAM_Hawk_PCP, + AirDefence.SAM_Chaparral_M48, + + Armed_speedboat, + ], "requirements": { + "Community A-4E": "https://heclak.github.io/community-a4e-c/", + }, "shorad": [ + AirDefence.SAM_Chaparral_M48, + ], "boat": [ + ], "has_jtac": True +} + +Israel_1982 = { + "country": "Israel", + "side": "blue", + "units":[ + F_4E, + A_4E_C, + F_15C, + F_16A, + F_16C_50, + + KC_135, + KC130, + C_130, + E_3A, + + UH_1H, + AH_1W, + + Armor.APC_M113, + Armor.MBT_M60A3_Patton, + Armor.MBT_Merkava_Mk__4, + + Unarmed.Transport_M818, + Infantry.Infantry_M4, + + AirDefence.SAM_Hawk_PCP, + AirDefence.SAM_Chaparral_M48, + + Armed_speedboat, + ], "requirements": { + "Community A-4E": "https://heclak.github.io/community-a4e-c/", + }, "shorad": [ + AirDefence.SAM_Chaparral_M48, + ], "boat": [ + ], "has_jtac": True +} \ No newline at end of file diff --git a/game/factions/israel_2000.py b/game/factions/israel_2000.py index 163bbfe3..6c0db9c0 100644 --- a/game/factions/israel_2000.py +++ b/game/factions/israel_2000.py @@ -9,6 +9,7 @@ Israel_2000 = { "units":[ F_16C_50, F_15C, + F_15E, F_4E, KC_135, @@ -21,6 +22,10 @@ Israel_2000 = { Armor.MBT_Merkava_Mk__4, Armor.APC_M113, + Armor.APC_M1043_HMMWV_Armament, + Armor.ATGM_M1045_HMMWV_TOW, + Artillery.SPH_M109_Paladin, + Artillery.MLRS_M270, Unarmed.Transport_M818, Infantry.Infantry_M4, diff --git a/game/factions/pakistan_2015.py b/game/factions/pakistan_2015.py index b5fa5f29..67bfa2aa 100644 --- a/game/factions/pakistan_2015.py +++ b/game/factions/pakistan_2015.py @@ -36,5 +36,7 @@ Pakistan_2015 = { AirDefence.AAA_ZU_23_Closed ], "boat": [ "Type54GroupGenerator", "OliverHazardPerryGroupGenerator" - ], "has_jtac": True + ], + "has_jtac": True, + "jtac_unit": WingLoong_I } diff --git a/game/factions/syria.py b/game/factions/syria.py new file mode 100644 index 00000000..b14df3db --- /dev/null +++ b/game/factions/syria.py @@ -0,0 +1,261 @@ +from dcs.helicopters import * +from dcs.planes import * +from dcs.vehicles import * + +Syria_2011 = { + "country": "Syria", + "side": "red", + "units": [ + + MiG_29S, + MiG_25PD, + L_39ZA, + Su_24M, + Su_17M4, + Mi_24V, + SA342M, + Mi_8MT, + + IL_76MD, + IL_78M, + An_26B, + An_30M, + Yak_40, + A_50, + + AirDefence.SAM_SA_6_Kub_LN_2P25, + AirDefence.SAM_SA_3_S_125_LN_5P73, + AirDefence.SAM_SA_2_LN_SM_90, + AirDefence.SAM_SA_8_Osa_9A33, + AirDefence.SAM_SA_11_Buk_LN_9A310M1, + AirDefence.SAM_SA_10_S_300PS_LN_5P85C, + + Armor.IFV_BMP_1, + Armor.IFV_BMP_2, + Armor.APC_BTR_80, + Armor.ARV_BRDM_2, + Armor.APC_MTLB, + Armor.APC_Cobra, + Armor.MBT_T_55, + Armor.MBT_T_72B, + Armor.MBT_T_90, + Artillery.MLRS_BM_21_Grad, + Artillery.MLRS_9K57_Uragan_BM_27, + Artillery.SPH_2S1_Gvozdika, + Artillery.SPH_2S9_Nona, + + Unarmed.Transport_Ural_375, + Unarmed.Transport_UAZ_469, + + Infantry.Paratrooper_RPG_16, + Infantry.Soldier_AK + + ], + "shorad": [ + AirDefence.SAM_SA_8_Osa_9A33, + AirDefence.SAM_SA_13_Strela_10M3_9A35M3, + AirDefence.SAM_SA_9_Strela_1_9P31, + AirDefence.SAM_SA_19_Tunguska_2S6, + AirDefence.AAA_ZU_23_on_Ural_375, + ], "boat": [ + "GrishaGroupGenerator", "MolniyaGroupGenerator" + ] +} + +Syria_1973 = { + "country": "Syria", + "side": "red", + "units": [ + + MiG_21Bis, + MiG_19P, + MiG_15bis, # Standing as Mig-17 + + Su_17M4, # Standing as Su-7 + Mi_8MT, + + IL_76MD, + IL_78M, + An_26B, + An_30M, + Yak_40, + + AirDefence.SAM_SA_6_Kub_LN_2P25, + AirDefence.SAM_SA_3_S_125_LN_5P73, + AirDefence.SAM_SA_2_LN_SM_90, + + Armor.IFV_BMP_1, + Armor.APC_MTLB, + Armor.MBT_T_55, + Artillery.MLRS_BM_21_Grad, + + Unarmed.Transport_Ural_375, + Unarmed.Transport_UAZ_469, + + Infantry.Paratrooper_RPG_16, + Infantry.Soldier_AK + + ], + "shorad": [ + AirDefence.AAA_ZU_23_on_Ural_375, + ], "boat": [ + "GrishaGroupGenerator" + ] +} + + +Syria_1982 = { + "country": "Syria", + "side": "red", + "units": [ + + MiG_21Bis, + MiG_23MLD, + MiG_25PD, + MiG_19P, + + Su_17M4, # Standing as Su-7 + Mi_8MT, + + IL_76MD, + IL_78M, + An_26B, + An_30M, + Yak_40, + + AirDefence.SAM_SA_6_Kub_LN_2P25, + AirDefence.SAM_SA_3_S_125_LN_5P73, + AirDefence.SAM_SA_2_LN_SM_90, + + Armor.IFV_BMP_1, + Armor.APC_MTLB, + Armor.MBT_T_55, + Armor.MBT_T_72B, + Artillery.MLRS_BM_21_Grad, + + Unarmed.Transport_Ural_375, + Unarmed.Transport_UAZ_469, + + Infantry.Paratrooper_RPG_16, + Infantry.Soldier_AK + + ], + "shorad": [ + AirDefence.AAA_ZU_23_on_Ural_375, + ], "boat": [ + "GrishaGroupGenerator" + ] +} + + +Syria_1967 = { + "country": "Syria", + "side": "red", + "units": [ + + MiG_21Bis, + MiG_19P, + MiG_15bis, # Standing as Mig-17 + + Su_17M4, # Standing as Su-7 + Mi_8MT, + + IL_76MD, + IL_78M, + An_26B, + An_30M, + Yak_40, + + AirDefence.SAM_SA_2_LN_SM_90, + + Armor.ARV_BRDM_2, + Armor.MBT_T_55, + Artillery.MLRS_BM_21_Grad, + + Unarmed.Transport_Ural_375, + Unarmed.Transport_UAZ_469, + + Infantry.Paratrooper_RPG_16, + Infantry.Soldier_AK + + ], + "shorad": [ + AirDefence.AAA_ZU_23_on_Ural_375, + ], "boat": [ + "GrishaGroupGenerator" + ] +} + +Syria_1967_WW2_Weapons = { + "country": "Syria", + "side": "red", + "units": [ + + MiG_21Bis, + MiG_19P, + MiG_15bis, # Standing as Mig-17 + + Su_17M4, # Standing as Su-7 + Mi_8MT, + + IL_76MD, + IL_78M, + An_26B, + An_30M, + Yak_40, + + AirDefence.SAM_SA_2_LN_SM_90, + + Armor.ARV_BRDM_2, + Armor.MBT_T_55, + Armor.MT_Pz_Kpfw_IV_Ausf_H, + Armor.StuG_III_Ausf__G, + Armor.TD_Jagdpanzer_IV, + Artillery.MLRS_BM_21_Grad, + + Unarmed.Transport_Ural_375, + Unarmed.Transport_UAZ_469, + + Infantry.Soldier_RPG, + Infantry.Soldier_AK + + ], "requirements": { + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, + "shorad": [ + AirDefence.AAA_ZU_23_on_Ural_375, + ], "boat": [ + "GrishaGroupGenerator" + ] +} + +Arab_Armies_1948 = { + "country": "Syria", + "side": "red", + "units": [ + SpitfireLFMkIX, + SpitfireLFMkIXCW, + + AirDefence.SAM_SA_2_LN_SM_90, + + Armor.MT_M4_Sherman, + Armor.MT_Pz_Kpfw_IV_Ausf_H, + Armor.APC_Sd_Kfz_251, + Armor.IFV_Sd_Kfz_234_2_Puma, + + Unarmed.Transport_Ural_375, + Unarmed.Transport_UAZ_469, + + Infantry.Infantry_SMLE_No_4_Mk_1, + + AirDefence.AAA_8_8cm_Flak_36, + + ], "requirements": { + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, + "shorad": [ + AirDefence.AAA_8_8cm_Flak_36, + ], "boat": [ + "GrishaGroupGenerator" + ] +} diff --git a/game/factions/turkey_2005.py b/game/factions/turkey_2005.py index 9a0504bf..02b0500d 100644 --- a/game/factions/turkey_2005.py +++ b/game/factions/turkey_2005.py @@ -16,7 +16,6 @@ Turkey_2005 = { E_3A, UH_1H, - OH_58D, AH_1W, Armor.MBT_Leopard_2, diff --git a/game/factions/uae_2005.py b/game/factions/uae_2005.py index 90990493..cc412f06 100644 --- a/game/factions/uae_2005.py +++ b/game/factions/uae_2005.py @@ -32,5 +32,7 @@ UAE_2005 = { Armed_speedboat, ], "boat":[ "OliverHazardPerryGroupGenerator" - ], "has_jtac": True + ], + "has_jtac": True, + "jtac_unit": WingLoong_I } \ No newline at end of file diff --git a/game/factions/uk_1944.py b/game/factions/uk_1944.py index abfaac59..7798d714 100644 --- a/game/factions/uk_1944.py +++ b/game/factions/uk_1944.py @@ -34,7 +34,9 @@ UK_1944 = { AirDefence.AAA_Bofors_40mm, ], "shorad":[ AirDefence.AAA_Bofors_40mm, - ], + ],"requirements":{ + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, "objects": WW2_ALLIES_BUILDINGS, "doctrine": WWII_DOCTRINE, "boat": ["WW2LSTGroupGenerator"], diff --git a/game/factions/usa_1944.py b/game/factions/usa_1944.py index 5ba73237..29e07372 100644 --- a/game/factions/usa_1944.py +++ b/game/factions/usa_1944.py @@ -32,7 +32,9 @@ USA_1944 = { AirDefence.AAA_Bofors_40mm, ], "shorad":[ AirDefence.AAA_Bofors_40mm, - ], + ],"requirements":{ + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, "objects": WW2_ALLIES_BUILDINGS, "doctrine": WWII_DOCTRINE, "boat": ["WW2LSTGroupGenerator"], @@ -74,7 +76,9 @@ ALLIES_1944 = { AirDefence.AAA_Bofors_40mm, ], "shorad":[ AirDefence.AAA_Bofors_40mm, - ], + ],"requirements":{ + "WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/", + }, "objects": WW2_ALLIES_BUILDINGS, "doctrine": WWII_DOCTRINE, "boat": ["WW2LSTGroupGenerator"], diff --git a/gen/armor.py b/gen/armor.py index d2d74a91..5d9a8b29 100644 --- a/gen/armor.py +++ b/gen/armor.py @@ -101,9 +101,14 @@ class GroundConflictGenerator: if "has_jtac" in self.game.player_faction and self.game.player_faction["has_jtac"] and self.game.settings.include_jtac_if_available: n = "JTAC" + str(self.conflict.from_cp.id) + str(self.conflict.to_cp.id) code = 1688 - len(self.game.jtacs) + + utype = MQ_9_Reaper + if "jtac_unit" in self.game.player_faction: + utype = self.game.player_faction["jtac_unit"] + jtac = self.mission.flight_group(country=self.mission.country(self.game.player_country), name=n, - aircraft_type=MQ_9_Reaper, + aircraft_type=utype, position=position[0], airport=None, altitude=5000) diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 06d0355b..1582276d 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -607,7 +607,8 @@ class FlightPlanner: :param flight: Flight to setup :param location: Location of the CAS targets """ - + is_helo = hasattr(flight.unit_type, "helicopter") and flight.unit_type.helicopter + cap_alt = 1000 flight.points = [] flight.flight_type = FlightType.CAS @@ -616,9 +617,12 @@ class FlightPlanner: egress = ingress.point_from_heading(heading, distance) ascend = self.generate_ascend_point(flight.from_cp) + if is_helo: + cap_alt = 500 + ascend.alt = 500 flight.points.append(ascend) - ingress_point = FlightWaypoint(ingress.x, ingress.y, 1000) + ingress_point = FlightWaypoint(ingress.x, ingress.y, cap_alt) ingress_point.alt_type = "RADIO" ingress_point.name = "INGRESS" ingress_point.pretty_name = "INGRESS" @@ -626,7 +630,7 @@ class FlightPlanner: ingress_point.waypoint_type = FlightWaypointType.INGRESS_CAS flight.points.append(ingress_point) - center_point = FlightWaypoint(center.x, center.y, 1000) + center_point = FlightWaypoint(center.x, center.y, cap_alt) center_point.alt_type = "RADIO" center_point.description = "Provide CAS" center_point.name = "CAS" @@ -634,7 +638,7 @@ class FlightPlanner: center_point.waypoint_type = FlightWaypointType.CAS flight.points.append(center_point) - egress_point = FlightWaypoint(egress.x, egress.y, 1000) + egress_point = FlightWaypoint(egress.x, egress.y, cap_alt) egress_point.alt_type = "RADIO" egress_point.description = "Egress from CAS area" egress_point.name = "EGRESS" @@ -643,6 +647,8 @@ class FlightPlanner: flight.points.append(egress_point) descend = self.generate_descend_point(flight.from_cp) + if is_helo: + descend.alt = 300 flight.points.append(descend) rtb = self.generate_rtb_waypoint(flight.from_cp) diff --git a/gen/flights/ai_flight_planner_db.py b/gen/flights/ai_flight_planner_db.py index 70e70e3a..ba989284 100644 --- a/gen/flights/ai_flight_planner_db.py +++ b/gen/flights/ai_flight_planner_db.py @@ -31,6 +31,7 @@ CAP_CAPABLE = [ MiG_19P, MiG_21Bis, MiG_23MLD, + MiG_25PD, MiG_29A, MiG_29G, MiG_29S, @@ -51,6 +52,7 @@ CAP_CAPABLE = [ F_14B, F_15C, F_15E, + F_16A, F_16C_50, FA_18C_hornet, @@ -100,6 +102,7 @@ CAS_CAPABLE = [ F_5E_3, F_14B, F_15E, + F_16A, F_16C_50, FA_18C_hornet, @@ -135,7 +138,11 @@ CAS_CAPABLE = [ FW_190A8, A_4E_C, - Rafale_A_S + Rafale_A_S, + + WingLoong_I, + MQ_9_Reaper, + RQ_1A_Predator ] # Aircraft used for SEAD / DEAD tasks @@ -184,6 +191,7 @@ STRIKE_CAPABLE = [ F_5E_3, F_14B, F_15E, + F_16A, F_16C_50, FA_18C_hornet, @@ -216,10 +224,17 @@ ANTISHIP_CAPABLE = [ F_15E, AV8BNA, JF_17, + F_16A, F_16C_50, A_10C, A_10A, Ju_88A4, Rafale_A_S -] \ No newline at end of file +] + +DRONES = [ + MQ_9_Reaper, + RQ_1A_Predator, + WingLoong_I +] diff --git a/gen/groundobjectsgen.py b/gen/groundobjectsgen.py index 458e5ae9..89a09293 100644 --- a/gen/groundobjectsgen.py +++ b/gen/groundobjectsgen.py @@ -66,6 +66,7 @@ class GroundObjectsGenerator: if not ground_object.sea_object: vg = self.m.vehicle_group(side, g.name, utype, position=g.position, heading=g.units[0].heading) vg.units[0].name = self.m.string(g.units[0].name) + vg.units[0].player_can_drive = True for i, u in enumerate(g.units): if i > 0: vehicle = Vehicle(self.m.next_unit_id(), self.m.string(u.name), u.type) diff --git a/qt_ui/main.py b/qt_ui/main.py index 5b075cdf..e019d32c 100644 --- a/qt_ui/main.py +++ b/qt_ui/main.py @@ -1,9 +1,5 @@ from userdata import logging_config -# Logging setup -VERSION_STRING = "2.0.10" -logging_config.init_logging(VERSION_STRING) - import logging import os import sys @@ -19,6 +15,9 @@ from qt_ui.windows.QLiberationWindow import QLiberationWindow from qt_ui.windows.preferences.QLiberationFirstStartWindow import QLiberationFirstStartWindow from userdata import liberation_install, persistency, liberation_theme +# Logging setup +logging_config.init_logging(uiconstants.VERSION_STRING) + if __name__ == "__main__": os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" # Potential fix for 4K screens diff --git a/qt_ui/uiconstants.py b/qt_ui/uiconstants.py index c0f13eac..c0d52631 100644 --- a/qt_ui/uiconstants.py +++ b/qt_ui/uiconstants.py @@ -8,6 +8,8 @@ from game.event import UnitsDeliveryEvent, FrontlineAttackEvent from theater.theatergroundobject import CATEGORY_MAP from userdata.liberation_theme import get_theme_icons +VERSION_STRING = "2.1.0" + URLS : Dict[str, str] = { "Manual": "https://github.com/khopa/dcs_liberation/wiki", "Repository": "https://github.com/khopa/dcs_liberation", @@ -69,7 +71,7 @@ COLORS: Dict[str, QColor] = { } -CP_SIZE = 24 +CP_SIZE = 12 AIRCRAFT_ICONS: Dict[str, QPixmap] = {} VEHICLES_ICONS: Dict[str, QPixmap] = {} @@ -86,6 +88,7 @@ def load_icons(): ICONS["Terrain_Nevada"] = QPixmap("./resources/ui/terrain_nevada.gif") ICONS["Terrain_Normandy"] = QPixmap("./resources/ui/terrain_normandy.gif") ICONS["Terrain_Channel"] = QPixmap("./resources/ui/terrain_channel.gif") + ICONS["Terrain_Syria"] = QPixmap("./resources/ui/terrain_syria.gif") ICONS["Dawn"] = QPixmap("./resources/ui/daytime/dawn.png") ICONS["Day"] = QPixmap("./resources/ui/daytime/day.png") diff --git a/qt_ui/windows/QLiberationWindow.py b/qt_ui/windows/QLiberationWindow.py index 9e3cd242..382b3289 100644 --- a/qt_ui/windows/QLiberationWindow.py +++ b/qt_ui/windows/QLiberationWindow.py @@ -12,10 +12,9 @@ from game import Game from qt_ui.uiconstants import URLS from qt_ui.widgets.QTopPanel import QTopPanel from qt_ui.widgets.map.QLiberationMap import QLiberationMap -from qt_ui.windows.preferences import QLiberationPreferences from qt_ui.windows.GameUpdateSignal import GameUpdateSignal, DebriefingSignal from qt_ui.windows.QDebriefingWindow import QDebriefingWindow -from qt_ui.windows.QNewGameWizard import NewGameWizard +from qt_ui.windows.newgame.QNewGameWizard import NewGameWizard from qt_ui.windows.infos.QInfoPanel import QInfoPanel from qt_ui.windows.preferences.QLiberationPreferencesWindow import QLiberationPreferencesWindow from userdata import persistency @@ -212,17 +211,16 @@ class QLiberationWindow(QMainWindow): self.info_panel.setGame(game) def showAboutDialog(self): - text = "

DCS Liberation

" + \ + text = "

DCS Liberation " + CONST.VERSION_STRING + "

" + \ "Source code : https://github.com/khopa/dcs_liberation" + \ "

Authors

" + \ "

DCS Liberation was originally developed by shdwp, DCS Liberation 2.0 is a partial rewrite based on this work by Khopa." \ "

Contributors

" + \ - "shdwp, Khopa, Wrycu, calvinmorrow, JohanAberg, Deus" + \ + "shdwp, Khopa, Wrycu, calvinmorrow, JohanAberg, Deus, root0fall, Captain Cody" + \ "

Special Thanks :

" \ "rp- for the pydcs framework
"\ "Grimes (mrSkortch) & Speed for the MIST framework
"\ "Ciribob for the JTACAutoLase.lua script
" - about = QMessageBox() about.setWindowTitle("About DCS Liberation") about.setIcon(QMessageBox.Icon.Information) diff --git a/qt_ui/windows/basemenu/QBaseMenu2.py b/qt_ui/windows/basemenu/QBaseMenu2.py index d74a72b8..678f6098 100644 --- a/qt_ui/windows/basemenu/QBaseMenu2.py +++ b/qt_ui/windows/basemenu/QBaseMenu2.py @@ -7,6 +7,7 @@ from game.event import ControlPointType from qt_ui.uiconstants import EVENT_ICONS from qt_ui.windows.GameUpdateSignal import GameUpdateSignal from qt_ui.windows.basemenu.QBaseMenuTabs import QBaseMenuTabs +from qt_ui.windows.basemenu.QRecruitBehaviour import QRecruitBehaviour from theater import ControlPoint @@ -19,6 +20,7 @@ class QBaseMenu2(QDialog): self.cp = cp self.game = game self.is_carrier = self.cp.cptype in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP] + self.objectName = "menuDialogue" # Widgets self.qbase_menu_tab = QBaseMenuTabs(cp, game) @@ -58,7 +60,6 @@ class QBaseMenu2(QDialog): title.setProperty("style", "base-title") unitsPower = QLabel("{} / {} / Runway : {}".format(self.cp.base.total_planes, self.cp.base.total_armor, "Available" if self.cp.has_runway() else "Unavailable")) - self.topLayout.addWidget(title) self.topLayout.addWidget(unitsPower) self.topLayout.setAlignment(Qt.AlignTop) @@ -69,7 +70,11 @@ class QBaseMenu2(QDialog): self.mainLayout.addWidget(header, 0, 0) self.mainLayout.addWidget(self.topLayoutWidget, 1, 0) self.mainLayout.addWidget(self.qbase_menu_tab, 2, 0) - + totalBudget = QLabel(QRecruitBehaviour.BUDGET_FORMAT.format(self.game.budget)) + totalBudget.setObjectName("budgetField") + totalBudget.setAlignment(Qt.AlignRight | Qt.AlignBottom) + totalBudget.setProperty("style", "budget-label") + self.mainLayout.addWidget(totalBudget) self.setLayout(self.mainLayout) def closeEvent(self, closeEvent:QCloseEvent): @@ -81,4 +86,4 @@ class QBaseMenu2(QDialog): elif self.cp.cptype == ControlPointType.LHA_GROUP: return "./resources/ui/lha.png" else: - return "./resources/ui/airbase.png" \ No newline at end of file + return "./resources/ui/airbase.png" diff --git a/qt_ui/windows/basemenu/QRecruitBehaviour.py b/qt_ui/windows/basemenu/QRecruitBehaviour.py index 86844e65..aa5c680b 100644 --- a/qt_ui/windows/basemenu/QRecruitBehaviour.py +++ b/qt_ui/windows/basemenu/QRecruitBehaviour.py @@ -5,6 +5,7 @@ from dcs.unittype import UnitType from theater import db + class QRecruitBehaviour: game = None @@ -12,10 +13,12 @@ class QRecruitBehaviour: deliveryEvent = None existing_units_labels = None bought_amount_labels = None + BUDGET_FORMAT = "Available Budget: ${}M" def __init__(self): self.bought_amount_labels = {} self.existing_units_labels = {} + self.update_available_budget() def add_purchase_row(self, unit_type, layout, row): @@ -91,12 +94,22 @@ class QRecruitBehaviour: self.cp.base.total_units_of_type(unit_type) )) + def update_available_budget(self): + parent = self.parent() + while parent.objectName != "menuDialogue": + parent = parent.parent() + for child in parent.children(): + if child.objectName() == "budgetField": + child.setText(QRecruitBehaviour.BUDGET_FORMAT.format(self.game.budget)) + def buy(self, unit_type): + price = db.PRICES[unit_type] if self.game.budget >= price: self.deliveryEvent.deliver({unit_type: 1}) self.game.budget -= price self._update_count_label(unit_type) + self.update_available_budget() def sell(self, unit_type): if self.deliveryEvent.units.get(unit_type, 0) > 0: @@ -111,3 +124,4 @@ class QRecruitBehaviour: self.cp.base.commit_losses({unit_type: 1}) self._update_count_label(unit_type) + self.update_available_budget() diff --git a/qt_ui/windows/mission/QMissionPlanning.py b/qt_ui/windows/mission/QMissionPlanning.py index 431ce00b..7dcc2231 100644 --- a/qt_ui/windows/mission/QMissionPlanning.py +++ b/qt_ui/windows/mission/QMissionPlanning.py @@ -98,6 +98,7 @@ class QMissionPlanning(QDialog): self.planned_flight_view.repaint() if self.flight_planner is not None: + self.flight_planner.on_planned_flight_changed.disconnect() self.flight_planner.clearTabs() try: diff --git a/qt_ui/windows/mission/QPlannedFlightsView.py b/qt_ui/windows/mission/QPlannedFlightsView.py index fb6f5316..0dcc8a81 100644 --- a/qt_ui/windows/mission/QPlannedFlightsView.py +++ b/qt_ui/windows/mission/QPlannedFlightsView.py @@ -23,6 +23,7 @@ class QPlannedFlightsView(QListView): self.flightitems[i].update(f) def setup_content(self, row=0): + self.flightitems = [] for i, f in enumerate(self.flight_planner.flights): item = QFlightItem(f) self.model.appendRow(item) diff --git a/qt_ui/windows/newgame/QCampaignList.py b/qt_ui/windows/newgame/QCampaignList.py new file mode 100644 index 00000000..06c42d9f --- /dev/null +++ b/qt_ui/windows/newgame/QCampaignList.py @@ -0,0 +1,72 @@ +from PySide2 import QtGui +from PySide2.QtCore import QSize, QItemSelectionModel +from PySide2.QtGui import QStandardItemModel, QStandardItem +from PySide2.QtWidgets import QListView, QAbstractItemView + +from theater import caucasus, nevada, persiangulf, normandy, thechannel, syria +import qt_ui.uiconstants as CONST + +CAMPAIGNS = [ + ("Caucasus - Western Georgia", caucasus.WesternGeorgia, "Terrain_Caucasus"), + ("Caucasus - Russia Small", caucasus.RussiaSmall, "Terrain_Caucasus"), + ("Caucasus - North Caucasus", caucasus.NorthCaucasus, "Terrain_Caucasus"), + ("Caucasus - Full Map", caucasus.CaucasusTheater, "Terrain_Caucasus"), + ("Nevada - North Nevada", nevada.NevadaTheater, "Terrain_Nevada"), + ("Persian Gulf - Invasion of Iran", persiangulf.IranianCampaign, "Terrain_Persian_Gulf"), + ("Persian Gulf - Invasion of Iran [Lite]", persiangulf.IranInvasionLite, "Terrain_Persian_Gulf"), + ("Persian Gulf - Emirates", persiangulf.Emirates, "Terrain_Persian_Gulf"), + ("Persian Gulf - Desert War", persiangulf.DesertWar, "Terrain_Persian_Gulf"), + ("Persian Gulf - Full Map", persiangulf.PersianGulfTheater, "Terrain_Persian_Gulf"), + + ("Syria - Golan heights battle", syria.GolanHeights, "Terrain_Syria"), + ("Syria - Invasion from Turkey", syria.TurkishInvasion, "Terrain_Syria"), + ("Syria - Syrian Civil War", syria.SyrianCivilWar, "Terrain_Syria"), + ("Syria - Inherent Resolve", syria.InherentResolve, "Terrain_Syria"), + ("Syria - Full Map", syria.SyriaFullMap, "Terrain_Syria"), + + ("Normandy - Normandy", normandy.NormandyTheater, "Terrain_Normandy"), + ("Normandy - Normandy Small", normandy.NormandySmall, "Terrain_Normandy"), + ("The Channel - Battle of Britain", thechannel.BattleOfBritain, "Terrain_Channel"), + ("The Channel - Dunkirk", thechannel.Dunkirk, "Terrain_Channel"), +] + + +class QCampaignItem(QStandardItem): + + def __init__(self, text, theater, icon): + super(QCampaignItem, self).__init__() + self.theater = theater + self.setIcon(QtGui.QIcon(CONST.ICONS[icon])) + self.setEditable(False) + self.setText(text) + +class QCampaignList(QListView): + + def __init__(self): + super(QCampaignList, self).__init__() + self.model = QStandardItemModel(self) + self.setModel(self.model) + self.setMinimumWidth(250) + self.setMinimumHeight(350) + self.campaigns = [] + self.setSelectionBehavior(QAbstractItemView.SelectItems) + self.setup_content() + + def setup_content(self): + for i, campaign in enumerate(CAMPAIGNS): + self.campaigns.append(campaign) + item = QCampaignItem(*campaign) + self.model.appendRow(item) + self.setSelectedCampaign(0) + self.repaint() + + def setSelectedCampaign(self, row): + self.selectionModel().clearSelection() + index = self.model.index(row, 0) + if not index.isValid(): + index = self.model.index(0, 0) + self.selectionModel().setCurrentIndex(index, QItemSelectionModel.Select) + self.repaint() + + def clear_layout(self): + self.model.removeRows(0, self.model.rowCount()) \ No newline at end of file diff --git a/qt_ui/windows/QNewGameWizard.py b/qt_ui/windows/newgame/QNewGameWizard.py similarity index 80% rename from qt_ui/windows/QNewGameWizard.py rename to qt_ui/windows/newgame/QNewGameWizard.py index e74f5e06..cb88fc21 100644 --- a/qt_ui/windows/QNewGameWizard.py +++ b/qt_ui/windows/newgame/QNewGameWizard.py @@ -1,8 +1,10 @@ from __future__ import unicode_literals import datetime +import logging from PySide2 import QtGui, QtWidgets +from PySide2.QtCore import QPoint, QItemSelectionModel from PySide2.QtWidgets import QHBoxLayout, QVBoxLayout from dcs.task import CAP, CAS @@ -10,6 +12,7 @@ import qt_ui.uiconstants as CONST from game import db, Game from game.settings import Settings from gen import namegen +from qt_ui.windows.newgame.QCampaignList import QCampaignList from theater import start_generator, persiangulf, nevada, caucasus, ConflictTheater, normandy, thechannel @@ -32,19 +35,15 @@ class NewGameWizard(QtWidgets.QWizard): def accept(self): + logging.info("New Game Wizard accept") + logging.info("======================") + blueFaction = [c for c in db.FACTIONS][self.field("blueFaction")] redFaction = [c for c in db.FACTIONS][self.field("redFaction")] - isTerrainPg = self.field("isTerrainPg") - isTerrainNttr = self.field("isTerrainNttr") - isTerrainCaucasusSmall = self.field("isTerrainCaucasusSmall") - isTerrainRussia = self.field("isTerrainRussia") - isTerrainCaucasusNorth= self.field("isTerrainCaucasusNorth") - isIranianCampaignTheater = self.field("isIranianCampaignTheater") - isTerrainNormandy = self.field("isTerrainNormandy") - isTerrainNormandySmall = self.field("isTerrainNormandySmall") - isTerrainChannel = self.field("isTerrainChannel") - isTerrainChannelComplete = self.field("isTerrainChannelComplete") - isTerrainEmirates = self.field("isTerrainEmirates") + + selectedCampaign = self.field("selectedCampaign") + conflictTheater = selectedCampaign[1]() + timePeriod = db.TIME_PERIODS[list(db.TIME_PERIODS.keys())[self.field("timePeriod")]] midGame = self.field("midGame") multiplier = self.field("multiplier") @@ -58,31 +57,6 @@ class NewGameWizard(QtWidgets.QWizard): player_name = blueFaction enemy_name = redFaction - if isTerrainPg: - conflicttheater = persiangulf.PersianGulfTheater() - elif isTerrainNttr: - conflicttheater = nevada.NevadaTheater() - elif isTerrainCaucasusSmall: - conflicttheater = caucasus.WesternGeorgia() - elif isTerrainRussia: - conflicttheater = caucasus.RussiaSmall() - elif isTerrainCaucasusNorth: - conflicttheater = caucasus.NorthCaucasus() - elif isIranianCampaignTheater: - conflicttheater = persiangulf.IranianCampaign() - elif isTerrainEmirates: - conflicttheater = persiangulf.Emirates() - elif isTerrainNormandy: - conflicttheater = normandy.NormandyTheater() - elif isTerrainNormandySmall: - conflicttheater = normandy.NormandySmall() - elif isTerrainChannel: - conflicttheater = thechannel.ChannelTheater() - elif isTerrainChannelComplete: - conflicttheater = thechannel.ChannelTheaterComplete() - else: - conflicttheater = caucasus.CaucasusTheater() - settings = Settings() settings.inverted = invertMap settings.supercarrier = supercarrier @@ -91,40 +65,40 @@ class NewGameWizard(QtWidgets.QWizard): settings.do_not_generate_player_navy = no_player_navy settings.do_not_generate_enemy_navy = no_enemy_navy - self.generatedGame = self.start_new_game(player_name, enemy_name, conflicttheater, midGame, multiplier, + self.generatedGame = self.start_new_game(player_name, enemy_name, conflictTheater, midGame, multiplier, timePeriod, settings) super(NewGameWizard, self).accept() - def start_new_game(self, player_name: str, enemy_name: str, conflicttheater: ConflictTheater, + def start_new_game(self, player_name: str, enemy_name: str, conflictTheater: ConflictTheater, midgame: bool, multiplier: float, period: datetime, settings:Settings): # Reset name generator namegen.reset() - start_generator.prepare_theater(conflicttheater, settings, midgame) + start_generator.prepare_theater(conflictTheater, settings, midgame) print("-- Starting New Game Generator") print("Enemy name : " + enemy_name) print("Player name : " + player_name) print("Midgame : " + str(midgame)) - start_generator.generate_inital_units(conflicttheater, enemy_name, True, multiplier) + start_generator.generate_inital_units(conflictTheater, enemy_name, True, multiplier) print("-- Initial units generated") game = Game(player_name=player_name, enemy_name=enemy_name, - theater=conflicttheater, + theater=conflictTheater, start_date=period, settings=settings) print("-- Game Object generated") - start_generator.generate_groundobjects(conflicttheater, game) + start_generator.generate_groundobjects(conflictTheater, game) game.budget = int(game.budget * multiplier) game.settings.multiplier = multiplier game.settings.sams = True - game.settings.version = "2.0.10" + game.settings.version = CONST.VERSION_STRING if midgame: - game.budget = game.budget * 4 * len(list(conflicttheater.conflicts())) + game.budget = game.budget * 4 * len(list(conflictTheater.conflicts())) return game @@ -295,6 +269,21 @@ class TheaterConfiguration(QtWidgets.QWizardPage): terrainChannelComplete.setIcon(QtGui.QIcon(CONST.ICONS["Terrain_Channel"])) terrainCaucasusSmall.setChecked(True) + # List of campaigns + campaignList = QCampaignList() + self.registerField("selectedCampaign", campaignList) + + def on_campaign_selected(): + index = campaignList.selectionModel().currentIndex().row() + campaign = campaignList.campaigns[index] + self.setField("selectedCampaign", campaign) + + campaignList.selectionModel().setCurrentIndex(campaignList.indexAt(QPoint(1, 1)), QItemSelectionModel.Rows) + campaignList.selectionModel().selectionChanged.connect(on_campaign_selected) + on_campaign_selected() + + + # Campaign settings mapSettingsGroup = QtWidgets.QGroupBox("Map Settings") invertMap = QtWidgets.QCheckBox() @@ -314,35 +303,8 @@ class TheaterConfiguration(QtWidgets.QWizardPage): timePeriodSelect.setCurrentIndex(21) # Register fields - self.registerField('isTerrainCaucasus', terrainCaucasus) - self.registerField('isTerrainCaucasusSmall', terrainCaucasusSmall) - self.registerField('isTerrainRussia', terrainRussia) - self.registerField('isTerrainCaucasusNorth', terrainCaucasusNorth) - self.registerField('isTerrainPg', terrainPg) - self.registerField('isIranianCampaignTheater', terrainIran) - self.registerField('isTerrainEmirates', terrainEmirates) - self.registerField('isTerrainNttr', terrainNttr) - self.registerField('isTerrainNormandy', terrainNormandy) - self.registerField('isTerrainNormandySmall', terrainNormandySmall) - self.registerField('isTerrainChannel', terrainChannel) - self.registerField('isTerrainChannelComplete', terrainChannelComplete) self.registerField('timePeriod', timePeriodSelect) - - # Build layout - terrainGroupLayout = QtWidgets.QVBoxLayout() - terrainGroupLayout.addWidget(terrainCaucasusSmall) - terrainGroupLayout.addWidget(terrainRussia) - terrainGroupLayout.addWidget(terrainCaucasusNorth) - terrainGroupLayout.addWidget(terrainCaucasus) - terrainGroupLayout.addWidget(terrainIran) - terrainGroupLayout.addWidget(terrainEmirates) - terrainGroupLayout.addWidget(terrainPg) - terrainGroupLayout.addWidget(terrainNttr) - terrainGroupLayout.addWidget(terrainNormandy) - terrainGroupLayout.addWidget(terrainNormandySmall) - terrainGroupLayout.addWidget(terrainChannelComplete) - terrainGroupLayout.addWidget(terrainChannel) - terrainGroup.setLayout(terrainGroupLayout) + self.registerField('timePeriod', timePeriodSelect) timeGroupLayout = QtWidgets.QGridLayout() timeGroupLayout.addWidget(timePeriod, 0, 0) @@ -351,7 +313,7 @@ class TheaterConfiguration(QtWidgets.QWizardPage): layout = QtWidgets.QGridLayout() layout.setColumnMinimumWidth(0, 20) - layout.addWidget(terrainGroup, 0, 0, 3, 1) + layout.addWidget(campaignList, 0, 0, 3, 1) layout.addWidget(mapSettingsGroup, 0, 1, 1, 1) layout.addWidget(timeGroup, 1, 1, 1, 1) self.setLayout(layout) diff --git a/resources/caulandmap.p b/resources/caulandmap.p index a9fe3cbe..68f6806f 100644 Binary files a/resources/caulandmap.p and b/resources/caulandmap.p differ diff --git a/resources/customized_payloads/AH-1W.lua b/resources/customized_payloads/AH-1W.lua new file mode 100644 index 00000000..a8fb30b3 --- /dev/null +++ b/resources/customized_payloads/AH-1W.lua @@ -0,0 +1,69 @@ +local unitPayloads = { + ["name"] = "AH-1W", + ["payloads"] = { + [1] = { + ["name"] = "CAS", + ["pylons"] = { + [1] = { + ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 18, + [2] = 31, + [3] = 32, + }, + }, + [2] = { + ["name"] = "STRIKE", + ["pylons"] = { + [1] = { + ["CLSID"] = "M260_HYDRA", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "M260_HYDRA", + ["num"] = 2, + }, + [3] = { + ["CLSID"] = "M260_HYDRA", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "M260_HYDRA", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 18, + [2] = 31, + [3] = 32, + }, + }, + [3] = { + ["name"] = "ANTISHIP", + ["pylons"] = { + [1] = { + ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 18, + [2] = 31, + [3] = 32, + }, + }, + }, + ["unitType"] = "AH-1W", +} +return unitPayloads diff --git a/resources/customized_payloads/F-16A.lua b/resources/customized_payloads/F-16A.lua new file mode 100644 index 00000000..9879239f --- /dev/null +++ b/resources/customized_payloads/F-16A.lua @@ -0,0 +1,219 @@ +local unitPayloads = { + ["name"] = "F-16A", + ["payloads"] = { + [1] = { + ["name"] = "CAP", + ["pylons"] = { + [1] = { + ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}", + ["num"] = 6, + }, + [2] = { + ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}", + ["num"] = 8, + }, + [3] = { + ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 2, + }, + [5] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 9, + }, + [6] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 1, + }, + [7] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 10, + }, + }, + ["tasks"] = { + [1] = 11, + }, + }, + [2] = { + ["name"] = "CAS", + ["pylons"] = { + [1] = { + ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}", + ["num"] = 6, + }, + [2] = { + ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}", + ["num"] = 8, + }, + [3] = { + ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98452}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 2, + }, + [5] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 9, + }, + [6] = { + ["CLSID"] = "{AIS_ASQ_T50}", + ["num"] = 1, + }, + [7] = { + ["CLSID"] = "{AIS_ASQ_T50}", + ["num"] = 10, + }, + [8] = { + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 7, + }, + [9] = { + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + }, + }, + [3] = { + ["name"] = "STRIKE", + ["pylons"] = { + [1] = { + ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}", + ["num"] = 6, + }, + [2] = { + ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}", + ["num"] = 8, + }, + [3] = { + ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 2, + }, + [5] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 9, + }, + [6] = { + ["CLSID"] = "{AIS_ASQ_T50}", + ["num"] = 1, + }, + [7] = { + ["CLSID"] = "{AIS_ASQ_T50}", + ["num"] = 10, + }, + [8] = { + ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}", + ["num"] = 7, + }, + [9] = { + ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + }, + }, + [4] = { + ["name"] = "ANTISHIP", + ["pylons"] = { + [1] = { + ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}", + ["num"] = 6, + }, + [2] = { + ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}", + ["num"] = 8, + }, + [3] = { + ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 2, + }, + [5] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 9, + }, + [6] = { + ["CLSID"] = "{AIS_ASQ_T50}", + ["num"] = 1, + }, + [7] = { + ["CLSID"] = "{AIS_ASQ_T50}", + ["num"] = 10, + }, + [8] = { + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 7, + }, + [9] = { + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + }, + }, + [5] = { + ["name"] = "SEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}", + ["num"] = 6, + }, + [2] = { + ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}", + ["num"] = 8, + }, + [3] = { + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 2, + }, + [5] = { + ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}", + ["num"] = 9, + }, + [6] = { + ["CLSID"] = "{AIS_ASQ_T50}", + ["num"] = 1, + }, + [7] = { + ["CLSID"] = "{AIS_ASQ_T50}", + ["num"] = 10, + }, + [8] = { + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 7, + }, + [9] = { + ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + }, + }, + }, + ["unitType"] = "F-16A", +} +return unitPayloads diff --git a/resources/customized_payloads/F-16C_50.lua b/resources/customized_payloads/F-16C_50.lua index 3f4cb98c..e2868660 100644 --- a/resources/customized_payloads/F-16C_50.lua +++ b/resources/customized_payloads/F-16C_50.lua @@ -2,49 +2,6 @@ local unitPayloads = { ["name"] = "F-16C_50", ["payloads"] = { [1] = { - ["name"] = "CAP", - ["pylons"] = { - [1] = { - ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}", - ["num"] = 5, - }, - [2] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 7, - }, - [3] = { - ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", - ["num"] = 3, - }, - [4] = { - ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", - ["num"] = 2, - }, - [5] = { - ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", - ["num"] = 1, - }, - [6] = { - ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", - ["num"] = 8, - }, - [7] = { - ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", - ["num"] = 9, - }, - [8] = { - ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}", - ["num"] = 4, - }, - [9] = { - ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}", - ["num"] = 6, - }, - }, - ["tasks"] = { - }, - }, - [2] = { ["name"] = "CAS", ["pylons"] = { [1] = { @@ -52,11 +9,11 @@ local unitPayloads = { ["num"] = 5, }, [2] = { - ["CLSID"] = "{TER_9A_2R*MK-82}", + ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}", ["num"] = 7, }, [3] = { - ["CLSID"] = "{TER_9A_2L*CBU-97}", + ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}", ["num"] = 3, }, [4] = { @@ -76,11 +33,11 @@ local unitPayloads = { ["num"] = 9, }, [8] = { - ["CLSID"] = "{TER_9A_2L*CBU-97}", + ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}", ["num"] = 4, }, [9] = { - ["CLSID"] = "{TER_9A_2R*CBU-97}", + ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}", ["num"] = 6, }, [10] = { @@ -91,7 +48,7 @@ local unitPayloads = { ["tasks"] = { }, }, - [3] = { + [2] = { ["name"] = "ANTISHIP", ["pylons"] = { [1] = { @@ -134,6 +91,49 @@ local unitPayloads = { ["tasks"] = { }, }, + [3] = { + ["name"] = "CAP", + ["pylons"] = { + [1] = { + ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}", + ["num"] = 5, + }, + [2] = { + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 7, + }, + [3] = { + ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 2, + }, + [5] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 1, + }, + [6] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 8, + }, + [7] = { + ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}", + ["num"] = 9, + }, + [8] = { + ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}", + ["num"] = 4, + }, + [9] = { + ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}", + ["num"] = 6, + }, + }, + ["tasks"] = { + }, + }, [4] = { ["name"] = "STRIKE", ["pylons"] = { @@ -181,7 +181,7 @@ local unitPayloads = { ["name"] = "SEAD", ["pylons"] = { [1] = { - ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}", + ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}", ["num"] = 6, }, [2] = { diff --git a/resources/customized_payloads/MQ-9 Reaper.lua b/resources/customized_payloads/MQ-9 Reaper.lua new file mode 100644 index 00000000..3fcba86c --- /dev/null +++ b/resources/customized_payloads/MQ-9 Reaper.lua @@ -0,0 +1,33 @@ +local unitPayloads = { + ["name"] = "MQ-9 Reaper", + ["payloads"] = { + [1] = { + ["name"] = "CAS", + ["pylons"] = { + [1] = { + ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}", + ["num"] = 4, + }, + [2] = { + ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "AGM114x2_OH_58", + ["num"] = 2, + }, + [4] = { + ["CLSID"] = "AGM114x2_OH_58", + ["num"] = 3, + }, + }, + ["tasks"] = { + [1] = 17, + }, + }, + }, + ["tasks"] = { + }, + ["unitType"] = "MQ-9 Reaper", +} +return unitPayloads diff --git a/resources/customized_payloads/MiG-25PD.lua b/resources/customized_payloads/MiG-25PD.lua new file mode 100644 index 00000000..ee6bafcc --- /dev/null +++ b/resources/customized_payloads/MiG-25PD.lua @@ -0,0 +1,142 @@ +local unitPayloads = { + ["name"] = "MiG-25PD", + ["payloads"] = { + [1] = { + ["name"] = "CAP", + ["pylons"] = { + [1] = { + ["CLSID"] = "{5F26DBC2-FB43-4153-92DE-6BBCE26CB0FF}", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 2, + }, + [3] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{5F26DBC2-FB43-4153-92DE-6BBCE26CB0FF}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + [2] = 10, + [3] = 18, + [4] = 19, + }, + }, + [2] = { + ["name"] = "STRIKE", + ["pylons"] = { + [1] = { + ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 2, + }, + [3] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + [2] = 10, + [3] = 18, + [4] = 19, + }, + }, + [3] = { + ["name"] = "CAS", + ["pylons"] = { + [1] = { + ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 2, + }, + [3] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + [2] = 10, + [3] = 18, + [4] = 19, + }, + }, + [4] = { + ["name"] = "ANTISHIP", + ["pylons"] = { + [1] = { + ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 2, + }, + [3] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + [2] = 10, + [3] = 18, + [4] = 19, + }, + }, + [5] = { + ["name"] = "SEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 2, + }, + [3] = { + ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}", + ["num"] = 3, + }, + [4] = { + ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 11, + [2] = 10, + [3] = 18, + [4] = 19, + }, + }, + }, + ["unitType"] = "MiG-25PD", +} +return unitPayloads diff --git a/resources/customized_payloads/RQ-1A Predator.lua b/resources/customized_payloads/RQ-1A Predator.lua new file mode 100644 index 00000000..71efb9d8 --- /dev/null +++ b/resources/customized_payloads/RQ-1A Predator.lua @@ -0,0 +1,23 @@ +local unitPayloads = { + ["name"] = "RQ-1A Predator", + ["payloads"] = { + [1] = { + ["name"] = "CAS", + ["pylons"] = { + [1] = { + ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}", + ["num"] = 2, + }, + [2] = { + ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}", + ["num"] = 1, + }, + }, + ["tasks"] = { + [1] = 17, + }, + }, + }, + ["unitType"] = "RQ-1A Predator", +} +return unitPayloads diff --git a/resources/customized_payloads/WingLoong-I.lua b/resources/customized_payloads/WingLoong-I.lua new file mode 100644 index 00000000..aa1a019a --- /dev/null +++ b/resources/customized_payloads/WingLoong-I.lua @@ -0,0 +1,25 @@ +local unitPayloads = { + ["name"] = "WingLoong-I", + ["payloads"] = { + [1] = { + ["name"] = "CAS", + ["pylons"] = { + [1] = { + ["CLSID"] = "DIS_AKD-10", + ["num"] = 2, + }, + [2] = { + ["CLSID"] = "DIS_AKD-10", + ["num"] = 1, + }, + }, + ["tasks"] = { + [1] = 17, + }, + }, + }, + ["tasks"] = { + }, + ["unitType"] = "WingLoong-I", +} +return unitPayloads diff --git a/resources/scripts/dcs_liberation.lua b/resources/scripts/dcs_liberation.lua index a9476fa4..5c594d35 100644 --- a/resources/scripts/dcs_liberation.lua +++ b/resources/scripts/dcs_liberation.lua @@ -34,11 +34,24 @@ write_state = function() } fp:write(json:encode(game_state)) fp:close() - --logger.info("Done writing DCS Liberation state") - --messageAll("Done writing DCS Liberation state.") + -- logger.info("Done writing DCS Liberation state") + -- messageAll("Done writing DCS Liberation state.") end -mist.scheduleFunction(write_state, {}, timer.getTime() + 10, 60, timer.getTime() + 3600) + +write_state_error_handling = function() + if pcall(write_state) then + -- messageAll("Written DCS Liberation state to "..debriefing_file_location) + else + messageAll("Unable to write DCS Liberation state to "..debriefing_file_location.. + "\nYou can abort the mission in DCS Liberation.\n".. + "\n\nPlease fix your setup in DCS Liberation, make sure you are pointing to the right installation directory from the File/Preferences menu. Then after fixing the path restart DCS Liberation, and then restart DCS.".. + "\n\nYou can also try to fix the issue manually by replacing the file /Scripts/MissionScripting.lua by the one provided there : /resources/scripts/MissionScripting.lua. And then restart DCS. (This will also have to be done again after each DCS update)".. + "\n\nIt's not worth playing, the state of the mission will not be recorded.") + end +end + +mist.scheduleFunction(write_state_error_handling, {}, timer.getTime() + 10, 60, timer.getTime() + 3600) activeWeapons = {} local function onEvent(event) diff --git a/resources/stylesheets/style-dcs.css b/resources/stylesheets/style-dcs.css index 47a8bee3..c01f398c 100644 --- a/resources/stylesheets/style-dcs.css +++ b/resources/stylesheets/style-dcs.css @@ -184,6 +184,11 @@ QLabel[style="base-title"]{ font-size: 24px; } +QLabel[style="budget-label"]{ + font-size: 16px; + margin-right: 20px; +} + QLabel[style="icon-plane"]{ background-color:#48719D; min-height:24px; diff --git a/resources/syria.gif b/resources/syria.gif new file mode 100644 index 00000000..24a39c94 Binary files /dev/null and b/resources/syria.gif differ diff --git a/resources/syrialandmap.p b/resources/syrialandmap.p new file mode 100644 index 00000000..d4169854 Binary files /dev/null and b/resources/syrialandmap.p differ diff --git a/resources/tools/cau_terrain.miz b/resources/tools/cau_terrain.miz index e0542b89..c885927d 100644 Binary files a/resources/tools/cau_terrain.miz and b/resources/tools/cau_terrain.miz differ diff --git a/resources/tools/syria_terrain.miz b/resources/tools/syria_terrain.miz new file mode 100644 index 00000000..a1a9fae9 Binary files /dev/null and b/resources/tools/syria_terrain.miz differ diff --git a/resources/ui/terrain_syria.gif b/resources/ui/terrain_syria.gif new file mode 100644 index 00000000..1c261d57 Binary files /dev/null and b/resources/ui/terrain_syria.gif differ diff --git a/resources/ui/units/aircrafts/MQ-1A Predator_24.jpg b/resources/ui/units/aircrafts/MQ-1A Predator_24.jpg new file mode 100644 index 00000000..f953e2ac Binary files /dev/null and b/resources/ui/units/aircrafts/MQ-1A Predator_24.jpg differ diff --git a/resources/ui/units/aircrafts/MQ-9 Reaper_24.jpg b/resources/ui/units/aircrafts/MQ-9 Reaper_24.jpg new file mode 100644 index 00000000..d49ef6d7 Binary files /dev/null and b/resources/ui/units/aircrafts/MQ-9 Reaper_24.jpg differ diff --git a/resources/ui/units/aircrafts/Mi-28_24.jpg b/resources/ui/units/aircrafts/Mi-28N_24.jpg similarity index 100% rename from resources/ui/units/aircrafts/Mi-28_24.jpg rename to resources/ui/units/aircrafts/Mi-28N_24.jpg diff --git a/resources/ui/units/aircrafts/WingLoong-I_24.jpg b/resources/ui/units/aircrafts/WingLoong-I_24.jpg new file mode 100644 index 00000000..32feeb36 Binary files /dev/null and b/resources/ui/units/aircrafts/WingLoong-I_24.jpg differ diff --git a/theater/controlpoint.py b/theater/controlpoint.py index 49da85b4..96b6605c 100644 --- a/theater/controlpoint.py +++ b/theater/controlpoint.py @@ -28,6 +28,7 @@ class ControlPoint: base = None # type: theater.base.Base at = None # type: db.StartPosition icls = 1 + allow_sea_units = True connected_points = None # type: typing.List[ControlPoint] ground_objects = None # type: typing.List[TheaterGroundObject] diff --git a/theater/persiangulf.py b/theater/persiangulf.py index 6826369b..0960c947 100644 --- a/theater/persiangulf.py +++ b/theater/persiangulf.py @@ -209,3 +209,90 @@ class Emirates(ConflictTheater): self.tarawa_carrier.captured_invert = True self.east_carrier.captured_invert = True self.fujairah.captured_invert = True + + +class DesertWar(ConflictTheater): + terrain = dcs.terrain.PersianGulf() + overview_image = "persiangulf.gif" + reference_points = { + (persiangulf.Shiraz_International_Airport.position.x, persiangulf.Shiraz_International_Airport.position.y): ( + 772, -1970), + (persiangulf.Liwa_Airbase.position.x, persiangulf.Liwa_Airbase.position.y): (1188, 78), } + landmap = load_landmap("resources\\gulflandmap.p") + daytime_map = { + "dawn": (6, 8), + "day": (8, 16), + "dusk": (16, 18), + "night": (0, 5), + } + + + def __init__(self): + super(DesertWar, self).__init__() + + self.liwa = ControlPoint.from_airport(persiangulf.Liwa_Airbase, LAND, SIZE_BIG, IMPORTANCE_MEDIUM) + self.al_maktoum = ControlPoint.from_airport(persiangulf.Al_Maktoum_Intl, LAND, SIZE_BIG, IMPORTANCE_LOW) + self.al_minhad = ControlPoint.from_airport(persiangulf.Al_Minhad_AB, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.al_ain = ControlPoint.from_airport(persiangulf.Al_Ain_International_Airport, LAND, SIZE_BIG,IMPORTANCE_LOW) + + self.carrier = ControlPoint.carrier("Carrier", Point(-124000, -303000), 1001) + self.tarawa_carrier = ControlPoint.lha("LHA Carrier", Point(-164000, -257000), 1002) + + self.add_controlpoint(self.liwa, connected_to=[self.al_ain]) + self.add_controlpoint(self.al_ain, connected_to=[self.al_maktoum, self.liwa]) + self.add_controlpoint(self.al_maktoum, connected_to=[self.al_minhad, self.al_ain]) + self.add_controlpoint(self.al_minhad, connected_to=[self.al_maktoum]) + + self.add_controlpoint(self.tarawa_carrier) + self.add_controlpoint(self.carrier) + + self.tarawa_carrier.captured = True + self.carrier.captured = True + self.liwa.captured = True + + self.tarawa_carrier.captured_invert = True + self.carrier.captured_invert = True + self.al_ain.captured_invert = True + + +class IranInvasionLite(ConflictTheater): + terrain = dcs.terrain.PersianGulf() + overview_image = "persiangulf.gif" + reference_points = { + (persiangulf.Shiraz_International_Airport.position.x, persiangulf.Shiraz_International_Airport.position.y): ( + 772, -1970), + (persiangulf.Liwa_Airbase.position.x, persiangulf.Liwa_Airbase.position.y): (1188, 78), } + landmap = load_landmap("resources\\gulflandmap.p") + daytime_map = { + "dawn": (6, 8), + "day": (8, 16), + "dusk": (16, 18), + "night": (0, 5), + } + + def __init__(self): + super(IranInvasionLite, self).__init__() + + self.bandar_lengeh = ControlPoint.from_airport(persiangulf.Bandar_Lengeh, [270, 315, 0, 45], SIZE_SMALL, IMPORTANCE_HIGH) + self.lar = ControlPoint.from_airport(persiangulf.Lar_Airbase, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.shiraz = ControlPoint.from_airport(persiangulf.Shiraz_International_Airport, LAND, SIZE_BIG, IMPORTANCE_HIGH) + self.kerman = ControlPoint.from_airport(persiangulf.Kerman_Airport, LAND, SIZE_BIG, IMPORTANCE_HIGH) + self.jiroft = ControlPoint.from_airport(persiangulf.Jiroft_Airport, LAND, SIZE_BIG, IMPORTANCE_HIGH) + self.carrier = ControlPoint.carrier("Carrier", Point(72000.324335475, -376000), 1001) + self.lha = ControlPoint.lha("LHA", Point(-27500.813952358, -147000.65947136), 1002) + + self.add_controlpoint(self.bandar_lengeh, connected_to=[self.lar]) + self.add_controlpoint(self.shiraz, connected_to=[self.lar, self.kerman]) + self.add_controlpoint(self.jiroft, connected_to=[self.kerman]) + self.add_controlpoint(self.kerman, connected_to=[self.shiraz, self.jiroft]) + self.add_controlpoint(self.lar, connected_to=[self.bandar_lengeh, self.shiraz]) + + self.add_controlpoint(self.carrier) + self.add_controlpoint(self.lha) + + self.carrier.captured = True + self.lha.captured = True + + self.shiraz.captured_invert = True + self.bandar_lengeh.captured = True + diff --git a/theater/start_generator.py b/theater/start_generator.py index 26820755..b029ae92 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -155,7 +155,7 @@ def generate_groundobjects(theater: ConflictTheater, game): logging.info(ground_object.groups) # Generate navy groups - if "boat" in db.FACTIONS[faction_name].keys(): + if "boat" in db.FACTIONS[faction_name].keys() and cp.allow_sea_units: if cp.captured and game.settings.do_not_generate_player_navy: continue diff --git a/theater/syria.py b/theater/syria.py new file mode 100644 index 00000000..ecdea405 --- /dev/null +++ b/theater/syria.py @@ -0,0 +1,221 @@ +from dcs.terrain import syria + +from .conflicttheater import * +from .landmap import * + + +class SyriaTheater(ConflictTheater): + terrain = dcs.terrain.Syria() + overview_image = "syria.gif" + reference_points = {(syria.Eyn_Shemer.position.x, syria.Eyn_Shemer.position.y): (1300, 1380), + (syria.Tabqa.position.x, syria.Tabqa.position.y): (2060, 570)} + landmap = load_landmap("resources\\syrialandmap.p") + daytime_map = { + "dawn": (6, 8), + "day": (8, 16), + "dusk": (16, 18), + "night": (0, 5), + } + + def __init__(self): + super(SyriaTheater, self).__init__() + + +class GolanHeights(SyriaTheater): + + def __init__(self): + super(GolanHeights, self).__init__() + + self.ramatDavid = ControlPoint.from_airport(syria.Ramat_David, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.kinghussein = ControlPoint.from_airport(syria.King_Hussein_Air_College, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.khalkhala = ControlPoint.from_airport(syria.Khalkhalah, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + + self.khalkhala.allow_sea_units = False + self.ramatDavid.allow_sea_units = False + self.kinghussein.allow_sea_units = False + + self.marjruhayyil = ControlPoint.from_airport(syria.Marj_Ruhayyil, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.mezzeh = ControlPoint.from_airport(syria.Mezzeh, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + self.aldumayr = ControlPoint.from_airport(syria.Al_Dumayr, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + + self.carrier = ControlPoint.carrier("Carrier", Point(-280000, -238000), 1001) + self.lha = ControlPoint.lha("LHA Carrier", Point(-237000, -89800), 1002) + + self.add_controlpoint(self.ramatDavid, connected_to=[self.khalkhala]) + self.add_controlpoint(self.khalkhala, connected_to=[self.ramatDavid, self.kinghussein, self.marjruhayyil]) + self.add_controlpoint(self.kinghussein, connected_to=[self.khalkhala]) + self.add_controlpoint(self.marjruhayyil, connected_to=[self.khalkhala, self.mezzeh, self.aldumayr]) + self.add_controlpoint(self.mezzeh, connected_to=[self.marjruhayyil]) + self.add_controlpoint(self.aldumayr, connected_to=[self.marjruhayyil]) + + self.add_controlpoint(self.carrier) + self.add_controlpoint(self.lha) + + self.ramatDavid.captured = True + self.carrier.captured = True + self.lha.captured = True + + self.aldumayr.captured_invert = True + self.carrier.captured_invert = True + self.lha.captured_invert = True + + +class TurkishInvasion(SyriaTheater): + + def __init__(self): + super(TurkishInvasion, self).__init__() + + self.hatay = ControlPoint.from_airport(syria.Hatay, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.incirlik = ControlPoint.from_airport(syria.Incirlik, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.minakh = ControlPoint.from_airport(syria.Minakh, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.aleppo = ControlPoint.from_airport(syria.Aleppo, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + self.kuweires = ControlPoint.from_airport(syria.Kuweires, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.jirah = ControlPoint.from_airport(syria.Jirah, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.tabqa = ControlPoint.from_airport(syria.Tabqa, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + + self.carrier = ControlPoint.carrier("Carrier", Point(133000, -54000), 1001) + self.lha = ControlPoint.lha("LHA", Point(155000, -19000), 1002) + + self.add_controlpoint(self.incirlik, connected_to=[]) + self.add_controlpoint(self.hatay, connected_to=[self.minakh]) + self.add_controlpoint(self.minakh, connected_to=[self.aleppo, self.hatay]) + self.add_controlpoint(self.aleppo, connected_to=[self.kuweires, self.minakh]) + self.add_controlpoint(self.kuweires, connected_to=[self.jirah, self.aleppo]) + self.add_controlpoint(self.jirah, connected_to=[self.tabqa, self.kuweires]) + self.add_controlpoint(self.tabqa, connected_to=[self.jirah]) + + self.add_controlpoint(self.carrier) + self.add_controlpoint(self.lha) + + self.incirlik.captured = True + self.hatay.captured = True + self.carrier.captured = True + self.lha.captured = True + + self.tabqa.captured_invert = True + + +class SyrianCivilWar(SyriaTheater): + + def __init__(self): + super(SyrianCivilWar, self).__init__() + + self.basselAlAssad = ControlPoint.from_airport(syria.Bassel_Al_Assad, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.marjruhayyil = ControlPoint.from_airport(syria.Marj_Ruhayyil, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.aldumayr = ControlPoint.from_airport(syria.Al_Dumayr, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + self.hama = ControlPoint.from_airport(syria.Hama, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.alqusair= ControlPoint.from_airport(syria.Al_Qusayr, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.aleppo = ControlPoint.from_airport(syria.Aleppo, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + + self.palmyra = ControlPoint.from_airport(syria.Palmyra, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + + self.carrier = ControlPoint.carrier("Carrier", Point(18537, -52000), 1001) + self.lha = ControlPoint.lha("LHA", Point(116000, 30000), 1002) + + self.add_controlpoint(self.basselAlAssad, connected_to=[self.hama]) + self.add_controlpoint(self.marjruhayyil, connected_to=[self.aldumayr]) + + self.add_controlpoint(self.hama, connected_to=[self.basselAlAssad, self.aleppo, self.alqusair]) + self.add_controlpoint(self.aleppo, connected_to=[self.hama]) + self.add_controlpoint(self.alqusair, connected_to=[self.hama, self.aldumayr, self.palmyra]) + self.add_controlpoint(self.palmyra, connected_to=[self.alqusair]) + self.add_controlpoint(self.aldumayr, connected_to=[self.alqusair, self.marjruhayyil]) + + self.add_controlpoint(self.carrier) + self.add_controlpoint(self.lha) + + self.basselAlAssad.captured = True + self.marjruhayyil.captured = True + self.carrier.captured = True + self.lha.captured = True + + self.aleppo.captured_invert = True + self.carrier.captured_invert = True + self.lha.captured_invert = True + + +class InherentResolve(SyriaTheater): + + def __init__(self): + super(InherentResolve, self).__init__() + + self.kinghussein = ControlPoint.from_airport(syria.King_Hussein_Air_College, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.khalkhala = ControlPoint.from_airport(syria.Khalkhalah, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + self.palmyra = ControlPoint.from_airport(syria.Palmyra, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.jirah = ControlPoint.from_airport(syria.Jirah, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.tabqa = ControlPoint.from_airport(syria.Tabqa, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + + self.carrier = ControlPoint.carrier("Carrier", Point(-210000, -200000), 1001) + self.lha = ControlPoint.lha("LHA", Point(-131000, -161000), 1002) + + self.add_controlpoint(self.kinghussein, connected_to=[self.khalkhala]) + self.add_controlpoint(self.khalkhala, connected_to=[self.kinghussein, self.palmyra]) + self.add_controlpoint(self.palmyra, connected_to=[self.khalkhala, self.tabqa]) + self.add_controlpoint(self.tabqa, connected_to=[self.palmyra, self.jirah]) + self.add_controlpoint(self.jirah, connected_to=[self.tabqa]) + + self.add_controlpoint(self.carrier) + self.add_controlpoint(self.lha) + + self.kinghussein.captured = True + self.carrier.captured = True + self.lha.captured = True + + self.jirah.captured_invert = True + self.carrier.captured_invert = True + self.lha.captured_invert = True + + +class SyriaFullMap(SyriaTheater): + + def __init__(self): + super(SyriaFullMap, self).__init__() + + self.ramatDavid = ControlPoint.from_airport(syria.Ramat_David, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.kinghussein = ControlPoint.from_airport(syria.King_Hussein_Air_College, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.khalkhala = ControlPoint.from_airport(syria.Khalkhalah, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + self.palmyra = ControlPoint.from_airport(syria.Palmyra, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.jirah = ControlPoint.from_airport(syria.Jirah, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.tabqa = ControlPoint.from_airport(syria.Tabqa, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.aldumayr = ControlPoint.from_airport(syria.Al_Dumayr, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + self.hama = ControlPoint.from_airport(syria.Hama, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.alqusair= ControlPoint.from_airport(syria.Al_Qusayr, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.aleppo = ControlPoint.from_airport(syria.Aleppo, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM) + self.basselAlAssad = ControlPoint.from_airport(syria.Bassel_Al_Assad, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.renemouawad = ControlPoint.from_airport(syria.Rene_Mouawad, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.minakh = ControlPoint.from_airport(syria.Minakh, LAND, SIZE_REGULAR, IMPORTANCE_LOW) + self.hatay = ControlPoint.from_airport(syria.Hatay, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + self.incirlik = ControlPoint.from_airport(syria.Incirlik, LAND, SIZE_REGULAR, IMPORTANCE_HIGH) + + + self.carrier = ControlPoint.carrier("Carrier", Point(-151000, -106000), 1001) + self.lha = ControlPoint.lha("LHA", Point(-131000, -161000), 1002) + + self.add_controlpoint(self.ramatDavid, connected_to=[self.kinghussein]) + self.add_controlpoint(self.kinghussein, connected_to=[self.khalkhala, self.ramatDavid]) + self.add_controlpoint(self.khalkhala, connected_to=[self.kinghussein, self.aldumayr]) + self.add_controlpoint(self.aldumayr, connected_to=[self.khalkhala, self.alqusair]) + self.add_controlpoint(self.alqusair, connected_to=[self.hama, self.aldumayr, self.palmyra, self.renemouawad]) + self.add_controlpoint(self.renemouawad, connected_to=[self.alqusair, self.basselAlAssad]) + self.add_controlpoint(self.hama, connected_to=[self.aleppo, self.alqusair, self.basselAlAssad]) + self.add_controlpoint(self.basselAlAssad, connected_to=[self.hama, self.hatay, self.renemouawad]) + self.add_controlpoint(self.palmyra, connected_to=[self.tabqa, self.alqusair]) + self.add_controlpoint(self.tabqa, connected_to=[self.palmyra, self.jirah]) + self.add_controlpoint(self.jirah, connected_to=[self.tabqa, self.aleppo]) + self.add_controlpoint(self.aleppo, connected_to=[self.hama, self.jirah, self.minakh]) + self.add_controlpoint(self.minakh, connected_to=[self.hatay, self.aleppo, self.incirlik]) + self.add_controlpoint(self.hatay, connected_to=[self.minakh, self.basselAlAssad]) + self.add_controlpoint(self.incirlik, connected_to=[self.minakh]) + + self.add_controlpoint(self.carrier) + self.add_controlpoint(self.lha) + + self.ramatDavid.captured = True + self.carrier.captured = True + self.lha.captured = True + + self.hatay.captured_invert = True + self.carrier.captured_invert = True + self.lha.captured_invert = True + + diff --git a/theater/thechannel.py b/theater/thechannel.py index 18b1a617..b37bbca3 100644 --- a/theater/thechannel.py +++ b/theater/thechannel.py @@ -4,7 +4,7 @@ from .conflicttheater import * from .landmap import * -class ChannelTheater(ConflictTheater): +class Dunkirk(ConflictTheater): terrain = dcs.terrain.TheChannel() overview_image = "thechannel.gif" reference_points = {(thechannel.Abbeville_Drucat.position.x, thechannel.Abbeville_Drucat.position.y): (2400, 4100), @@ -18,7 +18,7 @@ class ChannelTheater(ConflictTheater): } def __init__(self): - super(ChannelTheater, self).__init__() + super(Dunkirk, self).__init__() self.abeville = ControlPoint.from_airport(thechannel.Abbeville_Drucat, LAND, SIZE_SMALL, IMPORTANCE_LOW) #self.detling = ControlPoint.from_airport(thechannel.Detling, LAND, SIZE_SMALL, IMPORTANCE_LOW) @@ -57,7 +57,7 @@ class ChannelTheater(ConflictTheater): self.abeville.captured_invert = True -class ChannelTheaterComplete(ConflictTheater): +class BattleOfBritain(ConflictTheater): terrain = dcs.terrain.TheChannel() overview_image = "thechannel.gif" reference_points = {(thechannel.Abbeville_Drucat.position.x, thechannel.Abbeville_Drucat.position.y): (2400, 4100), @@ -71,7 +71,7 @@ class ChannelTheaterComplete(ConflictTheater): } def __init__(self): - super(ChannelTheaterComplete, self).__init__() + super(BattleOfBritain, self).__init__() self.abeville = ControlPoint.from_airport(thechannel.Abbeville_Drucat, LAND, SIZE_SMALL, IMPORTANCE_LOW) #self.detling = ControlPoint.from_airport(thechannel.Detling, LAND, SIZE_SMALL, IMPORTANCE_LOW)