Compare commits

...

25 Commits

Author SHA1 Message Date
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
76 changed files with 907 additions and 142 deletions

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: |
py -m venv ./venv
- name: Install dependencies
run: |
./venv/scripts/activate
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

4
.gitmodules vendored Normal file
View File

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

View File

@@ -1,3 +1,23 @@
# 2.1.1
## Features/Improvements :
* **[Other]** Added an installer option (thanks to contributor parithon)
* **[Cheat Menu]** Added possibility to replace destroyed SAM and base defenses units for the player (Click on a SAM site to fix it)
* **[Cheat Menu]** 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 Github 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.
# 2.1.0
## Features/Improvements :

View File

@@ -1,12 +1,12 @@
import inspect
import dcs
from pydcs import dcs
DEFAULT_AVAILABLE_BUILDINGS = ['fuel', 'ammo', 'comms', 'oil', 'ware', 'farp', 'fob', 'power', 'factory', 'derrick', 'aa']
WW2_GERMANY_BUILDINGS = ['fuel', 'factory', 'ww2bunker', 'ww2bunker', 'ww2bunker', 'allycamp', 'allycamp', 'aa']
WW2_ALLIES_BUILDINGS = ['fuel', 'factory', 'allycamp', 'allycamp', 'allycamp', 'allycamp', 'allycamp', 'aa']
FORTIFICATION_BUILDINGS = ['Siegfried Line', 'Concertina Wire', 'Czech hedgehogs 1', 'Czech hedgehogs 2',
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',

View File

@@ -295,23 +295,6 @@ PRICES = {
Unarmed.Transport_M818: 3,
AirDefence.AAA_Vulcan_M163: 5,
AirDefence.SAM_Linebacker_M6: 10,
AirDefence.AAA_ZU_23_Closed: 2,
AirDefence.SPAAA_ZSU_23_4_Shilka: 4,
AirDefence.SAM_SA_9_Strela_1_9P31: 8,
AirDefence.SAM_SA_19_Tunguska_2S6: 15,
AirDefence.SAM_SA_6_Kub_LN_2P25: 22,
AirDefence.SAM_SA_8_Osa_9A33: 12,
AirDefence.SAM_SA_3_S_125_LN_5P73: 20,
AirDefence.SAM_SA_2_LN_SM_90: 15,
AirDefence.SAM_SA_11_Buk_LN_9A310M1: 25,
AirDefence.SAM_Hawk_PCP: 20,
AirDefence.SAM_Patriot_LN_M901: 60,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: 60,
AirDefence.SAM_Chaparral_M48: 10,
# WW2
Armor.MT_Pz_Kpfw_V_Panther_Ausf_G:24,
Armor.MT_Pz_Kpfw_IV_Ausf_H:16,
@@ -332,9 +315,6 @@ PRICES = {
Armor.LAC_M8_Greyhound: 8,
Armor.TD_M10_GMC: 14,
Armor.StuG_III_Ausf__G: 12,
AirDefence.AAA_Bofors_40mm: 8,
AirDefence.AAA_8_8cm_Flak_36: 8,
AirDefence.AAA_8_8cm_Flak_18: 12,
Artillery.M12_GMC: 10,
Artillery.Sturmpanzer_IV_Brummbär: 10,
@@ -348,6 +328,79 @@ PRICES = {
Dry_cargo_ship_Ivanov: 10,
Tanker_Elnya_160: 10,
# Air Defence units
AirDefence.SAM_SA_19_Tunguska_2S6: 30,
AirDefence.SAM_SA_6_Kub_LN_2P25: 20,
AirDefence.SAM_SA_3_S_125_LN_5P73: 6,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: 22,
AirDefence.SAM_SA_10_S_300PS_LN_5P85D: 22,
AirDefence.SAM_SA_11_Buk_LN_9A310M1: 30,
AirDefence.SAM_SA_8_Osa_9A33: 28,
AirDefence.SAM_SA_15_Tor_9A331: 40,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3: 24,
AirDefence.SAM_SA_9_Strela_1_9P31: 16,
AirDefence.SAM_SA_11_Buk_CC_9S470M1: 25,
AirDefence.SAM_SA_8_Osa_LD_9T217: 22,
AirDefence.SAM_Patriot_AMG_AN_MRC_137: 35,
AirDefence.SAM_Patriot_ECS_AN_MSQ_104: 30,
AirDefence.SPAAA_Gepard: 24,
AirDefence.SAM_Hawk_PCP: 14,
AirDefence.AAA_Vulcan_M163: 12,
AirDefence.SAM_Hawk_LN_M192: 8,
AirDefence.SAM_Chaparral_M48: 16,
AirDefence.SAM_Linebacker_M6: 18,
AirDefence.SAM_Patriot_LN_M901: 15,
AirDefence.SAM_Avenger_M1097: 20,
AirDefence.SAM_Patriot_EPP_III: 15,
AirDefence.SAM_Patriot_ICC: 18,
AirDefence.SAM_Roland_ADS: 12,
AirDefence.SAM_SA_10_S_300PS_CP_54K6: 18,
AirDefence.Stinger_MANPADS: 6,
AirDefence.SAM_Stinger_comm_dsr: 4,
AirDefence.SAM_Stinger_comm: 4,
AirDefence.SPAAA_ZSU_23_4_Shilka: 12,
AirDefence.AAA_ZU_23_Closed: 6,
AirDefence.AAA_ZU_23_Emplacement: 6,
AirDefence.AAA_ZU_23_on_Ural_375: 8,
AirDefence.AAA_ZU_23_Insurgent_Closed: 6,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375: 8,
AirDefence.AAA_ZU_23_Insurgent: 6,
AirDefence.SAM_SA_18_Igla_MANPADS: 10,
AirDefence.SAM_SA_18_Igla_comm: 8,
AirDefence.SAM_SA_18_Igla_S_MANPADS: 12,
AirDefence.SAM_SA_18_Igla_S_comm: 8,
AirDefence.EWR_1L13: 30,
AirDefence.SAM_SA_6_Kub_STR_9S91: 22,
AirDefence.SAM_SA_10_S_300PS_TR_30N6: 24,
AirDefence.SAM_SA_10_S_300PS_SR_5N66M: 30,
AirDefence.EWR_55G6: 30,
AirDefence.SAM_SA_10_S_300PS_SR_64H6E: 30,
AirDefence.SAM_SA_11_Buk_SR_9S18M1: 28,
AirDefence.CP_9S80M1_Sborka: 10,
AirDefence.SAM_Hawk_TR_AN_MPQ_46: 14,
AirDefence.SAM_Hawk_SR_AN_MPQ_50: 18,
AirDefence.SAM_Patriot_STR_AN_MPQ_53: 22,
AirDefence.SAM_Hawk_CWAR_AN_MPQ_55: 20,
AirDefence.SAM_SR_P_19: 14,
AirDefence.SAM_Roland_EWR: 16,
AirDefence.SAM_SA_3_S_125_TR_SNR: 14,
AirDefence.SAM_SA_2_LN_SM_90: 8,
AirDefence.SAM_SA_2_TR_SNR_75_Fan_Song: 12,
AirDefence.Rapier_FSA_Launcher: 6,
AirDefence.Rapier_FSA_Optical_Tracker: 12,
AirDefence.Rapier_FSA_Blindfire_Tracker: 16,
AirDefence.HQ_7_Self_Propelled_LN: 20,
AirDefence.HQ_7_Self_Propelled_STR: 24,
AirDefence.AAA_8_8cm_Flak_18: 6,
AirDefence.AAA_Flak_38: 6,
AirDefence.AAA_8_8cm_Flak_36: 8,
AirDefence.AAA_8_8cm_Flak_37: 10,
AirDefence.AAA_Flak_Vierling_38:6,
AirDefence.AAA_Kdo_G_40: 8,
AirDefence.Flak_Searchlight_37: 4,
AirDefence.Maschinensatz_33: 10,
AirDefence.AAA_8_8cm_Flak_41: 12,
AirDefence.AAA_Bofors_40mm: 8,
# FRENCH PACK MOD
frenchpack.AMX_10RCR: 10,
@@ -959,10 +1012,8 @@ PLANE_PAYLOAD_OVERRIDES = {
RQ_1A_Predator: COMMON_OVERRIDE,
WingLoong_I: COMMON_OVERRIDE,
AH_1W: COMMON_OVERRIDE,
AH_64D:{
CAS: "AGM-114K*16"
},
AH_64D: COMMON_OVERRIDE,
AH_64A: COMMON_OVERRIDE,
Su_25TM: {
SEAD: "Kh-31P*2_Kh-25ML*4_R-73*2_L-081_MPS410",

View File

@@ -178,9 +178,12 @@ class Event:
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])

View File

@@ -7,14 +7,20 @@ Syria_2011 = {
"side": "red",
"units": [
MiG_29S,
MiG_21Bis,
MiG_23MLD,
MiG_25PD,
L_39ZA,
Su_24M,
MiG_29S,
Su_17M4,
Su_24M,
L_39ZA,
Mi_24V,
SA342M,
Mi_8MT,
SA342M,
SA342L,
IL_76MD,
IL_78M,

View File

@@ -11,12 +11,11 @@ USA_1990 = {
F_15E,
F_14B,
FA_18C_hornet,
F_16C_50,
A_10A,
AV8BNA,
B_1B,
KC_135,
KC130,
C_130,
@@ -24,7 +23,6 @@ USA_1990 = {
UH_1H,
AH_64A,
OH_58D,
Armor.MBT_M1A2_Abrams,
Armor.IFV_LAV_25,

View File

@@ -14,6 +14,7 @@ USA_2005 = {
F_16C_50,
A_10C,
AV8BNA,
MQ_9_Reaper,
KC_135,
KC130,
@@ -22,7 +23,6 @@ USA_2005 = {
UH_1H,
AH_64D,
OH_58D,
Armor.MBT_M1A2_Abrams,
Armor.ATGM_M1134_Stryker,

View File

@@ -316,10 +316,10 @@ class AircraftConflictGenerator:
detection_zone = self.m.triggers.add_triggerzone(flight.from_cp.position, radius=25000, hidden=False, name="ITZ")
if flight.from_cp.captured:
activation_trigger.add_condition(PartOfCoalitionInZone(self.game.get_enemy_color(), detection_zone.id)) # TODO : support unit type in part of coalition
activation_trigger.add_action(MessageToAll(String("WARNING : Enemy aircrafts have been detected in the vicinity of " + flight.from_cp.name + ". Interceptors are taking off."), 20))
activation_trigger.add_action(MessageToAll(String("WARNING : Enemy aircraft have been detected in the vicinity of " + flight.from_cp.name + ". Interceptors are taking off."), 20))
else:
activation_trigger.add_condition(PartOfCoalitionInZone(self.game.get_player_color(), detection_zone.id))
activation_trigger.add_action(MessageToAll(String("WARNING : We have detected that enemy aircrafts are scrambling for an interception on " + flight.from_cp.name + " airbase."), 20))
activation_trigger.add_action(MessageToAll(String("WARNING : We have detected that enemy aircraft are scrambling for an interception on " + flight.from_cp.name + " airbase."), 20))
def generate_planned_flight(self, cp, country, flight:Flight):
try:
@@ -516,6 +516,10 @@ class AircraftConflictGenerator:
group.points[0].tasks.append(OptRestrictJettison(True))
for point in flight.points:
group.add_waypoint(Point(point.x,point.y), point.alt)
group.add_waypoint(Point(point.x, point.y), point.alt)
def setup_radio_preset(self, flight, group):
pass

View File

@@ -1,7 +1,7 @@
import logging
import typing
import pdb
import dcs
from pydcs import dcs
from random import randint
from dcs import Mission

View File

@@ -7,7 +7,8 @@ from game.data.doctrine import MODERN_DOCTRINE
from game.data.radar_db import UNITS_WITH_RADAR
from game.utils import meter_to_feet, nm_to_meter
from gen import Conflict
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE, STRIKE_CAPABLE
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE, STRIKE_CAPABLE, \
DRONES
from gen.flights.flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
@@ -245,8 +246,13 @@ class FlightPlanner:
except IndexError:
break
inventory[unit] = inventory[unit] - 2
flight = Flight(unit, 2, self.from_cp, FlightType.STRIKE)
if unit in DRONES:
count = 1
else:
count = 2
inventory[unit] = inventory[unit] - count
flight = Flight(unit, count, self.from_cp, FlightType.STRIKE)
flight.points = []
flight.scheduled_in = offset + i*random.randint(self.doctrine["STRIKE_EVERY_X_MINUTES"] - 5, self.doctrine["STRIKE_EVERY_X_MINUTES"] + 5)

View File

@@ -74,7 +74,7 @@ CAP_CAPABLE = [
Rafale_M,
]
# USed for CAS (Close air support) and BAI (Battlefield Interdiction)
# Used for CAS (Close air support) and BAI (Battlefield Interdiction)
CAS_CAPABLE = [
MiG_15bis,
@@ -117,6 +117,8 @@ CAS_CAPABLE = [
AH_64A,
AH_64D,
AH_1W,
UH_1H,

View File

@@ -0,0 +1,4 @@
from dcs.unitgroup import FlyingGroup

View File

@@ -65,6 +65,40 @@ SAM_MAP = {
AirDefence.HQ_7_Self_Propelled_LN: HQ7Generator
}
SAM_PRICES = {
AirDefence.SAM_Hawk_PCP: 35,
AirDefence.AAA_ZU_23_Emplacement: 10,
AirDefence.AAA_ZU_23_Closed: 10,
AirDefence.AAA_ZU_23_on_Ural_375: 10,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375: 10,
AirDefence.AAA_ZU_23_Insurgent_Closed: 10,
AirDefence.AAA_ZU_23_Insurgent: 10,
AirDefence.SPAAA_ZSU_23_4_Shilka: 10,
AirDefence.AAA_Vulcan_M163: 15,
AirDefence.SAM_Linebacker_M6: 20,
AirDefence.Rapier_FSA_Launcher: 20,
AirDefence.SAM_Avenger_M1097: 22,
AirDefence.SPAAA_Gepard: 24,
AirDefence.SAM_Roland_ADS: 40,
AirDefence.SAM_Patriot_LN_M901: 85,
AirDefence.SAM_Patriot_EPP_III: 85,
AirDefence.SAM_Chaparral_M48: 25,
AirDefence.AAA_Bofors_40mm: 15,
AirDefence.AAA_8_8cm_Flak_36: 15,
AirDefence.SAM_SA_2_LN_SM_90: 30,
AirDefence.SAM_SA_3_S_125_LN_5P73: 35,
AirDefence.SAM_SA_6_Kub_LN_2P25: 45,
AirDefence.SAM_SA_8_Osa_9A33: 30,
AirDefence.SAM_SA_9_Strela_1_9P31: 25,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: 80,
AirDefence.SAM_SA_10_S_300PS_CP_54K6: 80,
AirDefence.SAM_SA_11_Buk_LN_9A310M1: 60,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3: 30,
AirDefence.SAM_SA_15_Tor_9A331: 40,
AirDefence.SAM_SA_19_Tunguska_2S6: 35,
AirDefence.HQ_7_Self_Propelled_LN: 35
}
def generate_anti_air_group(game, parent_cp, ground_object, faction:str):
"""
This generate a SAM group

BIN
installer/ISCC.exe Normal file

Binary file not shown.

View File

@@ -0,0 +1,51 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "DCS Liberation"
#define MyAppVersion "{{version}}"
#define MyAppPublisher "Khopa"
#define MyAppURL "https://github.com/Khopa/dcs_liberation/wiki"
#define MyAppExeName "liberation_main.exe"
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{6753B352-D281-42CB-9AFA-5E93EB90AA5A}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
; Remove the following line to run in administrative install mode (install for all users.)
PrivilegesRequired=lowest
PrivilegesRequiredOverridesAllowed=dialog
OutputDir=..\dist
OutputBaseFilename=dcs_liberation
SetupIconFile=..\resources\icon.ico
UninstallDisplayIcon={app}\liberation_main.exe
Compression=lzma
SolidCompression=yes
WizardStyle=modern
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "..\dist\dcs_liberation\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

1
pydcs Submodule

Submodule pydcs added at dcc3d84631

View File

@@ -4,7 +4,7 @@ import logging
import os
import sys
import dcs
from pydcs import dcs
from PySide2 import QtWidgets
from PySide2.QtGui import QPixmap
from PySide2.QtWidgets import QApplication, QSplashScreen

View File

@@ -143,7 +143,7 @@ class QLiberationMap(QGraphicsView):
go_pos = self._transform_point(ground_object.position)
if not ground_object.airbase_group:
buildings = self.game.theater.find_ground_objects_by_obj_name(ground_object.obj_name)
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 12, 12, cp, ground_object, buildings))
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 14, 12, cp, ground_object, self.game, buildings))
if ground_object.category == "aa" and self.get_display_rule("sam"):
max_range = 0

View File

@@ -1,19 +1,22 @@
from PySide2.QtCore import QPoint, QRect, QPointF, Qt
from PySide2.QtGui import QPainter
from PySide2.QtGui import QPainter, QBrush
from PySide2.QtWidgets import QGraphicsRectItem, QGraphicsItem, QGraphicsSceneHoverEvent, QGraphicsSceneMouseEvent
import qt_ui.uiconstants as CONST
from game import db
from game import db, Game
from game.data.building_data import FORTIFICATION_BUILDINGS
from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu
from theater import TheaterGroundObject, ControlPoint
class QMapGroundObject(QGraphicsRectItem):
def __init__(self, parent, x: float, y: float, w: float, h: float, cp: ControlPoint, model: TheaterGroundObject, buildings=[]):
def __init__(self, parent, x: float, y: float, w: float, h: float, cp: ControlPoint, model: TheaterGroundObject, game:Game, buildings=[]):
super(QMapGroundObject, self).__init__(x, y, w, h)
self.model = model
self.cp = cp
self.parent = parent
self.game = game
self.setAcceptHoverEvents(True)
self.setZValue(2)
self.buildings = buildings
@@ -39,6 +42,8 @@ class QMapGroundObject(QGraphicsRectItem):
tooltip = tooltip + str(building.dcs_identifier) + "\n"
self.setToolTip(tooltip[:-1])
def mousePressEvent(self, event:QGraphicsSceneMouseEvent):
self.openEditionMenu()
def paint(self, painter, option, widget=None):
#super(QMapControlPoint, self).paint(painter, option, widget)
@@ -53,14 +58,49 @@ class QMapGroundObject(QGraphicsRectItem):
if cat == "aa" and self.model.sea_object:
cat = "ship"
if not self.model.is_dead and not self.cp.captured:
painter.drawPixmap(option.rect, CONST.ICONS[cat + enemyIcons])
elif not self.model.is_dead:
painter.drawPixmap(option.rect, CONST.ICONS[cat + playerIcons])
rect = QRect(option.rect.x()+2,option.rect.y(),option.rect.width()-2,option.rect.height())
is_dead = self.model.is_dead
for building in self.buildings:
if not building.is_dead:
is_dead = False
break
if not is_dead and not self.cp.captured:
painter.drawPixmap(rect, CONST.ICONS[cat + enemyIcons])
elif not is_dead:
painter.drawPixmap(rect, CONST.ICONS[cat + playerIcons])
else:
painter.drawPixmap(option.rect, CONST.ICONS["destroyed"])
painter.drawPixmap(rect, CONST.ICONS["destroyed"])
self.drawHealthGauge(painter, option)
painter.restore()
def drawHealthGauge(self, painter, option):
units_alive = 0
units_dead = 0
if len(self.model.groups) == 0:
for building in self.buildings:
if building.dcs_identifier in FORTIFICATION_BUILDINGS:
continue
if building.is_dead:
units_dead += 1
else:
units_alive += 1
for g in self.model.groups:
units_alive += len(g.units)
if hasattr(g, "units_losts"):
units_dead += len(g.units_losts)
if units_dead + units_alive > 0:
ratio = float(units_alive)/(float(units_dead) + float(units_alive))
bar_height = ratio * option.rect.height()
painter.fillRect(option.rect.x(), option.rect.y(), 2, option.rect.height(), QBrush(CONST.COLORS["dark_red"]))
painter.fillRect(option.rect.x(), option.rect.y(), 2, bar_height, QBrush(CONST.COLORS["green"]))
def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent):
self.update()
self.setCursor(Qt.PointingHandCursor)
@@ -72,3 +112,7 @@ class QMapGroundObject(QGraphicsRectItem):
def hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent):
self.update()
def openEditionMenu(self):
self.editionMenu = QGroundObjectMenu(self.window(), self.model, self.buildings, self.cp, self.game)
self.editionMenu.show()

View File

@@ -121,7 +121,7 @@ class QWaitingForMissionResultWindow(QDialog):
updateBox.setLayout(updateLayout)
self.debriefing = debriefing
updateLayout.addWidget(QLabel("<b>Aircrafts destroyed</b>"), 0, 0)
updateLayout.addWidget(QLabel("<b>Aircraft destroyed</b>"), 0, 0)
updateLayout.addWidget(QLabel(str(len(debriefing.killed_aircrafts))), 0, 1)
updateLayout.addWidget(QLabel("<b>Ground units destroyed</b>"), 1, 0)

View File

@@ -1,16 +1,22 @@
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox, QPushButton
from qt_ui.uiconstants import VEHICLES_ICONS
from qt_ui.windows.groundobject.QGroundObjectMenu import QGroundObjectMenu
from theater import ControlPoint, TheaterGroundObject
class QBaseDefenseGroupInfo(QGroupBox):
def __init__(self, cp:ControlPoint, ground_object: TheaterGroundObject):
def __init__(self, cp:ControlPoint, ground_object: TheaterGroundObject, game):
super(QBaseDefenseGroupInfo, self).__init__("Group : " + ground_object.obj_name)
self.ground_object = ground_object
self.cp = cp
self.game = game
self.buildings = game.theater.find_ground_objects_by_obj_name(self.ground_object.obj_name)
self.init_ui()
def init_ui(self):
unit_dict = {}
layout = QGridLayout()
@@ -29,8 +35,18 @@ class QBaseDefenseGroupInfo(QGroupBox):
# icon.setText("<b>" + k[:6] + "</b>")
#icon.setProperty("style", "icon-plane")
#layout.addWidget(icon, i, 0)
layout.addWidget(QLabel(str(v) + " x " + "<strong>" + k + "</strong>"), i, 1)
layout.addWidget(QLabel(str(v) + " x " + "<strong>" + k + "</strong>"), i, 0)
i = i + 1
manage_button = QPushButton("Manage")
manage_button.setProperty("style", "btn-success")
manage_button.setMaximumWidth(180)
manage_button.clicked.connect(self.onManage)
layout.addWidget(manage_button, i+1, 0)
self.setLayout(layout)
def onManage(self):
self.editionMenu = QGroundObjectMenu(self.window(), self.ground_object, self.buildings, self.cp, self.game)
self.editionMenu.show()

View File

@@ -15,6 +15,6 @@ class QBaseDefensesHQ(QFrame):
def init_ui(self):
airport = self.game.theater.terrain.airport_by_id(self.cp.id)
layout = QGridLayout()
layout.addWidget(QBaseInformation(self.cp, airport))
layout.addWidget(QBaseInformation(self.cp, airport, self.game))
self.setLayout(layout)

View File

@@ -1,4 +1,5 @@
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox, QVBoxLayout, QFrame
from PySide2.QtGui import Qt
from PySide2.QtWidgets import QGridLayout, QLabel, QGroupBox, QVBoxLayout, QFrame, QWidget, QScrollArea
from game import db
from qt_ui.uiconstants import AIRCRAFT_ICONS, VEHICLES_ICONS
@@ -8,17 +9,34 @@ from theater import ControlPoint, Airport
class QBaseInformation(QFrame):
def __init__(self, cp:ControlPoint, airport:Airport):
def __init__(self, cp:ControlPoint, airport:Airport, game):
super(QBaseInformation, self).__init__()
self.cp = cp
self.airport = airport
self.game = game
self.setMinimumWidth(500)
self.init_ui()
def init_ui(self):
self.layout = QVBoxLayout()
self.mainLayout = QVBoxLayout()
scroll_content = QWidget()
task_box_layout = QGridLayout()
scroll_content.setLayout(task_box_layout)
row = 0
for g in self.cp.ground_objects:
if g.airbase_group:
group_info = QBaseDefenseGroupInfo(self.cp, g)
self.layout.addWidget(group_info)
self.setLayout(self.layout)
group_info = QBaseDefenseGroupInfo(self.cp, g, self.game)
task_box_layout.addWidget(group_info)
scroll_content.setLayout(task_box_layout)
scroll = QScrollArea()
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroll.setWidgetResizable(True)
scroll.setWidget(scroll_content)
self.mainLayout.addWidget(scroll)
self.setLayout(self.mainLayout)

View File

@@ -0,0 +1,33 @@
import os
from PySide2.QtGui import QPixmap
from PySide2.QtWidgets import QGroupBox, QHBoxLayout, QVBoxLayout, QLabel
class QBuildingInfo(QGroupBox):
def __init__(self, building, ground_object):
super(QBuildingInfo, self).__init__()
self.building = building
self.ground_object = ground_object
self.init_ui()
def init_ui(self):
self.header = QLabel()
path = os.path.join("./resources/ui/units/buildings/" + self.building.dcs_identifier + ".png")
if self.building.is_dead:
pixmap = QPixmap("./resources/ui/units/buildings/dead.png")
elif os.path.isfile(path):
pixmap = QPixmap(path)
else:
pixmap = QPixmap("./resources/ui/units/buildings/missing.png")
self.header.setPixmap(pixmap)
name = "<b>{}</b> {}".format(self.building.dcs_identifier[0:18], "[DEAD]" if self.building.is_dead else "")
self.name = QLabel(name)
self.name.setProperty("style", "small")
layout = QVBoxLayout()
layout.addWidget(self.header)
layout.addWidget(self.name)
footer = QHBoxLayout()
self.setLayout(layout)

View File

@@ -0,0 +1,117 @@
import logging
from PySide2.QtGui import QCloseEvent
from PySide2.QtWidgets import QHBoxLayout, QWidget, QDialog, QGridLayout, QLabel, QGroupBox, QVBoxLayout, QPushButton
from dcs import Point
from game import Game
from game.data.building_data import FORTIFICATION_BUILDINGS
from game.db import PRICES, unit_type_of
from qt_ui.uiconstants import EVENT_ICONS
from qt_ui.widgets.QBudgetBox import QBudgetBox
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.groundobject.QBuildingInfo import QBuildingInfo
from theater import ControlPoint, TheaterGroundObject
class QGroundObjectMenu(QDialog):
def __init__(self, parent, ground_object: TheaterGroundObject, buildings:[], cp: ControlPoint, game: Game):
super(QGroundObjectMenu, self).__init__(parent)
self.setMinimumWidth(350)
self.ground_object = ground_object
self.buildings = buildings
self.cp = cp
self.game = game
self.setWindowTitle("Location " + self.ground_object.obj_name)
self.setWindowIcon(EVENT_ICONS["capture"])
self.intelBox = QGroupBox("Units :")
self.buildingBox = QGroupBox("Buildings :")
self.intelLayout = QGridLayout()
self.buildingsLayout = QGridLayout()
self.init_ui()
def init_ui(self):
self.mainLayout = QVBoxLayout()
self.budget = QBudgetBox(self.game)
self.budget.setGame(self.game)
self.doLayout()
if len(self.ground_object.groups) > 0:
self.mainLayout.addWidget(self.intelBox)
else:
self.mainLayout.addWidget(self.buildingBox)
self.setLayout(self.mainLayout)
def doLayout(self):
self.intelBox = QGroupBox("Units :")
self.intelLayout = QGridLayout()
i = 0
for g in self.ground_object.groups:
if not hasattr(g, "units_losts"):
g.units_losts = []
for u in g.units:
self.intelLayout.addWidget(QLabel("<b>Unit #" + str(u.id) + " - " + str(u.type) + "</b>"), i, 0)
i = i + 1
for u in g.units_losts:
utype = unit_type_of(u)
if utype in PRICES:
price = PRICES[utype]
else:
price = 6
self.intelLayout.addWidget(QLabel("<b>Unit #" + str(u.id) + " - " + str(u.type) + "</b> [DEAD]"), i, 0)
if self.cp.captured:
repair = QPushButton("Repair [" + str(price) + "M]")
repair.setProperty("style", "btn-success")
repair.clicked.connect(lambda u=u, g=g, p=price: self.repair_unit(g, u, p))
self.intelLayout.addWidget(repair, i, 1)
i = i + 1
self.buildingBox = QGroupBox("Buildings :")
self.buildingsLayout = QGridLayout()
j = 0
for i, building in enumerate(self.buildings):
if building.dcs_identifier not in FORTIFICATION_BUILDINGS:
self.buildingsLayout.addWidget(QBuildingInfo(building, self.ground_object), j/3, j%3)
j = j + 1
self.buildingBox.setLayout(self.buildingsLayout)
self.intelBox.setLayout(self.intelLayout)
def do_refresh_layout(self):
try:
for i in range(self.mainLayout.count()):
self.mainLayout.removeItem(self.mainLayout.itemAt(i))
self.doLayout()
if len(self.ground_object.groups) > 0:
self.mainLayout.addWidget(self.intelBox)
else:
self.mainLayout.addWidget(self.buildingBox)
except Exception as e:
print(e)
def repair_unit(self, group, unit, price):
if self.game.budget > price:
self.game.budget -= price
group.units_losts = [u for u in group.units_losts if u.id != unit.id]
group.units.append(unit)
GameUpdateSignal.get_instance().updateGame(self.game)
# Remove destroyed units in the vicinity
destroyed_units = self.game.get_destroyed_units()
for d in destroyed_units:
p = Point(d["x"], d["z"])
if p.distance_to_point(unit.position) < 15:
destroyed_units.remove(d)
logging.info("Removed destroyed units " + str(d))
logging.info("Repaired unit : " + str(unit.id) + " " + str(unit.type))
self.do_refresh_layout()
def closeEvent(self, closeEvent: QCloseEvent):
GameUpdateSignal.get_instance().updateGame(self.game)

View File

@@ -24,7 +24,11 @@ class QLoadoutEditor(QGroupBox):
label = QLabel("<b>{}</b>".format(pylon.__name__[len("Pylon"):]))
label.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
layout.addWidget(label, i, 0)
layout.addWidget(QPylonEditor(flight, pylon, i+1), i, 1)
try:
pylon_number = int(pylon.__name__.split("Pylon")[1])
except:
pylon_number = i+1
layout.addWidget(QPylonEditor(flight, pylon, pylon_number), i, 1)
hboxLayout.addLayout(layout)
hboxLayout.addStretch()

View File

@@ -1,3 +1,5 @@
import logging
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
from PySide2.QtGui import QStandardItemModel, QStandardItem
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
@@ -269,32 +271,28 @@ class QSettingsWindow(QDialog):
self.moneyCheatBoxLayout = QGridLayout()
self.moneyCheatBox.setLayout(self.moneyCheatBoxLayout)
self.cheat25M = QPushButton("Cheat +25M")
self.cheat50M = QPushButton("Cheat +50M")
self.cheat100M = QPushButton("Cheat +100M")
self.cheat200M = QPushButton("Cheat +200M")
self.cheat500M = QPushButton("Cheat +500M")
self.cheat1000M = QPushButton("Cheat +1000M")
self.cheat25M.clicked.connect(lambda: self.cheatMoney(25))
self.cheat50M.clicked.connect(lambda: self.cheatMoney(50))
self.cheat100M.clicked.connect(lambda: self.cheatMoney(100))
self.cheat200M.clicked.connect(lambda: self.cheatMoney(200))
self.cheat500M.clicked.connect(lambda: self.cheatMoney(500))
self.cheat1000M.clicked.connect(lambda: self.cheatMoney(1000))
self.moneyCheatBoxLayout.addWidget(self.cheat25M, 0, 0)
self.moneyCheatBoxLayout.addWidget(self.cheat50M, 0, 1)
self.moneyCheatBoxLayout.addWidget(self.cheat100M, 1, 0)
self.moneyCheatBoxLayout.addWidget(self.cheat200M, 1, 1)
self.moneyCheatBoxLayout.addWidget(self.cheat500M, 2, 0)
self.moneyCheatBoxLayout.addWidget(self.cheat1000M, 2, 1)
cheats_amounts = [25, 50, 100, 200, 500, 1000, -25, -50, -100, -200]
for i, amount in enumerate(cheats_amounts):
if amount > 0:
btn = QPushButton("Cheat +" + str(amount) + "M")
btn.setProperty("style", "btn-success")
else:
btn = QPushButton("Cheat " + str(amount) + "M")
btn.setProperty("style", "btn-danger")
btn.clicked.connect(self.cheatLambda(amount))
self.moneyCheatBoxLayout.addWidget(btn, i/2, i%2)
self.cheatLayout.addWidget(self.moneyCheatBox, 0, 0)
def cheatLambda(self, amount):
return lambda: self.cheatMoney(amount)
def cheatMoney(self, amount):
logging.info("CHEATING FOR AMOUNT : " + str(amount) + "M")
self.game.budget += amount
self.game.informations.append(Information("CHEATER", "You are a cheater and you should feel bad", self.game.turn))
if amount > 0:
self.game.informations.append(Information("CHEATER", "You are a cheater and you should feel bad", self.game.turn))
else:
self.game.informations.append(Information("CHEATER", "You are still a cheater !", self.game.turn))
GameUpdateSignal.get_instance().updateGame(self.game)
def applySettings(self):

View File

@@ -1,4 +1,4 @@
pydcs>=0.9.10
#pydcs>=0.9.10
Pyside2>=5.13.0
pyinstaller==3.6
pyproj==2.6.1.post1

View File

@@ -0,0 +1,118 @@
local unitPayloads = {
["name"] = "AH-64A",
["payloads"] = {
[1] = {
["name"] = "CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
[3] = {
["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}",
["num"] = 2,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
[2] = {
["name"] = "STRIKE",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
[3] = {
["name"] = "CAP",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
[4] = {
["name"] = "ANTISHIP",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 3,
},
[3] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 2,
},
[4] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
[5] = {
["name"] = "SEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
},
["unitType"] = "AH-64A",
}
return unitPayloads

View File

@@ -0,0 +1,110 @@
local unitPayloads = {
["name"] = "AH-64D",
["payloads"] = {
[1] = {
["name"] = "CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
[2] = {
["name"] = "CAP",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
[3] = {
["name"] = "ANTISHIP",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
[3] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 2,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
[4] = {
["name"] = "SEAD",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
[5] = {
["name"] = "STRIKE",
["pylons"] = {
[1] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 4,
},
[2] = {
["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}",
["num"] = 1,
},
},
["tasks"] = {
[1] = 18,
[2] = 31,
[3] = 32,
[4] = 30,
},
},
},
["unitType"] = "AH-64D",
}
return unitPayloads

View File

@@ -2,53 +2,6 @@ local unitPayloads = {
["name"] = "F-16C_50",
["payloads"] = {
[1] = {
["name"] = "CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}",
["num"] = 5,
},
[2] = {
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
["num"] = 7,
},
[3] = {
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 2,
},
[5] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 1,
},
[6] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 8,
},
[7] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 9,
},
[8] = {
["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}",
["num"] = 4,
},
[9] = {
["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}",
["num"] = 6,
},
[10] = {
["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}",
["num"] = 11,
},
},
["tasks"] = {
},
},
[2] = {
["name"] = "ANTISHIP",
["pylons"] = {
[1] = {
@@ -91,7 +44,7 @@ local unitPayloads = {
["tasks"] = {
},
},
[3] = {
[2] = {
["name"] = "CAP",
["pylons"] = {
[1] = {
@@ -134,6 +87,53 @@ local unitPayloads = {
["tasks"] = {
},
},
[3] = {
["name"] = "CAS",
["pylons"] = {
[1] = {
["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}",
["num"] = 5,
},
[2] = {
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
["num"] = 7,
},
[3] = {
["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}",
["num"] = 3,
},
[4] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 2,
},
[5] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 1,
},
[6] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 8,
},
[7] = {
["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}",
["num"] = 9,
},
[8] = {
["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}",
["num"] = 4,
},
[9] = {
["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}",
["num"] = 6,
},
[11] = {
["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}",
["num"] = 11,
},
},
["tasks"] = {
},
},
[4] = {
["name"] = "STRIKE",
["pylons"] = {
@@ -173,6 +173,10 @@ local unitPayloads = {
["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}",
["num"] = 5,
},
[11] = {
["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}",
["num"] = 11,
},
},
["tasks"] = {
},

View File

@@ -486,3 +486,7 @@ QWidget[style="baseMenuHeader"]{
font-weight: bold;
color:white;
}*/
QLabel[style="small"]{
font-size: 8px;
}

View File

@@ -178,4 +178,8 @@ QLabel[style="SEAD"]{
QWidget[style="baseMenuHeader"]{
font-size: 24px;
font-weight: bold;
}*/
}*/
QLabel[style="small"]{
font-size: 8px;
}

View File

@@ -1,6 +1,6 @@
import os
import sys
import dcs
from pydcs import dcs
from game import db
from gen.aircraft import AircraftConflictGenerator

View File

@@ -45,7 +45,7 @@ def _mk_archieve():
shutil.rmtree("./dist")
except FileNotFoundError:
pass
os.system("pyinstaller.exe pyinstaller.spec")
os.system("pyinstaller.exe --clean pyinstaller.spec")
#archieve = ZipFile(path, "w")
#archieve.writestr("dcs_liberation.bat", "cd dist\\dcs_liberation\r\nliberation_main \"%UserProfile%\\Saved Games\" \"{}\"".format(VERSION))
#_zip_dir(archieve, "./dist/dcs_liberation")

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,6 +1,6 @@
import typing
import dcs
from pydcs import dcs
from dcs.mapping import Point
from .controlpoint import ControlPoint

View File

@@ -110,7 +110,7 @@ class SyrianCivilWar(SyriaTheater):
self.palmyra = ControlPoint.from_airport(syria.Palmyra, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
self.carrier = ControlPoint.carrier("Carrier", Point(18537, -52000), 1001)
self.lha = ControlPoint.lha("LHA", Point(116000, 30000), 1002)
self.lha = ControlPoint.lha("LHA", Point(116000, -30000), 1002)
self.add_controlpoint(self.basselAlAssad, connected_to=[self.hama])
self.add_controlpoint(self.marjruhayyil, connected_to=[self.aldumayr])
@@ -140,6 +140,7 @@ class InherentResolve(SyriaTheater):
super(InherentResolve, self).__init__()
self.kinghussein = ControlPoint.from_airport(syria.King_Hussein_Air_College, LAND, SIZE_REGULAR, IMPORTANCE_HIGH)
self.incirlik = ControlPoint.from_airport(syria.Incirlik, LAND, SIZE_REGULAR, IMPORTANCE_HIGH)
self.khalkhala = ControlPoint.from_airport(syria.Khalkhalah, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM)
self.palmyra = ControlPoint.from_airport(syria.Palmyra, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
self.jirah = ControlPoint.from_airport(syria.Jirah, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
@@ -149,6 +150,7 @@ class InherentResolve(SyriaTheater):
self.lha = ControlPoint.lha("LHA", Point(-131000, -161000), 1002)
self.add_controlpoint(self.kinghussein, connected_to=[self.khalkhala])
self.add_controlpoint(self.incirlik, connected_to=[self.incirlik])
self.add_controlpoint(self.khalkhala, connected_to=[self.kinghussein, self.palmyra])
self.add_controlpoint(self.palmyra, connected_to=[self.khalkhala, self.tabqa])
self.add_controlpoint(self.tabqa, connected_to=[self.palmyra, self.jirah])
@@ -158,10 +160,12 @@ class InherentResolve(SyriaTheater):
self.add_controlpoint(self.lha)
self.kinghussein.captured = True
self.incirlik.captured = True
self.carrier.captured = True
self.lha.captured = True
self.jirah.captured_invert = True
self.incirlik.captured_invert = True
self.carrier.captured_invert = True
self.lha.captured_invert = True
@@ -214,7 +218,7 @@ class SyriaFullMap(SyriaTheater):
self.carrier.captured = True
self.lha.captured = True
self.hatay.captured_invert = True
self.incirlik.captured_invert = True
self.carrier.captured_invert = True
self.lha.captured_invert = True

View File

@@ -2,7 +2,7 @@ import json
import os
from shutil import copyfile
import dcs
from pydcs import dcs
from userdata import persistency