Compare commits

...

764 Commits

Author SHA1 Message Date
Dan Albert
8c1f3e8116 Use python, not py.
py is a shortcut that launches the *latest* version of Python on the
machine. https://stackoverflow.com/a/50896577/632035

The build machines were updated to include python 3.9, so we were
doing everything with 3.9 instead of 3.8. pyproj doesn't have a binary
wheel for 3.9 on pypi yet, so we were falling back to building it from
source, which we aren't able to do, breaking the build.
2020-10-28 00:06:56 -07:00
Dan Albert
df00059d3f Fix initial frequencies for support aircraft.
Vaicom (a mod that adds voice control for the communications menus)
isn't able to follow the waypoint frequency change that normally sets
the radio channel for the AWACS/tanker flights. Set the group's
frequency correctly to start so it works.

(cherry picked from commit 4abf806837)
2020-10-17 15:56:48 -07:00
Khopa
2a3bf9821b Fixed EPLRS cherry pick merge. 2020-10-05 19:33:48 +02:00
Khopa
819d775282 EPLRS for 2.1.5 2020-10-05 19:30:43 +02:00
Khopa
efbc6fe3ae Enable EPLRS for ground units that can use it. 2020-10-05 19:29:34 +02:00
Khopa
262ba6c113 Chery picked another fix for this release, so updated changelog 2020-10-05 19:28:55 +02:00
Khopa
c41ecb6735 Fix aircrafts landing point 2020-10-05 19:27:03 +02:00
Khopa
f5c32c6b98 Version 2.1.5 2020-10-05 19:26:07 +02:00
Dan Albert
a1886e37f8 Fix save issues after aborting mission.
When the mission is aborted the pending mission is still in the event
list, which is part of the game option. That event has a reference to
the operation, which in turn contains all the mission generator
objects. Two of these objects are the radio/TACAN allocators, which
use a generator to track the next free channel. Generators cannot be
picked, so because these are transitively part of the game object the
game cannot be saved.

Aside from the briefing generator, none of those objects are
actually needed outside the generation function itself, so just make
them locals instead.

This probably needs a larger refactor at some point. It doesn't look
like we need so many calls into the operation type (it has an
initialize, a prepare, and a generate, and it doesn't seem to need
anything but the last one). The only reason breifinggen needs to
remain a part of the class is because the briefing title and
description are filled in from the derived class, where title and
description should probably be overridden properties instead. I'm also
not sure if we need to make the event list a part of game at all, and
also don't think that the mission needs to be one of these events.
2020-10-05 19:20:57 +02:00
Khopa
7dd3367203 Version number for release 2.1.4 2020-10-03 16:50:56 +02:00
Khopa
e72c82521a Forgot the changelog for 2.1.4 2020-10-03 16:45:21 +02:00
C. Perreau
aca415db23 Merge pull request #179 from Khopa/develop
Release 2.1.4
2020-10-03 16:33:26 +02:00
David Pierron
98b2d8b3b9 typo in the generate_initial_units function name 2020-10-02 13:15:40 -07:00
David Pierron
f8ef5db5a3 bug when continuing an old campaign save 2020-10-02 13:15:40 -07:00
Dan Albert
a44cbe5972 Tone down failure message for missing plugin file.
This looked an awful lot like an error, but it's the common case.
2020-10-01 23:57:53 -07:00
C. Perreau
2066a2e9bc Merge pull request #167 from Khopa/develop
Release 2.1.3
2020-10-01 23:23:06 +02:00
Khopa
f381bf85a4 Fixed JTAC script not working after changes made to lua files 2020-10-01 23:17:32 +02:00
Khopa
44dcdcc8bb Changelog update 2020-10-01 23:17:08 +02:00
Khopa
01220800f3 Fixed Viggen icon 2020-10-01 22:47:58 +02:00
Khopa
8ecb4cdcf4 Added more ground vehicles icons. 2020-10-01 21:09:05 +02:00
Khopa
8402d108c0 Pydcs location 2020-10-01 20:22:11 +02:00
Khopa
75af2d468e Fix A-10C_II icon 2020-10-01 19:38:43 +02:00
Khopa
72ce37f008 Added custom payloads for A-10C II 2020-10-01 19:33:46 +02:00
Khopa
e48e884286 Added A-10C_2. Changed bluefor factions' country to "Combined Joint Task Forces Blue" instead of "USA" (support more units) 2020-10-01 19:20:25 +02:00
Khopa
f9d5c1f8de Update pydcs location 2020-10-01 19:07:06 +02:00
Khopa
0873dcab0a Gitmodule points to pydcs 2020-10-01 19:06:38 +02:00
C. Perreau
a1343c2849 Merge pull request #166 from DanAlbert/build-canaries
Build and archive binaries on push/PR.
2020-10-01 12:53:35 +02:00
Dan Albert
f732cc54d0 Build and archive binaries on push/PR.
Not building a full release, but this makes it easier to test someone
else's PR, or for players to get at pre-release builds.
2020-09-30 21:03:12 -07:00
David Pierron
473a7d5fa4 added a 'mkrelease' config for VS.Code 2020-09-30 19:47:02 -07:00
David Pierron
8054a0b62f removed useless link.cmd.sample file 2020-09-30 19:47:02 -07:00
Dan Albert
7f9cba5d37 Fix more None ATC bugs.
Fixes https://github.com/Khopa/dcs_liberation/issues/164
2020-09-30 19:20:50 -07:00
C. Perreau
f68e6387e6 Merge pull request #161 from VEAF/make-mission-portable
Make mission portable
2020-09-29 23:50:34 +02:00
Khopa
f032001bee Limit number of aircraft that can be bought at a Control Point. 2020-09-29 23:47:57 +02:00
David Pierron
3bae591c04 corrected and enhanced mission portability 2020-09-29 20:46:22 +02:00
Khopa
18a1f0af94 Added credits to new contributor to about dialog. 2020-09-29 20:03:07 +02:00
David Pierron
afbd4a4716 Make mission portable
use inline json.lua and write to %LIBERATION_EXPORT_DIR%, %TEMP%
or the DCS working directory
2020-09-29 17:27:35 +02:00
David Pierron
a98da14c6f Merge pull request #1 from Khopa/master
Merge from base
2020-09-29 15:14:55 +02:00
Khopa
a2a70213a7 Update pydcs location 2020-09-28 00:55:02 +02:00
Khopa
8b0f877041 Verrsion string updated to 2.1.2 2020-09-28 00:42:27 +02:00
Khopa
bf7ad4cad2 Merge remote-tracking branch 'khopa/master' into develop 2020-09-28 00:27:25 +02:00
C. Perreau
66b659c0af Merge pull request #152 from VEAF/introduced-scripts-plugins
Introduced LUA scripts plugins
2020-09-28 00:26:26 +02:00
Khopa
8709ea948f Merge remote-tracking branch 'khopa/master' into develop 2020-09-28 00:21:33 +02:00
Khopa
7236c10403 Changelog update 2020-09-28 00:21:12 +02:00
C. Perreau
dde703ec41 Merge pull request #154 from VEAF/add-tanker-type-to-tanker-name
add tanker type to tanker name
2020-09-28 00:06:49 +02:00
Khopa
aa2e9b123c Fix : AI is not planning flights for Tornado. 2020-09-28 00:03:01 +02:00
Khopa
737e04d09e Merge branch 'master' into develop 2020-09-27 19:16:34 +02:00
C. Perreau
0fe59efd72 Merge pull request #157 from DanAlbert/fix-none
Fix None dereference.
2020-09-27 19:10:31 +02:00
C. Perreau
ddb50e6254 Merge pull request #151 from VEAF/UHF-intraflight-frequency-for-Player-and-Clients-A-10C
UHF Intraflight Frequency for Player and Clients A-10C
2020-09-27 19:09:33 +02:00
Dan Albert
72e6ae4186 Fix None dereference. 2020-09-26 16:32:02 -07:00
David Pierron
4d510f643a add tanker type to tanker name 2020-09-25 17:11:17 +02:00
David Pierron
66f607b5e6 added a comment that links to my forum post 2020-09-25 11:33:07 +02:00
David Pierron
1a125c62e7 added sample __plugins.lst file 2020-09-25 11:21:23 +02:00
David Pierron
84da44a27b Introduced LUA scripts plugins
In order to be able to customize the scripts that can be injected in the
mission, a __plugin.lst file is read and the scripts mentionned in this
file are injected (through DoScriptFile and not DoScript).

A mechanism checks if a standard script (Mist, JTACAutolase) has
already been loaded, to avoid loading them twice.
2020-09-25 11:06:25 +02:00
David Pierron
5e35efcaef UHF Intraflight Frequency for Player and Clients A-10C
In the mission editor, using a VHF frequency for a Player or
Client A-10C results in an error. Changed the radio definitions
to use AN/ARC-164 for intraflight comms.
2020-09-25 10:36:18 +02:00
Khopa
83f221c5e3 Use latest data-export 2020-09-25 01:23:05 +02:00
Khopa
e86a10e9ba JF-17 radio frequency fix. 2020-09-25 01:13:59 +02:00
C. Perreau
7eea328706 Merge pull request #149 from Khopa/develop
2.1.1
2020-09-25 01:06:09 +02:00
Khopa
aa9dcec0ad Version number 2020-09-25 00:58:11 +02:00
Khopa
e9bad2c7eb Version number update and changelog update 2020-09-25 00:56:12 +02:00
Khopa
ce257a31bb Fixed UI bugs when buying new units in base defense menu. 2020-09-25 00:36:13 +02:00
Khopa
c96b5cf4d7 Fixed bug when buying armor at base 2020-09-25 00:25:20 +02:00
Khopa
fb40e9273d Added newest contributors to about dialog. 2020-09-24 20:00:57 +02:00
Khopa
42c9af102b Added KJ 2000 to China as AWACS 2020-09-24 19:56:56 +02:00
Khopa
b7dff59542 P_47 variants added to db 2020-09-24 18:03:10 +02:00
Khopa
266927aa9a Added new payloads for F-16C for SEAD and CAS, added defaults payload for new P-47 variants. 2020-09-24 18:01:20 +02:00
C. Perreau
dcaa8d4e96 Merge pull request #142 from DanAlbert/update-pydcs
Update pydcs.
2020-09-23 00:39:17 +02:00
Khopa
0e2a449553 Fixes to Buy/Sell sam UI 2020-09-23 00:39:01 +02:00
Dan Albert
a70e035e02 Update pydcs.
This fixes the issue where delayed AI flights would not start if the
mission was not first saved via the DCS mission editor.
2020-09-20 15:07:32 -07:00
Khopa
4019da8ba9 Base defense armor unit icon style fix. 2020-09-20 17:15:43 +02:00
Khopa
5042ac1789 P-51/P-47 radios support. 2020-09-20 17:07:09 +02:00
Khopa
4031c9b978 Possible to sell/buy units at SAM location and in airports. 2020-09-19 17:11:43 +02:00
Khopa
65dd9bc286 Fix typo. 2020-09-19 17:10:56 +02:00
Khopa
e210dcb4df Added disband menu in ground object menu. 2020-09-19 14:02:53 +02:00
C. Perreau
52a379229e Merge pull request #134 from pedromagueija/master
Fix typo in CombatStance enumeration
2020-09-17 10:12:27 +02:00
Pedro Magueija
93b2e91c10 Fix usage of CombatStance typo 2020-09-15 15:03:41 +02:00
Pedro Magueija
b8afb01c46 Fix typo in CombatStance enumeration 2020-09-15 14:58:17 +02:00
C. Perreau
59e7665b65 Merge pull request #133 from DanAlbert/radio-naming
Name radios appropriately for each aircraft.
2020-09-12 22:35:49 +02:00
C. Perreau
8a8a835a32 Merge pull request #132 from DanAlbert/fix-radio-reservation
Ensure that allocated channels are reserved.
2020-09-12 22:35:00 +02:00
Dan Albert
6ceab69656 Name radios appropriately for each aircraft. 2020-09-12 12:30:52 -07:00
Dan Albert
9e98f05be0 Ensure that allocated channels are reserved.
This was previously mostly working because the allocator itself was
moving forward, but since each radio has its own allocator, aircraft
with different radios would often get overlapping intra-flight
frequencies.
2020-09-12 12:28:59 -07:00
Khopa
5da1db91fd Normandy airfields data export. 2020-09-12 15:49:30 +02:00
C. Perreau
f0d58acd62 Merge pull request #131 from DanAlbert/more-aircraft-radios
Add radio information for more aircraft.
2020-09-12 11:36:43 +02:00
Dan Albert
722ec00076 Add radio information for more aircraft.
Adds the following:

* AJS37
* AV-8B
* JF-17

This does move the preset channel allocation logic into its own class,
since we need to customize that behavior for the AJS37 since it has a
rather unique preset channel layout (see the comments in
`ViggenRadioChannelAllocator` for details).
2020-09-11 18:45:19 -07:00
Khopa
2db740e1ad Finished airfield export for PG map. 2020-09-11 22:00:22 +02:00
C. Perreau
70cd0e8c31 Merge pull request #130 from DanAlbert/callsigns
Handle callsigns for flights.
2020-09-11 20:53:44 +02:00
C. Perreau
848c92ec25 Merge pull request #129 from DanAlbert/fix-kneeboard-tacan
Fix TACAN/ILS info for airfields.
2020-09-11 20:52:15 +02:00
C. Perreau
98946d0a63 Merge pull request #128 from DanAlbert/coalesce-target-points
Improve target waypoint behavior in the kneeboard.
2020-09-11 20:51:52 +02:00
C. Perreau
e0a39104b1 Merge pull request #127 from DanAlbert/first-waypoint
Add first waypoint to FlightData.
2020-09-11 20:48:04 +02:00
C. Perreau
a4f66298a4 Merge pull request #126 from DanAlbert/syria-map-data
Add map data for Syria.
2020-09-11 20:47:32 +02:00
Dan Albert
993bf50012 Handle callsigns for flights.
We don't configure the callsigns that pydcs uses, so instead read
those from pydcs and use them where appropriate instead of just
guessing.

Fixes https://github.com/Khopa/dcs_liberation/issues/113.
2020-09-11 01:47:13 -07:00
Dan Albert
51bfc9a59b Update pydcs. 2020-09-11 01:47:13 -07:00
Dan Albert
837795e87a Fix TACAN/ILS info for airfields. 2020-09-10 17:05:32 -07:00
Dan Albert
d4820b2435 Coalesce large runs of target waypoints.
Since we create a target waypoint for every target in a
strike/SEAD/DEAD objective area (including every ground vehicle), the
kneeboard can quickly be overrun with target waypoints. When there are
many target waypoints, collapse them all into a single row for
brevity.
2020-09-10 01:38:27 -07:00
Dan Albert
180537cd48 Fix SEAD/DEAD reversal. 2020-09-10 01:38:27 -07:00
Dan Albert
8bc77bbf18 Make waypoint types less error prone.
Make the type of the waypoint a non-optional part of the constructor.
Every waypoint needs a type, and there's no good default (the previous
default, `TAKEOFF`, is actually unused). All of the target waypoints
were mistakenly being set as `TAKEOFF`, so I've fixed that in the
process.

Also, fix the bug where only the last custom target of a SEAD
objective was being added to the waypoint list because the append was
scoped incorrectly.
2020-09-10 01:38:25 -07:00
Dan Albert
474b606524 Add map data for Syria. 2020-09-08 16:45:08 -07:00
Dan Albert
8a7e43ef42 Also dedup ATC frequencies.
Some airports on the Syria map share ATC frequencies.
2020-09-08 16:45:08 -07:00
C. Perreau
7b5b486f0e Merge pull request #123 from DanAlbert/fix-radios
Fix radio information.
2020-09-07 23:50:36 +02:00
Dan Albert
ebedc02a0a Add first waypoint to FlightData.
The first waypoint is automatically added by pydcs, so it's not
actually in our waypoint list from the flight planner. Import is from
the group so it shows up in the kneeboard.
2020-09-06 22:07:10 -07:00
Dan Albert
ad42a3d956 Fix radio information.
Not every aircraft has a pydcs radio index, so we can't use that to
index into a list. Any mission with an A-10C crashes, since it would
try to use `None - 1` to index into the list of radios to find the
intra-flight radio.

Also fix the radio ranges for the newly added radios. The current
implementation can't model gaps, so extending the radio ranges across
those gaps means that we might allocate channels that aren't tunable
by those radios. Additionally, the end frequency is exclusive rather
than inclusive, so fix the ranges to include that last tunable
frequency.
2020-09-06 16:44:46 -07:00
Khopa
98d75bc721 Tomcat and M2000 radios support 2020-09-06 15:43:44 +02:00
Khopa
14fe68eb54 Added Mirage 2000 radios 2020-09-06 15:10:10 +02:00
Khopa
b6938c14ca Added southern airfields of PG map 2020-09-06 15:09:40 +02:00
Khopa
3c96c1d5b1 Removed incorrect imports causing pydcs being imported twice; 2020-09-06 12:33:40 +02:00
Khopa
2969ce2d56 Removed unused file 2020-09-06 12:11:03 +02:00
C. Perreau
bca92f5ee7 Merge pull request #122 from DanAlbert/fix-pydcs-path
Fix incorrect pydcs import paths.
2020-09-06 11:49:58 +02:00
C. Perreau
1c1982952e Merge pull request #121 from DanAlbert/preferred-runway
Pick ILS runways if possible.
2020-09-06 11:48:47 +02:00
Dan Albert
4b74b5a13d Fix incorrect pydcs import paths.
I've been wrongly importing these from `pydcs.dcs` instead of just
`dcs`, because that was what PyCharm thought they were. These will all
be broken when we get back to using a real pydcs instead of relying on
its directory being in our tree.

This page in the wiki should be updated:
https://github.com/Khopa/dcs_liberation/wiki/Developer's-Guide

Instead of recommending that `PYTHONPATH` be updated in the run
configuration, it should instead recommend that Settings -> Project:
dcs_liberation -> Project Structure be set to exclude the pydcs
directory from the dcs_liberation content root, and add the pydcs
directory as a *separate* content root.

Alternatively, we could recommend that configure a virtualenv (good
advice anyway, and pycharm knows how to set them up) that have people
run `pip install -e pydcs`.

I think even easier would be switching from the virtualenv-style
requirements.txt to pipenv, which can actually encode the `-e` style
pip install into its equivalent of requirements.txt.
2020-09-06 01:16:57 -07:00
Dan Albert
0fc00fac38 Pick ILS runways if possible. 2020-09-04 15:58:43 -07:00
C. Perreau
4446a7f060 Merge pull request #119 from DanAlbert/radio-setup
Allocate per-flight radio channels, set up preset channels.
2020-09-04 12:50:44 +02:00
Dan Albert
9d31c478d3 Fix briefing generation.
I removed the nav target info from the briefing because that doesn't
seem to have been doing what it was intended to do. It didn't give any
actual target information, all it would show was (example is a  JF-17
strike mission):

    PP1
    PP2
    PP3
    PP4

Without any additional context that doesn't seem too helpful to me.
I'll be following up (hopefully) shortly by adding target information
(type, coordinates, STPT/PP, etc) to both the briefing and the
kneeboard that will cover that.

Refactor a bunch to share some code with the kneeboard generator as
well.
2020-09-04 01:06:31 -07:00
Dan Albert
b31e186d1d Fix inconsistent runway numbering.
pydcs gives us a 3-digit runway, but most of our data is 2-digit
runway numbers, so we weren't finding any runways for those airfields.
2020-09-04 00:56:26 -07:00
Dan Albert
d02a3a0d3f Add carrier support to kneeboards. 2020-09-04 00:56:26 -07:00
Dan Albert
a9e65cc83d Setup default radio channels for player flights. 2020-09-03 15:02:59 -07:00
Dan Albert
010d505f04 Reserve frequencies used by beacons. 2020-09-03 15:02:59 -07:00
Dan Albert
95b9a3e1aa Check in beacon lists for most maps. 2020-09-03 15:02:59 -07:00
Dan Albert
d051859371 Add beacon list importer. 2020-09-03 15:02:59 -07:00
Dan Albert
af596c58c3 Control radio/TACAN allocation, set flight radios.
Add central registries for allocating TACAN/radio channels to the
Operation. These ensure that each channel is allocated uniquely, and
removes the caller's need to think about which frequency to use.

The registry allocates frequencies based on the radio it is given,
which ensures that the allocated frequency will be compatible with the
radio that needs it. A mapping from aircraft to the radio used by that
aircraft for intra-flight comms (i.e. the F-16 uses the AN/ARC-222)
exists for creating infra-flight channels appropriate for the
aircraft. Inter-flight channels are allocated by a generic UHF radio.

I've moved the inter-flight radio channels from the VHF to UHF range,
since that's the most easily allocated band, and inter-flight will be
in the highest demand.

Intra-flight radios are now generally not shared. For aircraft where
the radio type is not known we will still fall back to the shared
channel, but that will stop being the case as we gain more data.

Tankers have been moved to the Y TACAN band. Not completely needed,
but seems typical for most missions and deconflicts the tankers from
any unknown airfields (which always use the X band in DCS).
2020-09-03 15:02:59 -07:00
Dan Albert
b4e3067718 Update pydcs. 2020-09-03 15:02:59 -07:00
C. Perreau
40f8ae1cde Merge pull request #120 from DanAlbert/sort-objectives
Sort objective name combo boxes.
2020-09-03 21:36:06 +02:00
Dan Albert
f5f45a098e Sort objective name combo boxes. 2020-09-03 00:42:20 -07:00
Khopa
d429804c1f Airfields data for Nevada 2020-09-01 20:58:27 +02:00
Khopa
f5f770f401 Added airfields data for The Channel map. 2020-09-01 20:32:32 +02:00
Khopa
91d6ed0ee7 Completed Caucasus airfield data. 2020-09-01 20:23:52 +02:00
Khopa
06858b26c7 Added additional informations to the AirfieldData class 2020-09-01 13:47:41 +02:00
C. Perreau
7e60a43f53 Merge pull request #114 from DanAlbert/kneeboard
Generate kneeboards for player flights.
2020-09-01 12:51:04 +02:00
Dan Albert
e7e82dcd0b Build mission kneeboards.
This includes most of the briefing information in the kneeboard:

* Airfield info
* Waypoint info
* Comm info
* AWACS
* Tankers
* JTAC

There's more that could be done:

* Restrict tankers to the type compatible with the current aircraft
* Support for carriers
* Merge all relevant comm info (tankers, AWACS, JTAC, other flights)
  into the comm ladder

This gives us a good start and a framework to build on. Very likely
that we'll want to split part of this (probably the comm ladder) off
onto a separate page once we start adding more to this, since it's a
pretty full page currently.

Also missing is any checking that the contents do not go beyond the
bounds of the page. We could add this if needed. For now the page has
enough room for about a dozen waypoints, which is quite a bit more
than most missions need.
2020-08-31 13:01:05 -07:00
Dan Albert
66af6be063 Update pydcs. 2020-08-31 13:01:05 -07:00
C. Perreau
69e1d2779d Merge pull request #112 from DanAlbert/gitignore
Update gitignore.
2020-08-31 12:04:37 +02:00
Dan Albert
001752a81e Update gitignore. 2020-08-29 19:58:03 -07:00
C. Perreau
1000041bce Merge pull request #109 from DanAlbert/non-modal-mission-planning
Make the mission planning window non-modal.
2020-08-29 18:06:57 +02:00
Dan Albert
d50e791c30 Make the mission planning window non-modal.
Doesn't appear to be any need for this to be modal. Making it
non-modal allows interacting with the map during planning.
2020-08-28 13:42:38 -07:00
Khopa
7817d59989 Fixed campaign sometimes not starting when the user does not explicitly re-select a campaign and just kee p the default one.. 2020-08-27 23:47:00 +02:00
Khopa
139c4c1dd8 Fixed crash on mission generation when clearing slots. 2020-08-27 23:46:10 +02:00
Khopa
75bb6941d3 Added version string in the window title 2020-08-24 22:49:55 +02:00
Khopa
e92fb38271 Fixed Sweden 1990 faction not working 2020-08-24 22:32:37 +02:00
C. Perreau
e4eeef8f99 Merge pull request #102 from parithon/menukbsupport
Add keyboard support to the menu system
2020-08-24 21:42:27 +02:00
Khopa
21c355bc9f Fix small issue with ground object menu when the ground object is empty. 2020-08-24 21:34:24 +02:00
Anthony Conrad
04c878f57c Added keyboard support to the menu system 2020-08-23 22:25:16 -07:00
Anthony Conrad
ef23ce58d1 Added keyboard support for the menu system 2020-08-23 21:54:12 -07:00
C. Perreau
d213fa1b91 Merge pull request #98 from Khopa/develop
2.1.1-alpha-2
2020-08-23 18:26:14 +02:00
Khopa
4b2804427e Possible to replace SAM, possible to see building recon images on ground site. 2020-08-23 18:25:23 +02:00
Khopa
d707a59a71 Added thumbnail for strike targets / buildings. 2020-08-23 18:02:36 +02:00
Khopa
923358b364 Cheat menu : added buttons to remove money 2020-08-23 15:29:11 +02:00
C. Perreau
1d0c0ac19c Merge pull request #96 from parithon/develop
Add a Github Action and Installer
2020-08-23 14:14:30 +02:00
C. Perreau
7c97ecddac Merge branch 'develop' into develop 2020-08-23 14:08:09 +02:00
Khopa
bcae51cc92 Added possibility to repair SAM sites (WIP) 2020-08-23 13:43:33 +02:00
Anthony Conrad
18896a69cf Added PyDCS as a submodule 2020-08-22 20:00:07 -07:00
Anthony Conrad
4c310d268d Added an installer script using Inno Setup and Github Action to create releases when a tag is pushed. 2020-08-22 18:44:11 -07:00
Khopa
70babd9c32 Added Incirlik airbase in the Inherent Resolve campaign 2020-08-22 03:53:51 +02:00
Khopa
15d0edce2e Added MQ_9 Reaper as a recruitable CAS unit to usa 2005 2020-08-22 03:52:54 +02:00
Khopa
d7ab1774ac AI was not using AH_1W 2020-08-22 03:51:53 +02:00
Khopa
42d9607b0d Syria 2011 update 2020-08-22 03:51:18 +02:00
Khopa
bf82474fd7 Fixed Viper TGP bug. 2020-08-22 02:59:24 +02:00
Khopa
64211275cc Changelog update 2020-08-21 13:14:36 +02:00
Khopa
cf8060f7ff AH-64 better payloads management. 2020-08-21 13:14:03 +02:00
Khopa
cee1d01d9a Payloads fix for AH-64A. And AH-64D has payloads for all missions type. 2020-08-21 12:50:37 +02:00
Khopa
536d763a8e usa 1990 tweaks 2020-08-21 12:09:59 +02:00
Khopa
6d27b6ce41 Fixed position of Tarawa on Syrian Civil War campaign.(A new save is required though) 2020-08-21 12:03:50 +02:00
Khopa
0d05655e94 Merge branches 'develop' and 'master' of https://github.com/khopa/dcs_liberation into develop 2020-08-21 11:49:39 +02:00
C. Perreau
9cf697d72c Merge pull request #88 from Steveveepee/Steveveepee-patch-1
Update QWaitingForMissionResultWindow.py
2020-08-21 11:34:49 +02:00
C. Perreau
f0f818c524 Merge pull request #89 from Steveveepee/Steveveepee-patch-2
Update aircraft.py
2020-08-21 11:34:30 +02:00
Steve Pole
d2a3448819 Update aircraft.py
corrected spelling of aircrafts to aircraft
2020-08-21 17:07:10 +10:00
Steve Pole
1a25b15bce Update QWaitingForMissionResultWindow.py
corrected spelling of aircrafts to aircraft
2020-08-21 17:05:50 +10:00
Khopa
83808a63ed Fix inverted Syria map starting point 2020-08-21 03:06:19 +02:00
C. Perreau
515d1d0dee Merge pull request #83 from Khopa/develop
Version 2.1.0
2020-08-21 02:12:07 +02:00
Khopa
2d47df96b6 Better performances for Golan heights startup with only one frontline. 2020-08-21 01:13:20 +02:00
Khopa
ad4d71316f Israel 2000 update 2020-08-21 01:13:00 +02:00
Khopa
40932c9e84 More Performance for Golan heights startup with only one frontline. 2020-08-21 01:07:25 +02:00
Khopa
59bee5f23e Changelog update 2020-08-21 01:06:38 +02:00
Khopa
e6f00febea Credits 2020-08-21 01:06:00 +02:00
Khopa
6ea694bc7e Added more Syria campaigns 2020-08-21 00:41:34 +02:00
Khopa
8f7a8edde4 Added custom payloads for AH-1W 2020-08-21 00:39:31 +02:00
Khopa
11c7107152 Fixed assymetric default F16 payload for CAS 2020-08-21 00:37:04 +02:00
Khopa
d18a9f376f Added Syria map with GolanHeights setup.
Added a setting to forbid navy units on some control points.
2020-08-20 22:15:54 +02:00
Khopa
6ba95d8c70 Syria terrain update 2020-08-20 22:14:59 +02:00
Khopa
1c00418d64 Syria polygon, terrain and background image added. 2020-08-20 21:04:20 +02:00
Khopa
602e7fb530 Added syria map icon 2020-08-20 19:12:30 +02:00
Khopa
e6a0a1d4a4 Added payloads for drones. Possibility to setup a different JTAC unit for some factions. China using Wingloong instead of Reaper as JTAC unit. 2020-08-20 19:11:51 +02:00
Khopa
136cf143bd Added payloads for drones. Possibility to setup a different JTAC unit for some factions. China using Wingloong instead of Reaper as JTAC unit. 2020-08-20 16:08:52 +02:00
Khopa
5afa2a23f6 Version String managed in a single place. And shown in about Window 2020-08-20 16:02:16 +02:00
Khopa
513c81b508 Changelog update 2020-08-20 14:30:52 +02:00
Khopa
45af66e000 Fixed T+ not updating in the list of flight shown in the mission planner. 2020-08-20 14:22:10 +02:00
Khopa
b38f6c39e4 Changelog update with TODO 2020-08-20 14:21:06 +02:00
Khopa
036874fbf0 Preparing version 2.1.0 2020-08-20 13:12:26 +02:00
Khopa
9f3b49a7f5 Changelog update 2020-08-20 13:11:35 +02:00
Khopa
9c35156db9 Fix : First unit of base defenses group was not controllable with Combined Arms. 2020-08-20 12:54:03 +02:00
Khopa
ab2edc6e59 Added Syrian faction 1982. + Mig-25PD better support. 2020-08-20 12:53:34 +02:00
Khopa
9af278217c More start date. Some small factions changes, F-16A support. 2020-08-20 12:39:18 +02:00
Khopa
13dbc9c0fe Added error message in mission when state file can not be written. 2020-08-20 01:09:10 +02:00
Khopa
14f7fbe794 Added new exclusions zones in caucasus map 2020-08-20 00:18:07 +02:00
Khopa
a60e6aa860 Reworked campaign selection wizard. Added two small scale camapaigns on PG map 2020-08-20 00:17:10 +02:00
Khopa
220e72322c Added new factions in anticipation for new syria map. 2020-08-18 21:08:26 +02:00
Khopa
1a100dc54b Merge branches 'develop' and 'master' of https://github.com/khopa/dcs_liberation into develop 2020-08-18 17:53:27 +02:00
C. Perreau
04b95c986d Update README.md 2020-08-17 15:22:39 +02:00
C. Perreau
8f6bb90945 Update README.md 2020-08-17 15:21:57 +02:00
C. Perreau
50e78bd069 Update README.md 2020-08-17 15:20:14 +02:00
C. Perreau
ce60e1a8f8 Update README.md 2020-08-17 15:19:48 +02:00
C. Perreau
fb7ed19f7a Merge pull request #72 from root0fall/add_budget_update
add budget preview to purchase dialogue
2020-08-17 11:46:23 +02:00
root0fall
970888b5ca add budget preview to purchase dialogue 2020-08-17 12:37:02 +08:00
C. Perreau
8c934654ba Update README.md 2020-08-16 16:44:38 +02:00
C. Perreau
ad3dc70cfd Merge pull request #62 from Khopa/develop
Develop
2020-08-16 16:42:21 +02:00
Khopa
ae5949bc7f Added Ka-50 to Russia 1990 2020-08-16 16:32:59 +02:00
Khopa
c7c563e68c Requirements update to new pydcs version 2020-08-16 16:31:06 +02:00
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
Khopa
59986d74f4 Generate random TACAN frequency for ships at start.
TACAN infos are displayed in briefing.
2020-05-29 03:28:09 +02:00
Khopa
8afdf5ef65 Polishing, Bug Fixes, Slight improvements to flight generator for BARCAP. 2020-05-29 03:05:27 +02:00
Khopa
fc64e57495 Ground objects have 'Objective' name for easier search. Predefined Waypoint generator entirely reworked.
Added finances menu, and info panel.
2020-05-29 00:40:06 +02:00
Khopa
6dec5ea8f8 Reworked payloads, factions, map display, carrier. Re-added Tarawa support, many minor bug fixes. UI changes. 2020-05-27 21:45:58 +02:00
Khopa
3f2aafcd28 Now possible to create/delete flights. 2020-05-25 14:54:02 +02:00
Khopa
7a3ee6b1a9 Frontline progression is now based on combat results. 2020-05-25 04:09:51 +02:00
Khopa
f7d9c62afb Updated mission launch instructions. 2020-05-25 01:22:20 +02:00
Khopa
1a26a7f346 Fix an issue on Nevada map, cp not well connected. 2020-05-25 00:52:46 +02:00
Khopa
f6ff4405f8 Merge branch 'qt_ui' of https://github.com/shdwp/dcs_liberation into qt_ui 2020-05-24 23:53:51 +02:00
Khopa
14ceb0abc6 Fix : Interceptor groups can have custom waypoints. 2020-05-24 23:50:30 +02:00
Khopa
c9a3af6065 Flight waypoint editor to select targets 2020-05-24 23:44:06 +02:00
Khopa
4e4a7fe84e Budget amount per turn, now depends on factory owned and such 2020-05-24 21:30:05 +02:00
Khopa
989d25e2e2 Updated UI ground objects icons 2020-05-24 20:53:41 +02:00
Khopa
f57e453d8d Ground war rework 2020-05-24 20:32:45 +02:00
Wrycu
fcfa785ae9 fix(save): correct openbeta detection 2020-01-18 11:29:16 -08:00
Wrycu
3de688da29 fix(payloads): fix for payloads when compiled into an exe 2020-01-18 11:28:26 -08:00
Khopa
5884d9d120 Made it possible to toggle 'flight paths' visibility. 2019-12-14 20:32:39 +01:00
Khopa
074ea5c719 JF-17 Support (Require pydcs own data export) 2019-12-09 02:09:50 +01:00
Khopa
e794446a54 Fix briefing text being wrong 2019-12-04 19:42:46 +01:00
Khopa
1320a67e1f Fix briefing generation, missing line break 2019-12-04 19:39:04 +01:00
Khopa
7c45177650 Fix issue with bullseye missing causing a crash when launching the mission in MP on a server. 2019-12-04 19:18:20 +01:00
Khopa
6b2d6ab57f Updated pydcs version in requirements.txt 2019-11-21 22:22:39 +01:00
Khopa
04add8ebb5 Fix weird import issue in operation.py. 2019-11-21 22:08:05 +01:00
Khopa
ad8138fb04 Fix an issue with player UH-1H radio 2019-11-21 19:58:28 +01:00
Khopa
6598e034c1 Briefing generation changed to match new flight. Include info for all flight containing client slots; 2019-11-21 19:56:26 +01:00
Khopa
bba51c6a23 Changed position of the carrier on Caucasus small map 2019-11-21 19:55:29 +01:00
Khopa
7d524300e5 Start window maximized 2019-11-21 19:55:03 +01:00
Khopa
a25a0031ff Improved CAS flight waypoints generated by ai flight planner. 2019-11-11 02:41:17 +01:00
Khopa
98b899c9c7 Fix for SEAD flights not being correctly configured. 2019-11-10 23:41:47 +01:00
Khopa
4424425dd4 Changed default map when creating new game. (Added 'recommended' label to the maps i really tested the most) 2019-11-03 17:32:34 +01:00
Khopa
85de3a09ea Remove triggers from generated mission for now. Do not generate the 'quick' mission
Fix range for ai flight planner so they are more likely to plan CAS flights
(It's up to the player to setup flight on the runway or in flight)
2019-11-03 17:27:30 +01:00
Khopa
e82db1fecd Only allow recruiting carrier units in aircraft carrier groups. Generate one group on carrier when possible. 2019-10-26 23:54:33 +02:00
Khopa
76638b549f Generate ship groups for carriers. Carriers can be destroyed. Faction need to have carrier available. 2019-10-26 22:59:59 +02:00
Khopa
2936df6a02 Fix error (unable to start DCS liberation if no save file exists) 2019-10-26 20:58:28 +02:00
Khopa
27e3cf8ac5 Added possibility to setup parking slot type for players' flight. 2019-10-23 17:01:41 +02:00
Khopa
adf1f8db8c Print weapons with their pretty name in loadout editor 2019-10-20 01:54:33 +02:00
Khopa
9f319ab99a Added loadout editor to mission preparation screen. 2019-10-19 16:14:40 +02:00
Khopa
48a40f2511 Stats view now has a tab for vehicles forces. Display waypoint coordinates in waypoint tab. 2019-10-19 13:12:21 +02:00
Khopa
7fbc75b375 New mission briefing menu, work in progress. 2019-10-19 00:07:37 +02:00
Khopa
65a54acd4f Generate ground forces on all active frontlines. 2019-10-17 01:45:46 +02:00
Khopa
de96552f78 Actually generate the planned flights from the flight planner. 2019-10-16 23:20:11 +02:00
Khopa
fee959940a Base menu layout improved. 2019-10-16 22:22:16 +02:00
Khopa
48748bbc39 Improved base menu to show planned AI flights and base defence. (WIP) 2019-10-16 00:41:02 +02:00
Khopa
827138fc6a AI Flight planner generate CAS & SEAD 2019-10-15 23:52:43 +02:00
Khopa
b7ee98dcd6 Flight Planner first version (just print planned flight in log but does not generate them yet) 2019-10-15 23:06:21 +02:00
Khopa
fa99df3ce7 Normandy map image added to repo (was missing in last commit). 2019-10-15 23:05:43 +02:00
Khopa
d2ea6ed2fd Don't show airbase armor & air defense. 2019-10-15 19:19:44 +02:00
Khopa
d8d17e5c18 F_14B client slots are now by default using pre-alignement. 2019-10-14 18:53:43 +02:00
Khopa
0519438292 Improved german WW2 flak group generator. 2019-10-14 01:49:30 +02:00
Khopa
09b8ff6b93 Generate AA & armor to defend airbase. Destruction status correctly tracked. 2019-10-14 01:25:48 +02:00
Khopa
bd66dcb39e Added support for Normandy WW2 map 2019-10-13 23:00:26 +02:00
Khopa
93504eaf7a Added & generated Normandy theater geometry data 2019-10-13 21:24:13 +02:00
Khopa
9e116f481e Fixed issue with P51D liveries that caused errors. 2019-10-13 17:57:38 +02:00
Khopa
bd95258176 Fixed issue with lost helicopters causing errors in debriefing.
Mission generated now configure bluefor and redfor coalition properly, so it is possible to use country that are not in the default coalitions.
Added insurgent faction.
2019-10-13 17:17:33 +02:00
Khopa
a7e202bbc8 Made it possible to capture airbase ingame; 2019-10-13 05:16:34 +02:00
Khopa
3f5f4f4bb1 New automatic de-briefing system implemented 2019-10-13 03:40:22 +02:00
Khopa
4365db0fae Fix : Create default blank liveries for the F_16C_50 to avoid errors at mission generation; 2019-10-12 11:17:00 +02:00
Khopa
82bb608fd3 Mission units destroyed are stored in a json file being written mission runtime. (First step that will remove the need to save the debriefing manually after mission)
Using Mist framework to do this in the mission script env.
2019-10-12 03:21:33 +02:00
Khopa
ba0b3adf71 Added some factions, refactor bluefor/redfor distinction code. 2019-10-12 00:02:07 +02:00
Khopa
707e1f8b67 Refactored factions in separates files to declutter db.py. 2019-10-11 23:08:00 +02:00
Khopa
7f97e894a3 Fix issue with Zu23 Ural aa site generator 2019-10-11 02:07:08 +02:00
Khopa
19118f7b84 Update factions. 2019-10-11 02:05:18 +02:00
Khopa
63c46d1b21 Removed placeholder text. Polished UI when no saved game is found. 2019-10-11 01:27:29 +02:00
Khopa
4c3ff906ff Improved layout for airbase window layout.
Fixed missing icons for some windows.
2019-10-11 01:14:43 +02:00
Khopa
6b77e1cce5 Added possibility to not display SAM ranges in display options. 2019-10-11 00:27:10 +02:00
Khopa
fdd8f102e6 Generate battle environment : SEAD + CAS flight.
Added more factions.
2019-10-11 00:18:25 +02:00
Khopa
2d0c195e46 Added SAM HQ-7, tweaks in db 2019-10-08 22:35:08 +02:00
Khopa
f5a5fb765b Show SAM range on map. 2019-10-08 21:42:48 +02:00
Khopa
f698cb66b8 Ally SAM are shown with blue icon on map. 2019-10-08 21:07:06 +02:00
Khopa
fc51b16e4a Added playable F16C_Bl50 support (For now, you need to update pydcs to the version on my own fork at https://github.com/Khopa/dcs for it to work)
+ Payload overrides for F/A-18C and M-2000-5
2019-10-08 20:45:45 +02:00
Khopa
0365d7a900 Fix issue with payloads loading. 2019-10-08 00:44:57 +02:00
Khopa
7a14376765 Generate CAP on whole map, for 2 hours. Added China. 2019-10-07 01:57:36 +02:00
Khopa
2167953b87 Ground objects are always generated and destroyable, even when it's not the current mission objective.
Fix : SAM site destruction status is saved correctly.
Added most SAM site to generator.
2019-10-06 16:14:13 +02:00
Khopa
17352bfcf7 Fix : Not possible anymore to start a mission by clicking the PendingDelivery event icon. 2019-10-06 01:02:49 +02:00
Khopa
d4577aa7a6 Briefing Window : Only show "clients slot" spinbox if the aircraft is flyable. 2019-10-06 00:54:02 +02:00
Khopa
e955c10170 Added smaller Caucasus map for dev test and smaller campaign 2019-10-05 13:13:43 +02:00
Khopa
9d4b6183b0 Added Iranian faction, SAM SA-2 & SAM HAWK site generation added 2019-10-05 04:36:40 +02:00
Khopa
3c9bffb557 Persian Gulf : Added Liwa, Ras Al Khaimah & Al Ain airbases 2019-10-05 03:47:39 +02:00
Khopa
d4d7b546e1 Fixed debriefing success validation for others events. 2019-10-05 02:03:51 +02:00
Khopa
9f0c17115e Fixed debriefing for Naval Intercept 2019-10-05 02:01:12 +02:00
Khopa
f6fdd3d12a Fixed issue with FrontlineAttack debriefing validation 2019-10-05 01:52:18 +02:00
Khopa
2401da2b24 Persian Gulf Theather : Disconnect Lar from Qeshm 2019-10-04 23:34:01 +02:00
Khopa
50ef8fef24 Fixed Persian Gulf Theater control points in Iran being blue when midgame is selected. 2019-10-04 23:12:27 +02:00
Khopa
079248bfeb Fixed a few issue with the briefing view. 2019-10-04 22:18:20 +02:00
Khopa
650ee9666d Fix turn counter, so that turn 0 is turn 1 2019-07-19 19:52:26 +02:00
Khopa
18bcc1bce7 Implemented stats view. 2019-07-13 14:08:44 +02:00
Khopa
73b4ec47b9 Apply CSS to whole app, but disabled for now 2019-07-13 00:53:11 +02:00
Khopa
70331d913d UI : Daytime effect on map background 2019-07-13 00:35:35 +02:00
Khopa
9c72c9a063 Put correct cursor style when mouse hover a map item. 2019-07-13 00:05:59 +02:00
Khopa
af8ae09434 Draw control point as Arc with life gauge representing power 2019-07-12 23:37:44 +02:00
Khopa
e8a8364ac2 Added back the settings menu in the new UI 2019-07-12 23:13:03 +02:00
Khopa
0e7d49488c Put CSS in resources folder, so that it is properly embedded in the release. Updated requirement and release build for new UI. 2019-07-12 19:35:30 +02:00
Khopa
405c6659b9 Cleaned up some 'print'. 2019-07-12 19:14:44 +02:00
Khopa
7ca435337f Merge 2019-07-12 00:35:54 +02:00
Khopa
024b665dd9 Commit before merge 2019-07-12 00:32:47 +02:00
Khopa
a397296624 Fix : Only possible to open event menu if event is actually displayed. 2019-07-11 21:38:59 +02:00
Khopa
adb9e38ff4 Waiting and Debriefing Window, QT UI is now functionnal. 2019-07-11 21:31:16 +02:00
Khopa
c4dc432be1 Fix issue when the faction lack units in a category of task 2019-07-11 12:16:47 +02:00
Wrycu
49795993f1 refactor(release): clean up release build process
* handle case where a dist has never been created
* ignore requirements.txt
* include map resources instead of pulling from submodule
2019-07-10 23:17:52 -07:00
Wrycu
ea6b2ab2dc chore(ignore): removed unused/personal files 2019-07-10 23:14:46 -07:00
Wrycu
44d04d3ba6 chore(requirements): add release requirement 2019-07-10 23:12:49 -07:00
Wrycu
577c171d48 chore(ignore): removed unused/personal files 2019-07-10 23:11:45 -07:00
Vasyl Horbachenko
c5edf7a581 Update README.md 2019-07-09 18:04:50 +03:00
Vasyl Horbachenko
ac67ec86b1 Delete a.py 2019-07-09 18:04:19 +03:00
Wrycu
291f538645 chore(requirements): add requirements file 2019-07-07 18:03:51 -07:00
Khopa
817a3a5e15 Briefing has start function and departure airbase selection 2019-07-07 13:57:04 +02:00
Khopa
0b87e192ce Briefing windows layout done 2019-07-07 13:36:40 +02:00
Khopa
fc83ca0de6 Added credits to pydcs in about window 2019-07-07 12:16:04 +02:00
Khopa
c621e822dc Fix artifact on map when drawing events & improved base menu 2019-07-07 12:11:12 +02:00
Khopa
1776452964 Show events on map 2019-07-06 13:54:45 +02:00
Khopa
4e5e0a4a7a ix : Possible to buy units in player base, not ennemy bases 2019-07-06 13:22:09 +02:00
Khopa
bb32f47b8c Implemented basic base menu to buy units 2019-07-06 13:21:03 +02:00
Khopa
6b5f77c415 Added classes for sub windows. (WIP) 2019-07-05 22:01:16 +02:00
Khopa
9a73c78705 Using a singleton QObject to propagate game model update across whole app 2019-07-05 21:43:14 +02:00
Khopa
8246c8e94b Top bar layout, added some icons and possible to pass turn 2019-07-05 21:02:18 +02:00
Khopa
89e8ef65ea Added about dialog & credits + icon in pass turn button 2019-07-05 20:44:01 +02:00
Khopa
2428d39308 Implemented top bar with turn counter and budget info. Added CSS stylesheet. 2019-07-05 20:05:27 +02:00
Khopa
dc91f5004e New Game Wizard with Qt UI 2019-07-05 01:58:23 +02:00
Khopa
b66bf4cc36 Qt Map drawn with line and frontline 2019-07-04 19:04:31 +02:00
Khopa
67910bce61 Map implementation 2019-07-04 09:33:19 +02:00
Khopa
2adacdba02 icon as png for qt 2019-07-03 23:35:22 +02:00
Khopa
4652e7d188 Basics for QT UI 2019-07-03 23:33:47 +02:00
Khopa
a30d4a4514 Fix in 'unit_task' method 2019-07-03 21:06:03 +02:00
Khopa
a17a9399ef Merge remote-tracking branch 'wrycu/develop' into develop_khopa
# Conflicts:
#	gen/aaa.py
2019-07-03 19:45:03 +02:00
Khopa
ba6d10cd9e Small fix and database changes. 2019-07-03 18:50:16 +02:00
Wrycu
b1576e8f15 fix(SAMs): correctly track when a SAM site is destroyed 2019-07-01 21:49:25 -07:00
Wrycu
55de28105e fix(farp): remove unsupported units from spawning in farps 2019-07-01 21:45:58 -07:00
Wrycu
40e3d59432 fix(cap): cap now properly spawns at a randomized interval after take-off 2019-06-30 12:59:01 -07:00
Khopa
665f022111 Fix Ship Gen 2019-06-30 19:15:46 +02:00
Khopa
309c10c4cb Selectable factions wip 2019-06-30 14:05:26 +02:00
Khopa
658120b8d9 Tweaked ground object generator 2019-06-30 05:48:19 +02:00
Khopa
fbd01fbfdb WIP for possibility to select player and ennemy faction 2019-06-30 05:31:22 +02:00
Khopa
09135adadc Allow selection of a time period, for campaign start 2019-06-30 02:58:04 +02:00
Khopa
0c7a36cef6 Start time generation now more correct. 2019-06-30 01:56:40 +02:00
Khopa
abf6fe69bd Generate start time of the mission according to settings. 2019-06-30 01:38:12 +02:00
Khopa
b3318583ed Added a filter so that map displayed change color according to the time of the day. 2019-06-30 01:32:47 +02:00
Khopa
288fe20def Doubled size of map image for Caucasus 2019-06-30 01:12:15 +02:00
Khopa
96ee14bf08 Icon order in topbar 2019-06-30 01:11:46 +02:00
Khopa
00b9ba0f32 Display current day time icon in top bar and improved overall look and feel. 2019-06-30 01:02:50 +02:00
Khopa
2a63f7b187 Drew and added misc icons 2019-06-30 00:42:07 +02:00
Khopa
c655d97109 Drew a few placeholder icons for daytime 2019-06-30 00:25:18 +02:00
Khopa
fd26700867 Show current turn, date and time of the day in overview. 2019-06-30 00:14:33 +02:00
Khopa
df5d9782e7 Added turn counter, top bar refresh correctly. 2019-06-29 21:06:05 +02:00
Khopa
61af07bd79 Fixed pydoc 2019-06-27 22:47:01 +02:00
Khopa
0e008ac87b Added method to get DCS saved games directory 2019-06-27 22:41:58 +02:00
Khopa
28eab870d4 Added methods to retrieve the DCS installation directory (with Steam/Standalone version abstraction) 2019-06-27 22:38:05 +02:00
Khopa
86aedaf631 Added a module to check DCS environment, to be completed. 2019-06-27 21:58:12 +02:00
Khopa
e242851260 Optimized imports in debriefing.py 2019-06-27 21:43:09 +02:00
Khopa
c884fb7262 Merge remote-tracking branch 'wrycu/develop' into develop_khopa
# Conflicts:
#	ui/overviewcanvas.py
2019-06-27 21:24:01 +02:00
Khopa
b6104fbdaf Removed idea files from version control 2019-06-27 21:03:14 +02:00
Khopa
9305f1d483 Added xml idea files in gitignore 2019-06-27 21:00:02 +02:00
Khopa
048cd22d85 Removed idea files from version control 2019-06-27 20:56:23 +02:00
Khopa
e1ea9664dc Added idea files to gitignore 2019-06-27 20:54:36 +02:00
Wrycu
72d3863f8a feat(intercept): add random delay to enemy intercept 2019-06-25 22:21:12 -07:00
Wrycu
49de53f1c9 feat(strike): add chance of AAA/tanks to strike targets 2019-06-24 20:44:28 -07:00
Wrycu
b17e34351c fix(strike): spawn air defense SAM sites on strike 2019-06-24 19:01:56 -07:00
Wrycu
84b1df75c2 feat(attack): air defense spawns further from the thing they are defending 2019-06-23 14:27:07 -07:00
Wrycu
89f122c325 feat(attack): add multi-unit SAM site support 2019-06-23 13:43:16 -07:00
Wrycu
e9103acb07 feat(attack): base attack - now spawn all CAP aircraft when a base is attacked 2019-06-22 14:30:27 -07:00
Wrycu
c7eae7e97a fix(base): correct AA spawn 2019-06-22 14:17:28 -07:00
Wrycu
f5851d09f5 fix(overview): correct negative radius 2019-06-22 14:15:24 -07:00
Vasyl Horbachenko
ba8112280d Merge pull request #66 from shdwp/develop
Develop
2019-05-31 16:49:03 +03:00
Vasyl Horbachenko
4cc373595c Update README.md 2019-05-31 16:39:18 +03:00
Wrycu
36aa4edb05 refactor(units): add SAMs to air defense 2019-05-30 21:32:39 -07:00
Wrycu
26840373ed refactor(turns): modify turn settings
* raise air defense limits
* enemy gains more units even if no action is taken on a turn
* player gains money even if no action was taken on a turn
2019-05-30 21:31:50 -07:00
Vasyl Horbachenko
4c5a2650d1 Merge pull request #58 from JohanAberg/patch-1
ValueError: negative radius
2019-05-21 04:50:30 +03:00
Johan Aberg
b99cdfb5c3 ValueError: negative radius
When cp.base.strength is zero 0, radius_m becomes negative and an ValueError is raised.

INFO:root:Commision Al Maktoum: {<class 'dcs.vehicles.Armor.APC_BTR_80'>: 3}
ERROR:root:<class 'ValueError'>
Traceback (most recent call last):
  File "tkinter\__init__.py", line 1702, in __call__
  File "ui\window.py", line 156, in dismiss
  File "ui\mainmenu.py", line 29, in display
  File "ui\overviewcanvas.py", line 590, in update
  File "ui\overviewcanvas.py", line 252, in draw
  File "ui\overviewcanvas.py", line 312, in draw_map
  File "ui\overviewcanvas.py", line 331, in draw_bases
ValueError: negative radius

Proposed fix:
radius_m = max(radius * cp.base.strength - 2, 0)
2019-04-04 19:10:59 +13:00
Vasyl Horbachenko
6ec14e744e fixed starting bat; updated escort options for Strikes 2019-03-31 19:55:27 +03:00
Vasyl Horbachenko
310db66c22 Merge branch 'develop' of https://github.com/shdwp/dcs_liberation into develop 2019-03-27 11:53:14 +02:00
Vasyl Horbachenko
c7c2b9a248 special flight for AI to SEAD; AI bomb task 2019-03-27 11:53:00 +02:00
Vasyl Horbachenko
b697a8b40a cleanups & minor fixesh 2019-03-27 10:41:40 +02:00
Vasyl Horbachenko
c152b49b88 minor fixes; F-14B 2019-03-27 08:47:29 +02:00
Vasyl Horbachenko
2356fc2bbf Merge pull request #54 from Khopa/develop_khopa
Re-added missing png icons
2019-01-23 23:27:34 +02:00
Vasyl Horbachenko
f7e2c8921c integration tests for operation generation; adjusted waypoint altitude for AI to not fly too low; removed C101 from list of generated AI aircrafts 2019-01-16 01:07:24 +02:00
Khopa
604352f8df Re-added missing icons (they were somehow removed from the repository, and the software couldn't be launched) 2018-12-03 21:06:47 +01:00
Vasyl Horbachenko
fbbe56f954 fixes to convoy strikes; UI updates; don't generate helis for enemy 2018-11-06 04:06:59 +02:00
Vasyl Horbachenko
7842c69ebb fixed incompatible missions being available from carriers 2018-11-06 02:59:24 +02:00
Vasyl Horbachenko
e1d50f1f27 added missing assets; convoy strike event 2018-11-06 02:33:38 +02:00
Vasyl Horbachenko
9d0997624b fixes for selectable departure; generate statics for used units; raised RTB alt 2018-11-05 03:17:06 +02:00
Vasyl Horbachenko
355cd3e0e4 display events on map 2018-11-04 04:50:51 +02:00
Vasyl Horbachenko
af5cd57094 WIP: display events on the map 2018-11-04 04:06:44 +02:00
Vasyl Horbachenko
8f85101cec WIP: display events on the map; start events from adjacent CPs 2018-11-04 02:38:14 +02:00
Vasyl Horbachenko
97be483624 Merge pull request #43 from Khopa/sdl_map
Scrollable & Zoomable Map view
2018-11-04 00:58:14 +02:00
Khopa
1ff5721912 Possible to toggle map size 2018-11-03 23:56:10 +01:00
Vasyl Horbachenko
80cbc663bf Merge pull request #45 from calvinmorrow/labels_and_coalition_view
Labels and coalition view
2018-11-04 00:54:21 +02:00
Vasyl Horbachenko
b3e729af0d Merge pull request #44 from calvinmorrow/bugfix_37
Add initiatorMissionID key to multiplayer debriefing table
2018-11-03 20:45:56 +02:00
Calvin Morrow
3ed864021d Move log button and minimize padding to fit existing window size 2018-10-31 15:24:34 -07:00
Calvin Morrow
8bc269fa99 Add labels game setting and map visibility setting to mission generation forced options 2018-10-31 15:11:12 -07:00
Khopa
c656c0f7e4 Confirm dialog to start a new game 2018-10-31 17:18:08 +01:00
Khopa
858e5d2d04 Do redraw the map when declutter options are toggled 2018-10-31 14:35:17 +01:00
Khopa
903a8db46f Commented debug mouse cursos position rect 2018-10-31 14:26:23 +01:00
Khopa
5aa731853d The zoom is a bit less annoying to use 2018-10-31 14:24:37 +01:00
Khopa
540096178c Display zoom level on pygame overlay in bottom right corner 2018-10-31 14:22:49 +01:00
Khopa
ed2a611197 Removed unnecessary print 2018-10-31 14:14:17 +01:00
Khopa
1c61b0b5a2 Refactored the way icons are loaded + reformat 2018-10-31 13:10:07 +01:00
Calvin Morrow
82f7e5d0c4 Add initiatorMissionID key to multiplayer debriefing table for dead unit detection 2018-10-30 19:40:59 -07:00
Khopa
ecb2c86dc4 Change order of map view options 2018-10-31 01:29:47 +01:00
Khopa
5cbbc3b1ab Improved base intel view 2018-10-31 01:22:08 +01:00
Khopa
e0b2e178f9 Display detailled info about base when mouse hover 2018-10-31 00:59:02 +01:00
Khopa
390974ba0f Icons for all kind of targets 2018-10-31 00:20:29 +01:00
Khopa
91379ff7d9 Instructions for map + tweaks (enable AA for text) 2018-10-30 23:32:27 +01:00
Khopa
1fe9e56997 Added missing resources. Bigger maps for nevada & caucasus 2018-10-30 20:30:10 +01:00
Khopa
e10b853712 Much better performance for the pygame viewport. 2018-10-30 20:00:14 +01:00
Khopa
7d70862e72 Work in progress : features restored. 2018-10-30 17:12:35 +01:00
Khopa
90bdcec7ff Render map on a pygame SDL layer. WIP 2018-10-30 14:47:31 +01:00
Vasyl Horbachenko
63da350223 armor balance tweaks 2018-10-23 04:04:30 +03:00
Vasyl Horbachenko
854f31cb7a armor balance improvements; fixed trigger for farps 2018-10-23 03:40:12 +03:00
Vasyl Horbachenko
eba6daf6c8 Merge remote-tracking branch 'origin/master' 2018-10-23 03:08:13 +03:00
Vasyl Horbachenko
911d57b415 fixed FOB generation 2018-10-23 03:08:01 +03:00
Vasyl Horbachenko
d91e0344a7 Update README.md 2018-10-23 00:54:55 +03:00
Vasyl Horbachenko
e9d7ee51f3 readme upd 2018-10-22 02:29:42 +03:00
Vasyl Horbachenko
9053408e13 Merge branch 'develop' 2018-10-22 02:18:26 +03:00
Vasyl Horbachenko
8f4094ee98 number of fixes 2018-10-22 02:13:38 +03:00
Vasyl Horbachenko
933e064079 fixed debriefing crash 2018-10-14 04:30:46 +03:00
Vasyl Horbachenko
274e08dd8b quick mission debriefing fixed; adjusted constants 2018-10-14 04:09:05 +03:00
Vasyl Horbachenko
05c968edc2 added Gazelle as CAS aircraft + minor fixes 2018-10-13 23:38:26 +03:00
Vasyl Horbachenko
270820de0b added Gazelle as CAS aircraft 2018-10-13 22:50:26 +03:00
Vasyl Horbachenko
e049a97bec minor text update 2018-10-13 22:30:43 +03:00
Vasyl Horbachenko
e2306ba0f3 new weather, strike objectives placement fixes & tarawa for av8b 2018-10-13 22:28:30 +03:00
Vasyl Horbachenko
6d0f488672 updated version compatibility check 2018-10-13 04:44:59 +03:00
Vasyl Horbachenko
397f9a58cb fixed naval intercept crash; fixed wrong targets order; fixed initial waypoint being WP #1; m2k a2g ccip; fixed time being time zone offset ahead; lowered rain weather chance 2018-10-13 04:41:18 +03:00
Vasyl Horbachenko
4fc766a524 trigger fixes; strike waypoint fixes; m2k strike payload update 2018-10-13 02:36:25 +03:00
Vasyl Horbachenko
3f8b5c6c00 minor UI fix 2018-10-12 23:33:10 +03:00
Vasyl Horbachenko
ce43be0d67 display strike objectives on map; minor fixes 2018-10-12 23:31:00 +03:00
Vasyl Horbachenko
ff08888385 minor adjustment in strike objectives generation 2018-10-12 22:38:26 +03:00
Vasyl Horbachenko
6b96410ea4 updated config menu 2018-10-12 22:29:37 +03:00
Vasyl Horbachenko
f21bd10f09 number of minor bugfixes and UI improvements 2018-10-12 21:32:43 +03:00
Vasyl Horbachenko
07b35f8ee1 specify tanker callsign in briefing 2018-10-12 05:45:28 +03:00
Vasyl Horbachenko
251435ae0b debriefing results based only on IDs; fixes in strike ops 2018-10-12 05:41:52 +03:00
Vasyl Horbachenko
b81bf90319 few minor fixes 2018-10-12 03:46:53 +03:00
Vasyl Horbachenko
d6b1b8665d minor fixes 2018-10-12 03:37:32 +03:00
Vasyl Horbachenko
64bd3e6a52 removed debugging code 2018-10-12 03:17:41 +03:00
Vasyl Horbachenko
520a0f91fd UI update; enemy vehicle difficulty settings; minor adjustments 2018-10-12 03:13:33 +03:00
Vasyl Horbachenko
0015667829 new frontline position finding method; AA for strikes; other minor fixes and adjustments 2018-10-12 00:12:25 +03:00
Vasyl Horbachenko
35a7da2816 oil strike objectives correct placement; updated starting point for gulf 2018-10-11 04:42:38 +03:00
Vasyl Horbachenko
5bbf3fc49f fixed land map for gulf; ability to get logs from settings; minor trigger updates 2018-10-11 04:12:02 +03:00
Vasyl Horbachenko
7a8dfeb819 Merge remote-tracking branch 'origin/develop' into develop 2018-10-11 03:45:31 +03:00
Vasyl Horbachenko
e28a24c875 randomized strike objects with templates; forbid ground objects and vehicles placement on mountains and in forests; updated push trigger so it include player group; adjacent CP missions could be initiated from carriers 2018-10-11 03:45:20 +03:00
Vasyl Horbachenko
823c6a6137 Merge pull request #27 from Khopa/combined_arms_slots
Combined arms slots
2018-10-03 02:17:21 +03:00
Khopa
2cbe63f162 Fixed potential exception in start if user enter invalid value inside the combined arms slots entry. 2018-09-29 11:55:42 +02:00
Khopa
93d0746d3e Replaced with player faction check by coalition check 2018-09-29 11:46:15 +02:00
Khopa
8cb7c7378f Type for ca_slot_entry 2018-09-29 11:34:22 +02:00
Khopa
3500c85e8d UI for CA slot selection (align with unit count rows) 2018-09-22 13:42:51 +02:00
Khopa
c699567c73 Only generate Combined Arms "Tactical Commander" slots for player side. 2018-09-22 13:33:31 +02:00
Khopa
056c397e68 [Cherry Picked] Added possibility to add 'DCS: Combined Arms' slots to the generated mission. 2018-09-22 11:46:40 +02:00
Vasyl Horbachenko
8431c7745d fixed base atttack op 2018-09-15 00:30:40 +03:00
Vasyl Horbachenko
8df4607e50 Update README.md 2018-09-14 23:49:50 +03:00
Vasyl Horbachenko
edf9efddf9 update to ground objects parser; waypoints in briefings & general briefings update; minor fixes 2018-09-13 05:09:57 +03:00
Vasyl Horbachenko
03fc17fae6 new ground objects format & parser; place dead objects instead of removing them completely 2018-09-12 05:19:21 +03:00
Vasyl Horbachenko
6fb342a42c updated location argument; updated ground units placement during attack operation 2018-09-12 00:20:35 +03:00
Vasyl Horbachenko
262347f8c8 tweaked caucasus start times 2018-09-11 22:46:26 +03:00
Vasyl Horbachenko
1176b92073 capture armor placement tweaks 2018-09-11 17:39:23 +03:00
Vasyl Horbachenko
afb084ebf8 minor bugfixes 2018-09-11 05:55:05 +03:00
Vasyl Horbachenko
12853feec3 updated version check 2018-09-11 03:35:52 +03:00
Vasyl Horbachenko
d31876b65e FARP spawn for helis on frontline cas; updated ground object placements 2018-09-11 03:12:33 +03:00
Vasyl Horbachenko
ca521e7e51 FARPs for heli flights WIP 2018-09-10 23:12:04 +03:00
Vasyl Horbachenko
f21c515d5c convert resource files to gif 2018-09-10 21:46:34 +03:00
Vasyl Horbachenko
fa5259d1f2 minor fixes before rc 2018-09-10 01:48:38 +03:00
Vasyl Horbachenko
7a5361c057 minor updates and strike mission objects expand 2018-09-10 01:38:50 +03:00
Vasyl Horbachenko
40bfb6fa88 strike operations fixes 2018-09-09 23:56:30 +03:00
Vasyl Horbachenko
61a237d1ae proper settings for barcap 2018-09-09 20:57:32 +03:00
Vasyl Horbachenko
cf7276b528 updated AA units 2018-09-09 20:39:49 +03:00
Vasyl Horbachenko
67f69d0a7f updated AA units 2018-09-09 20:27:53 +03:00
Vasyl Horbachenko
a918914431 dont limit aircraft to predefined role; better scrambling screen 2018-09-09 20:21:07 +03:00
Vasyl Horbachenko
49f2c00d76 Update README.md 2018-09-09 04:39:53 +03:00
Vasyl Horbachenko
d284305323 Update README.md 2018-09-09 04:39:03 +03:00
Vasyl Horbachenko
c32ac8577c Update README.md 2018-09-09 04:38:47 +03:00
Vasyl Horbachenko
4ba1dd87e8 updates to strike missions; frontline operations invalid units placement fixed; minor UI updates 2018-09-09 04:15:44 +03:00
Vasyl Horbachenko
e0d82da6cb save game version check; mission description in briefings; minor fixes and improvements; predefined ground objects (statics) support; strike mission WIP 2018-09-09 01:21:32 +03:00
Vasyl Horbachenko
2179e4af47 Merge pull request #12 from Khopa/ui_dev
Modified UI Style
2018-09-08 19:15:52 +03:00
Vasyl Horbachenko
0d5530f5ea Update README.md 2018-08-15 15:14:19 +03:00
Vasyl Horbachenko
a528249062 Update README.md 2018-08-15 15:13:49 +03:00
Khopa
75d734d6e4 Typo in UI 2018-08-09 13:08:07 +02:00
Khopa
1d73affa08 New style for event result menu 2018-08-08 23:40:10 +02:00
Khopa
834ee30c86 Style for event result menu 2018-08-08 23:18:49 +02:00
Khopa
d236b8a94d UI alignement in base menu 2018-08-08 22:38:09 +02:00
Khopa
a132cba7ef Changed the color of text on map (easier to read this way for now imo) 2018-08-08 22:30:33 +02:00
Khopa
86706231e0 New style for event/mission menu 2018-08-08 22:30:12 +02:00
Khopa
5eb921948a Display the units x/x/x value of the base in the base menu. 2018-08-08 21:52:09 +02:00
Khopa
fd54a5f86c Display the name of the base in base menu 2018-08-08 21:41:16 +02:00
Khopa
1b2ad5b419 Improved style of main menu, configuration menu, and base menu 2018-08-08 21:22:00 +02:00
Khopa
14cd54668e Improved style of new game menu 2018-08-08 18:45:25 +02:00
Khopa
2047089b64 Added icon to ui windows. 2018-08-08 16:27:42 +02:00
Khopa
ee924ef36e Added title name to UI window 2018-08-08 16:24:20 +02:00
Vasyl Horbachenko
f9c1dd980b spamram for fa18; non-randomized groups vertical separation on spawn; argument to affect DCS folder selection 2018-08-04 04:35:27 +03:00
Vasyl Horbachenko
74c1861240 build archieve tool 2018-07-31 23:40:35 +03:00
Vasyl Horbachenko
e8226782c1 Merge pull request #8 from shdwp/develop
minor balance improvements
2018-07-31 04:17:48 +03:00
Vasyl Horbachenko
a592cf3a05 minor balance improvements 2018-07-31 04:16:17 +03:00
Vasyl Horbachenko
0b1cb0d770 Merge pull request #7 from shdwp/develop
Develop
2018-07-31 04:00:18 +03:00
Vasyl Horbachenko
a4aa1cff3a widened spawn windows for aircraft 2018-07-31 03:59:55 +03:00
Vasyl Horbachenko
6a02d2ffb6 few minor fixes; added F5 2018-07-31 03:47:50 +03:00
Vasyl Horbachenko
7458181e90 success rate calculation division by zero fix 2018-07-29 04:41:32 +03:00
Vasyl Horbachenko
ec28cdc936 version bump 2018-07-29 04:20:30 +03:00
Vasyl Horbachenko
9dbc9a8a56 prompt window with logs on raised exception; minor UI updates; minor fixes 2018-07-29 04:16:39 +03:00
Vasyl Horbachenko
73d4a2d414 moved viggen to CAS; tanker position fix on enemy attacks; more logs 2018-07-28 04:58:28 +03:00
Vasyl Horbachenko
e93ad8b800 adjusted budget amounts 2018-07-20 04:08:04 +03:00
Vasyl Horbachenko
d48985ca6d new airports for PG; TACANs and ICLS; list frequencies in mission briefing; carrier ops improvements; cold start option 2018-07-20 04:06:13 +03:00
Vasyl Horbachenko
5f7d717b63 fixed sir abu having a frontline 2018-07-19 01:07:24 +03:00
Vasyl Horbachenko
e266698e68 fixed start.bat for usernames w/ spaces; fixed triggers for player defending; minor fixes 2018-07-19 00:57:15 +03:00
Vasyl Horbachenko
e8098e795c added symlink to pydcs to resources/tools 2018-07-18 03:20:18 +03:00
Vasyl Horbachenko
8d69724272 env gen minor update 2018-07-18 03:14:25 +03:00
Vasyl Horbachenko
683114f916 updates to CAP op 2018-07-18 00:45:55 +03:00
Vasyl Horbachenko
3b454470f9 Merge branch 'improved_cas' of https://github.com/shdwp/dcs_pmcliberation into improved_cas 2018-07-17 23:31:58 +03:00
Vasyl Horbachenko
f40f83bb09 fixes and improvements for fronline CAP 2018-07-17 14:22:45 +03:00
Vasyl Horbachenko
932bec2f84 fixes to frontline attack; frontline CAP WIP 2018-07-17 14:22:45 +03:00
Vasyl Horbachenko
820820eb92 frontline attack ops 2018-07-17 14:22:45 +03:00
Vasyl Horbachenko
6f5835a2b8 Improved Frontline CAS 2018-07-17 14:21:50 +03:00
Vasiliy Horbachenko
07128bb5e6 fixed capture issue when two or more points were attacking the base 2018-07-17 05:53:55 +03:00
Vasyl Horbachenko
b302372d4c fixes and improvements for fronline CAP 2018-07-17 05:22:41 +03:00
Vasyl Horbachenko
cad7d2c735 fixes to frontline attack; frontline CAP WIP 2018-07-17 02:14:46 +03:00
Vasyl Horbachenko
e4c3f8bce2 frontline attack ops 2018-07-16 23:58:01 +03:00
Vasyl Horbachenko
1fbf4e292a Merge branch 'improved_cas' of https://github.com/shdwp/dcs_pmcliberation into improved_cas 2018-07-16 23:03:47 +03:00
Vasyl Horbachenko
62f5b2d06d Improved Frontline CAS 2018-07-16 23:02:08 +03:00
Vasyl Horbachenko
3831658162 more base recovery after attack 2018-07-16 22:55:29 +03:00
Vasyl Horbachenko
b2545e4de0 Improved Frontline CAS 2018-07-16 22:19:19 +03:00
Vasyl Horbachenko
26e43f5e54 Merge branch 'master' of https://github.com/shdwp/dcs_liberation 2018-07-16 22:12:31 +03:00
Vasyl Horbachenko
44ba5c32c6 use correct join char for paths 2018-07-16 22:11:47 +03:00
Vasyl Horbachenko
ce7d3a89c0 fixed user path for regular DCS 2018-07-16 22:11:03 +03:00
Vasyl Horbachenko
c74b1205df fixed user path for regular DCS 2018-07-16 22:05:42 +03:00
Vasyl Horbachenko
58dd16219b removed observer slots 2018-07-15 08:55:20 +03:00
Vasyl Horbachenko
e0e1d0238f nevada debugging code removal 2018-07-15 05:55:38 +03:00
Vasyl Horbachenko
71e22bdb21 Merge remote-tracking branch 'origin/master' 2018-07-15 04:21:07 +03:00
Vasyl Horbachenko
3c2025ab44 minor hotfixes in mp debriefing (WIP) 2018-07-15 04:20:55 +03:00
Vasyl Horbachenko
d314e22970 Update start.bat 2018-07-13 04:59:59 +03:00
Vasyl Horbachenko
ff7181b648 updated .gitignore to ignore payload resource files 2018-07-13 04:34:56 +03:00
Vasyl Horbachenko
4cbd30fdbc debriefing based on events, not world state; tweaked visualgen; vehicles will not group in single location during capture op; fixed triggers for carrier ops; fixed naval ops; correct speed for inflight heli spawns; awacs will not change it's freq 2018-07-13 04:33:07 +03:00
Vasiliy Horbachenko
4ce7480df8 debriefing based on events, not world state WIP 2018-07-12 05:12:01 +03:00
Vasyl Horbachenko
d2aede593b added files missing from git 2018-07-05 03:13:30 +03:00
Vasyl Horbachenko
32fb5ad0e2 fixed a number of issues: user directory on different drive, carrier ops, multiplayer debriefing parser, multiplayer mission generation; added su25 2018-07-05 02:42:46 +03:00
Vasyl Horbachenko
fa55ae1fcc fixed multiplayer mission start 2018-07-04 05:20:35 +03:00
848 changed files with 47708 additions and 36166 deletions

39
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install environment
run: |
python -m venv ./venv
- name: Install dependencies
run: |
./venv/scripts/activate
python -m pip install -r requirements.txt
# For some reason the shiboken2.abi3.dll is not found properly, so I copy it instead
Copy-Item .\venv\Lib\site-packages\shiboken2\shiboken2.abi3.dll .\venv\Lib\site-packages\PySide2\ -Force
- name: Build binaries
run: |
./venv/scripts/activate
$env:PYTHONPATH=".;./pydcs"
pyinstaller pyinstaller.spec
- uses: actions/upload-artifact@v2
with:
name: dcs_liberation
path: dist/

107
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,107 @@
name: Release Pipeline
on:
push:
tags: [ '*' ]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install environment
run: |
python -m venv ./venv
- name: Install dependencies
run: |
./venv/scripts/activate
python -m pip install -r requirements.txt
# For some reason the shiboken2.abi3.dll is not found properly, so I copy it instead
Copy-Item .\venv\Lib\site-packages\shiboken2\shiboken2.abi3.dll .\venv\Lib\site-packages\PySide2\ -Force
- name: Build binaries
run: |
./venv/scripts/activate
$env:PYTHONPATH=".;./pydcs"
pyinstaller pyinstaller.spec
- name: Create Installer
env:
TAG_NAME: ${{ github.ref }}
run: |
$version = ($env:TAG_NAME -split "/") | Select-Object -Last 1
(Get-Content .\installer\dcs_liberation.iss) -replace "{{version}}",$version | Out-File .\build\installer.iss
cd .\installer
iscc.exe ..\build\installer.iss
cd ..
Copy-Item .\changelog.md .\dist
- uses: actions/upload-artifact@v2
with:
name: dcs_liberation
path: dist/
release:
needs: [ build ]
runs-on: windows-latest
steps:
- uses: actions/download-artifact@v2
with:
name: dcs_liberation
- name: "Get Version"
id: version
env:
TAG_NAME: ${{ github.ref }}
run: |
Get-ChildItem -Recurse -Depth 1
$version = ($env:TAG_NAME -split "/") | Select-Object -Last 1
$prerelease = ("2.1.1-alpha3" -match '[^\.\d]').ToString().ToLower()
Write-Host $version
Write-Host $prerelease
Write-Output "::set-output name=number::$version"
Write-Output "::set-output name=prerelease::$prerelease"
$changelog = Get-Content .\changelog.md
$last_change = ($changelog | Select-String -Pattern "^#\s" | Select-Object -Skip 1 -First 1).LineNumber - 2
($changelog | Select-Object -First $last_change) -join "`n" | Out-File .\releasenotes.md
Compress-Archive -Path .\dcs_liberation -DestinationPath "dcs_liberation.$version.zip" -Compression Optimal
- uses: actions/create-release@v1
id: create_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
body_path: releasenotes.md
draft: false
prerelease: ${{ steps.version.outputs.prerelease }}
- uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dcs_liberation.exe
asset_name: dcs_liberation.${{ steps.version.outputs.number }}.exe
asset_content_type: application/exe
- uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dcs_liberation.${{ steps.version.outputs.number }}.zip
asset_name: dcs_liberation.${{ steps.version.outputs.number }}.zip
asset_content_type: application/zip

26
.gitignore vendored
View File

@@ -1,12 +1,24 @@
*.pyc
__pycache__
build/*
build/**
resources/payloads/*.lua
venv
logs.txt
.DS_Store
dist/**
a.py
resources/tools/a.miz
tests/**
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/dictionaries
.idea/**/shelf
.idea/misc.xml
.idea/*.iml
.idea/
/kneeboards
/liberation_preferences.json
/state.json
logs/liberation.log
qt_ui/logs/liberation.log
*.psd
resources/scripts/plugins/*

5
.gitmodules vendored
View File

@@ -1,3 +1,4 @@
[submodule "submodules/dcs"]
path = submodules/dcs
[submodule "pydcs"]
path = pydcs
url = https://github.com/pydcs/dcs
branch = master

View File

@@ -1,10 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/dcs_pmcliberation.iml" filepath="$PROJECT_DIR$/.idea/dcs_pmcliberation.iml" />
</modules>
</component>
</project>

11
.idea/vcs.xml generated
View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitSharedSettings">
<option name="FORCE_PUSH_PROHIBITED_PATTERNS">
<list />
</option>
</component>
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

30
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,30 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Main",
"type": "python",
"request": "launch",
"program": "qt_ui\\main.py",
"console": "integratedTerminal",
"env": {
"PYTHONPATH": ".;./pydcs"
},
"preLaunchTask": "Prepare Environment"
},
{
"name": "Python: Make Release",
"type": "python",
"request": "launch",
"program": "resources\\tools\\mkrelease.py",
"console": "integratedTerminal",
"env": {
"PYTHONPATH": ".;./pydcs"
},
"preLaunchTask": "Prepare Environment"
}
]
}

4
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"python.pythonPath": "g:\\python\\dcs_liberation\\venv\\Scripts\\python.exe",
"vsintellicode.python.completionsEnabled": true
}

35
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,35 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Prepare Environment",
"type": "shell",
"isBackground": false,
"problemMatcher": [],
"command": "powershell",
"args": [
"-Command",
"& {if (-not (Test-Path ${workspaceFolder}\\venv)) { python -m venv ${workspaceFolder}\\venv; . ${workspaceFolder}\\venv\\scripts\\activate.ps1; pip install -r requirements.txt; Copy-Item ${workspaceFolder}\\venv\\Lib\\site-packages\\shiboken2\\shiboken2.abi3.dll ${workspaceFolder}\\venv\\Lib\\site-packages\\PySide2 } }",
],
"group": "build",
"options": {
"env": {
"PYTHONPATH": ".;./pydcs"
}
},
"presentation": {
"echo": true,
"reveal": "never",
"focus": false,
"panel": "shared",
"showReuseMessage": true,
"clear": false
},
"runOptions": {
"runOn": "folderOpen"
}
}
]
}

View File

@@ -1,8 +1,36 @@
[DCS World](https://www.digitalcombatsimulator.com/en/products/world/) single-player liberation dynamic campaign.
![Logo](https://i.imgur.com/c2k18E1.png)
[Installation instructions/Manual](https://github.com/shdwp/dcs_liberation/wiki)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg?logo=paypal)](https://www.paypal.com/paypalme/KhopaDCSL)
[![Patreon](https://img.shields.io/badge/patreon-become%20a%20patron-orange?logo=patreon)](https://patreon.com/khopa)
Inspired by *ARMA Liberation* mission.
[![Download](https://img.shields.io/github/downloads/khopa/dcs_liberation/total?label=Download)](https://github.com/Khopa/dcs_liberation/releases)
Uses [pydcs](http://github.com/pydcs/dcs) for mission generation.
[![Discord](https://img.shields.io/discord/595702951800995872?label=Discord&logo=discord)](https://discord.gg/bKrtrkJ)
[![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)
## 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.
![Logo](https://imgur.com/B6tvlBJ.png)
## Downloads
Latest release is available here : https://github.com/Khopa/dcs_liberation/releases
## Resources
Tutorials, contributors and developer's guides are available in the project's [Wiki](https://github.com/Khopa/dcs_liberation/wiki/)
## 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,65 +0,0 @@
#!/usr/bin/env python3
import os
import dcs
import theater.caucasus
import theater.persiangulf
import theater.nevada
import ui.window
import ui.mainmenu
import ui.newgamemenu
import ui.corruptedsavemenu
from game.game import Game
from theater import start_generator
from userdata import persistency
dcs.planes.FlyingType.payload_dirs.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources\\payloads"))
def proceed_to_main_menu(game: Game):
m = ui.mainmenu.MainMenu(w, None, game)
m.display()
w = ui.window.Window()
try:
game = persistency.restore_game()
if not game:
new_game_menu = None # type: NewGameMenu
def start_new_game(player_name: str, enemy_name: str, terrain: str, sams: bool, midgame: bool, multiplier: float):
if terrain == "persiangulf":
conflicttheater = theater.persiangulf.PersianGulfTheater()
elif terrain == "nevada":
conflicttheater = theater.nevada.NevadaTheater()
else:
conflicttheater = theater.caucasus.CaucasusTheater()
if midgame:
for i in range(0, int(len(conflicttheater.controlpoints) / 2)):
conflicttheater.controlpoints[i].captured = True
start_generator.generate_initial(conflicttheater, enemy_name, sams, multiplier)
game = Game(player_name=player_name,
enemy_name=enemy_name,
theater=conflicttheater)
game.budget = int(game.budget * multiplier)
game.settings.multiplier = multiplier
game.settings.sams = sams
if midgame:
game.budget = game.budget * 4 * len(list(conflicttheater.conflicts()))
proceed_to_main_menu(game)
new_game_menu = ui.newgamemenu.NewGameMenu(w, start_new_game)
new_game_menu.display()
else:
proceed_to_main_menu(game)
except Exception as e:
ui.corruptedsavemenu.CorruptedSaveMenu(w).display()
w.run()

279
changelog.md Normal file
View File

@@ -0,0 +1,279 @@
# 2.1.5
## Features/Improvements :
* **[Units/Factions]** Enabled EPLRS for ground units that supports it (so they appear on A-10C II TAD and Helmet)
## Fixes :
* **[UI]** Fixed an issue that prevent saving after aborting a mission
* **[Mission Generator]** Fixed aircraft landing point type being wrong
# 2.1.4
## Fixes :
* **[UI]** Fixed an issue that prevent generating the mission (take off button no working) on old savegames.
# 2.1.3
## Features/Improvements :
* **[Units/Factions]** Added A-10C_2 to USA 2005 and Bluefor modern factions
* **[UI]** Limit number of aircraft that can be bought to the number of available parking slots.
* **[Mission Generator]** Use inline loading of the JSON.lua library, and save to either %LIBERATION_EXPORT_DIR%, or to DCS working directory
## Changes :
* **[Units/Factions]** Bluefor generic factions will now use the new "Combined Joint Task Forces Blue" country in the generated mission instead of "USA"
## Fixes :
* **[UI]** Fixed icon for Viggen
* **[UI]** Added icons for some ground units
* **[Misc]** Fixed issue with Chinese characters in pydcs preventing generating the mission. (Take Off button not working) (thanks to spark135246)
* **[Misc]** Fixed an error causing with ATC frequency preventing generating the mission. (Take Off button not working) (thanks to danalbert)
# 2.1.2
## Fixes :
* **[Mission Generator]** Fix mission generation issues with radio frequencies (Thanks to contributors davidp57 and danalbert)
* **[Mission Generator]** AI should now properly plan flights for Tornados
# 2.1.1
## Features/Improvements :
* **[Other]** Added an installer option (thanks to contributor parithon)
* **[Kneeboards]** Generate mission kneeboards for player flights. Kneeboards include
airfield/carrier information (ATC frequencies, ILS, TACAN, and runway
assignments), assigned radio channels, waypoint lists, and AWACS/JTAC/tanker
information. (Thanks to contributor danalbert)
* **[Radios]** Allocate separate intra-flight channels for most aircraft to reduce global
chatter. (Thanks to contributor danalbert)
* **[Radios]** Configure radio channel presets for most aircraft. Currently supported are:
* AJS37
* AV-8B
* F-14B
* F-16C
* F/A-18C
* JF-17
* M-2000C (Thanks to contributor danalbert)
* **[Base Menu]** Added possibility to repair destroyed SAM and base defenses units for the player (Click on a SAM site to fix it)
* **[Base Menu]** Added possibility to buy/sell/replace SAM units
* **[Map]** Added recon images for buildings on strike targets, click on a Strike target to get detailled informations
* **[Units/Factions]** Added F-16C to USA 1990
* **[Units/Factions]** Added MQ-9 Reaper as CAS unit for USA 2005
* **[Units/Factions]** Added Mig-21, Mig-23, SA-342L to Syria 2011
* **[Cheat Menu]** Added buttons to remove money
## Fixed issues :
* **[UI/UX]** Spelling issues (Thanks to contributor steveveepee)
* **[Campaign Generator]** LHA was placed on land in Syrian Civil War campaign
* **[Campaign Generator]** Fixed inverted configuration for Syria full map
* **[Campaign Generator]** Syria "Inherent Resolve" campaign, added Incirlik Air Base
* **[Mission Generator]** AH-1W was not used by AI to generate CAS mission by default
* **[Mission Generator]** Fixed F-16C targeting pod not being added to payload
* **[Mission Generator]** AH-64A and AH-64D payloads fix.
* **[Units/Factions]** China will use KJ-2000 as awacs instead of A-50
# 2.1.0
## Features/Improvements :
* **[Campaign Generator]** Added Syria map
* **[Campaign Generator]** Added 5 campaigns for the Syria map
* **[Campaign Generator]** Added 2 small scale campaign for Persian Gulf map
* **[Units/Factions]** Added factions for Syria map : Syria 2011, Arab Armies 1982, 1973, 1968, 1948, Israel 1982, 1973, 1948
* **[Base Menu]** Budget is visible in recruitment menu. (Thanks to Github contributor root0fall)
* **[Misc]** Added error message in mission when the state file can not be written
* **[Units/Factions]** China, Pakistan, UAE will now use the new WingLoong drone as JTAC instead of the MQ-9 Reaper
* **[Units/Factions]** Minor changes to Syria 2011 and Turkey 2005 factions
* **[UI]** Version number is shown in about dialog
## Fixed issues :
* **[Mission Generator]** Caucasus terrain improvement on exclusions zone (added forests between Vaziani and Beslan to exclusion zones)
* **[Mission Generator]** The first unit of every base defenses group could not be controlled with Combined Arms.
* **[Mission Generator]** Reduced generated helicopter altitude for CAS missions
* **[Mission Generator]** F-16C default CAS payload was asymmetric, fixed.
* **[Mission Generator]** AH-1W couldn't be bought, and added default payloads.
* **[UI/UX]** Fixed Mi-28N missing thumbnail
* **[UI/UX]** Fixed list of flights not refreshing when changing the mission departure (T+).
# 2.0.11
## Features/Improvements :
* **[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]*c* Basic JTAC on Frontlines
* **[Campaign Generator]** Added Tarawa in caucasus campaigns
* **[Campaign Generator]** Tuned the various existing campaign parameters
* **[Campaign Generator]** Added small campaign : "Russia" on Caucasus Theater
## 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)

1
dcs
View File

@@ -1 +0,0 @@
submodules/dcs/dcs

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', '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
]

1285
game/db.py

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,2 @@
from .event import *
from .groundintercept import *
from .intercept import *
from .capture import *
from .navalintercept import *
from .antiaastrike import *
from .groundattack import *
from .infantrytransport import *
from .frontlineattack import *

View File

@@ -1,86 +0,0 @@
import math
import random
from dcs.task import *
from game import *
from game.event import *
from game.operation.antiaastrike import AntiAAStrikeOperation
from userdata.debriefing import Debriefing
class AntiAAStrikeEvent(Event):
TARGET_AMOUNT_MAX = 2
STRENGTH_INFLUENCE = 0.3
SUCCESS_TARGETS_HIT_PERCENTAGE = 0.5
targets = None # type: db.ArmorDict
def __str__(self):
return "Anti-AA strike from {} at {}".format(self.from_cp, self.to_cp)
def is_successfull(self, debriefing: Debriefing):
total_targets = sum(self.targets.values())
destroyed_targets = 0
for unit, count in debriefing.destroyed_units[self.defender_name].items():
if unit in self.targets:
destroyed_targets += count
if self.from_cp.captured:
return math.ceil(float(destroyed_targets) / total_targets) >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
else:
return math.ceil(float(destroyed_targets) / total_targets) < self.SUCCESS_TARGETS_HIT_PERCENTAGE
def commit(self, debriefing: Debriefing):
super(AntiAAStrikeEvent, self).commit(debriefing)
if self.from_cp.captured:
if self.is_successfull(debriefing):
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(+self.STRENGTH_INFLUENCE)
else:
if self.is_successfull(debriefing):
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def skip(self):
if self.to_cp.captured:
self.to_cp.base.affect_strength(-0.1)
def player_attacking(self, strikegroup: db.PlaneDict, clients: db.PlaneDict):
self.targets = self.to_cp.base.assemble_aa(count=self.to_cp.base.total_aa)
op = AntiAAStrikeOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients=clients,
defender_clients={},
from_cp=self.from_cp,
to_cp=self.to_cp)
op.setup(target=self.targets,
strikegroup=strikegroup,
interceptors={})
self.operation = op
def player_defending(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
self.targets = self.to_cp.base.assemble_aa()
op = AntiAAStrikeOperation(
self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients={},
defender_clients=clients,
from_cp=self.from_cp,
to_cp=self.to_cp
)
strikegroup = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
op.setup(target=self.targets,
strikegroup=strikegroup,
interceptors=interceptors)
self.operation = op

View File

@@ -1,89 +0,0 @@
import math
import random
from dcs.task import *
from game import db
from game.operation.capture import CaptureOperation
from userdata.debriefing import Debriefing
from .event import Event
class CaptureEvent(Event):
silent = True
BONUS_BASE = 15
STRENGTH_RECOVERY = 0.35
def __str__(self):
return "Attack from {} to {}".format(self.from_cp, self.to_cp)
def is_successfull(self, debriefing: Debriefing):
alive_attackers = sum([v for k, v in debriefing.alive_units[self.attacker_name].items() if db.unit_task(k) == PinpointStrike])
alive_defenders = sum([v for k, v in debriefing.alive_units[self.defender_name].items() if db.unit_task(k) == PinpointStrike])
attackers_success = alive_attackers >= alive_defenders
if self.from_cp.captured:
return attackers_success
else:
return not attackers_success
def commit(self, debriefing: Debriefing):
super(CaptureEvent, self).commit(debriefing)
if self.is_successfull(debriefing):
if self.from_cp.captured:
self.to_cp.captured = True
self.to_cp.base.filter_units(db.UNIT_BY_COUNTRY[self.attacker_name])
self.to_cp.base.affect_strength(+self.STRENGTH_RECOVERY)
else:
if not self.from_cp.captured:
self.to_cp.captured = False
self.to_cp.base.affect_strength(+self.STRENGTH_RECOVERY)
def skip(self):
if self.to_cp.captured:
self.to_cp.captured = False
def player_defending(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
cas = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
escort = self.from_cp.base.scramble_sweep(self.game.settings.multiplier)
attackers = self.from_cp.base.armor
op = CaptureOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients={},
defender_clients=clients,
from_cp=self.from_cp,
to_cp=self.to_cp)
op.setup(cas=cas,
escort=escort,
attack=attackers,
intercept=interceptors,
defense=self.to_cp.base.armor,
aa=self.to_cp.base.aa)
self.operation = op
def player_attacking(self, cas: db.PlaneDict, escort: db.PlaneDict, armor: db.ArmorDict, clients: db.PlaneDict):
op = CaptureOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients=clients,
defender_clients={},
from_cp=self.from_cp,
to_cp=self.to_cp)
defenders = self.to_cp.base.scramble_sweep(self.game.settings.multiplier)
defenders.update(self.to_cp.base.scramble_cas(self.game.settings.multiplier))
op.setup(cas=cas,
escort=escort,
attack=armor,
intercept=defenders,
defense=self.to_cp.base.armor,
aa=self.to_cp.base.assemble_aa())
self.operation = op

View File

@@ -1,46 +1,89 @@
import typing
import logging
from dcs.action import Coalition
from dcs.unittype import UnitType
from dcs.task import *
from dcs.vehicles import AirDefence
from dcs.unittype import UnitType
from game import *
from game.infos.information import Information
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
DIFFICULTY_LOG_BASE = 1.1
import game.db as db
DIFFICULTY_LOG_BASE = 1.1
EVENT_DEPARTURE_MAX_DISTANCE = 340000
MINOR_DEFEAT_INFLUENCE = 0.1
DEFEAT_INFLUENCE = 0.3
STRONG_DEFEAT_INFLUENCE = 0.5
class Event:
silent = False
informational = False
is_awacs_enabled = False
ca_slots = 0
game = None # type: Game
location = None # type: Point
from_cp = None # type: ControlPoint
departure_cp = None # type: ControlPoint
to_cp = None # type: ControlPoint
operation = None # type: Operation
difficulty = 1 # type: int
game = None # type: Game
environment_settings = None # type: EnvironmentSettings
BONUS_BASE = 5
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint, game):
def __init__(self, game, from_cp: ControlPoint, target_cp: ControlPoint, location: Point, attacker_name: str, defender_name: str):
self.game = game
self.departure_cp = None
self.from_cp = from_cp
self.to_cp = target_cp
self.location = location
self.attacker_name = attacker_name
self.defender_name = defender_name
self.to_cp = to_cp
self.from_cp = from_cp
self.game = game
@property
def is_player_attacking(self) -> bool:
return self.attacker_name == self.game.player
return self.attacker_name == self.game.player_name
@property
def enemy_cp(self) -> ControlPoint:
if self.attacker_name == self.game.player:
if self.attacker_name == self.game.player_name:
return self.to_cp
else:
return self.from_cp
return self.departure_cp
@property
def threat_description(self) -> str:
return ""
def tasks(self) -> typing.Collection[typing.Type[Task]]:
return []
@property
def global_cp_available(self) -> bool:
return False
def is_departure_available_from(self, cp: ControlPoint) -> bool:
if not cp.captured:
return False
if self.location.distance_to_point(cp.position) > EVENT_DEPARTURE_MAX_DISTANCE:
return False
if cp.is_global and not self.global_cp_available:
return False
return True
def bonus(self) -> int:
return int(math.log(self.to_cp.importance + 1, DIFFICULTY_LOG_BASE) * self.BONUS_BASE)
@@ -48,45 +91,300 @@ class Event:
def is_successfull(self, debriefing: Debriefing) -> bool:
return self.operation.is_successfull(debriefing)
def player_attacking(self, cp: ControlPoint, flights: db.TaskForceDict):
if self.is_player_attacking:
self.departure_cp = cp
else:
self.to_cp = cp
def player_defending(self, cp: ControlPoint, flights: db.TaskForceDict):
if self.is_player_attacking:
self.departure_cp = cp
else:
self.to_cp = cp
def generate(self):
self.operation.is_awacs_enabled = self.is_awacs_enabled
self.operation.ca_slots = self.ca_slots
self.operation.prepare(self.game.theater.terrain, is_quick=False)
self.operation.generate()
self.operation.mission.save(persistency.mission_path_for("liberation_nextturn.miz"))
self.operation.current_mission.save(persistency.mission_path_for("liberation_nextturn.miz"))
self.environment_settings = self.operation.environment_settings
def generate_quick(self):
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.mission.save(persistency.mission_path_for("liberation_nextturn_quick.miz"))
def commit(self, debriefing: Debriefing):
for country, losses in debriefing.destroyed_units.items():
if country == self.attacker_name:
cp = self.from_cp
else:
cp = self.to_cp
cp.base.commit_losses(losses)
logging.info("Commiting mission results")
# ------------------------------
# Destroyed aircrafts
cp_map = {cp.id: cp for cp in self.game.theater.controlpoints}
for destroyed_aircraft in debriefing.killed_aircrafts:
try:
cpid = int(destroyed_aircraft.split("|")[3])
type = db.unit_type_from_name(destroyed_aircraft.split("|")[4])
if cpid in cp_map.keys():
cp = cp_map[cpid]
if type in cp.base.aircraft.keys():
logging.info("Aircraft destroyed : " + str(type))
cp.base.aircraft[type] = max(0, cp.base.aircraft[type]-1)
except Exception as e:
print(e)
# ------------------------------
# Destroyed ground units
killed_unit_count_by_cp = {cp.id: 0 for cp in self.game.theater.controlpoints}
cp_map = {cp.id: cp for cp in self.game.theater.controlpoints}
for killed_ground_unit in debriefing.killed_ground_units:
try:
cpid = int(killed_ground_unit.split("|")[3])
type = db.unit_type_from_name(killed_ground_unit.split("|")[4])
if cpid in cp_map.keys():
killed_unit_count_by_cp[cpid] = killed_unit_count_by_cp[cpid] + 1
cp = cp_map[cpid]
if type in cp.base.armor.keys():
logging.info("Ground unit destroyed : " + str(type))
cp.base.armor[type] = max(0, cp.base.armor[type] - 1)
except Exception as e:
print(e)
# ------------------------------
# Static ground objects
for destroyed_ground_unit_name in debriefing.killed_ground_units:
for cp in self.game.theater.controlpoints:
if not cp.ground_objects:
continue
# -- Static ground objects
for i, ground_object in enumerate(cp.ground_objects):
if ground_object.is_dead:
continue
if ground_object.matches_string_identifier(destroyed_ground_unit_name):
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:
if not hasattr(g, "units_losts"):
g.units_losts = []
for u in g.units:
if u.name == destroyed_ground_unit_name:
g.units.remove(u)
g.units_losts.append(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
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
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
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():
enemy_cps = [e for e in cp.connected_points if not e.captured]
for enemy_cp in enemy_cps:
print("Compute frontline progression for : " + cp.name + " to " + enemy_cp.name)
delta = 0
player_won = True
ally_casualties = killed_unit_count_by_cp[cp.id]
enemy_casualties = killed_unit_count_by_cp[enemy_cp.id]
ally_units_alive = cp.base.total_armor
enemy_units_alive = enemy_cp.base.total_armor
print(ally_units_alive)
print(enemy_units_alive)
print(ally_casualties)
print(enemy_casualties)
ratio = (1.0 + enemy_casualties) / (1.0 + ally_casualties)
player_aggresive = cp.stances[enemy_cp.id] in [CombatStance.AGGRESSIVE, CombatStance.ELIMINATION, CombatStance.BREAKTHROUGH]
if ally_units_alive == 0:
player_won = False
delta = STRONG_DEFEAT_INFLUENCE
elif enemy_units_alive == 0:
player_won = True
delta = STRONG_DEFEAT_INFLUENCE
elif cp.stances[enemy_cp.id] == CombatStance.RETREAT:
player_won = False
delta = STRONG_DEFEAT_INFLUENCE
else:
if enemy_casualties > ally_casualties:
player_won = True
if cp.stances[enemy_cp.id] == CombatStance.BREAKTHROUGH:
delta = STRONG_DEFEAT_INFLUENCE
else:
if ratio > 3:
delta = STRONG_DEFEAT_INFLUENCE
elif ratio < 1.5:
delta = MINOR_DEFEAT_INFLUENCE
else:
delta = DEFEAT_INFLUENCE
elif ally_casualties > enemy_casualties:
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:
# 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]:
print("Defensive stance, progress is limited")
delta = MINOR_DEFEAT_INFLUENCE
if player_won:
print(cp.name + " won ! factor > " + str(delta))
cp.base.affect_strength(delta)
enemy_cp.base.affect_strength(-delta)
info = Information("Frontline Report",
"Our ground forces from " + cp.name + " are making progress toward " + enemy_cp.name,
self.game.turn)
self.game.informations.append(info)
else:
print(cp.name + " lost ! factor > " + str(delta))
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,
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
units = None # type: typing.Dict[UnitType, int]
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint, game):
super(UnitsDeliveryEvent, self).__init__(attacker_name=attacker_name,
defender_name=defender_name,
super(UnitsDeliveryEvent, self).__init__(game=game,
location=to_cp.position,
from_cp=from_cp,
to_cp=to_cp,
game=game)
target_cp=to_cp,
attacker_name=attacker_name,
defender_name=defender_name)
self.units = {}
@@ -98,4 +396,9 @@ class UnitsDeliveryEvent(Event):
self.units[k] = self.units.get(k, 0) + v
def skip(self):
for k, v in self.units.items():
info = Information("Ally Reinforcement", str(k.id) + " x " + str(v) + " at " + self.to_cp.name, self.game.turn)
self.game.informations.append(info)
self.to_cp.base.commision_units(self.units)

View File

@@ -0,0 +1,53 @@
from game.event import *
from game.operation.frontlineattack import FrontlineAttackOperation
from userdata.debriefing import Debriefing
class FrontlineAttackEvent(Event):
@property
def tasks(self) -> typing.Collection[typing.Type[Task]]:
if self.is_player_attacking:
return [CAS, CAP]
else:
return [CAP]
@property
def global_cp_available(self) -> bool:
return True
def __str__(self):
return "Frontline attack"
def is_successfull(self, debriefing: Debriefing):
attackers_success = True
if self.from_cp.captured:
return attackers_success
else:
return not attackers_success
def commit(self, debriefing: Debriefing):
super(FrontlineAttackEvent, self).commit(debriefing)
def skip(self):
if self.to_cp.captured:
self.to_cp.base.affect_strength(-0.1)
def player_attacking(self, flights: db.TaskForceDict):
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)
self.operation = op
def player_defending(self, flights: db.TaskForceDict):
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)
self.operation = op

View File

@@ -1,40 +0,0 @@
import math
import random
from dcs.task import *
from game import *
from game.event import *
from game.event.groundintercept import GroundInterceptEvent
from game.operation.groundattack import GroundAttackOperation
class GroundAttackEvent(GroundInterceptEvent):
def __str__(self):
return "Destroy insurgents at {}".format(self.to_cp)
@property
def threat_description(self):
return ""
def player_defending(self, strikegroup: db.PlaneDict, clients: db.PlaneDict):
suitable_unittypes = db.find_unittype(Reconnaissance, self.attacker_name)
random.shuffle(suitable_unittypes)
unittypes = suitable_unittypes[:self.TARGET_VARIETY]
typecount = max(math.floor(self.difficulty * self.TARGET_AMOUNT_FACTOR), 1)
self.targets = {unittype: typecount for unittype in unittypes}
op = GroundAttackOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients={},
defender_clients=clients,
from_cp=self.from_cp,
to_cp=self.to_cp)
op.setup(target=self.targets,
strikegroup=strikegroup)
self.operation = op
def player_attacking(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
assert False

View File

@@ -1,106 +0,0 @@
import math
import random
from dcs.task import *
from dcs.vehicles import AirDefence
from game import *
from game.event import *
from game.operation.groundintercept import GroundInterceptOperation
from userdata.debriefing import Debriefing
class GroundInterceptEvent(Event):
TARGET_AMOUNT_FACTOR = 2
TARGET_VARIETY = 2
STRENGTH_INFLUENCE = 0.3
SUCCESS_TARGETS_HIT_PERCENTAGE = 0.5
targets = None # type: db.ArmorDict
@property
def threat_description(self):
if not self.game.is_player_attack(self):
return "{} aicraft".format(self.from_cp.base.scramble_count(self.game.settings.multiplier, CAS))
else:
return super(GroundInterceptEvent, self).threat_description
def __str__(self):
return "Fontline CAS from {} at {}".format(self.from_cp, self.to_cp)
def is_successfull(self, debriefing: Debriefing):
total_targets = sum(self.targets.values())
destroyed_targets = 0
for unit, count in debriefing.destroyed_units[self.defender_name].items():
if unit in self.targets:
destroyed_targets += count
if self.from_cp.captured:
return float(destroyed_targets) / total_targets >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
else:
return float(destroyed_targets) / total_targets < self.SUCCESS_TARGETS_HIT_PERCENTAGE
def commit(self, debriefing: Debriefing):
super(GroundInterceptEvent, self).commit(debriefing)
if self.from_cp.captured:
if self.is_successfull(debriefing):
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(+self.STRENGTH_INFLUENCE)
else:
if self.is_successfull(debriefing):
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def skip(self):
if self.to_cp.captured:
self.to_cp.base.affect_strength(-0.1)
def player_attacking(self, strikegroup: db.PlaneDict, clients: db.PlaneDict):
suitable_unittypes = db.find_unittype(PinpointStrike, self.defender_name)
random.shuffle(suitable_unittypes)
unittypes = suitable_unittypes[:self.TARGET_VARIETY]
typecount = max(math.floor(self.difficulty * self.TARGET_AMOUNT_FACTOR), 1)
self.targets = {unittype: typecount for unittype in unittypes}
defense_aa_unit = random.choice(self.game.commision_unit_types(self.to_cp, AirDefence))
self.targets[defense_aa_unit] = 1
op = GroundInterceptOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients=clients,
defender_clients={},
from_cp=self.from_cp,
to_cp=self.to_cp)
op.setup(target=self.targets,
strikegroup=strikegroup,
interceptors={})
self.operation = op
def player_defending(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
suitable_unittypes = db.find_unittype(PinpointStrike, self.defender_name)
random.shuffle(suitable_unittypes)
unittypes = suitable_unittypes[:self.TARGET_VARIETY]
typecount = max(math.floor(self.difficulty * self.TARGET_AMOUNT_FACTOR), 1)
self.targets = {unittype: typecount for unittype in unittypes}
op = GroundInterceptOperation(
self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients={},
defender_clients=clients,
from_cp=self.from_cp,
to_cp=self.to_cp
)
strikegroup = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
op.setup(target=self.targets,
strikegroup=strikegroup,
interceptors=interceptors)
self.operation = op

View File

@@ -1,47 +0,0 @@
import math
import random
from dcs.task import *
from dcs.vehicles import *
from game import db
from game.operation.infantrytransport import InfantryTransportOperation
from theater.conflicttheater import *
from userdata.debriefing import Debriefing
from .event import Event
class InfantryTransportEvent(Event):
STRENGTH_INFLUENCE = 0.3
def __str__(self):
return "Frontline transport troops to {}".format(self.to_cp)
def is_successfull(self, debriefing: Debriefing):
return True
def commit(self, debriefing: Debriefing):
super(InfantryTransportEvent, self).commit(debriefing)
if self.is_successfull(debriefing):
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def player_attacking(self, transport: db.HeliDict, clients: db.HeliDict):
op = InfantryTransportOperation(
game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients=clients,
defender_clients={},
from_cp=self.from_cp,
to_cp=self.to_cp
)
air_defense = db.find_unittype(AirDefence, self.defender_name)[0]
op.setup(transport=transport,
aa={air_defense: 2})
self.operation = op

View File

@@ -1,100 +0,0 @@
import math
import random
from dcs.task import *
from dcs.vehicles import *
from game import db
from game.operation.intercept import InterceptOperation
from theater.conflicttheater import *
from userdata.debriefing import Debriefing
from .event import Event
class InterceptEvent(Event):
STRENGTH_INFLUENCE = 0.3
GLOBAL_STRENGTH_INFLUENCE = 0.3
AIRDEFENSE_COUNT = 3
transport_unit = None # type: FlyingType
def __str__(self):
return "Intercept from {} at {}".format(self.from_cp, self.to_cp)
@property
def threat_description(self):
return "{} aircraft".format(self.enemy_cp.base.scramble_count(self.game.settings.multiplier, CAP))
def is_successfull(self, debriefing: Debriefing):
units_destroyed = debriefing.destroyed_units[self.defender_name].get(self.transport_unit, 0)
if self.from_cp.captured:
return units_destroyed > 0
else:
return units_destroyed == 0
def commit(self, debriefing: Debriefing):
super(InterceptEvent, self).commit(debriefing)
if self.attacker_name == self.game.player:
if self.is_successfull(debriefing):
for _, cp in self.game.theater.conflicts(True):
cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
# enemy attacking
if self.is_successfull(debriefing):
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def skip(self):
if self.to_cp.captured:
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def player_attacking(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
escort = self.to_cp.base.scramble_sweep(self.game.settings.multiplier)
self.transport_unit = random.choice(db.find_unittype(Transport, self.defender_name))
assert self.transport_unit is not None
airdefense_unit = db.find_unittype(AirDefence, self.defender_name)[-1]
op = InterceptOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients=clients,
defender_clients={},
from_cp=self.from_cp,
to_cp=self.to_cp)
op.setup(escort=escort,
transport={self.transport_unit: 1},
airdefense={airdefense_unit: self.AIRDEFENSE_COUNT},
interceptors=interceptors)
self.operation = op
def player_defending(self, escort: db.PlaneDict, clients: db.PlaneDict):
# TODO: even not quick mission is too quick
interceptors = self.from_cp.base.scramble_interceptors(self.game.settings.multiplier)
self.transport_unit = random.choice(db.find_unittype(Transport, self.defender_name))
assert self.transport_unit is not None
op = InterceptOperation(game=self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients={},
defender_clients=clients,
from_cp=self.from_cp,
to_cp=self.to_cp)
op.setup(escort=escort,
transport={self.transport_unit: 1},
interceptors=interceptors,
airdefense={})
self.operation = op

View File

@@ -1,108 +0,0 @@
import typing
import math
import random
from dcs.task import *
from dcs.vehicles import *
from game import db
from game.operation.navalintercept import NavalInterceptionOperation
from userdata.debriefing import Debriefing
from .event import Event
class NavalInterceptEvent(Event):
STRENGTH_INFLUENCE = 0.3
SUCCESS_RATE = 0.5
targets = None # type: db.ShipDict
def _targets_count(self) -> int:
from gen.conflictgen import IMPORTANCE_LOW, IMPORTANCE_HIGH
factor = (self.to_cp.importance - IMPORTANCE_LOW) * 10
return max(int(factor), 1)
def __str__(self) -> str:
return "Naval intercept at {}".format(self.to_cp)
@property
def threat_description(self):
s = "{} ship(s)".format(self._targets_count())
if not self.from_cp.captured:
s += ", {} aircraft".format(self.from_cp.base.scramble_count(self.game.settings.multiplier))
return s
def is_successfull(self, debriefing: Debriefing):
total_targets = sum(self.targets.values())
destroyed_targets = 0
for unit, count in debriefing.destroyed_units[self.defender_name].items():
if unit in self.targets:
destroyed_targets += count
if self.from_cp.captured:
return math.ceil(float(destroyed_targets) / total_targets) > self.SUCCESS_RATE
else:
return math.ceil(float(destroyed_targets) / total_targets) < self.SUCCESS_RATE
def commit(self, debriefing: Debriefing):
super(NavalInterceptEvent, self).commit(debriefing)
if self.attacker_name == self.game.player:
if self.is_successfull(debriefing):
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
# enemy attacking
if self.is_successfull(debriefing):
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def skip(self):
if self.to_cp.captured:
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def player_attacking(self, strikegroup: db.PlaneDict, clients: db.PlaneDict):
self.targets = {
random.choice(db.find_unittype(CargoTransportation, self.defender_name)): self._targets_count(),
}
op = NavalInterceptionOperation(
self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients=clients,
defender_clients={},
from_cp=self.from_cp,
to_cp=self.to_cp
)
op.setup(strikegroup=strikegroup,
interceptors={},
targets=self.targets)
self.operation = op
def player_defending(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
self.targets = {
random.choice(db.find_unittype(CargoTransportation, self.defender_name)): self._targets_count(),
}
op = NavalInterceptionOperation(
self.game,
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker_clients={},
defender_clients=clients,
from_cp=self.from_cp,
to_cp=self.to_cp
)
strikegroup = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
op.setup(strikegroup=strikegroup,
interceptors=interceptors,
targets=self.targets)
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": "Combined Joint Task Forces Blue",
"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": "Combined Joint Task Forces Blue",
"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,83 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
BLUEFOR_MODERN = {
"country": "Combined Joint Task Forces Blue",
"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,
A_10C_2,
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

@@ -0,0 +1,80 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
China_2010 = {
"country": "China",
"side": "red",
"units": [
MiG_21Bis, # Standing as J-7
Su_30,
Su_33,
J_11A,
JF_17,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
KJ_2000,
Mi_8MT,
Mi_28N,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C, # Standing as HQ-9+
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.HQ_7_Self_Propelled_LN,
Armor.ZTZ_96B,
Armor.MBT_T_55,
Armor.ZBD_04A,
Armor.IFV_BMP_1,
Artillery.MLRS_9A52_Smerch,
Artillery.SPH_2S9_Nona,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Paratrooper_AKS,
Infantry.Infantry_Soldier_Rus,
Infantry.Paratrooper_RPG_16,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160
],
"shorad":[
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.Rapier_FSA_Launcher, # Standing as PL-9C Shorad
AirDefence.HQ_7_Self_Propelled_LN
], "aircraft_carrier": [
CV_1143_5_Admiral_Kuznetsov,
], "destroyer": [
Type_052B_Destroyer,
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,
"jtac_unit": WingLoong_I
}

View File

@@ -0,0 +1,47 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
France_1995 = {
"country": "France",
"side": "blue",
"units": [
M_2000C,
Mirage_2000_5,
KC_135,
KC130,
C_130,
E_3A,
SA342M,
SA342L,
SA342Mistral,
Armor.MBT_Leclerc,
Armor.TPz_Fuchs, # Standing as VAB
Armor.APC_Cobra, # Standing as VBL
Armor.ATGM_M1134_Stryker, # Standing as VAB Mephisto
Artillery.SPH_M109_Paladin, # Standing as AMX30 AuF1
Artillery.MLRS_M270,
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
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,62 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
France_2005 = {
"country": "France",
"side": "blue",
"units":[
M_2000C,
Mirage_2000_5,
FA_18C_hornet, # Standing as Rafale M
KC_135,
KC130,
C_130,
E_3A,
SA342M,
SA342L,
SA342Mistral,
Armor.MBT_Leclerc,
Armor.TPz_Fuchs, # Standing as VAB
Armor.APC_Cobra, # Standing as VBL
Armor.ATGM_M1134_Stryker, # Standing as VAB Mephisto
Artillery.SPH_M109_Paladin, # Standing as AMX30 AuF1
Artillery.MLRS_M270,
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"
], "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

@@ -0,0 +1,47 @@
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",
"units": [
FW_190A8,
FW_190D9,
Bf_109K_4,
Ju_88A4,
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.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_8_8cm_Flak_36,
],"requirements":{
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
},
"shorad": [
AirDefence.AAA_8_8cm_Flak_36,
],
"objects": WW2_GERMANY_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["UBoatGroupGenerator", "SchnellbootGroupGenerator"],
"boat_count": 2,
"missiles": ["V1GroupGenerator"],
"missiles_count": 1
}

View File

@@ -0,0 +1,40 @@
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,
],"requirements":{
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
},
"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

@@ -0,0 +1,45 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Germany_1990 = {
"country": "Germany",
"side": "blue",
"units":[
MiG_29G,
Tornado_IDS,
F_4E,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
SA342M,
SA342L,
Armor.TPz_Fuchs,
Armor.MBT_Leopard_1A3,
Armor.MBT_Leopard_2,
Armor.IFV_Marder,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Roland_ADS,
AirDefence.SAM_Hawk_PCP,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
],
"shorad":[
AirDefence.SPAAA_Gepard,
AirDefence.SAM_Roland_ADS,
], "boat":[
"OliverHazardPerryGroupGenerator"
]
}

View File

@@ -0,0 +1,55 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
India_2010 = {
"country": "India",
"side": "blue",
"units": [
Mirage_2000_5,
M_2000C,
MiG_27K,
MiG_21Bis,
MiG_29S,
Su_30,
KC_135,
KC130,
C_130,
E_3A,
AH_64A,
Mi_8MT,
Armor.MBT_T_90,
Armor.MBT_T_72B,
Armor.IFV_BMP_2,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_3_S_125_LN_5P73,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
],
"shorad":[
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.AAA_ZU_23_Emplacement,
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3,
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.SAM_SA_19_Tunguska_2S6
], "aircraft_carrier": [
CV_1143_5_Admiral_Kuznetsov,
], "destroyer": [
FSG_1241_1MP_Molniya,
], "carrier_names": [
"INS Vikramaditya"
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator", "MolniyaGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,27 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
Insurgent = {
"country": "Insurgents",
"side": "red",
"units": [
AirDefence.AAA_ZU_23_Insurgent_Closed,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375,
Armor.APC_Cobra,
Armor.APC_MTLB,
Armor.ARV_BRDM_2,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Infantry_Soldier_Insurgents,
Infantry.Soldier_RPG,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160
]
}

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

@@ -0,0 +1,58 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Iran_2015 = {
"country": "Iran",
"side": "red",
"units": [
MiG_29A,
F_4E,
F_14B,
F_5E_3,
MiG_21Bis,
Su_24M,
Su_25,
Su_17M4,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
Mi_28N,
Mi_24V,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_SA_2_LN_SM_90,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
Armor.APC_M113,
Armor.APC_BTR_80,
Armor.MBT_M60A3_Patton,
Armor.MBT_T_72B,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Soldier_AK,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160
],
"shorad":[
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.AAA_ZU_23_Insurgent_Closed
], "boat":[
"GrishaGroupGenerator", "MolniyaGroupGenerator", "KiloSubGroupGenerator"
]
}

View File

@@ -0,0 +1,33 @@
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Israel_1948 = {
"country": "Israel",
"side": "blue",
"units":[
SpitfireLFMkIXCW,
SpitfireLFMkIX,
P_51D,
P_51D_30_NA,
Bf_109K_4, # Standing as Avia S-199
B_17G,
Armor.MT_M4A4_Sherman_Firefly,
Armor.APC_M2A1,
Armor.MT_M4_Sherman,
Armor.LAC_M8_Greyhound,
Unarmed.Transport_M818,
Infantry.Infantry_SMLE_No_4_Mk_1,
AirDefence.AAA_Bofors_40mm,
Armed_speedboat,
],"requirements":{
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
},
"shorad": [
AirDefence.AAA_Bofors_40mm
], "boat": [
], "has_jtac": False
}

View File

@@ -0,0 +1,112 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
from pydcs_extensions.a4ec.a4ec import A_4E_C
Israel_1973 = {
"country": "Israel",
"side": "blue",
"units":[
F_4E,
A_4E_C,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
Armor.MT_M4A4_Sherman_Firefly,
Armor.APC_M2A1,
Armor.MBT_M60A3_Patton,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.SAM_Hawk_PCP,
AirDefence.AAA_Bofors_40mm,
AirDefence.SAM_Chaparral_M48,
Armed_speedboat,
], "requirements": {
"Community A-4E": "https://heclak.github.io/community-a4e-c/",
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
}, "shorad": [
AirDefence.SAM_Chaparral_M48,
AirDefence.AAA_Bofors_40mm
], "boat": [
], "has_jtac": True
}
Israel_1973_NO_WW2_UNITS = {
"country": "Israel",
"side": "blue",
"units":[
F_4E,
A_4E_C,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
Armor.MBT_M60A3_Patton,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Chaparral_M48,
Armed_speedboat,
], "requirements": {
"Community A-4E": "https://heclak.github.io/community-a4e-c/",
}, "shorad": [
AirDefence.SAM_Chaparral_M48,
], "boat": [
], "has_jtac": True
}
Israel_1982 = {
"country": "Israel",
"side": "blue",
"units":[
F_4E,
A_4E_C,
F_15C,
F_16A,
F_16C_50,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
AH_1W,
Armor.APC_M113,
Armor.MBT_M60A3_Patton,
Armor.MBT_Merkava_Mk__4,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Chaparral_M48,
Armed_speedboat,
], "requirements": {
"Community A-4E": "https://heclak.github.io/community-a4e-c/",
}, "shorad": [
AirDefence.SAM_Chaparral_M48,
], "boat": [
], "has_jtac": True
}

View File

@@ -0,0 +1,44 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Israel_2000 = {
"country": "Israel",
"side": "blue",
"units":[
F_16C_50,
F_15C,
F_15E,
F_4E,
KC_135,
KC130,
C_130,
E_3A,
AH_1W,
AH_64D,
Armor.MBT_Merkava_Mk__4,
Armor.APC_M113,
Armor.APC_M1043_HMMWV_Armament,
Armor.ATGM_M1045_HMMWV_TOW,
Artillery.SPH_M109_Paladin,
Artillery.MLRS_M270,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.SAM_Patriot_EPP_III,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
],
"shorad": [
AirDefence.SAM_Avenger_M1097
], "boat": [
"ArleighBurkeGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,48 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Italy_1990 = {
"country": "Italy",
"side": "blue",
"units": [
Tornado_IDS,
AV8BNA,
# MB339,
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"
], "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

@@ -0,0 +1,49 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.vehicles import *
Libya_2011 = {
"country": "Libya",
"side": "red",
"units": [
MiG_21Bis,
MiG_23MLD,
Su_24M,
Su_17M4,
Mi_24V,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.SAM_SA_2_LN_SM_90,
AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.HQ_7_Self_Propelled_LN,
Armor.IFV_BMP_1,
Armor.FDDM_Grad,
Armor.ARV_BRDM_2,
Armor.MBT_T_55,
Armor.MBT_T_72B,
Artillery.MLRS_BM_21_Grad,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Paratrooper_RPG_16,
Infantry.Infantry_Soldier_Insurgents
],
"shorad":[
AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.SAM_SA_8_Osa_9A33,
], "boat": [
"GrishaGroupGenerator", "MolniyaGroupGenerator"
]
}

View File

@@ -0,0 +1,38 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Netherlands_1990 = {
"country": "The Netherlands",
"side": "blue",
"units": [
F_16C_50,
F_5E_3,
KC_135,
KC130,
C_130,
E_3A,
AH_64A,
Armor.APC_M113,
Armor.MBT_Leopard_1A3,
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
], "boat": [
"OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,53 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
NorthKorea_2000 = {
"country": "North Korea",
"side": "red",
"units":[
MiG_29A,
Su_25,
MiG_15bis,
MiG_21Bis,
MiG_23MLD,
MiG_19P,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
Mi_8MT,
Mi_24V,
Armor.MBT_T_55,
Armor.MBT_T_72B,
Armor.MBT_T_80U,
Armor.IFV_BMP_1,
Armor.APC_BTR_80,
Armor.ARV_BRDM_2,
Unarmed.Transport_M818,
Infantry.Soldier_AK,
AirDefence.SAM_SA_2_LN_SM_90,
AirDefence.SAM_SA_3_S_125_LN_5P73,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160
],
"shorad":[
AirDefence.AAA_ZU_23_Emplacement,
AirDefence.SPAAA_ZSU_23_4_Shilka
],
"boat": [
"GrishaGroupGenerator", "MolniyaGroupGenerator"
]
}

View File

@@ -0,0 +1,42 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Pakistan_2015 = {
"country": "Pakistan",
"side": "blue",
"units": [
JF_17,
F_16C_50,
MiG_21Bis, # Standing as J-7
MiG_19P, # Standing as J-6
IL_78M,
E_3A,
UH_1H,
AH_1W,
Armor.MBT_T_80U,
Armor.MBT_T_55, # Standing as Al-Zarrar / Type 59 MBT
Armor.ZBD_04A,
Armor.APC_BTR_80,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.SAM_SA_2_LN_SM_90, # Standing as HQ-2
AirDefence.SAM_SA_10_S_300PS_LN_5P85C, # Standing as HQ-9
Armed_speedboat,
], "shorad": [
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,
"jtac_unit": WingLoong_I
}

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

@@ -0,0 +1,38 @@
from dcs.planes import MiG_15bis, IL_76MD, IL_78M, An_26B, An_30M, Yak_40
from dcs.ships import CV_1143_5_Admiral_Kuznetsov, Bulk_cargo_ship_Yakushev, Dry_cargo_ship_Ivanov, Tanker_Elnya_160
from dcs.vehicles import AirDefence, Armor, Unarmed, Infantry, Artillery
Russia_1955 = {
"country": "Russia",
"side": "red",
"units": [
MiG_15bis,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
AirDefence.AAA_ZU_23_Closed,
AirDefence.AAA_ZU_23_on_Ural_375,
Armor.ARV_BRDM_2,
Armor.FDDM_Grad,
Armor.APC_MTLB,
Armor.MBT_T_55,
Artillery.MLRS_BM_21_Grad,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160,
# Infantry squad
Infantry.Paratrooper_AKS,
Infantry.Infantry_Soldier_Rus,
Infantry.Paratrooper_RPG_16,
]
}

View File

@@ -0,0 +1,55 @@
from dcs.helicopters import Mi_8MT
from dcs.planes import MiG_15bis, MiG_19P, MiG_21Bis, IL_76MD, IL_78M, An_26B, An_30M, Yak_40, A_50
from dcs.ships import CV_1143_5_Admiral_Kuznetsov, Bulk_cargo_ship_Yakushev, Dry_cargo_ship_Ivanov, Tanker_Elnya_160
from dcs.vehicles import AirDefence, Armor, Unarmed, Infantry, Artillery
Russia_1965 = {
"country": "Russia",
"side": "red",
"units": [
MiG_15bis,
MiG_19P,
MiG_21Bis,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
Mi_8MT,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_2_LN_SM_90,
AirDefence.SAM_SA_3_S_125_LN_5P73,
Armor.ARV_BRDM_2,
Armor.APC_BTR_80,
Armor.ARV_BTR_RD,
Armor.IFV_BMD_1,
Armor.IFV_BMP_1,
Armor.MBT_T_55,
Artillery.MLRS_BM_21_Grad,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160,
# Infantry squad
Infantry.Paratrooper_AKS,
Infantry.Infantry_Soldier_Rus,
Infantry.Paratrooper_RPG_16,
],
"shorad":[
AirDefence.AAA_ZU_23_Closed
], "boat": [
"GrishaGroupGenerator"
]
}

View File

@@ -0,0 +1,71 @@
from dcs.helicopters import Mi_8MT, Mi_24V
from dcs.planes import MiG_21Bis, MiG_23MLD, MiG_25PD, MiG_29A, Su_17M4, Su_24M, Su_25, IL_76MD, IL_78M, An_26B, An_30M, \
Yak_40, A_50
from dcs.ships import *
from dcs.vehicles import AirDefence, Armor, Unarmed, Infantry, Artillery
Russia_1975 = {
"country": "Russia",
"side": "red",
"units": [
MiG_21Bis,
MiG_23MLD,
MiG_25PD,
MiG_29A,
Su_17M4,
Su_24M,
Su_25,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
Mi_8MT,
Mi_24V,
AirDefence.AAA_ZU_23_Closed,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_3_S_125_LN_5P73,
Armor.ARV_BRDM_2,
Armor.APC_BTR_80,
Armor.IFV_BMD_1,
Armor.IFV_BMP_1,
Armor.MBT_T_55,
Artillery.SPH_2S9_Nona,
Artillery.SPH_2S1_Gvozdika,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160,
# Infantry squad
Infantry.Paratrooper_AKS,
Infantry.Infantry_Soldier_Rus,
Infantry.Paratrooper_RPG_16,
],
"shorad": [
AirDefence.AAA_ZU_23_Emplacement,
AirDefence.SPAAA_ZSU_23_4_Shilka
], "aircraft_carrier": [
CV_1143_5_Admiral_Kuznetsov,
], "destroyer": [
FF_1135M_Rezky,
], "cruiser": [
CGN_1144_2_Pyotr_Velikiy,
], "boat": [
"RussianNavyGroupGenerator", "KiloSubGroupGenerator", "MolniyaGroupGenerator"
]
}

View File

@@ -0,0 +1,74 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Russia_1990 = {
"country": "Russia",
"side": "red",
"units": [
MiG_23MLD,
MiG_25PD,
MiG_29A,
MiG_29S,
MiG_31,
Su_27,
Su_24M,
Su_25,
Ka_50,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
Mi_8MT,
Mi_24V,
AirDefence.AAA_ZU_23_Closed,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_3_S_125_LN_5P73,
Armor.ARV_BRDM_2,
Armor.APC_BTR_80,
Armor.IFV_BMD_1,
Armor.IFV_BMP_1,
Armor.MBT_T_55,
Artillery.MLRS_9K57_Uragan_BM_27,
Artillery.SPH_2S19_Msta,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160,
# Infantry squad
Infantry.Paratrooper_AKS,
Infantry.Infantry_Soldier_Rus,
Infantry.Paratrooper_RPG_16,
],
"shorad":[
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

@@ -0,0 +1,77 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Russia_2010 = {
"country": "Russia",
"side": "red",
"units": [
Su_27,
Su_30,
Su_33,
MiG_29S,
MiG_31,
Su_25,
Su_25T,
Su_34,
Su_24M,
L_39ZA,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
Ka_50,
Mi_8MT,
Mi_24V,
Mi_28N,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
Armor.APC_BTR_80,
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,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160,
# Infantry squad
Infantry.Paratrooper_AKS,
Infantry.Infantry_Soldier_Rus,
Infantry.Paratrooper_RPG_16,
],
"shorad":[
AirDefence.SAM_SA_19_Tunguska_2S6,
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

@@ -0,0 +1,50 @@
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Spain_1990 = {
"country": "Spain",
"side": "blue",
"units": [
FA_18C_hornet,
AV8BNA,
F_5E_3,
C_101CC,
KC_135,
KC130,
C_130,
E_3A,
Armor.MBT_M60A3_Patton,
Armor.MBT_Leopard_2,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
AirDefence.SAM_Avenger_M1097,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad":[
AirDefence.SAM_Avenger_M1097,
], "aircraft_carrier": [
CVN_74_John_C__Stennis, # Standing as Principe de Asturias
], "helicopter_carrier": [
LHA_1_Tarawa, # Standing as Juan Carlos
], "destroyer": [
Oliver_Hazzard_Perry_class,
], "cruiser": [
Ticonderoga_class,
], "carrier_names": [
"Principe de Asturias",
], "lhanames": [
"Juan Carlos I",
], "boat":[
"OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,31 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
Sweden_1990 = {
"country": "Sweden",
"side": "blue",
"units": [
AJS37,
UH_1H,
AirDefence.SAM_Hawk_PCP,
Armor.IFV_MCV_80, # Standing as Strf 90
Armor.MBT_Leopard_2,
Armor.APC_M1126_Stryker_ICV, # Closest thing available
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Soldier_AK,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160,
],
"shorad": [
AirDefence.SAM_Avenger_M1097
], "has_jtac": True
}

267
game/factions/syria.py Normal file
View File

@@ -0,0 +1,267 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.vehicles import *
Syria_2011 = {
"country": "Syria",
"side": "red",
"units": [
MiG_21Bis,
MiG_23MLD,
MiG_25PD,
MiG_29S,
Su_17M4,
Su_24M,
L_39ZA,
Mi_24V,
Mi_8MT,
SA342M,
SA342L,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_SA_2_LN_SM_90,
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
Armor.IFV_BMP_1,
Armor.IFV_BMP_2,
Armor.APC_BTR_80,
Armor.ARV_BRDM_2,
Armor.APC_MTLB,
Armor.APC_Cobra,
Armor.MBT_T_55,
Armor.MBT_T_72B,
Armor.MBT_T_90,
Artillery.MLRS_BM_21_Grad,
Artillery.MLRS_9K57_Uragan_BM_27,
Artillery.SPH_2S1_Gvozdika,
Artillery.SPH_2S9_Nona,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Paratrooper_RPG_16,
Infantry.Soldier_AK
],
"shorad": [
AirDefence.SAM_SA_8_Osa_9A33,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3,
AirDefence.SAM_SA_9_Strela_1_9P31,
AirDefence.SAM_SA_19_Tunguska_2S6,
AirDefence.AAA_ZU_23_on_Ural_375,
], "boat": [
"GrishaGroupGenerator", "MolniyaGroupGenerator"
]
}
Syria_1973 = {
"country": "Syria",
"side": "red",
"units": [
MiG_21Bis,
MiG_19P,
MiG_15bis, # Standing as Mig-17
Su_17M4, # Standing as Su-7
Mi_8MT,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_SA_2_LN_SM_90,
Armor.IFV_BMP_1,
Armor.APC_MTLB,
Armor.MBT_T_55,
Artillery.MLRS_BM_21_Grad,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Paratrooper_RPG_16,
Infantry.Soldier_AK
],
"shorad": [
AirDefence.AAA_ZU_23_on_Ural_375,
], "boat": [
"GrishaGroupGenerator"
]
}
Syria_1982 = {
"country": "Syria",
"side": "red",
"units": [
MiG_21Bis,
MiG_23MLD,
MiG_25PD,
MiG_19P,
Su_17M4, # Standing as Su-7
Mi_8MT,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
AirDefence.SAM_SA_6_Kub_LN_2P25,
AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_SA_2_LN_SM_90,
Armor.IFV_BMP_1,
Armor.APC_MTLB,
Armor.MBT_T_55,
Armor.MBT_T_72B,
Artillery.MLRS_BM_21_Grad,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Paratrooper_RPG_16,
Infantry.Soldier_AK
],
"shorad": [
AirDefence.AAA_ZU_23_on_Ural_375,
], "boat": [
"GrishaGroupGenerator"
]
}
Syria_1967 = {
"country": "Syria",
"side": "red",
"units": [
MiG_21Bis,
MiG_19P,
MiG_15bis, # Standing as Mig-17
Su_17M4, # Standing as Su-7
Mi_8MT,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
AirDefence.SAM_SA_2_LN_SM_90,
Armor.ARV_BRDM_2,
Armor.MBT_T_55,
Artillery.MLRS_BM_21_Grad,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Paratrooper_RPG_16,
Infantry.Soldier_AK
],
"shorad": [
AirDefence.AAA_ZU_23_on_Ural_375,
], "boat": [
"GrishaGroupGenerator"
]
}
Syria_1967_WW2_Weapons = {
"country": "Syria",
"side": "red",
"units": [
MiG_21Bis,
MiG_19P,
MiG_15bis, # Standing as Mig-17
Su_17M4, # Standing as Su-7
Mi_8MT,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
AirDefence.SAM_SA_2_LN_SM_90,
Armor.ARV_BRDM_2,
Armor.MBT_T_55,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
Armor.StuG_III_Ausf__G,
Armor.TD_Jagdpanzer_IV,
Artillery.MLRS_BM_21_Grad,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Soldier_RPG,
Infantry.Soldier_AK
], "requirements": {
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
},
"shorad": [
AirDefence.AAA_ZU_23_on_Ural_375,
], "boat": [
"GrishaGroupGenerator"
]
}
Arab_Armies_1948 = {
"country": "Syria",
"side": "red",
"units": [
SpitfireLFMkIX,
SpitfireLFMkIXCW,
AirDefence.SAM_SA_2_LN_SM_90,
Armor.MT_M4_Sherman,
Armor.MT_Pz_Kpfw_IV_Ausf_H,
Armor.APC_Sd_Kfz_251,
Armor.IFV_Sd_Kfz_234_2_Puma,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Infantry_SMLE_No_4_Mk_1,
AirDefence.AAA_8_8cm_Flak_36,
], "requirements": {
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
},
"shorad": [
AirDefence.AAA_8_8cm_Flak_36,
], "boat": [
"GrishaGroupGenerator"
]
}

View File

@@ -0,0 +1,41 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Turkey_2005 = {
"country": "Turkey",
"side": "blue",
"units":[
F_16C_50,
F_4E,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
AH_1W,
Armor.MBT_Leopard_2,
Armor.MBT_Leopard_1A3,
Armor.MBT_M60A3_Patton,
Armor.APC_Cobra,
Armor.APC_BTR_80,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.SAM_Avenger_M1097,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "shorad":[
AirDefence.AAA_ZU_23_Emplacement,
AirDefence.SPAAA_ZSU_23_4_Shilka
], "boat":[
"OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

38
game/factions/uae_2005.py Normal file
View File

@@ -0,0 +1,38 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
UAE_2005 = {
"country": "United Arab Emirates",
"side": "blue",
"units":[
M_2000C,
Mirage_2000_5,
F_16C_50,
KC_135,
KC130,
C_130,
E_3A,
AH_64D,
Armor.MBT_Leclerc,
Armor.IFV_BMP_3,
Armor.TPz_Fuchs,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.Rapier_FSA_Launcher,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
], "boat":[
"OliverHazardPerryGroupGenerator"
],
"has_jtac": True,
"jtac_unit": WingLoong_I
}

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

@@ -0,0 +1,44 @@
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,
],"requirements":{
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
},
"objects": WW2_ALLIES_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["WW2LSTGroupGenerator"],
"boat_count": 1
}

52
game/factions/uk_1990.py Normal file
View File

@@ -0,0 +1,52 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
UnitedKingdom_1990 = {
"country": "UK",
"side": "blue",
"units":[
AV8BNA, # Standing as BAE Harrier 2
Tornado_GR4,
F_4E,
KC_135,
KC130,
C_130,
E_3A,
SA342M,
AH_64A,
Armor.MBT_Challenger_II,
Armor.IFV_MCV_80,
Armor.APC_M1043_HMMWV_Armament,
Armor.ATGM_M1045_HMMWV_TOW,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.Rapier_FSA_Launcher,
AirDefence.SAM_Avenger_M1097, # Standing as Starstreak
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": [
"HMS Invincible",
"HMS Illustrious",
"HMS Ark Royal",
], "boat":[
"ArleighBurkeGroupGenerator", "OliverHazardPerryGroupGenerator"
], "has_jtac": True
}

View File

@@ -0,0 +1,53 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
Ukraine_2010 = {
"country": "Ukraine",
"side": "blue",
"units": [
Su_25,
Su_25T,
Su_24M,
Su_27,
MiG_29S,
L_39ZA,
IL_76MD,
IL_78M,
An_26B,
An_30M,
Yak_40,
A_50,
Mi_8MT,
Mi_24V,
AirDefence.SAM_SA_3_S_125_LN_5P73,
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C,
Armor.APC_M1043_HMMWV_Armament,
Armor.IFV_BMP_3,
Armor.IFV_BMP_2,
Armor.APC_BTR_80,
Armor.MBT_T_80U,
Armor.MBT_T_72B,
Unarmed.Transport_Ural_375,
Unarmed.Transport_UAZ_469,
Infantry.Soldier_AK,
CV_1143_5_Admiral_Kuznetsov,
Bulk_cargo_ship_Yakushev,
Dry_cargo_ship_Ivanov,
Tanker_Elnya_160,
],
"shorad":[
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"
]
}

86
game/factions/usa_1944.py Normal file
View File

@@ -0,0 +1,86 @@
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,
P_47D_30,
A_20G,
B_17G,
Armor.MT_M4_Sherman,
Armor.M30_Cargo_Carrier,
Armor.APC_M2A1,
Armor.LAC_M8_Greyhound,
Armor.TD_M10_GMC,
Artillery.M12_GMC,
Infantry.Infantry_M1_Garand,
LS_Samuel_Chase,
LST_Mk_II,
LCVP__Higgins_boat,
Unarmed.CCKW_353,
AirDefence.AAA_Bofors_40mm,
], "shorad":[
AirDefence.AAA_Bofors_40mm,
],"requirements":{
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
},
"objects": WW2_ALLIES_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["WW2LSTGroupGenerator"],
"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,
],"requirements":{
"WW2 Asset Pack": "https://www.digitalcombatsimulator.com/en/products/other/wwii_assets_pack/",
},
"objects": WW2_ALLIES_BUILDINGS,
"doctrine": WWII_DOCTRINE,
"boat": ["WW2LSTGroupGenerator"],
"boat_count": 2
}

33
game/factions/usa_1955.py Normal file
View File

@@ -0,0 +1,33 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
USA_1955 = {
"country": "USA",
"side": "blue",
"units": [
F_86F_Sabre,
P_51D,
KC_135,
KC130,
C_130,
E_3A,
Armor.MT_M4A4_Sherman_Firefly,
Armor.MT_M4_Sherman,
Armor.MBT_M60A3_Patton,
Armor.APC_M2A1,
Armor.M30_Cargo_Carrier,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
AirDefence.AAA_Bofors_40mm,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
]
}

36
game/factions/usa_1960.py Normal file
View File

@@ -0,0 +1,36 @@
from dcs.vehicles import *
from dcs.ships import *
from dcs.planes import *
from dcs.helicopters import *
USA_1960 = {
"country": "USA",
"side": "blue",
"units": [
F_86F_Sabre,
P_51D,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
Armor.MBT_M60A3_Patton,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.AAA_Vulcan_M163,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
],
"shorad":[
AirDefence.AAA_Vulcan_M163
]
}

41
game/factions/usa_1965.py Normal file
View File

@@ -0,0 +1,41 @@
from dcs.helicopters import *
from dcs.planes import *
from dcs.ships import *
from dcs.vehicles import *
USA_1965 = {
"country": "USA",
"side": "blue",
"units": [
F_5E_3,
F_4E,
KC_135,
KC130,
C_130,
E_3A,
B_52H,
UH_1H,
Armor.MBT_M60A3_Patton,
Armor.APC_M113,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Chaparral_M48,
AirDefence.SAM_Hawk_PCP,
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
],
"shorad":[
AirDefence.AAA_Vulcan_M163,
AirDefence.SAM_Chaparral_M48
], "boat":[
]
}

65
game/factions/usa_1990.py Normal file
View File

@@ -0,0 +1,65 @@
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,
F_16C_50,
A_10A,
AV8BNA,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
AH_64A,
Armor.MBT_M1A2_Abrams,
Armor.IFV_LAV_25,
Armor.APC_M1043_HMMWV_Armament,
Armor.ATGM_M1045_HMMWV_TOW,
Armor.ATGM_M1134_Stryker,
Unarmed.Transport_M818,
Infantry.Infantry_M4,
Infantry.Soldier_M249,
AirDefence.SAM_Hawk_PCP,
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-72 Abraham Lincoln",
"CVN-73 Georges 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
}

73
game/factions/usa_2005.py Normal file
View File

@@ -0,0 +1,73 @@
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,
A_10C,
A_10C_2,
AV8BNA,
MQ_9_Reaper,
KC_135,
KC130,
C_130,
E_3A,
UH_1H,
AH_64D,
Armor.MBT_M1A2_Abrams,
Armor.ATGM_M1134_Stryker,
Armor.APC_M1126_Stryker_ICV,
Armor.IFV_M2A2_Bradley,
Armor.IFV_LAV_25,
Armor.APC_M1043_HMMWV_Armament,
Armor.ATGM_M1045_HMMWV_TOW,
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": [
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"
], "has_jtac": True
}

View File

@@ -1,16 +1,11 @@
import typing
import random
import math
from datetime import datetime, timedelta
from dcs.task import *
from dcs.vehicles import *
from userdata.debriefing import Debriefing
from theater import *
from . import db
from .settings import Settings
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 .event import *
from .settings import Settings
COMMISION_UNIT_VARIETY = 4
COMMISION_LIMITS_SCALE = 1.5
@@ -18,42 +13,20 @@ COMMISION_LIMITS_FACTORS = {
PinpointStrike: 10,
CAS: 5,
CAP: 8,
AirDefence: 1,
AirDefence: 8,
}
COMMISION_AMOUNTS_SCALE = 1.5
COMMISION_AMOUNTS_FACTORS = {
PinpointStrike: 2,
PinpointStrike: 3,
CAS: 1,
CAP: 2,
AirDefence: 0.3,
AirDefence: 0.8,
}
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 25
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 30
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2
"""
Various events probabilities. First key is player probabilty, second is enemy probability.
For the enemy events, only 1 event of each type could be generated for a turn.
Events:
* CaptureEvent - capture base
* InterceptEvent - air intercept
* GroundInterceptEvent - frontline CAS
* GroundAttackEvent - destroy insurgents
* NavalInterceptEvent - naval intercept
* AntiAAStrikeEvent - anti-AA strike
* InfantryTransportEvent - helicopter infantry transport
"""
EVENT_PROBABILITIES = {
CaptureEvent: [100, 10],
InterceptEvent: [25, 10],
GroundInterceptEvent: [25, 10],
GroundAttackEvent: [0, 10],
NavalInterceptEvent: [25, 10],
AntiAAStrikeEvent: [25, 10],
InfantryTransportEvent: [25, 0],
}
PLAYER_BASEATTACK_THRESHOLD = 0.4
# amount of strength player bases recover for the turn
PLAYER_BASE_STRENGTH_RECOVERY = 0.2
@@ -65,9 +38,8 @@ ENEMY_BASE_STRENGTH_RECOVERY = 0.05
AWACS_BUDGET_COST = 4
# Initial budget value
PLAYER_BUDGET_INITIAL = 120
# Base post-turn bonus value
PLAYER_BUDGET_BASE = 10
PLAYER_BUDGET_INITIAL = 650
# Bonus multiplier logarithm base
PLAYER_BUDGET_IMPORTANCE_LOG = 2
@@ -78,99 +50,108 @@ class Game:
events = None # type: typing.List[Event]
pending_transfers = None # type: typing.Dict[]
ignored_cps = None # type: typing.Collection[ControlPoint]
turn = 0
game_stats: GameStats = None
def __init__(self, player_name: str, enemy_name: str, theater: ConflictTheater):
self.settings = Settings()
current_unit_id = 0
current_group_id = 0
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 = player_name
self.enemy = enemy_name
self.player_name = player_name
self.player_country = db.FACTIONS[player_name]["country"]
self.enemy_name = enemy_name
self.enemy_country = db.FACTIONS[enemy_name]["country"]
self.turn = 0
self.date = datetime(start_date.year, start_date.month, start_date.day)
self.game_stats = GameStats()
self.game_stats.update(self)
self.planners = {}
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):
return random.randint(1, 100) <= prob * mult
if self.settings.version == "dev":
# always generate all events for dev
return 100
else:
return random.randint(1, 100) <= prob * mult
def _generate_globalinterceptions(self):
global_count = len([x for x in self.theater.player_points() if x.is_global])
for from_cp in [x for x in self.theater.player_points() if x.is_global]:
probability_base = max(PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE / global_count, 1)
probability = probability_base * math.log(len(self.theater.player_points()) + 1, PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG)
if self._roll(probability, from_cp.base.strength):
to_cp = random.choice([x for x in self.theater.enemy_points() if x not in self.theater.conflicts()])
self.events.append(InterceptEvent(attacker_name=self.player,
defender_name=self.enemy,
from_cp=from_cp,
to_cp=to_cp,
game=self))
break
def _generate_player_event(self, event_class, player_cp, enemy_cp):
self.events.append(event_class(self, player_cp, enemy_cp, enemy_cp.position, self.player_name, self.enemy_name))
def _generate_events(self):
enemy_cap_generated = False
enemy_generated_types = []
for player_cp, enemy_cp in self.theater.conflicts(True):
if player_cp.is_global or enemy_cp.is_global:
continue
for event_class, (player_probability, enemy_probability) in EVENT_PROBABILITIES.items():
if self._roll(player_probability, player_cp.base.strength):
if event_class == NavalInterceptEvent and enemy_cp.radials == LAND:
pass
else:
self.events.append(event_class(self.player, self.enemy, player_cp, enemy_cp, self))
elif self._roll(enemy_probability, enemy_cp.base.strength):
if event_class in enemy_generated_types:
continue
if player_cp in self.ignored_cps:
continue
if enemy_cp.base.total_planes == 0:
continue
if event_class == NavalInterceptEvent:
if player_cp.radials == LAND:
continue
elif event_class == CaptureEvent:
if enemy_cap_generated:
continue
if enemy_cp.base.total_armor == 0:
continue
enemy_cap_generated = True
elif event_class == AntiAAStrikeEvent:
if player_cp.base.total_aa == 0:
continue
enemy_generated_types.append(event_class)
self.events.append(event_class(self.enemy, self.player, enemy_cp, player_cp, self))
self._generate_player_event(FrontlineAttackEvent, player_cp, enemy_cp)
def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> typing.Collection[UnitType]:
importance_factor = (cp.importance - IMPORTANCE_LOW) / (IMPORTANCE_HIGH - IMPORTANCE_LOW)
if for_task == AirDefence and not self.settings.sams:
return [x for x in db.find_unittype(AirDefence, self.enemy) if x not in db.SAM_BAN]
return [x for x in db.find_unittype(AirDefence, self.enemy_name) if x not in db.SAM_BAN]
else:
return db.choose_units(for_task, importance_factor, COMMISION_UNIT_VARIETY, self.enemy)
return db.choose_units(for_task, importance_factor, COMMISION_UNIT_VARIETY, self.enemy_name)
def _commision_units(self, cp: ControlPoint):
for for_task in [PinpointStrike, CAS, CAP, AirDefence]:
limit = COMMISION_LIMITS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_LIMITS_SCALE) * self.settings.multiplier
for for_task in [CAS, CAP, AirDefence]:
limit = COMMISION_LIMITS_FACTORS[for_task] * math.pow(cp.importance,
COMMISION_LIMITS_SCALE) * self.settings.multiplier
missing_units = limit - cp.base.total_units(for_task)
if missing_units > 0:
awarded_points = COMMISION_AMOUNTS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_AMOUNTS_SCALE) * self.settings.multiplier
awarded_points = COMMISION_AMOUNTS_FACTORS[for_task] * math.pow(cp.importance,
COMMISION_AMOUNTS_SCALE) * self.settings.multiplier
points_to_spend = cp.base.append_commision_points(for_task, awarded_points)
if points_to_spend > 0:
unittypes = self.commision_unit_types(cp, for_task)
d = {random.choice(unittypes): points_to_spend}
print("Commision {}: {}".format(cp, d))
cp.base.commision_units(d)
if len(unittypes) > 0:
d = {random.choice(unittypes): points_to_spend}
logging.info("Commision {}: {}".format(cp, d))
cp.base.commision_units(d)
@property
def budget_reward_amount(self):
reward = 0
if len(self.theater.player_points()) > 0:
total_importance = sum([x.importance * x.base.strength for x in self.theater.player_points()])
return math.ceil(math.log(total_importance + 1, PLAYER_BUDGET_IMPORTANCE_LOG) * PLAYER_BUDGET_BASE * self.settings.multiplier)
reward = PLAYER_BUDGET_BASE * len(self.theater.player_points())
for cp in self.theater.player_points():
for g in cp.ground_objects:
if g.category in REWARDS.keys():
reward = reward + REWARDS[g.category]
return reward
else:
return 0
return reward
def _budget_player(self):
self.budget += self.budget_reward_amount
@@ -179,8 +160,8 @@ class Game:
self.budget -= AWACS_BUDGET_COST
def units_delivery_event(self, to_cp: ControlPoint) -> UnitsDeliveryEvent:
event = UnitsDeliveryEvent(attacker_name=self.player,
defender_name=self.player,
event = UnitsDeliveryEvent(attacker_name=self.player_name,
defender_name=self.player_name,
from_cp=to_cp,
to_cp=to_cp,
game=self)
@@ -192,12 +173,12 @@ 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()
event.generate_quick()
def finish_event(self, event: Event, debriefing: Debriefing):
logging.info("Finishing event {}".format(event))
event.commit(debriefing)
if event.is_successfull(debriefing):
self.budget += event.bonus()
@@ -205,23 +186,38 @@ class Game:
if event in self.events:
self.events.remove(event)
else:
print("finish_event: event not in the events!")
logging.info("finish_event: event not in the events!")
def is_player_attack(self, event: Event):
return event.attacker_name == self.player
def is_player_attack(self, event):
if isinstance(event, Event):
return event and event.attacker_name and event.attacker_name == self.player_name
else:
return event and event.name and 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
def pass_turn(self, no_action=False, ignored_cps: typing.Collection[ControlPoint]=None):
for event in self.events:
event.skip()
if self.settings.version == "dev":
# don't damage player CPs in by skipping in dev mode
if isinstance(event, UnitsDeliveryEvent):
event.skip()
else:
event.skip()
if not no_action:
self._budget_player()
for cp in self.theater.enemy_points():
self._commision_units(cp)
self._enemy_reinforcement()
self._budget_player()
if not no_action and self.turn > 1:
for cp in self.theater.player_points():
cp.base.affect_strength(+PLAYER_BASE_STRENGTH_RECOVERY)
else:
for cp in self.theater.player_points():
if not cp.is_carrier and not cp.is_lha:
cp.base.affect_strength(-PLAYER_BASE_STRENGTH_RECOVERY)
self.ignored_cps = []
if ignored_cps:
@@ -229,5 +225,196 @@ class Game:
self.events = [] # type: typing.List[Event]
self._generate_events()
self._generate_globalinterceptions()
# Update statistics
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:
if cp.has_runway():
planner = FlightPlanner(cp, self)
planner.plan_flights()
self.planners[cp.id] = planner
if cp.has_frontline:
gplanner = GroundPlanner(cp, self)
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
production = 0.0
for enemy_point in self.theater.enemy_points():
for g in enemy_point.ground_objects:
if g.category in REWARDS.keys():
production = production + REWARDS[g.category]
production = production * 0.75
budget_for_armored_units = production / 2
budget_for_aircraft = production / 2
potential_cp_armor = []
for cp in self.theater.enemy_points():
for cpe in cp.connected_points:
if cpe.captured and cp.base.total_armor < MAX_ARMOR:
potential_cp_armor.append(cp)
if len(potential_cp_armor) == 0:
potential_cp_armor = self.theater.enemy_points()
i = 0
potential_units = [u for u in db.FACTIONS[self.enemy_name]["units"] if u in db.UNIT_BY_TASK[PinpointStrike]]
print("Enemy Recruiting")
print(potential_cp_armor)
print(budget_for_armored_units)
print(potential_units)
if len(potential_units) > 0 and len(potential_cp_armor) > 0:
while budget_for_armored_units > 0:
i = i + 1
if i > 50 or budget_for_armored_units <= 0:
break
target_cp = random.choice(potential_cp_armor)
if target_cp.base.total_armor >= MAX_ARMOR:
continue
unit = random.choice(potential_units)
price = db.PRICES[unit] * 2
budget_for_armored_units -= price * 2
target_cp.base.armor[unit] = target_cp.base.armor.get(unit, 0) + 2
info = Information("Enemy Reinforcement", unit.id + " x 2 at " + target_cp.name, self.turn)
print(str(info))
self.informations.append(info)
if budget_for_armored_units > 0:
budget_for_aircraft += budget_for_armored_units
potential_units = [u for u in db.FACTIONS[self.enemy_name]["units"] if
u in db.UNIT_BY_TASK[CAS] or u in db.UNIT_BY_TASK[CAP]]
if len(potential_units) > 0 and len(potential_cp_armor) > 0:
while budget_for_aircraft > 0:
i = i + 1
if i > 50 or budget_for_aircraft <= 0:
break
target_cp = random.choice(potential_cp_armor)
if target_cp.base.total_planes >= MAX_AIRCRAFT:
continue
unit = random.choice(potential_units)
price = db.PRICES[unit] * 2
budget_for_aircraft -= price * 2
target_cp.base.aircraft[unit] = target_cp.base.aircraft.get(unit, 0) + 2
info = Information("Enemy Reinforcement", unit.id + " x 2 at " + target_cp.name, self.turn)
print(str(info))
self.informations.append(info)
@property
def current_turn_daytime(self):
return ["dawn", "day", "dusk", "night"][self.turn % 4]
@property
def current_day(self):
return self.date + timedelta(days=self.turn // 4)
def next_unit_id(self):
"""
Next unit id for pre-generated units
"""
self.current_unit_id += 1
return self.current_unit_id
def next_group_id(self):
"""
Next unit id for pre-generated units
"""
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"

11
game/infos/information.py Normal file
View File

@@ -0,0 +1,11 @@
class Information():
def __init__(self, title="", text="", turn=0):
self.title = title
self.text = text
self.turn = turn
def __str__(self):
s = "[" + str(self.turn) + "] " + self.title + "\n" + self.text
return s

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 = []

56
game/models/game_stats.py Normal file
View File

@@ -0,0 +1,56 @@
class FactionTurnMetadata:
"""
Store metadata about a faction
"""
aircraft_count: int = 0
vehicles_count: int = 0
sam_count: int = 0
def __init__(self):
self.aircraft_count = 0
self.vehicles_count = 0
self.sam_count = 0
class GameTurnMetadata:
"""
Store metadata about a game turn
"""
allied_units:FactionTurnMetadata
enemy_units:FactionTurnMetadata
def __init__(self):
self.allied_units = FactionTurnMetadata()
self.enemy_units = FactionTurnMetadata()
class GameStats:
"""
Store statistics for the current game
"""
data_per_turn: [GameTurnMetadata] = []
def __init__(self):
self.data_per_turn = []
def update(self, game):
"""
Save data for current turn
:param game: Game we want to save the data about
"""
turn_data = GameTurnMetadata()
for cp in game.theater.controlpoints:
if cp.captured:
turn_data.allied_units.aircraft_count += sum(cp.base.aircraft.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.vehicles_count += sum(cp.base.armor.values())
self.data_per_turn.append(turn_data)

View File

@@ -1,53 +0,0 @@
from dcs.terrain import Terrain
from game import db
from gen.armor import *
from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict
from .operation import Operation
class AntiAAStrikeOperation(Operation):
strikegroup = None # type: db.PlaneDict
interceptors = None # type: db.PlaneDict
target = None # type: db.ArmorDict
def setup(self,
target: db.ArmorDict,
strikegroup: db.PlaneDict,
interceptors: db.PlaneDict):
self.strikegroup = strikegroup
self.interceptors = interceptors
self.target = target
def prepare(self, terrain: Terrain, is_quick: bool):
super(AntiAAStrikeOperation, self).prepare(terrain, is_quick)
if self.defender_name == self.game.player:
self.attackers_starting_position = None
self.defenders_starting_position = None
conflict = Conflict.ground_base_attack(
attacker=self.mission.country(self.attacker_name),
defender=self.mission.country(self.defender_name),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.mission,
conflict=conflict)
def generate(self):
self.airgen.generate_cas_strikegroup(self.strikegroup, clients=self.attacker_clients, at=self.attackers_starting_position)
if self.interceptors:
self.airgen.generate_defense(self.interceptors, clients=self.defender_clients, at=self.defenders_starting_position)
self.armorgen.generate({}, self.target)
super(AntiAAStrikeOperation, self).generate()

View File

@@ -1,67 +0,0 @@
from game import db
from gen.conflictgen import Conflict
from gen.armor import *
from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.visualgen import *
from .operation import Operation
class CaptureOperation(Operation):
cas = None # type: db.PlaneDict
escort = None # type: db.PlaneDict
intercept = None # type: db.PlaneDict
attack = None # type: db.ArmorDict
defense = None # type: db.ArmorDict
aa = None # type: db.AirDefenseDict
trigger_radius = TRIGGER_RADIUS_SMALL
def setup(self,
cas: db.PlaneDict,
escort: db.PlaneDict,
attack: db.ArmorDict,
intercept: db.PlaneDict,
defense: db.ArmorDict,
aa: db.AirDefenseDict):
self.cas = cas
self.escort = escort
self.intercept = intercept
self.attack = attack
self.defense = defense
self.aa = aa
def prepare(self, terrain: dcs.terrain.Terrain, is_quick: bool):
super(CaptureOperation, self).prepare(terrain, is_quick)
self.defenders_starting_position = None
if self.game.player == self.defender_name:
self.attackers_starting_position = None
conflict = Conflict.capture_conflict(
attacker=self.mission.country(self.attacker_name),
defender=self.mission.country(self.defender_name),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.mission,
conflict=conflict)
def generate(self):
self.armorgen.generate(self.attack, self.defense)
self.aagen.generate(self.aa)
self.airgen.generate_defense(self.intercept, clients=self.defender_clients, at=self.defenders_starting_position)
self.airgen.generate_cas_strikegroup(self.cas, clients=self.attacker_clients, at=self.attackers_starting_position)
self.airgen.generate_strikegroup_escort(self.escort, clients=self.attacker_clients, at=self.attackers_starting_position)
self.visualgen.generate_target_smokes(self.to_cp)
super(CaptureOperation, self).generate()

View File

@@ -0,0 +1,39 @@
from game.db import assigned_units_split
from .operation import *
MAX_DISTANCE_BETWEEN_GROUPS = 12000
class FrontlineAttackOperation(Operation):
interceptors = None # type: db.AssignedUnitsDict
escort = None # type: db.AssignedUnitsDict
strikegroup = None # type: db.AssignedUnitsDict
attackers = None # type: db.ArmorDict
defenders = None # type: db.ArmorDict
def prepare(self, terrain: Terrain, is_quick: bool):
super(FrontlineAttackOperation, self).prepare(terrain, is_quick)
if self.defender_name == self.game.player_name:
self.attackers_starting_position = None
self.defenders_starting_position = None
conflict = Conflict.frontline_cas_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.current_mission,
conflict=conflict)
def generate(self):
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."
super(FrontlineAttackOperation, self).generate()

View File

@@ -1,44 +0,0 @@
from dcs.terrain import Terrain
from game import db
from gen.armor import *
from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict
from .operation import Operation
class GroundAttackOperation(Operation):
strikegroup = None # type: db.PlaneDict
target = None # type: db.ArmorDict
def setup(self,
target: db.ArmorDict,
strikegroup: db.PlaneDict):
self.strikegroup = strikegroup
self.target = target
def prepare(self, terrain: Terrain, is_quick: bool):
super(GroundAttackOperation, self).prepare(terrain, is_quick)
conflict = Conflict.ground_attack_conflict(
attacker=self.mission.country(self.attacker_name),
defender=self.mission.country(self.defender_name),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.mission,
conflict=conflict)
def generate(self):
self.airgen.generate_defense(self.strikegroup, self.defender_clients, self.defenders_starting_position)
self.armorgen.generate(self.target, {})
super(GroundAttackOperation, self).generate()

View File

@@ -1,53 +0,0 @@
from dcs.terrain import Terrain
from game import db
from gen.armor import *
from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict
from .operation import Operation
class GroundInterceptOperation(Operation):
strikegroup = None # type: db.PlaneDict
interceptors = None # type: db.PlaneDict
target = None # type: db.ArmorDict
def setup(self,
target: db.ArmorDict,
strikegroup: db.PlaneDict,
interceptors: db.PlaneDict):
self.strikegroup = strikegroup
self.interceptors = interceptors
self.target = target
def prepare(self, terrain: Terrain, is_quick: bool):
super(GroundInterceptOperation, self).prepare(terrain, is_quick)
if self.defender_name == self.game.player:
self.attackers_starting_position = None
self.defenders_starting_position = None
conflict = Conflict.ground_intercept_conflict(
attacker=self.mission.country(self.attacker_name),
defender=self.mission.country(self.defender_name),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.mission,
conflict=conflict)
def generate(self):
self.airgen.generate_cas_strikegroup(self.strikegroup, clients=self.attacker_clients, at=self.attackers_starting_position)
if self.interceptors:
self.airgen.generate_defense(self.interceptors, clients=self.defender_clients, at=self.defenders_starting_position)
self.armorgen.generate({}, self.target)
super(GroundInterceptOperation, self).generate()

View File

@@ -1,56 +0,0 @@
from dcs.terrain import Terrain
from game import db
from gen.armor import *
from gen.aircraft import *
from gen.aaa import *
from gen.shipgen import *
from gen.triggergen import *
from gen.awacsgen import *
from gen.visualgen import *
from gen.conflictgen import Conflict
from .operation import Operation
class InfantryTransportOperation(Operation):
transport = None # type: db.HeliDict
aa = None # type: db.AirDefenseDict
def setup(self, transport: db.HeliDict, aa: db.AirDefenseDict):
self.transport = transport
self.aa = aa
def prepare(self, terrain: Terrain, is_quick: bool):
super(InfantryTransportOperation, self).prepare(terrain, is_quick)
conflict = Conflict.transport_conflict(
attacker=self.mission.country(self.attacker_name),
defender=self.mission.country(self.defender_name),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.mission,
conflict=conflict)
def generate(self):
self.airgen.generate_passenger_transport(
helis=self.transport,
clients=self.attacker_clients,
at=self.attackers_starting_position
)
self.armorgen.generate_passengers(count=6)
self.aagen.generate_at_defenders_location(self.aa)
self.visualgen.generate_transportation_marker(self.conflict.ground_attackers_location)
self.visualgen.generate_transportation_destination(self.conflict.position)
# TODO: horrible, horrible hack
# this will disable vehicle activation triggers,
# which aren't needed on this type of missions
self.is_quick = True
super(InfantryTransportOperation, self).generate()
self.is_quick = False

View File

@@ -1,52 +0,0 @@
from dcs.terrain import Terrain
from gen import *
from .operation import Operation
class InterceptOperation(Operation):
escort = None # type: db.PlaneDict
transport = None # type: db.PlaneDict
interceptors = None # type: db.PlaneDict
airdefense = None # type: db.AirDefenseDict
trigger_radius = TRIGGER_RADIUS_LARGE
def setup(self,
escort: db.PlaneDict,
transport: db.PlaneDict,
airdefense: db.AirDefenseDict,
interceptors: db.PlaneDict):
self.escort = escort
self.transport = transport
self.airdefense = airdefense
self.interceptors = interceptors
def prepare(self, terrain: Terrain, is_quick: bool):
super(InterceptOperation, self).prepare(terrain, is_quick)
self.defenders_starting_position = None
if self.defender_name == self.game.player:
self.attackers_starting_position = None
conflict = Conflict.intercept_conflict(
attacker=self.mission.country(self.attacker_name),
defender=self.mission.country(self.defender_name),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.mission,
conflict=conflict)
def generate(self):
self.airgen.generate_transport(self.transport, self.to_cp.at)
self.airgen.generate_transport_escort(self.escort, clients=self.defender_clients)
if self.from_cp.is_global:
super(InterceptOperation, self).generate()
self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.attackers_starting_position)
else:
self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.attackers_starting_position)
super(InterceptOperation, self).generate()

View File

@@ -1,53 +0,0 @@
from dcs.terrain import Terrain
from gen import *
from .operation import Operation
class NavalInterceptionOperation(Operation):
strikegroup = None # type: db.PlaneDict
interceptors = None # type: db.PlaneDict
targets = None # type: db.ShipDict
trigger_radius = TRIGGER_RADIUS_LARGE
def setup(self,
strikegroup: db.PlaneDict,
interceptors: db.PlaneDict,
targets: db.ShipDict):
self.strikegroup = strikegroup
self.interceptors = interceptors
self.targets = targets
def prepare(self, terrain: Terrain, is_quick: bool):
super(NavalInterceptionOperation, self).prepare(terrain, is_quick)
if self.defender_name == self.game.player:
self.attackers_starting_position = None
conflict = Conflict.naval_intercept_conflict(
attacker=self.mission.country(self.attacker_name),
defender=self.mission.country(self.defender_name),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(self.mission, conflict)
def generate(self):
super(NavalInterceptionOperation, self).generate()
target_groups = self.shipgen.generate_cargo(units=self.targets)
self.airgen.generate_ship_strikegroup(
attackers=self.strikegroup,
clients=self.attacker_clients,
target_groups=target_groups,
at=self.attackers_starting_position
)
if self.interceptors:
self.airgen.generate_defense(
defenders=self.interceptors,
clients=self.defender_clients,
at=self.defenders_starting_position
)

View File

@@ -1,103 +1,381 @@
from dcs.terrain import Terrain
from typing import Set
from userdata.debriefing import *
from theater import *
from gen import *
from gen.airfields import AIRFIELD_DATA
from gen.beacons import load_beacons_for_terrain
from gen.radios import RadioRegistry
from gen.tacan import TacanRegistry
from dcs.countries import country_dict
from dcs.lua.parse import loads
from dcs.terrain.terrain import Terrain
from userdata.debriefing import *
class Operation:
attackers_starting_position = None # type: db.StartingPosition
defenders_starting_position = None # type: db.StartingPosition
mission = None # type: dcs.Mission
current_mission = None # type: dcs.Mission
regular_mission = None # type: dcs.Mission
quick_mission = None # type: dcs.Mission
conflict = None # type: Conflict
armorgen = None # type: ArmorConflictGenerator
airgen = None # type: AircraftConflictGenerator
aagen = None # type: AAConflictGenerator
extra_aagen = None # type: ExtraAAConflictGenerator
shipgen = None # type: ShipGenerator
triggersgen = None # type: TriggersGenerator
awacsgen = None # type: AWACSConflictGenerator
airsupportgen = None # type: AirSupportConflictGenerator
visualgen = None # type: VisualGenerator
envgen = None # type: EnvironmentGenerator
groundobjectgen = None # type: GroundObjectsGenerator
briefinggen = None # type: BriefingGenerator
forcedoptionsgen = None # type: ForcedOptionsGenerator
radio_registry: Optional[RadioRegistry] = None
tacan_registry: Optional[TacanRegistry] = None
environment_settings = None
trigger_radius = TRIGGER_RADIUS_MEDIUM
is_quick = None
is_awacs_enabled = False
ca_slots = 0
def __init__(self,
game,
attacker_name: str,
defender_name: str,
attacker_clients: db.PlaneDict,
defender_clients: db.PlaneDict,
from_cp: ControlPoint,
departure_cp: ControlPoint,
to_cp: ControlPoint = None):
self.game = game
self.attacker_name = attacker_name
self.attacker_country = db.FACTIONS[attacker_name]["country"]
self.defender_name = defender_name
self.attacker_clients = attacker_clients
self.defender_clients = defender_clients
self.defender_country = db.FACTIONS[defender_name]["country"]
print(self.defender_country, self.attacker_country)
self.from_cp = from_cp
self.departure_cp = departure_cp
self.to_cp = to_cp
self.is_quick = False
def initialize(self, mission: Mission, conflict: Conflict):
self.mission = mission
self.conflict = conflict
self.armorgen = ArmorConflictGenerator(mission, conflict)
self.airgen = AircraftConflictGenerator(mission, conflict, self.game.settings)
self.aagen = AAConflictGenerator(mission, conflict)
self.shipgen = ShipGenerator(mission, conflict)
self.awacsgen = AWACSConflictGenerator(mission, conflict, self.game)
self.triggersgen = TriggersGenerator(mission, conflict, self.game)
self.visualgen = VisualGenerator(mission, conflict, self.game)
self.envgen = EnviromentGenerator(mission, conflict, self.game)
player_name = self.from_cp.captured and self.attacker_name or self.defender_name
enemy_name = self.from_cp.captured and self.defender_name or self.attacker_name
self.extra_aagen = ExtraAAConflictGenerator(mission, conflict, self.game, player_name, enemy_name)
def prepare(self, terrain: Terrain, is_quick: bool):
self.mission = dcs.Mission(terrain)
self.is_quick = is_quick
if is_quick:
self.attackers_starting_position = None
self.defenders_starting_position = None
else:
self.attackers_starting_position = self.from_cp.at
self.defenders_starting_position = self.to_cp.at
def generate(self):
self.visualgen.generate()
if self.is_awacs_enabled:
self.awacsgen.generate()
self.extra_aagen.generate()
self.triggersgen.generate(self.is_quick, self.trigger_radius)
if self.environment_settings is None:
self.environment_settings = self.envgen.generate()
else:
self.envgen.load(self.environment_settings)
for global_cp in self.game.theater.controlpoints:
if not global_cp.is_global:
continue
ship = self.shipgen.generate_carrier(type=db.find_unittype(Carriage, self.game.player)[0],
country=self.game.player,
at=global_cp.at)
if global_cp == self.from_cp and not self.is_quick:
self.attackers_starting_position = ship
def units_of(self, country_name: str) -> typing.Collection[UnitType]:
return []
def is_successfull(self, debriefing: Debriefing) -> bool:
return True
@property
def is_player_attack(self) -> bool:
return self.from_cp.captured
def initialize(self, mission: Mission, conflict: Conflict):
self.current_mission = mission
self.conflict = conflict
self.briefinggen = BriefingGenerator(self.current_mission,
self.conflict, self.game)
def prepare(self, terrain: Terrain, is_quick: bool):
with open("resources/default_options.lua", "r") as f:
options_dict = loads(f.read())["options"]
self.current_mission = dcs.Mission(terrain)
print(self.game.player_country)
print(country_dict[db.country_id_from_name(self.game.player_country)])
print(country_dict[db.country_id_from_name(self.game.player_country)]())
# Setup coalition :
self.current_mission.coalition["blue"] = Coalition("blue")
self.current_mission.coalition["red"] = Coalition("red")
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()])
if is_quick:
self.quick_mission = self.current_mission
else:
self.regular_mission = self.current_mission
self.current_mission.options.load_from_dict(options_dict)
self.is_quick = is_quick
if is_quick:
self.attackers_starting_position = None
self.defenders_starting_position = None
else:
self.attackers_starting_position = self.departure_cp.at
self.defenders_starting_position = self.to_cp.at
def generate(self):
radio_registry = RadioRegistry()
tacan_registry = TacanRegistry()
# Dedup beacon/radio frequencies, since some maps have some frequencies
# used multiple times.
beacons = load_beacons_for_terrain(self.game.theater.terrain.name)
unique_map_frequencies: Set[RadioFrequency] = set()
for beacon in beacons:
unique_map_frequencies.add(beacon.frequency)
if beacon.is_tacan:
if beacon.channel is None:
logging.error(
f"TACAN beacon has no channel: {beacon.callsign}")
else:
tacan_registry.reserve(beacon.tacan_channel)
for airfield, data in AIRFIELD_DATA.items():
if data.theater == self.game.theater.terrain.name:
unique_map_frequencies.add(data.atc.hf)
unique_map_frequencies.add(data.atc.vhf_fm)
unique_map_frequencies.add(data.atc.vhf_am)
unique_map_frequencies.add(data.atc.uhf)
# No need to reserve ILS or TACAN because those are in the
# beacon list.
for frequency in unique_map_frequencies:
radio_registry.reserve(frequency)
# Generate meteo
envgen = EnviromentGenerator(self.current_mission, self.conflict,
self.game)
if self.environment_settings is None:
self.environment_settings = envgen.generate()
else:
envgen.load(self.environment_settings)
# Generate ground object first
groundobjectgen = GroundObjectsGenerator(
self.current_mission,
self.conflict,
self.game,
radio_registry,
tacan_registry
)
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)
airsupportgen = AirSupportConflictGenerator(
self.current_mission, self.conflict, self.game, radio_registry,
tacan_registry)
airsupportgen.generate(self.is_awacs_enabled)
# Generate Activity on the map
airgen = AircraftConflictGenerator(
self.current_mission, self.conflict, self.game.settings, self.game,
radio_registry)
for cp in self.game.theater.controlpoints:
side = cp.captured
if side:
country = self.current_mission.country(self.game.player_country)
else:
country = self.current_mission.country(self.game.enemy_country)
if cp.id in self.game.planners.keys():
airgen.generate_flights(
cp,
country,
self.game.planners[cp.id],
groundobjectgen.runways
)
# Generate ground units on frontline everywhere
jtacs: List[JtacInfo] = []
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),
self.current_mission.country(self.defender_country),
player_cp, enemy_cp, self.game.theater)
# Generate frontline ops
player_gp = self.game.ground_planners[player_cp.id].units_per_cp[enemy_cp.id]
enemy_gp = self.game.ground_planners[enemy_cp.id].units_per_cp[player_cp.id]
groundConflictGen = GroundConflictGenerator(self.current_mission, conflict, self.game, player_gp, enemy_gp, player_cp.stances[enemy_cp.id])
groundConflictGen.generate()
jtacs.extend(groundConflictGen.jtacs)
# Setup combined arms parameters
self.current_mission.groundControl.pilot_can_control_vehicles = self.ca_slots > 0
if self.game.player_country in [country.name for country in self.current_mission.coalition["blue"].countries.values()]:
self.current_mission.groundControl.blue_tactical_commander = self.ca_slots
else:
self.current_mission.groundControl.red_tactical_commander = self.ca_slots
# Triggers
triggersgen = TriggersGenerator(self.current_mission, self.conflict,
self.game)
triggersgen.generate()
# Options
forcedoptionsgen = ForcedOptionsGenerator(self.current_mission,
self.conflict, self.game)
forcedoptionsgen.generate()
# Generate Visuals Smoke Effects
visualgen = VisualGenerator(self.current_mission, self.conflict,
self.game)
if self.game.settings.perf_smoke_gen:
visualgen.generate()
# Inject Plugins Lua Scripts
listOfPluginsScripts = []
plugin_file_path = Path("./resources/scripts/plugins/__plugins.lst")
if plugin_file_path.exists():
for line in plugin_file_path.read_text().splitlines():
name = line.strip()
if not name.startswith( '#' ):
trigger = TriggerStart(comment="Load " + name)
listOfPluginsScripts.append(name)
fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/plugins/" + name)
trigger.add_action(DoScriptFile(fileref))
self.current_mission.triggerrules.triggers.append(trigger)
else:
logging.info(
f"Not loading plugins, {plugin_file_path} does not exist")
# Inject Mist Script if not done already in the plugins
if not "mist.lua" in listOfPluginsScripts and not "mist_4_3_74.lua" in listOfPluginsScripts: # don't load the script twice
trigger = TriggerStart(comment="Load Mist Lua framework")
fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/mist_4_3_74.lua")
trigger.add_action(DoScriptFile(fileref))
self.current_mission.triggerrules.triggers.append(trigger)
# Inject JSON library if not done already in the plugins
if not "json.lua" in listOfPluginsScripts : # don't load the script twice
trigger = TriggerStart(comment="Load JSON Lua library")
fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/json.lua")
trigger.add_action(DoScriptFile(fileref))
self.current_mission.triggerrules.triggers.append(trigger)
# Inject Ciribob's JTACAutoLase if not done already in the plugins
if not "JTACAutoLase.lua" in listOfPluginsScripts : # don't load the script twice
trigger = TriggerStart(comment="Load JTACAutoLase.lua script")
fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/JTACAutoLase.lua")
trigger.add_action(DoScriptFile(fileref))
self.current_mission.triggerrules.triggers.append(trigger)
# set a LUA table with data from Liberation that we want to set
# at the moment it contains Liberation's install path, and an overridable definition for the JTACAutoLase function
# later, we'll add data about the units and points having been generated, in order to facilitate the configuration of the plugin lua scripts
state_location = "[[" + os.path.abspath("state.json") + "]]"
lua = """
-- setting configuration table
env.info("DCSLiberation|: setting configuration table")
-- all data in this table is overridable.
dcsLiberation = {}
-- the base location for state.json; if non-existent, it'll be replaced with LIBERATION_EXPORT_DIR, TEMP, or DCS working directory
dcsLiberation.installPath=""" + state_location + """
-- you can override dcsLiberation.JTACAutoLase to make it use your own function ; it will be called with these parameters : ({jtac.unit_name}, {jtac.code}, {smoke}, 'vehicle') for all JTACs
if ctld then
dcsLiberation.JTACAutoLase=ctld.JTACAutoLase
elseif JTACAutoLase then
dcsLiberation.JTACAutoLase=JTACAutoLase
end
-- later, we'll add more data to the table
--dcsLiberation.POIs = {}
--dcsLiberation.BASEs = {}
--dcsLiberation.JTACs = {}
"""
trigger = TriggerStart(comment="Set DCS Liberation data")
trigger.add_action(DoScript(String(lua)))
self.current_mission.triggerrules.triggers.append(trigger)
# Inject DCS-Liberation script if not done already in the plugins
if not "dcs_liberation.lua" in listOfPluginsScripts : # don't load the script twice
trigger = TriggerStart(comment="Load DCS Liberation script")
fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/dcs_liberation.lua")
trigger.add_action(DoScriptFile(fileref))
self.current_mission.triggerrules.triggers.append(trigger)
# add a configuration for JTACAutoLase and start lasing for all JTACs
smoke = "true"
if hasattr(self.game.settings, "jtac_smoke_on"):
if not self.game.settings.jtac_smoke_on:
smoke = "false"
lua = """
-- setting and starting JTACs
env.info("DCSLiberation|: setting and starting JTACs")
"""
for jtac in jtacs:
lua += f"if dcsLiberation.JTACAutoLase then dcsLiberation.JTACAutoLase('{jtac.unit_name}', {jtac.code}, {smoke}, 'vehicle') end\n"
trigger = TriggerStart(comment="Start JTACs")
trigger.add_action(DoScript(String(lua)))
self.current_mission.triggerrules.triggers.append(trigger)
self.assign_channels_to_flights(airgen.flights,
airsupportgen.air_support)
kneeboard_generator = KneeboardGenerator(self.current_mission)
for dynamic_runway in groundobjectgen.runways.values():
self.briefinggen.add_dynamic_runway(dynamic_runway)
for tanker in airsupportgen.air_support.tankers:
self.briefinggen.add_tanker(tanker)
kneeboard_generator.add_tanker(tanker)
if self.is_awacs_enabled:
for awacs in airsupportgen.air_support.awacs:
self.briefinggen.add_awacs(awacs)
kneeboard_generator.add_awacs(awacs)
for jtac in jtacs:
self.briefinggen.add_jtac(jtac)
kneeboard_generator.add_jtac(jtac)
for flight in airgen.flights:
self.briefinggen.add_flight(flight)
kneeboard_generator.add_flight(flight)
self.briefinggen.generate()
kneeboard_generator.generate()
def assign_channels_to_flights(self, flights: List[FlightData],
air_support: AirSupport) -> None:
"""Assigns preset radio channels for client flights."""
for flight in flights:
if not flight.client_units:
continue
self.assign_channels_to_flight(flight, air_support)
def assign_channels_to_flight(self, flight: FlightData,
air_support: AirSupport) -> None:
"""Assigns preset radio channels for a client flight."""
airframe = flight.aircraft_type
try:
aircraft_data = AIRCRAFT_DATA[airframe.id]
except KeyError:
logging.warning(f"No aircraft data for {airframe.id}")
return
aircraft_data.channel_allocator.assign_channels_for_flight(
flight, air_support
)

View File

@@ -1,8 +1,43 @@
class Settings:
player_skill = "Good"
enemy_skill = "Average"
only_player_takeoff = False
night_disabled = False
multiplier = 1
sams = True
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

@@ -1,12 +1,15 @@
from .aaa import *
from .aircraft import *
from .armor import *
from .awacsgen import *
from .airsupportgen import *
from .conflictgen import *
from .shipgen import *
from .visualgen import *
from .triggergen import *
from .environmentgen import *
from .groundobjectsgen import *
from .briefinggen import *
from .forcedoptionsgen import *
from .kneeboard import *
from . import naming

View File

@@ -1,55 +1,26 @@
from game import *
from theater.conflicttheater import ConflictTheater
from .conflictgen import *
from .naming import *
from dcs.mission import *
from dcs.mission import *
from .conflictgen import *
from .naming import *
DISTANCE_FACTOR = 0.5, 1
EXTRA_AA_MIN_DISTANCE = 35000
EXTRA_AA_MIN_DISTANCE = 50000
EXTRA_AA_MAX_DISTANCE = 150000
EXTRA_AA_POSITION_FROM_CP = 550
class AAConflictGenerator:
def __init__(self, mission: Mission, conflict: Conflict):
self.m = mission
self.conflict = conflict
def generate_at_defenders_location(self, units: db.AirDefenseDict):
for unit_type, count in units.items():
for _ in range(count):
self.m.vehicle_group(
country=self.conflict.defenders_side,
name=namegen.next_ground_group_name(),
_type=unit_type,
position=self.conflict.ground_defenders_location.random_point_within(100, 100),
group_size=1)
def generate(self, units: db.AirDefenseDict):
for type, count in units.items():
for _, radial in zip(range(count), self.conflict.radials):
distance = randint(self.conflict.size * DISTANCE_FACTOR[0], self.conflict.size * DISTANCE_FACTOR[1])
p = self.conflict.position.point_from_heading(radial, distance)
self.m.vehicle_group(
country=self.conflict.defenders_side,
name=namegen.next_ground_group_name(),
_type=type,
position=p,
group_size=1)
class ExtraAAConflictGenerator:
def __init__(self, mission: Mission, conflict: Conflict, game, player_name: Country, enemy_name: Country):
def __init__(self, mission: Mission, conflict: Conflict, game, player_country: Country, enemy_country: Country):
self.mission = mission
self.game = game
self.conflict = conflict
self.player_name = player_name
self.enemy_name = enemy_name
self.player_country = player_country
self.enemy_country = enemy_country
def generate(self):
from theater.conflicttheater import ControlPoint
for cp in self.game.theater.controlpoints:
if cp.is_global:
@@ -61,14 +32,20 @@ class ExtraAAConflictGenerator:
if cp.position.distance_to_point(self.conflict.from_cp.position) < EXTRA_AA_MIN_DISTANCE:
continue
country_name = cp.captured and self.player_name or self.enemy_name
if cp.position.distance_to_point(self.conflict.to_cp.position) < EXTRA_AA_MIN_DISTANCE:
continue
if cp.position.distance_to_point(self.conflict.position) > EXTRA_AA_MAX_DISTANCE:
continue
country_name = cp.captured and self.player_country or self.enemy_country
position = cp.position.point_from_heading(0, EXTRA_AA_POSITION_FROM_CP)
self.mission.vehicle_group(
country=self.mission.country(country_name),
name=namegen.next_ground_group_name(),
name=namegen.next_basedefense_name(),
_type=db.EXTRA_AA[country_name],
position=position,
group_size=2
group_size=1
)

File diff suppressed because it is too large Load Diff

1561
gen/airfields.py Normal file

File diff suppressed because it is too large Load Diff

130
gen/airsupportgen.py Normal file
View File

@@ -0,0 +1,130 @@
from dataclasses import dataclass, field
from .callsigns import callsign_for_support_unit
from .conflictgen import *
from .naming import *
from .radios import RadioFrequency, RadioRegistry
from .tacan import TacanBand, TacanChannel, TacanRegistry
TANKER_DISTANCE = 15000
TANKER_ALT = 4572
TANKER_HEADING_OFFSET = 45
AWACS_DISTANCE = 150000
AWACS_ALT = 13000
@dataclass
class AwacsInfo:
"""AWACS information for the kneeboard."""
callsign: str
freq: RadioFrequency
@dataclass
class TankerInfo:
"""Tanker information for the kneeboard."""
callsign: str
variant: str
freq: RadioFrequency
tacan: TacanChannel
@dataclass
class AirSupport:
awacs: List[AwacsInfo] = field(default_factory=list)
tankers: List[TankerInfo] = field(default_factory=list)
class AirSupportConflictGenerator:
def __init__(self, mission: Mission, conflict: Conflict, game,
radio_registry: RadioRegistry,
tacan_registry: TacanRegistry) -> None:
self.mission = mission
self.conflict = conflict
self.game = game
self.air_support = AirSupport()
self.radio_registry = radio_registry
self.tacan_registry = tacan_registry
@classmethod
def support_tasks(cls) -> typing.Collection[typing.Type[MainTask]]:
return [Refueling, AWACS]
def generate(self, is_awacs_enabled):
player_cp = self.conflict.from_cp if self.conflict.from_cp.captured else self.conflict.to_cp
fallback_tanker_number = 0
for i, tanker_unit_type in enumerate(db.find_unittype(Refueling, self.conflict.attackers_side)):
variant = db.unit_type_name(tanker_unit_type)
freq = self.radio_registry.alloc_uhf()
tacan = self.tacan_registry.alloc_for_band(TacanBand.Y)
tanker_heading = self.conflict.to_cp.position.heading_between_point(self.conflict.from_cp.position) + TANKER_HEADING_OFFSET * i
tanker_position = player_cp.position.point_from_heading(tanker_heading, TANKER_DISTANCE)
tanker_group = self.mission.refuel_flight(
country=self.mission.country(self.game.player_country),
name=namegen.next_tanker_name(self.mission.country(self.game.player_country), tanker_unit_type),
airport=None,
plane_type=tanker_unit_type,
position=tanker_position,
altitude=TANKER_ALT,
race_distance=58000,
frequency=freq.mhz,
start_type=StartType.Warm,
speed=574,
tacanchannel=str(tacan),
)
tanker_group.set_frequency(freq.mhz)
callsign = callsign_for_support_unit(tanker_group)
tacan_callsign = {
"Texaco": "TEX",
"Arco": "ARC",
"Shell": "SHL",
}.get(callsign)
if tacan_callsign is None:
# The dict above is all the callsigns currently in the game, but
# non-Western countries don't use the callsigns and instead just
# use numbers. It's possible that none of those nations have
# TACAN compatible refueling aircraft, but fallback just in
# case.
tacan_callsign = f"TK{fallback_tanker_number}"
fallback_tanker_number += 1
if tanker_unit_type != IL_78M:
# Override PyDCS tacan channel.
tanker_group.points[0].tasks.pop()
tanker_group.points[0].tasks.append(ActivateBeaconCommand(
tacan.number, tacan.band.value, tacan_callsign, True,
tanker_group.units[0].id, True))
tanker_group.points[0].tasks.append(SetInvisibleCommand(True))
tanker_group.points[0].tasks.append(SetImmortalCommand(True))
self.air_support.tankers.append(TankerInfo(callsign, variant, freq, tacan))
if is_awacs_enabled:
try:
freq = self.radio_registry.alloc_uhf()
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=freq.mhz,
start_type=StartType.Warm,
)
awacs_flight.set_frequency(freq.mhz)
awacs_flight.points[0].tasks.append(SetInvisibleCommand(True))
awacs_flight.points[0].tasks.append(SetImmortalCommand(True))
self.air_support.awacs.append(AwacsInfo(
callsign_for_support_unit(awacs_flight), freq))
except:
print("No AWACS for faction")

View File

@@ -1,64 +1,462 @@
from game import db
from .conflictgen import *
from .naming import *
from dataclasses import dataclass
from dcs.mission import *
from dcs.unittype import *
from dcs.point import *
from dcs.task import *
from dcs.country import *
from dcs.action import AITaskPush
from dcs.condition import TimeAfter, UnitDamaged, Or, GroupLifeLess
from dcs.triggers import TriggerOnce, Event
from gen import namegen
from gen.ground_forces.ai_ground_planner import CombatGroupRole, DISTANCE_FROM_FRONTLINE
from .callsigns import callsign_for_support_unit
from .conflictgen import *
SPREAD_DISTANCE_FACTOR = 0.1, 0.3
SPREAD_DISTANCE_SIZE_FACTOR = 0.1
FRONTLINE_CAS_FIGHTS_COUNT = 16, 24
FRONTLINE_CAS_GROUP_MIN = 1, 2
FRONTLINE_CAS_PADDING = 12000
class ArmorConflictGenerator:
def __init__(self, mission: Mission, conflict: Conflict):
self.m = mission
RETREAT_DISTANCE = 20000
BREAKTHROUGH_OFFENSIVE_DISTANCE = 35000
AGGRESIVE_MOVE_DISTANCE = 16000
FIGHT_DISTANCE = 3500
RANDOM_OFFSET_ATTACK = 250
@dataclass(frozen=True)
class JtacInfo:
"""JTAC information."""
unit_name: str
callsign: str
region: str
code: str
# TODO: Radio info? Type?
class GroundConflictGenerator:
def __init__(self, mission: Mission, conflict: Conflict, game, player_planned_combat_groups, enemy_planned_combat_groups, player_stance):
self.mission = mission
self.conflict = conflict
self.enemy_planned_combat_groups = enemy_planned_combat_groups
self.player_planned_combat_groups = player_planned_combat_groups
self.player_stance = CombatStance(player_stance)
self.enemy_stance = random.choice([CombatStance.AGGRESSIVE, CombatStance.AGGRESSIVE, CombatStance.AGGRESSIVE, CombatStance.ELIMINATION, CombatStance.BREAKTHROUGH]) if len(enemy_planned_combat_groups) > len(player_planned_combat_groups) else random.choice([CombatStance.DEFENSIVE, CombatStance.DEFENSIVE, CombatStance.DEFENSIVE, CombatStance.AMBUSH, CombatStance.AGGRESSIVE])
self.game = game
self.jtacs: List[JtacInfo] = []
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_SIZE_FACTOR)
def _generate_group(self, side: Country, unit: VehicleType, count: int, at: Point):
def generate(self):
player_groups = []
enemy_groups = []
combat_width = self.conflict.distance/2
if combat_width > 500000:
combat_width = 500000
if combat_width < 35000:
combat_width = 35000
position = Conflict.frontline_position(self.game.theater, self.conflict.from_cp, self.conflict.to_cp)
# Create player groups at random position
for group in self.player_planned_combat_groups:
if group.role == CombatGroupRole.ARTILLERY:
distance_from_frontline = self.get_artilery_group_distance_from_frontline(group)
else:
distance_from_frontline = DISTANCE_FROM_FRONTLINE[group.role]
final_position = self.get_valid_position_for_group(position, True, combat_width, distance_from_frontline)
if final_position is not None:
g = self._generate_group(
side=self.mission.country(self.game.player_country),
unit=group.units[0],
heading=self.conflict.heading+90,
count=len(group.units),
at=final_position)
g.set_skill(self.game.settings.player_skill)
player_groups.append((g,group))
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:
if group.role == CombatGroupRole.ARTILLERY:
distance_from_frontline = self.get_artilery_group_distance_from_frontline(group)
else:
distance_from_frontline = DISTANCE_FROM_FRONTLINE[group.role]
final_position = self.get_valid_position_for_group(position, False, combat_width, distance_from_frontline)
if final_position is not None:
g = self._generate_group(
side=self.mission.country(self.game.enemy_country),
unit=group.units[0],
heading=self.conflict.heading - 90,
count=len(group.units),
at=final_position)
g.set_skill(self.game.settings.enemy_vehicle_skill)
enemy_groups.append((g, group))
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.jtacs)
utype = MQ_9_Reaper
if "jtac_unit" in self.game.player_faction:
utype = self.game.player_faction["jtac_unit"]
jtac = self.mission.flight_group(country=self.mission.country(self.game.player_country),
name=n,
aircraft_type=utype,
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))
frontline = f"Frontline {self.conflict.from_cp.name}/{self.conflict.to_cp.name}"
# Note: Will need to change if we ever add ground based JTAC.
callsign = callsign_for_support_unit(jtac)
self.jtacs.append(JtacInfo(n, callsign, frontline, str(code)))
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:
cp = self.conflict.from_cp
else:
cp = self.conflict.to_cp
if is_player:
faction = self.game.player_name
else:
faction = self.game.enemy_name
possible_infantry_units = db.find_infantry(faction)
if len(possible_infantry_units) == 0:
return
u = random.choice(possible_infantry_units)
self.mission.vehicle_group(
side,
namegen.next_infantry_name(side, cp, u), u,
position=infantry_position,
group_size=1,
heading=forward_heading,
move_formation=PointAction.OffRoad)
for i in range(randint(3, 10)):
u = random.choice(possible_infantry_units)
position = infantry_position.random_point_within(55, 5)
self.mission.vehicle_group(
side,
namegen.next_infantry_name(side, cp, u), u,
position=position,
group_size=1,
heading=forward_heading,
move_formation=PointAction.OffRoad)
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 hasattr(group.units[0], 'eplrs'):
if group.units[0].eplrs:
dcs_group.points[0].tasks.append(EPLRS(dcs_group.id))
if group.role == CombatGroupRole.ARTILLERY:
# Fire on any ennemy in range
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.AGGRESSIVE:
# 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(-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))
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)
else:
attack_point = self.find_offensive_point(dcs_group, forward_heading, AGGRESIVE_MOVE_DISTANCE)
dcs_group.add_waypoint(attack_point, PointAction.OnRoad)
elif stance == CombatStance.BREAKTHROUGH:
# In breakthrough mode, the units will move forward
# If the enemy base is close enough, the units will attack the base
if to_cp.position.distance_to_point(
dcs_group.points[0].position) <= BREAKTHROUGH_OFFENSIVE_DISTANCE:
attack_point = to_cp.position.random_point_within(500, 0)
else:
attack_point = self.find_offensive_point(dcs_group, forward_heading, BREAKTHROUGH_OFFENSIVE_DISTANCE)
dcs_group.add_waypoint(attack_point, PointAction.OnRoad)
elif stance == CombatStance.ELIMINATION:
# In elimination mode, the units focus on destroying as much enemy groups as possible
targets = self.find_n_nearest_enemy_groups(dcs_group, enemy_groups, 3)
i = 1
for target in targets:
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.AGGRESSIVE, CombatStance.BREAKTHROUGH, CombatStance.ELIMINATION]:
# APC & ATGM will never move too much forward, but will follow along any offensive
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)
else:
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
if from_cp.position.distance_to_point(dcs_group.points[0].position) <= RETREAT_DISTANCE:
retreat_point = from_cp.position.random_point_within(500, 250)
else:
retreat_point = self.find_retreat_point(dcs_group, forward_heading)
reposition_point = retreat_point.point_from_heading(forward_heading, 10) # Another point to make the unit face the enemy
dcs_group.add_waypoint(retreat_point, PointAction.OnRoad)
dcs_group.add_waypoint(reposition_point, PointAction.OffRoad)
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, distance)
def find_offensive_point(self, dcs_group, frontline_heading, distance):
"""
Find a point to attack
:param dcs_group: DCS mission group we are searching an attack point for
:param frontline_heading: Heading of the frontline
:param distance: Distance of the offensive (how far unit should move)
:return: dcs.mapping.Point object with the desired position
"""
return dcs_group.points[0].position.point_from_heading(frontline_heading, distance)
def find_n_nearest_enemy_groups(self, player_group, enemy_groups, n):
"""
Return the neaarest enemy group for the player group
@param group Group for which we should find the nearest ennemies
@param enemy_groups Potential enemy groups
@param n number of nearby groups to take
"""
targets = []
sorted_list = sorted(enemy_groups, key=lambda group: player_group.points[0].position.distance_to_point(group[0].points[0].position))
for i in range(n):
if len(sorted_list) <= i:
break
else:
targets.append(sorted_list[i][0])
return targets
def find_nearest_enemy_group(self, player_group, enemy_groups):
"""
Search the enemy groups for a potential target suitable to armored assault
@param group Group for which we should find the nearest ennemy
@param enemy_groups Potential enemy groups
"""
min_distance = 99999999
target = None
for dcs_group, group in enemy_groups:
dist = player_group.points[0].position.distance_to_point(dcs_group.points[0].position)
if dist < min_distance:
min_distance = dist
target = dcs_group
return target
def get_artillery_target_in_range(self, dcs_group, group, enemy_groups):
"""
Search the enemy groups for a potential target suitable to an artillery unit
"""
rng = group.units[0].threat_range
if len(enemy_groups) == 0:
return None
for o in range(10):
potential_target = random.choice(enemy_groups)[0]
distance_to_target = dcs_group.points[0].position.distance_to_point(potential_target.points[0].position)
if distance_to_target < rng:
return potential_target.points[0].position
return None
def get_artilery_group_distance_from_frontline(self, group):
"""
For artilery group, decide the distance from frontline with the range of the unit
"""
rg = group.units[0].threat_range - 7500
if rg > DISTANCE_FROM_FRONTLINE[CombatGroupRole.ARTILLERY]:
rg = DISTANCE_FROM_FRONTLINE[CombatGroupRole.ARTILLERY]
if rg < DISTANCE_FROM_FRONTLINE[CombatGroupRole.TANK]:
rg = DISTANCE_FROM_FRONTLINE[CombatGroupRole.TANK] + 100
return rg
def get_valid_position_for_group(self, conflict_position, isplayer, combat_width, distance_from_frontline):
i = 0
while i < 25: # 25 attempt for valid position
heading_diff = -90 if isplayer else 90
shifted = conflict_position[0].point_from_heading(self.conflict.heading,
random.randint((int)(-combat_width / 2), (int)(combat_width / 2)))
final_position = shifted.point_from_heading(self.conflict.heading + heading_diff, distance_from_frontline)
if self.conflict.theater.is_on_land(final_position):
return final_position
else:
i = i + 1
continue
return None
def _generate_group(self, side: Country, unit: VehicleType, count: int, at: Point, move_formation: PointAction = PointAction.OffRoad, heading=0):
if side == self.conflict.attackers_country:
cp = self.conflict.from_cp
else:
cp = self.conflict.to_cp
logging.info("armorgen: {} for {}".format(unit, side.id))
group = self.mission.vehicle_group(
side,
namegen.next_unit_name(side, cp.id, unit), unit,
position=self._group_point(at),
group_size=count,
heading=heading,
move_formation=move_formation)
for c in range(count):
group = self.m.vehicle_group(
side,
namegen.next_armor_group_name(),
unit,
position=self._group_point(at),
group_size=1,
move_formation=PointAction.OffRoad)
wayp = group.add_waypoint(self.conflict.position.point_from_heading(0, 500))
wayp.tasks = []
vehicle: Vehicle = group.units[c]
vehicle.player_can_drive = True
def generate(self, attackers: db.ArmorDict, defenders: db.ArmorDict):
for type, count in attackers.items():
self._generate_group(
side=self.conflict.attackers_side,
unit=type,
count=count,
at=self.conflict.ground_attackers_location)
for type, count in defenders.items():
self._generate_group(
side=self.conflict.defenders_side,
unit=type,
count=count,
at=self.conflict.ground_defenders_location)
def generate_passengers(self, count: int):
unit_type = random.choice(db.find_unittype(Nothing, self.conflict.attackers_side.name))
self.m.vehicle_group(
country=self.conflict.attackers_side,
name=namegen.next_passenger_group_name(),
_type=unit_type,
position=self.conflict.ground_attackers_location,
group_size=count
)
return group

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