mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
commit
f61e23153b
34
README.md
34
README.md
@ -1,9 +1,22 @@
|
||||

|
||||
|
||||
[DCS World](https://www.digitalcombatsimulator.com/en/products/world/) single-player semi dynamic campaign.
|
||||
[](https://github.com/Khopa/dcs_liberation/releases)
|
||||
[](https://www.paypal.com/paypalme/KhopaDCSL)
|
||||
[](https://discord.gg/bKrtrkJ)
|
||||
|
||||
DCS Liberation uses [pydcs](http://github.com/pydcs/dcs) for mission generation
|
||||
and [Mist](https://github.com/mrSkortch/MissionScriptingTools) for mission scripting
|
||||
[](https://github.com/Khopa/dcs_liberation)
|
||||
[](https://github.com/Khopa/dcs_liberation/issues)
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
## Downloads
|
||||
|
||||
Latest release is available here : https://github.com/Khopa/dcs_liberation/releases
|
||||
|
||||
## Resources
|
||||
|
||||
@ -11,15 +24,16 @@ and [Mist](https://github.com/mrSkortch/MissionScriptingTools) for mission scrip
|
||||
|
||||
* [Tutorials](https://github.com/Khopa/dcs_liberation/wiki/Tutorial-01-:-UI)
|
||||
|
||||
## Development Guide (WIP)
|
||||
* [Developer/Contributor Guide]()(TODO)
|
||||
|
||||
Develop is the main development branch which is updated regularly.
|
||||
Master branch will be updated less regularly and on release on new version.
|
||||
* [Hosting DCS Liberation generated missions on a dedicated server]()(TODO)
|
||||
|
||||
Other branch might be used for feature development.
|
||||
|
||||
**Note :**
|
||||
If you have errors with pydcs object not being defined, please check that you have the latest version installed. Sometimes the dev branch will use an even more recent version of pydcs that has not been published yet, so you might want to download pydcs directly from the pydcs repository, and copy it in your Python (or virtual env) ./Libs/site-package directory.
|
||||
## 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 !
|
||||
25
changelog.md
25
changelog.md
@ -1,3 +1,25 @@
|
||||
# 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]** 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 :
|
||||
@ -10,7 +32,7 @@
|
||||
* **[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
|
||||
* **[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.
|
||||
@ -19,6 +41,7 @@
|
||||
* **[Mission Generator]** The briefing will now contain the carrier ATC frequency
|
||||
* **[Mission Generator]** The briefing contains a small situation update.
|
||||
* **[Mission Generator]** Previously destroyed units are visible in the mission. (And added a performance settings to disable this behaviour)
|
||||
* **[Mission Generator]** Basic JTAC on Frontlines
|
||||
* **[Campaign Generator]** Added Tarawa in caucasus campaigns
|
||||
* **[Campaign Generator]** Tuned the various existing campaign parameters
|
||||
* **[Campaign Generator]** Added small campaign : "Russia" on Caucasus Theater
|
||||
|
||||
26
game/db.py
26
game/db.py
@ -31,7 +31,7 @@ from game.factions.israel_2000 import Israel_2000
|
||||
from game.factions.italy_1990 import Italy_1990
|
||||
from game.factions.italy_1990_mb339 import Italy_1990_MB339
|
||||
from game.factions.japan_2005 import Japan_2005
|
||||
from game.factions.libya_2011 import Lybia_2011
|
||||
from game.factions.libya_2011 import Libya_2011
|
||||
from game.factions.netherlands_1990 import Netherlands_1990
|
||||
from game.factions.north_korea_2000 import NorthKorea_2000
|
||||
from game.factions.pakistan_2015 import Pakistan_2015
|
||||
@ -166,13 +166,14 @@ PRICES = {
|
||||
|
||||
AV8BNA: 14,
|
||||
M_2000C: 16,
|
||||
Mirage_2000_5: 22,
|
||||
FA_18C_hornet: 24,
|
||||
F_15C: 26,
|
||||
Mirage_2000_5: 20,
|
||||
FA_18C_hornet: 22,
|
||||
F_15C: 22,
|
||||
F_15E: 24,
|
||||
F_16C_50: 20,
|
||||
F_14B: 22,
|
||||
Tornado_IDS: 24,
|
||||
Tornado_GR4: 24,
|
||||
F_14B: 24,
|
||||
Tornado_IDS: 20,
|
||||
Tornado_GR4: 20,
|
||||
|
||||
# bomber
|
||||
Su_17M4: 10,
|
||||
@ -396,6 +397,7 @@ UNIT_BY_TASK = {
|
||||
MiG_21Bis,
|
||||
MiG_29A,
|
||||
MiG_29S,
|
||||
MiG_31,
|
||||
FA_18C_hornet,
|
||||
F_15C,
|
||||
F_14B,
|
||||
@ -420,6 +422,7 @@ UNIT_BY_TASK = {
|
||||
SA342Mistral
|
||||
],
|
||||
CAS: [
|
||||
F_15E,
|
||||
F_86F_Sabre,
|
||||
MiG_15bis,
|
||||
L_39ZA,
|
||||
@ -756,7 +759,7 @@ FACTIONS = {
|
||||
|
||||
"Netherlands 1990": Netherlands_1990,
|
||||
|
||||
"United Kingdown 1990": UnitedKingdom_1990,
|
||||
"United Kingdom 1990": UnitedKingdom_1990,
|
||||
|
||||
"Spain 1990": Spain_1990,
|
||||
|
||||
@ -783,7 +786,7 @@ FACTIONS = {
|
||||
|
||||
"India 2010": India_2010,
|
||||
|
||||
"Lybia 2011": Lybia_2011,
|
||||
"Libya 2011": Libya_2011,
|
||||
|
||||
"Pakistan 2015": Pakistan_2015,
|
||||
|
||||
@ -872,6 +875,7 @@ PLANE_PAYLOAD_OVERRIDES = {
|
||||
F_5E_3: COMMON_OVERRIDE,
|
||||
F_14B: COMMON_OVERRIDE,
|
||||
F_15C: COMMON_OVERRIDE,
|
||||
F_15E: COMMON_OVERRIDE,
|
||||
F_16C_50: COMMON_OVERRIDE,
|
||||
JF_17: COMMON_OVERRIDE,
|
||||
M_2000C: COMMON_OVERRIDE,
|
||||
@ -899,6 +903,8 @@ PLANE_PAYLOAD_OVERRIDES = {
|
||||
SA342L:COMMON_OVERRIDE,
|
||||
SA342Mistral:COMMON_OVERRIDE,
|
||||
Mi_8MT:COMMON_OVERRIDE,
|
||||
Mi_24V:COMMON_OVERRIDE,
|
||||
Mi_28N:COMMON_OVERRIDE,
|
||||
Ka_50:COMMON_OVERRIDE,
|
||||
L_39ZA:COMMON_OVERRIDE,
|
||||
L_39C:COMMON_OVERRIDE,
|
||||
@ -942,8 +948,6 @@ PLANE_LIVERY_OVERRIDES = {
|
||||
FA_18C_hornet: "VFA-34", # default livery for the hornet is blue angels one
|
||||
}
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Possible time periods for new games
|
||||
|
||||
|
||||
@ -65,25 +65,10 @@ class Event:
|
||||
else:
|
||||
return self.departure_cp
|
||||
|
||||
@property
|
||||
def threat_description(self) -> str:
|
||||
return ""
|
||||
|
||||
def flight_name(self, for_task: typing.Type[typing.Type[Task]]) -> str:
|
||||
return "Flight"
|
||||
|
||||
@property
|
||||
def tasks(self) -> typing.Collection[typing.Type[Task]]:
|
||||
return []
|
||||
|
||||
@property
|
||||
def ai_banned_tasks(self) -> typing.Collection[typing.Type[Task]]:
|
||||
return []
|
||||
|
||||
@property
|
||||
def player_banned_tasks(self) -> typing.Collection[typing.Type[Task]]:
|
||||
return []
|
||||
|
||||
@property
|
||||
def global_cp_available(self) -> bool:
|
||||
return False
|
||||
@ -255,7 +240,6 @@ class Event:
|
||||
|
||||
# Destroyed units carcass
|
||||
# -------------------------
|
||||
|
||||
for destroyed_unit in debriefing.destroyed_units:
|
||||
self.game.add_destroyed_units(destroyed_unit)
|
||||
|
||||
|
||||
@ -4,16 +4,6 @@ from userdata.debriefing import Debriefing
|
||||
|
||||
|
||||
class FrontlineAttackEvent(Event):
|
||||
TARGET_VARIETY = 2
|
||||
TARGET_AMOUNT_FACTOR = 0.5
|
||||
ATTACKER_AMOUNT_FACTOR = 0.4
|
||||
ATTACKER_DEFENDER_FACTOR = 0.7
|
||||
STRENGTH_INFLUENCE = 0.3
|
||||
SUCCESS_FACTOR = 1.5
|
||||
|
||||
@property
|
||||
def threat_description(self):
|
||||
return "{} vehicles".format(self.to_cp.base.assemble_count())
|
||||
|
||||
@property
|
||||
def tasks(self) -> typing.Collection[typing.Type[Task]]:
|
||||
@ -26,32 +16,11 @@ class FrontlineAttackEvent(Event):
|
||||
def global_cp_available(self) -> bool:
|
||||
return True
|
||||
|
||||
def flight_name(self, for_task: typing.Type[Task]) -> str:
|
||||
if for_task == CAS:
|
||||
return "CAS flight"
|
||||
elif for_task == CAP:
|
||||
return "CAP flight"
|
||||
elif for_task == PinpointStrike:
|
||||
return "Ground attack"
|
||||
|
||||
def __str__(self):
|
||||
return "Frontline attack"
|
||||
|
||||
def is_successfull(self, debriefing: Debriefing):
|
||||
|
||||
if self.game.player_name == self.attacker_name:
|
||||
attacker_country = self.game.player_country
|
||||
defender_country = self.game.enemy_country
|
||||
else:
|
||||
attacker_country = self.game.enemy_country
|
||||
defender_country = self.game.player_country
|
||||
|
||||
# TODO : Rework
|
||||
#alive_attackers = sum([v for k, v in debriefing.alive_units.get(attacker_country, {}).items() if db.unit_task(k) == PinpointStrike])
|
||||
#alive_defenders = sum([v for k, v in debriefing.alive_units.get(defender_country, {}).items() if db.unit_task(k) == PinpointStrike])
|
||||
#attackers_success = (float(alive_attackers) / (alive_defenders + 0.01)) > self.SUCCESS_FACTOR
|
||||
attackers_success = True
|
||||
|
||||
if self.from_cp.captured:
|
||||
return attackers_success
|
||||
else:
|
||||
@ -65,46 +34,20 @@ class FrontlineAttackEvent(Event):
|
||||
self.to_cp.base.affect_strength(-0.1)
|
||||
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
# assert CAS in flights and CAP in flights and len(flights) == 2, "Invalid flights"
|
||||
|
||||
op = FrontlineAttackOperation(game=self.game,
|
||||
attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
from_cp=self.from_cp,
|
||||
departure_cp=self.departure_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
defenders = self.to_cp.base.assemble_attack()
|
||||
max_attackers = int(math.ceil(sum(defenders.values()) * self.ATTACKER_DEFENDER_FACTOR))
|
||||
attackers = db.unitdict_restrict_count(self.from_cp.base.assemble_attack(), max_attackers)
|
||||
op.setup(defenders=defenders,
|
||||
attackers=attackers,
|
||||
strikegroup=flights[CAS],
|
||||
escort=flights[CAP],
|
||||
interceptors=assigned_units_from(self.to_cp.base.scramble_interceptors(1)))
|
||||
|
||||
self.operation = op
|
||||
|
||||
def player_defending(self, flights: db.TaskForceDict):
|
||||
# assert CAP in flights and len(flights) == 1, "Invalid flights"
|
||||
|
||||
op = FrontlineAttackOperation(game=self.game,
|
||||
attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
from_cp=self.from_cp,
|
||||
departure_cp=self.departure_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
defenders = self.to_cp.base.assemble_attack()
|
||||
|
||||
max_attackers = int(math.ceil(sum(defenders.values())))
|
||||
attackers = db.unitdict_restrict_count(self.from_cp.base.assemble_attack(), max_attackers)
|
||||
|
||||
op.setup(defenders=defenders,
|
||||
attackers=attackers,
|
||||
strikegroup=assigned_units_from(self.from_cp.base.scramble_cas(1)),
|
||||
escort=assigned_units_from(self.from_cp.base.scramble_sweep(1)),
|
||||
interceptors=flights[CAP])
|
||||
|
||||
self.operation = op
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@ from dcs.helicopters import *
|
||||
from dcs.planes import *
|
||||
from dcs.vehicles import *
|
||||
|
||||
Lybia_2011 = {
|
||||
"country": "Lybia",
|
||||
Libya_2011 = {
|
||||
"country": "Libya",
|
||||
"side": "red",
|
||||
"units": [
|
||||
|
||||
|
||||
@ -7,12 +7,14 @@ Russia_2010 = {
|
||||
"country": "Russia",
|
||||
"side": "red",
|
||||
"units": [
|
||||
MiG_23MLD,
|
||||
Su_25,
|
||||
|
||||
Su_27,
|
||||
Su_30,
|
||||
Su_33,
|
||||
MiG_29S,
|
||||
MiG_31,
|
||||
|
||||
Su_25,
|
||||
Su_25T,
|
||||
Su_34,
|
||||
Su_24M,
|
||||
@ -27,6 +29,8 @@ Russia_2010 = {
|
||||
|
||||
Ka_50,
|
||||
Mi_8MT,
|
||||
Mi_24V,
|
||||
Mi_28N,
|
||||
|
||||
AirDefence.SAM_SA_19_Tunguska_2S6,
|
||||
AirDefence.SAM_SA_11_Buk_LN_9A310M1,
|
||||
|
||||
@ -8,6 +8,7 @@ USA_1990 = {
|
||||
"side": "blue",
|
||||
"units": [
|
||||
F_15C,
|
||||
F_15E,
|
||||
F_14B,
|
||||
FA_18C_hornet,
|
||||
|
||||
@ -23,6 +24,7 @@ USA_1990 = {
|
||||
|
||||
UH_1H,
|
||||
AH_64A,
|
||||
OH_58D,
|
||||
|
||||
Armor.MBT_M1A2_Abrams,
|
||||
Armor.IFV_LAV_25,
|
||||
|
||||
@ -8,6 +8,7 @@ USA_2005 = {
|
||||
"side": "blue",
|
||||
"units": [
|
||||
F_15C,
|
||||
F_15E,
|
||||
F_14B,
|
||||
FA_18C_hornet,
|
||||
F_16C_50,
|
||||
@ -21,6 +22,7 @@ USA_2005 = {
|
||||
|
||||
UH_1H,
|
||||
AH_64D,
|
||||
OH_58D,
|
||||
|
||||
Armor.MBT_M1A2_Abrams,
|
||||
Armor.ATGM_M1134_Stryker,
|
||||
|
||||
@ -378,8 +378,10 @@ class Game:
|
||||
|
||||
return points
|
||||
|
||||
def add_destroyed_units(self, destroyed_unit_data):
|
||||
self.__destroyed_units.append(destroyed_unit_data)
|
||||
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
|
||||
|
||||
@ -14,19 +14,6 @@ class FrontlineAttackOperation(Operation):
|
||||
attackers = None # type: db.ArmorDict
|
||||
defenders = None # type: db.ArmorDict
|
||||
|
||||
def setup(self,
|
||||
defenders: db.ArmorDict,
|
||||
attackers: db.ArmorDict,
|
||||
strikegroup: db.AssignedUnitsDict,
|
||||
escort: db.AssignedUnitsDict,
|
||||
interceptors: db.AssignedUnitsDict):
|
||||
self.strikegroup = strikegroup
|
||||
self.escort = escort
|
||||
self.interceptors = interceptors
|
||||
|
||||
self.defenders = defenders
|
||||
self.attackers = attackers
|
||||
|
||||
def prepare(self, terrain: Terrain, is_quick: bool):
|
||||
super(FrontlineAttackOperation, self).prepare(terrain, is_quick)
|
||||
if self.defender_name == self.game.player_name:
|
||||
|
||||
@ -72,9 +72,6 @@ class Operation:
|
||||
self.groundobjectgen = GroundObjectsGenerator(mission, conflict, self.game)
|
||||
self.briefinggen = BriefingGenerator(mission, conflict, self.game)
|
||||
|
||||
player_country = self.from_cp.captured and self.attacker_country or self.defender_country
|
||||
enemy_country = self.from_cp.captured and self.defender_country or self.attacker_country
|
||||
|
||||
def prepare(self, terrain: Terrain, is_quick: bool):
|
||||
with open("resources/default_options.lua", "r") as f:
|
||||
options_dict = loads(f.read())["options"]
|
||||
@ -202,8 +199,14 @@ class Operation:
|
||||
|
||||
script = f.read()
|
||||
script = script + "\n"
|
||||
|
||||
smoke = "true"
|
||||
if hasattr(self.game.settings, "jtac_smoke_on"):
|
||||
if not self.game.settings.jtac_smoke_on:
|
||||
smoke = "false"
|
||||
|
||||
for jtac in self.game.jtacs:
|
||||
script = script + "\n" + "JTACAutoLase('" + str(jtac[2]) + "', " + str(jtac[1]) + ", true, \"vehicle\")" + "\n"
|
||||
script = script + "\n" + "JTACAutoLase('" + str(jtac[2]) + "', " + str(jtac[1]) + ", " + smoke + ", \"vehicle\")" + "\n"
|
||||
|
||||
load_autolase.add_action(DoScript(String(script)))
|
||||
self.current_mission.triggerrules.triggers.append(load_autolase)
|
||||
|
||||
@ -25,6 +25,7 @@ class Settings:
|
||||
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
|
||||
|
||||
@ -431,6 +431,7 @@ class AircraftConflictGenerator:
|
||||
group.points[0].tasks.append(OptRestrictJettison(True))
|
||||
|
||||
group.points[0].tasks.append(OptRTBOnBingoFuel(True))
|
||||
group.points[0].tasks.append(OptRestrictAfterburner(True))
|
||||
|
||||
if hasattr(flight.unit_type, 'eplrs'):
|
||||
if flight.unit_type.eplrs:
|
||||
|
||||
@ -53,7 +53,7 @@ class AirSupportConflictGenerator:
|
||||
|
||||
if tanker_unit_type != IL_78M:
|
||||
tanker_group.points[0].tasks.pop() # Override PyDCS tacan channel
|
||||
tanker_group.points[0].tasks.append(ActivateBeaconCommand(97+1, "X", CALLSIGNS[i], True, tanker_group.units[0].id, True))
|
||||
tanker_group.points[0].tasks.append(ActivateBeaconCommand(60 + i, "X", CALLSIGNS[i], True, tanker_group.units[0].id, True))
|
||||
|
||||
tanker_group.points[0].tasks.append(SetInvisibleCommand(True))
|
||||
tanker_group.points[0].tasks.append(SetImmortalCommand(True))
|
||||
|
||||
@ -100,16 +100,16 @@ class GroundConflictGenerator:
|
||||
# Add JTAC
|
||||
if "has_jtac" in self.game.player_faction and self.game.player_faction["has_jtac"] and self.game.settings.include_jtac_if_available:
|
||||
n = "JTAC" + str(self.conflict.from_cp.id) + str(self.conflict.to_cp.id)
|
||||
code = 1688 + len(self.game.jtacs)
|
||||
code = 1688 - len(self.game.jtacs)
|
||||
jtac = self.mission.flight_group(country=self.mission.country(self.game.player_country),
|
||||
name=n,
|
||||
aircraft_type=MQ_9_Reaper,
|
||||
position=position[0],
|
||||
airport=None,
|
||||
altitude=5000)
|
||||
jtac.points[0].tasks.append(OrbitAction(5000, 300, OrbitAction.OrbitPattern.Circle))
|
||||
jtac.points[0].tasks.append(SetInvisibleCommand(True))
|
||||
jtac.points[0].tasks.append(SetImmortalCommand(True))
|
||||
jtac.points[0].tasks.append(OrbitAction(5000, 300, OrbitAction.OrbitPattern.Circle))
|
||||
self.game.jtacs.append(("Frontline " + self.conflict.from_cp.name + "/" + self.conflict.to_cp.name, code, n))
|
||||
|
||||
def gen_infantry_group_for_group(self, group, is_player, side:Country, forward_heading):
|
||||
|
||||
@ -34,6 +34,7 @@ CAP_CAPABLE = [
|
||||
MiG_29A,
|
||||
MiG_29G,
|
||||
MiG_29S,
|
||||
MiG_31,
|
||||
|
||||
Su_27,
|
||||
J_11A,
|
||||
@ -49,6 +50,7 @@ CAP_CAPABLE = [
|
||||
F_5E_3,
|
||||
F_14B,
|
||||
F_15C,
|
||||
F_15E,
|
||||
F_16C_50,
|
||||
FA_18C_hornet,
|
||||
|
||||
@ -97,6 +99,7 @@ CAS_CAPABLE = [
|
||||
F_86F_Sabre,
|
||||
F_5E_3,
|
||||
F_14B,
|
||||
F_15E,
|
||||
F_16C_50,
|
||||
FA_18C_hornet,
|
||||
|
||||
@ -107,6 +110,7 @@ CAS_CAPABLE = [
|
||||
|
||||
SA342M,
|
||||
SA342L,
|
||||
OH_58D,
|
||||
|
||||
AH_64A,
|
||||
AH_64D,
|
||||
@ -138,6 +142,7 @@ CAS_CAPABLE = [
|
||||
SEAD_CAPABLE = [
|
||||
F_4E,
|
||||
FA_18C_hornet,
|
||||
F_15E,
|
||||
# F_16C_50, Not yet
|
||||
AV8BNA,
|
||||
JF_17,
|
||||
@ -178,6 +183,7 @@ STRIKE_CAPABLE = [
|
||||
F_86F_Sabre,
|
||||
F_5E_3,
|
||||
F_14B,
|
||||
F_15E,
|
||||
F_16C_50,
|
||||
FA_18C_hornet,
|
||||
|
||||
@ -207,6 +213,7 @@ ANTISHIP_CAPABLE = [
|
||||
Su_24M,
|
||||
Su_17M4,
|
||||
F_A_18C,
|
||||
F_15E,
|
||||
AV8BNA,
|
||||
JF_17,
|
||||
F_16C_50,
|
||||
|
||||
@ -46,6 +46,22 @@ class TriggersGenerator:
|
||||
"""
|
||||
Set airbase initial coalition
|
||||
"""
|
||||
|
||||
# Empty neutrals airports
|
||||
cp_ids = [cp.id for cp in self.game.theater.controlpoints]
|
||||
for airport in self.mission.terrain.airport_list():
|
||||
if airport.id not in cp_ids:
|
||||
airport.unlimited_fuel = False
|
||||
airport.unlimited_munitions = False
|
||||
airport.unlimited_aircrafts = False
|
||||
airport.gasoline_init = 0
|
||||
airport.methanol_mixture_init = 0
|
||||
airport.diesel_init = 0
|
||||
airport.jet_init = 0
|
||||
airport.operating_level_air = 0
|
||||
airport.operating_level_equipment = 0
|
||||
airport.operating_level_fuel = 0
|
||||
|
||||
for cp in self.game.theater.controlpoints:
|
||||
if cp.is_global:
|
||||
continue
|
||||
|
||||
@ -15,7 +15,6 @@ from game.event import UnitsDeliveryEvent, Event, ControlPointType
|
||||
from gen import Conflict
|
||||
from qt_ui.widgets.map.QLiberationScene import QLiberationScene
|
||||
from qt_ui.widgets.map.QMapControlPoint import QMapControlPoint
|
||||
from qt_ui.widgets.map.QMapEvent import QMapEvent
|
||||
from qt_ui.widgets.map.QMapGroundObject import QMapGroundObject
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from theater import ControlPoint
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
from PySide2.QtGui import QPen, Qt
|
||||
from PySide2.QtWidgets import QGraphicsRectItem, QGraphicsSceneMouseEvent, QGraphicsSceneHoverEvent
|
||||
|
||||
import qt_ui.uiconstants as CONST
|
||||
from game.event import Event, UnitsDeliveryEvent
|
||||
from qt_ui.windows.QBriefingWindow import QBriefingWindow
|
||||
|
||||
|
||||
class QMapEvent(QGraphicsRectItem):
|
||||
|
||||
def __init__(self, parent, x: float, y: float, w: float, h: float, gameEvent: Event):
|
||||
super(QMapEvent, self).__init__(x, y, w, h)
|
||||
self.gameEvent = gameEvent
|
||||
self.parent = parent
|
||||
self.setAcceptHoverEvents(True)
|
||||
self.setZValue(2)
|
||||
self.setToolTip(str(self.gameEvent))
|
||||
self.playable = not isinstance(self.gameEvent, UnitsDeliveryEvent)
|
||||
|
||||
|
||||
|
||||
def paint(self, painter, option, widget=None):
|
||||
|
||||
playerColor = self.game.get_player_color()
|
||||
enemyColor = self.game.get_enemy_color()
|
||||
|
||||
if self.parent.get_display_rule("events"):
|
||||
painter.save()
|
||||
|
||||
if self.gameEvent.is_player_attacking:
|
||||
painter.setPen(QPen(brush=CONST.COLORS[playerColor]))
|
||||
painter.setBrush(CONST.COLORS[playerColor])
|
||||
else:
|
||||
painter.setPen(QPen(brush=CONST.COLORS[enemyColor]))
|
||||
painter.setBrush(CONST.COLORS[enemyColor])
|
||||
|
||||
if self.isUnderMouse() and self.playable:
|
||||
painter.setBrush(CONST.COLORS["white"])
|
||||
|
||||
painter.drawRect(option.rect)
|
||||
painter.drawPixmap(option.rect, CONST.EVENT_ICONS[self.gameEvent.__class__])
|
||||
painter.restore()
|
||||
|
||||
def mousePressEvent(self, event:QGraphicsSceneMouseEvent):
|
||||
if self.parent.get_display_rule("events"):
|
||||
self.openBriefing()
|
||||
|
||||
def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent):
|
||||
self.update()
|
||||
if self.playable:
|
||||
self.setCursor(Qt.PointingHandCursor)
|
||||
|
||||
def openBriefing(self):
|
||||
if self.playable:
|
||||
self.briefing = QBriefingWindow(self.gameEvent)
|
||||
self.briefing.show()
|
||||
@ -1,283 +0,0 @@
|
||||
import os
|
||||
|
||||
from PySide2.QtGui import QWindow
|
||||
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget, QDialog, QVBoxLayout, QGridLayout, QGroupBox, QCheckBox, \
|
||||
QSpinBox, QPushButton, QMessageBox, QComboBox
|
||||
from pip._internal.utils import typing
|
||||
|
||||
from game.game import AWACS_BUDGET_COST, PinpointStrike, db, Event, FrontlineAttackEvent, Task, \
|
||||
UnitType
|
||||
from qt_ui.windows.QWaitingForMissionResultWindow import QWaitingForMissionResultWindow
|
||||
from userdata.persistency import base_path
|
||||
import qt_ui.uiconstants as CONST
|
||||
|
||||
|
||||
class QBriefingWindow(QDialog):
|
||||
|
||||
def __init__(self, gameEvent: Event):
|
||||
super(QBriefingWindow, self).__init__()
|
||||
self.gameEvent = gameEvent
|
||||
self.setWindowTitle("Briefing : " + str(gameEvent))
|
||||
self.setMinimumSize(200,200)
|
||||
self.setWindowIcon(CONST.EVENT_ICONS[self.gameEvent.__class__])
|
||||
self.setModal(True)
|
||||
self.game = self.gameEvent.game
|
||||
|
||||
if self.gameEvent.attacker_name == self.game.player_name:
|
||||
self.base = self.gameEvent.from_cp.base
|
||||
self.playerFromCp = self.gameEvent.from_cp
|
||||
else:
|
||||
self.base = self.gameEvent.to_cp.base
|
||||
self.playerFromCp = self.gameEvent.to_cp
|
||||
|
||||
self.scramble_entries = {k: {} for k in self.gameEvent.tasks}
|
||||
self.initUi()
|
||||
|
||||
def initUi(self):
|
||||
|
||||
self.layout = QVBoxLayout()
|
||||
|
||||
self.depart_box = QGroupBox("Departure")
|
||||
self.depart_layout = QHBoxLayout()
|
||||
self.depart_box.setLayout(self.depart_layout)
|
||||
self.depart_from_label = QLabel("Depart from : ")
|
||||
self.depart_from = QComboBox()
|
||||
|
||||
for i, cp in enumerate([b for b in self.game.theater.controlpoints if b.captured]):
|
||||
self.depart_from.addItem(str(cp.name), cp)
|
||||
if cp.name == self.playerFromCp.name:
|
||||
self.depart_from.setCurrentIndex(i)
|
||||
|
||||
self.depart_from.currentTextChanged.connect(self.on_departure_cp_changed)
|
||||
self.depart_layout.addWidget(self.depart_from_label)
|
||||
self.depart_layout.addWidget(self.depart_from)
|
||||
|
||||
# Mission Description
|
||||
self.gridLayout = QGridLayout()
|
||||
self.initUnitRows()
|
||||
self.scramble_box = QGroupBox("Units")
|
||||
self.scramble_box.setLayout(self.gridLayout)
|
||||
|
||||
self.action_layout = QHBoxLayout()
|
||||
self.commit_button = QPushButton("Commit")
|
||||
self.back_button = QPushButton("Cancel")
|
||||
self.commit_button.clicked.connect(self.start)
|
||||
self.back_button.clicked.connect(self.close)
|
||||
self.action_layout.addWidget(self.commit_button)
|
||||
self.action_layout.addWidget(self.back_button)
|
||||
|
||||
self.support_box = self.initSupportBox()
|
||||
self.layout.addWidget(QLabel("<h2>{} on {}</h2>".format(self.gameEvent, self.gameEvent.to_cp.name)))
|
||||
self.layout.addWidget(self.depart_box)
|
||||
self.layout.addWidget(self.scramble_box)
|
||||
self.layout.addWidget(self.support_box)
|
||||
self.layout.addWidget(QLabel("<b>Ready?</b>"))
|
||||
self.layout.addLayout(self.action_layout)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def initUnitRows(self):
|
||||
|
||||
row = 0
|
||||
|
||||
def header(text, row):
|
||||
self.gridLayout.addWidget(QLabel("<b>" + text + "</b>"), row, 0, 1, 2)
|
||||
|
||||
def scramble_row(task_type, unit_type, unit_count, client_slots: bool, row: int):
|
||||
unit_name = QLabel("{} ({})".format(db.unit_type_name(unit_type), unit_count))
|
||||
self.gridLayout.addWidget(unit_name, row, 0)
|
||||
|
||||
scramble_entry = QSpinBox()
|
||||
self.gridLayout.addWidget(scramble_entry, row, 1)
|
||||
|
||||
if client_slots:
|
||||
client_entry = QSpinBox()
|
||||
self.gridLayout.addWidget(client_entry, row, 2)
|
||||
else:
|
||||
client_entry = None
|
||||
|
||||
self.scramble_entries[task_type][unit_type] = scramble_entry, client_entry
|
||||
|
||||
# Table headers
|
||||
self.gridLayout.addWidget(QLabel("Amount"), row, 1)
|
||||
self.gridLayout.addWidget(QLabel("Client slots"), row, 2)
|
||||
row += 1
|
||||
|
||||
for flight_task in self.gameEvent.tasks:
|
||||
header("{}:".format(self.gameEvent.flight_name(flight_task)), row)
|
||||
row += 1
|
||||
|
||||
if flight_task == PinpointStrike:
|
||||
if not self.base.armor:
|
||||
self.gridLayout.addWidget(QLabel("No units"), row, 1)
|
||||
row += 1
|
||||
for t, c in self.base.armor.items():
|
||||
scramble_row(flight_task, t, c, False, row)
|
||||
row += 1
|
||||
else:
|
||||
if not self.base.aircraft:
|
||||
self.gridLayout.addWidget(QLabel("No units"), row, 1)
|
||||
row += 1
|
||||
for t, c in self.base.aircraft.items():
|
||||
scramble_row(flight_task, t, c, t.flyable, row)
|
||||
row += 1
|
||||
|
||||
return self.gridLayout
|
||||
|
||||
def initSupportBox(self):
|
||||
|
||||
self.support_box = QGroupBox("Support")
|
||||
self.support_layout = QGridLayout()
|
||||
self.support_box.setLayout(self.support_layout)
|
||||
|
||||
self.awacs_label = QLabel("AWACS ({}m)".format(AWACS_BUDGET_COST))
|
||||
self.awacs_checkbox = QCheckBox()
|
||||
|
||||
self.ca_slot_label = QLabel("Combined Arms Slots")
|
||||
self.ca_slot_entry = QSpinBox()
|
||||
self.ca_slot_entry.setValue(0)
|
||||
self.ca_slot_entry.setMinimum(0)
|
||||
self.ca_slot_entry.setMaximum(32)
|
||||
|
||||
self.support_layout.addWidget(self.awacs_label, 0, 0)
|
||||
self.support_layout.addWidget(self.awacs_checkbox, 0, 1)
|
||||
self.support_layout.addWidget(self.ca_slot_label, 1, 0)
|
||||
self.support_layout.addWidget(self.ca_slot_entry, 1, 1)
|
||||
return self.support_box
|
||||
|
||||
|
||||
def initWaitingForResults(self):
|
||||
|
||||
layout = QVBoxLayout()
|
||||
|
||||
layout.addWidget(QLabel("<b>You are clear for takeoff</b>"))
|
||||
layout.addWidget(QLabel("In DCS open and play the mission : "))
|
||||
layout.addWidget(QLabel("<i>liberation_nextturn</i>"))
|
||||
layout.addWidget(QLabel("or"))
|
||||
layout.addWidget(QLabel("<i>liberation_nextturn_quick</i>"))
|
||||
|
||||
layout.addWidget(QLabel("<b>Then save the debriefing to folder :</b>"))
|
||||
layout.addWidget(QLabel("Then save the debriefing to the folder:"))
|
||||
layout.addWidget(QLabel("<i>" + self.debriefing_directory_location() + "</i>"))
|
||||
layout.addWidget(QLabel("Waiting for results..."))
|
||||
|
||||
# layout.addWidget(QLabel("In DCS open and play the mission : "))
|
||||
# layout.addWidget(QLabel("<b>You are clear for takeoff</b>"))
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
pass
|
||||
|
||||
def debriefing_directory_location(self) -> str:
|
||||
return os.path.join(base_path(), "liberation_debriefings")
|
||||
|
||||
def start(self):
|
||||
|
||||
if self.awacs_checkbox.isChecked() == 1:
|
||||
self.gameEvent.is_awacs_enabled = True
|
||||
self.game.awacs_expense_commit()
|
||||
else:
|
||||
self.gameEvent.is_awacs_enabled = False
|
||||
|
||||
ca_slot_entry_value = self.ca_slot_entry.value()
|
||||
try:
|
||||
ca_slots = int(ca_slot_entry_value and ca_slot_entry_value or "0")
|
||||
except:
|
||||
ca_slots = 0
|
||||
self.gameEvent.ca_slots = ca_slots
|
||||
|
||||
|
||||
# Resolve Departure CP
|
||||
self.gameEvent.departure_cp = self.depart_from.itemData(self.depart_from.currentIndex())
|
||||
|
||||
|
||||
flights = {k: {} for k in self.gameEvent.tasks} # type: db.TaskForceDict
|
||||
units_scramble_counts = {} # type: typing.Dict[typing.Type[UnitType], int]
|
||||
tasks_scramble_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
||||
tasks_clients_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
||||
|
||||
def dampen_count(unit_type, count: int) -> int:
|
||||
nonlocal units_scramble_counts
|
||||
total_count = self.base.total_units_of_type(unit_type)
|
||||
|
||||
total_scrambled = units_scramble_counts.get(unit_type, 0)
|
||||
dampened_value = count if count + total_scrambled < total_count else total_count - total_scrambled
|
||||
units_scramble_counts[unit_type] = units_scramble_counts.get(unit_type, 0) + dampened_value
|
||||
|
||||
return dampened_value
|
||||
|
||||
for task_type, dict in self.scramble_entries.items():
|
||||
for unit_type, (count_entry, clients_entry) in dict.items():
|
||||
try:
|
||||
count = int(count_entry.value())
|
||||
except:
|
||||
count = 0
|
||||
|
||||
try:
|
||||
clients_count = int(clients_entry and clients_entry.value() or 0)
|
||||
except:
|
||||
clients_count = 0
|
||||
|
||||
dampened_count = dampen_count(unit_type, count)
|
||||
tasks_clients_counts[task_type] = tasks_clients_counts.get(task_type, 0) + clients_count
|
||||
tasks_scramble_counts[task_type] = tasks_scramble_counts.get(task_type, 0) + dampened_count
|
||||
|
||||
flights[task_type][unit_type] = dampened_count, clients_count
|
||||
|
||||
for task in self.gameEvent.ai_banned_tasks:
|
||||
if tasks_clients_counts.get(task, 0) == 0 and tasks_scramble_counts.get(task, 0) > 0:
|
||||
self.showErrorMessage("Need at least one player in flight {}".format(self.gameEvent.flight_name(task)))
|
||||
return
|
||||
|
||||
for task in self.gameEvent.player_banned_tasks:
|
||||
if tasks_clients_counts.get(task, 0) != 0:
|
||||
self.showErrorMessage("Players are not allowed on flight {}".format(self.gameEvent.flight_name(task)))
|
||||
return
|
||||
|
||||
if self.game.is_player_attack(self.gameEvent):
|
||||
if isinstance(self.gameEvent, FrontlineAttackEvent):
|
||||
if self.base.total_armor == 0:
|
||||
self.showErrorMessage("No ground vehicles available to attack!")
|
||||
return
|
||||
|
||||
self.gameEvent.player_attacking(flights)
|
||||
else:
|
||||
if isinstance(self.gameEvent, FrontlineAttackEvent):
|
||||
if self.gameEvent.to_cp.base.total_armor == 0:
|
||||
self.showErrorMessage("No ground vehicles available to defend!")
|
||||
return
|
||||
|
||||
self.gameEvent.player_defending(flights)
|
||||
|
||||
self.game.initiate_event(self.gameEvent)
|
||||
|
||||
waiting = QWaitingForMissionResultWindow(self.gameEvent, self.game)
|
||||
waiting.show()
|
||||
|
||||
self.close()
|
||||
|
||||
def showErrorMessage(self, text):
|
||||
about = QMessageBox()
|
||||
about.setWindowTitle("Error")
|
||||
about.setIcon(QMessageBox.Icon.Critical)
|
||||
about.setText(text)
|
||||
about.exec_()
|
||||
|
||||
def on_departure_cp_changed(self):
|
||||
|
||||
selectedBase = self.depart_from.itemData(self.depart_from.currentIndex())
|
||||
|
||||
for i, cp in enumerate([b for b in self.game.theater.controlpoints if b.captured]):
|
||||
if cp.name == selectedBase.name:
|
||||
self.base = cp.base
|
||||
self.playerFromCp = cp
|
||||
break
|
||||
|
||||
# Clear current selection
|
||||
self.scramble_entries = {k: {} for k in self.gameEvent.tasks}
|
||||
|
||||
# Clear the grid layout
|
||||
for i in reversed(range(self.gridLayout.count())):
|
||||
self.gridLayout.itemAt(i).widget().setParent(None)
|
||||
|
||||
# Rebuild the grid layout, so that it correspond to the newly selected CP
|
||||
self.initUnitRows()
|
||||
@ -169,17 +169,25 @@ class QSettingsWindow(QDialog):
|
||||
|
||||
if not hasattr(self.game.settings, "include_jtac_if_available"):
|
||||
self.game.settings.include_jtac_if_available = True
|
||||
if not hasattr(self.game.settings, "jtac_smoke_on"):
|
||||
self.game.settings.jtac_smoke_on= True
|
||||
|
||||
self.include_jtac_if_available = QCheckBox()
|
||||
self.include_jtac_if_available.setChecked(self.game.settings.include_jtac_if_available)
|
||||
self.include_jtac_if_available.toggled.connect(self.applySettings)
|
||||
|
||||
self.jtac_smoke_on = QCheckBox()
|
||||
self.jtac_smoke_on.setChecked(self.game.settings.jtac_smoke_on)
|
||||
self.jtac_smoke_on.toggled.connect(self.applySettings)
|
||||
|
||||
self.gameplayLayout.addWidget(QLabel("Use Supercarrier Module"), 0, 0)
|
||||
self.gameplayLayout.addWidget(self.supercarrier, 0, 1, Qt.AlignRight)
|
||||
self.gameplayLayout.addWidget(QLabel("Put Objective Markers on Map"), 1, 0)
|
||||
self.gameplayLayout.addWidget(self.generate_marks, 1, 1, Qt.AlignRight)
|
||||
self.gameplayLayout.addWidget(QLabel("Include JTAC (If available)"), 2, 0)
|
||||
self.gameplayLayout.addWidget(self.include_jtac_if_available, 2, 1, Qt.AlignRight)
|
||||
self.gameplayLayout.addWidget(QLabel("Enable JTAC smoke markers"), 3, 0)
|
||||
self.gameplayLayout.addWidget(self.jtac_smoke_on, 3, 1, Qt.AlignRight)
|
||||
|
||||
self.performance = QGroupBox("Performance")
|
||||
self.performanceLayout = QGridLayout()
|
||||
@ -299,6 +307,7 @@ class QSettingsWindow(QDialog):
|
||||
self.game.settings.external_views_allowed = self.ext_views.isChecked()
|
||||
self.game.settings.generate_marks = self.generate_marks.isChecked()
|
||||
self.game.settings.include_jtac_if_available = self.include_jtac_if_available.isChecked()
|
||||
self.game.settings.jtac_smoke_on = self.jtac_smoke_on.isChecked()
|
||||
|
||||
print(self.game.settings.map_coalition_visibility)
|
||||
|
||||
|
||||
283
resources/customized_payloads/F-15E.lua
Normal file
283
resources/customized_payloads/F-15E.lua
Normal file
@ -0,0 +1,283 @@
|
||||
local unitPayloads = {
|
||||
["name"] = "F-15E",
|
||||
["payloads"] = {
|
||||
[1] = {
|
||||
["name"] = "CAS",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}",
|
||||
["num"] = 14,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}",
|
||||
["num"] = 16,
|
||||
},
|
||||
[12] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[13] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
[14] = {
|
||||
["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[15] = {
|
||||
["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}",
|
||||
["num"] = 2,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 32,
|
||||
},
|
||||
},
|
||||
[2] = {
|
||||
["name"] = "STRIKE",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 14,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 16,
|
||||
},
|
||||
[12] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[13] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 32,
|
||||
},
|
||||
},
|
||||
[3] = {
|
||||
["name"] = "CAP",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 2,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 32,
|
||||
},
|
||||
},
|
||||
[4] = {
|
||||
["name"] = "ANTISHIP",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 12,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 8,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 32,
|
||||
},
|
||||
},
|
||||
[5] = {
|
||||
["name"] = "SEAD",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 9,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}",
|
||||
["num"] = 10,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 11,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}",
|
||||
["num"] = 19,
|
||||
},
|
||||
[7] = {
|
||||
["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}",
|
||||
["num"] = 17,
|
||||
},
|
||||
[8] = {
|
||||
["CLSID"] = "{9BCC2A2B-5708-4860-B1F1-053A18442067}",
|
||||
["num"] = 18,
|
||||
},
|
||||
[9] = {
|
||||
["CLSID"] = "{9BCC2A2B-5708-4860-B1F1-053A18442067}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[10] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 12,
|
||||
},
|
||||
[11] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 8,
|
||||
},
|
||||
[12] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 13,
|
||||
},
|
||||
[13] = {
|
||||
["CLSID"] = "{GBU-38}",
|
||||
["num"] = 7,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 32,
|
||||
},
|
||||
},
|
||||
},
|
||||
["unitType"] = "F-15E",
|
||||
}
|
||||
return unitPayloads
|
||||
148
resources/customized_payloads/Mi-24V.lua
Normal file
148
resources/customized_payloads/Mi-24V.lua
Normal file
@ -0,0 +1,148 @@
|
||||
local unitPayloads = {
|
||||
["name"] = "Mi-24V",
|
||||
["payloads"] = {
|
||||
[1] = {
|
||||
["name"] = "CAS",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 5,
|
||||
},
|
||||
[6] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 6,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
},
|
||||
},
|
||||
[2] = {
|
||||
["name"] = "STRIKE",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 6,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
[4] = 30,
|
||||
},
|
||||
},
|
||||
[3] = {
|
||||
["name"] = "ANTISHIP",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 6,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
[4] = 30,
|
||||
},
|
||||
},
|
||||
[4] = {
|
||||
["name"] = "SEAD",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}",
|
||||
["num"] = 6,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
[4] = 30,
|
||||
},
|
||||
},
|
||||
[5] = {
|
||||
["name"] = "CAP",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
|
||||
["num"] = 4,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
|
||||
["num"] = 5,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
},
|
||||
},
|
||||
},
|
||||
["unitType"] = "Mi-24V",
|
||||
}
|
||||
return unitPayloads
|
||||
131
resources/customized_payloads/Mi-28.lua
Normal file
131
resources/customized_payloads/Mi-28.lua
Normal file
@ -0,0 +1,131 @@
|
||||
local unitPayloads = {
|
||||
["name"] = "Mi-28",
|
||||
["payloads"] = {
|
||||
[1] = {
|
||||
["name"] = "STRIKE",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 4,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
},
|
||||
},
|
||||
[2] = {
|
||||
["name"] = "CAS",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}",
|
||||
["num"] = 4,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
[4] = 30,
|
||||
},
|
||||
},
|
||||
[3] = {
|
||||
["name"] = "ANTISHIP",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}",
|
||||
["num"] = 4,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
[4] = 30,
|
||||
},
|
||||
},
|
||||
[4] = {
|
||||
["name"] = "SEAD",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}",
|
||||
["num"] = 4,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
},
|
||||
},
|
||||
[5] = {
|
||||
["name"] = "CAP",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
|
||||
["num"] = 2,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
|
||||
["num"] = 3,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{05544F1A-C39C-466b-BC37-5BD1D52E57BB}",
|
||||
["num"] = 4,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 31,
|
||||
[2] = 32,
|
||||
[3] = 18,
|
||||
},
|
||||
},
|
||||
},
|
||||
["unitType"] = "Mi-28N",
|
||||
}
|
||||
return unitPayloads
|
||||
Binary file not shown.
@ -554,7 +554,7 @@ function getJTACStatus()
|
||||
end
|
||||
end
|
||||
|
||||
notify(message, 10)
|
||||
notify(message, 25)
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -85,13 +85,11 @@ QPushButton {
|
||||
border: 1px solid #97A9A9;
|
||||
color:#fff;
|
||||
padding: 6px 10px;
|
||||
cursor: pointer;
|
||||
border-radius:2px;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
background: #6c7b7f;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
/*btn-primary*/
|
||||
@ -101,7 +99,6 @@ QPushButton[style="btn-primary"]{
|
||||
color:#fff;
|
||||
padding: 6px;
|
||||
border-radius:2px;
|
||||
cursor: pointer;
|
||||
font-weight:bold;
|
||||
text-transform:uppercase;
|
||||
}
|
||||
@ -114,7 +111,6 @@ QPushButton[style="btn-primary"]:hover{
|
||||
QPushButton[style="btn-success"] , QPushButton[style="start-button"]{
|
||||
background-color:#82A466;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
border-radius:2px;
|
||||
font-weight:bold;
|
||||
text-transform:uppercase;
|
||||
@ -134,7 +130,6 @@ QPushButton[style="btn-success"]:hover , QPushButton[style="start-button"]:hover
|
||||
QPushButton[style="btn-buy"]{
|
||||
background-color:#82A466;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
border-radius:2px;
|
||||
font-weight:bold;
|
||||
text-transform:uppercase;
|
||||
@ -143,7 +138,6 @@ QPushButton[style="btn-buy"]{
|
||||
}
|
||||
|
||||
QPushButton[style="btn-buy"]:hover{
|
||||
cursor:pointer;
|
||||
background:#5C863F;
|
||||
}
|
||||
|
||||
@ -151,7 +145,6 @@ QPushButton[style="btn-buy"]:hover{
|
||||
QPushButton[style="btn-sell"]{
|
||||
background-color:#9E3232;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
border-radius:2px;
|
||||
font-weight:bold;
|
||||
text-transform:uppercase;
|
||||
@ -160,7 +153,6 @@ QPushButton[style="btn-sell"]{
|
||||
}
|
||||
|
||||
QPushButton[style="btn-sell"]:hover{
|
||||
cursor:pointer;
|
||||
background:#D84545;
|
||||
}
|
||||
|
||||
@ -169,7 +161,6 @@ QPushButton[style="btn-sell"]:hover{
|
||||
QPushButton[style="btn-danger"]{
|
||||
background-color:#9E3232;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
padding: 6px;
|
||||
border-radius:2px;
|
||||
border: 1px solid #9E3232;
|
||||
@ -191,7 +182,6 @@ QLabel{
|
||||
|
||||
QLabel[style="base-title"]{
|
||||
font-size: 24px;
|
||||
font-color: #ccc;
|
||||
}
|
||||
|
||||
QLabel[style="icon-plane"]{
|
||||
|
||||
@ -26,7 +26,6 @@ QTopPanel *{
|
||||
QPushButton[style="btn-success"]{
|
||||
background-color:#699245;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
padding: 5px 5px 5px 5px;
|
||||
border-radius:5px;
|
||||
}
|
||||
@ -35,13 +34,11 @@ QPushButton[style="btn-success"]:hover{
|
||||
background-color:#8ABC5A;
|
||||
padding: 5px 5px 5px 5px;
|
||||
border-radius:5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
QPushButton[style="start-button"]{
|
||||
background-color:#699245;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
padding: 5px 5px 5px 5px;
|
||||
border-radius:5px;
|
||||
}
|
||||
@ -50,14 +47,12 @@ QPushButton[style="start-button"]:hover{
|
||||
background-color:#8ABC5A;
|
||||
padding: 15px 15px 15px 15px;
|
||||
border-radius:5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Buy button */
|
||||
QPushButton[style="btn-buy"]{
|
||||
background-color:#82A466;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
border-radius:2px;
|
||||
font-weight:bold;
|
||||
text-transform:uppercase;
|
||||
@ -66,7 +61,6 @@ QPushButton[style="btn-buy"]{
|
||||
}
|
||||
|
||||
QPushButton[style="btn-buy"]:hover{
|
||||
cursor:pointer;
|
||||
background:#5C863F;
|
||||
}
|
||||
|
||||
@ -74,7 +68,6 @@ QPushButton[style="btn-buy"]:hover{
|
||||
QPushButton[style="btn-sell"]{
|
||||
background-color:#9E3232;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
border-radius:2px;
|
||||
font-weight:bold;
|
||||
text-transform:uppercase;
|
||||
@ -83,14 +76,12 @@ QPushButton[style="btn-sell"]{
|
||||
}
|
||||
|
||||
QPushButton[style="btn-sell"]:hover{
|
||||
cursor:pointer;
|
||||
background:#D84545;
|
||||
}
|
||||
|
||||
QPushButton[style="btn-danger"]{
|
||||
background-color:#9E3232;
|
||||
color: white;
|
||||
cursor:pointer;
|
||||
padding: 5px 5px 5px 5px;
|
||||
border-radius:5px;
|
||||
}
|
||||
@ -99,12 +90,10 @@ QPushButton[style="btn-danger"]:hover{
|
||||
background-color:#D84545;
|
||||
padding: 5px 5px 5px 5px;
|
||||
border-radius:5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
QLabel[style="base-title"]{
|
||||
font-size: 24px;
|
||||
font-color: #ccc;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
|
||||
@ -46,9 +46,9 @@ def _mk_archieve():
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
os.system("pyinstaller.exe 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")
|
||||
#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")
|
||||
|
||||
|
||||
_mk_archieve()
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user