Compare commits

..

230 Commits

Author SHA1 Message Date
C. Perreau
3dac0af6c4 Merge pull request #61 from Khopa/develop
2.0.11
2020-08-16 15:27:25 +02:00
Khopa
f9ce6966bb Changelog update 2020-08-16 15:26:20 +02:00
C. Perreau
f61e23153b Merge pull request #60 from Khopa/develop
Develop
2020-08-16 15:22:10 +02:00
Khopa
ff4f008a63 Merge branches 'develop' and 'master' of https://github.com/khopa/dcs_liberation into develop 2020-08-16 15:21:22 +02:00
C. Perreau
cbcf8a0a90 Merge pull request #59 from bwRavencl/fix_uk_typo
Fixed typo "United Kingdown" -> "United Kingdom"
2020-08-16 15:20:59 +02:00
Khopa
647e62059f Changelog update 2020-08-16 15:10:55 +02:00
Khopa
6e3ef24e3a Changelog update 2020-08-16 15:09:44 +02:00
Khopa
2559b27a6f Restrict afterburner for AI units. 2020-08-16 15:08:27 +02:00
Khopa
421e2508d4 JTAC invisble and immortal commands update. 2020-08-16 15:01:34 +02:00
Matteo Hausner
c9f8a93813 Fixed typo "United Kingdown" -> "United Kingdom" 2020-08-16 14:07:37 +02:00
Khopa
126849cf9a JTAC message will be displayed for 25 seconds instead of just 10. 2020-08-16 13:52:42 +02:00
Khopa
c08768f648 Cleaned up dead code 2020-08-16 13:31:12 +02:00
Khopa
2c07257bf6 Small update to nevada exclusion polygons around nellis AFB. 2020-08-16 13:30:36 +02:00
Khopa
f797bbb97f Fixed JTAC using code above than 1688 that cannot be used in game. 2020-08-16 13:11:28 +02:00
Khopa
a7f3b6e0dc F-15E added for USA 2005 and USA 1990 factions. 2020-08-16 13:09:31 +02:00
Khopa
60732c33c0 Libya mispell issue 2020-08-16 12:53:40 +02:00
Khopa
65b77e241f Changelog update 2020-08-16 02:41:56 +02:00
Khopa
a167b95cec Destroyed units will not remain on airfields. 2020-08-16 02:25:42 +02:00
Khopa
283cfd1ce9 Removed some dead code. 2020-08-16 02:19:52 +02:00
Khopa
e16db60d0f Fix error with JTAC compatibility with old saves 2020-08-16 02:18:30 +02:00
Khopa
6a3b5bbe1d Empty neutral airports from supply 2020-08-16 02:17:43 +02:00
Khopa
339c3f506c changelog update 2020-08-16 01:02:12 +02:00
Khopa
9fade70092 Fixed Tankers TACAN being the same and being different from the one in briefing. 2020-08-16 01:01:01 +02:00
Khopa
e18d84ae5e Fixed issues with libya 2011 faction. 2020-08-15 01:10:30 +02:00
Khopa
fa76e31640 JTAC smoke markers can be disabled 2020-08-14 22:59:45 +02:00
Khopa
2fd4fa25f7 Added JTAC smoke parameter. 2020-08-14 22:39:45 +02:00
Khopa
c27d8e3b16 Updated readme.md file. 2020-08-14 19:45:02 +02:00
Khopa
0841c52a75 Readme update link 2020-08-14 19:28:46 +02:00
Khopa
669bff13c7 Updated Github readme. 2020-08-14 19:24:35 +02:00
Khopa
01ea4fa7a6 Fixed big performance issues in release executable. 2020-08-13 16:53:56 +02:00
Khopa
ef024b5118 Removed unused part of release script 2020-08-13 16:10:37 +02:00
Khopa
a96a107ef9 Added Mi24, Mi28, Mig31, Su30 to Russia. 2020-08-13 14:51:30 +02:00
Khopa
8d3ab2be5d Payloads for Mi-24V && Mi-28 2020-08-13 14:50:36 +02:00
Khopa
6ed407f656 Fixed OH-58D not being used by AI 2020-08-13 14:47:59 +02:00
Khopa
6b3625f0ea Forgot to put jtac in changelog. 2020-08-13 00:36:28 +02:00
C. Perreau
db8e7f0474 Merge pull request #46 from Khopa/develop
Merge develop 2.0.10
2020-08-13 00:02:21 +02:00
Khopa
d6398630df Version number 2020-08-12 23:58:23 +02:00
Khopa
464bfccfb6 C-101 picture fix.
Removed UH60 from PMCs.
2020-08-12 23:57:25 +02:00
Khopa
aa16da837d Fixed error 2020-08-12 22:59:00 +02:00
Khopa
ce4478803a Added new factions, and OH-58D payloads. 2020-08-12 22:57:50 +02:00
Khopa
114239fe8e Default size for info panel & map changed 2020-08-12 18:27:13 +02:00
Khopa
67d96061da Fixed JTAC infos in briefing 2020-08-12 18:26:49 +02:00
Khopa
2d5ad16399 More WW2 factions 2020-08-12 18:26:26 +02:00
Khopa
4c7f79c6f8 Fix bug in mission result window. 2020-08-12 03:31:56 +02:00
Khopa
2a50768db1 JTAC support 2020-08-12 03:13:51 +02:00
Khopa
bff33e6992 Added LHA to Caucasus campaigns. 2020-08-10 18:41:41 +02:00
Khopa
448057a0b9 Disabled interceptors for upcoming release 2020-08-10 18:17:00 +02:00
Khopa
0a47669b14 Possible fix for debriefing updates. 2020-08-10 18:10:10 +02:00
Khopa
b5893ce521 Fix potential error in mission waiting for results window. 2020-08-10 17:56:30 +02:00
Khopa
23537211b0 Fallback point is further away 2020-08-10 17:55:32 +02:00
Khopa
39f25db439 Replaced Sa342L by SA342M in uk 90 factions. (L version doesn't want to attack ennemy.) 2020-08-10 17:49:22 +02:00
Khopa
a551067c72 Restrict Jettison for CAS aircrafts 2020-08-10 17:04:46 +02:00
Khopa
23f4df766c Now possible to open and save game under different names. 2020-08-09 17:31:53 +02:00
Khopa
7354a34f1a Misc UI changes to new game wizard and mission result window. 2020-08-09 16:37:10 +02:00
Khopa
2de48b3918 Fix no lha for some factions 2020-08-09 16:36:21 +02:00
Khopa
e823a7a7b0 Replaced new game wizard picture by my own screenshoots (not sure of the source for the previous ones) 2020-08-09 16:36:00 +02:00
Khopa
ffc1f9d48e New harrier payload, tarawa compatible. 2020-08-09 14:43:53 +02:00
Khopa
bb19bfb925 Improved special case for Su-33 carrier takeoff payload 2020-08-07 23:06:54 +02:00
Khopa
b3a2464249 Fixed issue with IL-78M tanker 2020-08-07 23:03:15 +02:00
Khopa
09718e73a3 Changed campaign names in new game window 2020-08-06 00:37:39 +02:00
Khopa
d5f20377ea Remove weapons fired from debriefing window (not computed anymore) 2020-08-06 00:36:49 +02:00
Khopa
f703d620c2 Changed the Nevada campaign setup 2020-08-06 00:35:55 +02:00
Khopa
5ac680b37d Slight change to base defense position calculations 2020-08-06 00:35:24 +02:00
Khopa
9bf57e99fb Removed Mig-29 from Strike mission 2020-08-06 00:34:13 +02:00
Khopa
b787f7cb11 RTB rules for CAS aircraft changed. Added PP M points for AJS 37 2020-08-06 00:33:37 +02:00
Khopa
7b35965dbf Fix : Awacs frequency in briefing 2020-08-06 00:32:47 +02:00
Khopa
1618c1e677 Awacs use 233Mhz instead of 133Mhz 2020-08-06 00:32:17 +02:00
Khopa
0a5ce108b7 Added preplanned point to briefing 2020-08-06 00:31:50 +02:00
Khopa
99c180441d Updated terrain data for all maps. 2020-08-05 22:01:32 +02:00
Khopa
79a7b0557c Improved Caucasus landmap collision data, added exclusions zones for airports. 2020-08-05 20:13:42 +02:00
Khopa
91cf192d2e Fixed AI aircraft do not start datalink. 2020-08-05 01:04:44 +02:00
Khopa
66d7435ed6 Minor balances changes 2020-08-05 00:58:14 +02:00
Khopa
19ea75b281 Fixed all aircraft spawning in the air after a few missions have been played without restarting DCS Liberation. 2020-08-05 00:58:02 +02:00
Khopa
f0350b7045 New Caucasus campaign in Russia 2020-08-04 01:17:26 +02:00
Khopa
9d4d3d0523 Avoid duplicate groups id. 2020-08-04 01:08:27 +02:00
Khopa
a76962e206 Added new campaign generation settings. Added Helicopter Carrier to China faction. 2020-08-04 00:14:42 +02:00
Khopa
4060039440 Changed tanker frequency range to avoid overlap with Persian Gulf TACAN frequencies. 2020-08-03 21:47:22 +02:00
Khopa
c3a3a428a4 Fix tanker speed, tacan and increased race track length. 2020-08-03 20:34:28 +02:00
Khopa
171e23bd09 Fixed S-300 (SA-10) sites missing a tracking radar. 2020-08-03 19:47:08 +02:00
Khopa
6f4b7e0f1a WIP 2020-08-03 19:43:12 +02:00
Khopa
ccf2cd3425 Factions small changes 2020-08-03 19:42:09 +02:00
Khopa
6ee444efd7 Aircraft should RTB when Bingo.
CAP should RTB when winchester.
2020-08-02 13:59:55 +02:00
Khopa
3e5be909a2 Lua script injected in mission will not listen to weapon fired event anymore. 2020-08-02 02:46:00 +02:00
Khopa
dac78f8f09 changelog update 2020-08-02 02:45:19 +02:00
Khopa
6b91e1b03c Fixed FW-190A8 spawning with bomb rack even when configured for CAP 2020-08-02 02:31:40 +02:00
Khopa
772295fc04 Avoid having Su-33 crashing when taking off from their carrier with a too big payload by removing some fuel. 2020-08-01 18:07:49 +02:00
Khopa
a4e93276b8 Possible to mix factions side. Player will always be blue. 2020-08-01 14:21:34 +02:00
Khopa
456a82acaa Multiple factions fixes 2020-08-01 14:20:37 +02:00
Khopa
f2fb2cb363 Fixed label in strike mission generator 2020-08-01 14:19:46 +02:00
C. Perreau
2a7e5eecd7 Merge pull request #30 from DeusEx010101/add-usa-aggressors-faction
Added USA aggressors aircraft.
2020-07-31 20:35:18 +02:00
Khopa
79502f56a0 Added Australia / Canada 2020-07-31 20:34:27 +02:00
Khopa
12dacfe2d2 Fixed A-20G payloads. 2020-07-30 19:31:38 +02:00
Donnie
d46337d694 Added USA aggressors. TODO. Decide on final aggressors unit list. 2020-07-26 11:27:18 -04:00
Khopa
f897cf745f Multiple WIP changes on UI / Submit manually debriefing. 2020-07-26 12:59:16 +02:00
Khopa
cfa4f7da2e Take off alt waypoint was editable in flight waypoint table. 2020-07-26 00:57:45 +02:00
Khopa
b21272cfab Made waypoint altitude column not editable 2020-07-25 23:07:23 +02:00
Khopa
8ce0520101 QSettings Windows can edit new performance setting to disable destroyed units 2020-07-25 23:05:13 +02:00
Khopa
4c17e1fd33 Possible to disable destroyed units. 2020-07-25 23:04:00 +02:00
Khopa
d5fb1f62f5 Previously destroyed units are added to the mission. 2020-07-25 18:46:10 +02:00
Khopa
b34ede3795 LHA carrier group ships are more spread out. 2020-07-25 16:21:03 +02:00
Khopa
4989d84693 Carrier group ships are more spread out. 2020-07-25 16:18:13 +02:00
Khopa
2f210ab59f Fixed error in carrier group generator if faction has no destroyers 2020-07-25 16:17:40 +02:00
Khopa
3ffea901f1 Added japan_2005 faction. 2020-07-25 16:15:23 +02:00
Khopa
5e2e6520ce Fixed issues with coldwar factions. 2020-07-25 16:14:53 +02:00
Khopa
a8679c8eef Fixed strike mission generator window was named "sead mission generator" 2020-07-25 15:14:48 +02:00
Khopa
469e842e96 Fixed wrong radio frequency for german WW2 warbirds. 2020-07-24 01:37:33 +02:00
Khopa
cd945c625f Base defense units can be controlled with CA. 2020-07-24 00:23:11 +02:00
Khopa
1346192b75 Fix : Carrier on Persian Gulf full map were sharing the same id. 2020-07-24 00:11:55 +02:00
Khopa
45bebdd94e Updated pydcs version in requirements.txt 2020-07-24 00:02:13 +02:00
Khopa
d0bbb025d3 Added carrier frequency to briefing. 2020-07-23 21:30:50 +02:00
Khopa
8d0c53ef69 Remove Oliver Hazard Perry from Cold War factions. 2020-07-23 21:12:46 +02:00
Khopa
a59c2dfb10 Changed F-15C default payload. Replaced AIM-9P by AIM-9M. Replaced AIM-120B by AIM-120C. 2020-07-22 23:59:25 +02:00
Khopa
9c7689f9b5 Increased offset for attack points. 2020-07-20 21:32:49 +02:00
Khopa
c580979fee Open base menu by single mouse click. 2020-07-20 20:36:57 +02:00
Khopa
e8e7bc95ea Culling is a bit less aggresive. 2020-07-20 00:29:37 +02:00
Khopa
839e3e0833 Removed JF-17 from usa 2005 faction. 2020-07-19 17:11:34 +02:00
Khopa
4f451fab2f Show required mods in new gam wizard 2020-07-19 17:11:05 +02:00
Khopa
7d0413f41d Remove Type 93 from radar db and cc fleet gen 2020-07-17 01:45:46 +02:00
Khopa
bbac78195d Credits 2020-07-17 01:08:47 +02:00
Khopa
20fef86b84 Fixed aircraft carrier cold start 2020-07-17 01:02:21 +02:00
Khopa
9581a8f1f4 Support for frenchpack mod & Rafale Mod 2020-07-09 00:39:33 +02:00
Khopa
58b4c36b6c MB-339PAN payload fix. 2020-07-05 18:10:54 +02:00
Khopa
15aaa5d9a1 MB-339PAN support. 2020-07-05 17:15:43 +02:00
Khopa
b38332d061 Requirements update, new pydcs version 2020-07-04 16:43:01 +02:00
Khopa
4cfbbb6756 A-4E-C is now considered carrier capable; 2020-07-04 15:59:50 +02:00
Khopa
dec7db9e69 Cleaning up dead code 2020-07-04 15:59:23 +02:00
Khopa
274be3bcfc Fix : Carrier sail into the wind. Not in the same direction. 2020-07-04 15:59:00 +02:00
Khopa
d8a668ce60 Fix : Channel map, removed town names 2020-07-04 02:04:53 +02:00
Khopa
a845ed1998 Fix : Code that should be commented for custom ref point. 2020-07-04 01:37:04 +02:00
Khopa
53bd147de2 Community A-4E-C support 2020-07-04 01:35:48 +02:00
Khopa
4248b518a2 Merge branch 'develop' of https://github.com/khopa/dcs_liberation 2020-07-03 02:55:50 +02:00
Khopa
8f65a88d8b New satelitte background for all maps. 2020-07-03 02:54:58 +02:00
C. Perreau
4d4a640f34 Merge pull request #11 from DeusEx010101/UI-fixes-new-themes
UI Update!
2020-07-01 15:39:31 +02:00
Donnie
af9ead5937 lots of UI enhancements for better feedback and state 2020-06-30 22:19:45 -04:00
Donnie
ae3518f450 Map cp lines and flight paths are now the color of your coalition (red or blue) 2020-06-30 16:44:04 -04:00
Donnie
04e77a97f2 Fix: map icons now match player side color (red or blue) 2020-06-29 17:32:29 -04:00
Donnie
0ff3ce98e0 new map graphic test 2020-06-29 17:31:47 -04:00
Donnie
df2659787c adjust map colors 2020-06-29 17:31:35 -04:00
Donnie
d994673e91 blurred map background to soften edges 2020-06-29 10:00:12 -04:00
Donnie
dce781ef0e New splash screen 2020-06-29 09:59:20 -04:00
Donnie
b0e2c73024 Made SAM range circles easier to see 2020-06-28 22:56:48 -04:00
Donnie
bda28f81cc Added disable button style 2020-06-28 22:45:30 -04:00
Donnie
d8dc3d48b1 made dcs theme default 2020-06-28 01:12:47 -04:00
Donnie
5fdfa6339d front line thinner 2020-06-28 01:10:38 -04:00
Donnie
9a799190ef Map ui design updated 2020-06-28 01:06:02 -04:00
Donnie
8d32ba5b8e Map red icons darker 2020-06-28 01:05:37 -04:00
Donnie
85a7f89ba9 Css updates to dcs theme 2020-06-27 23:55:56 -04:00
Donnie
17f5378326 Modified recruit button layout 2020-06-27 23:54:27 -04:00
Donnie
9d67741310 made font references constants 2020-06-27 23:53:56 -04:00
Donnie
ac6a106c6a Merge branch 'master' into DCS-UI-Theme 2020-06-26 16:18:01 -04:00
Donnie
d775b8baa0 Some clean up and refactoring 2020-06-26 11:39:28 -04:00
Donnie
2dc1b3ec43 Icons change based on theme. wip 2020-06-26 00:57:00 -04:00
Donnie
d3d5160861 UI Theme switcher working 2020-06-26 00:39:04 -04:00
Donnie
cdf8c3b6e5 menu bar and info panel spacing 2020-06-24 22:09:31 -04:00
Donnie
29b1bbab9d combobox styles. what a pain. WIP 2020-06-24 18:13:20 -04:00
Khopa
c5d055c19b Prepared version RC9 2020-06-24 23:54:23 +02:00
Khopa
8f7b51a3df Fixed an issue with MolniyaGroup generator causing an error on campaign start. 2020-06-24 23:51:23 +02:00
Khopa
44e8cc810f Fixed an issue with MolniyaGroup generator causing an error on campaign start. 2020-06-24 23:49:27 +02:00
Donnie
b994878465 checkboxes 2020-06-24 17:33:36 -04:00
Khopa
8d5d703cbe Merge branches 'develop' and 'master' of https://github.com/khopa/dcs_liberation into develop 2020-06-24 23:22:34 +02:00
Khopa
1c1936d8f8 Fix : Carrier TACAN was wrongfully set up as an A/A TACAN 2020-06-24 23:22:07 +02:00
Donnie
7890fd5cc7 Base theme applied. WIP. 2020-06-24 16:40:19 -04:00
C. Perreau
4bdf11eb79 Merge pull request #9 from DeusEx010101/New-Icons
changed AA icon
2020-06-24 22:29:56 +02:00
Donnie
81f4c7303f changed AA icon 2020-06-24 15:39:08 -04:00
C. Perreau
0641907ea0 Merge pull request #8 from DeusEx010101/New-Icons
Icons updated to be more consistent
2020-06-24 21:31:32 +02:00
Donnie
ff0f32fcf5 Icons updated to be more consistent 2020-06-24 14:52:06 -04:00
Khopa
768049ca36 Changelog update 2020-06-23 12:57:46 +02:00
Khopa
88c8fe7cca Fixed zoom on map. 2020-06-23 12:56:01 +02:00
Khopa
5e7facfeb6 Fixed issue with WW2 LST group (boats superposed) 2020-06-23 12:06:19 +02:00
Khopa
6e43467ef6 Fix : Reduced maximum number of uboat 2020-06-23 12:05:15 +02:00
Khopa
cd4ef8ae32 Fix frequency for P-47 2020-06-23 11:46:57 +02:00
Khopa
93a4463f22 Fixed logging issues and SEAD flights departing without waiting. 2020-06-22 23:20:14 +02:00
Khopa
56cf6bdaa4 Mission planning polishing. 2020-06-22 21:31:25 +02:00
Khopa
fe02df27a2 Do not allow selection of non existing carrier in mission planner 2020-06-22 12:44:49 +02:00
Khopa
a60ab68287 Aircraft Carrier will try to sail in the wind when possible. 2020-06-21 18:15:58 +02:00
Khopa
83e46ddc97 SEAD AI will only target the designated target group. 2020-06-21 17:50:06 +02:00
Khopa
9c89ad7c72 Reduced maximum wind in generated missions. 2020-06-21 15:05:57 +02:00
Khopa
0518abdedc Balance for WW2 aircraft. WW2 B_17 bombing mode is now much more effective. 2020-06-20 15:28:42 +02:00
Khopa
93bcd07c7f Added aircraft icons + fixed ww2 empty aircraft loadout not being loaded. 2020-06-20 13:44:11 +02:00
Khopa
5f1f4f8d81 Culling optimizations + fixed some aircraft icons 2020-06-19 14:31:25 +02:00
Khopa
e78120d9c6 Fix : Egress waypoint for SEAD mission is wrongfully named INGRESS 2020-06-17 23:15:44 +02:00
Khopa
cc5986d435 Updated readme 2020-06-17 13:48:33 +02:00
Khopa
5192306b06 Generate fleet and missiles sites 2020-06-17 13:04:55 +02:00
Khopa
826935eb7d Ship icons for ship groups 2020-06-14 17:31:45 +02:00
Khopa
cd41bcf45c Generate WW2 Ship groups, added B17 to allies. Implemented modifiable doctrine to setup flight generator. 2020-06-13 18:53:43 +02:00
Khopa
601375d06f Channel map support. 2020-06-12 19:10:58 +02:00
Khopa
c708abafc8 Started refactoring on ground objects. WW2 factions will have WW2 style buildings. Added ground objects templates for : "village", "ww2bunker", "allycamp" 2020-06-11 21:50:09 +02:00
Khopa
90d588353c Icon and background image for channel map. Updated Normandy map background. 2020-06-11 21:48:16 +02:00
Khopa
2d4287df2a Polished mission generator, fixed sam bug on map view. 2020-06-10 22:34:31 +02:00
Khopa
fde3a988b7 Added missions generators in flight planner. + refactoring 2020-06-09 02:13:46 +02:00
Khopa
397164e667 Added multiple settings (external views, map views) and added marker generators. 2020-06-07 19:55:38 +02:00
Khopa
a7824039e3 Added revenue for derrick building 2020-06-07 15:54:15 +02:00
Khopa
bb9247e821 Fix info panel messages. 2020-06-06 16:57:20 +02:00
Khopa
4bc04ec031 Auto redeploy frontline units. 2020-06-06 16:50:19 +02:00
Khopa
8fd91e6c5c Added possible ground target : Oil derrick 2020-06-06 15:45:15 +02:00
Khopa
ee137d086a Change power station template. (Some buildings could superpose in older version) 2020-06-06 15:10:07 +02:00
Khopa
fcd81850cb Debriefing and info on AA site and buildings destroyed. KC130 replace S3B 2020-06-06 04:10:22 +02:00
Khopa
aa4b07d024 Add more waypoints to generated flights 2020-06-05 21:24:23 +02:00
Khopa
16a096d288 Possible to setup whether AI should starts from parking or not. 2020-06-05 14:23:38 +02:00
Khopa
b219b2a71b Possible to setup custom saved game and installation directory. 2020-06-05 14:21:42 +02:00
Khopa
ce70242c35 Added 947 to allies and default payload for P47 2020-06-04 13:30:38 +02:00
Khopa
dec01e2611 Added P-47 to db 2020-06-04 13:25:14 +02:00
Khopa
4373d89661 WIP on CAP, and AI units can starts from ground uncontrolled instead of using late activation. 2020-06-03 00:45:44 +02:00
Khopa
c73290eebb Nav Target point for JF-17 and F-14.
Fix activation trigger using wrong coalition when playing REDFOR side.
2020-06-02 13:00:10 +02:00
Khopa
a022f9c2e1 Changelog update 2020-06-01 15:27:45 +02:00
Khopa
5adb25a695 Using late activation trigger. Planned flight will not spawn if their home base has been captured or is contested. 2020-06-01 15:11:38 +02:00
Khopa
08c2972cf9 Added map theater : North Caucasus 2020-06-01 14:20:43 +02:00
Khopa
8132c7e676 Fix : CAP aircraft will jettison fuel tanks. 2020-06-01 13:03:35 +02:00
Khopa
8c68c9f703 Fix for payload for release versions. 2020-06-01 12:51:59 +02:00
Khopa
000b6142fd Added Ka-50 to bluefor modern. 2020-06-01 12:42:02 +02:00
Khopa
c203ded1cd Improved Mission Planning flight selection behaviour. 2020-06-01 12:36:10 +02:00
Khopa
64c5c39b2a BARCAP renamed CAP for regular airbases. 2020-06-01 11:14:30 +02:00
Khopa
a8d2a1e371 Removed Ju-88 from CAS (only has torpedo in DCS) 2020-06-01 01:49:20 +02:00
Khopa
9e5846b24a Improved WW2 support. 2020-06-01 01:27:16 +02:00
Khopa
836ff9122c Fix base defense units not being generated when other ground objects were too close. 2020-06-01 00:35:26 +02:00
Khopa
75d836358b Revert an error on sam site generation. (Disabled the wrong code.) 2020-06-01 00:05:32 +02:00
Khopa
bb11e7f90c Removed FARP AA that does not respect the factions config. 2020-05-31 23:58:43 +02:00
Khopa
cf6a71ab86 Fix issue when "no night mission" is enabled. 2020-05-31 23:50:13 +02:00
Khopa
7f7288937d Handle error when there is no AWACS for a faction. 2020-05-31 23:26:03 +02:00
Khopa
a38f9c2183 Added performance settings. 2020-05-31 23:07:54 +02:00
Khopa
7ee880cadc Generate ICLS command for carriers 2020-05-31 20:00:07 +02:00
Khopa
9ae34d474b Added Bluefor modern faction 2020-05-31 19:44:53 +02:00
Khopa
2817e2f2c8 Update for new pyDCS version. Supercarrier support added. 2020-05-31 19:19:03 +02:00
Khopa
02886a09d3 AI Strike flight with user generated STRIKE, will now perform their bombing task correctly. 2020-05-31 18:02:00 +02:00
Khopa
0b9d827ad6 AI Strike flight will bomb all their targets correctly 2020-05-31 15:43:56 +02:00
Khopa
ab3ea84d70 AI flight planner now auto generate STRIKE flights.
Fix CAS point position in predefined wpt selector.
When an airbase is captured, base defenses are re-generated for the new base owner.
2020-05-30 02:32:45 +02:00
Khopa
03a1c44659 README update for QT UI branch 2020-05-30 00:03:42 +02:00
Khopa
53364444fd Possible fix for crash when loading old save files. 2020-05-30 00:03:11 +02:00
Khopa
94040e8551 Fix new campaign wizard crashing and made the campaign generator slightly faster. 2020-05-29 23:47:13 +02:00
Khopa
34d46ee28e Fix objective name error when no more objective name are availables. 2020-05-29 23:43:26 +02:00
413 changed files with 13242 additions and 3295 deletions

8
.gitignore vendored
View File

@@ -11,3 +11,11 @@ resources/tools/a.miz
tests/**
# User-specific stuff
.idea/
liberation_preferences.json
logs/liberation.log
qt_ui/logs/liberation.log
*.psd

View File

@@ -1,26 +1,39 @@
![Logo](https://i.imgur.com/c2k18E1.png)
[DCS World](https://www.digitalcombatsimulator.com/en/products/world/) single-player dynamic campaign.
[![Download](https://img.shields.io/github/downloads/khopa/dcs_liberation/total?label=Download)](https://github.com/Khopa/dcs_liberation/releases)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/paypalme/KhopaDCSL)
[![Discord](https://img.shields.io/discord/595702951800995872?label=Discord&logo=discord)](https://discord.gg/bKrtrkJ)
Uses [pydcs](http://github.com/pydcs/dcs) for mission generation.
[![GitHub pull requests](https://img.shields.io/github/issues-pr/khopa/dcs_liberation)](https://github.com/Khopa/dcs_liberation)
[![GitHub issues](https://img.shields.io/github/issues/khopa/dcs_liberation)](https://github.com/Khopa/dcs_liberation/issues)
![GitHub stars](https://img.shields.io/github/stars/khopa/dcs_liberation?style=social)
## Tutorials
* [Manual](https://github.com/shdwp/dcs_liberation/wiki/Manual)
## About DCS Liberation
DCS Liberation is a [DCS World](https://www.digitalcombatsimulator.com/en/products/world/) turn based single-player semi dynamic campaign.
It is an external program that generates full and complex DCS missions and manage a persistent combat environment.
You should start with the manual, it covers everything you need to know before playing the campaign.
![Logo](https://imgur.com/B6tvlBJ.png)
* [Strike objectives reference images](https://imgur.com/a/vCSHa9f)
## Downloads
If you can't find the strike objective you can see here how it's supposed to look.
Latest release is available here : https://github.com/Khopa/dcs_liberation/releases
* [Troubleshooting](https://github.com/shdwp/dcs_liberation/wiki/Troubleshooting)
## Resources
You could also briefly check the troubleshooting page to get familiar with the known issues that you could probably fix by yourself.
* [Getting Started](https://github.com/Khopa/dcs_liberation/wiki/Getting-started)
* [Modding tutorial](https://github.com/shdwp/dcs_liberation/wiki/Modding-tutorial)
* [Tutorials](https://github.com/Khopa/dcs_liberation/wiki/Tutorial-01-:-UI)
Modding tutorial will cover how to change default loadouts, configure which planes are present in the campaign (or add new altogether) and more. Check this out if you find that something is not going for your liking, there could be a tutorial for changing that. Although be aware that it would require changing source files and could easily result in non functioning application.
* [Developer/Contributor Guide]()(TODO)
* [Development guide](https://github.com/shdwp/dcs_liberation/wiki/Development-guide)
* [Hosting DCS Liberation generated missions on a dedicated server]()(TODO)
If you want to contribute to the project, this will give you a brief overview and on how to actually run it from source files.
## Special Thanks
First, a big thanks to shdwp, for starting the original DCS Liberation project.
Then, DCS Liberation uses [pydcs](http://github.com/pydcs/dcs) for mission generation, and nothing would be possible without this.
It also uses the popular [Mist](https://github.com/mrSkortch/MissionScriptingTools) lua framework for mission scripting.
And for the JTAC feature, DCS Liberation embed Ciribob's JTAC Autolase [script](https://github.com/ciribob/DCS-JTACAutoLaze).
Please also show some support to these projects !

View File

@@ -1,64 +0,0 @@
#!/usr/bin/env python3
import logging
import os
import re
import sys
import dcs
import ui.corruptedsavemenu
import ui.mainmenu
import ui.newgamemenu
import ui.window
from game.game import Game
from userdata import persistency, logging as logging_module
assert len(sys.argv) >= 3, "__init__.py should be started with two mandatory arguments: %UserProfile% location and application version"
persistency.setup(sys.argv[1])
dcs.planes.FlyingType.payload_dirs = [os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources\\payloads")]
VERSION_STRING = sys.argv[2]
logging_module.setup_version_string(VERSION_STRING)
logging.info("Using {} as userdata folder".format(persistency.base_path()))
def proceed_to_main_menu(game: Game):
m = ui.mainmenu.MainMenu(w, None, game)
m.display()
def is_version_compatible(save_version):
current_version_components = re.split(r"[\._]", VERSION_STRING)
save_version_components = re.split(r"[\._]", save_version)
if "--ignore-save" in sys.argv:
return False
if current_version_components == save_version_components:
return True
if save_version in ["1.4_rc1", "1.4_rc2", "1.4_rc3", "1.4_rc4", "1.4_rc5", "1.4_rc6"]:
return False
if current_version_components[:2] == save_version_components[:2]:
return True
return False
w = ui.window.Window()
try:
game = persistency.restore_game()
if not game or not is_version_compatible(game.settings.version):
ui.newgamemenu.NewGameMenu(w, w.start_new_game).display()
else:
game.settings.version = VERSION_STRING
proceed_to_main_menu(game)
except Exception as e:
logging.exception(e)
ui.corruptedsavemenu.CorruptedSaveMenu(w).display()
w.run()

183
changelog.md Normal file
View File

@@ -0,0 +1,183 @@
# 2.0.11
## Features/Improvements :
* **[Units/Factions]** Added Mig-31, Su-30, Mi-24V, Mi-28N to Russia 2010 faction.
* **[Units/Factions]** Added F-15E to USA 2005 and USA 1990 factions.
* **[Mission Generator]** Added a parameter to choose whether the JTACs should use smoke markers or not
## Fixed issues :
* **[Units/Factions]** Fixed big performance issue in new release UI that occurred only when running the .exe
* **[Units/Factions]** Fixed mission generation not working with Libya faction
* **[Units/Factions]** Fixed OH-58D not being used by AI
* **[Units/Factions]** Typo in UK 1990 name (fixed by bwRavencl)
* **[Units/Factions]** Fixed Tanker Tacan channel not being the same as the briefing one. (Sorry)
* **[Mission Generator]** Neutral airbases services will now be disabled. (Not possible to refuel or re-arm there)
* **[Mission Generator]** AI will be configured to limit afterburner usage
* **[Mission Generator]** JTAC will not use laser codes above 1688 anymore
* **[Mission Generator]** JTAC units were misconfigured and would not be invisible/immortal.
* **[Mission Generator]** Increased JTAC status message duration to 25s, so you have more time to enter coordinates;
* **[Mission Generator]** Destroyed units carcass will not appear on airfields to avoid having a destroyed vehicle blocking a runway or taxiway.
# 2.0.10
## Features/Improvements :
* **[Misc]** Now possible to save game in a different file, and to open DCS Liberation savegame files. (You are not restricted to a single save file anymore)
* **[UI/UX]** New dark UI Theme and default theme improvement by Deus
* **[UI/UX]** New "satellite" map backgrounds
* **[UX]** Base menu is opened with a single mouse click
* **[Units/Factions/Mods]** Added Community A-4E-C support for faction Bluefor Cold War
* **[Units/Factions/Mods]** Added MB-339PAN support for faction Bluefor Cold War
* **[Units/Factions/Mods]** Added Rafale AI mod support
* **[Units/Factions/Mods]** Added faction "France Modded" with units from frenchpack v3.5 mod
* **[Units/Factions/Mods]** Added faction "Insurgent modded" with Insurgent units from frenchpack v3.5 mod (Toyota truck)
* **[Units/Factions/Mods]** Added factions Canada 2005, Australia 2005, Japan 2005, USA Aggressors, PMC
* **[New Game Wizard]** Added the list of required mods for modded factions.
* **[New Game Wizard]** No more RED vs BLUE opposing faction restrictions.
* **[New Game Wizard]** New campaign generation settings added : No aircraft carrier, no lha, no navy, invert map starting positions.
* **[Mission Generator]** Artillery units will start firing mission after a random delay. It should reduces lag spikes induced by artillery strikes by spreading them out.
* **[Mission Generator]** Ground units will retreat after taking too much casualties. Artillery units will retreat if engaged.
* **[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
* **[Campaign Generator]** Added Tarawa in caucasus campaigns
* **[Campaign Generator]** Tuned the various existing campaign parameters
* **[Campaign Generator]** Added small campaign : "Russia" on Caucasus Theater
## Fixed issues :
* **[Mission Generator]** Carrier will sail into the wind, not in the same direction
* **[Mission Generator]** Carrier cold start was not working (flight was starting warm even when cold was selected)
* **[Mission Generator]** Carrier group ships are more spread out
* **[Mission Generator]** Fixed wrong radio frequency for german WW2 warbirds
* **[Mission Generator]** Fixed FW-190A8 spawning with bomb rack for CAP missions
* **[Mission Generator]** Fixed A-20G spawning with no payload
* **[Mission Generator]** Fixed Su-33 spawning too heavy to take off from carrier
* **[Mission Generator]** Fixed Harrier AV-8B spawning too heavy to take off from tarawa
* **[Mission Generator]** Base defense units were not controllable with Combined Arms
* **[Mission Generator]** Tanker speed was too low
* **[Mission Generator]** Tanker TACAN settings were wrong
* **[Mission Generator]** AI aircraft should start datalink ON (EPLRS)
* **[Mission Generator]** Base defense units should not spawn on runway and or taxyway. (The chance for this to happen should now be really really low)
* **[Mission Generator]** Fixed all flights starting "In flight" after playing a few missions (parking slot reset issue)
* **[Mission Script/Performance]** Mission lua script will not listen to weapons fired event anymore and register every fired weapons. This should improve performance especially in WW2 scenarios or when rocket artillery is firing.
* **[Campaign Generator]** Carrier name will now not appear for faction who do not have carriers
* **[Campaign Generator]** SA-10 sites will now have a tracking radar.
* **[Units/Factions]** Remove JF-17 from USA 2005 faction
* **[Units/Factions]** Remove AJS-37 from Russia 2010
* **[Units/Factions]** Removed Oliver Hazard Perry from cold war factions (too powerful sam system for the era)
* **[Bug]** On the persian gulf full map campaign, the two carriers were sharing the same id, this was causing a lot of bugs
* **[Performance]** Tuned the culling setting so that you cannot run into situation where no friendly or enemy AI flights are generated
* **[Other]** Application doesn't gracefully exit.
* **[Other]** Other minor fixes, and multiples factions small changes
# 2.0 RC 9
## Features/Improvements :
* **[UI/UX]** New icons from contributor Deus
## Fixed issues :
* **[Mission Generator]** Carrier TACAN was wrongfully set up as an A/A TACAN
* **[Campaign Generator]** Fixed issue with Russian navy group generator causing a random crash on campaign creation.
# 2.0 RC 8
## Fixed issues :
* **[Mission Generator]** Frequency for P-47D-30 changed to 124Mhz (Generated mission with 251Mhz would not work)
* **[Mission Generator]** Reduced the maximum number of uboat per generated group
* **[Mission Generator]** Fixed an issue with the WW2 LST groups (superposed units).
* **[UI]** Fixed issue with the zoom
# 2.0 RC 7
## Features/Improvements :
* **[Units/Factions]** Added P-47D-30 for factions allies_1944
* **[Units/Factions]** Added factions : Bluefor Coldwar, Germany 1944 Easy
* **[Campaign/Map]** Added a campaign in the Channel map
* **[Campaign/Map]** Changed the Normandy campaign map
* **[Campaign/Map]** Added new campaign Normandy Small
* **[Mission Generator]** AI Flight generator has been reworked
* **[Mission Generator]** Add PP points for JF-17 on STRIKE missions
* **[Mission Generator]** Add ST point for F-14B on STRIKE missions
* **[Mission Generator]** Flights with client slots will never be delayed
* **[Mission Generator]** AI units can start from parking (With a new setting in Settings Window to disable it)
* **[Mission Generator]** Tacan for carrier will only be in Mode X from now
* **[Mission Generator]** RTB waypoints for autogenerated flights
* **[Flight Planner]** Added CAS mission generator
* **[Flight Planner]** Added CAP mission generator
* **[Flight Planner]** Added SEAD mission generator
* **[Flight Planner]** Added STRIKE mission generator
* **[Flight Planner]** Added buttons to add autogenerated waypoints (ASCEND, DESCEND, RTB)
* **[Flight Planner]** Improved waypoint list
* **[Flight Planner]** WW2 factions uses different parameters for flight planning.
* **[Settings]** Added settings to disallow external views
* **[Settings]** Added settings to choose F10 Map mode (All, Allies only, Player only, Fog of War, Map Only)
* **[Settings]** Added settings to choose whether to auto-generate objective marks on the F10 map
* **[Info Panel]** Added information about destroyed buildings in info panel
* **[Info Panel]** Added information about destroyed units at SAM site in info panel
* **[Debriefing]** Added information about units destroyed outside the frontline in the debriefing window
* **[Debriefing]** Added destroyed buildings in the debriefing window
* **[Map]** Tooltip now contains the list of building for Strike targets on the map
* **[Map]** Added "Oil derrick" building
* **[Map]** Added "ww2 bunker" building (WW2)
* **[Map]** Added "ally camp" building (WW2)
* **[Map]** Added "V1 Site" (WW2)
* **[Misc]** Made it possible to setup DCS Saved Games directory and DCS installation directory manually at first start
* **[Misc]** Added culling performance settings
## Fixed issues :
* **[Units/Factions]** Replaced S3-B Tanker by KC130 for most factions (More fuel)
* **[Units/Factions]** WW2 factions will not have offshore oil station and other modern buildings generated. No more third-reich operated offshore stations will spawn on normandy's coast.
* **[Units/Factions]** Aircraft carrier will try to move in the wind direction
* **[Units/Factions]** Missing icons added for some aircraft
* **[Mission Generator]** When playing as RED the activation trigger would not be properly generated
* **[Mission Generator]** FW-190A8 is now properly considered as a flyable aircraft
* **[Mission Generator]** Changed "strike" payload for Su-24M that was ineffective
* **[Mission Generator]** Changed "strike" payload for JF-17 to use LS-6 bombs instead of GBU
* **[Mission Generator]** Change power station template. (Buildings could end up superposed).
* **[Maps/Campaign]** Now using Vasiani airbase instead of Soganlung airport in Caucasus campaigns (more parking slot)
* **[Info Panel]** Message displayed on base capture event stated that the enemy captured an airbase, while it was the player who captured it.
* **[Map View]** Graphical glitch on map when one building of an objective was destroyed, but not the others
* **[Mission Planner]** The list of flights was not updated on departure time change.
# 2.0 RC 6
Saves file from RC5 are not compatible with the new version.
Sorry :(
## Features/Improvements :
* **[Units/Factions]** Supercarrier support (You have to go to settings to enable it, if you have the supercarrier module)
* **[Units/Factions]** Added 'Modern Bluefor' factions, containing all most popular DCS flyable units
* **[Units/Factions]** Factions US 2005 / 1990 will now sometimes have Arleigh Burke class ships instead of Perry as carrier escorts
* **[Units/Factions]** Added support for newest WW2 Units
* **[Campaign logic]** When a base is captured, refill the "base defenses" group with units for the new owner.
* **[Mission Generator]** Carrier ICLS channel will now be configured (check your briefing)
* **[Mission Generator]** SAM units will spawn on RED Alarm state
* **[Mission Generator]** AI Flight planner now creates its own STRIKE flights
* **[Mission Generator]** AI units assigned to Strike flight will now actually engage the buildings they have been assigned.
* **[Mission Generator]** Added performance settings to allow disabling : smoke, artillery strike, moving units, infantry, SAM Red alert mode.
* **[Mission Generator]** Using Late Activation & Trigger in attempt to improve performance & reduce stutter (Previously they were spawned through 'ETA' feature)
* **[UX]** : Improved flight selection behaviour in the Mission Planning Window
## Fixed issues :
* **[Mission Generator]** Payloads were not correctly assigned in the release version.
* **[Mission Generator]** Game generation does not work when "no night mission" settings was selected and the current time was "day"
* **[Mission Generator]** Game generation does not work when the player selected faction has no AWACS
* **[Mission Generator]** Planned flights will spawn even if their home base has been captured or is being contested by enemy ground units.
* **[Campaign Generator]** Base defenses would not be generated on Normandy map and in some rare cases on others maps as well
* **[Mission Planning]** CAS waypoints created from the "Predefined waypoint selector" would not be at the exact location of the frontline
* **[Naming]** CAP mission flown from airbase are not named BARCAP anymore (CAP from carrier is still named BARCAP)

21
game/data/aaa_db.py Normal file
View File

@@ -0,0 +1,21 @@
from dcs.vehicles import AirDefence
AAA_UNITS = [
AirDefence.SPAAA_Gepard,
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.AAA_Vulcan_M163,
AirDefence.AAA_ZU_23_Closed,
AirDefence.AAA_ZU_23_Emplacement,
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,
AirDefence.AAA_8_8cm_Flak_36,
AirDefence.AAA_8_8cm_Flak_37,
AirDefence.AAA_Flak_Vierling_38,
AirDefence.AAA_Kdo_G_40,
AirDefence.AAA_8_8cm_Flak_41,
AirDefence.AAA_Bofors_40mm
]

View File

@@ -0,0 +1,16 @@
import inspect
import dcs
DEFAULT_AVAILABLE_BUILDINGS = ['fuel', 'ammo', 'comms', 'oil', 'ware', 'farp', 'fob', 'power', 'factory', 'derrick', 'aa']
WW2_GERMANY_BUILDINGS = ['fuel', 'factory', 'ww2bunker', 'ww2bunker', 'ww2bunker', 'allycamp', 'allycamp', 'aa']
WW2_ALLIES_BUILDINGS = ['fuel', 'factory', 'allycamp', 'allycamp', 'allycamp', 'allycamp', 'allycamp', 'aa']
FORTIFICATION_BUILDINGS = ['Siegfried Line', 'Concertina Wire', 'Czech hedgehogs 1', 'Czech hedgehogs 2',
'Dragonteeth 1', 'Dragonteeth 2', 'Dragonteeth 3', 'Dragonteeth 4', 'Dragonteeth 5',
'Haystack 1', 'Haystack 2', 'Haystack 3', 'Haystack 4', 'Hemmkurvenvenhindernis',
'Log posts 1', 'Log posts 2', 'Log posts 3', 'Log ramps 1', 'Log ramps 2', 'Log ramps 3',
'Belgian Gate', 'Container white']
FORTIFICATION_UNITS = [c for c in vars(dcs.vehicles.Fortification).values() if inspect.isclass(c)]
FORTIFICATION_UNITS_ID = [c.id for c in vars(dcs.vehicles.Fortification).values() if inspect.isclass(c)]

View File

@@ -0,0 +1,33 @@
from dcs.planes import *
from pydcs_extensions.a4ec.a4ec import A_4E_C
"""
This list contains the aircraft that do not use the guns as the last resort weapons, but as a main weapon
They'll RTB when they don't have gun ammo left
"""
GUNFIGHTERS = [
# Cold War
MiG_15bis,
MiG_19P,
MiG_21Bis,
F_86F_Sabre,
A_4E_C,
F_5E_3,
# Trainers
C_101CC,
L_39ZA,
# WW2
P_51D_30_NA,
P_51D,
P_47D_30,
SpitfireLFMkIXCW,
SpitfireLFMkIX,
Bf_109K_4,
FW_190D9,
FW_190A8,
I_16,
]

95
game/data/doctrine.py Normal file
View File

@@ -0,0 +1,95 @@
from game.utils import nm_to_meter, feet_to_meter
MODERN_DOCTRINE = {
"GENERATORS": {
"CAS": True,
"CAP": True,
"SEAD": True,
"STRIKE": True,
"ANTISHIP": True,
},
"STRIKE_MAX_RANGE": 1500000,
"SEAD_MAX_RANGE": 1500000,
"CAP_EVERY_X_MINUTES": 20,
"CAS_EVERY_X_MINUTES": 30,
"SEAD_EVERY_X_MINUTES": 40,
"STRIKE_EVERY_X_MINUTES": 40,
"INGRESS_EGRESS_DISTANCE": nm_to_meter(45),
"INGRESS_ALT": feet_to_meter(20000),
"EGRESS_ALT": feet_to_meter(20000),
"PATROL_ALT_RANGE": (feet_to_meter(15000), feet_to_meter(33000)),
"PATTERN_ALTITUDE": feet_to_meter(5000),
"CAP_PATTERN_LENGTH": (nm_to_meter(15), nm_to_meter(40)),
"FRONTLINE_CAP_DISTANCE_FROM_FRONTLINE": (nm_to_meter(6), nm_to_meter(15)),
"CAP_DISTANCE_FROM_CP": (nm_to_meter(10), nm_to_meter(40)),
"MAX_NUMBER_OF_INTERCEPTION_GROUP": 3,
}
COLDWAR_DOCTRINE = {
"GENERATORS": {
"CAS": True,
"CAP": True,
"SEAD": True,
"STRIKE": True,
"ANTISHIP": True,
},
"STRIKE_MAX_RANGE": 1500000,
"SEAD_MAX_RANGE": 1500000,
"CAP_EVERY_X_MINUTES": 20,
"CAS_EVERY_X_MINUTES": 30,
"SEAD_EVERY_X_MINUTES": 40,
"STRIKE_EVERY_X_MINUTES": 40,
"INGRESS_EGRESS_DISTANCE": nm_to_meter(30),
"INGRESS_ALT": feet_to_meter(18000),
"EGRESS_ALT": feet_to_meter(18000),
"PATROL_ALT_RANGE": (feet_to_meter(10000), feet_to_meter(24000)),
"PATTERN_ALTITUDE": feet_to_meter(5000),
"CAP_PATTERN_LENGTH": (nm_to_meter(12), nm_to_meter(24)),
"FRONTLINE_CAP_DISTANCE_FROM_FRONTLINE": (nm_to_meter(2), nm_to_meter(8)),
"CAP_DISTANCE_FROM_CP": (nm_to_meter(8), nm_to_meter(25)),
"MAX_NUMBER_OF_INTERCEPTION_GROUP": 3,
}
WWII_DOCTRINE = {
"GENERATORS": {
"CAS": True,
"CAP": True,
"SEAD": False,
"STRIKE": True,
"ANTISHIP": True,
},
"STRIKE_MAX_RANGE": 1500000,
"SEAD_MAX_RANGE": 1500000,
"CAP_EVERY_X_MINUTES": 20,
"CAS_EVERY_X_MINUTES": 30,
"SEAD_EVERY_X_MINUTES": 40,
"STRIKE_EVERY_X_MINUTES": 40,
"INGRESS_EGRESS_DISTANCE": nm_to_meter(7),
"INGRESS_ALT": feet_to_meter(8000),
"EGRESS_ALT": feet_to_meter(8000),
"PATROL_ALT_RANGE": (feet_to_meter(4000), feet_to_meter(15000)),
"PATTERN_ALTITUDE": feet_to_meter(5000),
"CAP_PATTERN_LENGTH": (nm_to_meter(8), nm_to_meter(18)),
"FRONTLINE_CAP_DISTANCE_FROM_FRONTLINE": (nm_to_meter(1), nm_to_meter(6)),
"CAP_DISTANCE_FROM_CP": (nm_to_meter(0), nm_to_meter(5)),
"MAX_NUMBER_OF_INTERCEPTION_GROUP": 3,
}

53
game/data/radar_db.py Normal file
View File

@@ -0,0 +1,53 @@
from dcs.vehicles import AirDefence
from dcs.ships import *
UNITS_WITH_RADAR = [
# Radars
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.AAA_Vulcan_M163,
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.EWR_1L13,
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_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_SR_P_19,
AirDefence.SAM_Roland_EWR,
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,
Oliver_Hazzard_Perry_class,
Ticonderoga_class,
FFL_1124_4_Grisha,
CV_1143_5_Admiral_Kuznetsov,
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,
USS_Arleigh_Burke_IIa,
LHA_1_Tarawa,
Type_052B_Destroyer,
Type_054A_Frigate,
Type_052C_Destroyer
]

View File

@@ -13,18 +13,29 @@ from dcs.unit import *
from dcs.unittype import *
from dcs.unitgroup import *
from game.factions.china_2000 import China_2000
from game.factions.australia_2005 import Australia_2005
from game.factions.bluefor_coldwar import BLUEFOR_COLDWAR
from game.factions.bluefor_coldwar_a4 import BLUEFOR_COLDWAR_A4
from game.factions.bluefor_coldwar_mods import BLUEFOR_COLDWAR_MODS
from game.factions.canada_2005 import Canada_2005
from game.factions.china_2010 import China_2010
from game.factions.france_1995 import France_1995
from game.factions.france_2005 import France_2005
from game.factions.france_modded import France_2005_Modded
from game.factions.germany_1944_easy import Germany_1944_Easy
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_2000 import Israel_2000
from game.factions.italy_1990 import Italy_1990
from game.factions.libya_2011 import Lybia_2011
from game.factions.italy_1990_mb339 import Italy_1990_MB339
from game.factions.japan_2005 import Japan_2005
from game.factions.libya_2011 import Libya_2011
from game.factions.netherlands_1990 import Netherlands_1990
from game.factions.north_korea_2000 import NorthKorea_2000
from game.factions.pakistan_2015 import Pakistan_2015
from game.factions.private_miltary_companies import PMC_WESTERN_B, PMC_RUSSIAN, PMC_WESTERN_A
from game.factions.russia_1975 import Russia_1975
from game.factions.germany_1944 import Germany_1944
from game.factions.india_2010 import India_2010
@@ -36,14 +47,64 @@ from game.factions.spain_1990 import Spain_1990
from game.factions.sweden_1990 import Sweden_1990
from game.factions.turkey_2005 import Turkey_2005
from game.factions.uae_2005 import UAE_2005
from game.factions.uk_1944 import UK_1944
from game.factions.uk_1990 import UnitedKingdom_1990
from game.factions.ukraine_2010 import Ukraine_2010
from game.factions.usa_1944 import USA_1944
from game.factions.us_aggressors import US_Aggressors
from game.factions.usa_1944 import USA_1944, ALLIES_1944
from game.factions.usa_1955 import USA_1955
from game.factions.usa_1960 import USA_1960
from game.factions.usa_1965 import USA_1965
from game.factions.usa_1990 import USA_1990
from game.factions.usa_2005 import USA_2005
from game.factions.bluefor_modern import BLUEFOR_MODERN
# PATCH pydcs data with MODS
from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.mb339.mb339 import MB_339PAN
import pydcs_extensions.frenchpack.frenchpack as frenchpack
from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M
plane_map["A-4E-C"] = A_4E_C
plane_map["MB-339PAN"] = MB_339PAN
plane_map["Rafale_M"] = Rafale_M
plane_map["Rafale_A_S"] = Rafale_A_S
vehicle_map["FieldHL"] = frenchpack._FIELD_HIDE
vehicle_map["HARRIERH"] = frenchpack._FIELD_HIDE_SMALL
vehicle_map["SMOKESAM"] = frenchpack.SMOKE_SAM_IR
vehicle_map["SmokeD1"] = frenchpack.SmokeD1
vehicle_map["SmokeD3"] = frenchpack.SmokeD3
vehicle_map["AMX10RCR"] = frenchpack.AMX_10RCR
vehicle_map["SEPAR"] = frenchpack.AMX_10RCR_SEPAR
vehicle_map["ERC"] = frenchpack.ERC_90
vehicle_map["M120"] = frenchpack.MO_120_RT
vehicle_map["AA20"] = frenchpack._53T2
vehicle_map["TRM2000"] = frenchpack.TRM_2000
vehicle_map["TRM2000_Citerne"] = frenchpack.TRM_2000_Fuel
vehicle_map["TRM2000_AA20"] = frenchpack.TRM_2000_53T2
vehicle_map["TRMMISTRAL"] = frenchpack.TRM_2000_PAMELA
vehicle_map["VABH"] = frenchpack.VAB_MEDICAL
vehicle_map["VAB_RADIO"] = frenchpack.VAB
vehicle_map["VAB_50"] = frenchpack.VAB__50
vehicle_map["VIB_VBR"] = frenchpack.VAB_T20_13
vehicle_map["VAB_HOT"] = frenchpack.VAB_MEPHISTO
vehicle_map["VAB_MORTIER"] = frenchpack.VAB_MORTIER
vehicle_map["VBL50"] = frenchpack.VBL__50
vehicle_map["VBLANF1"] = frenchpack.VBL_AANF1
vehicle_map["VBL-radio"] = frenchpack.VBL
vehicle_map["VBAE"] = frenchpack.VBAE_CRAB
vehicle_map["VBAE_MMP"] = frenchpack.VBAE_CRAB_MMP
vehicle_map["AMX-30B2"] = frenchpack.AMX_30B2
vehicle_map["Tracma"] = frenchpack.Tracma_TD_1500
vehicle_map["JTACFP"] = frenchpack.Infantry_Soldier_JTAC
vehicle_map["SHERIDAN"] = frenchpack.Char_M551_Sheridan
vehicle_map["Leclerc_XXI"] = frenchpack.Leclerc_Serie_XXI
vehicle_map["Toyota_bleu"] = frenchpack.DIM__TOYOTA_BLUE
vehicle_map["Toyota_vert"] = frenchpack.DIM__TOYOTA_GREEN
vehicle_map["Toyota_desert"] = frenchpack.DIM__TOYOTA_DESERT
vehicle_map["Kamikaze"] = frenchpack.DIM__KAMIKAZE
"""
---------- BEGINNING OF CONFIGURATION SECTION
@@ -83,11 +144,14 @@ PRICES = {
J_11A: 26,
JF_17: 20,
Su_30: 24,
SpitfireLFMkIX:3,
SpitfireLFMkIXCW:3,
Bf_109K_4:3,
FW_190D9:3,
FW_190A8:3,
SpitfireLFMkIX: 14,
SpitfireLFMkIXCW: 14,
Bf_109K_4: 14,
FW_190D9: 16,
FW_190A8: 14,
A_20G: 22,
Ju_88A4: 24,
F_5E_3: 8,
MiG_15bis: 4,
@@ -97,16 +161,19 @@ PRICES = {
F_4E: 10,
AJS37: 12,
C_101CC: 6,
A_4E_C: 8,
MB_339PAN: 6,
AV8BNA: 14,
M_2000C: 16,
Mirage_2000_5: 22,
FA_18C_hornet: 24,
F_15C: 26,
Mirage_2000_5: 20,
FA_18C_hornet: 22,
F_15C: 22,
F_15E: 24,
F_16C_50: 20,
F_14B: 22,
Tornado_IDS: 24,
Tornado_GR4: 24,
F_14B: 24,
Tornado_IDS: 20,
Tornado_GR4: 20,
# bomber
Su_17M4: 10,
@@ -125,17 +192,19 @@ PRICES = {
Ka_50: 13,
SA342M: 8,
SA342L: 5,
SA342Minigun: 4,
SA342Mistral: 8,
UH_1H: 4,
Mi_8MT: 5,
Mi_24V: 12,
Mi_28N: 16,
AH_1W: 10,
AH_64A: 12,
AH_64D: 16,
Mi_24V: 18,
Mi_28N: 24,
AH_1W: 20,
AH_64A: 24,
AH_64D: 30,
OH_58D: 6,
# Bombers
B_52H: 25,
B_52H: 35,
B_1B: 50,
# special
@@ -146,31 +215,38 @@ PRICES = {
S_3B_Tanker: 13,
IL_78M: 13,
KC_135: 13,
KC130: 13,
A_50: 8,
E_3A: 8,
C_130: 8,
# WW2
P_51D_30_NA: 3,
P_51D: 3,
P_51D_30_NA: 18,
P_51D: 16,
P_47D_30: 18,
B_17G: 30,
# Modded
Rafale_M: 26,
Rafale_A_S: 26,
# armor
Armor.APC_MTLB: 4,
Armor.ARV_MTLB_U_BOMAN: 5,
Armor.FDDM_Grad: 5,
Armor.ARV_BRDM_2: 6,
Armor.ARV_BTR_RD: 8,
Armor.APC_BTR_80: 8,
Armor.MBT_T_55: 18,
Armor.MBT_T_72B: 25,
Armor.MBT_T_80U: 30,
Armor.MBT_T_90: 35,
Armor.MBT_T_72B: 22,
Armor.MBT_T_80U: 25,
Armor.MBT_T_90: 30,
Armor.IFV_BMD_1: 8,
Armor.IFV_BMP_1: 14,
Armor.IFV_BMP_2: 16,
Armor.IFV_BMP_3: 18,
Armor.ZBD_04A: 12,
Armor.ZTZ_96B: 35,
Armor.ZTZ_96B: 30,
Armor.APC_Cobra: 4,
Armor.APC_M113: 6,
@@ -179,14 +255,14 @@ PRICES = {
Armor.IFV_M2A2_Bradley: 12,
Armor.APC_M1126_Stryker_ICV: 10,
Armor.ATGM_M1134_Stryker: 12,
Armor.MBT_M60A3_Patton: 18,
Armor.MBT_M1A2_Abrams: 35,
Armor.MBT_Leclerc: 35,
Armor.MBT_Leopard_1A3: 24,
Armor.MBT_Leopard_2: 35,
Armor.MBT_Merkava_Mk__4: 35,
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_Mk__4: 25,
Armor.TPz_Fuchs: 5,
Armor.MBT_Challenger_II: 30,
Armor.MBT_Challenger_II: 25,
Armor.IFV_Marder: 10,
Armor.IFV_MCV_80: 10,
Armor.IFV_LAV_25: 7,
@@ -199,7 +275,7 @@ PRICES = {
Artillery.SPH_2S3_Akatsia: 24,
Artillery.SPH_2S19_Msta: 30,
Artillery.MLRS_BM_21_Grad: 15,
Artillery.MLRS_9K57_Uragan_BM_27: 40,
Artillery.MLRS_9K57_Uragan_BM_27: 50,
Artillery.MLRS_9A52_Smerch: 40,
Unarmed.Transport_UAZ_469: 3,
@@ -227,22 +303,30 @@ PRICES = {
AirDefence.SAM_Chaparral_M48: 10,
# WW2
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G:7,
Armor.MT_Pz_Kpfw_IV_Ausf_H:4,
Armor.HT_Pz_Kpfw_VI_Tiger_I:10,
Armor.HT_Pz_Kpfw_VI_Ausf__B__Tiger_II:12,
Armor.APC_Sd_Kfz_251:3,
Armor.IFV_Sd_Kfz_234_2_Puma:4,
Armor.MT_M4_Sherman:4,
Armor.MT_M4A4_Sherman_Firefly:6,
Armor.CT_Cromwell_IV:8,
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G:24,
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.TD_Jagdpanther_G1: 18,
Armor.TD_Jagdpanzer_IV: 11,
Armor.Sd_Kfz_184_Elefant: 18,
Armor.APC_Sd_Kfz_251:4,
Armor.IFV_Sd_Kfz_234_2_Puma:8,
Armor.MT_M4_Sherman:12,
Armor.MT_M4A4_Sherman_Firefly:16,
Armor.CT_Cromwell_IV:12,
Armor.M30_Cargo_Carrier:2,
Armor.APC_M2A1:2,
AirDefence.AAA_Bofors_40mm:4,
AirDefence.AAA_Flak_36:6,
AirDefence.AAA_Flak_18:4,
Artillery.M12_GMC:2,
Artillery.Sturmpanzer_IV_Brummbär:2,
Armor.APC_M2A1:4,
Armor.ST_Centaur_IV: 10,
Armor.HIT_Churchill_VII: 16,
Armor.LAC_M8_Greyhound: 8,
Armor.TD_M10_GMC: 14,
Armor.StuG_III_Ausf__G: 12,
AirDefence.AAA_Bofors_40mm: 8,
AirDefence.AAA_8_8cm_Flak_36: 8,
AirDefence.AAA_8_8cm_Flak_18: 12,
Artillery.M12_GMC: 10,
Artillery.Sturmpanzer_IV_Brummbär: 10,
# ship
CV_1143_5_Admiral_Kuznetsov: 100,
@@ -253,6 +337,38 @@ PRICES = {
Armed_speedboat: 10,
Dry_cargo_ship_Ivanov: 10,
Tanker_Elnya_160: 10,
# FRENCH PACK MOD
frenchpack.AMX_10RCR: 10,
frenchpack.AMX_10RCR_SEPAR: 12,
frenchpack.ERC_90: 12,
frenchpack.MO_120_RT: 10,
frenchpack._53T2: 4,
frenchpack.TRM_2000: 4,
frenchpack.TRM_2000_Fuel: 4,
frenchpack.TRM_2000_53T2: 8,
frenchpack.TRM_2000_PAMELA: 14,
frenchpack.VAB_MEDICAL: 8,
frenchpack.VAB: 6,
frenchpack.VAB__50: 4,
frenchpack.VAB_T20_13: 6,
frenchpack.VAB_MEPHISTO: 8,
frenchpack.VAB_MORTIER: 10,
frenchpack.VBL__50: 4,
frenchpack.VBL_AANF1: 2,
frenchpack.VBL: 1,
frenchpack.VBAE_CRAB: 8,
frenchpack.VBAE_CRAB_MMP: 12,
frenchpack.AMX_30B2: 18,
frenchpack.Tracma_TD_1500: 2,
frenchpack.Infantry_Soldier_JTAC: 1,
frenchpack.Leclerc_Serie_XXI: 35,
frenchpack.DIM__TOYOTA_BLUE: 2,
frenchpack.DIM__TOYOTA_GREEN: 2,
frenchpack.DIM__TOYOTA_DESERT: 2,
frenchpack.DIM__KAMIKAZE: 6,
}
"""
@@ -281,6 +397,7 @@ UNIT_BY_TASK = {
MiG_21Bis,
MiG_29A,
MiG_29S,
MiG_31,
FA_18C_hornet,
F_15C,
F_14B,
@@ -299,9 +416,13 @@ UNIT_BY_TASK = {
FW_190D9,
FW_190A8,
SpitfireLFMkIXCW,
SpitfireLFMkIX
SpitfireLFMkIX,
A_4E_C,
Rafale_M,
SA342Mistral
],
CAS: [
F_15E,
F_86F_Sabre,
MiG_15bis,
L_39ZA,
@@ -316,6 +437,7 @@ UNIT_BY_TASK = {
Ka_50,
SA342M,
SA342L,
SA342Minigun,
Su_24M,
Su_24MR,
AH_64A,
@@ -330,6 +452,12 @@ UNIT_BY_TASK = {
Mi_28N,
Mi_24V,
MiG_27K,
A_20G,
P_47D_30,
Ju_88A4,
B_17G,
MB_339PAN,
Rafale_A_S
],
Transport: [
IL_76MD,
@@ -342,6 +470,7 @@ UNIT_BY_TASK = {
Refueling: [
IL_78M,
KC_135,
KC130,
S_3B_Tanker,
],
AWACS: [E_3A, A_50, ],
@@ -351,11 +480,11 @@ UNIT_BY_TASK = {
Armor.APC_MTLB,
Armor.APC_MTLB,
Armor.APC_MTLB,
Armor.ARV_MTLB_U_BOMAN,
Armor.ARV_MTLB_U_BOMAN,
Armor.ARV_MTLB_U_BOMAN,
Armor.ARV_MTLB_U_BOMAN,
Armor.ARV_MTLB_U_BOMAN,
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,
@@ -450,6 +579,33 @@ UNIT_BY_TASK = {
Armor.APC_M2A1,
Armor.APC_M2A1,
Armor.APC_M2A1,
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
Armor.HT_Pz_Kpfw_VI_Tiger_I,
Armor.HT_Pz_Kpfw_VI_Ausf__B__Tiger_II,
Armor.TD_Jagdpanther_G1,
Armor.TD_Jagdpanzer_IV,
Armor.Sd_Kfz_184_Elefant,
Armor.APC_Sd_Kfz_251,
Armor.IFV_Sd_Kfz_234_2_Puma,
Armor.MT_M4_Sherman,
Armor.MT_M4A4_Sherman_Firefly,
Armor.CT_Cromwell_IV,
Armor.M30_Cargo_Carrier,
Armor.M30_Cargo_Carrier,
Armor.M30_Cargo_Carrier,
Armor.APC_M2A1,
Armor.APC_M2A1,
Armor.ST_Centaur_IV,
Armor.ST_Centaur_IV,
Armor.HIT_Churchill_VII,
Armor.LAC_M8_Greyhound,
Armor.LAC_M8_Greyhound,
Armor.TD_M10_GMC,
Armor.TD_M10_GMC,
Armor.StuG_III_Ausf__G,
Artillery.M12_GMC,
Artillery.Sturmpanzer_IV_Brummbär,
Artillery.MLRS_M270,
Artillery.SPH_M109_Paladin,
@@ -464,6 +620,29 @@ UNIT_BY_TASK = {
Artillery.M12_GMC,
Artillery.Sturmpanzer_IV_Brummbär,
frenchpack.DIM__TOYOTA_BLUE,
frenchpack.DIM__TOYOTA_DESERT,
frenchpack.DIM__TOYOTA_GREEN,
frenchpack.DIM__KAMIKAZE,
frenchpack.AMX_10RCR,
frenchpack.AMX_10RCR_SEPAR,
frenchpack.ERC_90,
frenchpack.TRM_2000_PAMELA,
frenchpack.VAB__50,
frenchpack.VAB_MEPHISTO,
frenchpack.VAB_T20_13,
frenchpack.VBL__50,
frenchpack.VBL_AANF1,
frenchpack.VBAE_CRAB,
frenchpack.VBAE_CRAB_MMP,
frenchpack.AMX_30B2,
frenchpack.Leclerc_Serie_XXI,
frenchpack.DIM__TOYOTA_BLUE,
frenchpack.DIM__TOYOTA_GREEN,
frenchpack.DIM__TOYOTA_DESERT,
frenchpack.DIM__KAMIKAZE,
],
AirDefence: [
@@ -534,6 +713,7 @@ SAM_CONVERT = {
}
}
"""
Units that will always be spawned in the air
"""
@@ -548,45 +728,87 @@ CARRIER_TAKEOFF_BAN = [
]
"""
Units separated by country. Currently only Russia and USA are supported.
Units separated by country.
country : DCS Country name
"""
FACTIONS = {
"Bluefor Modern": BLUEFOR_MODERN,
"Bluefor Cold War 1970s": BLUEFOR_COLDWAR,
"Bluefor Cold War (with A-4)": BLUEFOR_COLDWAR_A4,
"Bluefor Cold War (with A-4 and MB339)": BLUEFOR_COLDWAR_MODS,
"USA 1955 (WW2 Pack)": USA_1955,
"USA 1960": USA_1960,
"USA 1965": USA_1965,
"USA 1990": USA_1990,
"USA 2005": USA_2005,
"USA Aggressors 2005": US_Aggressors,
"Russia 1955": Russia_1955,
"Russia 1965": Russia_1965,
"Russia 1975": Russia_1975,
"Russia 1990": Russia_1990,
"Russia 2010": Russia_2010,
"Iran 2015": Iran_2015,
"Lybia 2011": Lybia_2011,
"China 2000": China_2000,
"North Korea 2000": NorthKorea_2000,
"Insurgent": Insurgent,
"USA 2005": USA_2005,
"USA 1990": USA_1990,
"USA 1965": USA_1965,
"USA 1960": USA_1960,
"USA 1955 (Require WW2 Pack)": USA_1955,
"USA 1944 (Require WW2 Pack)": USA_1944,
"France 1995": France_1995,
"France 2005": France_2005,
"France 2005 (Modded)": France_2005_Modded,
"Germany 1990": Germany_1990,
"Netherlands 1990": Netherlands_1990,
"United Kingdown 1990": UnitedKingdom_1990,
"United Kingdom 1990": UnitedKingdom_1990,
"Spain 1990": Spain_1990,
"Italy 1990": Italy_1990,
"Sweden 1990": Sweden_1990,
"Ukraine 2010": Ukraine_2010,
"India 2010": India_2010,
"Pakistan 2015": Pakistan_2015,
"Italy 1990 (With MB339)": Italy_1990_MB339,
"Israel 2000": Israel_2000,
"China 2010": China_2010,
"Sweden 1990": Sweden_1990,
"Australia 2005": Australia_2005,
"Canada 2005": Canada_2005,
"Japan 2005": Japan_2005,
"Turkey 2005": Turkey_2005,
"United Arab Emirates 2005": UAE_2005,
"Germany 1944 (Require WW2 Pack)": Germany_1944
"Ukraine 2010": Ukraine_2010,
"India 2010": India_2010,
"Libya 2011": Libya_2011,
"Pakistan 2015": Pakistan_2015,
"Iran 2015": Iran_2015,
"North Korea 2000": NorthKorea_2000,
"Insurgent": Insurgent,
"Insurgent (Modded)": Insurgent_modded,
"PMC (American)": PMC_WESTERN_A,
"PMC (American) - MB339": PMC_WESTERN_B,
"PMC (Russian)": PMC_RUSSIAN,
"Allies 1944 (WW2 Pack)": USA_1944,
"USA 1944 (WW2 Pack)": ALLIES_1944,
"UK 1944 (WW2 Pack)": UK_1944,
"Germany 1944 (WW2 Pack)": Germany_1944,
"Germany 1944 Easy (WW2 Pack)": Germany_1944_Easy,
}
BLUEFOR_FACTIONS = [FACTIONS[f]["country"] for f in FACTIONS if FACTIONS[f]["side"] == "blue"]
print(BLUEFOR_FACTIONS)
CARRIER_TYPE_BY_PLANE = {
@@ -637,7 +859,15 @@ PLANE_PAYLOAD_OVERRIDES = {
AntishipStrike: "ANTISHIP",
GroundAttack: "STRIKE"
},
F_A_18C: {
CAP: "CAP HEAVY",
Intercept: "CAP HEAVY",
CAS: "CAS MAVERICK F",
PinpointStrike: "STRIKE",
SEAD: "SEAD",
AntishipStrike: "ANTISHIP",
GroundAttack: "STRIKE"
},
A_10A: COMMON_OVERRIDE,
A_10C: COMMON_OVERRIDE,
AV8BNA: COMMON_OVERRIDE,
@@ -645,6 +875,7 @@ PLANE_PAYLOAD_OVERRIDES = {
F_5E_3: COMMON_OVERRIDE,
F_14B: COMMON_OVERRIDE,
F_15C: COMMON_OVERRIDE,
F_15E: COMMON_OVERRIDE,
F_16C_50: COMMON_OVERRIDE,
JF_17: COMMON_OVERRIDE,
M_2000C: COMMON_OVERRIDE,
@@ -672,11 +903,28 @@ PLANE_PAYLOAD_OVERRIDES = {
SA342L:COMMON_OVERRIDE,
SA342Mistral:COMMON_OVERRIDE,
Mi_8MT:COMMON_OVERRIDE,
Mi_24V:COMMON_OVERRIDE,
Mi_28N:COMMON_OVERRIDE,
Ka_50:COMMON_OVERRIDE,
L_39ZA:COMMON_OVERRIDE,
L_39C:COMMON_OVERRIDE,
Su_17M4: COMMON_OVERRIDE,
F_4E: COMMON_OVERRIDE,
P_47D_30:COMMON_OVERRIDE,
B_17G: COMMON_OVERRIDE,
P_51D: COMMON_OVERRIDE,
P_51D_30_NA: COMMON_OVERRIDE,
FW_190D9: COMMON_OVERRIDE,
FW_190A8: COMMON_OVERRIDE,
Bf_109K_4: COMMON_OVERRIDE,
SpitfireLFMkIXCW: COMMON_OVERRIDE,
SpitfireLFMkIX: COMMON_OVERRIDE,
A_20G: COMMON_OVERRIDE,
A_4E_C: COMMON_OVERRIDE,
MB_339PAN: COMMON_OVERRIDE,
Rafale_M: COMMON_OVERRIDE,
Rafale_A_S: COMMON_OVERRIDE,
OH_58D: COMMON_OVERRIDE,
AH_64D:{
CAS: "AGM-114K*16"
@@ -700,8 +948,6 @@ PLANE_LIVERY_OVERRIDES = {
FA_18C_hornet: "VFA-34", # default livery for the hornet is blue angels one
}
"""
Possible time periods for new games
@@ -741,7 +987,8 @@ TIME_PERIODS = {
REWARDS = {
"power": 4, "warehouse": 2, "fuel": 2, "ammo": 2,
"farp": 1, "fob": 1, "factory": 10, "comms": 10, "oil": 10
"farp": 1, "fob": 1, "factory": 10, "comms": 10, "oil": 10,
"derrick": 8
}
# Base post-turn bonus value
@@ -752,12 +999,14 @@ CARRIER_CAPABLE = [
F_14B,
AV8BNA,
Su_33,
A_4E_C,
UH_1H,
Mi_8MT,
Ka_50,
AH_1W,
OH_58D,
UH_60A,
SA342L,
SA342M,
@@ -773,6 +1022,7 @@ LHA_CAPABLE = [
Ka_50,
AH_1W,
OH_58D,
UH_60A,
SA342L,
SA342M,
@@ -797,6 +1047,21 @@ TaskForceDict = typing.Dict[typing.Type[Task], AssignedUnitsDict]
StartingPosition = typing.Optional[typing.Union[ShipGroup, StaticGroup, Airport, Point]]
def upgrade_to_supercarrier(unit, name: str):
if unit == CVN_74_John_C__Stennis:
if name == "CVN-71 Theodore Roosevelt":
return CVN_71_Theodore_Roosevelt
elif name == "CVN-72 Abraham Lincoln":
return CVN_72_Abraham_Lincoln
elif name == "CVN-73 George Washington":
return CVN_73_George_Washington
else:
return CVN_71_Theodore_Roosevelt
elif unit == CV_1143_5_Admiral_Kuznetsov:
return CV_1143_5_Admiral_Kuznetsov_2017
else:
return unit
def unit_task(unit: UnitType) -> Task:
for task, units in UNIT_BY_TASK.items():
if unit in units:
@@ -831,6 +1096,8 @@ def find_infantry(country_name: str) -> typing.List[UnitType]:
def unit_type_name(unit_type) -> str:
return unit_type.id and unit_type.id or unit_type.name
def unit_type_name_2(unit_type) -> str:
return unit_type.name and unit_type.name or unit_type.id
def unit_type_from_name(name: str) -> UnitType:
if name in vehicle_map:
@@ -962,14 +1229,6 @@ def _validate_db():
assert unit_type not in total_set, "{} is duplicate for task {}".format(unit_type, t)
total_set.add(unit_type)
# check country allegiance
for unit_type in total_set:
did_find = False
for country_units_list in FACTIONS.values():
if unit_type in country_units_list["units"]:
did_find = True
print("WARN : {} not in country list".format(unit_type))
# check prices
for unit_type in total_set:
assert unit_type in PRICES, "{} not in prices".format(unit_type)
@@ -982,4 +1241,6 @@ class DefaultLiveries:
OH_58D.Liveries = DefaultLiveries
F_16C_50.Liveries = DefaultLiveries
P_51D_30_NA.Liveries = DefaultLiveries
P_51D_30_NA.Liveries = DefaultLiveries
Ju_88A4.Liveries = DefaultLiveries
B_17G.Liveries = DefaultLiveries

View File

@@ -13,6 +13,7 @@ from theater import *
from gen.environmentgen import EnvironmentSettings
from gen.conflictgen import Conflict
from game.db import assigned_units_from, unitdict_from
from theater.start_generator import generate_airbase_defense_group
from userdata.debriefing import Debriefing
from userdata import persistency
@@ -64,25 +65,10 @@ class Event:
else:
return self.departure_cp
@property
def threat_description(self) -> str:
return ""
def flight_name(self, for_task: typing.Type[typing.Type[Task]]) -> str:
return "Flight"
@property
def tasks(self) -> typing.Collection[typing.Type[Task]]:
return []
@property
def ai_banned_tasks(self) -> typing.Collection[typing.Type[Task]]:
return []
@property
def player_banned_tasks(self) -> typing.Collection[typing.Type[Task]]:
return []
@property
def global_cp_available(self) -> bool:
return False
@@ -126,17 +112,6 @@ class Event:
self.operation.current_mission.save(persistency.mission_path_for("liberation_nextturn.miz"))
self.environment_settings = self.operation.environment_settings
def generate_quick(self):
pass
# TODO : This is not needed anymore. The player can start mission in flight from the flight planner if he want it to be quick.
# TODO : remove this method
#self.operation.is_awacs_enabled = self.is_awacs_enabled
#self.operation.environment_settings = self.environment_settings
#
#self.operation.prepare(self.game.theater.terrain, is_quick=True)
#self.operation.generate()
#self.operation.current_mission.save(persistency.mission_path_for("liberation_nextturn_quick.miz"))
def commit(self, debriefing: Debriefing):
logging.info("Commiting mission results")
@@ -189,56 +164,85 @@ class Event:
logging.info("cp {} killing ground object {}".format(cp, ground_object.string_identifier))
cp.ground_objects[i].is_dead = True
info = Information("Building destroyed",
ground_object.dcs_identifier + " has been destroyed at location " + ground_object.obj_name,
self.game.turn)
self.game.informations.append(info)
# -- AA Site groups
destroyed_units = 0
info = Information("Units destroyed at " + ground_object.obj_name,
"",
self.game.turn)
for i, ground_object in enumerate(cp.ground_objects):
if ground_object.dcs_identifier in ["AA", "CARRIER", "LHA"]:
for g in ground_object.groups:
for u in g.units:
if u.name == destroyed_ground_unit_name:
g.units.remove(u)
destroyed_units = destroyed_units + 1
info.text = u.type
ucount = sum([len(g.units) for g in ground_object.groups])
if ucount == 0:
ground_object.is_dead = True
if destroyed_units > 0:
self.game.informations.append(info)
# ------------------------------
# Captured bases
if self.game.player_country in db.BLUEFOR_FACTIONS:
coalition = 2 # Value in DCS mission event for BLUE
else:
coalition = 1 # Value in DCS mission event for RED
#if self.game.player_country in db.BLUEFOR_FACTIONS:
coalition = 2 # Value in DCS mission event for BLUE
#else:
# coalition = 1 # Value in DCS mission event for RED
for captured in debriefing.base_capture_events:
try:
id = int(captured.split("||")[0])
new_owner_coalition = int(captured.split("||")[1])
captured_cps = []
for cp in self.game.theater.controlpoints:
if cp.id == id:
if cp.captured and new_owner_coalition != coalition:
cp.captured = False
cp.base.aircraft = {}
cp.base.armor = {}
cp.base.aa = {}
for g in cp.ground_objects:
g.groups = []
info = Information(cp.name + " lost !",
"The ennemy took control of " + cp.name + "\nShame on us !",
self.game.turn)
info = Information(cp.name + " lost !", "The ennemy took control of " + cp.name + "\nShame on us !", self.game.turn)
self.game.informations.append(info)
pname = self.game.enemy_name
captured_cps.append(cp)
elif not(cp.captured) and new_owner_coalition == coalition:
cp.captured = True
cp.base.aircraft = {}
cp.base.armor = {}
cp.base.aa = {}
for g in cp.ground_objects:
g.groups = []
info = Information(cp.name + " captured !",
"The ennemy took control of " + cp.name + "\nShame on us !",
self.game.turn)
info = Information(cp.name + " captured !", "We took control of " + cp.name + "! Great job !", self.game.turn)
self.game.informations.append(info)
pname = self.game.player_name
captured_cps.append(cp)
else:
continue
cp.base.aircraft = {}
cp.base.armor = {}
airbase_def_id = 0
for g in cp.ground_objects:
g.groups = []
if g.airbase_group and pname != "":
generate_airbase_defense_group(airbase_def_id, g, pname, self.game, cp)
airbase_def_id = airbase_def_id + 1
for cp in captured_cps:
logging.info("Will run redeploy for " + cp.name)
self.redeploy_units(cp)
except Exception as e:
print(e)
# Destroyed units carcass
# -------------------------
for destroyed_unit in debriefing.destroyed_units:
self.game.add_destroyed_units(destroyed_unit)
# -----------------------------------
# Compute damage to bases
for cp in self.game.theater.player_points():
@@ -260,6 +264,8 @@ class Event:
ratio = (1.0 + enemy_casualties) / (1.0 + ally_casualties)
player_aggresive = cp.stances[enemy_cp.id] in [CombatStance.AGGRESIVE, CombatStance.ELIMINATION, CombatStance.BREAKTHROUGH]
if ally_units_alive == 0:
player_won = False
delta = STRONG_DEFEAT_INFLUENCE
@@ -282,11 +288,21 @@ class Event:
else:
delta = DEFEAT_INFLUENCE
elif ally_casualties > enemy_casualties:
player_won = False
if cp.stances[enemy_cp.id] == CombatStance.BREAKTHROUGH:
if ally_units_alive > 2*enemy_units_alive and player_aggresive:
# Even with casualties if the enemy is overwhelmed, they are going to lose ground
player_won = True
delta = MINOR_DEFEAT_INFLUENCE
elif ally_units_alive > 3*enemy_units_alive and player_aggresive:
player_won = True
delta = STRONG_DEFEAT_INFLUENCE
else:
delta = STRONG_DEFEAT_INFLUENCE
# But is the enemy is not outnumbered, we lose
player_won = False
if cp.stances[enemy_cp.id] == CombatStance.BREAKTHROUGH:
delta = STRONG_DEFEAT_INFLUENCE
else:
delta = STRONG_DEFEAT_INFLUENCE
# No progress with defensive strategies
if player_won and cp.stances[enemy_cp.id] in [CombatStance.DEFENSIVE, CombatStance.AMBUSH]:
@@ -306,13 +322,54 @@ class Event:
enemy_cp.base.affect_strength(delta)
cp.base.affect_strength(-delta)
info = Information("Frontline Report",
"Our ground forces from " + cp.name + " are losing ground against the enemy forces from" + enemy_cp.name,
"Our ground forces from " + cp.name + " are losing ground against the enemy forces from " + enemy_cp.name,
self.game.turn)
self.game.informations.append(info)
def skip(self):
pass
def redeploy_units(self, cp):
""""
Auto redeploy units to newly captured base
"""
ally_connected_cps = [ocp for ocp in cp.connected_points if cp.captured == ocp.captured]
enemy_connected_cps = [ocp for ocp in cp.connected_points if cp.captured != ocp.captured]
# If the newly captured cp does not have enemy connected cp,
# then it is not necessary to redeploy frontline units there.
if len(enemy_connected_cps) == 0:
return
else:
# From each ally cp, send reinforcements
for ally_cp in ally_connected_cps:
total_units_redeployed = 0
own_enemy_cp = [ocp for ocp in ally_cp.connected_points if ally_cp.captured != ocp.captured]
moved_units = {}
# If the connected base, does not have any more enemy cp connected.
# Or if it is not the opponent redeploying forces there (enemy AI will never redeploy all their forces at once)
if len(own_enemy_cp) > 0 or not cp.captured:
for frontline_unit, count in ally_cp.base.armor.items():
moved_units[frontline_unit] = int(count/2)
total_units_redeployed = total_units_redeployed + int(count/2)
else: # So if the old base, does not have any more enemy cp connected, or if it is an enemy base
for frontline_unit, count in ally_cp.base.armor.items():
moved_units[frontline_unit] = count
total_units_redeployed = total_units_redeployed + count
cp.base.commision_units(moved_units)
ally_cp.base.commit_losses(moved_units)
if total_units_redeployed > 0:
info = Information("Units redeployed", "", self.game.turn)
info.text = str(total_units_redeployed) + " units have been redeployed from " + ally_cp.name + " to " + cp.name
self.game.informations.append(info)
logging.info(info.text)
class UnitsDeliveryEvent(Event):
informational = True

View File

@@ -4,16 +4,6 @@ from userdata.debriefing import Debriefing
class FrontlineAttackEvent(Event):
TARGET_VARIETY = 2
TARGET_AMOUNT_FACTOR = 0.5
ATTACKER_AMOUNT_FACTOR = 0.4
ATTACKER_DEFENDER_FACTOR = 0.7
STRENGTH_INFLUENCE = 0.3
SUCCESS_FACTOR = 1.5
@property
def threat_description(self):
return "{} vehicles".format(self.to_cp.base.assemble_count())
@property
def tasks(self) -> typing.Collection[typing.Type[Task]]:
@@ -26,32 +16,11 @@ class FrontlineAttackEvent(Event):
def global_cp_available(self) -> bool:
return True
def flight_name(self, for_task: typing.Type[Task]) -> str:
if for_task == CAS:
return "CAS flight"
elif for_task == CAP:
return "CAP flight"
elif for_task == PinpointStrike:
return "Ground attack"
def __str__(self):
return "Frontline attack"
def is_successfull(self, debriefing: Debriefing):
if self.game.player_name == self.attacker_name:
attacker_country = self.game.player_country
defender_country = self.game.enemy_country
else:
attacker_country = self.game.enemy_country
defender_country = self.game.player_country
# TODO : Rework
#alive_attackers = sum([v for k, v in debriefing.alive_units.get(attacker_country, {}).items() if db.unit_task(k) == PinpointStrike])
#alive_defenders = sum([v for k, v in debriefing.alive_units.get(defender_country, {}).items() if db.unit_task(k) == PinpointStrike])
#attackers_success = (float(alive_attackers) / (alive_defenders + 0.01)) > self.SUCCESS_FACTOR
attackers_success = True
if self.from_cp.captured:
return attackers_success
else:
@@ -65,46 +34,20 @@ class FrontlineAttackEvent(Event):
self.to_cp.base.affect_strength(-0.1)
def player_attacking(self, flights: db.TaskForceDict):
# assert CAS in flights and CAP in flights and len(flights) == 2, "Invalid flights"
op = FrontlineAttackOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
from_cp=self.from_cp,
departure_cp=self.departure_cp,
to_cp=self.to_cp)
defenders = self.to_cp.base.assemble_attack()
max_attackers = int(math.ceil(sum(defenders.values()) * self.ATTACKER_DEFENDER_FACTOR))
attackers = db.unitdict_restrict_count(self.from_cp.base.assemble_attack(), max_attackers)
op.setup(defenders=defenders,
attackers=attackers,
strikegroup=flights[CAS],
escort=flights[CAP],
interceptors=assigned_units_from(self.to_cp.base.scramble_interceptors(1)))
self.operation = op
def player_defending(self, flights: db.TaskForceDict):
# assert CAP in flights and len(flights) == 1, "Invalid flights"
op = FrontlineAttackOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
from_cp=self.from_cp,
departure_cp=self.departure_cp,
to_cp=self.to_cp)
defenders = self.to_cp.base.assemble_attack()
max_attackers = int(math.ceil(sum(defenders.values())))
attackers = db.unitdict_restrict_count(self.from_cp.base.assemble_attack(), max_attackers)
op.setup(defenders=defenders,
attackers=attackers,
strikegroup=assigned_units_from(self.from_cp.base.scramble_cas(1)),
escort=assigned_units_from(self.from_cp.base.scramble_sweep(1)),
interceptors=flights[CAP])
self.operation = op

View File

@@ -0,0 +1,50 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Australia_2005 = {
"country": "Australia",
"side": "blue",
"units": [
FA_18C_hornet,
KC_135,
KC130,
C_130,
E_3A,
Armor.MBT_M1A2_Abrams,
Armor.MBT_Leopard_1A3,
Armor.APC_M113,
Armor.IFV_LAV_25,
Armor.IFV_MCV_80,
UH_1H,
AH_1W, # Standing as EC Tiger
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
AirDefence.Rapier_FSA_Launcher,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad": [
AirDefence.Rapier_FSA_Launcher,
], "helicopter_carrier": [
LHA_1_Tarawa,
], "destroyer": [
USS_Arleigh_Burke_IIa,
], "cruiser": [
Ticonderoga_class,
], "lhanames": [
"HMAS Canberra",
"HMAS Adelaide"
], "boat":[
"ArleighBurkeGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,58 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
BLUEFOR_COLDWAR = {
"country": "USA",
"side": "blue",
"units": [
F_14B,
F_4E,
F_5E_3,
A_10A,
AJS37,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
SA342M,
SA342L,
Armor.MBT_M60A3_Patton,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Chaparral_M48,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad": [
AirDefence.AAA_Vulcan_M163,
], "aircraft_carrier": [
CVN_74_John_C__Stennis,
], "helicopter_carrier": [
LHA_1_Tarawa,
], "carrier_names": [
"CVN-71 Theodore Roosevelt",
"CVN-72 Abraham Lincoln",
"CVN-73 George Washington",
"CVN-74 John C. Stennis",
], "lhanames": [
"LHA-1 Tarawa",
"LHA-2 Saipan",
"LHA-3 Belleau Wood",
"LHA-4 Nassau",
"LHA-5 Peleliu"
], "boat": [
], "has_jtac": True
}

View File

@@ -0,0 +1,65 @@
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
BLUEFOR_COLDWAR_A4 = {
"country": "USA",
"side": "blue",
"units": [
F_14B,
F_4E,
F_5E_3,
A_10A,
AJS37,
A_4E_C,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
SA342M,
SA342L,
Armor.MBT_M60A3_Patton,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Chaparral_M48,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad": [
AirDefence.AAA_Vulcan_M163,
], "aircraft_carrier": [
CVN_74_John_C__Stennis,
], "helicopter_carrier": [
LHA_1_Tarawa,
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
"CVN-71 Theodore Roosevelt",
"CVN-72 Abraham Lincoln",
"CVN-73 George Washington",
"CVN-74 John C. Stennis",
], "lhanames": [
"LHA-1 Tarawa",
"LHA-2 Saipan",
"LHA-3 Belleau Wood",
"LHA-4 Nassau",
"LHA-5 Peleliu"
], "boat": [
], "requirements": {
"Community A-4E": "https://heclak.github.io/community-a4e-c/",
}, "has_jtac": True
}

View File

@@ -0,0 +1,68 @@
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
from pydcs_extensions.mb339.mb339 import MB_339PAN
BLUEFOR_COLDWAR_MODS = {
"country": "USA",
"side": "blue",
"units": [
F_14B,
F_4E,
F_5E_3,
A_10A,
AJS37,
A_4E_C,
MB_339PAN,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
SA342M,
SA342L,
Armor.MBT_M60A3_Patton,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Chaparral_M48,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad": [
AirDefence.AAA_Vulcan_M163,
], "aircraft_carrier": [
CVN_74_John_C__Stennis,
], "helicopter_carrier": [
LHA_1_Tarawa,
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
"CVN-71 Theodore Roosevelt",
"CVN-72 Abraham Lincoln",
"CVN-73 George Washington",
"CVN-74 John C. Stennis",
], "lhanames": [
"LHA-1 Tarawa",
"LHA-2 Saipan",
"LHA-3 Belleau Wood",
"LHA-4 Nassau",
"LHA-5 Peleliu"
], "boat": [
], "requirements": {
"MB-339A": "http://www.freccetricolorivirtuali.net/",
"Community A-4E": "https://heclak.github.io/community-a4e-c/",
}, "has_jtac": True
}

View File

@@ -0,0 +1,82 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
BLUEFOR_MODERN = {
"country": "USA",
"side": "blue",
"units": [
F_15C,
F_14B,
FA_18C_hornet,
F_16C_50,
JF_17,
M_2000C,
F_5E_3,
Su_27,
Su_25T,
A_10A,
A_10C,
AV8BNA,
AJS37,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
AH_64D,
Ka_50,
SA342M,
SA342L,
Armor.MBT_M1A2_Abrams,
Armor.MBT_Leopard_2,
Armor.ATGM_M1134_Stryker,
Armor.IFV_M2A2_Bradley,
Armor.IFV_Marder,
Armor.APC_M1043_HMMWV_Armament,
Artillery.MLRS_M270,
Artillery.SPH_M109_Paladin,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Patriot_EPP_III,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad": [
AirDefence.SAM_Avenger_M1097,
], "aircraft_carrier": [
CVN_74_John_C__Stennis,
], "helicopter_carrier": [
LHA_1_Tarawa,
], "destroyer": [
Oliver_Hazzard_Perry_class,
USS_Arleigh_Burke_IIa,
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
"CVN-71 Theodore Roosevelt",
"CVN-72 Abraham Lincoln",
"CVN-73 George Washington",
"CVN-74 John C. Stennis",
], "lhanames": [
"LHA-1 Tarawa",
"LHA-2 Saipan",
"LHA-3 Belleau Wood",
"LHA-4 Nassau",
"LHA-5 Peleliu"
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,43 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Canada_2005 = {
"country": "Canada",
"side": "blue",
"units": [
FA_18C_hornet,
KC_135,
KC130,
C_130,
E_3A,
Armor.MBT_Leopard_1A3,
Armor.MBT_Leopard_2,
Armor.IFV_LAV_25,
Armor.APC_M113,
Armor.IFV_MCV_80,
UH_1H,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Avenger_M1097,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad": [
AirDefence.SAM_Avenger_M1097,
], "destroyer": [
USS_Arleigh_Burke_IIa,
], "cruiser": [
Ticonderoga_class,
], "boat":[
"ArleighBurkeGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,9 +1,9 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
China_2000 = {
China_2010 = {
"country": "China",
"side": "red",
"units": [
@@ -37,7 +37,9 @@ China_2000 = {
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Soldier_AK,
Infantry.Paratrooper_AKS,
Infantry.Infantry_Soldier_Rus,
Infantry.Paratrooper_RPG_16,
CV_1143_5_Admiral_Kuznetsov,
@@ -56,8 +58,20 @@ China_2000 = {
Type_052C_Destroyer
], "cruiser": [
Type_054A_Frigate,
], "helicopter_carrier": [
Type_071_Amphibious_Transport_Dock,
], "lhanames": [
"Kunlun Shan",
"Jinggang Shan",
"Changbai Shan",
"Yimeng Shan",
"Longhu Shan",
"Wuzhi Shan",
"Wudang Shan"
], "carrier_names": [
"001 Liaoning",
"002 Shandong",
]
], "boat":[
"Type54GroupGenerator"
], "has_jtac": True
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
France_1995 = {
"country": "France",
@@ -11,12 +11,13 @@ France_1995 = {
Mirage_2000_5,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
SA342M,
SA342L,
SA342Mistral,
Armor.MBT_Leclerc,
Armor.TPz_Fuchs, # Standing as VAB
@@ -40,5 +41,7 @@ France_1995 = {
], "shorad": [
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.SAM_Roland_ADS
]
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
France_2005 = {
"country": "France",
@@ -12,12 +12,13 @@ France_2005 = {
FA_18C_hornet, # Standing as Rafale M
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
SA342M,
SA342L,
SA342Mistral,
Armor.MBT_Leclerc,
Armor.TPz_Fuchs, # Standing as VAB
@@ -50,10 +51,12 @@ France_2005 = {
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
"R91 Charles de Gaulle",
"PA Charles de Gaulle",
], "lhanames": [
"L9013 Mistral",
"L9014 Tonerre",
"L9015 Dixmude"
]
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,80 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
import pydcs_extensions.frenchpack.frenchpack as frenchpack
from pydcs_extensions.rafale.rafale import Rafale_M, Rafale_A_S
France_2005_Modded = {
"country": "France",
"side": "blue",
"units": [
M_2000C,
Mirage_2000_5,
Rafale_M,
Rafale_A_S,
KC_135,
KC130,
C_130,
E_3A,
SA342M,
SA342L,
SA342Mistral,
Armor.MBT_Leclerc,
Artillery.SPH_M109_Paladin, # Standing as AMX30 AuF1
Artillery.MLRS_M270,
frenchpack.AMX_10RCR,
frenchpack.AMX_10RCR_SEPAR,
frenchpack.ERC_90,
frenchpack.TRM_2000_PAMELA,
frenchpack.VAB__50,
frenchpack.VAB_MEPHISTO,
frenchpack.VAB_T20_13,
frenchpack.VBL__50,
frenchpack.VBL_AANF1,
frenchpack.VBAE_CRAB,
frenchpack.VBAE_CRAB_MMP,
frenchpack.AMX_30B2,
frenchpack.Leclerc_Serie_XXI,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Roland_ADS,
AirDefence.SAM_Hawk_PCP,
AirDefence.HQ_7_Self_Propelled_LN, # Standing as Crotale
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad": [
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.SAM_Roland_ADS
], "aircraft_carrier": [
CVN_74_John_C__Stennis, # Standing as CDG Aircraft Carrier
], "helicopter_carrier": [
LHA_1_Tarawa, # Standing as Mistral Class
], "destroyer": [
Oliver_Hazzard_Perry_class,
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
"PA Charles de Gaulle",
], "lhanames": [
"L9013 Mistral",
"L9014 Tonerre",
"L9015 Dixmude"
], "boat": [
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
], "requirements": {
"frenchpack V3.5": "https://forums.eagle.ru/showthread.php?t=279974",
"RAFALE 2.5.5": "https://www.digitalcombatsimulator.com/fr/files/3307478/",
}, "has_jtac": True
}

View File

@@ -1,6 +1,9 @@
from dcs.planes import *
from dcs.vehicles import *
from game.data.building_data import WW2_GERMANY_BUILDINGS
from game.data.doctrine import WWII_DOCTRINE
Germany_1944 = {
"country": "Third Reich",
"side": "red",
@@ -9,6 +12,7 @@ Germany_1944 = {
FW_190A8,
FW_190D9,
Bf_109K_4,
Ju_88A4,
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
@@ -16,13 +20,26 @@ Germany_1944 = {
Armor.HT_Pz_Kpfw_VI_Ausf__B__Tiger_II,
Armor.APC_Sd_Kfz_251,
Armor.IFV_Sd_Kfz_234_2_Puma,
Armor.Sd_Kfz_184_Elefant,
Armor.TD_Jagdpanther_G1,
Armor.TD_Jagdpanzer_IV,
Artillery.Sturmpanzer_IV_Brummbär,
Unarmed.Sd_Kfz_2,
Unarmed.Sd_Kfz_7,
Unarmed.Kübelwagen_82,
Infantry.Infantry_Mauser_98,
AirDefence.AAA_Flak_36,
]
AirDefence.AAA_8_8cm_Flak_36,
],
"shorad": [
AirDefence.AAA_8_8cm_Flak_36,
],
"objects": WW2_GERMANY_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["UBoatGroupGenerator", "SchnellbootGroupGenerator"],
"boat_count": 2,
"missiles": ["V1GroupGenerator"],
"missiles_count": 1
}

View File

@@ -0,0 +1,38 @@
from dcs.planes import *
from dcs.vehicles import *
from game.data.building_data import WW2_GERMANY_BUILDINGS
from game.data.doctrine import WWII_DOCTRINE
Germany_1944_Easy = {
"country": "Third Reich",
"side": "red",
"units": [
FW_190A8,
FW_190D9,
Bf_109K_4,
Ju_88A4,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
Armor.APC_Sd_Kfz_251,
Armor.IFV_Sd_Kfz_234_2_Puma,
Artillery.Sturmpanzer_IV_Brummbär,
Unarmed.Sd_Kfz_2,
Unarmed.Sd_Kfz_7,
Unarmed.Kübelwagen_82,
Infantry.Infantry_Mauser_98,
AirDefence.AAA_8_8cm_Flak_36,
],
"shorad":[
AirDefence.AAA_8_8cm_Flak_36,
],
"objects": WW2_GERMANY_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["UBoatGroupGenerator", "SchnellbootGroupGenerator"],
"boat_count": 1,
"missiles": ["V1GroupGenerator"],
"missiles_count": 1
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Germany_1990 = {
"country": "Germany",
@@ -12,7 +12,7 @@ Germany_1990 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
@@ -39,5 +39,7 @@ Germany_1990 = {
"shorad":[
AirDefence.SPAAA_Gepard,
AirDefence.SAM_Roland_ADS,
], "boat":[
"OliverHazardPerryGroupGenerator"
]
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
India_2010 = {
"country": "India",
@@ -15,7 +15,7 @@ India_2010 = {
Su_30,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
@@ -49,5 +49,7 @@ India_2010 = {
FSG_1241_1MP_Molniya,
], "carrier_names": [
"INS Vikramaditya"
]
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator", "MolniyaGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,33 @@
from dcs.ships import *
from dcs.vehicles import *
from pydcs_extensions.frenchpack.frenchpack import DIM__TOYOTA_BLUE, DIM__TOYOTA_DESERT, DIM__TOYOTA_GREEN, \
DIM__KAMIKAZE
Insurgent_modded = {
"country": "Insurgents",
"side": "red",
"units": [
AirDefence.AAA_ZU_23_Insurgent_Closed,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375,
DIM__TOYOTA_BLUE,
DIM__TOYOTA_DESERT,
DIM__TOYOTA_GREEN,
DIM__KAMIKAZE,
Armor.ARV_BRDM_2,
Armor.APC_Cobra,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Soldier_AK,
Infantry.Infantry_Soldier_Insurgents,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160
], "requirements": {
"frenchpack V3.5": "https://forums.eagle.ru/showthread.php?t=279974",
}
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Iran_2015 = {
"country": "Iran",
@@ -52,5 +52,7 @@ Iran_2015 = {
"shorad":[
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.AAA_ZU_23_Insurgent_Closed
], "boat":[
"GrishaGroupGenerator", "MolniyaGroupGenerator", "KiloSubGroupGenerator"
]
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Israel_2000 = {
"country": "Israel",
@@ -12,7 +12,7 @@ Israel_2000 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
@@ -31,7 +31,9 @@ Israel_2000 = {
LHA_1_Tarawa,
Armed_speedboat,
],
"shorad":[
"shorad": [
AirDefence.SAM_Avenger_M1097
]
], "boat": [
"ArleighBurkeGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Italy_1990 = {
"country": "Italy",
@@ -39,8 +39,10 @@ Italy_1990 = {
Oliver_Hazzard_Perry_class,
], "cruiser": [
Ticonderoga_class,
], "lha_names": [
], "lhanames": [
"Giuseppe Garibaldi",
"Cavour",
]
], "boat":[
"OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,52 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
from pydcs_extensions.mb339.mb339 import MB_339PAN
Italy_1990_MB339 = {
"country": "Italy",
"side": "blue",
"units": [
Tornado_IDS,
AV8BNA,
MB_339PAN,
KC_135,
S_3B_Tanker,
C_130,
E_3A,
AH_1W,
UH_1H,
Armor.MBT_Leopard_1A3, # OF-40 MBT
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Avenger_M1097,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad":[
AirDefence.SAM_Avenger_M1097,
], "helicopter_carrier": [
LHA_1_Tarawa,
], "destroyer": [
Oliver_Hazzard_Perry_class,
], "cruiser": [
Ticonderoga_class,
], "lhanames": [
"Giuseppe Garibaldi",
"Cavour",
], "boat": [
"OliverHazardPerryGroupGenerator"
], "requirements": {
"MB-339A": "http://www.freccetricolorivirtuali.net/",
}, "has_jtac": True
}

View File

@@ -0,0 +1,54 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Japan_2005 = {
"country": "Japan",
"side": "blue",
"units": [
F_15C, # F-15J/DJ
F_16C_50, # F-2A/B
F_4E, # F-4EJ
KC_135,
KC130,
C_130,
E_3A,
AH_1W,
AH_64D,
Armor.MBT_Merkava_Mk__4, # Standing as Type 10 MBT
Armor.MBT_M1A2_Abrams, # Standing as Type 90 MBT
Armor.IFV_Marder, # Standing as Type 89 IFV
Armor.TPz_Fuchs, # Standing as Type 96 APC
Armor.IFV_LAV_25, # Standing as Type 16 or Type 87
Armor.APC_M1043_HMMWV_Armament,
Artillery.MLRS_M270,
Artillery.SPH_M109_Paladin, # Standing as Type 99 SPH
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Patriot_EPP_III,
LHA_1_Tarawa,
], "shorad": [
AirDefence.SPAAA_Gepard, # Type 87 SPAG
], "helicopter_carrier": [
LHA_1_Tarawa, # Standing as Hyuga-class helicopter carrier
], "destroyer": [
USS_Arleigh_Burke_IIa,
], "cruiser": [
Ticonderoga_class,
], "lhanames": [
"Hyuga",
"Ise",
], "boat":[
"ArleighBurkeGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,10 +1,9 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.vehicles import *
Lybia_2011 = {
"country": "Russia",
Libya_2011 = {
"country": "Libya",
"side": "red",
"units": [
@@ -28,7 +27,7 @@ Lybia_2011 = {
AirDefence.HQ_7_Self_Propelled_LN,
Armor.IFV_BMP_1,
Armor.ARV_MTLB_U_BOMAN,
Armor.FDDM_Grad,
Armor.ARV_BRDM_2,
Armor.MBT_T_55,
Armor.MBT_T_72B,
@@ -44,5 +43,7 @@ Lybia_2011 = {
"shorad":[
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.SAM_SA_8_Osa_9A33,
], "boat": [
"GrishaGroupGenerator", "MolniyaGroupGenerator"
]
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Netherlands_1990 = {
"country": "The Netherlands",
@@ -11,7 +11,7 @@ Netherlands_1990 = {
F_5E_3,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
@@ -30,7 +30,9 @@ Netherlands_1990 = {
LHA_1_Tarawa,
Armed_speedboat,
],
"shorad":[
"shorad": [
AirDefence.SAM_Avenger_M1097
]
}
], "boat": [
"OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
NorthKorea_2000 = {
"country": "North Korea",
@@ -46,5 +46,8 @@ NorthKorea_2000 = {
"shorad":[
AirDefence.AAA_ZU_23_Emplacement,
AirDefence.SPAAA_ZSU_23_4_Shilka
],
"boat": [
"GrishaGroupGenerator", "MolniyaGroupGenerator"
]
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Pakistan_2015 = {
"country": "Pakistan",
@@ -34,5 +34,7 @@ Pakistan_2015 = {
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375,
AirDefence.AAA_ZU_23_Closed
]
], "boat": [
"Type54GroupGenerator", "OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,91 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
from pydcs_extensions.mb339.mb339 import MB_339PAN
PMC_WESTERN_A = {
"country": "USA",
"side": "blue",
"units": [
C_101CC,
UH_1H,
Mi_8MT,
OH_58D,
SA342M,
Armor.APC_M1043_HMMWV_Armament,
Armor.IFV_MCV_80,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Avenger_M1097,
Armed_speedboat,
], "shorad":[
AirDefence.SAM_Avenger_M1097,
], "has_jtac": True
}
PMC_WESTERN_B = {
"country": "USA",
"side": "blue",
"units": [
MB_339PAN,
C_101CC,
UH_1H,
Mi_8MT,
OH_58D,
SA342M,
Armor.APC_M1043_HMMWV_Armament,
Armor.IFV_MCV_80,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Avenger_M1097,
Armed_speedboat,
], "shorad":[
AirDefence.SAM_Avenger_M1097,
], "has_jtac": True,
"requirements": {
"MB-339A": "http://www.freccetricolorivirtuali.net/",
}
}
PMC_RUSSIAN = {
"country": "Russia",
"side": "blue",
"units": [
L_39C,
L_39ZA,
Mi_8MT,
Mi_24V,
Ka_50,
Armor.APC_Cobra,
Armor.APC_BTR_80,
Armor.ARV_BRDM_2,
Unarmed.Transport_Ural_375,
Infantry.Paratrooper_AKS,
Infantry.Paratrooper_RPG_16,
AirDefence.AAA_ZU_23_on_Ural_375,
Armed_speedboat,
], "shorad":[
AirDefence.AAA_ZU_23_on_Ural_375,
AirDefence.AAA_ZU_23_Closed,
], "has_jtac": True
}

View File

@@ -17,7 +17,7 @@ Russia_1955 = {
AirDefence.AAA_ZU_23_Closed,
AirDefence.AAA_ZU_23_on_Ural_375,
Armor.ARV_BRDM_2,
Armor.ARV_MTLB_U_BOMAN,
Armor.FDDM_Grad,
Armor.APC_MTLB,
Armor.MBT_T_55,
Artillery.MLRS_BM_21_Grad,

View File

@@ -49,5 +49,7 @@ Russia_1965 = {
],
"shorad":[
AirDefence.AAA_ZU_23_Closed
], "boat": [
"GrishaGroupGenerator"
]
}

View File

@@ -65,5 +65,7 @@ Russia_1975 = {
FF_1135M_Rezky,
], "cruiser": [
CGN_1144_2_Pyotr_Velikiy,
], "boat": [
"RussianNavyGroupGenerator", "KiloSubGroupGenerator", "MolniyaGroupGenerator"
]
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Russia_1990 = {
"country": "Russia",
@@ -58,11 +58,16 @@ Russia_1990 = {
AirDefence.SAM_SA_9_Strela_1_9P31,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3,
AirDefence.SPAAA_ZSU_23_4_Shilka
], "carrier_names": [
"Admiral Kuznetov",
"Admiral Gorshkov"
], "aircraft_carrier": [
CV_1143_5_Admiral_Kuznetsov,
], "destroyer": [
FF_1135M_Rezky,
], "cruiser": [
FSG_1241_1MP_Molniya,
], "boat":[
"RussianNavyGroupGenerator", "KiloSubGroupGenerator"
]
}

View File

@@ -1,19 +1,20 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Russia_2010 = {
"country": "Russia",
"side": "red",
"units": [
AJS37,
MiG_23MLD,
Su_25,
Su_27,
Su_30,
Su_33,
MiG_29S,
MiG_31,
Su_25,
Su_25T,
Su_34,
Su_24M,
@@ -28,6 +29,8 @@ Russia_2010 = {
Ka_50,
Mi_8MT,
Mi_24V,
Mi_28N,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
@@ -37,6 +40,9 @@ Russia_2010 = {
Armor.MBT_T_90,
Armor.MBT_T_80U,
Armor.MBT_T_72B,
Armor.IFV_BMP_1,
Armor.IFV_BMP_2,
Armor.IFV_BMP_3,
Artillery.MLRS_9K57_Uragan_BM_27,
Artillery.SPH_2S19_Msta,
@@ -59,9 +65,13 @@ Russia_2010 = {
AirDefence.SAM_SA_13_Strela_10M3_9A35M3
], "aircraft_carrier": [
CV_1143_5_Admiral_Kuznetsov,
], "carrier_names": [
"Admiral Kuznetov"
], "destroyer": [
FF_1135M_Rezky,
], "cruiser": [
FSG_1241_1MP_Molniya,
], "boat": [
"RussianNavyGroupGenerator", "KiloSubGroupGenerator"
]
}

View File

@@ -1,6 +1,6 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Spain_1990 = {
"country": "Spain",
@@ -12,7 +12,7 @@ Spain_1990 = {
C_101CC,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
@@ -44,5 +44,7 @@ Spain_1990 = {
"Principe de Asturias",
], "lhanames": [
"Juan Carlos I",
]
], "boat":[
"OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -25,7 +25,7 @@ Sweden_1990 = {
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160,
],
"shorad":[
"shorad": [
AirDefence.SAM_Avenger_M1097
]
], "has_jtac": True
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Turkey_2005 = {
"country": "Turkey",
@@ -11,7 +11,7 @@ Turkey_2005 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
@@ -36,5 +36,7 @@ Turkey_2005 = {
], "shorad":[
AirDefence.AAA_ZU_23_Emplacement,
AirDefence.SPAAA_ZSU_23_4_Shilka
]
], "boat":[
"OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
UAE_2005 = {
"country": "United Arab Emirates",
@@ -12,7 +12,7 @@ UAE_2005 = {
F_16C_50,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
@@ -30,5 +30,7 @@ UAE_2005 = {
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
]
], "boat":[
"OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

42
game/factions/uk_1944.py Normal file
View File

@@ -0,0 +1,42 @@
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
from game.data.building_data import WW2_ALLIES_BUILDINGS
from game.data.doctrine import WWII_DOCTRINE
UK_1944 = {
"country": "UK",
"side": "blue",
"units": [
P_51D,
P_51D_30_NA,
P_47D_30,
SpitfireLFMkIX,
SpitfireLFMkIXCW,
A_20G,
B_17G,
Armor.MT_M4A4_Sherman_Firefly,
Armor.MT_M4_Sherman,
Armor.APC_M2A1,
Armor.CT_Cromwell_IV,
Armor.ST_Centaur_IV,
Armor.HIT_Churchill_VII,
Infantry.Infantry_SMLE_No_4_Mk_1,
LS_Samuel_Chase,
LST_Mk_II,
LCVP__Higgins_boat,
Unarmed.CCKW_353,
AirDefence.AAA_Bofors_40mm,
], "shorad":[
AirDefence.AAA_Bofors_40mm,
],
"objects": WW2_ALLIES_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["WW2LSTGroupGenerator"],
"boat_count": 1
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
UnitedKingdom_1990 = {
"country": "UK",
@@ -12,11 +12,11 @@ UnitedKingdom_1990 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
SA342L,
SA342M,
AH_64A,
Armor.MBT_Challenger_II,
@@ -42,9 +42,11 @@ UnitedKingdom_1990 = {
Oliver_Hazzard_Perry_class,
], "cruiser": [
Ticonderoga_class,
], "lha_names": [
], "lhanames": [
"HMS Invincible",
"HMS Illustrious",
"HMS Ark Royal",
]
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Ukraine_2010 = {
"country": "Ukraine",
@@ -47,5 +47,7 @@ Ukraine_2010 = {
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3,
AirDefence.AAA_ZU_23_on_Ural_375
], "boat":[
"GrishaGroupGenerator"
]
}

View File

@@ -0,0 +1,72 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
US_Aggressors = {
"country": "USAF Aggressors",
"side": "red",
"units": [
F_15C,
F_5E_3,
FA_18C_hornet,
F_16C_50,
Su_27,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
AH_64D,
Ka_50,
SA342M,
SA342L,
Armor.MBT_M1A2_Abrams,
Armor.MBT_Leopard_2,
Armor.ATGM_M1134_Stryker,
Armor.IFV_M2A2_Bradley,
Armor.APC_M1043_HMMWV_Armament,
Artillery.MLRS_M270,
Artillery.SPH_M109_Paladin,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Patriot_EPP_III,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad": [
AirDefence.SAM_Avenger_M1097,
], "aircraft_carrier": [
CVN_74_John_C__Stennis,
], "helicopter_carrier": [
LHA_1_Tarawa,
], "destroyer": [
Oliver_Hazzard_Perry_class,
USS_Arleigh_Burke_IIa,
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
"CVN-71 Theodore Roosevelt",
"CVN-72 Abraham Lincoln",
"CVN-73 George Washington",
"CVN-74 John C. Stennis",
], "lhanames": [
"LHA-1 Tarawa",
"LHA-2 Saipan",
"LHA-3 Belleau Wood",
"LHA-4 Nassau",
"LHA-5 Peleliu"
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
]
}

View File

@@ -2,20 +2,24 @@ from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
from game.data.building_data import WW2_ALLIES_BUILDINGS
from game.data.doctrine import WWII_DOCTRINE
USA_1944 = {
"country": "USA",
"side": "blue",
"units": [
P_51D,
P_51D_30_NA,
SpitfireLFMkIX,
SpitfireLFMkIXCW,
P_47D_30,
A_20G,
B_17G,
Armor.MT_M4_Sherman,
Armor.MT_M4A4_Sherman_Firefly,
Armor.M30_Cargo_Carrier,
Armor.APC_M2A1,
Armor.CT_Cromwell_IV,
Armor.LAC_M8_Greyhound,
Armor.TD_M10_GMC,
Artillery.M12_GMC,
Infantry.Infantry_M1_Garand,
@@ -26,5 +30,53 @@ USA_1944 = {
Unarmed.CCKW_353,
AirDefence.AAA_Bofors_40mm,
]
], "shorad":[
AirDefence.AAA_Bofors_40mm,
],
"objects": WW2_ALLIES_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["WW2LSTGroupGenerator"],
"boat_count": 2
}
ALLIES_1944 = {
"country": "USA",
"side": "blue",
"units": [
P_51D,
P_51D_30_NA,
P_47D_30,
SpitfireLFMkIX,
SpitfireLFMkIXCW,
A_20G,
B_17G,
Armor.MT_M4_Sherman,
Armor.MT_M4A4_Sherman_Firefly,
Armor.CT_Cromwell_IV,
Armor.M30_Cargo_Carrier,
Armor.APC_M2A1,
Armor.CT_Cromwell_IV,
Armor.ST_Centaur_IV,
Armor.HIT_Churchill_VII,
Armor.LAC_M8_Greyhound,
Armor.TD_M10_GMC,
Artillery.M12_GMC,
Infantry.Infantry_M1_Garand,
Infantry.Infantry_SMLE_No_4_Mk_1,
LS_Samuel_Chase,
LST_Mk_II,
LCVP__Higgins_boat,
Unarmed.CCKW_353,
AirDefence.AAA_Bofors_40mm,
], "shorad":[
AirDefence.AAA_Bofors_40mm,
],
"objects": WW2_ALLIES_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["WW2LSTGroupGenerator"],
"boat_count": 2
}

View File

@@ -11,7 +11,7 @@ USA_1955 = {
P_51D,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@@ -11,7 +11,7 @@ USA_1960 = {
P_51D,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@@ -1,7 +1,7 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
USA_1965 = {
"country": "USA",
@@ -12,7 +12,7 @@ USA_1965 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
@@ -36,5 +36,6 @@ USA_1965 = {
"shorad":[
AirDefence.AAA_Vulcan_M163,
AirDefence.SAM_Chaparral_M48
], "boat":[
]
}

View File

@@ -1,13 +1,14 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
USA_1990 = {
"country": "USA",
"side": "blue",
"units": [
F_15C,
F_15E,
F_14B,
FA_18C_hornet,
@@ -17,12 +18,13 @@ USA_1990 = {
B_1B,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
UH_1H,
AH_64A,
OH_58D,
Armor.MBT_M1A2_Abrams,
Armor.IFV_LAV_25,
@@ -46,6 +48,7 @@ USA_1990 = {
LHA_1_Tarawa,
], "destroyer": [
Oliver_Hazzard_Perry_class,
USS_Arleigh_Burke_IIa,
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
@@ -58,5 +61,7 @@ USA_1990 = {
"LHA-3 Belleau Wood",
"LHA-4 Nassau",
"LHA-5 Peleliu"
]
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,28 +1,28 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
USA_2005 = {
"country": "USA",
"side": "blue",
"units": [
F_15C,
F_15E,
F_14B,
FA_18C_hornet,
F_16C_50,
JF_17,
A_10C,
AV8BNA,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,
UH_1H,
AH_64D,
OH_58D,
Armor.MBT_M1A2_Abrams,
Armor.ATGM_M1134_Stryker,
@@ -52,12 +52,13 @@ USA_2005 = {
], "helicopter_carrier": [
LHA_1_Tarawa,
], "destroyer": [
Oliver_Hazzard_Perry_class,
USS_Arleigh_Burke_IIa,
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
"CVN-71 Theodore Roosevelt",
"CVN-72 Abraham Lincoln",
"CVN-73 Georges Washington",
"CVN-73 George Washington",
"CVN-74 John C. Stennis",
], "lhanames": [
"LHA-1 Tarawa",
@@ -65,5 +66,7 @@ USA_2005 = {
"LHA-3 Belleau Wood",
"LHA-4 Nassau",
"LHA-5 Peleliu"
]
], "boat":[
"ArleighBurkeGroupGenerator"
], "has_jtac": True
}

View File

@@ -1,24 +1,11 @@
import logging
import typing
import random
import math
from datetime import datetime, timedelta
from dcs.task import *
from dcs.vehicles import *
from game.db import REWARDS, PLAYER_BUDGET_BASE
from game.game_stats import GameStats
from game.infos.information import Information
from gen.conflictgen import Conflict
from game.db import REWARDS, PLAYER_BUDGET_BASE, sys
from game.models.game_stats import GameStats
from gen.flights.ai_flight_planner import FlightPlanner
from gen.ground_forces.ai_ground_planner import GroundPlanner
from userdata.debriefing import Debriefing
from theater import *
from . import db
from .settings import Settings
from .event import *
from datetime import datetime, timedelta
from .settings import Settings
COMMISION_UNIT_VARIETY = 4
COMMISION_LIMITS_SCALE = 1.5
@@ -69,8 +56,8 @@ class Game:
current_unit_id = 0
current_group_id = 0
def __init__(self, player_name: str, enemy_name: str, theater: ConflictTheater, start_date: datetime):
self.settings = Settings()
def __init__(self, player_name: str, enemy_name: str, theater: ConflictTheater, start_date: datetime, settings):
self.settings = settings
self.events = []
self.theater = theater
self.player_name = player_name
@@ -85,6 +72,35 @@ class Game:
self.ground_planners = {}
self.informations = []
self.informations.append(Information("Game Start", "-" * 40, 0))
self.__culling_points = self.compute_conflicts_position()
self.__frontlineData = []
self.__destroyed_units = []
self.jtacs = []
self.savepath = ""
self.sanitize_sides()
def sanitize_sides(self):
"""
Make sure the opposing factions are using different countries
:return:
"""
if self.player_country == self.enemy_country:
if self.player_country == "USA":
self.enemy_country = "USAF Aggressors"
elif self.player_country == "Russia":
self.enemy_country = "USSR"
else:
self.enemy_country = "Russia"
@property
def player_faction(self):
return db.FACTIONS[self.player_name]
@property
def enemy_faction(self):
return db.FACTIONS[self.enemy_name]
def _roll(self, prob, mult):
if self.settings.version == "dev":
@@ -157,12 +173,9 @@ class Game:
self.events.remove(event)
def initiate_event(self, event: Event):
assert event in self.events
#assert event in self.events
logging.info("Generating {} (regular)".format(event))
event.generate()
logging.info("Generating {} (quick)".format(event))
event.generate_quick()
def finish_event(self, event: Event, debriefing: Debriefing):
logging.info("Finishing event {}".format(event))
@@ -182,6 +195,7 @@ class Game:
return event.name == self.player_name
def pass_turn(self, no_action=False, ignored_cps: typing.Collection[ControlPoint] = None):
logging.info("Pass turn")
self.informations.append(Information("End of turn #" + str(self.turn), "-" * 40, 0))
self.turn = self.turn + 1
@@ -197,7 +211,7 @@ class Game:
self._enemy_reinforcement()
self._budget_player()
if not no_action:
if not no_action and self.turn > 1:
for cp in self.theater.player_points():
cp.base.affect_strength(+PLAYER_BASE_STRENGTH_RECOVERY)
else:
@@ -216,6 +230,7 @@ class Game:
self.game_stats.update(self)
# Plan flights & combat for next turn
self.__culling_points = self.compute_conflicts_position()
self.planners = {}
self.ground_planners = {}
for cp in self.theater.controlpoints:
@@ -229,7 +244,14 @@ class Game:
gplanner.plan_groundwar()
self.ground_planners[cp.id] = gplanner
# Autosave progress
persistency.autosave(self)
def _enemy_reinforcement(self):
"""
Compute and commision reinforcement for enemy bases
"""
MAX_ARMOR = 30 * self.settings.multiplier
MAX_AIRCRAFT = 25 * self.settings.multiplier
@@ -317,3 +339,82 @@ class Game:
"""
self.current_group_id += 1
return self.current_group_id
def compute_conflicts_position(self):
"""
Compute the current conflict center position(s), mainly used for culling calculation
:return: List of points of interests
"""
points = []
# By default, use the existing frontline conflict position
for conflict in self.theater.conflicts():
points.append(Conflict.frontline_position(self.theater, conflict[0], conflict[1])[0])
points.append(conflict[0].position)
points.append(conflict[1].position)
# If there is no conflict take the center point between the two nearest opposing bases
if len(points) == 0:
cpoint = None
min_distance = sys.maxsize
for cp in self.theater.player_points():
for cp2 in self.theater.enemy_points():
d = cp.position.distance_to_point(cp2.position)
if d < min_distance:
min_distance = d
cpoint = Point((cp.position.x + cp2.position.x) / 2, (cp.position.y + cp2.position.y) / 2)
points.append(cp.position)
points.append(cp2.position)
break
if cpoint is not None:
break
if cpoint is not None:
points.append(cpoint)
# Else 0,0, since we need a default value
# (in this case this means the whole map is owned by the same player, so it is not an issue)
if len(points) == 0:
points.append(Point(0, 0))
return points
def add_destroyed_units(self, data):
pos = Point(data["x"], data["z"])
if self.theater.is_on_land(pos):
self.__destroyed_units.append(data)
def get_destroyed_units(self):
return self.__destroyed_units
def position_culled(self, pos):
"""
Check if unit can be generated at given position depending on culling performance settings
:param pos: Position you are tryng to spawn stuff at
:return: True if units can not be added at given position
"""
if self.settings.perf_culling == False:
return False
else:
for c in self.__culling_points:
if c.distance_to_point(pos) < self.settings.perf_culling_distance * 1000:
return False
return True
# 1 = red, 2 = blue
def get_player_coalition_id(self):
return 2
def get_enemy_coalition_id(self):
return 1
def get_player_coalition(self):
return dcs.action.Coalition.Blue
def get_enemy_coalition(self):
return dcs.action.Coalition.Red
def get_player_color(self):
return "blue"
def get_enemy_color(self):
return "red"

View File

@@ -0,0 +1,14 @@
class DestroyedUnit:
"""
Store info about a destroyed unit
"""
x: int
y: int
name: str
def __init__(self, x , y, name):
self.x = x
self.y = y
self.name = name

View File

@@ -0,0 +1,13 @@
from theater import ControlPoint
class FrontlineData:
"""
This Data structure will store information about an existing frontline
"""
def __init__(self, from_cp:ControlPoint, to_cp: ControlPoint):
self.to_cp = to_cp
self.from_cp = from_cp
self.enemy_units_position = []
self.blue_units_position = []

View File

@@ -47,11 +47,9 @@ class GameStats:
for cp in game.theater.controlpoints:
if cp.captured:
turn_data.allied_units.aircraft_count += sum(cp.base.aircraft.values())
turn_data.allied_units.sam_count += sum(cp.base.aa.values())
turn_data.allied_units.vehicles_count += sum(cp.base.armor.values())
else:
turn_data.enemy_units.aircraft_count += sum(cp.base.aircraft.values())
turn_data.enemy_units.sam_count += sum(cp.base.aa.values())
turn_data.enemy_units.vehicles_count += sum(cp.base.armor.values())
self.data_per_turn.append(turn_data)

View File

@@ -14,19 +14,6 @@ class FrontlineAttackOperation(Operation):
attackers = None # type: db.ArmorDict
defenders = None # type: db.ArmorDict
def setup(self,
defenders: db.ArmorDict,
attackers: db.ArmorDict,
strikegroup: db.AssignedUnitsDict,
escort: db.AssignedUnitsDict,
interceptors: db.AssignedUnitsDict):
self.strikegroup = strikegroup
self.escort = escort
self.interceptors = interceptors
self.defenders = defenders
self.attackers = attackers
def prepare(self, terrain: Terrain, is_quick: bool):
super(FrontlineAttackOperation, self).prepare(terrain, is_quick)
if self.defender_name == self.game.player_name:
@@ -47,29 +34,6 @@ class FrontlineAttackOperation(Operation):
conflict=conflict)
def generate(self):
#if self.is_player_attack:
# self.prepare_carriers(db.unitdict_from(self.strikegroup))
# ground units
# self.armorgen.generate_vec(self.attackers, self.defenders)
## strike group w/ heli support
#planes_flights = {k: v for k, v in self.strikegroup.items() if k in plane_map.values()}
#self.airgen.generate_cas_strikegroup(*assigned_units_split(planes_flights), at=self.attackers_starting_position)
#heli_flights = {k: v for k, v in self.strikegroup.items() if k in helicopters.helicopter_map.values()}
#if heli_flights:
# self.briefinggen.append_frequency("FARP + Heli flights", "127.5 MHz AM")
# for farp, dict in zip(self.groundobjectgen.generate_farps(sum([x[0] for x in heli_flights.values()])),
# db.assignedunits_split_to_count(heli_flights, self.groundobjectgen.FARP_CAPACITY)):
# self.airgen.generate_cas_strikegroup(*assigned_units_split(dict),
# at=farp,
# escort=len(planes_flights) == 0)
#self.airgen.generate_attackers_escort(*assigned_units_split(self.escort), at=self.attackers_starting_position)
#self.airgen.generate_defense(*assigned_units_split(self.interceptors), at=self.defenders_starting_position)
self.briefinggen.title = "Frontline CAS"
self.briefinggen.description = "Provide CAS for the ground forces attacking enemy lines. Operation will be considered successful if total number of enemy units will be lower than your own by a factor of 1.5 (i.e. with 12 units from both sides, enemy forces need to be reduced to at least 8), meaning that you (and, probably, your wingmans) should concentrate on destroying the enemy units. Target base strength will be lowered as a result. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
self.briefinggen.append_waypoint("CAS AREA IP")

View File

@@ -18,7 +18,6 @@ class Operation:
conflict = None # type: Conflict
armorgen = None # type: ArmorConflictGenerator
airgen = None # type: AircraftConflictGenerator
shipgen = None # type: ShipGenerator
triggersgen = None # type: TriggersGenerator
airsupportgen = None # type: AirSupportConflictGenerator
visualgen = None # type: VisualGenerator
@@ -64,8 +63,7 @@ class Operation:
def initialize(self, mission: Mission, conflict: Conflict):
self.current_mission = mission
self.conflict = conflict
self.airgen = AircraftConflictGenerator(mission, conflict, self.game.settings)
self.shipgen = ShipGenerator(mission, conflict)
self.airgen = AircraftConflictGenerator(mission, conflict, self.game.settings, self.game)
self.airsupportgen = AirSupportConflictGenerator(mission, conflict, self.game)
self.triggersgen = TriggersGenerator(mission, conflict, self.game)
self.visualgen = VisualGenerator(mission, conflict, self.game)
@@ -74,9 +72,6 @@ class Operation:
self.groundobjectgen = GroundObjectsGenerator(mission, conflict, self.game)
self.briefinggen = BriefingGenerator(mission, conflict, self.game)
player_country = self.from_cp.captured and self.attacker_country or self.defender_country
enemy_country = self.from_cp.captured and self.defender_country or self.attacker_country
def prepare(self, terrain: Terrain, is_quick: bool):
with open("resources/default_options.lua", "r") as f:
options_dict = loads(f.read())["options"]
@@ -90,12 +85,12 @@ class Operation:
# Setup coalition :
self.current_mission.coalition["blue"] = Coalition("blue")
self.current_mission.coalition["red"] = Coalition("red")
if self.game.player_country and self.game.player_country in db.BLUEFOR_FACTIONS:
self.current_mission.coalition["blue"].add_country(country_dict[db.country_id_from_name(self.game.player_country)]())
self.current_mission.coalition["red"].add_country(country_dict[db.country_id_from_name(self.game.enemy_country)]())
else:
self.current_mission.coalition["blue"].add_country(country_dict[db.country_id_from_name(self.game.enemy_country)]())
self.current_mission.coalition["red"].add_country(country_dict[db.country_id_from_name(self.game.player_country)]())
p_country = self.game.player_country
e_country = self.game.enemy_country
self.current_mission.coalition["blue"].add_country(country_dict[db.country_id_from_name(p_country)]())
self.current_mission.coalition["red"].add_country(country_dict[db.country_id_from_name(e_country)]())
print([c for c in self.current_mission.coalition["blue"].countries.keys()])
print([c for c in self.current_mission.coalition["red"].countries.keys()])
@@ -116,9 +111,35 @@ class Operation:
def generate(self):
# Generate meteo
if self.environment_settings is None:
self.environment_settings = self.envgen.generate()
else:
self.envgen.load(self.environment_settings)
# Generate ground object first
self.groundobjectgen.generate()
# Generate destroyed units
for d in self.game.get_destroyed_units():
try:
utype = db.unit_type_from_name(d["type"])
except KeyError:
continue
pos = Point(d["x"], d["z"])
if utype is not None and not self.game.position_culled(pos) and self.game.settings.perf_destroyed_units:
self.current_mission.static_group(
country=self.current_mission.country(self.game.player_country),
name="",
_type=utype,
hidden=True,
position=pos,
heading=d["orientation"],
dead=True,
)
# Air Support (Tanker & Awacs)
self.airsupportgen.generate(self.is_awacs_enabled)
@@ -133,6 +154,7 @@ class Operation:
self.airgen.generate_flights(cp, country, self.game.planners[cp.id])
# Generate ground units on frontline everywhere
self.game.jtacs = []
for player_cp, enemy_cp in self.game.theater.conflicts(True):
conflict = Conflict.frontline_cas_conflict(self.attacker_name, self.defender_name,
self.current_mission.country(self.attacker_country),
@@ -151,28 +173,19 @@ class Operation:
else:
self.current_mission.groundControl.red_tactical_commander = self.ca_slots
# triggers
# Triggers
if self.game.is_player_attack(self.conflict.attackers_country):
cp = self.conflict.from_cp
else:
cp = self.conflict.to_cp
self.triggersgen.generate()
self.triggersgen.generate(player_cp=cp,
is_quick=False,
activation_trigger_radius=self.trigger_radius,
awacs_enabled=self.is_awacs_enabled)
# env settings
if self.environment_settings is None:
self.environment_settings = self.envgen.generate()
else:
self.envgen.load(self.environment_settings)
# options
# Options
self.forcedoptionsgen.generate()
# Generate Visuals Smoke Effects
self.visualgen.generate()
if self.game.settings.perf_smoke_gen:
self.visualgen.generate()
# Inject Lua Scripts
load_mist = TriggerStart(comment="Load Mist Lua Framework")
@@ -180,6 +193,24 @@ class Operation:
load_mist.add_action(DoScript(String(f.read())))
self.current_mission.triggerrules.triggers.append(load_mist)
# Load Ciribob's JTACAutoLase script
load_autolase = TriggerStart(comment="Load JTAC script")
with open("./resources/scripts/JTACAutoLase.lua") as f:
script = f.read()
script = script + "\n"
smoke = "true"
if hasattr(self.game.settings, "jtac_smoke_on"):
if not self.game.settings.jtac_smoke_on:
smoke = "false"
for jtac in self.game.jtacs:
script = script + "\n" + "JTACAutoLase('" + str(jtac[2]) + "', " + str(jtac[1]) + ", " + smoke + ", \"vehicle\")" + "\n"
load_autolase.add_action(DoScript(String(script)))
self.current_mission.triggerrules.triggers.append(load_autolase)
load_dcs_libe = TriggerStart(comment="Load DCS Liberation Script")
with open("./resources/scripts/dcs_liberation.lua") as f:
script = f.read()
@@ -192,14 +223,12 @@ class Operation:
# Briefing Generation
for i, tanker_type in enumerate(self.airsupportgen.generated_tankers):
self.briefinggen.append_frequency("Tanker {} ({})".format(TANKER_CALLSIGNS[i], tanker_type), "{}X/{} MHz AM".format(97+i, 130+i))
self.briefinggen.append_frequency("Tanker {} ({})".format(TANKER_CALLSIGNS[i], tanker_type), "{}X/{} MHz AM".format(60+i, 130+i))
if self.is_awacs_enabled:
self.briefinggen.append_frequency("AWACS", "133 MHz AM")
self.briefinggen.append_frequency("AWACS", "233 MHz AM")
self.briefinggen.append_frequency("Flight", "251 MHz AM")
if self.departure_cp.is_global or self.conflict.to_cp.is_global:
self.briefinggen.append_frequency("Carrier", "20X/ICLS CHAN1")
# Generate the briefing
self.briefinggen.generate()

View File

@@ -1,14 +1,43 @@
class Settings:
player_skill = "Good"
enemy_skill = "Average"
enemy_vehicle_skill = "Average"
map_coalition_visibility = "All Units"
labels = "Full"
only_player_takeoff = True
night_disabled = False
supercarrier = False
multiplier = 1
sams = True
cold_start = False
version = None
def __init__(self):
# Generator settings
self.inverted = False
self.do_not_generate_carrier = False # TODO : implement
self.do_not_generate_lha = False # TODO : implement
self.do_not_generate_player_navy = True # TODO : implement
self.do_not_generate_enemy_navy = True # TODO : implement
# Difficulty settings
self.player_skill = "Good"
self.enemy_skill = "Average"
self.enemy_vehicle_skill = "Average"
self.map_coalition_visibility = "All Units"
self.labels = "Full"
self.only_player_takeoff = True # Legacy parameter do not use
self.night_disabled = False
self.external_views_allowed = True
self.supercarrier = False
self.multiplier = 1
self.generate_marks = True
self.sams = True # Legacy parameter do not use
self.cold_start = False # Legacy parameter do not use
self.version = None
self.include_jtac_if_available = True
self.jtac_smoke_on = True
# Performance oriented
self.perf_red_alert_state = True
self.perf_smoke_gen = True
self.perf_artillery = True
self.perf_moving_units = True
self.perf_infantry = True
self.perf_ai_parking_start = True
self.perf_destroyed_units = True
# Performance culling
self.perf_culling = False
self.perf_culling_distance = 100

14
game/utils.py Normal file
View File

@@ -0,0 +1,14 @@
def meter_to_feet(value_in_meter):
return int(3.28084 * value_in_meter)
def feet_to_meter(value_in_feet):
return int(float(value_in_feet)/3.048)
def meter_to_nm(value_in_meter):
return int(float(value_in_meter)*0.000539957)
def nm_to_meter(value_in_nm):
return int(float(value_in_nm)*1852)

View File

@@ -3,7 +3,6 @@ from .aircraft import *
from .armor import *
from .airsupportgen import *
from .conflictgen import *
from .shipgen import *
from .visualgen import *
from .triggergen import *
from .environmentgen import *

View File

@@ -1,53 +1,35 @@
import logging
from dcs.action import ActivateGroup, AITaskPush, MessageToCoalition, MessageToAll
from dcs.condition import TimeAfter, CoalitionHasAirdrome, PartOfCoalitionInZone
from dcs.helicopters import UH_1H
from dcs.terrain.terrain import NoParkingSlotError
from dcs.triggers import TriggerOnce, Event
from game import db
from game.data.cap_capabilities_db import GUNFIGHTERS
from game.settings import Settings
from game.utils import nm_to_meter
from gen.flights.ai_flight_planner import FlightPlanner
from gen.flights.flight import Flight, FlightType
from gen.flights.flight import Flight, FlightType, FlightWaypointType
from .conflictgen import *
from .naming import *
from .triggergen import TRIGGER_WAYPOINT_OFFSET
from dcs.mission import *
from dcs.unitgroup import *
from dcs.unittype import *
from dcs.task import *
from dcs.terrain.terrain import NoParkingSlotError, RunwayOccupiedError
SPREAD_DISTANCE_FACTOR = 1, 2
ESCORT_ENGAGEMENT_MAX_DIST = 100000
WORKAROUND_WAYP_DIST = 1000
WARM_START_HELI_AIRSPEED = 120
WARM_START_HELI_ALT = 500
WARM_START_ALTITUDE = 3000
WARM_START_AIRSPEED = 550
INTERCEPTION_AIRSPEED = 1000
BARCAP_RACETRACK_DISTANCE = 20000
CAP_DURATION = 30 # minutes
ATTACK_CIRCLE_ALT = 1000
ATTACK_CIRCLE_DURATION = 15
CAS_ALTITUDE = 800
RTB_ALTITUDE = 800
RTB_DISTANCE = 5000
HELI_ALT = 500
TRANSPORT_LANDING_ALT = 2000
DEFENCE_ENGAGEMENT_MAX_DISTANCE = 60000
INTERCEPT_MAX_DISTANCE = 200000
class AircraftConflictGenerator:
escort_targets = [] # type: typing.List[typing.Tuple[FlyingGroup, int]]
def __init__(self, mission: Mission, conflict: Conflict, settings: Settings):
def __init__(self, mission: Mission, conflict: Conflict, settings: Settings, game):
self.m = mission
self.game = game
self.settings = settings
self.conflict = conflict
self.escort_targets = []
@@ -55,43 +37,20 @@ class AircraftConflictGenerator:
def _start_type(self) -> StartType:
return self.settings.cold_start and StartType.Cold or StartType.Warm
def _group_point(self, point) -> Point:
distance = randint(
int(self.conflict.size * SPREAD_DISTANCE_FACTOR[0]),
int(self.conflict.size * SPREAD_DISTANCE_FACTOR[1]),
)
return point.random_point_within(distance, self.conflict.size * SPREAD_DISTANCE_FACTOR[0])
def _split_to_groups(self, dict: db.PlaneDict, clients: db.PlaneDict = None) -> typing.Collection[typing.Tuple[FlyingType, int, int]]:
for flying_type, count in dict.items():
if clients:
client_count = clients.get(flying_type, 0)
else:
client_count = 0
if flying_type == F_14B:
# workaround since 2 and 3 tomcat collide on carrier
group_size = 2
else:
group_size = 4
while count > 0:
group_size = min(count, group_size)
client_size = max(min(client_count, group_size), 0)
yield (flying_type, group_size, client_size)
count -= group_size
client_count -= client_size
def _setup_group(self, group: FlyingGroup, for_task: typing.Type[Task], client_count: int):
def _setup_group(self, group: FlyingGroup, for_task: typing.Type[Task], flight: Flight):
did_load_loadout = False
unit_type = group.units[0].unit_type
print("SETUP GROUP : " + str(for_task) + " -- " + str(group.name))
if unit_type in db.PLANE_PAYLOAD_OVERRIDES:
override_loadout = db.PLANE_PAYLOAD_OVERRIDES[unit_type]
if type(override_loadout) == dict:
# Clear pylons
for p in group.units:
p.pylons.clear()
# Now load loadout
if for_task in db.PLANE_PAYLOAD_OVERRIDES[unit_type]:
payload_name = db.PLANE_PAYLOAD_OVERRIDES[unit_type][for_task]
group.load_loadout(payload_name)
@@ -113,8 +72,8 @@ class AircraftConflictGenerator:
for unit_instance in group.units:
unit_instance.livery_id = db.PLANE_LIVERY_OVERRIDES[unit_type]
single_client = client_count == 1
for idx in range(0, min(len(group.units), client_count)):
single_client = flight.client_count == 1
for idx in range(0, min(len(group.units), flight.client_count)):
if single_client:
group.units[idx].set_player()
else:
@@ -128,16 +87,32 @@ class AircraftConflictGenerator:
if unit_type is F_14B:
group.units[idx].set_property(F_14B.Properties.INSAlignmentStored.id, True)
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
# TODO : refactor this following bad specific special case code :(
if unit_type in helicopters.helicopter_map.values() and unit_type not in [UH_1H]:
group.set_frequency(127.5)
else:
if unit_type not in [P_51D_30_NA, P_51D, SpitfireLFMkIX, SpitfireLFMkIXCW, FW_190A8, FW_190D9, Bf_109K_4]:
if unit_type not in [P_51D_30_NA, P_51D, SpitfireLFMkIX, SpitfireLFMkIXCW, P_47D_30, I_16, FW_190A8, FW_190D9, Bf_109K_4]:
group.set_frequency(251.0)
else:
# WW2
group.set_frequency(124.0)
if unit_type in [FW_190A8, FW_190D9, Bf_109K_4, Ju_88A4]:
group.set_frequency(40)
else:
group.set_frequency(124.0)
# Special case so Su 33 carrier take off
if unit_type is Su_33:
if task is not CAP:
for unit in group.units:
unit.fuel = Su_33.fuel_max / 2.2
else:
for unit in group.units:
unit.fuel = Su_33.fuel_max * 0.8
def _generate_at_airport(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, airport: Airport = None, start_type = None) -> FlyingGroup:
assert count > 0
@@ -151,7 +126,7 @@ class AircraftConflictGenerator:
country=side,
name=name,
aircraft_type=unit_type,
airport=self.m.terrain.airport_by_id(airport.id),
airport=airport,
maintask=None,
start_type=start_type,
group_size=count,
@@ -186,10 +161,13 @@ class AircraftConflictGenerator:
group.points[0].alt_type = "RADIO"
return group
def _generate_at_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: typing.Union[ShipGroup, StaticGroup]) -> FlyingGroup:
def _generate_at_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: typing.Union[ShipGroup, StaticGroup], start_type=None) -> FlyingGroup:
assert count > 0
assert unit is not None
if start_type is None:
start_type = self._start_type()
logging.info("airgen: {} for {} at unit {}".format(unit_type, side.id, at))
return self.m.flight_group_from_unit(
country=side,
@@ -197,7 +175,7 @@ class AircraftConflictGenerator:
aircraft_type=unit_type,
pad_group=at,
maintask=None,
start_type=self._start_type(),
start_type=start_type,
group_size=count)
def _generate_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: db.StartingPosition):
@@ -255,37 +233,6 @@ class AircraftConflictGenerator:
else:
assert False
def _generate_escort(self, side: Country, units: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition, cp, is_quick=False, should_orbit=False):
groups = []
for flying_type, count, client_count in self._split_to_groups(units, clients):
group = self._generate_group(
name=namegen.next_unit_name(side, cp.id, flying_type),
side=side,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at)
group.task = Escort.name
self._setup_group(group, CAP, client_count)
for escorted_group, waypoint_index in self.escort_targets:
waypoint_index += 1
if not is_quick:
waypoint_index += TRIGGER_WAYPOINT_OFFSET
group.points[0].tasks.append(EscortTaskAction(escorted_group.id, engagement_max_dist=ESCORT_ENGAGEMENT_MAX_DIST, lastwpt=waypoint_index))
if should_orbit:
orbit_task = ControlledTask(OrbitAction(ATTACK_CIRCLE_ALT, pattern=OrbitAction.OrbitPattern.Circle))
orbit_task.stop_after_duration(ATTACK_CIRCLE_DURATION * 60)
orbit_waypoint = self._add_radio_waypoint(group, self.conflict.position, CAS_ALTITUDE)
orbit_waypoint.tasks.append(orbit_task)
orbit_waypoint.tasks.append(EngageTargets(max_distance=DEFENCE_ENGAGEMENT_MAX_DISTANCE))
groups.append(group)
return groups
def _setup_custom_payload(self, flight, group:FlyingGroup):
if flight.use_custom_loadout:
@@ -307,47 +254,79 @@ class AircraftConflictGenerator:
def generate_flights(self, cp, country, flight_planner:FlightPlanner):
for flight in flight_planner.interceptor_flights:
group = self.generate_planned_flight(cp, country, flight)
self.setup_group_as_intercept_flight(group, flight)
self._setup_custom_payload(flight, group)
# Clear pydcs parking slots
if cp.airport is not None:
for ps in cp.airport.parking_slots:
ps.unit_id = None
for flight in flight_planner.cap_flights:
group = self.generate_planned_flight(cp, country, flight)
self.setup_group_as_cap_flight(group, flight)
self._setup_custom_payload(flight, group)
for flight in flight_planner.flights:
for flight in flight_planner.cas_flights:
group = self.generate_planned_flight(cp, country, flight)
self.setup_group_as_cas_flight(group, flight)
self._setup_custom_payload(flight, group)
if flight.client_count == 0 and self.game.position_culled(flight.from_cp.position):
logging.info("Flight not generated : culled")
continue
for flight in flight_planner.sead_flights:
group = self.generate_planned_flight(cp, country, flight)
self.setup_group_as_sead_flight(group, flight)
self._setup_custom_payload(flight, group)
self.setup_flight_group(group, flight, flight.flight_type)
self.setup_group_activation_trigger(flight, group)
for flight in flight_planner.custom_flights:
group = self.generate_planned_flight(cp, country, flight)
if flight.flight_type == FlightType.INTERCEPTION:
self.setup_group_as_intercept_flight(group, flight)
elif flight.flight_type in [FlightType.CAP, FlightType.TARCAP, FlightType.BARCAP]:
self.setup_group_as_cap_flight(group, flight)
elif flight.flight_type in [FlightType.CAS, FlightType.BAI]:
self.setup_group_as_cas_flight(group, flight)
elif flight.flight_type in [FlightType.STRIKE]:
self.setup_group_as_strike_flight(group, flight)
elif flight.flight_type in [FlightType.ANTISHIP]:
self.setup_group_as_antiship_flight(group, flight)
elif flight.flight_type in [FlightType.SEAD, FlightType.DEAD]:
self.setup_group_as_sead_flight(group, flight)
def setup_group_activation_trigger(self, flight, group):
if flight.scheduled_in > 0 and flight.client_count == 0:
if flight.start_type != "In Flight" and flight.from_cp.cptype not in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP]:
group.late_activation = False
group.uncontrolled = True
activation_trigger = TriggerOnce(Event.NoEvent, "FlightStartTrigger" + str(group.id))
activation_trigger.add_condition(TimeAfter(seconds=flight.scheduled_in * 60))
if (flight.from_cp.cptype == ControlPointType.AIRBASE):
if flight.from_cp.captured:
activation_trigger.add_condition(
CoalitionHasAirdrome(self.game.get_player_coalition_id(), flight.from_cp.id))
else:
activation_trigger.add_condition(
CoalitionHasAirdrome(self.game.get_enemy_coalition_id(), flight.from_cp.id))
if flight.flight_type == FlightType.INTERCEPTION:
self.setup_interceptor_triggers(group, flight, activation_trigger)
group.add_trigger_action(StartCommand())
activation_trigger.add_action(AITaskPush(group.id, len(group.tasks)))
self.m.triggerrules.triggers.append(activation_trigger)
else:
self.setup_group_as_cap_flight(group, flight)
self._setup_custom_payload(flight, group)
group.late_activation = True
activation_trigger = TriggerOnce(Event.NoEvent, "FlightLateActivationTrigger" + str(group.id))
activation_trigger.add_condition(TimeAfter(seconds=flight.scheduled_in*60))
if(flight.from_cp.cptype == ControlPointType.AIRBASE):
if flight.from_cp.captured:
activation_trigger.add_condition(CoalitionHasAirdrome(self.game.get_player_coalition_id(), flight.from_cp.id))
else:
activation_trigger.add_condition(CoalitionHasAirdrome(self.game.get_enemy_coalition_id(), flight.from_cp.id))
if flight.flight_type == FlightType.INTERCEPTION:
self.setup_interceptor_triggers(group, flight, activation_trigger)
activation_trigger.add_action(ActivateGroup(group.id))
self.m.triggerrules.triggers.append(activation_trigger)
def setup_interceptor_triggers(self, group, flight, activation_trigger):
detection_zone = self.m.triggers.add_triggerzone(flight.from_cp.position, radius=25000, hidden=False, name="ITZ")
if flight.from_cp.captured:
activation_trigger.add_condition(PartOfCoalitionInZone(self.game.get_enemy_color(), detection_zone.id)) # TODO : support unit type in part of coalition
activation_trigger.add_action(MessageToAll(String("WARNING : Enemy aircrafts have been detected in the vicinity of " + flight.from_cp.name + ". Interceptors are taking off."), 20))
else:
activation_trigger.add_condition(PartOfCoalitionInZone(self.game.get_player_color(), detection_zone.id))
activation_trigger.add_action(MessageToAll(String("WARNING : We have detected that enemy aircrafts are scrambling for an interception on " + flight.from_cp.name + " airbase."), 20))
def generate_planned_flight(self, cp, country, flight:Flight):
try:
if flight.start_type == "In Flight" or flight.client_count == 0:
if flight.client_count == 0 and self.game.settings.perf_ai_parking_start:
flight.start_type = "Warm"
if flight.start_type == "In Flight":
group = self._generate_group(
name=namegen.next_unit_name(country, cp.id, flight.unit_type),
side=country,
@@ -356,7 +335,6 @@ class AircraftConflictGenerator:
client_count=0,
at=cp.position)
else:
st = StartType.Runway
if flight.start_type == "Cold":
st = StartType.Cold
@@ -371,7 +349,8 @@ class AircraftConflictGenerator:
unit_type=flight.unit_type,
count=flight.count,
client_count=0,
at=self.m.find_group(group_name),)
at=self.m.find_group(group_name),
start_type=st)
else:
group = self._generate_at_airport(
name=namegen.next_unit_name(country, cp.id, flight.unit_type),
@@ -379,10 +358,11 @@ class AircraftConflictGenerator:
unit_type=flight.unit_type,
count=flight.count,
client_count=0,
airport=self.m.terrain.airport_by_id(cp.at.id),
airport=cp.airport,
start_type=st)
except Exception:
# Generated when there is no place on Runway or on Parking Slots
flight.start_type = "In Flight"
group = self._generate_group(
name=namegen.next_unit_name(country, cp.id, flight.unit_type),
side=country,
@@ -391,69 +371,143 @@ class AircraftConflictGenerator:
client_count=0,
at=cp.position)
group.points[0].alt = 1500
group.points[0].ETA = flight.scheduled_in * 60
flight.group = group
return group
def setup_group_as_intercept_flight(self, group, flight):
group.points[0].ETA = 0
group.late_activation = True
self._setup_group(group, Intercept, flight.client_count)
self._setup_group(group, Intercept, flight)
for point in flight.points:
group.add_waypoint(Point(point.x,point.y), point.alt)
def setup_group_as_cap_flight(self, group, flight):
self._setup_group(group, CAP, flight.client_count)
for point in flight.points:
group.add_waypoint(Point(point.x,point.y), point.alt)
def setup_flight_group(self, group, flight, flight_type):
def setup_group_as_cas_flight(self, group, flight):
group.task = CAS.name
self._setup_group(group, CAS, flight.client_count)
if flight_type in [FlightType.CAP, FlightType.BARCAP, FlightType.TARCAP, FlightType.INTERCEPTION]:
group.task = CAP.name
self._setup_group(group, CAP, flight)
# group.points[0].tasks.clear()
group.points[0].tasks.clear()
group.points[0].tasks.append(EngageTargets(max_distance=nm_to_meter(50), targets=[Targets.All.Air]))
# group.tasks.append(EngageTargets(max_distance=nm_to_meter(120), targets=[Targets.All.Air]))
if flight.unit_type not in GUNFIGHTERS:
group.points[0].tasks.append(OptRTBOnOutOfAmmo(OptRTBOnOutOfAmmo.Values.AAM))
else:
group.points[0].tasks.append(OptRTBOnOutOfAmmo(OptRTBOnOutOfAmmo.Values.Cannon))
group.points[0].tasks.clear()
group.points[0].tasks.append(CASTaskAction())
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree))
group.points[0].tasks.append(OptRestrictJettison(True))
elif flight_type in [FlightType.CAS, FlightType.BAI]:
group.task = CAS.name
self._setup_group(group, CAS, flight)
group.points[0].tasks.clear()
group.points[0].tasks.append(EngageTargets(max_distance=nm_to_meter(10), targets=[Targets.All.GroundUnits.GroundVehicles]))
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree))
group.points[0].tasks.append(OptRTBOnOutOfAmmo(OptRTBOnOutOfAmmo.Values.Unguided))
group.points[0].tasks.append(OptRestrictJettison(True))
elif flight_type in [FlightType.SEAD, FlightType.DEAD]:
group.task = SEAD.name
self._setup_group(group, SEAD, flight)
group.points[0].tasks.clear()
group.points[0].tasks.append(NoTask())
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFire))
group.points[0].tasks.append(OptRestrictJettison(True))
group.points[0].tasks.append(OptRTBOnOutOfAmmo(OptRTBOnOutOfAmmo.Values.ASM))
elif flight_type in [FlightType.STRIKE]:
group.task = PinpointStrike.name
self._setup_group(group, GroundAttack, flight)
group.points[0].tasks.clear()
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFire))
group.points[0].tasks.append(OptRestrictJettison(True))
elif flight_type in [FlightType.ANTISHIP]:
group.task = AntishipStrike.name
self._setup_group(group, AntishipStrike, flight)
group.points[0].tasks.clear()
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFire))
group.points[0].tasks.append(OptRestrictJettison(True))
for point in flight.points:
group.add_waypoint(Point(point.x,point.y), point.alt)
group.points[0].tasks.append(OptRTBOnBingoFuel(True))
group.points[0].tasks.append(OptRestrictAfterburner(True))
def setup_group_as_sead_flight(self, group, flight):
group.task = SEAD.name
self._setup_group(group, SEAD, flight.client_count)
if hasattr(flight.unit_type, 'eplrs'):
if flight.unit_type.eplrs:
group.points[0].tasks.append(EPLRS(group.id))
group.points[0].tasks.clear()
group.points[0].tasks.append(SEADTaskAction())
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree))
group.points[0].tasks.append(OptRestrictJettison(True))
for i, point in enumerate(flight.points):
if not point.only_for_player or (point.only_for_player and flight.client_count > 0):
pt = group.add_waypoint(Point(point.x, point.y), point.alt)
if point.waypoint_type == FlightWaypointType.PATROL_TRACK:
action = ControlledTask(OrbitAction(altitude=pt.alt, pattern=OrbitAction.OrbitPattern.RaceTrack))
action.stop_after_duration(CAP_DURATION * 60)
#for tgt in point.targets:
# if hasattr(tgt, "position"):
# engagetgt = EngageTargetsInZone(tgt.position, radius=CAP_DEFAULT_ENGAGE_DISTANCE, targets=[Targets.All.Air])
# pt.tasks.append(engagetgt)
elif point.waypoint_type == FlightWaypointType.LANDING_POINT:
pt.type = "Land"
elif point.waypoint_type == FlightWaypointType.INGRESS_STRIKE:
i = 1
for point in flight.points:
group.add_waypoint(Point(point.x,point.y), point.alt)
group.points[i].tasks.clear()
group.points[i].tasks.append(SEADTaskAction())
i = i + 1
if group.units[0].unit_type == B_17G:
if len(point.targets) > 0:
bcenter = Point(0,0)
for j, t in enumerate(point.targets):
bcenter.x += t.position.x
bcenter.y += t.position.y
bcenter.x = bcenter.x / len(point.targets)
bcenter.y = bcenter.y / len(point.targets)
bombing = Bombing(bcenter)
bombing.params["expend"] = "All"
bombing.params["attackQtyLimit"] = False
bombing.params["directionEnabled"] = False
bombing.params["altitudeEnabled"] = False
bombing.params["weaponType"] = 2032
bombing.params["groupAttack"] = True
pt.tasks.append(bombing)
else:
for j, t in enumerate(point.targets):
print(t.position)
pt.tasks.append(Bombing(t.position))
if group.units[0].unit_type == JF_17 and j < 4:
group.add_nav_target_point(t.position, "PP" + str(j + 1))
if group.units[0].unit_type == F_14B and j == 0:
group.add_nav_target_point(t.position, "ST")
if group.units[0].unit_type == AJS37 and j < 9:
group.add_nav_target_point(t.position, "M" + str(j + 1))
elif point.waypoint_type == FlightWaypointType.INGRESS_SEAD:
def setup_group_as_strike_flight(self, group, flight):
group.task = PinpointStrike.name
self._setup_group(group, GroundAttack, flight.client_count)
tgroup = self.m.find_group(point.targetGroup.group_identifier)
if tgroup is not None:
task = AttackGroup(tgroup.id)
task.params["expend"] = "All"
task.params["attackQtyLimit"] = False
task.params["directionEnabled"] = False
task.params["altitudeEnabled"] = False
task.params["weaponType"] = 268402702 # Guided Weapons
task.params["groupAttack"] = True
pt.tasks.append(task)
group.points[0].tasks.clear()
group.points[0].tasks.append(CASTaskAction())
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree))
group.points[0].tasks.append(OptRestrictJettison(True))
for j, t in enumerate(point.targets):
if group.units[0].unit_type == JF_17 and j < 4:
group.add_nav_target_point(t.position, "PP" + str(j + 1))
if group.units[0].unit_type == F_14B and j == 0:
group.add_nav_target_point(t.position, "ST")
if group.units[0].unit_type == AJS37 and j < 9:
group.add_nav_target_point(t.position, "M" + str(j + 1))
if pt is not None:
pt.alt_type = point.alt_type
pt.name = String(point.name)
self._setup_custom_payload(flight, group)
for point in flight.points:
group.add_waypoint(Point(point.x,point.y), point.alt)
def setup_group_as_antiship_flight(self, group, flight):
group.task = AntishipStrike.name
self._setup_group(group, AntishipStrike, flight.client_count)
self._setup_group(group, AntishipStrike, flight)
group.points[0].tasks.clear()
group.points[0].tasks.append(AntishipStrikeTaskAction())
@@ -464,263 +518,4 @@ class AircraftConflictGenerator:
for point in flight.points:
group.add_waypoint(Point(point.x,point.y), point.alt)
def generate_cas_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None, escort=True):
assert not escort or len(self.escort_targets) == 0
for flying_type, count, client_count in self._split_to_groups(attackers, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, flying_type),
side=self.conflict.attackers_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location))
waypoint = self._add_radio_waypoint(group, self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
if self.conflict.is_vector:
self._add_radio_waypoint(group, self.conflict.tail, CAS_ALTITUDE, WARM_START_AIRSPEED)
group.task = CAS.name
self._setup_group(group, CAS, client_count)
if escort:
self.escort_targets.append((group, group.points.index(waypoint)))
self._rtb_for(group, self.conflict.from_cp, at)
def generate_ground_attack_strikegroup(self, strikegroup: db.PlaneDict, clients: db.PlaneDict, targets: typing.List[typing.Tuple[str, Point]], at: db.StartingPosition = None, escort=True):
assert not escort or len(self.escort_targets) == 0
for flying_type, count, client_count in self._split_to_groups(strikegroup, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, flying_type),
side=self.conflict.attackers_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location))
escort_until_waypoint = None
for name, pos in targets:
waypoint = group.add_waypoint(pos, 0, WARM_START_AIRSPEED, self.m.translation.create_string(name))
waypoint.tasks.append(Bombing(pos, attack_qty=2))
if escort_until_waypoint is None:
escort_until_waypoint = waypoint
group.task = GroundAttack.name
self._setup_group(group, GroundAttack, client_count)
if escort:
self.escort_targets.append((group, group.points.index(escort_until_waypoint)))
self._rtb_for(group, self.conflict.from_cp, at)
def generate_sead_strikegroup(self, strikegroup: db.PlaneDict, clients: db.PlaneDict, targets: typing.List[typing.Tuple[str, Point]], at: db.StartingPosition, escort=True):
assert not escort or len(self.escort_targets) == 0
for flying_type, count, client_count in self._split_to_groups(strikegroup, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, flying_type),
side=self.conflict.attackers_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location))
escort_until_waypoint = None
for name, pos in targets:
waypoint = group.add_waypoint(pos, 0, WARM_START_AIRSPEED, self.m.translation.create_string(name))
if escort_until_waypoint is None:
escort_until_waypoint = waypoint
group.task = SEAD.name
self._setup_group(group, SEAD, client_count)
if escort:
self.escort_targets.append((group, group.points.index(escort_until_waypoint)))
self._rtb_for(group, self.conflict.from_cp, at)
def generate_defenders_cas(self, defenders: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None, escort=True):
assert not escort or len(self.escort_targets) == 0
for flying_type, count, client_count in self._split_to_groups(defenders, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.defenders_country, self.conflict.to_cp.id, flying_type),
side=self.conflict.defenders_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_defenders_location))
location = self._group_point(self.conflict.air_defenders_location)
insertion_point = self.conflict.find_insertion_point(location)
waypoint = self._add_radio_waypoint(group, insertion_point, CAS_ALTITUDE, WARM_START_AIRSPEED)
if self.conflict.is_vector:
destination_tail = self.conflict.tail.distance_to_point(insertion_point) > self.conflict.position.distance_to_point(insertion_point)
self._add_radio_waypoint(group, destination_tail and self.conflict.tail or self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
group.task = CAS.name
self._setup_group(group, CAS, client_count)
if escort:
self.escort_targets.append((group, group.points.index(waypoint)))
self._rtb_for(group, self.conflict.to_cp, at)
def generate_ship_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, target_groups: typing.Collection[ShipGroup], at: db.StartingPosition = None, escort=True):
assert not escort or len(self.escort_targets) == 0
for flying_type, count, client_count in self._split_to_groups(attackers, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, flying_type),
side=self.conflict.attackers_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location))
wayp = self._add_radio_waypoint(group, self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
for target_group in target_groups:
wayp.tasks.append(AttackGroup(target_group.id))
group.task = AntishipStrike.name
self._setup_group(group, AntishipStrike, client_count)
if escort:
self.escort_targets.append((group, group.points.index(wayp)))
self._rtb_for(group, self.conflict.from_cp, at)
def generate_attackers_escort(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for g in self._generate_escort(
side=self.conflict.attackers_country,
units=attackers,
clients=clients,
at=at and at or self._group_point(self.conflict.air_attackers_location),
is_quick=at is None,
cp=self.conflict.from_cp,
should_orbit=True):
self._rtb_for(g, self.conflict.from_cp, at)
def generate_defenders_escort(self, escort: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for g in self._generate_escort(
side=self.conflict.defenders_country,
units=escort,
clients=clients,
at=at and at or self._group_point(self.conflict.air_defenders_location),
is_quick=at is None,
cp=self.conflict.to_cp,
should_orbit=False):
self._rtb_for(g, self.conflict.to_cp, at)
def generate_defense(self, defenders: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for flying_type, count, client_count in self._split_to_groups(defenders, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.to_cp.id, flying_type),
side=self.conflict.defenders_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_defenders_location))
group.task = CAP.name
wayp = self._add_radio_waypoint(group, self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
wayp.tasks.append(dcs.task.EngageTargets(max_distance=DEFENCE_ENGAGEMENT_MAX_DISTANCE))
wayp.tasks.append(dcs.task.OrbitAction(ATTACK_CIRCLE_ALT, pattern=OrbitAction.OrbitPattern.Circle))
self._setup_group(group, CAP, client_count)
self._rtb_for(group, self.conflict.to_cp, at)
def generate_migcap(self, patrol: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for flying_type, count, client_count in self._split_to_groups(patrol, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, flying_type),
side=self.conflict.attackers_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location))
waypoint = self._add_radio_waypoint(group, self.conflict.position, WARM_START_ALTITUDE, WARM_START_AIRSPEED)
if self.conflict.is_vector:
self._add_radio_waypoint(group, self.conflict.tail, WARM_START_ALTITUDE, WARM_START_AIRSPEED)
group.task = CAP.name
self._setup_group(group, CAP, client_count)
self._rtb_for(group, self.conflict.from_cp, at)
def generate_barcap(self, patrol: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for flying_type, count, client_count in self._split_to_groups(patrol, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, flying_type),
side=self.conflict.defenders_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_defenders_location))
waypoint = self._add_radio_waypoint(group, self.conflict.position, WARM_START_ALTITUDE, WARM_START_AIRSPEED)
if self.conflict.is_vector:
self._add_radio_waypoint(group, self.conflict.tail, WARM_START_ALTITUDE, WARM_START_AIRSPEED)
else:
heading = group.position.heading_between_point(self.conflict.position)
waypoint = self._add_radio_waypoint(group, self.conflict.position.point_from_heading(heading, BARCAP_RACETRACK_DISTANCE),
WARM_START_ALTITUDE,
WARM_START_AIRSPEED)
waypoint.tasks.append(OrbitAction(WARM_START_ALTITUDE, WARM_START_AIRSPEED))
group.task = CAP.name
self._setup_group(group, CAP, client_count)
self._rtb_for(group, self.conflict.to_cp, at)
def generate_transport(self, transport: db.PlaneDict, destination: Airport, escort=True):
assert not escort or len(self.escort_targets) == 0
for flying_type, count, client_count in self._split_to_groups(transport):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, flying_type),
side=self.conflict.defenders_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=self._group_point(self.conflict.air_defenders_location))
waypoint = self._rtb_for(group, self.conflict.to_cp)
if escort:
self.escort_targets.append((group, group.points.index(waypoint)))
self._add_radio_waypoint(group, destination.position, RTB_ALTITUDE)
group.task = Transport.name
group.land_at(destination)
def generate_interception(self, interceptors: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for flying_type, count, client_count in self._split_to_groups(interceptors, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, flying_type),
side=self.conflict.attackers_country,
unit_type=flying_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location))
group.task = CAP.name
group.points[0].tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
wayp = self._add_radio_waypoint(group, self.conflict.position, WARM_START_ALTITUDE, INTERCEPTION_AIRSPEED)
wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
if self.conflict.is_vector:
self._add_radio_waypoint(group, self.conflict.tail, CAS_ALTITUDE, WARM_START_ALTITUDE)
self._setup_group(group, CAP, client_count)
self._rtb_for(group, self.conflict.from_cp, at)
def generate_passenger_transport(self, helis: db.HeliDict, clients: db.HeliDict, at: db.StartingPosition):
for heli_type, count, client_count in self._split_to_groups(helis, clients):
group = self._generate_group(
name=namegen.next_unit_name(self.conflict.attackers_country, self.conflict.from_cp.id, heli_type),
side=self.conflict.attackers_country,
unit_type=heli_type,
count=count,
client_count=client_count,
at=at and at or self._group_point(self.conflict.air_attackers_location)
)
self._add_radio_waypoint(group, self.conflict.position, HELI_ALT)
self._setup_group(group, Transport, client_count)

View File

@@ -32,6 +32,7 @@ class AirSupportConflictGenerator:
def generate(self, is_awacs_enabled):
player_cp = self.conflict.from_cp if self.conflict.from_cp.captured else self.conflict.to_cp
CALLSIGNS = ["TKR", "TEX", "FUL", "FUE", ""]
for i, tanker_unit_type in enumerate(db.find_unittype(Refueling, self.conflict.attackers_side)):
self.generated_tankers.append(db.unit_type_name(tanker_unit_type))
tanker_heading = self.conflict.to_cp.position.heading_between_point(self.conflict.from_cp.position) + TANKER_HEADING_OFFSET * i
@@ -43,27 +44,35 @@ class AirSupportConflictGenerator:
plane_type=tanker_unit_type,
position=tanker_position,
altitude=TANKER_ALT,
race_distance=58000,
frequency=130 + i,
start_type=StartType.Warm,
tacanchannel="{}X".format(97 + i),
speed=574,
tacanchannel="{}X".format(60 + i),
)
tanker_group.points[0].tasks.append(ActivateBeaconCommand(channel=97 + i, unit_id=tanker_group.id, aa=False))
if tanker_unit_type != IL_78M:
tanker_group.points[0].tasks.pop() # Override PyDCS tacan channel
tanker_group.points[0].tasks.append(ActivateBeaconCommand(60 + i, "X", CALLSIGNS[i], True, tanker_group.units[0].id, True))
tanker_group.points[0].tasks.append(SetInvisibleCommand(True))
tanker_group.points[0].tasks.append(SetImmortalCommand(True))
if is_awacs_enabled:
awacs_unit = db.find_unittype(AWACS, self.conflict.attackers_side)[0]
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=133,
start_type=StartType.Warm,
)
try:
awacs_unit = db.find_unittype(AWACS, self.conflict.attackers_side)[0]
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=233,
start_type=StartType.Warm,
)
awacs_flight.points[0].tasks.append(SetInvisibleCommand(True))
awacs_flight.points[0].tasks.append(SetImmortalCommand(True))
except:
print("No AWACS for faction")
awacs_flight.points[0].tasks.append(SetInvisibleCommand(True))
awacs_flight.points[0].tasks.append(SetImmortalCommand(True))

View File

@@ -1,4 +1,7 @@
from dcs.action import AITaskPush, AITaskSet
from dcs.condition import TimeAfter, UnitDamaged, Or, GroupLifeLess
from dcs.task import *
from dcs.triggers import TriggerOnce, Event
from gen import namegen
from gen.ground_forces.ai_ground_planner import CombatGroupRole, DISTANCE_FROM_FRONTLINE
@@ -17,10 +20,12 @@ AGGRESIVE_MOVE_DISTANCE = 16000
FIGHT_DISTANCE = 3500
RANDOM_OFFSET_ATTACK = 250
class GroundConflictGenerator:
def __init__(self, mission: Mission, conflict: Conflict, game, player_planned_combat_groups, enemy_planned_combat_groups, player_stance):
self.m = mission
self.mission = mission
self.conflict = conflict
self.enemy_planned_combat_groups = enemy_planned_combat_groups
self.player_planned_combat_groups = player_planned_combat_groups
@@ -58,7 +63,7 @@ class GroundConflictGenerator:
if final_position is not None:
g = self._generate_group(
side=self.m.country(self.game.player_country),
side=self.mission.country(self.game.player_country),
unit=group.units[0],
heading=self.conflict.heading+90,
count=len(group.units),
@@ -66,7 +71,7 @@ class GroundConflictGenerator:
g.set_skill(self.game.settings.player_skill)
player_groups.append((g,group))
self.gen_infantry_group_for_group(g, True, self.m.country(self.game.player_country), self.conflict.heading + 90)
self.gen_infantry_group_for_group(g, True, self.mission.country(self.game.player_country), self.conflict.heading + 90)
# Create enemy groups at random position
for group in self.enemy_planned_combat_groups:
@@ -78,7 +83,7 @@ class GroundConflictGenerator:
if final_position is not None:
g = self._generate_group(
side=self.m.country(self.game.enemy_country),
side=self.mission.country(self.game.enemy_country),
unit=group.units[0],
heading=self.conflict.heading - 90,
count=len(group.units),
@@ -86,16 +91,33 @@ class GroundConflictGenerator:
g.set_skill(self.game.settings.enemy_vehicle_skill)
enemy_groups.append((g, group))
self.gen_infantry_group_for_group(g, False, self.m.country(self.game.enemy_country), self.conflict.heading - 90)
self.gen_infantry_group_for_group(g, False, self.mission.country(self.game.enemy_country), self.conflict.heading - 90)
# Plan combat actions for groups
self.plan_action_for_groups(self.player_stance, player_groups, enemy_groups, self.conflict.heading + 90, self.conflict.from_cp, self.conflict.to_cp)
self.plan_action_for_groups(self.enemy_stance, enemy_groups, player_groups, self.conflict.heading - 90, self.conflict.to_cp, self.conflict.from_cp)
# Add JTAC
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)
jtac = self.mission.flight_group(country=self.mission.country(self.game.player_country),
name=n,
aircraft_type=MQ_9_Reaper,
position=position[0],
airport=None,
altitude=5000)
jtac.points[0].tasks.append(SetInvisibleCommand(True))
jtac.points[0].tasks.append(SetImmortalCommand(True))
jtac.points[0].tasks.append(OrbitAction(5000, 300, OrbitAction.OrbitPattern.Circle))
self.game.jtacs.append(("Frontline " + self.conflict.from_cp.name + "/" + self.conflict.to_cp.name, code, n))
def gen_infantry_group_for_group(self, group, is_player, side:Country, forward_heading):
# Disable infantry unit gen if disabled
if not self.game.settings.perf_infantry:
return
infantry_position = group.points[0].position.random_point_within(250, 50)
if side == self.conflict.attackers_country:
@@ -113,7 +135,7 @@ class GroundConflictGenerator:
return
u = random.choice(possible_infantry_units)
self.m.vehicle_group(
self.mission.vehicle_group(
side,
namegen.next_infantry_name(side, cp, u), u,
position=infantry_position,
@@ -124,7 +146,7 @@ class GroundConflictGenerator:
for i in range(randint(3, 10)):
u = random.choice(possible_infantry_units)
position = infantry_position.random_point_within(55, 5)
self.m.vehicle_group(
self.mission.vehicle_group(
side,
namegen.next_infantry_name(side, cp, u), u,
position=position,
@@ -135,19 +157,72 @@ class GroundConflictGenerator:
def plan_action_for_groups(self, stance, ally_groups, enemy_groups, forward_heading, from_cp, to_cp):
if not self.game.settings.perf_moving_units:
return
for dcs_group, group in ally_groups:
if group.role == CombatGroupRole.ARTILLERY:
# Fire on any ennemy in range
target = self.get_artillery_target_in_range(dcs_group, group, enemy_groups)
if target is not None:
dcs_group.points[0].tasks.append(FireAtPoint(target, len(group.units) * 10, 100))
if self.game.settings.perf_artillery:
target = self.get_artillery_target_in_range(dcs_group, group, enemy_groups)
if target is not None:
if stance != CombatStance.RETREAT:
hold_task = Hold()
hold_task.number = 1
dcs_group.add_trigger_action(hold_task)
# Artillery strike random start
artillery_trigger = TriggerOnce(Event.NoEvent, "ArtilleryFireTask #" + str(dcs_group.id))
artillery_trigger.add_condition(TimeAfter(seconds=random.randint(1, 45)* 60))
fire_task = FireAtPoint(target, len(group.units) * 10, 100)
if stance != CombatStance.RETREAT:
fire_task.number = 2
else:
fire_task.number = 1
dcs_group.add_trigger_action(fire_task)
artillery_trigger.add_action(AITaskPush(dcs_group.id, len(dcs_group.tasks)))
self.mission.triggerrules.triggers.append(artillery_trigger)
# Artillery will fall back when under attack
if stance != CombatStance.RETREAT:
# Hold position
dcs_group.points[0].tasks.append(Hold())
retreat = self.find_retreat_point(dcs_group, forward_heading, (int)(RETREAT_DISTANCE/3))
dcs_group.add_waypoint(dcs_group.position.point_from_heading(forward_heading, 1), PointAction.OffRoad)
dcs_group.points[1].tasks.append(Hold())
dcs_group.add_waypoint(retreat, PointAction.OffRoad)
artillery_fallback = TriggerOnce(Event.NoEvent, "ArtilleryRetreat #" + str(dcs_group.id))
for i, u in enumerate(dcs_group.units):
artillery_fallback.add_condition(UnitDamaged(u.id))
if i < len(dcs_group.units) - 1:
artillery_fallback.add_condition(Or())
hold_2 = Hold()
hold_2.number = 3
dcs_group.add_trigger_action(hold_2)
retreat_task = GoToWaypoint(toIndex=3)
retreat_task.number = 4
dcs_group.add_trigger_action(retreat_task)
artillery_fallback.add_action(AITaskPush(dcs_group.id, len(dcs_group.tasks)))
self.mission.triggerrules.triggers.append(artillery_fallback)
for u in dcs_group.units:
u.initial = True
u.heading = forward_heading + random.randint(-5,5)
elif group.role in [CombatGroupRole.TANK, CombatGroupRole.IFV]:
if stance == CombatStance.AGGRESIVE:
# Attack nearest enemy if any
# Then move forward OR Attack enemy base if it is not too far away
target = self.find_nearest_enemy_group(dcs_group, enemy_groups)
if target is not None:
rand_offset = Point(random.randint(-50, 50), random.randint(-50, 50))
rand_offset = Point(random.randint(-RANDOM_OFFSET_ATTACK, RANDOM_OFFSET_ATTACK), random.randint(-RANDOM_OFFSET_ATTACK, RANDOM_OFFSET_ATTACK))
dcs_group.add_waypoint(target.points[0].position + rand_offset, PointAction.OffRoad)
dcs_group.points[1].tasks.append(AttackGroup(target.id))
@@ -170,13 +245,17 @@ class GroundConflictGenerator:
targets = self.find_n_nearest_enemy_groups(dcs_group, enemy_groups, 3)
i = 1
for target in targets:
rand_offset = Point(random.randint(-50, 50), random.randint(-50, 50))
dcs_group.add_waypoint(target.points[0].position+rand_offset,PointAction.OffRoad)
rand_offset = Point(random.randint(-RANDOM_OFFSET_ATTACK, RANDOM_OFFSET_ATTACK), random.randint(-RANDOM_OFFSET_ATTACK, RANDOM_OFFSET_ATTACK))
dcs_group.add_waypoint(target.points[0].position+rand_offset, PointAction.OffRoad)
dcs_group.points[i].tasks.append(AttackGroup(target.id))
i = i + 1
if to_cp.position.distance_to_point(dcs_group.points[0].position) <= AGGRESIVE_MOVE_DISTANCE:
attack_point = to_cp.position.random_point_within(500, 0)
dcs_group.add_waypoint(attack_point)
if stance != CombatStance.RETREAT:
self.add_morale_trigger(dcs_group, forward_heading)
elif group.role in [CombatGroupRole.APC, CombatGroupRole.ATGM]:
if stance in [CombatStance.AGGRESIVE, CombatStance.BREAKTHROUGH, CombatStance.ELIMINATION]:
@@ -187,6 +266,9 @@ class GroundConflictGenerator:
attack_point = self.find_offensive_point(dcs_group, forward_heading, AGGRESIVE_MOVE_DISTANCE)
dcs_group.add_waypoint(attack_point, PointAction.OnRoad)
if stance != CombatStance.RETREAT:
self.add_morale_trigger(dcs_group, forward_heading)
if stance == CombatStance.RETREAT:
# In retreat mode, the units will fall back
# If the ally base is close enough, the units will even regroup there
@@ -199,14 +281,51 @@ class GroundConflictGenerator:
dcs_group.add_waypoint(reposition_point, PointAction.OffRoad)
def find_retreat_point(self, dcs_group, frontline_heading):
def add_morale_trigger(self, dcs_group, forward_heading):
"""
This add a trigger to manage units fleeing whenever their group is hit hard, or being engaged by CAS
"""
if len(dcs_group.units) == 1:
return
# Units should hold position on last waypoint
dcs_group.points[len(dcs_group.points) - 1].tasks.append(Hold())
# Force unit heading
for unit in dcs_group.units:
unit.heading = forward_heading
dcs_group.manualHeading = True
# We add a new retreat waypoint
dcs_group.add_waypoint(self.find_retreat_point(dcs_group, forward_heading, (int)(RETREAT_DISTANCE / 8)), PointAction.OffRoad)
# Fallback task
fallback = ControlledTask(GoToWaypoint(toIndex=len(dcs_group.points)))
fallback.enabled = False
dcs_group.add_trigger_action(Hold())
dcs_group.add_trigger_action(fallback)
# Create trigger
fallback = TriggerOnce(Event.NoEvent, "Morale manager #" + str(dcs_group.id))
# Usually more than 50% casualties = RETREAT
fallback.add_condition(GroupLifeLess(dcs_group.id, random.randint(51, 76)))
# Do retreat to the configured retreat waypoint
fallback.add_action(AITaskPush(dcs_group.id, len(dcs_group.tasks)))
self.mission.triggerrules.triggers.append(fallback)
def find_retreat_point(self, dcs_group, frontline_heading, distance=RETREAT_DISTANCE):
"""
Find a point to retreat to
:param dcs_group: DCS mission group we are searching a retreat point for
:param frontline_heading: Heading of the frontline
:return: dcs.mapping.Point object with the desired position
"""
return dcs_group.points[0].position.point_from_heading(frontline_heading-180, RETREAT_DISTANCE)
return dcs_group.points[0].position.point_from_heading(frontline_heading-180, distance)
def find_offensive_point(self, dcs_group, frontline_heading, distance):
"""
@@ -301,7 +420,7 @@ class GroundConflictGenerator:
cp = self.conflict.to_cp
logging.info("armorgen: {} for {}".format(unit, side.id))
group = self.m.vehicle_group(
group = self.mission.vehicle_group(
side,
namegen.next_unit_name(side, cp.id, unit), unit,
position=self._group_point(at),

View File

@@ -24,6 +24,8 @@ class BriefingGenerator:
self.targets = []
self.waypoints = []
self.jtacs = []
def append_frequency(self, name: str, frequency: str):
self.freqs.append((name, frequency))
@@ -39,42 +41,65 @@ class BriefingGenerator:
return
flight_unit_name = db.unit_type_name(flight.unit_type)
self.description += 2 * "\n" + "-" * 50 + "\n"
self.description += "-" * 50 + "\n"
self.description += flight_unit_name + " x " + str(flight.count) + 2 * "\n"
self.description += "#0 -- TAKEOFF : Take off\n"
self.description += "#0 -- TAKEOFF : Take off from " + flight.from_cp.name + "\n"
for i, wpt in enumerate(flight.points):
self.description += "#" + str(1+i) + " -- " + wpt.name + " : " + wpt.description + "\n"
self.description += "#" + str(len(flight.points) + 1) + " -- RTB\n"
self.description += "#" + str(len(flight.points) + 1) + " -- RTB\n\n"
group = flight.group
if group is not None:
for i, nav_target in enumerate(group.nav_target_points):
self.description += nav_target.text_comment + "\n"
self.description += "\n"
self.description += "-" * 50 + "\n"
def add_ally_flight_description(self, flight):
if flight.client_count == 0:
flight_unit_name = db.unit_type_name(flight.unit_type)
self.description += flight.flight_type.name + " " + flight_unit_name + " x " + str(flight.count) + ", departing in " + str(flight.scheduled_in) + " minutes \n"
def generate(self):
self.description = ""
self.description += "DCS Liberation turn #" + str(self.game.turn) + "\n"
self.description += "-"*50 + "\n"
self.description += "=" * 15 + "\n\n"
self.generate_ongoing_war_text()
self.description += "\n"*2
self.description += "Your flights:" + "\n"
self.description += "=" * 15 + "\n\n"
for planner in self.game.planners.values():
for flight in planner.cap_flights:
self.add_flight_description(flight)
for flight in planner.cas_flights:
self.add_flight_description(flight)
for flight in planner.sead_flights:
for flight in planner.flights:
self.add_flight_description(flight)
self.description += "\n"*2
self.description += "Planned ally flights:" + "\n"
self.description += "=" * 15 + "\n"
for planner in self.game.planners.values():
if planner.from_cp.captured and len(planner.flights) > 0:
self.description += "\nFrom " + planner.from_cp.full_name + " \n"
self.description += "-" * 50 + "\n\n"
for flight in planner.flights:
self.add_ally_flight_description(flight)
if self.freqs:
self.description += "\n\nComms Frequencies:\n"
self.description += "-" * 50 + "\n"
self.description += "=" * 15 + "\n"
for name, freq in self.freqs:
self.description += "\n{}: {}".format(name, freq)
self.description += "{}: {}\n".format(name, freq)
self.description += ("-" * 50) + "\n"
for cp in self.game.theater.controlpoints:
if cp.captured and cp.cptype in [ControlPointType.LHA_GROUP, ControlPointType.AIRCRAFT_CARRIER_GROUP]:
self.description += "\n"
self.description += cp.name + " TACAN : "
self.description += cp.name + "\n"
self.description += "RADIO : 127.5 Mhz AM\n"
self.description += "TACAN : "
self.description += str(cp.tacanN)
if cp.tacanY:
self.description += "Y"
@@ -82,7 +107,84 @@ class BriefingGenerator:
self.description += "X"
self.description += " " + str(cp.tacanI) + "\n"
if cp.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP and hasattr(cp, "icls"):
self.description += "ICLS Channel : " + str(cp.icls) + "\n"
self.description += "-" * 50 + "\n"
self.description += "JTACS [F-10 Menu] : \n"
self.description += "===================\n\n"
for jtac in self.game.jtacs:
self.description += str(jtac[0]) + " -- Code : " + str(jtac[1]) + "\n"
self.m.set_description_text(self.description)
self.m.add_picture_blue(os.path.abspath("./resources/ui/splash_screen.png"))
def generate_ongoing_war_text(self):
self.description += "Current situation:\n"
self.description += "=" * 15 + "\n\n"
conflict_number = 0
for c in self.game.theater.conflicts():
conflict_number = conflict_number + 1
if c[0].captured:
player_base = c[0]
enemy_base = c[1]
else:
player_base = c[1]
enemy_base = c[0]
has_numerical_superiority = player_base.base.total_armor > enemy_base.base.total_armor
self.description += self.__random_frontline_sentence(player_base.name, enemy_base.name)
if enemy_base.id in player_base.stances.keys():
stance = player_base.stances[enemy_base.id]
if player_base.base.total_armor == 0:
self.description += "We do not have a single vehicle available to hold our position, the situation is critical, and we will lose ground inevitably.\n"
elif enemy_base.base.total_armor == 0:
self.description += "The enemy forces have been crushed, we will be able to make significant progress toward " + enemy_base.name + ". \n"
if stance == CombatStance.AGGRESIVE:
if has_numerical_superiority:
self.description += "On this location, our ground forces will try to make progress against the enemy"
self.description += ". As the enemy is outnumbered, our forces should have no issue making progress.\n"
elif has_numerical_superiority:
self.description += "On this location, our ground forces will try an audacious assault against enemies in superior numbers. The operation is risky, and the enemy might counter attack.\n"
elif stance == CombatStance.ELIMINATION:
if has_numerical_superiority:
self.description += "On this location, our ground forces will focus on the destruction of enemy assets, before attempting to make progress toward " + enemy_base.name + ". "
self.description += "The enemy is already outnumbered, and this maneuver might draw a final blow to their forces.\n"
elif has_numerical_superiority:
self.description += "On this location, our ground forces will try an audacious assault against enemies in superior numbers. The operation is risky, and the enemy might counter attack.\n"
elif stance == CombatStance.BREAKTHROUGH:
if has_numerical_superiority:
self.description += "On this location, our ground forces will focus on progression toward " + enemy_base.name + ".\n"
elif has_numerical_superiority:
self.description += "On this location, our ground forces have been ordered to rush toward " + enemy_base.name + ". Wish them luck... We are also expecting a counter attack.\n"
elif stance in [CombatStance.DEFENSIVE, CombatStance.AMBUSH]:
if has_numerical_superiority:
self.description += "On this location, our ground forces will hold position. We are not expecting an enemy assault.\n"
elif has_numerical_superiority:
self.description += "On this location, our ground forces have been ordered to hold still, and defend against enemy attacks. An enemy assault might be iminent.\n"
if conflict_number == 0:
self.description += "There are currently no fights on the ground.\n"
self.description += "\n\n"
def __random_frontline_sentence(self, player_base_name, enemy_base_name):
templates = [
"There are combats between {} and {}. ",
"The war on the ground is still going on between {} an {}. ",
"Our ground forces in {} are opposed to enemy forces based in {}. ",
"Our forces from {} are fighting enemies based in {}. ",
"There is an active frontline between {} and {}. ",
]
return random.choice(templates).format(player_base_name, enemy_base_name)

View File

@@ -172,13 +172,6 @@ class Conflict:
position = middle_point.point_from_heading(attack_heading, strength_delta * attack_distance / 2 - FRONTLINE_MIN_CP_DISTANCE)
return position, _opposite_heading(attack_heading)
ground_position = cls._find_ground_position(position, attack_distance / 2 - FRONTLINE_MIN_CP_DISTANCE, attack_heading, theater)
if ground_position:
return ground_position, _opposite_heading(attack_heading)
else:
logging.warning("Coudn't find frontline position between {} and {}!".format(from_cp, to_cp))
return position, _opposite_heading(attack_heading)
@classmethod
def frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> typing.Optional[typing.Tuple[Point, int, int]]:

View File

@@ -61,12 +61,14 @@ class EnviromentGenerator:
logging.info("Skip Night mission due to user settings")
if daytime == "dawn":
time_range = (8, 9)
elif daytime == "noon":
elif daytime == "day":
time_range = (10, 12)
elif daytime == "dusk":
time_range = (12, 14)
elif daytime == "night":
time_range = (14, 17)
else:
time_range = (10, 12)
else:
time_range = self.game.theater.daytime_map[daytime]
@@ -113,7 +115,7 @@ class EnviromentGenerator:
if weather_type == 1:
# thunderstorm
self._generate_base_weather()
self._generate_wind(random.randint(8, 12))
self._generate_wind(random.randint(0, 8))
self.mission.weather.clouds_density = random.randint(9, 10)
self.mission.weather.clouds_iprecptns = Weather.Preceptions.Thunderstorm
@@ -123,7 +125,7 @@ class EnviromentGenerator:
self.mission.weather.clouds_density = random.randint(5, 8)
self.mission.weather.clouds_iprecptns = Weather.Preceptions.Rain
self._generate_wind(random.randint(4, 8))
self._generate_wind(random.randint(0, 6))
elif weather_type == 3:
# clouds
self._generate_base_weather()

View File

@@ -23,11 +23,12 @@ class CarrierGroupGenerator(GroupGenerator):
return
# Add destroyers escort
dd_type = random.choice(self.faction["destroyer"])
self.add_unit(dd_type, "DD1", self.position.x + 250, self.position.y + 450, self.heading)
self.add_unit(dd_type, "DD2", self.position.x + 250, self.position.y - 450, self.heading)
if "destroyer" in self.faction.keys():
dd_type = random.choice(self.faction["destroyer"])
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 + 450, self.position.y + 850, self.heading)
self.add_unit(dd_type, "DD4", self.position.x + 450, self.position.y - 850, 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

42
gen/fleet/cn_dd_group.py Normal file
View File

@@ -0,0 +1,42 @@
import random
from gen.fleet.dd_group import DDGroupGenerator
from gen.sam.group_generator import GroupGenerator
from dcs.ships import *
class ChineseNavyGroupGenerator(GroupGenerator):
def __init__(self, game, ground_object, faction):
super(ChineseNavyGroupGenerator, self).__init__(game, ground_object)
self.faction = faction
def generate(self):
include_frigate = random.choice([True, True, False])
include_dd = random.choice([True, False])
if include_dd:
include_cc = random.choice([True, False])
else:
include_cc = False
if include_frigate:
self.add_unit(Type_054A_Frigate, "FF1", self.position.x + 1200, self.position.y + 900, self.heading)
self.add_unit(Type_054A_Frigate, "FF2", self.position.x + 1200, self.position.y - 900, self.heading)
if include_dd:
dd_type = random.choice([Type_052C_Destroyer, Type_052B_Destroyer])
self.add_unit(dd_type, "FF1", self.position.x + 2400, self.position.y + 900, self.heading)
self.add_unit(dd_type, "FF2", self.position.x + 2400, self.position.y - 900, self.heading)
if include_cc:
cc_type = random.choice([CGN_1144_2_Pyotr_Velikiy])
self.add_unit(cc_type, "CC1", self.position.x, self.position.y, self.heading)
self.get_generated_group().points[0].speed = 20
class Type54GroupGenerator(DDGroupGenerator):
def __init__(self, game, ground_object, faction):
super(Type54GroupGenerator, self).__init__(game, ground_object, faction, Type_054A_Frigate)

27
gen/fleet/dd_group.py Normal file
View File

@@ -0,0 +1,27 @@
import random
from gen.sam.group_generator import GroupGenerator
from dcs.ships import *
class DDGroupGenerator(GroupGenerator):
def __init__(self, game, ground_object, faction, ddtype):
super(DDGroupGenerator, self).__init__(game, ground_object)
self.faction = faction
self.ddtype = ddtype
def generate(self):
self.add_unit(self.ddtype, "DD1", self.position.x + 500, self.position.y + 900, self.heading)
self.add_unit(self.ddtype, "DD2", self.position.x + 500, self.position.y - 900, self.heading)
self.get_generated_group().points[0].speed = 20
class OliverHazardPerryGroupGenerator(DDGroupGenerator):
def __init__(self, game, ground_object, faction):
super(OliverHazardPerryGroupGenerator, self).__init__(game, ground_object, faction, Oliver_Hazzard_Perry_class)
class ArleighBurkeGroupGenerator(DDGroupGenerator):
def __init__(self, game, ground_object, faction):
super(ArleighBurkeGroupGenerator, self).__init__(game, ground_object, faction, USS_Arleigh_Burke_IIa)

View File

@@ -19,7 +19,7 @@ class LHAGroupGenerator(GroupGenerator):
# Add destroyers escort
if "destroyer" in self.faction.keys():
dd_type = random.choice(self.faction["destroyer"])
self.add_unit(dd_type, "DD1", self.position.x + 250, self.position.y + 450, self.heading)
self.add_unit(dd_type, "DD2", self.position.x + 250, self.position.y - 450, self.heading)
self.add_unit(dd_type, "DD1", self.position.x + 1250, self.position.y + 1450, self.heading)
self.add_unit(dd_type, "DD2", self.position.x + 1250, self.position.y - 1450, self.heading)
self.get_generated_group().points[0].speed = 20

59
gen/fleet/ru_dd_group.py Normal file
View File

@@ -0,0 +1,59 @@
import random
from gen.fleet.dd_group import DDGroupGenerator
from gen.sam.group_generator import GroupGenerator
from dcs.ships import *
class RussianNavyGroupGenerator(GroupGenerator):
def __init__(self, game, ground_object, faction):
super(RussianNavyGroupGenerator, self).__init__(game, ground_object)
self.faction = faction
def generate(self):
include_frigate = random.choice([True, True, False])
include_dd = random.choice([True, False])
if include_dd:
include_cc = random.choice([True, False])
else:
include_cc = False
if include_frigate:
frigate_type = random.choice([FFL_1124_4_Grisha, FSG_1241_1MP_Molniya])
self.add_unit(frigate_type, "FF1", self.position.x + 1200, self.position.y + 900, self.heading)
self.add_unit(frigate_type, "FF2", self.position.x + 1200, self.position.y - 900, self.heading)
if include_dd:
dd_type = random.choice([FFG_11540_Neustrashimy, FF_1135M_Rezky])
self.add_unit(dd_type, "FF1", self.position.x + 2400, self.position.y + 900, self.heading)
self.add_unit(dd_type, "FF2", self.position.x + 2400, self.position.y - 900, self.heading)
if include_cc:
cc_type = random.choice([CG_1164_Moskva, CGN_1144_2_Pyotr_Velikiy])
self.add_unit(cc_type, "CC1", self.position.x, self.position.y, self.heading)
self.get_generated_group().points[0].speed = 20
class GrishaGroupGenerator(DDGroupGenerator):
def __init__(self, game, ground_object, faction):
super(GrishaGroupGenerator, self).__init__(game, ground_object, faction, FFL_1124_4_Grisha)
class MolniyaGroupGenerator(DDGroupGenerator):
def __init__(self, game, ground_object, faction):
super(MolniyaGroupGenerator, self).__init__(game, ground_object, faction, FSG_1241_1MP_Molniya)
class KiloSubGroupGenerator(DDGroupGenerator):
def __init__(self, game, ground_object, faction):
super(KiloSubGroupGenerator, self).__init__(game, ground_object, faction, SSK_877)
class TangoSubGroupGenerator(DDGroupGenerator):
def __init__(self, game, ground_object, faction):
super(TangoSubGroupGenerator, self).__init__(game, ground_object, faction, SSK_641B)

19
gen/fleet/schnellboot.py Normal file
View File

@@ -0,0 +1,19 @@
import random
from dcs.ships import Schnellboot_type_S130
from gen.sam.group_generator import GroupGenerator
class SchnellbootGroupGenerator(GroupGenerator):
def __init__(self, game, ground_object, faction):
super(SchnellbootGroupGenerator, self).__init__(game, ground_object)
self.faction = faction
def generate(self):
for i in range(random.randint(2, 4)):
self.add_unit(Schnellboot_type_S130, "Schnellboot" + str(i), self.position.x + i * random.randint(100, 250), self.position.y + (random.randint(100, 200)-100), self.heading)
self.get_generated_group().points[0].speed = 20

View File

@@ -1,6 +1,50 @@
import logging
import random
from game import db
from gen.fleet.carrier_group import CarrierGroupGenerator
from gen.fleet.cn_dd_group import ChineseNavyGroupGenerator, Type54GroupGenerator
from gen.fleet.dd_group import ArleighBurkeGroupGenerator, OliverHazardPerryGroupGenerator
from gen.fleet.lha_group import LHAGroupGenerator
from gen.fleet.ru_dd_group import RussianNavyGroupGenerator, GrishaGroupGenerator, MolniyaGroupGenerator, \
KiloSubGroupGenerator, TangoSubGroupGenerator
from gen.fleet.schnellboot import SchnellbootGroupGenerator
from gen.fleet.uboat import UBoatGroupGenerator
from gen.fleet.ww2lst import WW2LSTGroupGenerator
SHIP_MAP = {
"SchnellbootGroupGenerator": SchnellbootGroupGenerator,
"WW2LSTGroupGenerator": WW2LSTGroupGenerator,
"UBoatGroupGenerator": UBoatGroupGenerator,
"OliverHazardPerryGroupGenerator": OliverHazardPerryGroupGenerator,
"ArleighBurkeGroupGenerator": ArleighBurkeGroupGenerator,
"RussianNavyGroupGenerator": RussianNavyGroupGenerator,
"ChineseNavyGroupGenerator": ChineseNavyGroupGenerator,
"GrishaGroupGenerator": GrishaGroupGenerator,
"MolniyaGroupGenerator": MolniyaGroupGenerator,
"KiloSubGroupGenerator": KiloSubGroupGenerator,
"TangoSubGroupGenerator": TangoSubGroupGenerator,
"Type54GroupGenerator": Type54GroupGenerator
}
def generate_ship_group(game, ground_object, faction:str):
"""
This generate a ship group
:return: Nothing, but put the group reference inside the ground object
"""
faction = db.FACTIONS[faction]
if "boat" in faction.keys():
generators = faction["boat"]
if len(generators) > 0:
gen = random.choice(generators)
if gen in SHIP_MAP.keys():
generator = SHIP_MAP[gen](game, ground_object, faction)
generator.generate()
return generator.get_generated_group()
else:
logging.info("Unable to generate ship group, generator : " + str(gen) + "does not exists")
return None
def generate_carrier_group(faction:str, game, ground_object):

19
gen/fleet/uboat.py Normal file
View File

@@ -0,0 +1,19 @@
import random
from dcs.ships import Uboat_VIIC_U_flak
from gen.sam.group_generator import GroupGenerator
class UBoatGroupGenerator(GroupGenerator):
def __init__(self, game, ground_object, faction):
super(UBoatGroupGenerator, self).__init__(game, ground_object)
self.faction = faction
def generate(self):
for i in range(random.randint(1, 4)):
self.add_unit(Uboat_VIIC_U_flak, "Uboat" + str(i), self.position.x + i * random.randint(100, 250), self.position.y + (random.randint(100, 200)-100), self.heading)
self.get_generated_group().points[0].speed = 20

22
gen/fleet/ww2lst.py Normal file
View File

@@ -0,0 +1,22 @@
import random
from dcs.ships import LS_Samuel_Chase, LST_Mk_II
from gen.sam.group_generator import GroupGenerator
class WW2LSTGroupGenerator(GroupGenerator):
def __init__(self, game, ground_object, faction):
super(WW2LSTGroupGenerator, self).__init__(game, ground_object)
self.faction = faction
def generate(self):
# Add LS Samuel Chase
self.add_unit(LS_Samuel_Chase, "SamuelChase", self.position.x, self.position.y, self.heading)
for i in range(1, random.randint(3, 4)):
self.add_unit(LST_Mk_II, "LST" + str(i), self.position.x + i * random.randint(800, 1200), self.position.y, self.heading)
self.get_generated_group().points[0].speed = 20

View File

@@ -1,22 +1,17 @@
import math
import operator
import typing
import random
from game import db
from game.data.doctrine import MODERN_DOCTRINE
from game.data.radar_db import UNITS_WITH_RADAR
from game.utils import meter_to_feet, nm_to_meter
from gen import Conflict
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE
from gen.flights.flight import Flight, FlightType, FlightWaypoint
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE, STRIKE_CAPABLE
from gen.flights.flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
# TODO : Ideally should be based on the aircraft type instead / Availability of fuel
STRIKE_MAX_RANGE = 1500000
SEAD_MAX_RANGE = 1500000
MAX_NUMBER_OF_INTERCEPTION_GROUP = 3
MISSION_DURATION = 120 # in minutes
CAP_EVERY_X_MINUTES = 20
CAS_EVERY_X_MINUTES = 30
SEAD_EVERY_X_MINUTES = 40
MISSION_DURATION = 80
class FlightPlanner:
@@ -28,6 +23,17 @@ class FlightPlanner:
self.game = game
self.aircraft_inventory = {} # local copy of the airbase inventory
if from_cp.captured:
self.faction = self.game.player_faction
else:
self.faction = self.game.enemy_faction
if "doctrine" in self.faction.keys():
self.doctrine = self.faction["doctrine"]
else:
self.doctrine = MODERN_DOCTRINE
def reset(self):
"""
Reset the planned flights and available units
@@ -50,10 +56,10 @@ class FlightPlanner:
self.compute_strike_targets()
# The priority is to assign air-superiority fighter or interceptor to interception roles, so they can scramble if there is an attacker
#self.commision_interceptors()
# self.commision_interceptors()
# Then some CAP patrol for the next 2 hours
self.commision_barcap()
self.commision_cap()
# Then setup cas
self.commision_cas()
@@ -61,7 +67,9 @@ class FlightPlanner:
# Then prepare some sead flights if required
self.commision_sead()
# TODO : commision STRIKE / ANTISHIP
self.commision_strike()
# TODO : commision ANTISHIP
def remove_flight(self, index):
try:
@@ -83,7 +91,7 @@ class FlightPlanner:
"""
# At least try to generate one interceptor group
number_of_interceptor_groups = min(max(sum([v for k, v in self.aircraft_inventory.items()]) / 4, MAX_NUMBER_OF_INTERCEPTION_GROUP), 1)
number_of_interceptor_groups = min(max(sum([v for k, v in self.aircraft_inventory.items()]) / 4, self.doctrine["MAX_NUMBER_OF_INTERCEPTION_GROUP"]), 1)
possible_interceptors = [k for k in self.aircraft_inventory.keys() if k in INTERCEPT_CAPABLE]
if len(possible_interceptors) <= 0:
@@ -98,6 +106,7 @@ class FlightPlanner:
break
inventory[unit] = inventory[unit] - 2
flight = Flight(unit, 2, self.from_cp, FlightType.INTERCEPTION)
flight.scheduled_in = 1
flight.points = []
self.interceptor_flights.append(flight)
@@ -107,7 +116,7 @@ class FlightPlanner:
for k, v in inventory.items():
self.aircraft_inventory[k] = v
def commision_barcap(self):
def commision_cap(self):
"""
Pick some aircraft to assign them to defensive CAP roles (BARCAP)
"""
@@ -116,7 +125,7 @@ class FlightPlanner:
inventory = dict({k: v for k, v in self.aircraft_inventory.items() if k in possible_aircraft})
offset = random.randint(0,5)
for i in range(int(MISSION_DURATION/CAP_EVERY_X_MINUTES)):
for i in range(int(MISSION_DURATION/self.doctrine["CAP_EVERY_X_MINUTES"])):
try:
unit = random.choice([k for k, v in inventory.items() if v >= 2])
@@ -124,32 +133,16 @@ class FlightPlanner:
break
inventory[unit] = inventory[unit] - 2
flight = Flight(unit, 2, self.from_cp, FlightType.BARCAP)
flight = Flight(unit, 2, self.from_cp, FlightType.CAP)
# Flight path : fly over each ground object (TODO : improve)
flight.points = []
flight.scheduled_in = offset + i*random.randint(CAP_EVERY_X_MINUTES-5, CAP_EVERY_X_MINUTES+5)
flight.scheduled_in = offset + i*random.randint(self.doctrine["CAP_EVERY_X_MINUTES"] - 5, self.doctrine["CAP_EVERY_X_MINUTES"] + 5)
patrol_alt = random.randint(3600, 7000)
patrolled = []
for ground_object in self.from_cp.ground_objects:
if ground_object.group_id not in patrolled and not ground_object.airbase_group:
point = FlightWaypoint(ground_object.position.x, ground_object.position.y, patrol_alt)
point.name = "Patrol point"
point.description = "Patrol #" + str(len(flight.points))
point.pretty_name = "Patrol #" + str(len(flight.points))
flight.points.append(point)
patrolled.append(ground_object.group_id)
if len(flight.points) == 0:
for i in range(3):
pos = self.from_cp.position.point_from_heading(random.randint(0,360), random.randint(30000, 80000))
point = FlightWaypoint(pos.x, pos.y, patrol_alt)
point.name = "Patrol point"
point.description = "Patrol #" + str(len(flight.points))
point.pretty_name = "Patrol #" + str(len(flight.points))
flight.points.append(point)
if len(self._get_cas_locations()) > 0:
enemy_cp = random.choice(self._get_cas_locations())
self.generate_frontline_cap(flight, flight.from_cp, enemy_cp)
else:
self.generate_barcap(flight, flight.from_cp)
self.cap_flights.append(flight)
self.flights.append(flight)
@@ -170,7 +163,7 @@ class FlightPlanner:
if len(cas_location) > 0:
offset = random.randint(0,5)
for i in range(int(MISSION_DURATION/CAS_EVERY_X_MINUTES)):
for i in range(int(MISSION_DURATION/self.doctrine["CAS_EVERY_X_MINUTES"])):
try:
unit = random.choice([k for k, v in inventory.items() if v >= 2])
@@ -179,34 +172,11 @@ class FlightPlanner:
inventory[unit] = inventory[unit] - 2
flight = Flight(unit, 2, self.from_cp, FlightType.CAS)
flight.points = []
flight.scheduled_in = offset + i*random.randint(CAS_EVERY_X_MINUTES-5, CAS_EVERY_X_MINUTES+5)
flight.scheduled_in = offset + i * random.randint(self.doctrine["CAS_EVERY_X_MINUTES"] - 5, self.doctrine["CAS_EVERY_X_MINUTES"] + 5)
location = random.choice(cas_location)
ingress, heading, distance = Conflict.frontline_vector(self.from_cp, location, self.game.theater)
center = ingress.point_from_heading(heading, distance/2)
egress = ingress.point_from_heading(heading, distance)
flight.targets.append(center)
ingress_point = FlightWaypoint(ingress.x, ingress.y, 1000)
ingress_point.name = "INGRESS"
ingress_point.pretty_name = "INGRESS"
ingress_point.description = "Ingress into CAS area"
flight.points.append(ingress_point)
center_point = FlightWaypoint(center.x, center.y, 1000)
center_point.description = "Provide CAS"
center_point.name = "CAS"
center_point.pretty_name = "INGRESS"
flight.points.append(center_point)
egress_point = FlightWaypoint(egress.x, egress.y, 1000)
egress_point.description = "Egress from CAS area"
egress_point.name = "EGRESS"
egress_point.pretty_name = "EGRESS"
flight.points.append(egress_point)
self.generate_cas(flight, flight.from_cp, location)
self.cas_flights.append(flight)
self.flights.append(flight)
@@ -226,7 +196,7 @@ class FlightPlanner:
if len(self.potential_sead_targets) > 0:
offset = random.randint(0,5)
for i in range(int(MISSION_DURATION/SEAD_EVERY_X_MINUTES)):
for i in range(int(MISSION_DURATION/self.doctrine["SEAD_EVERY_X_MINUTES"])):
if len(self.potential_sead_targets) <= 0:
break
@@ -240,16 +210,12 @@ class FlightPlanner:
flight = Flight(unit, 2, self.from_cp, random.choice([FlightType.SEAD, FlightType.DEAD]))
flight.points = []
flight.scheduled_in = offset + i*random.randint(SEAD_EVERY_X_MINUTES-5, SEAD_EVERY_X_MINUTES+5)
flight.scheduled_in = offset + i*random.randint(self.doctrine["SEAD_EVERY_X_MINUTES"] - 5, self.doctrine["SEAD_EVERY_X_MINUTES"] + 5)
location = self.potential_sead_targets[0][0]
self.potential_sead_targets.pop(0)
point = FlightWaypoint(location.position.x, location.position.y, 1000)
point.description = "SEAD"
point.pretty_name = "SEAD"
point.targets.append(location)
flight.points.append(point)
self.generate_sead(flight, location, [])
self.sead_flights.append(flight)
self.flights.append(flight)
@@ -258,10 +224,52 @@ class FlightPlanner:
for k, v in inventory.items():
self.aircraft_inventory[k] = v
def commision_strike(self):
"""
Pick some aircraft to assign them to STRIKE tasks
"""
possible_aircraft = [k for k, v in self.aircraft_inventory.items() if k in STRIKE_CAPABLE and v >= 2]
inventory = dict({k: v for k, v in self.aircraft_inventory.items() if k in possible_aircraft})
if len(self.potential_strike_targets) > 0:
offset = random.randint(0,5)
for i in range(int(MISSION_DURATION/self.doctrine["STRIKE_EVERY_X_MINUTES"])):
if len(self.potential_strike_targets) <= 0:
break
try:
unit = random.choice([k for k, v in inventory.items() if v >= 2])
except IndexError:
break
inventory[unit] = inventory[unit] - 2
flight = Flight(unit, 2, self.from_cp, FlightType.STRIKE)
flight.points = []
flight.scheduled_in = offset + i*random.randint(self.doctrine["STRIKE_EVERY_X_MINUTES"] - 5, self.doctrine["STRIKE_EVERY_X_MINUTES"] + 5)
location = self.potential_strike_targets[0][0]
self.potential_strike_targets.pop(0)
self.generate_strike(flight, location)
self.strike_flights.append(flight)
self.flights.append(flight)
# Update inventory
for k, v in inventory.items():
self.aircraft_inventory[k] = v
def _get_cas_locations(self):
return self._get_cas_locations_for_cp(self.from_cp)
def _get_cas_locations_for_cp(self, for_cp):
cas_locations = []
for cp in self.from_cp.connected_points:
if cp.captured != self.from_cp.captured:
for cp in for_cp.connected_points:
if cp.captured != for_cp.captured:
cas_locations.append(cp)
return cas_locations
@@ -279,19 +287,19 @@ class FlightPlanner:
distance = math.hypot(cp.position.x - self.from_cp.position.x,
cp.position.y - self.from_cp.position.y)
if distance > 2*STRIKE_MAX_RANGE:
if distance > 2*self.doctrine["STRIKE_MAX_RANGE"]:
# Then it's unlikely any child ground object is in range
return
added_group = []
for g in cp.ground_objects:
if g.group_id in added_group: continue
if g.group_id in added_group or g.is_dead: continue
# Compute distance to current cp
distance = math.hypot(cp.position.x - self.from_cp.position.x,
cp.position.y - self.from_cp.position.y)
if distance < SEAD_MAX_RANGE:
if distance < self.doctrine["SEAD_MAX_RANGE"]:
self.potential_strike_targets.append((g, distance))
added_group.append(g)
@@ -312,7 +320,7 @@ class FlightPlanner:
cp.position.y - self.from_cp.position.y)
# Then it's unlikely any ground object is range
if distance > 2*SEAD_MAX_RANGE:
if distance > 2*self.doctrine["SEAD_MAX_RANGE"]:
return
for g in cp.ground_objects:
@@ -320,8 +328,7 @@ class FlightPlanner:
if g.dcs_identifier == "AA":
# Check that there is at least one unit with a radar in the ground objects unit groups
number_of_units = sum([len([r for r in group.units if hasattr(db.unit_type_from_name(r.type), "detection_range")
and db.unit_type_from_name(r.type).detection_range > 1000]) for group in g.groups])
number_of_units = sum([len([r for r in group.units if db.unit_type_from_name(r.type) in UNITS_WITH_RADAR]) for group in g.groups])
if number_of_units <= 0:
continue
@@ -329,7 +336,7 @@ class FlightPlanner:
distance = math.hypot(cp.position.x - self.from_cp.position.x,
cp.position.y - self.from_cp.position.y)
if distance < SEAD_MAX_RANGE:
if distance < self.doctrine["SEAD_MAX_RANGE"]:
self.potential_sead_targets.append((g, distance))
self.potential_sead_targets.sort(key=operator.itemgetter(1))
@@ -347,3 +354,346 @@ class FlightPlanner:
del base_aircraft_inventory[f.unit_type]
return base_aircraft_inventory
def generate_strike(self, flight, location):
flight.flight_type = FlightType.STRIKE
ascend = self.generate_ascend_point(flight.from_cp)
flight.points.append(ascend)
heading = flight.from_cp.position.heading_between_point(location.position)
ingress_heading = heading - 180 + 25
egress_heading = heading - 180 - 25
ingress_pos = location.position.point_from_heading(ingress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"])
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, self.doctrine["INGRESS_ALT"])
ingress_point.pretty_name = "INGRESS on " + location.obj_name
ingress_point.description = "INGRESS on " + location.obj_name
ingress_point.name = "INGRESS"
ingress_point.waypoint_type = FlightWaypointType.INGRESS_STRIKE
flight.points.append(ingress_point)
if len(location.groups) > 0 and location.dcs_identifier == "AA":
for g in location.groups:
for j, u in enumerate(g.units):
point = FlightWaypoint(u.position.x, u.position.y, 0)
point.description = "STRIKE " + "[" + str(location.obj_name) + "] : " + u.type + " #" + str(j)
point.pretty_name = "STRIKE " + "[" + str(location.obj_name) + "] : " + u.type + " #" + str(j)
point.name = location.obj_name + "#" + str(j)
point.only_for_player = True
ingress_point.targets.append(location)
flight.points.append(point)
else:
if hasattr(location, "obj_name"):
buildings = self.game.theater.find_ground_objects_by_obj_name(location.obj_name)
print(buildings)
for building in buildings:
print("BUILDING " + str(building.is_dead) + " " + str(building.dcs_identifier))
if building.is_dead:
continue
point = FlightWaypoint(building.position.x, building.position.y, 0)
point.description = "STRIKE on " + building.obj_name + " " + building.category + " [" + str(building.dcs_identifier) + " ]"
point.pretty_name = "STRIKE on " + building.obj_name + " " + building.category + " [" + str(building.dcs_identifier) + " ]"
point.name = building.obj_name
point.only_for_player = True
ingress_point.targets.append(building)
flight.points.append(point)
else:
point = FlightWaypoint(location.position.x, location.position.y, 0)
point.description = "STRIKE on " + location.obj_name
point.pretty_name = "STRIKE on " + location.obj_name
point.name = location.obj_name
point.only_for_player = True
ingress_point.targets.append(location)
flight.points.append(point)
egress_pos = location.position.point_from_heading(egress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"])
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, self.doctrine["EGRESS_ALT"])
egress_point.name = "EGRESS"
egress_point.pretty_name = "EGRESS from " + location.obj_name
egress_point.description = "EGRESS from " + location.obj_name
egress_point.waypoint_type = FlightWaypointType.EGRESS
flight.points.append(egress_point)
descend = self.generate_descend_point(flight.from_cp)
flight.points.append(descend)
rtb = self.generate_rtb_waypoint(flight.from_cp)
flight.points.append(rtb)
def generate_barcap(self, flight, for_cp):
"""
Generate a barcap flight at a given location
:param flight: Flight to setup
:param for_cp: CP to protect
"""
flight.flight_type = FlightType.BARCAP if for_cp.is_carrier else FlightType.CAP
patrol_alt = random.randint(self.doctrine["PATROL_ALT_RANGE"][0], self.doctrine["PATROL_ALT_RANGE"][1])
if len(for_cp.ground_objects) > 0:
loc = random.choice(for_cp.ground_objects)
hdg = for_cp.position.heading_between_point(loc.position)
radius = random.randint(self.doctrine["CAP_PATTERN_LENGTH"][0], self.doctrine["CAP_PATTERN_LENGTH"][1])
orbit0p = loc.position.point_from_heading(hdg - 90, radius)
orbit1p = loc.position.point_from_heading(hdg + 90, radius)
else:
loc = for_cp.position.point_from_heading(random.randint(0, 360), random.randint(self.doctrine["CAP_DISTANCE_FROM_CP"][0], self.doctrine["CAP_DISTANCE_FROM_CP"][1]))
hdg = for_cp.position.heading_between_point(loc)
radius = random.randint(self.doctrine["CAP_PATTERN_LENGTH"][0], self.doctrine["CAP_PATTERN_LENGTH"][1])
orbit0p = loc.point_from_heading(hdg - 90, radius)
orbit1p = loc.point_from_heading(hdg + 90, radius)
# Create points
ascend = self.generate_ascend_point(flight.from_cp)
flight.points.append(ascend)
orbit0 = FlightWaypoint(orbit0p.x, orbit0p.y, patrol_alt)
orbit0.name = "ORBIT 0"
orbit0.description = "Standby between this point and the next one"
orbit0.pretty_name = "Race-track start"
orbit0.waypoint_type = FlightWaypointType.PATROL_TRACK
flight.points.append(orbit0)
orbit1 = FlightWaypoint(orbit1p.x, orbit1p.y, patrol_alt)
orbit1.name = "ORBIT 1"
orbit1.description = "Standby between this point and the previous one"
orbit1.pretty_name = "Race-track end"
orbit1.waypoint_type = FlightWaypointType.PATROL
flight.points.append(orbit1)
orbit0.targets.append(for_cp)
obj_added = []
for ground_object in for_cp.ground_objects:
if ground_object.obj_name not in obj_added and not ground_object.airbase_group:
orbit0.targets.append(ground_object)
obj_added.append(ground_object.obj_name)
descend = self.generate_descend_point(flight.from_cp)
flight.points.append(descend)
rtb = self.generate_rtb_waypoint(flight.from_cp)
flight.points.append(rtb)
def generate_frontline_cap(self, flight, ally_cp, enemy_cp):
"""
Generate a cap flight for the frontline between ally_cp and enemy cp in order to ensure air superiority and
protect friendly CAP airbase
:param flight: Flight to setup
:param ally_cp: CP to protect
:param enemy_cp: Enemy connected cp
"""
flight.flight_type = FlightType.CAP
patrol_alt = random.randint(self.doctrine["PATROL_ALT_RANGE"][0], self.doctrine["PATROL_ALT_RANGE"][1])
# Find targets waypoints
ingress, heading, distance = Conflict.frontline_vector(ally_cp, enemy_cp, self.game.theater)
center = ingress.point_from_heading(heading, distance / 2)
orbit_center = center.point_from_heading(heading - 90, random.randint(nm_to_meter(6), nm_to_meter(15)))
combat_width = distance / 2
if combat_width > 500000:
combat_width = 500000
if combat_width < 35000:
combat_width = 35000
radius = combat_width*1.25
orbit0p = orbit_center.point_from_heading(heading, radius)
orbit1p = orbit_center.point_from_heading(heading + 180, radius)
# Create points
ascend = self.generate_ascend_point(flight.from_cp)
flight.points.append(ascend)
orbit0 = FlightWaypoint(orbit0p.x, orbit0p.y, patrol_alt)
orbit0.name = "ORBIT 0"
orbit0.description = "Standby between this point and the next one"
orbit0.pretty_name = "Race-track start"
orbit0.waypoint_type = FlightWaypointType.PATROL_TRACK
flight.points.append(orbit0)
orbit1 = FlightWaypoint(orbit1p.x, orbit1p.y, patrol_alt)
orbit1.name = "ORBIT 1"
orbit1.description = "Standby between this point and the previous one"
orbit1.pretty_name = "Race-track end"
orbit1.waypoint_type = FlightWaypointType.PATROL
flight.points.append(orbit1)
# Note : Targets of a PATROL TRACK waypoints are the points to be defended
orbit0.targets.append(flight.from_cp)
orbit0.targets.append(center)
descend = self.generate_descend_point(flight.from_cp)
flight.points.append(descend)
rtb = self.generate_rtb_waypoint(flight.from_cp)
flight.points.append(rtb)
def generate_sead(self, flight, location, custom_targets = []):
"""
Generate a sead flight at a given location
:param flight: Flight to setup
:param location: Location of the SEAD target
:param custom_targets: Custom targets if any
"""
flight.points = []
flight.flight_type = random.choice([FlightType.SEAD, FlightType.DEAD])
ascend = self.generate_ascend_point(flight.from_cp)
flight.points.append(ascend)
heading = flight.from_cp.position.heading_between_point(location.position)
ingress_heading = heading - 180 + 25
egress_heading = heading - 180 - 25
ingress_pos = location.position.point_from_heading(ingress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"])
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, self.doctrine["INGRESS_ALT"])
ingress_point.name = "INGRESS"
ingress_point.pretty_name = "INGRESS on " + location.obj_name
ingress_point.description = "INGRESS on " + location.obj_name
ingress_point.waypoint_type = FlightWaypointType.INGRESS_SEAD
flight.points.append(ingress_point)
if len(custom_targets) > 0:
for target in custom_targets:
point = FlightWaypoint(target.position.x, target.position.y, 0)
point.alt_type = "RADIO"
if flight.flight_type == FlightType.DEAD:
point.description = "SEAD on " + target.type
point.pretty_name = "SEAD on " + location.obj_name
point.only_for_player = True
else:
point.description = "DEAD on " + location.obj_name
point.pretty_name = "DEAD on " + location.obj_name
point.only_for_player = True
ingress_point.targets.append(location)
ingress_point.targetGroup = location
flight.points.append(point)
else:
point = FlightWaypoint(location.position.x, location.position.y, 0)
point.alt_type = "RADIO"
if flight.flight_type == FlightType.DEAD:
point.description = "SEAD on " + location.obj_name
point.pretty_name = "SEAD on " + location.obj_name
point.only_for_player = True
else:
point.description = "DEAD on " + location.obj_name
point.pretty_name = "DEAD on " + location.obj_name
point.only_for_player = True
ingress_point.targets.append(location)
ingress_point.targetGroup = location
flight.points.append(point)
egress_pos = location.position.point_from_heading(egress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"])
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, self.doctrine["EGRESS_ALT"])
egress_point.name = "EGRESS"
egress_point.pretty_name = "EGRESS from " + location.obj_name
egress_point.description = "EGRESS from " + location.obj_name
egress_point.waypoint_type = FlightWaypointType.EGRESS
flight.points.append(egress_point)
descend = self.generate_descend_point(flight.from_cp)
flight.points.append(descend)
rtb = self.generate_rtb_waypoint(flight.from_cp)
flight.points.append(rtb)
def generate_cas(self, flight, from_cp, location):
"""
Generate a CAS flight at a given location
:param flight: Flight to setup
:param location: Location of the CAS targets
"""
flight.points = []
flight.flight_type = FlightType.CAS
ingress, heading, distance = Conflict.frontline_vector(from_cp, location, self.game.theater)
center = ingress.point_from_heading(heading, distance / 2)
egress = ingress.point_from_heading(heading, distance)
ascend = self.generate_ascend_point(flight.from_cp)
flight.points.append(ascend)
ingress_point = FlightWaypoint(ingress.x, ingress.y, 1000)
ingress_point.alt_type = "RADIO"
ingress_point.name = "INGRESS"
ingress_point.pretty_name = "INGRESS"
ingress_point.description = "Ingress into CAS area"
ingress_point.waypoint_type = FlightWaypointType.INGRESS_CAS
flight.points.append(ingress_point)
center_point = FlightWaypoint(center.x, center.y, 1000)
center_point.alt_type = "RADIO"
center_point.description = "Provide CAS"
center_point.name = "CAS"
center_point.pretty_name = "CAS"
center_point.waypoint_type = FlightWaypointType.CAS
flight.points.append(center_point)
egress_point = FlightWaypoint(egress.x, egress.y, 1000)
egress_point.alt_type = "RADIO"
egress_point.description = "Egress from CAS area"
egress_point.name = "EGRESS"
egress_point.pretty_name = "EGRESS"
egress_point.waypoint_type = FlightWaypointType.EGRESS
flight.points.append(egress_point)
descend = self.generate_descend_point(flight.from_cp)
flight.points.append(descend)
rtb = self.generate_rtb_waypoint(flight.from_cp)
flight.points.append(rtb)
def generate_ascend_point(self, from_cp):
"""
Generate ascend point
:param from_cp: Airport you're taking off from
:return:
"""
ascend_heading = from_cp.heading
pos_ascend = from_cp.position.point_from_heading(ascend_heading, 10000)
ascend = FlightWaypoint(pos_ascend.x, pos_ascend.y, self.doctrine["PATTERN_ALTITUDE"])
ascend.name = "ASCEND"
ascend.alt_type = "RADIO"
ascend.description = "Ascend"
ascend.pretty_name = "Ascend"
ascend.waypoint_type = FlightWaypointType.ASCEND_POINT
return ascend
def generate_descend_point(self, from_cp):
"""
Generate approach/descend point
:param from_cp: Airport you're landing at
:return:
"""
ascend_heading = from_cp.heading
descend = from_cp.position.point_from_heading(ascend_heading - 180, 10000)
descend = FlightWaypoint(descend.x, descend.y, self.doctrine["PATTERN_ALTITUDE"])
descend.name = "DESCEND"
descend.alt_type = "RADIO"
descend.description = "Descend to pattern alt"
descend.pretty_name = "Descend to pattern alt"
descend.waypoint_type = FlightWaypointType.DESCENT_POINT
return descend
def generate_rtb_waypoint(self, from_cp):
"""
Generate RTB landing point
:param from_cp: Airport you're landing at
:return:
"""
rtb = from_cp.position
rtb = FlightWaypoint(rtb.x, rtb.y, 0)
rtb.name = "LANDING"
rtb.alt_type = "RADIO"
rtb.description = "RTB"
rtb.pretty_name = "RTB"
rtb.waypoint_type = FlightWaypointType.LANDING_POINT
return rtb

View File

@@ -3,13 +3,22 @@ from dcs.helicopters import *
# Interceptor are the aircraft prioritized for interception tasks
# If none is available, the AI will use regular CAP-capable aircraft instead
from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.mb339.mb339 import MB_339PAN
from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M
INTERCEPT_CAPABLE = [
MiG_21Bis,
MiG_25PD,
MiG_31,
MiG_29S,
MiG_29A,
MiG_29G,
MiG_29K,
M_2000C,
Mirage_2000_5,
Rafale_M,
F_14B,
F_15C,
@@ -25,6 +34,7 @@ CAP_CAPABLE = [
MiG_29A,
MiG_29G,
MiG_29S,
MiG_31,
Su_27,
J_11A,
@@ -40,6 +50,7 @@ CAP_CAPABLE = [
F_5E_3,
F_14B,
F_15C,
F_15E,
F_16C_50,
FA_18C_hornet,
@@ -48,6 +59,7 @@ CAP_CAPABLE = [
P_51D_30_NA,
P_51D,
P_47D_30,
SpitfireLFMkIXCW,
SpitfireLFMkIX,
@@ -55,6 +67,9 @@ CAP_CAPABLE = [
Bf_109K_4,
FW_190D9,
FW_190A8,
A_4E_C,
Rafale_M,
]
# USed for CAS (Close air support) and BAI (Battlefield Interdiction)
@@ -84,15 +99,18 @@ CAS_CAPABLE = [
F_86F_Sabre,
F_5E_3,
F_14B,
F_15E,
F_16C_50,
FA_18C_hornet,
C_101CC,
MB_339PAN,
L_39ZA,
AJS37,
SA342M,
SA342L,
OH_58D,
AH_64A,
AH_64D,
@@ -106,6 +124,8 @@ CAS_CAPABLE = [
P_51D_30_NA,
P_51D,
P_47D_30,
A_20G,
SpitfireLFMkIXCW,
SpitfireLFMkIX,
@@ -113,13 +133,17 @@ CAS_CAPABLE = [
Bf_109K_4,
FW_190D9,
FW_190A8,
A_4E_C,
Rafale_A_S
]
# Aircraft used for SEAD / DEAD tasks
SEAD_CAPABLE = [
F_4E,
FA_18C_hornet,
F_16C_50,
F_15E,
# F_16C_50, Not yet
AV8BNA,
JF_17,
@@ -130,14 +154,16 @@ SEAD_CAPABLE = [
Su_30,
Su_34,
MiG_27K,
A_4E_C,
Rafale_A_S
]
# Aircraft used for Strike mission
STRIKE_CAPABLE = [
MiG_15bis,
MiG_29A,
MiG_27K,
MiG_29S,
MB_339PAN,
Su_17M4,
Su_24M,
@@ -157,6 +183,7 @@ STRIKE_CAPABLE = [
F_86F_Sabre,
F_5E_3,
F_14B,
F_15E,
F_16C_50,
FA_18C_hornet,
@@ -164,10 +191,11 @@ STRIKE_CAPABLE = [
L_39ZA,
AJS37,
M_2000C,
P_51D_30_NA,
P_51D,
P_47D_30,
A_20G,
B_17G,
SpitfireLFMkIXCW,
SpitfireLFMkIX,
@@ -175,11 +203,23 @@ STRIKE_CAPABLE = [
Bf_109K_4,
FW_190D9,
FW_190A8,
A_4E_C,
Rafale_A_S
]
ANTISHIP_CAPABLE = [
Su_24M,
Su_17M4,
F_A_18C,
F_15E,
AV8BNA,
JF_17
JF_17,
F_16C_50,
A_10C,
A_10A,
Ju_88A4,
Rafale_A_S
]

View File

@@ -30,17 +30,53 @@ class FlightType(Enum):
EWAR = 16
class FlightWaypoint():
class FlightWaypointType(Enum):
TAKEOFF = 0 # Take off point
ASCEND_POINT = 1 # Ascension point after take off
PATROL = 2 # Patrol point
PATROL_TRACK = 3 # Patrol race track
NAV = 4 # Nav point
INGRESS_STRIKE = 5 # Ingress strike (For generator, means that this should have bombing on next TARGET_POINT points)
INGRESS_SEAD = 6 # Ingress sead (For generator, means that this should attack groups on TARGET_GROUP_LOC points)
INGRESS_CAS = 7 # Ingress cas (should start CAS task)
CAS = 8 # Should do CAS there
EGRESS = 9 # Should stop attack
DESCENT_POINT = 10 # Should start descending to pattern alt
LANDING_POINT = 11 # Should land there
TARGET_POINT = 12 # A target building or static object, position
TARGET_GROUP_LOC = 13 # A target group approximate location
TARGET_SHIP = 14 # A target ship known location
CUSTOM = 15 # User waypoint (no specific behaviour)
class PredefinedWaypointCategory(Enum):
NOT_PREDEFINED = 0
ALLY_CP = 1
ENEMY_CP = 2
FRONTLINE = 3
ENEMY_BUILDING = 4
ENEMY_UNIT = 5
ALLY_BUILDING = 6
ALLY_UNIT = 7
class FlightWaypoint:
def __init__(self, x: float, y: float, alt=0):
self.x = x
self.y = y
self.alt = alt
self.alt_type = "BARO"
self.name = ""
self.description = ""
self.targets = []
self.targetGroup = None
self.obj_name = ""
self.pretty_name = ""
self.waypoint_type = FlightWaypointType.TAKEOFF # type: FlightWaypointType
self.category = PredefinedWaypointCategory.NOT_PREDEFINED# type: PredefinedWaypointCategory
self.only_for_player = False
self.data = None
class Flight:
@@ -55,6 +91,7 @@ class Flight:
loadout = {}
preset_loadout_name = ""
start_type = "Runway"
group = False # Contains DCS Mission group data after mission has been generated
# How long before this flight should take off
scheduled_in = 0

View File

@@ -22,15 +22,22 @@ class ForcedOptionsGenerator:
self.game = game
def _set_options_view(self):
if self.game.settings.map_coalition_visibility == "All Units":
if self.game.settings.map_coalition_visibility == ForcedOptions.Views.All:
self.mission.forced_options.options_view = ForcedOptions.Views.All
elif self.game.settings.map_coalition_visibility == "Allied Units":
elif self.game.settings.map_coalition_visibility == ForcedOptions.Views.Allies:
self.mission.forced_options.options_view = ForcedOptions.Views.Allies
elif self.game.settings.map_coalition_visibility == "Own Aircraft":
elif self.game.settings.map_coalition_visibility == ForcedOptions.Views.OnlyAllies:
self.mission.forced_options.options_view = ForcedOptions.Views.OnlyAllies
elif self.game.settings.map_coalition_visibility == ForcedOptions.Views.MyAircraft:
self.mission.forced_options.options_view = ForcedOptions.Views.MyAircraft
elif self.game.settings.map_coalition_visibility == "None":
elif self.game.settings.map_coalition_visibility == ForcedOptions.Views.OnlyMap:
self.mission.forced_options.options_view = ForcedOptions.Views.OnlyMap
def _set_external_views(self):
if not self.game.settings.external_views_allowed:
self.mission.forced_options.external_views = self.game.settings.external_views_allowed
def _set_labels(self):
if self.game.settings.labels == "Abbreviated":
self.mission.forced_options.labels = int(Labels.Abbreviated)
@@ -41,5 +48,8 @@ class ForcedOptionsGenerator:
def generate(self):
self._set_options_view()
self._set_external_views()
self._set_labels()

View File

@@ -7,6 +7,8 @@ from gen import Conflict
from gen.ground_forces.combat_stance import CombatStance
from theater import ControlPoint
import pydcs_extensions.frenchpack.frenchpack as frenchpack
TYPE_TANKS = [
Armor.MBT_T_55,
Armor.MBT_T_72B,
@@ -19,6 +21,9 @@ TYPE_TANKS = [
Armor.MBT_M1A2_Abrams,
Armor.MBT_M60A3_Patton,
Armor.MBT_Merkava_Mk__4,
Armor.ZTZ_96B,
# WW2
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
Armor.HT_Pz_Kpfw_VI_Tiger_I,
@@ -26,13 +31,39 @@ TYPE_TANKS = [
Armor.MT_M4_Sherman,
Armor.MT_M4A4_Sherman_Firefly,
Armor.StuG_IV,
Armor.ZTZ_96B
Armor.ST_Centaur_IV,
Armor.CT_Cromwell_IV,
Armor.HIT_Churchill_VII,
# Mods
frenchpack.DIM__TOYOTA_BLUE,
frenchpack.DIM__TOYOTA_GREEN,
frenchpack.DIM__TOYOTA_DESERT,
frenchpack.DIM__KAMIKAZE,
frenchpack.AMX_10RCR,
frenchpack.AMX_10RCR_SEPAR,
frenchpack.AMX_30B2,
frenchpack.Leclerc_Serie_XXI,
]
TYPE_ATGM = [
Armor.ATGM_M1045_HMMWV_TOW,
Armor.ATGM_M1134_Stryker,
Armor.IFV_BMP_2,
# WW2 (Tank Destroyers)
Armor.M30_Cargo_Carrier,
Armor.TD_Jagdpanzer_IV,
Armor.TD_Jagdpanther_G1,
Armor.TD_M10_GMC,
# Mods
frenchpack.VBAE_CRAB_MMP,
frenchpack.VAB_MEPHISTO,
frenchpack.TRM_2000_PAMELA,
]
TYPE_IFV = [
@@ -46,8 +77,16 @@ TYPE_IFV = [
Armor.IFV_M2A2_Bradley,
Armor.IFV_BMD_1,
Armor.ZBD_04A,
Armor.APC_Sd_Kfz_251,
# WW2
Armor.IFV_Sd_Kfz_234_2_Puma,
Armor.LAC_M8_Greyhound,
# Mods
frenchpack.ERC_90,
frenchpack.VBAE_CRAB,
frenchpack.VAB_T20_13
]
TYPE_APC = [
@@ -63,9 +102,17 @@ TYPE_APC = [
Armor.TPz_Fuchs,
Armor.ARV_BRDM_2,
Armor.ARV_BTR_RD,
Armor.ARV_MTLB_U_BOMAN,
Armor.M30_Cargo_Carrier,
Armor.FDDM_Grad,
# WW2
Armor.APC_M2A1,
Armor.APC_Sd_Kfz_251,
# Mods
frenchpack.VAB__50,
frenchpack.VBL__50,
frenchpack.VBL_AANF1,
]
TYPE_ARTILLERY = [
@@ -79,9 +126,11 @@ TYPE_ARTILLERY = [
Artillery.SPH_2S9_Nona,
Artillery.SpGH_Dana,
Artillery.SPH_2S19_Msta,
Artillery.M12_GMC,
Artillery.MLRS_FDDM,
Artillery.Sturmpanzer_IV_Brummbär
# WW2
Artillery.Sturmpanzer_IV_Brummbär,
Artillery.M12_GMC
]
TYPE_LOGI = [
@@ -100,6 +149,11 @@ TYPE_LOGI = [
Unarmed.Willys_MB,
Unarmed.Land_Rover_109_S3,
Unarmed.Land_Rover_101_FC,
# Mods
frenchpack.VBL,
frenchpack.VAB,
]
TYPE_INFANTRY = [
@@ -131,14 +185,14 @@ class CombatGroupRole(Enum):
DISTANCE_FROM_FRONTLINE = {
CombatGroupRole.TANK:2800,
CombatGroupRole.APC:7000,
CombatGroupRole.IFV:3000,
CombatGroupRole.ARTILLERY:14000,
CombatGroupRole.SHORAD:12000,
CombatGroupRole.LOGI:18000,
CombatGroupRole.INFANTRY:2800,
CombatGroupRole.ATGM:5500
CombatGroupRole.TANK:3200,
CombatGroupRole.APC:8000,
CombatGroupRole.IFV:3700,
CombatGroupRole.ARTILLERY:18000,
CombatGroupRole.SHORAD:13000,
CombatGroupRole.LOGI:20000,
CombatGroupRole.INFANTRY:3000,
CombatGroupRole.ATGM:6200
}
GROUP_SIZES_BY_COMBAT_STANCE = {

View File

@@ -1,6 +1,7 @@
import logging
from game import db
from game.data.building_data import FORTIFICATION_UNITS_ID, FORTIFICATION_UNITS
from game.db import unit_type_from_name
from .conflictgen import *
from .naming import *
@@ -44,15 +45,6 @@ class GroundObjectsGenerator:
def generate(self):
cp = None # type: ControlPoint
if self.conflict.attackers_country.name == self.game.player_country:
cp = self.conflict.to_cp
else:
cp = self.conflict.from_cp
consumed_farps = set()
for cp in self.game.theater.controlpoints:
if cp.captured:
@@ -63,28 +55,55 @@ class GroundObjectsGenerator:
for ground_object in cp.ground_objects:
if ground_object.dcs_identifier == "AA":
if self.game.position_culled(ground_object.position):
continue
for g in ground_object.groups:
if len(g.units) > 0:
utype = unit_type_from_name(g.units[0].type)
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)
for i, u in enumerate(g.units):
if i > 0:
vehicle = Vehicle(self.m.next_unit_id(), self.m.string(u.name), u.type)
vehicle.position.x = u.position.x
vehicle.position.y = u.position.y
vehicle.heading = u.heading
vg.add_unit(vehicle)
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)
for i, u in enumerate(g.units):
if i > 0:
vehicle = Vehicle(self.m.next_unit_id(), self.m.string(u.name), u.type)
vehicle.position.x = u.position.x
vehicle.position.y = u.position.y
vehicle.heading = u.heading
vehicle.player_can_drive = True
vg.add_unit(vehicle)
else:
vg = self.m.ship_group(side, g.name, utype, position=g.position,
heading=g.units[0].heading)
vg.units[0].name = self.m.string(g.units[0].name)
for i, u in enumerate(g.units):
utype = unit_type_from_name(u.type)
if i > 0:
ship = Ship(self.m.next_unit_id(), self.m.string(u.name), utype)
ship.position.x = u.position.x
ship.position.y = u.position.y
ship.heading = u.heading
vg.add_unit(ship)
if self.game.settings.perf_red_alert_state:
vg.points[0].tasks.append(OptAlarmState(2))
else:
vg.points[0].tasks.append(OptAlarmState(1))
elif ground_object.dcs_identifier in ["CARRIER", "LHA"]:
for g in ground_object.groups:
if len(g.units) > 0:
utype = unit_type_from_name(g.units[0].type)
sg = self.m.ship_group(side, g.name, utype, position=g.position, heading=g.units[0].heading)
if ground_object.dcs_identifier == "CARRIER" and self.game.settings.supercarrier == True:
utype = db.upgrade_to_supercarrier(utype, cp.name)
sg = self.m.ship_group(side, g.name, utype, position=g.position, heading=g.units[0].heading)
sg.units[0].name = self.m.string(g.units[0].name)
for i, u in enumerate(g.units):
if i > 0:
ship = Ship(self.m.next_unit_id(), self.m.string(u.name), unit_type_from_name(u.type))
@@ -93,70 +112,61 @@ class GroundObjectsGenerator:
ship.heading = u.heading
sg.add_unit(ship)
# TODO : make sure the point is not on Land
sg.add_waypoint(sg.points[0].position.point_from_heading(g.units[0].heading, 100000))
# Find carrier direction (In the wind)
found_carrier_destination = False
attempt = 0
while not found_carrier_destination and attempt < 5:
point = sg.points[0].position.point_from_heading(self.m.weather.wind_at_ground.direction + 180, 100000-attempt*20000)
if self.game.theater.is_in_sea(point):
found_carrier_destination = True
sg.add_waypoint(point)
else:
attempt = attempt + 1
# SET UP TACAN
# Set UP TACAN and ICLS
modeChannel = "X" if not cp.tacanY else "Y"
sg.points[0].tasks.append(ActivateBeaconCommand(channel=cp.tacanN, modechannel=modeChannel, callsign=cp.tacanI, unit_id=sg.units[0].id))
sg.points[0].tasks.append(ActivateBeaconCommand(channel=cp.tacanN, modechannel=modeChannel, callsign=cp.tacanI, unit_id=sg.units[0].id, aa=False))
if ground_object.dcs_identifier == "CARRIER" and hasattr(cp, "icls"):
sg.points[0].tasks.append(ActivateICLSCommand(cp.icls, unit_id=sg.units[0].id))
else:
if self.game.position_culled(ground_object.position):
continue
static_type = None
if ground_object.dcs_identifier in warehouse_map:
static_type = warehouse_map[ground_object.dcs_identifier]
else:
elif ground_object.dcs_identifier in fortification_map:
static_type = fortification_map[ground_object.dcs_identifier]
if not static_type:
elif ground_object.dcs_identifier in FORTIFICATION_UNITS_ID:
for f in FORTIFICATION_UNITS:
if f.id == ground_object.dcs_identifier:
unit_type = f
break
else:
print("Didn't find {} in static _map(s)!".format(ground_object.dcs_identifier))
continue
if ground_object.group_id not in consumed_farps:
consumed_farps.add(ground_object.group_id)
if random.randint(0, 100) > 50:
farp_aa(
self.m,
side,
ground_object.string_identifier,
ground_object.position,
if static_type is None:
if not ground_object.is_dead:
group = self.m.vehicle_group(
country=side,
name=ground_object.string_identifier,
_type=unit_type,
position=ground_object.position,
heading=ground_object.heading,
)
logging.info("generated {}object identifier {} with mission id {}".format(
"dead " if ground_object.is_dead else "", group.name, group.id))
else:
group = self.m.static_group(
country=side,
name=ground_object.string_identifier,
_type=static_type,
position=ground_object.position,
heading=ground_object.heading,
dead=ground_object.is_dead,
)
group = self.m.static_group(
country=side,
name=ground_object.string_identifier,
_type=static_type,
position=ground_object.position,
heading=ground_object.heading,
dead=ground_object.is_dead,
)
logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id))
def farp_aa(mission_obj, country, name, position: mapping.Point):
"""
Add AAA to a FARP :)
:param mission_obj:
:param country:
:param name:
:param position:
:return:
"""
vg = unitgroup.VehicleGroup(mission_obj.next_group_id(), mission_obj.string(name))
units = [
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.AAA_ZU_23_Closed,
]
v = mission_obj.vehicle(name + "_AAA", random.choice(units))
v.position.x = position.x - random.randint(5, 30)
v.position.y = position.y - random.randint(5, 30)
v.heading = random.randint(0, 359)
vg.add_unit(v)
wp = vg.add_waypoint(vg.units[0].position, PointAction.OffRoad, 0)
wp.ETA_locked = True
country.add_vehicle_group(vg)
return vg
logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id))

View File

@@ -0,0 +1,27 @@
import logging
import random
from game import db
from gen.missiles.v1_group import V1GroupGenerator
MISSILES_MAP = {
"V1GroupGenerator": V1GroupGenerator,
}
def generate_missile_group(game, ground_object, faction:str):
"""
This generate a ship group
:return: Nothing, but put the group reference inside the ground object
"""
faction = db.FACTIONS[faction]
if "missiles" in faction.keys():
generators = faction["missiles"]
if len(generators) > 0:
gen = random.choice(generators)
if gen in MISSILES_MAP.keys():
generator = MISSILES_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

32
gen/missiles/v1_group.py Normal file
View File

@@ -0,0 +1,32 @@
import random
from dcs.vehicles import Unarmed, MissilesSS, AirDefence
from gen.sam.group_generator import GroupGenerator
class V1GroupGenerator(GroupGenerator):
def __init__(self, game, ground_object, faction):
super(V1GroupGenerator, self).__init__(game, ground_object)
self.faction = faction
def generate(self):
# Ramps
self.add_unit(MissilesSS.V_1_ramp, "V1#0", self.position.x, self.position.y + random.randint(1, 8), self.heading)
self.add_unit(MissilesSS.V_1_ramp, "V1#1", self.position.x + 50, self.position.y + random.randint(1, 8), self.heading)
self.add_unit(MissilesSS.V_1_ramp, "V1#2", self.position.x + 100, self.position.y + random.randint(1, 8), self.heading)
# Commander
self.add_unit(Unarmed.Kübelwagen_82, "Kubel#0", self.position.x - 35, self.position.y - 20,
self.heading)
# Self defense flak
flak_unit = random.choice([AirDefence.AAA_Flak_Vierling_38, AirDefence.AAA_Flak_38])
self.add_unit(flak_unit, "FLAK#0", self.position.x - 55, self.position.y - 38,
self.heading)
self.add_unit(Unarmed.Blitz_3_6_6700A, "Blitz#0",
self.position.x + 200, self.position.y + 15, 90)

View File

@@ -32,7 +32,10 @@ class NameGenerator:
"TERMITE", "URCHIN", "SHRIMP", "TURKEY", "TOUCAN", "TETRA", "HUSKY", "STARFISH", "SWAN",
"FROG", "SQUIRREL", "WALRUS", "WARTHOG", "CORGI", "WEASEL", "WOMBAT", "WOLVERINE", "MAMMOTH",
"TOAD", "WOLF", "ZEBU", "SEAL", "SKATE", "JELLYFISH", "MOSQUITO", "LOCUST", "SLUG", "SNAIL",
"HEDGEHOG", "PIGLET", "FENNEC", "BADGER", "ALPACA"
"HEDGEHOG", "PIGLET", "FENNEC", "BADGER", "ALPACA", "DINGO", "COLT", "SKUNK", "BUNNY", "IMPALA",
"GUANACO", "CAPYBARA", "ELK", "MINK", "PRONGHORN", "CROW", "BUMBLEBEE", "FAWN", "OTTER", "WATERBUCK",
"JERBOA", "KITTEN", "ARGALI", "OX", "MARE", "FINCH", "BASILISK", "GOPHER", "HAMSTER", "CANARY", "WOODCHUCK",
"ANACONDA"
]
def __init__(self):
@@ -68,7 +71,7 @@ class NameGenerator:
def random_objective_name(self):
if len(self.ANIMALS) == 0:
random.choice(ALPHA_MILITARY).upper() + " #" + str(random.randint(0, 100))
return random.choice(ALPHA_MILITARY).upper() + "#" + str(random.randint(0, 100))
else:
animal = random.choice(self.ANIMALS)
self.ANIMALS.remove(animal)

View File

@@ -4,7 +4,7 @@ from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import GroupGenerator
GFLAK = [AirDefence.AAA_Flak_Vierling_38, AirDefence.AAA_Flak_Vierling_38, AirDefence.AAA_Flak_18, AirDefence.AAA_Flak_36, AirDefence.AAA_Flak_37, AirDefence.AAA_Flak_38]
GFLAK = [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]
class FlakGenerator(GroupGenerator):
"""
@@ -15,7 +15,7 @@ class FlakGenerator(GroupGenerator):
grid_x = random.randint(2, 4)
grid_y = random.randint(2, 4)
spacing = random.randint(10,40)
spacing = random.randint(30,60)
index = 0
mixed = random.choice([True, False])
@@ -25,15 +25,29 @@ class FlakGenerator(GroupGenerator):
for j in range(grid_y):
index = index+1
self.add_unit(unit_type, "AAA#" + str(index),
self.position.x + spacing*i,
self.position.y + spacing*j, self.heading)
self.position.x + spacing*i + random.randint(1,5),
self.position.y + spacing*j + random.randint(1,5), self.heading)
if(mixed):
unit_type = random.choice(GFLAK)
# Enough Opel truck to transport the guns
for i in range(grid_x):
for j in range(grid_y):
# Search lights
search_pos = self.get_circular_position(random.randint(2,5), 90)
for index, pos in enumerate(search_pos):
self.add_unit(AirDefence.Flak_Searchlight_37, "SearchLight#" + str(index), pos[0], pos[1], self.heading)
# Support
self.add_unit(AirDefence.Maschinensatz_33, "MC33#", self.position.x-20, self.position.y-20, self.heading)
self.add_unit(AirDefence.AAA_Kdo_G_40, "KDO#", self.position.x - 25, self.position.y - 20,
self.heading)
# Commander
self.add_unit(Unarmed.Kübelwagen_82, "Kubel#", self.position.x - 35, self.position.y - 20,
self.heading)
# Some Opel Blitz trucks
for i in range(int(max(1,grid_x/2))):
for j in range(int(max(1,grid_x/2))):
self.add_unit(Unarmed.Blitz_3_6_6700A, "AAA#" + str(index),
self.position.x + 200 + 9*i,
self.position.y + 9*j, 90)
self.position.x + 200 + 15*i + random.randint(1,5),
self.position.y + 15*j + random.randint(1,5), 90)

View File

@@ -50,7 +50,7 @@ SAM_MAP = {
AirDefence.SAM_Patriot_EPP_III: PatriotGenerator,
AirDefence.SAM_Chaparral_M48: ChaparralGenerator,
AirDefence.AAA_Bofors_40mm: BoforsGenerator,
AirDefence.AAA_Flak_36: FlakGenerator,
AirDefence.AAA_8_8cm_Flak_36: FlakGenerator,
AirDefence.SAM_SA_2_LN_SM_90: SA2Generator,
AirDefence.SAM_SA_3_S_125_LN_5P73: SA3Generator,
AirDefence.SAM_SA_6_Kub_LN_2P25: SA6Generator,

View File

@@ -20,6 +20,12 @@ class SA10Generator(GroupGenerator):
# Search radar for missiles (optionnal)
self.add_unit(AirDefence.SAM_SA_10_S_300PS_SR_64H6E, "SR2", self.position.x - 40, self.position.y, self.heading)
# 2 Tracking radars
self.add_unit(AirDefence.SAM_SA_10_S_300PS_TR_30N6, "TR1", self.position.x - 40, self.position.y - 40, self.heading)
self.add_unit(AirDefence.SAM_SA_10_S_300PS_TR_30N6, "TR2", self.position.x + 40, self.position.y - 40,
self.heading)
# 2 different launcher type (C & D)
num_launchers = random.randint(6, 8)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=360)
@@ -40,4 +46,4 @@ class SA10Generator(GroupGenerator):
num_launchers = random.randint(6, 8)
positions = self.get_circular_position(num_launchers, launcher_distance=350, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.AAA_ZU_23_Emplacement, "AA#" + str(i), position[0], position[1], position[2])
self.add_unit(AirDefence.SPAAA_ZSU_23_4_Shilka, "AA#" + str(i), position[0], position[1], position[2])

View File

@@ -1,53 +0,0 @@
import logging
from game import db
from .conflictgen import *
from .naming import *
from dcs.mission import *
from dcs.unitgroup import *
from dcs.task import *
SHIP_RANDOM_SPREAD = 300
class ShipGenerator:
def __init__(self, mission: Mission, conflict: Conflict):
self.m = mission
self.conflict = conflict
def generate_carrier(self, for_units: typing.Collection[UnitType], country: str, at: Point) -> ShipGroup:
type = db.find_unittype(Carriage, country)[0]
for unit_type in for_units:
if unit_type in db.CARRIER_TYPE_BY_PLANE:
type = db.CARRIER_TYPE_BY_PLANE[unit_type]
break
group = self.m.ship_group(
country=self.m.country(country),
name=namegen.next_carrier_name(self.m.country(country)),
_type=type,
position=at)
group.points[0].tasks.append(ActivateBeaconCommand(unit_id=group.id, channel=20, callsign="SHDW", aa=False))
group.points[0].tasks.append(ActivateICLSCommand(unit_id=group.id, channel=1))
return group
def generate_cargo(self, units: db.ShipDict) -> typing.Collection[ShipGroup]:
groups = []
offset = 0
for unit_type, unit_count in units.items():
for _ in range(unit_count):
offset += 1
logging.info("shipgen: {} ({}) for {}".format(unit_type, unit_count, self.conflict.defenders_side))
group = self.m.ship_group(
country=self.conflict.defenders_country,
name=namegen.next_unit_name(self.conflict.defenders_country, unit_type),
_type=unit_type,
position=self.conflict.ground_defenders_location.random_point_within(SHIP_RANDOM_SPREAD, SHIP_RANDOM_SPREAD).point_from_heading(0, offset * SHIP_RANDOM_SPREAD)
)
group.add_waypoint(self.conflict.to_cp.position)
groups.append(group)
return groups

View File

@@ -42,100 +42,35 @@ class TriggersGenerator:
self.conflict = conflict
self.game = game
def _gen_activation_trigger(self, radius: int, player_cp: ControlPoint, player_coalition: str, enemy_coalition: str):
conflict_distance = player_cp.position.distance_to_point(self.conflict.position)
minimum_radius = max(conflict_distance - TRIGGER_MIN_DISTANCE_FROM_START, TRIGGER_RADIUS_MINIMUM)
if minimum_radius < 0:
minimum_radius = 0
radius = min(minimum_radius, radius)
activation_trigger_zone = self.mission.triggers.add_triggerzone(
self.conflict.position,
radius,
name="Activation zone",
)
activation_trigger = TriggerOnce(Event.NoEvent, "Activation trigger")
activation_trigger.add_condition(PartOfCoalitionInZone(player_coalition, activation_trigger_zone.id))
activation_trigger.add_condition(FlagIsTrue())
activate_by_trigger = []
flag_id = 2
for coalition_name, coalition in self.mission.coalition.items():
for country in coalition.countries.values():
if coalition_name == enemy_coalition:
for plane_group in country.plane_group + country.helicopter_group:
plane_group.late_activation = True
self.delayed_trigger(
plane_group,
flag_id,
flag_lower_limit=180,
flag_upper_limit=2400,
)
flag_id += 1
for vehicle_group in country.vehicle_group:
vehicle_group.late_activation = True
activate_by_trigger.append(vehicle_group)
for group in activate_by_trigger:
activation_trigger.add_action(ActivateGroup(group.id))
self.mission.triggerrules.triggers.append(activation_trigger)
def _gen_push_trigger(self, player_cp: ControlPoint, player_coalition: str):
push_by_trigger = []
for coalition_name, coalition in self.mission.coalition.items():
for country in coalition.countries.values():
if coalition_name == player_coalition:
for group in country.plane_group + country.helicopter_group:
if group.task == AWACS.name or group.task == Refueling.name:
continue
push_by_trigger.append(group)
"""if not group.units[0].is_human():
regroup_heading = self.conflict.to_cp.position.heading_between_point(player_cp.position)
pos1 = group.position.point_from_heading(regroup_heading, REGROUP_ZONE_DISTANCE)
pos2 = group.position.point_from_heading(regroup_heading, REGROUP_ZONE_DISTANCE+5000)
w1 = group.add_waypoint(pos1, REGROUP_ALT)
w2 = group.add_waypoint(pos2, REGROUP_ALT)
group.points.remove(w1)
group.points.remove(w2)
group.points.insert(1, w2)
group.points.insert(1, w1)
w1.tasks.append(Silence(True))
switch_waypoint_task = ControlledTask(SwitchWaypoint(from_waypoint=3, to_waypoint=2))
switch_waypoint_task.start_if_user_flag(1, False)
w2.tasks.append(switch_waypoint_task)
group.points[3].tasks.append(Silence(False))
group.add_trigger_action(SwitchWaypoint(to_waypoint=4))"""
push_trigger = TriggerOnce(Event.NoEvent, "Push trigger")
for group in push_by_trigger:
for unit in group.units:
push_trigger.add_condition(UnitAltitudeHigherAGL(unit.id, PUSH_TRIGGER_ACTIVATION_AGL))
if not group.units[0].is_human():
push_trigger.add_action(AITaskPush(group.id, 1))
message_string = self.mission.string("Task force is in the air, proceed with the objective.")
push_trigger.add_action(MessageToAll(message_string, clearview=True))
push_trigger.add_action(SetFlagValue())
self.mission.triggerrules.triggers.append(push_trigger)
def _set_allegiances(self, player_coalition: str, enemy_coalition: str):
"""
Set airbase initial coalition
"""
# Empty neutrals airports
cp_ids = [cp.id for cp in self.game.theater.controlpoints]
for airport in self.mission.terrain.airport_list():
if airport.id not in cp_ids:
airport.unlimited_fuel = False
airport.unlimited_munitions = False
airport.unlimited_aircrafts = False
airport.gasoline_init = 0
airport.methanol_mixture_init = 0
airport.diesel_init = 0
airport.jet_init = 0
airport.operating_level_air = 0
airport.operating_level_equipment = 0
airport.operating_level_fuel = 0
for cp in self.game.theater.controlpoints:
if cp.is_global:
continue
self.mission.terrain.airport_by_id(cp.at.id).set_coalition(cp.captured and player_coalition or enemy_coalition)
def _set_skill(self, player_coalition: str, enemy_coalition: str):
"""
Set skill level for all aircraft in the mission
"""
for coalition_name, coalition in self.mission.coalition.items():
if coalition_name == player_coalition:
skill_level = self.game.settings.player_skill, self.game.settings.player_skill
@@ -153,53 +88,38 @@ class TriggersGenerator:
for vehicle_group in country.vehicle_group:
vehicle_group.set_skill(Skill(skill_level[1]))
def delayed_trigger(self, group, flag_id, flag_lower_limit, flag_upper_limit):
def _gen_markers(self):
"""
Create an activation trigger a randomized amount after the main activation occurs
:param group:
group to activate
:param flag_id:
ID of the flag to use
:param flag_lower_limit:
lower limit of what the random time can be (shouldn't be negative)
:param flag_upper_limit:
uopper limit of what the random time can be
:return:
N/A
Generate markers on F10 map for each existing objective
"""
trigger_one = TriggerOnce(Event.NoEvent, "Activation trigger")
trigger_one.add_condition(FlagEquals(1, 1))
trigger_one.add_action(SetFlagValue(flag_id, 1))
if self.game.settings.generate_marks:
mark_trigger = TriggerOnce(Event.NoEvent, "Marks generator")
mark_trigger.add_condition(TimeAfter(1))
v = 10
for cp in self.game.theater.controlpoints:
added = []
for ground_object in cp.ground_objects:
if ground_object.obj_name not in added:
zone = self.mission.triggers.add_triggerzone(ground_object.position, radius=10, hidden=True, name="MARK")
if cp.captured:
name = ground_object.obj_name + " [ALLY]"
else:
name = ground_object.obj_name + " [ENEMY]"
mark_trigger.add_action(MarkToAll(v, zone.id, String(name)))
v = v + 1
added.append(ground_object.obj_name)
self.mission.triggerrules.triggers.append(mark_trigger)
trigger_two = TriggerCondition()
trigger_two.add_condition(
TimeSinceFlag(
flag_id,
seconds=random.randint(
flag_lower_limit,
flag_upper_limit
)
)
)
trigger_two.add_action(ActivateGroup(group.id))
self.mission.triggerrules.triggers.append(trigger_one)
self.mission.triggerrules.triggers.append(trigger_two)
def generate(self, player_cp: ControlPoint, is_quick: bool, activation_trigger_radius: int, awacs_enabled: bool):
player_coalition = self.game.player_country in db.BLUEFOR_FACTIONS and "blue" or "red"
enemy_coalition = player_coalition == "blue" and "red" or "blue"
def generate(self):
player_coalition = "blue"
enemy_coalition = "red"
self.mission.coalition["blue"].bullseye = {"x": self.conflict.position.x,
"y": self.conflict.position.y}
"y": self.conflict.position.y}
self.mission.coalition["red"].bullseye = {"x": self.conflict.position.x,
"y": self.conflict.position.y}
self._set_skill(player_coalition, enemy_coalition)
self._set_allegiances(player_coalition, enemy_coalition)
#if not is_quick:
# # TODO: waypoint parts of this should not be post-hacked but added in airgen
# self._gen_activation_trigger(activation_trigger_radius, player_cp, player_coalition, enemy_coalition)
# self._gen_push_trigger(player_cp, player_coalition)
self._gen_markers()

1
liberation_theme.json Normal file
View File

@@ -0,0 +1 @@
{"theme_index": 1}

View File

@@ -0,0 +1,782 @@
from enum import Enum
from dcs import task
from dcs.planes import PlaneType
from dcs.weapons_data import Weapons
class WeaponsA4EC:
AN_M57__2__TER_ = {"clsid": "{AN-M57_TER_2_L}", "name": "AN-M57 *2 (TER)", "weight": 273.6}
AN_M57__2__TER__ = {"clsid": "{AN-M57_TER_2_R}", "name": "AN-M57 *2 (TER)", "weight": 273.6}
AN_M57__3__TER_ = {"clsid": "{AN-M57_TER_3_C}", "name": "AN-M57 *3 (TER)", "weight": 386.6}
AN_M57__5__MER_ = {"clsid": "{AN-M57_MER_5_L}", "name": "AN-M57 *5 (MER)", "weight": 664.8}
AN_M57__5__MER__ = {"clsid": "{AN-M57_MER_5_R}", "name": "AN-M57 *5 (MER)", "weight": 664.8}
AN_M57__6__MER_ = {"clsid": "{AN-M57_MER_6_C}", "name": "AN-M57 *6 (MER)", "weight": 777.8}
AN_M66A2 = {"clsid": "{AN-M66A2}", "name": "AN-M66A2", "weight": 970.68688}
AN_M81 = {"clsid": "{AN-M81}", "name": "AN-M81", "weight": 117.93392}
AN_M81__5__MER_ = {"clsid": "{AN-M81_MER_5_L}", "name": "AN-M81 *5 (MER)", "weight": 689.3}
AN_M81__5__MER__ = {"clsid": "{AN-M81_MER_5_R}", "name": "AN-M81 *5 (MER)", "weight": 689.3}
AN_M81__6__MER_ = {"clsid": "{AN-M81_MER_6_C}", "name": "AN-M81 *6 (MER)", "weight": 807.2}
AN_M88 = {"clsid": "{AN-M88}", "name": "AN-M88", "weight": 98.0665904}
AN_M88__5__MER_ = {"clsid": "{AN-M88_MER_5_L}", "name": "AN-M88 *5 (MER)", "weight": 589.8}
AN_M88__5__MER__ = {"clsid": "{AN-M88_MER_5_R}", "name": "AN-M88 *5 (MER)", "weight": 589.8}
AN_M88__6__MER_ = {"clsid": "{AN-M88_MER_6_C}", "name": "AN-M88 *6 (MER)", "weight": 687.8}
CBU_1_A = {"clsid": "{CBU-1/A}", "name": "CBU-1/A", "weight": 458.921706}
CBU_1_A__2 = {"clsid": "{CBU-1/A_TER_2_L}", "name": "CBU-1/A *2", "weight": 713.473056}
CBU_1_A__2_ = {"clsid": "{CBU-1/A_TER_2_R}", "name": "CBU-1/A *2", "weight": 713.473056}
CBU_2B_A = {"clsid": "{CBU-2B/A}", "name": "CBU-2B/A", "weight": 379.543106}
CBU_2B_A__2 = {"clsid": "{CBU-2B/A_TER_2_L}", "name": "CBU-2B/A *2", "weight": 806.686212}
CBU_2B_A__2_ = {"clsid": "{CBU-2B/A_TER_2_R}", "name": "CBU-2B/A *2", "weight": 806.686212}
CBU_2_A = {"clsid": "{CBU-2/A}", "name": "CBU-2/A", "weight": 343.822736}
CBU_2_A__2 = {"clsid": "{CBU-2/A_TER_2_L}", "name": "CBU-2/A *2", "weight": 735.245472}
CBU_2_A__2_ = {"clsid": "{CBU-2/A_TER_2_R}", "name": "CBU-2/A *2", "weight": 735.245472}
D_704_Refueling_Pod = {"clsid": "{D-704_BUDDY_POD}", "name": "D-704 Refueling Pod", "weight": 1234.532648}
Fuel_Tank_150_gallons = {"clsid": "{DFT-150gal}", "name": "Fuel Tank 150 gallons", "weight": 515.888512}
Fuel_Tank_300_gallons = {"clsid": "{DFT-300gal}", "name": "Fuel Tank 300 gallons", "weight": 991.407336}
Fuel_Tank_300_gallons_ = {"clsid": "{DFT-300gal_LR}", "name": "Fuel Tank 300 gallons", "weight": 998.664808}
Fuel_Tank_400_gallons = {"clsid": "{DFT-400gal}", "name": "Fuel Tank 400 gallons", "weight": 1320.06208}
LAU_10_2___4_ZUNI_MK_71 = {"clsid": "{LAU-10 ZUNI_TER_2_C}", "name": "LAU-10*2 - 4 ZUNI MK 71", "weight": 927.6}
LAU_10_2___4_ZUNI_MK_71_ = {"clsid": "{LAU-10 ZUNI_TER_2_L}", "name": "LAU-10*2 - 4 ZUNI MK 71", "weight": 927.6}
LAU_10_2___4_ZUNI_MK_71__ = {"clsid": "{LAU-10 ZUNI_TER_2_R}", "name": "LAU-10*2 - 4 ZUNI MK 71", "weight": 927.6}
LAU_10_3___4_ZUNI_MK_71 = {"clsid": "{LAU-10 ZUNI_TER_3_C}", "name": "LAU-10*3 - 4 ZUNI MK 71", "weight": 1367.6}
LAU_3_2___19_FFAR_M156_WP = {"clsid": "{LAU-3 FFAR WP156_TER_2_C}", "name": "LAU-3*2 - 19 FFAR M156 WP", "weight": 673.3414512}
LAU_3_2___19_FFAR_M156_WP_ = {"clsid": "{LAU-3 FFAR WP156_TER_2_L}", "name": "LAU-3*2 - 19 FFAR M156 WP", "weight": 673.3414512}
LAU_3_2___19_FFAR_M156_WP__ = {"clsid": "{LAU-3 FFAR WP156_TER_2_R}", "name": "LAU-3*2 - 19 FFAR M156 WP", "weight": 673.3414512}
LAU_3_2___19_FFAR_Mk1_HE = {"clsid": "{LAU-3 FFAR Mk1 HE_TER_2_C}", "name": "LAU-3*2 - 19 FFAR Mk1 HE", "weight": 618.184664}
LAU_3_2___19_FFAR_Mk1_HE_ = {"clsid": "{LAU-3 FFAR Mk1 HE_TER_2_L}", "name": "LAU-3*2 - 19 FFAR Mk1 HE", "weight": 618.184664}
LAU_3_2___19_FFAR_Mk1_HE__ = {"clsid": "{LAU-3 FFAR Mk1 HE_TER_2_R}", "name": "LAU-3*2 - 19 FFAR Mk1 HE", "weight": 618.184664}
LAU_3_2___19_FFAR_Mk5_HEAT = {"clsid": "{LAU-3 FFAR Mk5 HEAT_TER_2_C}", "name": "LAU-3*2 - 19 FFAR Mk5 HEAT", "weight": 619.9083136}
LAU_3_2___19_FFAR_Mk5_HEAT_ = {"clsid": "{LAU-3 FFAR Mk5 HEAT_TER_2_L}", "name": "LAU-3*2 - 19 FFAR Mk5 HEAT", "weight": 619.9083136}
LAU_3_2___19_FFAR_Mk5_HEAT__ = {"clsid": "{LAU-3 FFAR Mk5 HEAT_TER_2_R}", "name": "LAU-3*2 - 19 FFAR Mk5 HEAT", "weight": 619.9083136}
LAU_3_3___19_FFAR_M156_WP = {"clsid": "{LAU-3 FFAR WP156_TER_3_C}", "name": "LAU-3*3 - 19 FFAR M156 WP", "weight": 986.2121768}
LAU_3_3___19_FFAR_Mk1_HE = {"clsid": "{LAU-3 FFAR Mk1 HE_TER_3_C}", "name": "LAU-3*3 - 19 FFAR Mk1 HE", "weight": 903.476996}
LAU_3_3___19_FFAR_Mk5_HEAT = {"clsid": "{LAU-3 FFAR Mk5 HEAT_TER_3_C}", "name": "LAU-3*3 - 19 FFAR Mk5 HEAT", "weight": 906.0624704}
LAU_68_2___7_FFAR_M156_WP = {"clsid": "{LAU-68 FFAR WP156_TER_2_C}", "name": "LAU-68*2 - 7 FFAR M156 WP", "weight": 287.9121136}
LAU_68_2___7_FFAR_M156_WP_ = {"clsid": "{LAU-68 FFAR WP156_TER_2_L}", "name": "LAU-68*2 - 7 FFAR M156 WP", "weight": 287.9121136}
LAU_68_2___7_FFAR_M156_WP__ = {"clsid": "{LAU-68 FFAR WP156_TER_2_R}", "name": "LAU-68*2 - 7 FFAR M156 WP", "weight": 287.9121136}
LAU_68_2___7_FFAR_Mk1_HE = {"clsid": "{LAU-68 FFAR Mk1 HE_TER_2_C}", "name": "LAU-68*2 - 7 FFAR Mk1 HE", "weight": 267.591192}
LAU_68_2___7_FFAR_Mk1_HE_ = {"clsid": "{LAU-68 FFAR Mk1 HE_TER_2_L}", "name": "LAU-68*2 - 7 FFAR Mk1 HE", "weight": 267.591192}
LAU_68_2___7_FFAR_Mk1_HE__ = {"clsid": "{LAU-68 FFAR Mk1 HE_TER_2_R}", "name": "LAU-68*2 - 7 FFAR Mk1 HE", "weight": 267.591192}
LAU_68_2___7_FFAR_Mk5_HEAT = {"clsid": "{LAU-68 FFAR Mk5 HEAT_TER_2_C}", "name": "LAU-68*2 - 7 FFAR Mk5 HEAT", "weight": 268.2262208}
LAU_68_2___7_FFAR_Mk5_HEAT_ = {"clsid": "{LAU-68 FFAR Mk5 HEAT_TER_2_L}", "name": "LAU-68*2 - 7 FFAR Mk5 HEAT", "weight": 268.2262208}
LAU_68_2___7_FFAR_Mk5_HEAT__ = {"clsid": "{LAU-68 FFAR Mk5 HEAT_TER_2_R}", "name": "LAU-68*2 - 7 FFAR Mk5 HEAT", "weight": 268.2262208}
LAU_68_3___7_FFAR_M156_WP = {"clsid": "{LAU-68 FFAR WP156_TER_3_C}", "name": "LAU-68*3 - 7 FFAR M156 WP", "weight": 408.0681704}
LAU_68_3___7_FFAR_Mk1_HE = {"clsid": "{LAU-68 FFAR Mk1 HE_TER_3_C}", "name": "LAU-68*3 - 7 FFAR Mk1 HE", "weight": 377.586788}
LAU_68_3___7_FFAR_Mk5_HEAT = {"clsid": "{LAU-68 FFAR Mk5 HEAT_TER_3_C}", "name": "LAU-68*3 - 7 FFAR Mk5 HEAT", "weight": 378.5393312}
MAK79_2_MK_20 = {"clsid": "{MAK79_MK20 2L}", "name": "MAK79 2 MK-20", "weight": 464}
MAK79_2_MK_20_ = {"clsid": "{MAK79_MK20 2R}", "name": "MAK79 2 MK-20", "weight": 464}
MAK79_MK_20 = {"clsid": "{MAK79_MK20 1R}", "name": "MAK79 MK-20", "weight": 232}
MAK79_MK_20_ = {"clsid": "{MAK79_MK20 1L}", "name": "MAK79 MK-20", "weight": 232}
Mk4_HIPEG = {"clsid": "{Mk4 HIPEG}", "name": "Mk4 HIPEG", "weight": 612.35}
Mk_20__2__TER_ = {"clsid": "{Mk-20_TER_2_L}", "name": "Mk-20 *2 (TER)", "weight": 491.6}
Mk_20__2__TER__ = {"clsid": "{Mk-20_TER_2_R}", "name": "Mk-20 *2 (TER)", "weight": 491.6}
Mk_20__2__TER___ = {"clsid": "{Mk-20_TER_2_C}", "name": "Mk-20 *2 (TER)", "weight": 491.6}
Mk_20__3__TER_ = {"clsid": "{Mk-20_TER_3_C}", "name": "Mk-20 *3 (TER)", "weight": 713.6}
Mk_77_mod_0 = {"clsid": "{mk77mod0}", "name": "Mk-77 mod 0", "weight": 340}
Mk_77_mod_1 = {"clsid": "{mk77mod1}", "name": "Mk-77 mod 1", "weight": 230}
Mk_77_mod_1__2__TER_ = {"clsid": "{Mk-77 mod 1_TER_2_L}", "name": "Mk-77 mod 1 *2 (TER)", "weight": 507.6}
Mk_77_mod_1__2__TER__ = {"clsid": "{Mk-77 mod 1_TER_2_R}", "name": "Mk-77 mod 1 *2 (TER)", "weight": 507.6}
Mk_77_mod_1__2__TER___ = {"clsid": "{Mk-77 mod 1_TER_2_C}", "name": "Mk-77 mod 1 *2 (TER)", "weight": 507.6}
Mk_77_mod_1__4__MER_ = {"clsid": "{Mk-77 mod 1_MER_4_C}", "name": "Mk-77 mod 1 *4 (MER)", "weight": 1019.8}
Mk_81SE = {"clsid": "{MK-81SE}", "name": "Mk-81SE", "weight": 113.398}
Mk_81SE__5__MER_ = {"clsid": "{Mk-81SE_MER_5_L}", "name": "Mk-81SE *5 (MER)", "weight": 689.8}
Mk_81SE__5__MER__ = {"clsid": "{Mk-81SE_MER_5_R}", "name": "Mk-81SE *5 (MER)", "weight": 689.8}
Mk_81SE__6__MER_ = {"clsid": "{Mk-81SE_MER_6_C}", "name": "Mk-81SE *6 (MER)", "weight": 807.8}
Mk_81__5__MER_ = {"clsid": "{Mk-81_MER_5_L}", "name": "Mk-81 *5 (MER)", "weight": 689.8}
Mk_81__5__MER__ = {"clsid": "{Mk-81_MER_5_R}", "name": "Mk-81 *5 (MER)", "weight": 689.8}
Mk_81__6__MER_ = {"clsid": "{Mk-81_MER_6_C}", "name": "Mk-81 *6 (MER)", "weight": 807.8}
Mk_82_Snakeye__2__TER_ = {"clsid": "{Mk-82 Snakeye_TER_2_L}", "name": "Mk-82 Snakeye *2 (TER)", "weight": 529.6}
Mk_82_Snakeye__2__TER__ = {"clsid": "{Mk-82 Snakeye_TER_2_R}", "name": "Mk-82 Snakeye *2 (TER)", "weight": 529.6}
Mk_82_Snakeye__3__TER_ = {"clsid": "{Mk-82 Snakeye_TER_3_C}", "name": "Mk-82 Snakeye *3 (TER)", "weight": 770.6}
Mk_82_Snakeye__4__MER_ = {"clsid": "{Mk-82 Snakeye_MER_4_C}", "name": "Mk-82 Snakeye *4 (MER)", "weight": 1063.8}
Mk_82_Snakeye__6__MER_ = {"clsid": "{Mk-82 Snakeye_MER_6_C}", "name": "Mk-82 Snakeye *6 (MER)", "weight": 1545.8}
Mk_82__2__TER_ = {"clsid": "{Mk-82_TER_2_L}", "name": "Mk-82 *2 (TER)", "weight": 529.6}
Mk_82__2__TER__ = {"clsid": "{Mk-82_TER_2_R}", "name": "Mk-82 *2 (TER)", "weight": 529.6}
Mk_82__3__TER_ = {"clsid": "{Mk-82_TER_3_C}", "name": "Mk-82 *3 (TER)", "weight": 770.6}
Mk_82__4__MER_ = {"clsid": "{Mk-82_MER_4_C}", "name": "Mk-82 *4 (MER)", "weight": 1063.8}
Mk_82__6__MER_ = {"clsid": "{Mk-82_MER_6_C}", "name": "Mk-82 *6 (MER)", "weight": 1545.8}
Mk_83__2__TER_ = {"clsid": "{Mk-83_TER_2_C}", "name": "Mk-83 *2 (TER)", "weight": 941.6}
Mk_83__3__TER_ = {"clsid": "{Mk-83_TER_3_C}", "name": "Mk-83 *3 (TER)", "weight": 1388.6}
_3_LAU_61 = {"clsid": "{TER,LAU-61*3}", "name": "3*LAU-61", "weight": 98}
class A_4E_C(PlaneType):
id = "A-4E-C"
flyable = True
height = 4.57
width = 8.38
length = 12.22
fuel_max = 2467.5454273299
max_speed = 1082.88
chaff = 30
flare = 30
charge_total = 60
chaff_charge_size = 1
flare_charge_size = 1
category = "Interceptor" #{78EFB7A2-FD52-4b57-A6A6-3BF0E1D6555F}
radio_frequency = 254
panel_radio = {
1: {
"channels": {
1: 264,
2: 265,
4: 254,
8: 258,
16: 267,
17: 251,
9: 262,
18: 253,
5: 250,
10: 259,
20: 252,
11: 268,
3: 256,
6: 270,
12: 269,
13: 260,
7: 257,
14: 263,
19: 266,
15: 261
},
},
}
property_defaults = {
"HideECMPanel": False,
"CBU2ATPP": 0,
"CBU2BATPP": 0,
"CMS_BURSTS": 1,
"CMS_BURST_INTERVAL": 1,
"CMS_SALVOS": 1,
"CMS_SALVO_INTERVAL": 1,
}
class Properties:
class HideECMPanel:
id = "HideECMPanel"
class CBU2ATPP:
id = "CBU2ATPP"
class Values:
_1_tube = 0
_2_tubes = 1
_3_tubes = 2
_4_tubes = 3
_6_tubes = 4
_17_tubes__salvo = 5
class CBU2BATPP:
id = "CBU2BATPP"
class Values:
_2_tubes = 0
_4_tubes = 1
_6_tubes = 2
class CMS_BURSTS:
id = "CMS_BURSTS"
class Values:
_1 = 1
_2 = 2
_3 = 3
_4 = 4
class CMS_BURST_INTERVAL:
id = "CMS_BURST_INTERVAL"
class Values:
_0_2_seconds = 1
_0_3_seconds = 2
_0_4_seconds = 3
_0_5_seconds = 4
class CMS_SALVOS:
id = "CMS_SALVOS"
class Values:
_8 = 1
_12 = 2
_16 = 3
_20 = 4
_24 = 5
_28 = 6
_32 = 7
class CMS_SALVO_INTERVAL:
id = "CMS_SALVO_INTERVAL"
class Values:
_2_seconds = 1
_4_seconds = 2
_6_seconds = 3
_8_seconds = 4
_10_seconds = 5
_12_seconds = 6
_14_seconds = 7
class Liveries:
class Georgia(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Syria(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Finland(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Australia(Enum):
Unmarked = "Unmarked"
International_Australia = "International Australia"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
International_New_Zealand = "International New Zealand"
International_New_Zealand_Kiwi_Red = "International New Zealand Kiwi Red"
International_New_Zealand_Sqn_75 = "International New Zealand Sqn 75"
class Germany(Enum):
Unmarked = "Unmarked"
Trainer_BAE_Systems = "Trainer BAE Systems"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class SaudiArabia(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Israel(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
International_Israel = "International Israel"
class Croatia(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class CzechRepublic(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Norway(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Romania(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Spain(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Ukraine(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Belgium(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Slovakia(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Greece(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class UK(Enum):
Unmarked = "Unmarked"
Trainer_BAE_Systems = "Trainer BAE Systems"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Insurgents(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Hungary(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class France(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Abkhazia(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Russia(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Sweden(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Austria(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Switzerland(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Italy(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class SouthOssetia(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class SouthKorea(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Iran(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class China(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Pakistan(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Belarus(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class NorthKorea(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Iraq(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Kazakhstan(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Bulgaria(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Serbia(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class India(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class USAFAggressors(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
Aggressor_USMC_TopGun_MiG_17 = "Aggressor USMC TopGun MiG-17"
Aggressor_USN_TopGun = "Aggressor USN TopGun"
Aggressor_USN_VF_126_Bandits = "Aggressor USN VF-126 Bandits"
Aggressor_USN_VF_127_Royal_Blues = "Aggressor USN VF-127 Royal Blues"
Aggressor_USN_VFA_127_Cyclons__Forest = "Aggressor USN VFA-127 Cyclons (Forest)"
Aggressor_USN_VFA_127_Cyclons__Sea = "Aggressor USN VFA-127 Cyclons (Sea)"
class USA(Enum):
Unmarked = "Unmarked"
International_Argentina = "International Argentina"
International_Australia = "International Australia"
Trainer_BAE_Systems = "Trainer BAE Systems"
Blue_Angels_no_1 = "Blue Angels no 1"
Blue_Angels_no_2 = "Blue Angels no 2"
Blue_Angels_no_3 = "Blue Angels no 3"
Blue_Angels_no_4 = "Blue Angels no 4"
Blue_Angels_no_5 = "Blue Angels no 5"
Blue_Angels_no_6 = "Blue Angels no 6"
International_Brazil = "International Brazil"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
International_Israel = "International Israel"
International_Kuwait = "International Kuwait"
International_New_Zealand = "International New Zealand"
International_New_Zealand_Kiwi_Red = "International New Zealand Kiwi Red"
International_New_Zealand_Sqn_75 = "International New Zealand Sqn 75"
Trainer_USMC_PTMC = "Trainer USMC PTMC"
Aggressor_USMC_TopGun_MiG_17 = "Aggressor USMC TopGun MiG-17"
USMC_VMA_121_Green_Knights = "USMC VMA-121 Green Knights"
USMC_VMA_124_Memphis_Marines = "USMC VMA-124 Memphis Marines"
USMC_VMA_131_Diamondbacks = "USMC VMA-131 Diamondbacks"
USMC_VMA_142_Flying_Gators = "USMC VMA-142 Flying Gators"
USMC_VMA_211_Avengers = "USMC VMA-211 Avengers"
USMC_VMA_311_Tomcats = "USMC VMA-311 Tomcats"
USMC_VMA_322_Fighting_Gamecocks = "USMC VMA-322 Fighting Gamecocks"
Trainer_USMC_VMAT_102 = "Trainer USMC VMAT-102"
Trainer_USN_Bare_Metal_1956 = "Trainer USN Bare Metal 1956"
Trainer_USN_NFWS_Gray = "Trainer USN NFWS Gray"
Trainer_USN_NFWS_Green = "Trainer USN NFWS Green"
Aggressor_USN_TopGun = "Aggressor USN TopGun"
USN_VA_144_Roadrunners = "USN VA-144 Roadrunners"
USN_VA_153_Blue_Tail_Flies = "USN VA-153 Blue Tail Flies"
USN_VA_163_Saints = "USN VA-163 Saints"
USN_VA_164_Ghostriders = "USN VA-164 Ghostriders"
USN_VA_195_Dambusters = "USN VA-195 Dambusters"
USN_VA_212_Rampant_Raiders = "USN VA-212 Rampant Raiders"
USN_VA_45_Blackbirds = "USN VA-45 Blackbirds"
USN_VA_55_Warhorses = "USN VA-55 Warhorses"
USN_VA_64_Black_Lancers = "USN VA-64 Black Lancers"
Trainer_USN_VC_1_FLECOMPRON_One = "Trainer USN VC-1 FLECOMPRON One"
Trainer_USN_VC_5_Checkertails = "Trainer USN VC-5 Checkertails"
USN_VC_7_Tallyhoers = "USN VC-7 Tallyhoers"
Trainer_USN_VC_8_Redtails = "Trainer USN VC-8 Redtails"
Aggressor_USN_VF_126_Bandits = "Aggressor USN VF-126 Bandits"
Aggressor_USN_VF_127_Royal_Blues = "Aggressor USN VF-127 Royal Blues"
Aggressor_USN_VFA_127_Cyclons__Forest = "Aggressor USN VFA-127 Cyclons (Forest)"
Aggressor_USN_VFA_127_Cyclons__Sea = "Aggressor USN VFA-127 Cyclons (Sea)"
Trainer_USN_VT_7_Eagles = "Trainer USN VT-7 Eagles"
class Denmark(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Egypt(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Canada(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class TheNetherlands(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Turkey(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Japan(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
class Poland(Enum):
Unmarked = "Unmarked"
Community_A_4E = "Community A-4E"
Community_A_4E_II = "Community A-4E II"
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>
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>
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>
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>
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>
pylons = {1, 2, 3, 4, 5}
tasks = [task.CAP, task.CAS, task.SEAD, task.GroundAttack, task.AFAC, task.Refueling]
task_default = task.CAS

View File

@@ -0,0 +1,288 @@
# Requires French Pack mod :
# https://forums.eagle.ru/showthread.php?t=279974
#
from dcs import unittype
class AMX_10RCR(unittype.VehicleType):
id = "AMX10RCR"
name = "AMX-10RCR"
detection_range = 0
threat_range = 4000
air_weapon_dist = 4000
class AMX_10RCR_SEPAR(unittype.VehicleType):
id = "SEPAR"
name = "AMX-10RCR SEPAR"
detection_range = 0
threat_range = 4000
air_weapon_dist = 4000
class ERC_90(unittype.VehicleType):
id = "ERC"
name = "ERC-90"
detection_range = 0
threat_range = 4000
air_weapon_dist = 4000
eprls = True
class VAB__50(unittype.VehicleType):
id = "VAB_50"
name = "VAB .50"
detection_range = 0
threat_range = 1200
air_weapon_dist = 1200
eprls = True
class VAB_T20_13(unittype.VehicleType):
id = "VIB_VBR"
name = "VAB T20/13"
detection_range = 0
threat_range = 2000
air_weapon_dist = 2000
eprls = True
class VAB_MEPHISTO(unittype.VehicleType):
id = "VAB_HOT"
name = "VAB MEPHISTO"
detection_range = 0
threat_range = 4000
air_weapon_dist = 4000
eprls = True
class VBL__50(unittype.VehicleType):
id = "VBL50"
name = "VBL .50"
detection_range = 0
threat_range = 1200
air_weapon_dist = 1200
eprls = True
class VBL_AANF1(unittype.VehicleType):
id = "VBLANF1"
name = "VBL AANF1"
detection_range = 0
threat_range = 1000
air_weapon_dist = 1000
eprls = True
class VBAE_CRAB(unittype.VehicleType):
id = "VBAE"
name = "VBAE CRAB"
detection_range = 0
threat_range = 3500
air_weapon_dist = 3500
eprls = True
class VBAE_CRAB_MMP(unittype.VehicleType):
id = "VBAE_MMP"
name = "VBAE CRAB MMP"
detection_range = 0
threat_range = 3500
air_weapon_dist = 3500
eprls = True
class AMX_30B2(unittype.VehicleType):
id = "AMX-30B2"
name = "AMX-30B2"
detection_range = 0
threat_range = 3500
air_weapon_dist = 2500
class Char_M551_Sheridan(unittype.VehicleType):
id = "SHERIDAN"
name = "Char M551 Sheridan"
detection_range = 0
threat_range = 5000
air_weapon_dist = 5000
class Leclerc_Serie_XXI(unittype.VehicleType):
id = "Leclerc_XXI"
name = "Leclerc Série XXI"
detection_range = 0
threat_range = 5000
air_weapon_dist = 5000
class DIM__TOYOTA_BLUE(unittype.VehicleType):
id = "Toyota_bleu"
name = "DIM' TOYOTA BLUE"
detection_range = 0
threat_range = 1200
air_weapon_dist = 1200
eprls = True
class DIM__TOYOTA_GREEN(unittype.VehicleType):
id = "Toyota_vert"
name = "DIM' TOYOTA GREEN"
detection_range = 0
threat_range = 1200
air_weapon_dist = 1200
eprls = True
class DIM__TOYOTA_DESERT(unittype.VehicleType):
id = "Toyota_desert"
name = "DIM' TOYOTA DESERT"
detection_range = 0
threat_range = 1200
air_weapon_dist = 1200
eprls = True
class DIM__KAMIKAZE(unittype.VehicleType):
id = "Kamikaze"
name = "DIM' KAMIKAZE"
detection_range = 0
threat_range = 50
air_weapon_dist = 50
eprls = True
## FORTIFICATION
class _FIELD_HIDE(unittype.VehicleType):
id = "FieldHL"
name = "*FIELD HIDE"
detection_range = 0
threat_range = 0
air_weapon_dist = 0
class _FIELD_HIDE_SMALL(unittype.VehicleType):
id = "HARRIERH"
name = "*FIELD HIDE SMALL"
detection_range = 0
threat_range = 0
air_weapon_dist = 0
class SmokeD1(unittype.VehicleType):
id = "SmokeD1"
name = "SmokeD1"
detection_range = 0
threat_range = 0
air_weapon_dist = 0
class SmokeD3(unittype.VehicleType):
id = "SmokeD3"
name = "SmokeD3"
detection_range = 0
threat_range = 0
air_weapon_dist = 0
class TRM_2000(unittype.VehicleType):
id = "TRM2000"
name = "TRM-2000"
detection_range = 3500
threat_range = 0
air_weapon_dist = 0
eprls = True
class TRM_2000_Fuel(unittype.VehicleType):
id = "TRM2000_Citerne"
name = "TRM-2000 Fuel"
detection_range = 3500
threat_range = 0
air_weapon_dist = 0
eprls = True
class VAB_MEDICAL(unittype.VehicleType):
id = "VABH"
name = "VAB MEDICAL"
detection_range = 0
threat_range = 0
air_weapon_dist = 0
eprls = True
class VAB(unittype.VehicleType):
id = "VAB_RADIO"
name = "VAB"
detection_range = 0
threat_range = 0
air_weapon_dist = 0
eprls = True
class VBL(unittype.VehicleType):
id = "VBL-Radio"
name = "VBL"
detection_range = 0
threat_range = 0
air_weapon_dist = 0
eprls = True
class Tracma_TD_1500(unittype.VehicleType):
id = "Tracma"
name = "Tracma TD 1500"
detection_range = 0
threat_range = 0
air_weapon_dist = 0
## AIRDEFENCE
class SMOKE_SAM_IR(unittype.VehicleType):
id = "SMOKESAM"
name = "SMOKE SAM IR"
detection_range = 20000
threat_range = 20000
air_weapon_dist = 20000
eprls = True
class _53T2(unittype.VehicleType):
id = "AA20"
name = "53T2"
detection_range = 5000
threat_range = 2000
air_weapon_dist = 2000
class TRM_2000_53T2(unittype.VehicleType):
id = "TRM2000_AA20"
name = "TRM-2000 53T2"
detection_range = 6000
threat_range = 2000
air_weapon_dist = 2000
eprls = True
class TRM_2000_PAMELA(unittype.VehicleType):
id = "TRMMISTRAL"
name = "TRM-2000 PAMELA"
detection_range = 8000
threat_range = 10000
air_weapon_dist = 10000
eprls = True
## INFANTRY
class Infantry_Soldier_JTAC(unittype.VehicleType):
id = "JTACFP"
name = "Infantry Soldier JTAC"
detection_range = 0
threat_range = 500
air_weapon_dist = 500
## ARTILERY
class MO_120_RT(unittype.VehicleType):
id = "M120"
name = "MO 120 RT"
detection_range = 0
threat_range = 15000
air_weapon_dist = 15000
class VAB_MORTIER(unittype.VehicleType):
id = "VAB_MORTIER"
name = "VAB MORTIER"
detection_range = 0
threat_range = 15000
air_weapon_dist = 15000
eprls = True

View File

@@ -0,0 +1,446 @@
from enum import Enum
from dcs import task
from dcs.planes import PlaneType
from dcs.weapons_data import Weapons
class MB_339PAN_Weapons:
ARF8M3_TP = {"clsid": "{ARF8M3_TP}", "name": "ARF8M3 TP", "weight": None}
BRD_4_250_4_MK_76_2_ARF_8M3TP_ = {"clsid": "{BRD-4-250}", "name": "BRD-4-250(4*MK.76+2*ARF-8M3TP)", "weight": 137.6}
Color_Oil_Tank = {"clsid": "{COLOR-TANK}", "name": "Color Oil Tank", "weight": 183}
Empty_Pylon = {"clsid": "{VOID-PYLON-MB339A}", "name": "Empty Pylon", "weight": 20}
Fuel_Tank_330lt = {"clsid": "{FUEL-SUBAL_TANK-330}", "name": "Fuel Tank 330lt", "weight": 315}
GunPod_AN_M3 = {"clsid": "{MB339-AN-M3_L}", "name": "GunPod AN/M3", "weight": 75}
GunPod_AN_M3_ = {"clsid": "{MB339-AN-M3_R}", "name": "GunPod AN/M3", "weight": 75}
GunPod_DEFA553 = {"clsid": "{MB339-DEFA553_L}", "name": "GunPod DEFA553", "weight": 190}
GunPod_DEFA553_ = {"clsid": "{MB339-DEFA553_R}", "name": "GunPod DEFA553", "weight": 190}
LAU_10___4_ZUNI_MK_71___ = {"clsid": "{LAU-10}", "name": "LAU-10 - 4 ZUNI MK 71", "weight": 308}
LR_25___25_ARF_8M3_API_ = {"clsid": "{LR-25API}", "name": "LR-25 - 25 ARF/8M3(API)", "weight": 141}
LR_25___25_ARF_8M3_HEI_ = {"clsid": "{LR-25HEI}", "name": "LR-25 - 25 ARF/8M3(HEI)", "weight": 161}
MAK79_2_MK_20 = {"clsid": "{MAK79_MK20 2L}", "name": "MAK79 2 MK-20", "weight": 464}
MAK79_2_MK_20_ = {"clsid": "{MAK79_MK20 2R}", "name": "MAK79 2 MK-20", "weight": 464}
MAK79_MK_20 = {"clsid": "{MAK79_MK20 1R}", "name": "MAK79 MK-20", "weight": 232}
MAK79_MK_20_ = {"clsid": "{MAK79_MK20 1L}", "name": "MAK79 MK-20", "weight": 232}
MB339_Black_Smoke = {"clsid": "{SMOKE-BLACK-MB339}", "name": "MB339 Black Smoke", "weight": 1}
MB339_Green_Smoke = {"clsid": "{SMOKE-GREEN-MB339}", "name": "MB339 Green Smoke", "weight": 1}
MB339_ORANGE_Smoke = {"clsid": "{SMOKE-ORANGE-MB339}", "name": "MB339 ORANGE Smoke", "weight": 1}
MB339_Red_Smoke = {"clsid": "{SMOKE-RED-MB339}", "name": "MB339 Red Smoke", "weight": 1}
MB339_White_Smoke = {"clsid": "{SMOKE-WHITE-MB339}", "name": "MB339 White Smoke", "weight": 1}
MB339_YELLOW_Smoke = {"clsid": "{SMOKE-YELLOW-MB339}", "name": "MB339 YELLOW Smoke", "weight": 1}
MK76 = {"clsid": "{MK76}", "name": "MK76", "weight": 11.3}
Tip_Fuel_Tank_500lt = {"clsid": "{FUEL-TIP-TANK-500-L}", "name": "Tip Fuel Tank 500lt", "weight": 471}
Tip_Fuel_Tank_500lt_ = {"clsid": "{FUEL-TIP-TANK-500-R}", "name": "Tip Fuel Tank 500lt", "weight": 471}
Tip_Fuel_Tank_Ellittici_320lt = {"clsid": "{FUEL-TIP-ELLITTIC-L}", "name": "Tip Fuel Tank Ellittici 320lt", "weight": 314.2}
Tip_Fuel_Tank_Ellittici_320lt_ = {"clsid": "{FUEL-TIP-ELLITTIC-R}", "name": "Tip Fuel Tank Ellittici 320lt", "weight": 314.2}
class MB_339PAN(PlaneType):
id = "MB-339PAN"
flyable = True
height = 4.77
width = 10.5
length = 12.13
fuel_max = 626
max_speed = 763.2
category = "Interceptor" #{78EFB7A2-FD52-4b57-A6A6-3BF0E1D6555F}
radio_frequency = 124
panel_radio = {
1: {
"channels": {
1: 225,
2: 258,
4: 270,
8: 257,
16: 252,
17: 268,
9: 253,
18: 269,
5: 255,
10: 263,
20: 269,
11: 267,
3: 260,
6: 259,
12: 254,
13: 264,
7: 262,
14: 266,
19: 268,
15: 265
},
},
2: {
"channels": {
1: 225,
2: 258,
4: 270,
8: 257,
16: 252,
17: 268,
9: 253,
18: 269,
5: 255,
10: 263,
20: 269,
30: 263,
21: 225,
11: 267,
22: 258,
3: 260,
6: 259,
12: 254,
24: 270,
19: 268,
25: 255,
13: 264,
26: 259,
27: 262,
7: 262,
14: 266,
28: 257,
23: 260,
29: 253,
15: 265
},
},
}
property_defaults = {
"SoloFlight": False,
"NetCrewControlPriority": 1,
}
class Properties:
class SoloFlight:
id = "SoloFlight"
class NetCrewControlPriority:
id = "NetCrewControlPriority"
class Values:
Pilot = 0
Instructor = 1
Ask_Always = -1
Equally_Responsible = -2
class Liveries:
class Georgia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Syria(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Finland(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Australia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Germany(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class SaudiArabia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Israel(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Croatia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class CzechRepublic(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Norway(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Romania(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Spain(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Ukraine(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Belgium(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Slovakia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Greece(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class UK(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Insurgents(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Hungary(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class France(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Abkhazia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Russia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Sweden(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Austria(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Switzerland(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Italy(Enum):
MB339PAN__Frecce_Tricolori = "MB339PAN 'Frecce Tricolori'"
MB339A__SVBIA____FACTORY = "MB339A 'SVBIA' - FACTORY"
MB339A__61BRIGATA____CAMO = "MB339A '61BRIGATA' - CAMO"
MB339A__61STORMO____CAMO = "MB339A '61STORMO' - CAMO"
MB339A__61STORMO____GREY = "MB339A '61STORMO' - GREY"
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class SouthOssetia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class SouthKorea(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Iran(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class China(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Pakistan(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Belarus(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class NorthKorea(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Iraq(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Kazakhstan(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Bulgaria(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Serbia(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class India(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class USAFAggressors(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class USA(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Denmark(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Egypt(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Canada(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class TheNetherlands(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Turkey(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Japan(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Poland(Enum):
MB339AA__ARMADA____Crippa = "MB339AA 'ARMADA' - Crippa"
MB339AA__ARMADA____Yellow_Band = "MB339AA 'ARMADA' - Yellow Band"
MB339__Factory = "MB339 'Factory'"
class Pylon1:
Tip_Fuel_Tank_500lt = (1, MB_339PAN_Weapons.Tip_Fuel_Tank_500lt)
Tip_Fuel_Tank_Ellittici_320lt = (1, MB_339PAN_Weapons.Tip_Fuel_Tank_Ellittici_320lt)
class Pylon2:
Empty_Pylon = (2, MB_339PAN_Weapons.Empty_Pylon)
LR_25___25_ARF_8M3_HEI_ = (2, MB_339PAN_Weapons.LR_25___25_ARF_8M3_HEI_)
LR_25___25_ARF_8M3_API_ = (2, MB_339PAN_Weapons.LR_25___25_ARF_8M3_API_)
Mk_82 = (2, Weapons.Mk_82)
Matra_Type_155_Rocket_Pod = (2, Weapons.Matra_Type_155_Rocket_Pod)
class Pylon3:
Fuel_Tank_330lt = (3, MB_339PAN_Weapons.Fuel_Tank_330lt)
Empty_Pylon = (3, MB_339PAN_Weapons.Empty_Pylon)
LR_25___25_ARF_8M3_HEI_ = (3, MB_339PAN_Weapons.LR_25___25_ARF_8M3_HEI_)
LR_25___25_ARF_8M3_API_ = (3, MB_339PAN_Weapons.LR_25___25_ARF_8M3_API_)
Mk_82 = (3, Weapons.Mk_82)
LAU_10___4_ZUNI_MK_71___ = (3, MB_339PAN_Weapons.LAU_10___4_ZUNI_MK_71___)
BRD_4_250_4_MK_76_2_ARF_8M3TP_ = (3, MB_339PAN_Weapons.BRD_4_250_4_MK_76_2_ARF_8M3TP_)
Matra_Type_155_Rocket_Pod = (3, Weapons.Matra_Type_155_Rocket_Pod)
class Pylon4:
Color_Oil_Tank = (4, MB_339PAN_Weapons.Color_Oil_Tank)
Empty_Pylon = (4, MB_339PAN_Weapons.Empty_Pylon)
GunPod_AN_M3 = (4, MB_339PAN_Weapons.GunPod_AN_M3)
GunPod_DEFA553 = (4, MB_339PAN_Weapons.GunPod_DEFA553)
LR_25___25_ARF_8M3_HEI_ = (4, MB_339PAN_Weapons.LR_25___25_ARF_8M3_HEI_)
LR_25___25_ARF_8M3_API_ = (4, MB_339PAN_Weapons.LR_25___25_ARF_8M3_API_)
Mk_82 = (4, Weapons.Mk_82)
Matra_Type_155_Rocket_Pod = (4, Weapons.Matra_Type_155_Rocket_Pod)
class Pylon5:
MB339_Red_Smoke = (5, MB_339PAN_Weapons.MB339_Red_Smoke)
MB339_Green_Smoke = (5, MB_339PAN_Weapons.MB339_Green_Smoke)
MB339_YELLOW_Smoke = (5, MB_339PAN_Weapons.MB339_YELLOW_Smoke)
MB339_ORANGE_Smoke = (5, MB_339PAN_Weapons.MB339_ORANGE_Smoke)
MB339_Black_Smoke = (5, MB_339PAN_Weapons.MB339_Black_Smoke)
class Pylon6:
MB339_White_Smoke = (6, MB_339PAN_Weapons.MB339_White_Smoke)
class Pylon7:
Color_Oil_Tank = (7, MB_339PAN_Weapons.Color_Oil_Tank)
Empty_Pylon = (7, MB_339PAN_Weapons.Empty_Pylon)
GunPod_AN_M3_ = (7, MB_339PAN_Weapons.GunPod_AN_M3_)
GunPod_DEFA553_ = (7, MB_339PAN_Weapons.GunPod_DEFA553_)
LR_25___25_ARF_8M3_HEI_ = (7, MB_339PAN_Weapons.LR_25___25_ARF_8M3_HEI_)
LR_25___25_ARF_8M3_API_ = (7, MB_339PAN_Weapons.LR_25___25_ARF_8M3_API_)
Mk_82 = (7, Weapons.Mk_82)
Matra_Type_155_Rocket_Pod = (7, Weapons.Matra_Type_155_Rocket_Pod)
class Pylon8:
Fuel_Tank_330lt = (8, MB_339PAN_Weapons.Fuel_Tank_330lt)
Empty_Pylon = (8, MB_339PAN_Weapons.Empty_Pylon)
LR_25___25_ARF_8M3_HEI_ = (8, MB_339PAN_Weapons.LR_25___25_ARF_8M3_HEI_)
LR_25___25_ARF_8M3_API_ = (8, MB_339PAN_Weapons.LR_25___25_ARF_8M3_API_)
Mk_82 = (8, Weapons.Mk_82)
LAU_10___4_ZUNI_MK_71___ = (8, MB_339PAN_Weapons.LAU_10___4_ZUNI_MK_71___)
Matra_Type_155_Rocket_Pod = (8, Weapons.Matra_Type_155_Rocket_Pod)
BRD_4_250_4_MK_76_2_ARF_8M3TP_ = (8, MB_339PAN_Weapons.BRD_4_250_4_MK_76_2_ARF_8M3TP_)
class Pylon9:
Empty_Pylon = (9, MB_339PAN_Weapons.Empty_Pylon)
LR_25___25_ARF_8M3_HEI_ = (9, MB_339PAN_Weapons.LR_25___25_ARF_8M3_HEI_)
LR_25___25_ARF_8M3_API_ = (9, MB_339PAN_Weapons.LR_25___25_ARF_8M3_API_)
Mk_82 = (9, Weapons.Mk_82)
Matra_Type_155_Rocket_Pod = (9, Weapons.Matra_Type_155_Rocket_Pod)
class Pylon10:
Tip_Fuel_Tank_500lt_ = (10, MB_339PAN_Weapons.Tip_Fuel_Tank_500lt_)
Tip_Fuel_Tank_Ellittici_320lt_ = (10, MB_339PAN_Weapons.Tip_Fuel_Tank_Ellittici_320lt_)
pylons = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
tasks = [task.GroundAttack, task.RunwayAttack, task.CAS, task.AntishipStrike, task.Reconnaissance]
task_default = task.Nothing

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +1,54 @@
from userdata import logging_config
# Logging setup
VERSION_STRING = "2.0.10"
logging_config.init_logging(VERSION_STRING)
import logging
import os
import sys
from shutil import copyfile
import dcs
from PySide2 import QtWidgets
from PySide2.QtGui import QPixmap
from PySide2.QtWidgets import QApplication, QSplashScreen
from dcs import installation
from qt_ui import uiconstants
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.QLiberationWindow import QLiberationWindow
from userdata import persistency, logging as logging_module
from qt_ui.windows.preferences.QLiberationFirstStartWindow import QLiberationFirstStartWindow
from userdata import liberation_install, persistency, liberation_theme
if __name__ == "__main__":
persistency.setup(installation.get_dcs_saved_games_directory())
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" # Potential fix for 4K screens
app = QApplication(sys.argv)
# init the theme and load the stylesheet based on the theme index
liberation_theme.init()
css = ""
with open("./resources/stylesheets/"+liberation_theme.get_theme_css_file()) as stylesheet:
app.setStyleSheet(stylesheet.read())
# Inject custom payload in pydcs framework
custom_payloads = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..\\resources\\customized_payloads")
if os.path.exists(custom_payloads):
dcs.planes.FlyingType.payload_dirs.append(custom_payloads)
else:
# For release version the path is different.
custom_payloads = os.path.join(os.path.dirname(os.path.realpath(__file__)),
"resources\\customized_payloads")
if os.path.exists(custom_payloads):
dcs.planes.FlyingType.payload_dirs.append(custom_payloads)
VERSION_STRING = "2.0"
logging_module.setup_version_string(VERSION_STRING)
logging.info("Using {} as userdata folder".format(persistency.base_path()))
app = QApplication(sys.argv)
first_start = liberation_install.init()
if first_start:
window = QLiberationFirstStartWindow()
window.exec_()
logging.info("Using {} as 'Saved Game Folder'".format(persistency.base_path()))
logging.info("Using {} as 'DCS installation folder'".format(liberation_install.get_dcs_install_directory()))
# Splash screen setup
pixmap = QPixmap("./resources/ui/splash_screen.png")
@@ -38,24 +61,28 @@ if __name__ == "__main__":
uiconstants.load_aircraft_icons()
uiconstants.load_vehicle_icons()
css = ""
with open("./resources/stylesheets/style.css") as stylesheet:
css = stylesheet.read()
# Replace DCS Mission scripting file to allow DCS Liberation to work
print("Replace : " + installation.get_dcs_install_directory() + os.path.sep + "Scripts/MissionScripting.lua")
copyfile("./resources/scripts/MissionScripting.lua", installation.get_dcs_install_directory() + os.path.sep + "Scripts/MissionScripting.lua")
app.processEvents()
try:
liberation_install.replace_mission_scripting_file()
except:
error_dialog = QtWidgets.QErrorMessage()
error_dialog.setWindowTitle("Wrong DCS installation directory.")
error_dialog.showMessage("Unable to modify Mission Scripting file. Possible issues with rights. Try running as admin, or please perform the modification of the MissionScripting file manually.")
error_dialog.exec_()
# Apply CSS (need works)
app.setStyleSheet(css)
GameUpdateSignal()
# Start window
window = QLiberationWindow()
window.showMaximized()
splash.finish(window)
sys.exit(app.exec_())
qt_execution_code = app.exec_()
# Restore Mission Scripting file
logging.info("QT App terminated with status code : " + str(qt_execution_code))
logging.info("Attempt to restore original mission scripting file")
liberation_install.restore_original_mission_scripting()
logging.info("QT process exited with code : " + str(qt_execution_code))

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