diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..9d0da6a6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,39 @@ +name: Build + +on: [push, pull_request] + +jobs: + + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + + - name: Install environment + run: | + 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 + + - uses: actions/upload-artifact@v2 + with: + name: dcs_liberation + path: dist/ diff --git a/.gitmodules b/.gitmodules index d1f0105e..d8db9cf5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "pydcs"] path = pydcs - url = https://github.com/khopa/dcs - branch = dataexport + url = https://github.com/pydcs/dcs + branch = master diff --git a/.vscode/launch.json b/.vscode/launch.json index 646c8768..fde0564f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,6 +14,17 @@ "PYTHONPATH": ".;./pydcs" }, "preLaunchTask": "Prepare Environment" + }, + { + "name": "Python: Make Release", + "type": "python", + "request": "launch", + "program": "resources\\tools\\mkrelease.py", + "console": "integratedTerminal", + "env": { + "PYTHONPATH": ".;./pydcs" + }, + "preLaunchTask": "Prepare Environment" } ] } \ No newline at end of file diff --git a/changelog.md b/changelog.md index 865636e7..0f60b72f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,19 @@ +# 2.1.3 + +## Features/Improvements : +* **[Units/Factions]** Added A-10C_2 to USA 2005 and Bluefor modern factions +* **[UI]** Limit number of aircraft that can be bought to the number of available parking slots. +* **[Mission Generator]** Use inline loading of the JSON.lua library, and save to either %LIBERATION_EXPORT_DIR%, or to DCS working directory + +## Changes : +* **[Units/Factions]** Bluefor generic factions will now use the new "Combined Joint Task Forces Blue" country in the generated mission instead of "USA" + +## Fixes : +* **[UI]** Fixed icon for Viggen +* **[UI]** Added icons for some ground units +* **[Misc]** Fixed issue with Chinese characters in pydcs preventing generating the mission. (Take Off button not working) (thanks to spark135246) +* **[Misc]** Fixed an error causing with ATC frequency preventing generating the mission. (Take Off button not working) (thanks to danalbert) + # 2.1.2 ## Fixes : diff --git a/game/db.py b/game/db.py index 02120a45..f2b94b54 100644 --- a/game/db.py +++ b/game/db.py @@ -192,6 +192,7 @@ PRICES = { A_10A: 16, A_10C: 22, + A_10C_2: 24, # heli Ka_50: 13, @@ -498,6 +499,7 @@ UNIT_BY_TASK = { AJS37, A_10A, A_10C, + A_10C_2, Su_17M4, Su_25, Su_25T, @@ -957,6 +959,7 @@ PLANE_PAYLOAD_OVERRIDES = { }, A_10A: COMMON_OVERRIDE, A_10C: COMMON_OVERRIDE, + A_10C_2: COMMON_OVERRIDE, AV8BNA: COMMON_OVERRIDE, C_101CC: COMMON_OVERRIDE, F_5E_3: COMMON_OVERRIDE, diff --git a/game/factions/bluefor_coldwar.py b/game/factions/bluefor_coldwar.py index 70bf9467..5db15d73 100644 --- a/game/factions/bluefor_coldwar.py +++ b/game/factions/bluefor_coldwar.py @@ -4,7 +4,7 @@ from dcs.ships import * from dcs.vehicles import * BLUEFOR_COLDWAR = { - "country": "USA", + "country": "Combined Joint Task Forces Blue", "side": "blue", "units": [ diff --git a/game/factions/bluefor_coldwar_a4.py b/game/factions/bluefor_coldwar_a4.py index 5bf366f5..74983134 100644 --- a/game/factions/bluefor_coldwar_a4.py +++ b/game/factions/bluefor_coldwar_a4.py @@ -6,7 +6,7 @@ from dcs.vehicles import * from pydcs_extensions.a4ec.a4ec import A_4E_C BLUEFOR_COLDWAR_A4 = { - "country": "USA", + "country": "Combined Joint Task Forces Blue", "side": "blue", "units": [ diff --git a/game/factions/bluefor_modern.py b/game/factions/bluefor_modern.py index ca64e2f5..8db0ad89 100644 --- a/game/factions/bluefor_modern.py +++ b/game/factions/bluefor_modern.py @@ -4,7 +4,7 @@ from dcs.ships import * from dcs.vehicles import * BLUEFOR_MODERN = { - "country": "USA", + "country": "Combined Joint Task Forces Blue", "side": "blue", "units": [ @@ -20,6 +20,7 @@ BLUEFOR_MODERN = { Su_25T, A_10A, A_10C, + A_10C_2, AV8BNA, AJS37, diff --git a/game/factions/usa_2005.py b/game/factions/usa_2005.py index ddeccd0b..d6b63a58 100644 --- a/game/factions/usa_2005.py +++ b/game/factions/usa_2005.py @@ -13,6 +13,7 @@ USA_2005 = { FA_18C_hornet, F_16C_50, A_10C, + A_10C_2, AV8BNA, MQ_9_Reaper, diff --git a/game/operation/operation.py b/game/operation/operation.py index 2449746e..4bee75b0 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -250,41 +250,81 @@ class Operation: print(e) # Inject Mist Script if not done already in the plugins - if not "mist.lua" in listOfPluginsScripts and not "mist_4_3_74.lua" in listOfPluginsScripts: # don't load mist twice - trigger = TriggerStart(comment="Load Mist Lua Framework") + if not "mist.lua" in listOfPluginsScripts and not "mist_4_3_74.lua" in listOfPluginsScripts: # don't load the script twice + trigger = TriggerStart(comment="Load Mist Lua framework") fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/mist_4_3_74.lua") trigger.add_action(DoScriptFile(fileref)) self.current_mission.triggerrules.triggers.append(trigger) - # Inject Liberation script - load_dcs_libe = TriggerStart(comment="Load DCS Liberation Script") - with open("./resources/scripts/dcs_liberation.lua") as f: - script = f.read() - json_location = "[["+os.path.abspath("resources\\scripts\\json.lua")+"]]" - state_location = "[[" + os.path.abspath("state.json") + "]]" - script = script.replace("{{json_file_abs_location}}", json_location) - script = script.replace("{{debriefing_file_location}}", state_location) - load_dcs_libe.add_action(DoScript(String(script))) - self.current_mission.triggerrules.triggers.append(load_dcs_libe) + # Inject JSON library if not done already in the plugins + if not "json.lua" in listOfPluginsScripts : # don't load the script twice + trigger = TriggerStart(comment="Load JSON Lua library") + fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/json.lua") + trigger.add_action(DoScriptFile(fileref)) + self.current_mission.triggerrules.triggers.append(trigger) - # Load Ciribob's JTACAutoLase script if not done already in the plugins - if not "JTACAutoLase.lua" in listOfPluginsScripts: # don't load JTACAutoLase twice - load_autolase = TriggerStart(comment="Load JTAC script") - with open("./resources/scripts/JTACAutoLase.lua") as f: + # Inject Ciribob's JTACAutoLase if not done already in the plugins + if not "JTACAutoLase.lua" in listOfPluginsScripts : # don't load the script twice + trigger = TriggerStart(comment="Load JTACAutoLase.lua script") + fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/JTACAutoLase.lua") + trigger.add_action(DoScriptFile(fileref)) + self.current_mission.triggerrules.triggers.append(trigger) - script = f.read() - script = script + "\n" + # set a LUA table with data from Liberation that we want to set + # at the moment it contains Liberation's install path, and an overridable definition for the JTACAutoLase function + # later, we'll add data about the units and points having been generated, in order to facilitate the configuration of the plugin lua scripts + state_location = "[[" + os.path.abspath("state.json") + "]]" + lua = """ + -- setting configuration table + env.info("DCSLiberation|: setting configuration table") + + -- all data in this table is overridable. + dcsLiberation = {} + + -- the base location for state.json; if non-existent, it'll be replaced with LIBERATION_EXPORT_DIR, TEMP, or DCS working directory + dcsLiberation.installPath=""" + state_location + """ + + -- you can override dcsLiberation.JTACAutoLase to make it use your own function ; it will be called with these parameters : ({jtac.unit_name}, {jtac.code}, {smoke}, 'vehicle') for all JTACs + if ctld then + dcsLiberation.JTACAutoLase=ctld.JTACAutoLase + elseif JTACAutoLase then + dcsLiberation.JTACAutoLase=JTACAutoLase + end + + -- later, we'll add more data to the table + --dcsLiberation.POIs = {} + --dcsLiberation.BASEs = {} + --dcsLiberation.JTACs = {} + """ - smoke = "true" - if hasattr(self.game.settings, "jtac_smoke_on"): - if not self.game.settings.jtac_smoke_on: - smoke = "false" + trigger = TriggerStart(comment="Set DCS Liberation data") + trigger.add_action(DoScript(String(lua))) + self.current_mission.triggerrules.triggers.append(trigger) - for jtac in jtacs: - script += f"\nJTACAutoLase('{jtac.unit_name}', {jtac.code}, {smoke}, 'vehicle')\n" + # Inject DCS-Liberation script if not done already in the plugins + if not "dcs_liberation.lua" in listOfPluginsScripts : # don't load the script twice + trigger = TriggerStart(comment="Load DCS Liberation script") + fileref = self.current_mission.map_resource.add_resource_file("./resources/scripts/dcs_liberation.lua") + trigger.add_action(DoScriptFile(fileref)) + self.current_mission.triggerrules.triggers.append(trigger) - load_autolase.add_action(DoScript(String(script))) - self.current_mission.triggerrules.triggers.append(load_autolase) + # add a configuration for JTACAutoLase and start lasing for all JTACs + smoke = "true" + if hasattr(self.game.settings, "jtac_smoke_on"): + if not self.game.settings.jtac_smoke_on: + smoke = "false" + + lua = """ + -- setting and starting JTACs + env.info("DCSLiberation|: setting and starting JTACs") + """ + + for jtac in jtacs: + lua += f"if dcsLiberation.JTACAutoLase then dcsLiberation.JTACAutoLase('{jtac.unit_name}', {jtac.code}, {smoke}, 'vehicle') end\n" + + trigger = TriggerStart(comment="Start JTACs") + trigger.add_action(DoScript(String(lua))) + self.current_mission.triggerrules.triggers.append(trigger) self.assign_channels_to_flights() diff --git a/gen/aircraft.py b/gen/aircraft.py index 81a6202e..ec5dec26 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -279,13 +279,15 @@ class CommonRadioChannelAllocator(RadioChannelAllocator): last_channel = flight.num_radio_channels(radio_id) channel_alloc = iter(range(first_channel, last_channel + 1)) - flight.assign_channel(radio_id, next(channel_alloc), flight.departure.atc) + if flight.departure.atc is not None: + flight.assign_channel(radio_id, next(channel_alloc), + flight.departure.atc) # TODO: If there ever are multiple AWACS, limit to mission relevant. for awacs in air_support.awacs: flight.assign_channel(radio_id, next(channel_alloc), awacs.freq) - if flight.arrival != flight.departure: + if flight.arrival != flight.departure and flight.arrival.atc is not None: flight.assign_channel(radio_id, next(channel_alloc), flight.arrival.atc) @@ -295,7 +297,7 @@ class CommonRadioChannelAllocator(RadioChannelAllocator): flight.assign_channel( radio_id, next(channel_alloc), tanker.freq) - if flight.divert is not None: + if flight.divert is not None and flight.divert.atc is not None: flight.assign_channel(radio_id, next(channel_alloc), flight.divert.atc) except StopIteration: diff --git a/gen/flights/ai_flight_planner_db.py b/gen/flights/ai_flight_planner_db.py index 3b11b8ee..e1393a1a 100644 --- a/gen/flights/ai_flight_planner_db.py +++ b/gen/flights/ai_flight_planner_db.py @@ -99,6 +99,7 @@ CAS_CAPABLE = [ A_10A, A_10C, + A_10C_2, AV8BNA, F_86F_Sabre, @@ -197,6 +198,7 @@ STRIKE_CAPABLE = [ A_10A, A_10C, + A_10C_2, AV8BNA, F_86F_Sabre, @@ -244,6 +246,7 @@ ANTISHIP_CAPABLE = [ F_16A, F_16C_50, A_10C, + A_10C_2, A_10A, Tornado_IDS, diff --git a/pydcs b/pydcs index 7b7c0322..ceea62a8 160000 --- a/pydcs +++ b/pydcs @@ -1 +1 @@ -Subproject commit 7b7c0322856c43ed8d1c7d29b2e30121129af048 +Subproject commit ceea62a8e0731c21b3e1a3e90682aa0affc168f1 diff --git a/qt_ui/uiconstants.py b/qt_ui/uiconstants.py index 98026f3a..ada6c94c 100644 --- a/qt_ui/uiconstants.py +++ b/qt_ui/uiconstants.py @@ -8,7 +8,7 @@ from game.event import UnitsDeliveryEvent, FrontlineAttackEvent from theater.theatergroundobject import CATEGORY_MAP from userdata.liberation_theme import get_theme_icons -VERSION_STRING = "2.1.2" +VERSION_STRING = "2.1.3" URLS : Dict[str, str] = { "Manual": "https://github.com/khopa/dcs_liberation/wiki", @@ -82,6 +82,7 @@ def load_icons(): ICONS["New"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/new.png") ICONS["Open"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/open.png") ICONS["Save"] = QPixmap("./resources/ui/misc/"+get_theme_icons()+"/save.png") + ICONS["Hangar"] = QPixmap("./resources/ui/misc/hangar.png") ICONS["Terrain_Caucasus"] = QPixmap("./resources/ui/terrain_caucasus.gif") ICONS["Terrain_Persian_Gulf"] = QPixmap("./resources/ui/terrain_pg.gif") @@ -138,6 +139,7 @@ def load_aircraft_icons(): AIRCRAFT_ICONS[aircraft[:-7]] = QPixmap(os.path.join("./resources/ui/units/aircrafts/", aircraft)) AIRCRAFT_ICONS["F-16C_50"] = AIRCRAFT_ICONS["F-16C"] AIRCRAFT_ICONS["FA-18C_hornet"] = AIRCRAFT_ICONS["FA-18C"] + AIRCRAFT_ICONS["A-10C_2"] = AIRCRAFT_ICONS["A-10C"] def load_vehicle_icons(): diff --git a/qt_ui/windows/QLiberationWindow.py b/qt_ui/windows/QLiberationWindow.py index c51547e6..bf086c5d 100644 --- a/qt_ui/windows/QLiberationWindow.py +++ b/qt_ui/windows/QLiberationWindow.py @@ -221,7 +221,7 @@ class QLiberationWindow(QMainWindow): "

Authors

" + \ "

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

Contributors

" + \ - "shdwp, Khopa, ColonelPanic, Wrycu, calvinmorrow, JohanAberg, Deus, root0fall, Captain Cody, steveveepee, pedromagueija, parithon, bwRavencl" + \ + "shdwp, Khopa, ColonelPanic, Wrycu, calvinmorrow, JohanAberg, Deus, root0fall, Captain Cody, steveveepee, pedromagueija, parithon, bwRavencl, davidp57" + \ "

Special Thanks :

" \ "rp- for the pydcs framework
"\ "Grimes (mrSkortch) & Speed for the MIST framework
"\ diff --git a/qt_ui/windows/basemenu/QRecruitBehaviour.py b/qt_ui/windows/basemenu/QRecruitBehaviour.py index a42b00d5..f180dd58 100644 --- a/qt_ui/windows/basemenu/QRecruitBehaviour.py +++ b/qt_ui/windows/basemenu/QRecruitBehaviour.py @@ -1,3 +1,5 @@ +import logging + from PySide2.QtWidgets import QLabel, QPushButton, \ QSizePolicy, QSpacerItem, QGroupBox, QHBoxLayout from dcs.unittype import UnitType @@ -11,11 +13,14 @@ class QRecruitBehaviour: deliveryEvent = None existing_units_labels = None bought_amount_labels = None + maximum_units = -1 + recruitable_types = [] BUDGET_FORMAT = "Available Budget: ${}M" def __init__(self): self.bought_amount_labels = {} self.existing_units_labels = {} + self.recruitable_types = [] self.update_available_budget() def add_purchase_row(self, unit_type, layout, row): @@ -66,7 +71,6 @@ class QRecruitBehaviour: sell.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) sell.clicked.connect(lambda: self.sell(unit_type)) - existLayout.addWidget(unitName) existLayout.addItem(QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Minimum)) existLayout.addWidget(existing_units) @@ -102,10 +106,19 @@ class QRecruitBehaviour: def buy(self, unit_type): + if self.maximum_units > 0: + if self.total_units + 1 > self.maximum_units: + logging.info("Not enough space left !") + # TODO : display modal warning + return + price = db.PRICES[unit_type] if self.game.budget >= price: self.deliveryEvent.deliver({unit_type: 1}) self.game.budget -= price + else: + # TODO : display modal warning + logging.info("Not enough money !") self._update_count_label(unit_type) self.update_available_budget() @@ -123,3 +136,34 @@ class QRecruitBehaviour: self._update_count_label(unit_type) self.update_available_budget() + + @property + def total_units(self): + + total = 0 + for unit_type in self.recruitables_types: + total += self.cp.base.total_units(unit_type) + print(unit_type, total, self.cp.base.total_units(unit_type)) + print("--------------------------------") + + if self.deliveryEvent: + for unit_bought in self.deliveryEvent.units: + if db.unit_task(unit_bought) in self.recruitables_types: + total += self.deliveryEvent.units[unit_bought] + print(unit_bought, total, self.deliveryEvent.units[unit_bought]) + + print("=============================") + + return total + + def set_maximum_units(self, maximum_units): + """ + Set the maximum number of units that can be bought + """ + self.maximum_units = maximum_units + + def set_recruitable_types(self, recruitables_types): + """ + Set the maximum number of units that can be bought + """ + self.recruitables_types = recruitables_types \ No newline at end of file diff --git a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py index 2d4621d6..a4abf404 100644 --- a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py @@ -1,28 +1,35 @@ from PySide2.QtCore import Qt -from PySide2.QtWidgets import QVBoxLayout, QGridLayout, QGroupBox, QScrollArea, QFrame, QWidget +from PySide2.QtWidgets import QVBoxLayout, QGridLayout, QGroupBox, QScrollArea, QFrame, QWidget, QHBoxLayout, QLabel from game.event import UnitsDeliveryEvent +from qt_ui.uiconstants import ICONS from qt_ui.windows.basemenu.QRecruitBehaviour import QRecruitBehaviour -from theater import ControlPoint, CAP, CAS, db +from theater import ControlPoint, CAP, CAS, db, ControlPointType from game import Game class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): - def __init__(self, cp:ControlPoint, game:Game): + def __init__(self, cp: ControlPoint, game: Game): QFrame.__init__(self) self.cp = cp self.game = game - self.bought_amount_labels = {} - self.existing_units_labels = {} - for event in self.game.events: if event.__class__ == UnitsDeliveryEvent and event.from_cp == self.cp: self.deliveryEvent = event if not self.deliveryEvent: self.deliveryEvent = self.game.units_delivery_event(self.cp) + # Determine maximum number of aircrafts that can be bought + self.set_maximum_units(self.cp.available_aircraft_slots) + self.set_recruitable_types([CAP, CAS]) + + self.bought_amount_labels = {} + self.existing_units_labels = {} + + self.hangar_status = QHangarStatus(self.total_units, self.cp.available_aircraft_slots) + self.init_ui() def init_ui(self): @@ -57,5 +64,32 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) scroll.setWidgetResizable(True) scroll.setWidget(scroll_content) + main_layout.addLayout(self.hangar_status) main_layout.addWidget(scroll) self.setLayout(main_layout) + + def buy(self, unit_type): + super().buy(unit_type) + self.hangar_status.update_label(self.total_units, self.cp.available_aircraft_slots) + + def sell(self, unit_type): + super().sell(unit_type) + self.hangar_status.update_label(self.total_units, self.cp.available_aircraft_slots) + + +class QHangarStatus(QHBoxLayout): + + def __init__(self, current_amount: int, max_amount: int): + super(QHangarStatus, self).__init__() + self.icon = QLabel() + self.icon.setPixmap(ICONS["Hangar"]) + self.text = QLabel("") + + self.update_label(current_amount, max_amount) + self.addWidget(self.icon, Qt.AlignLeft) + self.addWidget(self.text, Qt.AlignLeft) + self.addStretch(50) + self.setAlignment(Qt.AlignLeft) + + def update_label(self, current_amount: int, max_amount: int): + self.text.setText("{}/{}".format(current_amount, max_amount)) diff --git a/resources/customized_payloads/A-10C_2.lua b/resources/customized_payloads/A-10C_2.lua new file mode 100644 index 00000000..bae0f048 --- /dev/null +++ b/resources/customized_payloads/A-10C_2.lua @@ -0,0 +1,219 @@ +local unitPayloads = { + ["name"] = "A-10C II", + ["payloads"] = { + [1] = { + ["name"] = "New Payload", + ["pylons"] = { + [1] = { + ["CLSID"] = "{LAU-131x3 - 7 AGR-20A}", + ["num"] = 8, + }, + [2] = { + ["CLSID"] = "{LAU-131x3 - 7 AGR-20 M282}", + ["num"] = 9, + }, + [3] = { + ["CLSID"] = "{LAU-131x3 - 7 AGR-20A}", + ["num"] = 4, + }, + [4] = { + ["CLSID"] = "{LAU-131x3 - 7 AGR-20 M282}", + ["num"] = 3, + }, + [5] = { + ["CLSID"] = "{LAU-131 - 7 AGR-20A}", + ["num"] = 2, + }, + [6] = { + ["CLSID"] = "{LAU-131 - 7 AGR-20A}", + ["num"] = 10, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, + [2] = { + ["name"] = "CAP", + ["pylons"] = { + [1] = { + ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}", + ["num"] = 11, + }, + [2] = { + ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}", + ["num"] = 1, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, + [3] = { + ["name"] = "CAS", + ["pylons"] = { + [1] = { + ["CLSID"] = "ALQ_184", + ["num"] = 1, + }, + [2] = { + ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}", + ["num"] = 11, + }, + [3] = { + ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}", + ["num"] = 10, + }, + [4] = { + ["CLSID"] = "{LAU-131 - 7 AGR-20 M282}", + ["num"] = 8, + }, + [5] = { + ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}", + ["num"] = 9, + }, + [6] = { + ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98452}", + ["num"] = 3, + }, + [7] = { + ["CLSID"] = "{LAU-131 - 7 AGR-20 M282}", + ["num"] = 4, + }, + [8] = { + ["CLSID"] = "{LAU-131 - 7 AGR-20A}", + ["num"] = 2, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, + [4] = { + ["name"] = "STRIKE", + ["pylons"] = { + [1] = { + ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}", + ["num"] = 11, + }, + [2] = { + ["CLSID"] = "ALQ_184", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}", + ["num"] = 10, + }, + [4] = { + ["CLSID"] = "{GBU-38}", + ["num"] = 8, + }, + [5] = { + ["CLSID"] = "{GBU-38}", + ["num"] = 7, + }, + [6] = { + ["CLSID"] = "{GBU-38}", + ["num"] = 4, + }, + [7] = { + ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}", + ["num"] = 3, + }, + [8] = { + ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}", + ["num"] = 9, + }, + [9] = { + ["CLSID"] = "{GBU-38}", + ["num"] = 5, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, + [5] = { + ["name"] = "ANTISHIP", + ["pylons"] = { + [1] = { + ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}", + ["num"] = 11, + }, + [2] = { + ["CLSID"] = "ALQ_184", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}", + ["num"] = 10, + }, + [4] = { + ["CLSID"] = "{DAC53A2F-79CA-42FF-A77A-F5649B601308}", + ["num"] = 9, + }, + [5] = { + ["CLSID"] = "{DAC53A2F-79CA-42FF-A77A-F5649B601308}", + ["num"] = 3, + }, + [6] = { + ["CLSID"] = "{LAU-131 - 7 AGR-20 M282}", + ["num"] = 2, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, + [6] = { + ["name"] = "SEAD", + ["pylons"] = { + [1] = { + ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}", + ["num"] = 11, + }, + [2] = { + ["CLSID"] = "ALQ_184", + ["num"] = 1, + }, + [3] = { + ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}", + ["num"] = 10, + }, + [4] = { + ["CLSID"] = "{DAC53A2F-79CA-42FF-A77A-F5649B601308}", + ["num"] = 9, + }, + [5] = { + ["CLSID"] = "{DAC53A2F-79CA-42FF-A77A-F5649B601308}", + ["num"] = 3, + }, + [6] = { + ["CLSID"] = "{LAU-131 - 7 AGR-20 M282}", + ["num"] = 2, + }, + [7] = { + ["CLSID"] = "{GBU-38}", + ["num"] = 7, + }, + [8] = { + ["CLSID"] = "{GBU-38}", + ["num"] = 5, + }, + [9] = { + ["CLSID"] = "{GBU-38}", + ["num"] = 8, + }, + [10] = { + ["CLSID"] = "{GBU-38}", + ["num"] = 4, + }, + }, + ["tasks"] = { + [1] = 31, + }, + }, + }, + ["unitType"] = "A-10C_2", +} +return unitPayloads diff --git a/resources/scripts/dcs_liberation.lua b/resources/scripts/dcs_liberation.lua index 5c594d35..70a5c239 100644 --- a/resources/scripts/dcs_liberation.lua +++ b/resources/scripts/dcs_liberation.lua @@ -1,9 +1,5 @@ -local jsonlib = {{json_file_abs_location}} -json = loadfile(jsonlib)() - logger = mist.Logger:new("DCSLiberation", "info") - -debriefing_file_location = {{debriefing_file_location}} +logger:info("Check that json.lua is loaded : json = "..tostring(json)) killed_aircrafts = {} killed_ground_units = {} @@ -32,12 +28,56 @@ write_state = function() ["mission_ended"] = mission_ended, ["destroyed_objects_positions"] = destroyed_objects_positions, } + if not json then + local message = string.format("Unable to save DCS Liberation state to %s, JSON library is not loaded !",debriefing_file_location) + logger:error(message) + messageAll(message) + end fp:write(json:encode(game_state)) fp:close() -- logger.info("Done writing DCS Liberation state") -- messageAll("Done writing DCS Liberation state.") end +debriefing_file_location = nil +if dcsLiberation then + debriefing_file_location = dcsLiberation.installPath +end +if debriefing_file_location then + logger:info("Using DCS Liberation install folder for state.json") +else + if os then + debriefing_file_location = os.getenv("LIBERATION_EXPORT_DIR") + if debriefing_file_location then debriefing_file_location = debriefing_file_location .. "\\" end + end + if debriefing_file_location then + logger:info("Using LIBERATION_EXPORT_DIR environment variable for state.json") + else + if os then + debriefing_file_location = os.getenv("TEMP") + if debriefing_file_location then debriefing_file_location = debriefing_file_location .. "\\" end + end + if debriefing_file_location then + logger:info("Using TEMP environment variable for state.json") + else + if lfs then + debriefing_file_location = lfs.writedir() + end + if debriefing_file_location then + logger:info("Using DCS working directory for state.json") + end + end + end +end +if debriefing_file_location then + local filename = "state.json" + if not debriefing_file_location:sub(-#filename) == filename then + debriefing_file_location = debriefing_file_location .. filename + end + logger:info(string.format("DCS Liberation state will be written as json to [[%s]]",debriefing_file_location)) +else + logger:error("No usable storage path for state.json") +end write_state_error_handling = function() if pcall(write_state) then diff --git a/resources/scripts/json.lua b/resources/scripts/json.lua index 8b3ddb1f..632c6840 100644 --- a/resources/scripts/json.lua +++ b/resources/scripts/json.lua @@ -968,7 +968,7 @@ function OBJDEF:new(args) return setmetatable(new, OBJDEF) end -return OBJDEF:new() +json = OBJDEF:new() -- -- Version history: diff --git a/resources/scripts/plugins/link.cmd.sample b/resources/scripts/plugins/link.cmd.sample deleted file mode 100644 index e9c69ce7..00000000 --- a/resources/scripts/plugins/link.cmd.sample +++ /dev/null @@ -1,29 +0,0 @@ -rem this can be used to easily create hardlinks from your plugin development folder - -mklink mist.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\community\mist.lua -mklink Moose.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\community\Moose.lua -mklink CTLD.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\community\CTLD.lua -mklink NIOD.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\community\NIOD.lua -mklink WeatherMark.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\community\WeatherMark.lua -mklink veaf.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veaf.lua -mklink dcsUnits.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\dcsUnits.lua -mklink JTACAutoLase.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\JTACAutoLase.lua -mklink veafAssets.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafAssets.lua -mklink veafCarrierOperations.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafCarrierOperations.lua -mklink veafCarrierOperations2.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafCarrierOperations2.lua -mklink veafCasMission.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafCasMission.lua -mklink veafCombatMission.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafCombatMission.lua -mklink veafCombatZone.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafCombatZone.lua -mklink veafGrass.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafGrass.lua -mklink veafInterpreter.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafInterpreter.lua -mklink veafMarkers.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafMarkers.lua -mklink veafMove.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafMove.lua -mklink veafNamedPoints.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafNamedPoints.lua -mklink veafRadio.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafRadio.lua -mklink veafRemote.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafRemote.lua -mklink veafSecurity.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafSecurity.lua -mklink veafShortcuts.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafShortcuts.lua -mklink veafSpawn.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafSpawn.lua -mklink veafTransportMission.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafTransportMission.lua -mklink veafUnits.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\veafUnits.lua -mklink missionConfig.lua d:\dev\_VEAF\VEAF-Mission-Creation-Tools\src\scripts\veaf\missionConfig.lua diff --git a/resources/ui/misc/hangar.png b/resources/ui/misc/hangar.png new file mode 100644 index 00000000..dc98f559 Binary files /dev/null and b/resources/ui/misc/hangar.png differ diff --git a/resources/ui/units/aircrafts/AJS37 Viggen_24.jpg b/resources/ui/units/aircrafts/AJS37_24.jpg similarity index 100% rename from resources/ui/units/aircrafts/AJS37 Viggen_24.jpg rename to resources/ui/units/aircrafts/AJS37_24.jpg diff --git a/resources/ui/units/vehicles/2S6 Tunguska_24.jpg b/resources/ui/units/vehicles/2S6 Tunguska_24.jpg new file mode 100644 index 00000000..94e5ee27 Binary files /dev/null and b/resources/ui/units/vehicles/2S6 Tunguska_24.jpg differ diff --git a/resources/ui/units/vehicles/Bofors 40 mm_24.jpg b/resources/ui/units/vehicles/Bofors 40 mm_24.jpg new file mode 100644 index 00000000..dda787d8 Binary files /dev/null and b/resources/ui/units/vehicles/Bofors 40 mm_24.jpg differ diff --git a/resources/ui/units/vehicles/Gepard_24.jpg b/resources/ui/units/vehicles/Gepard_24.jpg new file mode 100644 index 00000000..f2775a84 Binary files /dev/null and b/resources/ui/units/vehicles/Gepard_24.jpg differ diff --git a/resources/ui/units/vehicles/HAWK ANMPG-46 TR_24.jpg b/resources/ui/units/vehicles/HAWK ANMPG-46 TR_24.jpg new file mode 100644 index 00000000..7c1ae752 Binary files /dev/null and b/resources/ui/units/vehicles/HAWK ANMPG-46 TR_24.jpg differ diff --git a/resources/ui/units/vehicles/HAWK ANMPQ-50 SR_24.jpg b/resources/ui/units/vehicles/HAWK ANMPQ-50 SR_24.jpg new file mode 100644 index 00000000..17408863 Binary files /dev/null and b/resources/ui/units/vehicles/HAWK ANMPQ-50 SR_24.jpg differ diff --git a/resources/ui/units/vehicles/HAWK M192 LN_24.jpg b/resources/ui/units/vehicles/HAWK M192 LN_24.jpg new file mode 100644 index 00000000..08544b41 Binary files /dev/null and b/resources/ui/units/vehicles/HAWK M192 LN_24.jpg differ diff --git a/resources/ui/units/vehicles/HQ-7 Mobile Launcher_24.jpg b/resources/ui/units/vehicles/HQ-7 Mobile Launcher_24.jpg new file mode 100644 index 00000000..7fd18f05 Binary files /dev/null and b/resources/ui/units/vehicles/HQ-7 Mobile Launcher_24.jpg differ diff --git a/resources/ui/units/vehicles/HQ-7 Mobile Radar_24.jpg b/resources/ui/units/vehicles/HQ-7 Mobile Radar_24.jpg new file mode 100644 index 00000000..377709ef Binary files /dev/null and b/resources/ui/units/vehicles/HQ-7 Mobile Radar_24.jpg differ diff --git a/resources/ui/units/vehicles/M-163 Vulcan_24.jpg b/resources/ui/units/vehicles/M-163 Vulcan_24.jpg new file mode 100644 index 00000000..f5489310 Binary files /dev/null and b/resources/ui/units/vehicles/M-163 Vulcan_24.jpg differ diff --git a/resources/ui/units/vehicles/M1043 HMMWV_24.jpg b/resources/ui/units/vehicles/M1043 HMMWV Armament_24.jpg similarity index 100% rename from resources/ui/units/vehicles/M1043 HMMWV_24.jpg rename to resources/ui/units/vehicles/M1043 HMMWV Armament_24.jpg diff --git a/resources/ui/units/vehicles/M1097 Avenger_24.jpg b/resources/ui/units/vehicles/M1097 Avenger_24.jpg new file mode 100644 index 00000000..1ed50975 Binary files /dev/null and b/resources/ui/units/vehicles/M1097 Avenger_24.jpg differ diff --git a/resources/ui/units/vehicles/M1A2_24.jpg b/resources/ui/units/vehicles/M1A2_24.jpg new file mode 100644 index 00000000..d0bf9a66 Binary files /dev/null and b/resources/ui/units/vehicles/M1A2_24.jpg differ diff --git a/resources/ui/units/vehicles/M2A2_24.jpg b/resources/ui/units/vehicles/M2A2_24.jpg new file mode 100644 index 00000000..037dddf1 Binary files /dev/null and b/resources/ui/units/vehicles/M2A2_24.jpg differ diff --git a/resources/ui/units/vehicles/M48 Chaparral_24.jpg b/resources/ui/units/vehicles/M48 Chaparral_24.jpg new file mode 100644 index 00000000..2d01a9cc Binary files /dev/null and b/resources/ui/units/vehicles/M48 Chaparral_24.jpg differ diff --git a/resources/ui/units/vehicles/M6 Linebacker_24.jpg b/resources/ui/units/vehicles/M6 Linebacker_24.jpg new file mode 100644 index 00000000..615368da Binary files /dev/null and b/resources/ui/units/vehicles/M6 Linebacker_24.jpg differ diff --git a/resources/ui/units/vehicles/M818_24.jpg b/resources/ui/units/vehicles/M818_24.jpg new file mode 100644 index 00000000..23372bf0 Binary files /dev/null and b/resources/ui/units/vehicles/M818_24.jpg differ diff --git a/resources/ui/units/vehicles/Marder_24.jpg b/resources/ui/units/vehicles/Marder_24.jpg new file mode 100644 index 00000000..3717e28d Binary files /dev/null and b/resources/ui/units/vehicles/Marder_24.jpg differ diff --git a/resources/ui/units/vehicles/Merkava Mk IV_24.jpg b/resources/ui/units/vehicles/Merkava Mk4_24.jpg similarity index 100% rename from resources/ui/units/vehicles/Merkava Mk IV_24.jpg rename to resources/ui/units/vehicles/Merkava Mk4_24.jpg diff --git a/resources/ui/units/vehicles/Osa 9A33 ln_24.jpg b/resources/ui/units/vehicles/Osa 9A33 ln_24.jpg new file mode 100644 index 00000000..5efab07a Binary files /dev/null and b/resources/ui/units/vehicles/Osa 9A33 ln_24.jpg differ diff --git a/resources/ui/units/vehicles/Roland ADS_24.jpg b/resources/ui/units/vehicles/Roland ADS_24.jpg new file mode 100644 index 00000000..3ee30605 Binary files /dev/null and b/resources/ui/units/vehicles/Roland ADS_24.jpg differ diff --git a/resources/ui/units/vehicles/Roland Radar_24.jpg b/resources/ui/units/vehicles/Roland Radar_24.jpg new file mode 100644 index 00000000..5969b934 Binary files /dev/null and b/resources/ui/units/vehicles/Roland Radar_24.jpg differ diff --git a/resources/ui/units/vehicles/T-80UD_24.jpg b/resources/ui/units/vehicles/T-80UD_24.jpg new file mode 100644 index 00000000..8537a9b3 Binary files /dev/null and b/resources/ui/units/vehicles/T-80UD_24.jpg differ diff --git a/resources/ui/units/vehicles/ZU-23 Ural_24.jpg b/resources/ui/units/vehicles/ZU-23 Ural_24.jpg new file mode 100644 index 00000000..57179b9d Binary files /dev/null and b/resources/ui/units/vehicles/ZU-23 Ural_24.jpg differ diff --git a/resources/ui/units/vehicles/ZU-23_24.jpg b/resources/ui/units/vehicles/ZU-23_24.jpg new file mode 100644 index 00000000..4dbf6d31 Binary files /dev/null and b/resources/ui/units/vehicles/ZU-23_24.jpg differ diff --git a/theater/controlpoint.py b/theater/controlpoint.py index d7a726e7..2aba30ca 100644 --- a/theater/controlpoint.py +++ b/theater/controlpoint.py @@ -102,14 +102,23 @@ class ControlPoint: @property def is_carrier(self): + """ + :return: Whether this control point is an aircraft carrier + """ return self.cptype in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP] @property def is_fleet(self): + """ + :return: Whether this control point is a boat (mobile) + """ return self.cptype in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP] @property def is_lha(self): + """ + :return: Whether this control point is an LHA + """ return self.cptype in [ControlPointType.LHA_GROUP] @property @@ -122,6 +131,20 @@ class ControlPoint: result.append(r) return result + @property + def available_aircraft_slots(self): + """ + :return: The maximum number of aircraft that can be stored in this control point + """ + if self.cptype == ControlPointType.AIRBASE: + return len(self.airport.parking_slots) + elif self.is_lha: + return 20 + elif self.is_carrier: + return 90 + else: + return 0 + def connect(self, to): self.connected_points.append(to) self.stances[to.id] = CombatStance.DEFENSIVE