For users:
-Added KA-50 III and AV8BNA Harrier to slot selection
-Changed message in mission generated success dialog
-Zone protect SAMs now part of 'Advanced Defenses' feature
-Late activated friendly/enemy CAP units are placed in mission as a template for Deployed CAP fighters (ie will not be active unless using Advanced Defenses or 'DEPLOY_FIGHTERS' name for radar ground unit)
-improve idle troop behavior at bases/FARPs

For Mission creators:
-Updated pydcs library supports new units such as technicals
-Updated pydcs library supports Falklands map
-allow troop pickup from HELO_CARRIER
-enemy units with radar can be designated to deploy intercept fighters on detection (see RotorOps.fighter options in RotorOps.lua for details) with options for min detection altitude and distance (min detection altitude allows helis to fly 'under the radar')
-Insert RotorOpsServer.lua script and trigger actions if option set in scenario config: rotorops_server: true
-scenario template triggers should now be 'untouched' after mission generation, allowing previously unsupported triggers and actions to be used, along with color coding
-block adding player helicopters if slots locked in scenario config
-Added RotorOps.draw_conflict_zones setting to give users the ability to disable or enable displaying of zones on the map.
-allow disabling spinboxes in scenario config
-mission ends 10 mins after mission success/fail
-copy helicopter start type from templates

Internal:
-github actions workflow to automatically deploy to update server
-Startup version check will ignore micro version
-bypassing triggers and merging before save (to preserve unsupported triggers in pydcs). Our goal is to leave the trigrules and trig from the source mission untouched
-if using random weather, set ice halo to auto and crystals to none
-dont put planes at airports without ILS (to avoid putting planes at helicopter airports ie. Syria)
-improved guardPosition task
-refactored 'coalition' variables to 'coal' to help prevent introducing errors in RotorOps.lua
This commit is contained in:
spencershepard
2023-01-03 12:05:18 -08:00
committed by GitHub
parent fa02707e23
commit f382a2e3cc
24 changed files with 1070 additions and 396 deletions

View File

@@ -2,15 +2,16 @@ import json
import yaml
import sys
import os
import operator
import RotorOpsMission as ROps
import RotorOpsUnits
import version
import user
import logging
import requests
from packaging import version
from packaging import version as ver
from PyQt5.QtWidgets import (
QApplication, QDialog, QMainWindow, QMessageBox, QCheckBox, QSpinBox, QSplashScreen, QFileDialog, QRadioButton,
@@ -19,7 +20,6 @@ from PyQt5.QtWidgets import (
from PyQt5 import QtGui
from PyQt5.QtGui import QPixmap, QFont
from PyQt5.QtCore import QObject, QEvent, Qt, QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
import resources # pyqt resource file
from MissionGeneratorUI import Ui_MainWindow
@@ -27,20 +27,15 @@ from MissionGeneratorUI import Ui_MainWindow
import qtmodern.styles
import qtmodern.windows
# UPDATE BUILD VERSION
maj_version = 1
minor_version = 2
patch_version = 0
modules_version = 2
modules_url = 'https://dcs-helicopters.com/user-files/modules/'
version_url = 'https://dcs-helicopters.com/app-updates/versions.yaml'
modules_map_url = 'https://dcs-helicopters.com/user-files/modules/module-map-v2.yaml'
ratings_url = 'https://dcs-helicopters.com/user-files/ratings.php'
allowed_paths = ['templates\\Scenarios\\downloaded', 'templates\\Forces\\downloaded', 'templates\\Imports\\downloaded']
user_files_url = 'https://dcs-helicopters.com/user-files/'
version_url = 'https://dcs-helicopters.com/app-updates/versioncheck.yaml'
version.version_url = 'https://dcs-helicopters.com/app-updates/versioncheck.yaml'
#Setup logfile and exception handler
logger = logging.getLogger(__name__)
@@ -102,17 +97,16 @@ def handle_exception(exc_type, exc_value, exc_traceback):
sys.excepthook = handle_exception
version_string = str(maj_version) + "." + str(minor_version) + "." + str(patch_version)
defenders_text = "Defending Forces:"
attackers_text = "Attacking Forces:"
ratings_json = None
logger.info("RotorOps v" + version_string)
logger.info("RotorOps v" + version.version_string)
# Try to set windows app ID to display taskbar icon properly
try:
from ctypes import windll
appid = 'RotorOps.MissionGenerator.' + version_string
appid = 'RotorOps.MissionGenerator.' + version.version_string
windll.shell32.SetCurrentProcessExplicitAppUserModelID(appid)
except ImportError:
pass
@@ -156,7 +150,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.statusbar = self.statusBar()
self.statusbar.setStyleSheet(
"QStatusBar{padding-left:5px;}")
self.version_label.setText("Version " + version_string)
self.version_label.setText("Version " + version.version_string)
self.scenarioChanged()
@@ -421,6 +415,12 @@ class Window(QMainWindow, Ui_MainWindow):
if qobj:
qobj.setValue(config['spinboxes'][box])
for box in QObject.findChildren(self, QSpinBox):
if 'disable_spinboxes' in config and config['disable_spinboxes'] is not None and box.objectName() in config['disable_spinboxes']:
box.setEnabled(False)
else:
box.setEnabled(True)
for button in QObject.findChildren(self, QRadioButton):
if 'radiobuttons' in config and button.objectName() in config['radiobuttons']:
button.setChecked(True)
@@ -570,7 +570,6 @@ class Window(QMainWindow, Ui_MainWindow):
"game_display": self.game_status_checkBox.isChecked(),
"defending": self.defense_checkBox.isChecked(),
"slots": self.slot_template_comboBox.currentText(),
"zone_protect_sams": self.zone_sams_checkBox.isChecked(),
"zone_farps": self.farp_buttonGroup.checkedButton().objectName(),
"e_transport_helos": self.e_transport_helos_spinBox.value(),
"transport_drop_qty": self.troop_drop_spinBox.value(),
@@ -588,6 +587,10 @@ class Window(QMainWindow, Ui_MainWindow):
"logistics_farp_file": self.scenario.getConfigValue("logistics_farp_file", default=None),
"zone_protect_file": self.scenario.getConfigValue("zone_protect_file", default=None),
"script": self.scenario.getConfigValue("script", default=None),
"advanced_defenses": self.advanced_defenses_checkBox.isChecked(),
"red_cap": self.scenario.getConfigValue("red_cap", default=True),
"blue_cap": self.scenario.getConfigValue("blue_cap", default=True),
"rotorops_server": self.scenario.getConfigValue("rotorops_server", default=False),
}
logger.info("Generating mission with options:")
@@ -606,11 +609,9 @@ class Window(QMainWindow, Ui_MainWindow):
msg.setText("Awesome, your mission is ready! It's located in this directory: \n" +
result["directory"] + "\n" +
"\n" +
"Next, you should use the DCS Mission Editor to fine tune unit placements. Don't be afraid to edit the missions that this generator produces. \n" +
"You MUST use the DCS Mission Editor to open the mission, or else it may not work correctly. Save the mission or launch it directly from the editor.\n" +
"\n" +
"There are no hidden script changes, everything is visible in the ME. Triggers have been created to help you to add your own actions based on active zone and game status. \n" +
"\n" +
"Units can be changed or moved without issue. Player slots can be changed or moved without issue (one per group though!) \n" +
"It's also highly recommended to fine-tune ground unit placements.\n" +
"\n" +
"Don't forget, you can also create your own templates that can include any mission options, objects, or even scripts. \n" +
"\n" +
@@ -632,20 +633,20 @@ class Window(QMainWindow, Ui_MainWindow):
# works fine but no use for this currently
class myWebView(QDialog):
def __init__(self, window, parent=None):
QDialog.__init__(self, parent)
vbox = QVBoxLayout(self)
self.webEngineView = QWebEngineView()
self.webEngineView.load(QUrl('https://dcs-helicopters.com'))
vbox.addWidget(self.webEngineView)
self.setLayout(vbox)
self.setGeometry(600, 600, 700, 500)
self.setWindowTitle('QWebEngineView')
# class myWebView(QDialog):
# def __init__(self, window, parent=None):
# QDialog.__init__(self, parent)
# vbox = QVBoxLayout(self)
#
# self.webEngineView = QWebEngineView()
# self.webEngineView.load(QUrl('https://dcs-helicopters.com'))
#
# vbox.addWidget(self.webEngineView)
#
# self.setLayout(vbox)
#
# self.setGeometry(600, 600, 700, 500)
# self.setWindowTitle('QWebEngineView')
class slotDialog(QDialog):
def __init__(self, window, parent=None):
@@ -770,10 +771,14 @@ def checkVersion(splashscreen):
try:
r = requests.get(version_url, allow_redirects=False, timeout=7)
r = requests.get(version.version_url, allow_redirects=False, timeout=7)
v = yaml.safe_load(r.content)
avail_build = v["version"]
if version.parse(avail_build) > version.parse(version_string):
avail_version = ver.parse(avail_build)
current_version = ver.parse(version.version_string)
current_maj_min = ver.parse(str(current_version.major) + "." + str(current_version.minor))
avail_maj_min = ver.parse(str(avail_version.major) + "." + str(avail_version.minor))
if avail_maj_min > current_maj_min:
logger.warning("New version available. Please update to available version " + v["version"])
msg = QMessageBox()
msg.setWindowTitle(v["title"])
@@ -781,7 +786,7 @@ def checkVersion(splashscreen):
msg.setIcon(QMessageBox.Icon.Information)
x = msg.exec_()
else:
logger.info("Version check complete: running the latest version.")
logger.info("Version check complete: running the latest version. (micro version ignored)")
except:
logger.error("Online version check failed.")