mirror of
https://github.com/spencershepard/RotorOps.git
synced 2025-11-10 15:45:30 +00:00
1.2 update
..
This commit is contained in:
@@ -2,6 +2,7 @@ import json
|
||||
import yaml
|
||||
import sys
|
||||
import os
|
||||
import operator
|
||||
|
||||
import RotorOpsMission as ROps
|
||||
import RotorOpsUnits
|
||||
@@ -28,10 +29,18 @@ import qtmodern.windows
|
||||
|
||||
# UPDATE BUILD VERSION
|
||||
maj_version = 1
|
||||
minor_version = 1
|
||||
patch_version = 2
|
||||
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'
|
||||
|
||||
#Setup logfile and exception handler
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -50,27 +59,39 @@ class directories:
|
||||
os.chdir("..")
|
||||
cls.home_dir = os.getcwd()
|
||||
cls.scenarios = cls.home_dir + "\\templates\\Scenarios"
|
||||
cls.forces = cls.home_dir + "\\templates\\Forces"
|
||||
cls.forces_downloaded = cls.home_dir + "\\templates\\Forces\\downloaded"
|
||||
cls.forces_user = cls.home_dir + "\\templates\\Forces\\user"
|
||||
cls.scripts = cls.home_dir + "\\scripts"
|
||||
cls.sound = cls.home_dir + "\\sound\\embedded"
|
||||
cls.output = cls.home_dir + "\\MissionOutput"
|
||||
cls.assets = cls.home_dir + "\\assets"
|
||||
cls.imports = cls.home_dir + "\\templates\\Imports"
|
||||
cls.imports_downloaded = cls.home_dir + "\\templates\\Imports\\downloaded"
|
||||
cls.imports_user = cls.home_dir + "\\templates\\Imports\\user"
|
||||
cls.user_datafile_path = cls.home_dir + "\\config\\user-data.yaml"
|
||||
cls.scenarios_downloaded = cls.scenarios + "\\downloaded"
|
||||
cls.scenarios_user = cls.scenarios + "\\user"
|
||||
cls.default_config = cls.home_dir + '\\config\\default-config.yaml'
|
||||
os.chdir(current_dir)
|
||||
|
||||
directories.find()
|
||||
@classmethod
|
||||
def createDirectories(cls):
|
||||
required_dirs = [cls.scenarios_user, cls.scenarios_downloaded, cls.imports_user, cls.imports_downloaded, cls.forces_user, cls.forces_downloaded, cls.output]
|
||||
for path in required_dirs:
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
import MissionGeneratorScenario
|
||||
|
||||
directories.find()
|
||||
directories.createDirectories()
|
||||
|
||||
import MissionGeneratorTemplates
|
||||
|
||||
def handle_exception(exc_type, exc_value, exc_traceback):
|
||||
if issubclass(exc_type, KeyboardInterrupt): #example of handling error subclasses
|
||||
sys.__excepthook__(exc_type, exc_value, exc_traceback)
|
||||
return
|
||||
|
||||
QApplication.restoreOverrideCursor()
|
||||
logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
|
||||
msg = QMessageBox()
|
||||
msg.setWindowTitle("Uncaught exception")
|
||||
@@ -82,9 +103,6 @@ sys.excepthook = handle_exception
|
||||
|
||||
|
||||
version_string = str(maj_version) + "." + str(minor_version) + "." + str(patch_version)
|
||||
# scenarios = []
|
||||
red_forces_files = []
|
||||
blue_forces_files = []
|
||||
defenders_text = "Defending Forces:"
|
||||
attackers_text = "Attacking Forces:"
|
||||
ratings_json = None
|
||||
@@ -120,16 +138,17 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
self.player_slots = []
|
||||
self.user_output_dir = None
|
||||
self.user_data = None
|
||||
self.forces_list = []
|
||||
self.imports_list = []
|
||||
|
||||
self.user_data = self.loadUserData()
|
||||
|
||||
self.m = ROps.RotorOpsMission()
|
||||
self.setupUi(self)
|
||||
self.connectSignalsSlots()
|
||||
self.populateScenarios()
|
||||
self.populateForces("red", self.redforces_comboBox, red_forces_files)
|
||||
self.populateForces("blue", self.blueforces_comboBox, blue_forces_files)
|
||||
self.populateForces()
|
||||
self.populateSlotSelection()
|
||||
self.getImports()
|
||||
|
||||
# self.blue_forces_label.setText(attackers_text)
|
||||
# self.red_forces_label.setText(defenders_text)
|
||||
@@ -139,11 +158,15 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
"QStatusBar{padding-left:5px;}")
|
||||
self.version_label.setText("Version " + version_string)
|
||||
|
||||
self.scenarioChanged()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
self.time_comboBox.addItem("Default Time")
|
||||
self.time_comboBox.addItem("Day")
|
||||
self.time_comboBox.addItem("Night")
|
||||
self.time_comboBox.addItem("Dusk")
|
||||
self.time_comboBox.addItem("Dawn")
|
||||
self.time_comboBox.addItem("Noon")
|
||||
self.time_comboBox.addItem("Random")
|
||||
|
||||
|
||||
def connectSignalsSlots(self):
|
||||
@@ -212,7 +235,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
basename = filename.removesuffix('.miz')
|
||||
mizpath = os.path.join(path, folder, filename)
|
||||
# create scenario object
|
||||
s = MissionGeneratorScenario.Scenario(mizpath, basename)
|
||||
s = MissionGeneratorTemplates.Scenario(mizpath, basename)
|
||||
|
||||
#apply some properties if found in the downloads directory
|
||||
if path == directories.scenarios_downloaded:
|
||||
@@ -221,7 +244,6 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
s.packageID = folder
|
||||
|
||||
if ratings_json:
|
||||
print(ratings_json)
|
||||
for module in ratings_json:
|
||||
if module['package'] == folder:
|
||||
s.rating = module["avg_rating"]
|
||||
@@ -256,8 +278,8 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
t_scenarios.append(s)
|
||||
scenarios = t_scenarios.copy()
|
||||
|
||||
#self.scenario_comboBox.addItem(s.name)
|
||||
self.scenarios_list = scenarios.copy()
|
||||
self.scenarios_list = sorted(scenarios, key=lambda x: x.name, reverse=False)
|
||||
|
||||
for s in self.scenarios_list:
|
||||
self.scenario_comboBox.addItem(s.name)
|
||||
|
||||
@@ -268,18 +290,67 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
self.populateScenarios()
|
||||
# self.scenarioChanged() haven't tried yet
|
||||
|
||||
def populateForces(self, side, combobox, files_list):
|
||||
os.chdir(directories.home_dir)
|
||||
# os.chdir(directories.forces + "/" + side)
|
||||
os.chdir(directories.forces)
|
||||
path = os.getcwd()
|
||||
dir_list = os.listdir(path)
|
||||
logger.info("Looking for " + side + " Forces files in '" + path)
|
||||
def populateForces(self):
|
||||
self.forces_list = []
|
||||
|
||||
for filename in dir_list:
|
||||
if filename.endswith(".miz"):
|
||||
files_list.append(filename)
|
||||
combobox.addItem(filename.removesuffix('.miz'))
|
||||
for path in [directories.forces_downloaded, directories.forces_user]:
|
||||
logger.info("Looking for forces files in " + path)
|
||||
os.chdir(path)
|
||||
module_folders = next(os.walk('.'))[1]
|
||||
|
||||
for folder in module_folders:
|
||||
for filename in os.listdir(folder):
|
||||
if filename.endswith(".miz"):
|
||||
basename = filename.removesuffix('.miz')
|
||||
mizpath = os.path.join(path, folder, filename)
|
||||
config_file_path = os.path.join(path, folder, basename + '.yaml')
|
||||
if os.path.exists(config_file_path):
|
||||
# create forces object with config
|
||||
try:
|
||||
config = yaml.safe_load(open(config_file_path))
|
||||
f = MissionGeneratorTemplates.Forces(mizpath, filename, config)
|
||||
self.forces_list.append(f)
|
||||
except:
|
||||
logger.error("Error in " + config_file_path)
|
||||
|
||||
else:
|
||||
# create forces object without config
|
||||
f = MissionGeneratorTemplates.Forces(mizpath, basename)
|
||||
self.forces_list.append(f)
|
||||
|
||||
self.forces_list = sorted(self.forces_list, key=lambda x: x.name, reverse=False)
|
||||
|
||||
for forces in self.forces_list:
|
||||
self.redforces_comboBox.addItem(forces.name)
|
||||
self.blueforces_comboBox.addItem(forces.name)
|
||||
|
||||
def getImports(self):
|
||||
self.imports_list = []
|
||||
|
||||
for path in [directories.imports_downloaded, directories.imports_user]:
|
||||
logger.info("Looking for imports files in " + path)
|
||||
os.chdir(path)
|
||||
module_folders = next(os.walk('.'))[1]
|
||||
|
||||
for folder in module_folders:
|
||||
for filename in os.listdir(folder):
|
||||
if filename.endswith(".miz"):
|
||||
basename = filename.removesuffix('.miz')
|
||||
mizpath = os.path.join(path, folder, filename)
|
||||
config_file_path = os.path.join(path, folder, basename + '.yaml')
|
||||
if os.path.exists(config_file_path):
|
||||
# create imports object with config
|
||||
try:
|
||||
config = yaml.safe_load(config_file_path)
|
||||
f = MissionGeneratorTemplates.Import(mizpath, filename, config)
|
||||
self.imports_list.append(f)
|
||||
except:
|
||||
logger.error("Error in " + config_file_path)
|
||||
|
||||
else:
|
||||
# create imports object without config
|
||||
f = MissionGeneratorTemplates.Import(mizpath, filename)
|
||||
self.imports_list.append(f)
|
||||
|
||||
def populateSlotSelection(self):
|
||||
self.slot_template_comboBox.addItem("Multiple Slots")
|
||||
@@ -321,8 +392,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
|
||||
# reset some UI elements
|
||||
self.defense_checkBox.setEnabled(True)
|
||||
if self.lockedSlot():
|
||||
self.slot_template_comboBox.removeItem(self.lockedSlot())
|
||||
self.slot_template_comboBox.removeItem(self.lockedSlot())
|
||||
|
||||
self.slot_template_comboBox.setEnabled(True)
|
||||
self.slot_template_comboBox.setCurrentIndex(0)
|
||||
@@ -362,11 +432,14 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
button.setEnabled(True)
|
||||
|
||||
if 'blue_forces' in config:
|
||||
self.blueforces_comboBox.setCurrentIndex(self.blueforces_comboBox.findText(config['blue_forces']))
|
||||
for template in self.forces_list:
|
||||
if template.basename == config['blue_forces']:
|
||||
self.blueforces_comboBox.setCurrentIndex(self.blueforces_comboBox.findText(template.name))
|
||||
|
||||
if 'red_forces' in config:
|
||||
if self.redforces_comboBox.findText(config['red_forces']) >= 0:
|
||||
self.redforces_comboBox.setCurrentIndex(self.redforces_comboBox.findText(config['red_forces']))
|
||||
for template in self.forces_list:
|
||||
if template.basename == config['red_forces']:
|
||||
self.redforces_comboBox.setCurrentIndex(self.redforces_comboBox.findText(template.name))
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Error loading config file: " + str(e))
|
||||
@@ -416,16 +489,16 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
return
|
||||
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
self.slot_template_comboBox.setCurrentIndex(0)
|
||||
|
||||
self.scenario = self.scenarios_list[self.scenario_comboBox.currentIndex()]
|
||||
|
||||
# reset generator options to default
|
||||
default_config = self.loadScenarioConfig(directories.default_config)
|
||||
self.applyScenarioConfig(default_config)
|
||||
|
||||
if self.scenario.config:
|
||||
self.applyScenarioConfig(self.scenario.config)
|
||||
self.m.setConfig(self.scenario.config)
|
||||
else:
|
||||
default_config = self.loadScenarioConfig(directories.default_config)
|
||||
self.applyScenarioConfig(default_config)
|
||||
self.m.setConfig(default_config)
|
||||
|
||||
path = self.scenario.path.removesuffix(".miz") + ".jpg"
|
||||
if os.path.isfile(path):
|
||||
@@ -462,17 +535,27 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
def generateMissionAction(self):
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
|
||||
red_forces_filename = red_forces_files[self.redforces_comboBox.currentIndex()]
|
||||
blue_forces_filename = blue_forces_files[self.blueforces_comboBox.currentIndex()]
|
||||
red_forces = self.forces_list[self.redforces_comboBox.currentIndex()]
|
||||
blue_forces = self.forces_list[self.blueforces_comboBox.currentIndex()]
|
||||
scenario_name = self.scenario.name
|
||||
scenario_path = self.scenario.path
|
||||
source = "offline"
|
||||
|
||||
credits = ("'" + scenario_name + "' mission template by " + self.scenario.author + "\n" +
|
||||
"'" + red_forces.name + "' by " + red_forces.author + "\n" +
|
||||
"'" + blue_forces.name + "' by " + blue_forces.author + "\n"
|
||||
)
|
||||
|
||||
objects = {
|
||||
"imports": self.imports_list,
|
||||
}
|
||||
|
||||
data = {
|
||||
"source": source,
|
||||
"objects": objects,
|
||||
"credits": credits,
|
||||
"scenario_file": scenario_path,
|
||||
"scenario_name": scenario_name,
|
||||
"red_forces_filename": red_forces_filename,
|
||||
"blue_forces_filename": blue_forces_filename,
|
||||
"red_forces_path": red_forces.path,
|
||||
"blue_forces_path": blue_forces.path,
|
||||
"red_quantity": self.redqty_spinBox.value(),
|
||||
"blue_quantity": self.blueqty_spinBox.value(),
|
||||
"inf_spawn_qty": self.inf_spawn_spinBox.value(),
|
||||
@@ -483,7 +566,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
"f_awacs": self.awacs_checkBox.isChecked(),
|
||||
"f_tankers": self.tankers_checkBox.isChecked(),
|
||||
"voiceovers": self.voiceovers_checkBox.isChecked(),
|
||||
"force_offroad": self.force_offroad_checkBox.isChecked(),
|
||||
"force_offroad": self.scenario.getConfigValue("force_offroad", default=False),
|
||||
"game_display": self.game_status_checkBox.isChecked(),
|
||||
"defending": self.defense_checkBox.isChecked(),
|
||||
"slots": self.slot_template_comboBox.currentText(),
|
||||
@@ -494,6 +577,17 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
"smoke_pickup_zones": self.smoke_pickup_zone_checkBox.isChecked(),
|
||||
"player_slots": self.player_slots,
|
||||
"player_hotstart": self.hotstart_checkBox.isChecked(),
|
||||
"random_weather": self.random_weather_checkBox.isChecked(),
|
||||
"time": self.time_comboBox.currentText(),
|
||||
"start_trigger": self.scenario.getConfigValue("start_trigger", default=True),
|
||||
"end_trigger": self.scenario.getConfigValue("end_trigger", default=True),
|
||||
"farp_spawns": self.farp_spawn_checkBox.isChecked(),
|
||||
"staging_logistics_file": self.scenario.getConfigValue("staging_logistics_file", default=None),
|
||||
"zone_farp_file": self.scenario.getConfigValue("zone_farp_file", default=None),
|
||||
"defensive_farp_file": self.scenario.getConfigValue("defensive_farp_file", default=None),
|
||||
"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),
|
||||
}
|
||||
|
||||
logger.info("Generating mission with options:")
|
||||
@@ -674,7 +768,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
|
||||
def checkVersion(splashscreen):
|
||||
|
||||
version_url = 'https://dcs-helicopters.com/app-updates/versioncheck.yaml'
|
||||
|
||||
try:
|
||||
r = requests.get(version_url, allow_redirects=False, timeout=7)
|
||||
v = yaml.safe_load(r.content)
|
||||
@@ -693,31 +787,33 @@ def checkVersion(splashscreen):
|
||||
|
||||
|
||||
|
||||
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.yaml'
|
||||
ratings_url = 'https://dcs-helicopters.com/user-files/ratings.php'
|
||||
|
||||
def loadModules(splashscreen):
|
||||
msg = QMessageBox()
|
||||
msg.setWindowTitle("Unable to connect to server")
|
||||
msg.setText(
|
||||
"We were unable to connect to the RotorOps server to download content. This is a temporary problem, so please try again later. If the problem persists, please get in touch via Discord.")
|
||||
|
||||
try:
|
||||
r = requests.get(modules_map_url, allow_redirects=False, timeout=7)
|
||||
if not r.status_code == 200:
|
||||
logger.error("Could not retrieve the modules map.")
|
||||
x = msg.exec_()
|
||||
return
|
||||
except:
|
||||
logger.error("Failed to retrieve module map.")
|
||||
x = msg.exec_()
|
||||
return
|
||||
|
||||
module_list = yaml.safe_load(r.content)
|
||||
files_success = []
|
||||
files_failed = []
|
||||
new_scenarios = []
|
||||
updated_scenarios = []
|
||||
new_modules = []
|
||||
updated_modules = []
|
||||
outversioned_modules = []
|
||||
|
||||
|
||||
# Download scenarios files
|
||||
#os.chdir(directories.scenarios)
|
||||
|
||||
if module_list:
|
||||
|
||||
for module in module_list:
|
||||
@@ -725,15 +821,31 @@ def loadModules(splashscreen):
|
||||
should_download = False
|
||||
new_module = False
|
||||
|
||||
# only allow predefined paths
|
||||
dp = module_list[module]["path"]
|
||||
if dp not in allowed_paths:
|
||||
logger.warning("Invalid path for module: " + module)
|
||||
continue
|
||||
|
||||
# check if local version already exists
|
||||
package_file_path = os.path.join(directories.scenarios_downloaded, module, "package.yaml")
|
||||
package_file_path = os.path.join(directories.home_dir, module_list[module]["path"], module, "package.yaml")
|
||||
|
||||
if os.path.exists(package_file_path):
|
||||
pkg_file = yaml.safe_load(open(package_file_path))
|
||||
else:
|
||||
pkg_file = None
|
||||
|
||||
#compare local and remote versions
|
||||
# compare required generator version and actual version
|
||||
if 'requires' in module_list[module]:
|
||||
if module_list[module]['requires'] > modules_version:
|
||||
name = 'unknown module'
|
||||
if 'name' in module_list[module]:
|
||||
name = module_list[module]['name']
|
||||
outversioned_modules.append(name)
|
||||
continue
|
||||
|
||||
|
||||
# compare local and remote versions
|
||||
if pkg_file and 'version' in pkg_file:
|
||||
local_version = pkg_file['version']
|
||||
|
||||
@@ -744,6 +856,20 @@ def loadModules(splashscreen):
|
||||
should_download = True
|
||||
new_module = True
|
||||
|
||||
# delete modules with 'remove' dist property
|
||||
if 'dist' in module_list[module] and module_list[module]['dist'] == 'remove':
|
||||
for filename in module_list[module]["files"]:
|
||||
module_dir = os.path.join(directories.home_dir, module_list[module]["path"], module)
|
||||
file_path = os.path.join(module_dir, filename)
|
||||
if os.path.exists(file_path):
|
||||
try:
|
||||
os.remove(file_path)
|
||||
print("Removed module file: " + filename)
|
||||
except:
|
||||
logger.error("Error while trying to remove " + filename)
|
||||
continue
|
||||
|
||||
# download files
|
||||
if should_download:
|
||||
logger.info("Updating module: " + module)
|
||||
module_dir = os.path.join(directories.home_dir, module_list[module]["path"], module)
|
||||
@@ -751,10 +877,11 @@ def loadModules(splashscreen):
|
||||
# download files in remote package
|
||||
for filename in module_list[module]["files"]:
|
||||
broken_file = False
|
||||
type_path = module_list[module]["type"]
|
||||
splash.showMessage("Downloading " + filename + " ...", Qt.AlignHCenter | Qt.AlignTop, Qt.white)
|
||||
app.processEvents()
|
||||
|
||||
url = modules_url + module + "/" + filename
|
||||
url = modules_url + type_path + "/" + module + "/" + filename
|
||||
try:
|
||||
r = requests.get(url, allow_redirects=False, timeout=10)
|
||||
except:
|
||||
@@ -771,9 +898,9 @@ def loadModules(splashscreen):
|
||||
# do some stuff for the dialog popup
|
||||
if filename.endswith('.miz') and "name" in module_list[module]:
|
||||
if new_module:
|
||||
new_scenarios.append(module_list[module]["name"])
|
||||
new_modules.append(module_list[module]["name"])
|
||||
else:
|
||||
updated_scenarios.append(module_list[module]["name"])
|
||||
updated_modules.append(module_list[module]["name"])
|
||||
else:
|
||||
broken_file = True
|
||||
files_failed.append(filename)
|
||||
@@ -791,7 +918,7 @@ def loadModules(splashscreen):
|
||||
logger.error("Problem encountered with modules map.")
|
||||
|
||||
# show a popup if we downloaded any packages
|
||||
if len(files_success) > 0 or len(files_failed) > 0:
|
||||
if len(files_success) > 0 or len(files_failed) > 0 or len(outversioned_modules) > 0:
|
||||
if len(files_failed) > 0:
|
||||
fs = ""
|
||||
for filename in files_failed:
|
||||
@@ -800,16 +927,18 @@ def loadModules(splashscreen):
|
||||
msg = QMessageBox()
|
||||
msg.setWindowTitle("Downloaded Files")
|
||||
message = ""
|
||||
if len(new_scenarios) > 0:
|
||||
message = message + "New scenarios added: \n\n"
|
||||
for name in new_scenarios:
|
||||
if len(new_modules) > 0:
|
||||
message = message + "New modules added: \n\n"
|
||||
for name in new_modules:
|
||||
message = message + name + "\n"
|
||||
if len(updated_scenarios) > 0:
|
||||
message = message + "\nScenarios updated: \n"
|
||||
for name in updated_scenarios:
|
||||
if len(updated_modules) > 0:
|
||||
message = message + "\nModules updated: \n"
|
||||
for name in updated_modules:
|
||||
message = message + name + "\n"
|
||||
if len(files_failed) > 0:
|
||||
message = message + "\n\n" + str(len(files_failed)) + " files failed."
|
||||
if len(outversioned_modules) > 0:
|
||||
message = message + "\n\n" + str(len(outversioned_modules)) + " modules did not download because you need an required update."
|
||||
msg.setText(message)
|
||||
x = msg.exec_()
|
||||
else:
|
||||
|
||||
@@ -19,6 +19,8 @@ class Scenario:
|
||||
self.rating_qty = None
|
||||
self.packageID = None
|
||||
self.local_rating = None
|
||||
self.author = "unknown"
|
||||
|
||||
|
||||
def applyConfig(self, config):
|
||||
self.config = config
|
||||
@@ -31,8 +33,16 @@ class Scenario:
|
||||
if 'tags' in config:
|
||||
for tag in config['tags']:
|
||||
self.tags.append(tag)
|
||||
if 'author' in config:
|
||||
self.author = config["author"]
|
||||
|
||||
|
||||
def getConfigValue(self, key, default):
|
||||
if self.config and key in self.config:
|
||||
return self.config[key]
|
||||
else:
|
||||
return default
|
||||
|
||||
|
||||
def evaluateMiz(self):
|
||||
# check if we have the miz file
|
||||
@@ -116,3 +126,35 @@ class Scenario:
|
||||
|
||||
|
||||
|
||||
class Forces:
|
||||
|
||||
def __init__(self, path, filename, config=None):
|
||||
self.path = path
|
||||
self.filename = filename
|
||||
self.basename = filename.removesuffix('.miz')
|
||||
self.name = filename.removesuffix('.miz')
|
||||
self.author = "unknown"
|
||||
|
||||
|
||||
if config:
|
||||
if 'name' in config:
|
||||
self.name = config["name"]
|
||||
|
||||
if 'author' in config:
|
||||
self.author = config["author"]
|
||||
|
||||
class Import:
|
||||
|
||||
def __init__(self, path, filename, config=None):
|
||||
self.path = path
|
||||
self.filename = filename
|
||||
self.name = filename.removesuffix('.miz')
|
||||
self.author = "unknown"
|
||||
|
||||
|
||||
if config:
|
||||
if 'name' in config:
|
||||
self.name = config["name"]
|
||||
|
||||
if 'author' in config:
|
||||
self.author = config["author"]
|
||||
@@ -34,7 +34,7 @@ class Ui_MainWindow(object):
|
||||
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName("centralwidget")
|
||||
self.logistics_crates_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.logistics_crates_checkBox.setGeometry(QtCore.QRect(990, 211, 251, 28))
|
||||
self.logistics_crates_checkBox.setGeometry(QtCore.QRect(980, 211, 251, 28))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
@@ -42,7 +42,7 @@ class Ui_MainWindow(object):
|
||||
self.logistics_crates_checkBox.setChecked(True)
|
||||
self.logistics_crates_checkBox.setObjectName("logistics_crates_checkBox")
|
||||
self.zone_sams_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.zone_sams_checkBox.setGeometry(QtCore.QRect(990, 320, 241, 28))
|
||||
self.zone_sams_checkBox.setGeometry(QtCore.QRect(980, 320, 241, 28))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
@@ -79,9 +79,9 @@ class Ui_MainWindow(object):
|
||||
self.description_textBrowser.setObjectName("description_textBrowser")
|
||||
self.defense_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.defense_checkBox.setEnabled(True)
|
||||
self.defense_checkBox.setGeometry(QtCore.QRect(470, 120, 156, 28))
|
||||
self.defense_checkBox.setGeometry(QtCore.QRect(470, 130, 156, 28))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setPointSize(11)
|
||||
font.setBold(False)
|
||||
self.defense_checkBox.setFont(font)
|
||||
self.defense_checkBox.setCheckable(True)
|
||||
@@ -116,7 +116,7 @@ class Ui_MainWindow(object):
|
||||
self.scenario_label_8.setFont(font)
|
||||
self.scenario_label_8.setObjectName("scenario_label_8")
|
||||
self.slot_template_comboBox = QtWidgets.QComboBox(self.centralwidget)
|
||||
self.slot_template_comboBox.setGeometry(QtCore.QRect(960, 384, 271, 33))
|
||||
self.slot_template_comboBox.setGeometry(QtCore.QRect(980, 474, 271, 33))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
@@ -216,7 +216,7 @@ class Ui_MainWindow(object):
|
||||
self.e_attack_helos_spinBox.setKeyboardTracking(True)
|
||||
self.e_attack_helos_spinBox.setMinimum(0)
|
||||
self.e_attack_helos_spinBox.setMaximum(8)
|
||||
self.e_attack_helos_spinBox.setProperty("value", 2)
|
||||
self.e_attack_helos_spinBox.setProperty("value", 1)
|
||||
self.e_attack_helos_spinBox.setObjectName("e_attack_helos_spinBox")
|
||||
self.scenario_label_7 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_label_7.setGeometry(QtCore.QRect(570, 180, 271, 24))
|
||||
@@ -226,20 +226,20 @@ class Ui_MainWindow(object):
|
||||
self.scenario_label_7.setFont(font)
|
||||
self.scenario_label_7.setObjectName("scenario_label_7")
|
||||
self.label_2 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.label_2.setGeometry(QtCore.QRect(840, 390, 111, 24))
|
||||
self.label_2.setGeometry(QtCore.QRect(860, 480, 111, 24))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
self.label_2.setFont(font)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.scenario_label_9 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_label_9.setGeometry(QtCore.QRect(490, 450, 251, 23))
|
||||
self.scenario_label_9.setGeometry(QtCore.QRect(480, 401, 251, 23))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
self.scenario_label_9.setFont(font)
|
||||
self.scenario_label_9.setObjectName("scenario_label_9")
|
||||
self.awacs_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.awacs_checkBox.setGeometry(QtCore.QRect(990, 246, 241, 28))
|
||||
self.awacs_checkBox.setGeometry(QtCore.QRect(980, 246, 241, 28))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
@@ -247,7 +247,7 @@ class Ui_MainWindow(object):
|
||||
self.awacs_checkBox.setChecked(True)
|
||||
self.awacs_checkBox.setObjectName("awacs_checkBox")
|
||||
self.tankers_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.tankers_checkBox.setGeometry(QtCore.QRect(990, 282, 241, 28))
|
||||
self.tankers_checkBox.setGeometry(QtCore.QRect(980, 282, 241, 28))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
@@ -255,21 +255,21 @@ class Ui_MainWindow(object):
|
||||
self.tankers_checkBox.setChecked(True)
|
||||
self.tankers_checkBox.setObjectName("tankers_checkBox")
|
||||
self.voiceovers_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.voiceovers_checkBox.setGeometry(QtCore.QRect(960, 517, 171, 24))
|
||||
self.voiceovers_checkBox.setGeometry(QtCore.QRect(500, 594, 171, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.voiceovers_checkBox.setFont(font)
|
||||
self.voiceovers_checkBox.setChecked(True)
|
||||
self.voiceovers_checkBox.setObjectName("voiceovers_checkBox")
|
||||
self.smoke_pickup_zone_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.smoke_pickup_zone_checkBox.setGeometry(QtCore.QRect(960, 460, 271, 24))
|
||||
self.smoke_pickup_zone_checkBox.setGeometry(QtCore.QRect(500, 541, 231, 20))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.smoke_pickup_zone_checkBox.setFont(font)
|
||||
self.smoke_pickup_zone_checkBox.setChecked(False)
|
||||
self.smoke_pickup_zone_checkBox.setObjectName("smoke_pickup_zone_checkBox")
|
||||
self.game_status_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.game_status_checkBox.setGeometry(QtCore.QRect(960, 490, 271, 24))
|
||||
self.game_status_checkBox.setGeometry(QtCore.QRect(500, 570, 221, 21))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.game_status_checkBox.setFont(font)
|
||||
@@ -277,24 +277,24 @@ class Ui_MainWindow(object):
|
||||
self.game_status_checkBox.setTristate(False)
|
||||
self.game_status_checkBox.setObjectName("game_status_checkBox")
|
||||
self.label = QtWidgets.QLabel(self.centralwidget)
|
||||
self.label.setGeometry(QtCore.QRect(570, 380, 261, 23))
|
||||
self.label.setGeometry(QtCore.QRect(570, 340, 261, 23))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
self.label.setFont(font)
|
||||
self.label.setObjectName("label")
|
||||
self.inf_spawn_spinBox = QtWidgets.QSpinBox(self.centralwidget)
|
||||
self.inf_spawn_spinBox.setGeometry(QtCore.QRect(510, 380, 47, 31))
|
||||
self.inf_spawn_spinBox.setGeometry(QtCore.QRect(510, 340, 51, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.inf_spawn_spinBox.setFont(font)
|
||||
self.inf_spawn_spinBox.setButtonSymbols(QtWidgets.QAbstractSpinBox.PlusMinus)
|
||||
self.inf_spawn_spinBox.setMinimum(0)
|
||||
self.inf_spawn_spinBox.setMaximum(20)
|
||||
self.inf_spawn_spinBox.setProperty("value", 2)
|
||||
self.inf_spawn_spinBox.setProperty("value", 0)
|
||||
self.inf_spawn_spinBox.setObjectName("inf_spawn_spinBox")
|
||||
self.troop_drop_spinBox = QtWidgets.QSpinBox(self.centralwidget)
|
||||
self.troop_drop_spinBox.setGeometry(QtCore.QRect(510, 330, 47, 31))
|
||||
self.troop_drop_spinBox.setGeometry(QtCore.QRect(510, 300, 51, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.troop_drop_spinBox.setFont(font)
|
||||
@@ -303,23 +303,23 @@ class Ui_MainWindow(object):
|
||||
self.troop_drop_spinBox.setMaximum(10)
|
||||
self.troop_drop_spinBox.setProperty("value", 4)
|
||||
self.troop_drop_spinBox.setObjectName("troop_drop_spinBox")
|
||||
self.force_offroad_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.force_offroad_checkBox.setGeometry(QtCore.QRect(960, 548, 161, 24))
|
||||
self.random_weather_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.random_weather_checkBox.setGeometry(QtCore.QRect(980, 420, 211, 24))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.force_offroad_checkBox.setFont(font)
|
||||
self.force_offroad_checkBox.setChecked(False)
|
||||
self.force_offroad_checkBox.setTristate(False)
|
||||
self.force_offroad_checkBox.setObjectName("force_offroad_checkBox")
|
||||
self.random_weather_checkBox.setFont(font)
|
||||
self.random_weather_checkBox.setChecked(False)
|
||||
self.random_weather_checkBox.setTristate(False)
|
||||
self.random_weather_checkBox.setObjectName("random_weather_checkBox")
|
||||
self.label_3 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.label_3.setGeometry(QtCore.QRect(570, 330, 281, 23))
|
||||
self.label_3.setGeometry(QtCore.QRect(570, 300, 281, 23))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
self.label_3.setFont(font)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.apcs_spawn_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.apcs_spawn_checkBox.setGeometry(QtCore.QRect(990, 180, 251, 27))
|
||||
self.apcs_spawn_checkBox.setGeometry(QtCore.QRect(980, 180, 251, 27))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
@@ -328,7 +328,7 @@ class Ui_MainWindow(object):
|
||||
self.apcs_spawn_checkBox.setObjectName("apcs_spawn_checkBox")
|
||||
self.generateButton = QtWidgets.QPushButton(self.centralwidget)
|
||||
self.generateButton.setEnabled(True)
|
||||
self.generateButton.setGeometry(QtCore.QRect(710, 600, 231, 51))
|
||||
self.generateButton.setGeometry(QtCore.QRect(750, 600, 231, 51))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
font.setBold(True)
|
||||
@@ -336,7 +336,7 @@ class Ui_MainWindow(object):
|
||||
self.generateButton.setStyleSheet("")
|
||||
self.generateButton.setObjectName("generateButton")
|
||||
self.farp_always = QtWidgets.QRadioButton(self.centralwidget)
|
||||
self.farp_always.setGeometry(QtCore.QRect(510, 480, 261, 24))
|
||||
self.farp_always.setGeometry(QtCore.QRect(500, 431, 261, 24))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.farp_always.setFont(font)
|
||||
@@ -345,14 +345,14 @@ class Ui_MainWindow(object):
|
||||
self.farp_buttonGroup.setObjectName("farp_buttonGroup")
|
||||
self.farp_buttonGroup.addButton(self.farp_always)
|
||||
self.farp_never = QtWidgets.QRadioButton(self.centralwidget)
|
||||
self.farp_never.setGeometry(QtCore.QRect(510, 540, 271, 24))
|
||||
self.farp_never.setGeometry(QtCore.QRect(500, 491, 271, 24))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.farp_never.setFont(font)
|
||||
self.farp_never.setObjectName("farp_never")
|
||||
self.farp_buttonGroup.addButton(self.farp_never)
|
||||
self.farp_gunits = QtWidgets.QRadioButton(self.centralwidget)
|
||||
self.farp_gunits.setGeometry(QtCore.QRect(510, 509, 261, 24))
|
||||
self.farp_gunits.setGeometry(QtCore.QRect(500, 460, 261, 24))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.farp_gunits.setFont(font)
|
||||
@@ -397,7 +397,7 @@ class Ui_MainWindow(object):
|
||||
self.rateButton1.setText("")
|
||||
self.rateButton1.setObjectName("rateButton1")
|
||||
self.hotstart_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.hotstart_checkBox.setGeometry(QtCore.QRect(960, 430, 271, 24))
|
||||
self.hotstart_checkBox.setGeometry(QtCore.QRect(980, 520, 271, 24))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.hotstart_checkBox.setFont(font)
|
||||
@@ -440,6 +440,21 @@ class Ui_MainWindow(object):
|
||||
self.rateButton5.setStyleSheet("border-image:url(\'../assets/star_full.png\');")
|
||||
self.rateButton5.setText("")
|
||||
self.rateButton5.setObjectName("rateButton5")
|
||||
self.time_comboBox = QtWidgets.QComboBox(self.centralwidget)
|
||||
self.time_comboBox.setGeometry(QtCore.QRect(980, 370, 161, 33))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(False)
|
||||
self.time_comboBox.setFont(font)
|
||||
self.time_comboBox.setObjectName("time_comboBox")
|
||||
self.farp_spawn_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.farp_spawn_checkBox.setGeometry(QtCore.QRect(980, 550, 271, 24))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.farp_spawn_checkBox.setFont(font)
|
||||
self.farp_spawn_checkBox.setChecked(False)
|
||||
self.farp_spawn_checkBox.setTristate(False)
|
||||
self.farp_spawn_checkBox.setObjectName("farp_spawn_checkBox")
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QtWidgets.QMenuBar(MainWindow)
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1280, 29))
|
||||
@@ -564,10 +579,10 @@ class Ui_MainWindow(object):
|
||||
def retranslateUi(self, MainWindow):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MainWindow.setWindowTitle(_translate("MainWindow", "RotorOps Mission Generator"))
|
||||
self.logistics_crates_checkBox.setStatusTip(_translate("MainWindow", "Enable CTLD logistics crates for building ground units and air defenses. Pickup logistics containers to create new logistics sites."))
|
||||
self.logistics_crates_checkBox.setText(_translate("MainWindow", "Logistics"))
|
||||
self.zone_sams_checkBox.setStatusTip(_translate("MainWindow", "Inactive conflict zones will be protected by SAMs. When a zone is cleared, SAMs at next active zone will be destroyed."))
|
||||
self.zone_sams_checkBox.setText(_translate("MainWindow", "Inactive Zone SAMs"))
|
||||
self.logistics_crates_checkBox.setStatusTip(_translate("MainWindow", "Enable a base or FARP near the start position that can spawn CTLD crates for building ground units and air defenses. Sling load the logistics containers to create new logistics sites."))
|
||||
self.logistics_crates_checkBox.setText(_translate("MainWindow", "Logistics Base"))
|
||||
self.zone_sams_checkBox.setStatusTip(_translate("MainWindow", "Inactive conflict zones will be protected by SAMs. When a zone is cleared, SAMs at next active zone will be destroyed. No effect if Blue on defense."))
|
||||
self.zone_sams_checkBox.setText(_translate("MainWindow", "Protect Inactive Zones"))
|
||||
self.red_forces_label.setText(_translate("MainWindow", "Red Forces:"))
|
||||
self.scenario_comboBox.setStatusTip(_translate("MainWindow", "Tip: You can create your own templates that include mission options like kneeboards, briefings, weather, static units, triggers, scripts, etc."))
|
||||
self.description_textBrowser.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
@@ -575,6 +590,7 @@ class Ui_MainWindow(object):
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'Segoe UI\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
|
||||
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'MS Shell Dlg 2\'; font-size:10pt;\">Provide close air support for our convoys as we take back Las Vegas from the enemy!</span></p></body></html>"))
|
||||
self.defense_checkBox.setStatusTip(_translate("MainWindow", "Turn the tables and defend your zones against the enemy\'s attack."))
|
||||
self.defense_checkBox.setText(_translate("MainWindow", "Blue on Defense"))
|
||||
self.redqty_spinBox.setStatusTip(_translate("MainWindow", "Red vehicle groups per staging or conflict zone."))
|
||||
self.redforces_comboBox.setStatusTip(_translate("MainWindow", "Tip: You can create your own custom ground forces groups to be automatically generated."))
|
||||
@@ -602,20 +618,20 @@ class Ui_MainWindow(object):
|
||||
self.tankers_checkBox.setText(_translate("MainWindow", "Friendly Tankers"))
|
||||
self.voiceovers_checkBox.setStatusTip(_translate("MainWindow", "Voiceovers from the ground commander. Helps keep focus on the active zone."))
|
||||
self.voiceovers_checkBox.setText(_translate("MainWindow", "Voiceovers"))
|
||||
self.smoke_pickup_zone_checkBox.setStatusTip(_translate("MainWindow", "Infinite troop pickup zones will be marked with blue smoke."))
|
||||
self.smoke_pickup_zone_checkBox.setStatusTip(_translate("MainWindow", "Troop pickup zones and FARPs will be marked with blue smoke."))
|
||||
self.smoke_pickup_zone_checkBox.setText(_translate("MainWindow", "Smoke at Troop Pickup Zones"))
|
||||
self.game_status_checkBox.setStatusTip(_translate("MainWindow", "Enable an onscreen zone status display. This helps keep focus on the active conflict zone."))
|
||||
self.game_status_checkBox.setText(_translate("MainWindow", "Game Status Display"))
|
||||
self.label.setStatusTip(_translate("MainWindow", "This value is multiplied by the number of spawn zones in the mission template."))
|
||||
self.label.setText(_translate("MainWindow", "Infantry Spawns per zone"))
|
||||
self.label.setStatusTip(_translate("MainWindow", "Total number of infantry groups to spawn per game."))
|
||||
self.label.setText(_translate("MainWindow", "Infantry Spawns"))
|
||||
self.inf_spawn_spinBox.setStatusTip(_translate("MainWindow", "This value is multiplied by the number of spawn zones in the mission template."))
|
||||
self.troop_drop_spinBox.setStatusTip(_translate("MainWindow", "The number of troop drops per transport helicopter flight."))
|
||||
self.force_offroad_checkBox.setStatusTip(_translate("MainWindow", "May help prevent long travel times or pathfinding issues. "))
|
||||
self.force_offroad_checkBox.setText(_translate("MainWindow", "Force Offroad"))
|
||||
self.random_weather_checkBox.setStatusTip(_translate("MainWindow", "Random weather preset will be applied."))
|
||||
self.random_weather_checkBox.setText(_translate("MainWindow", "Random Weather"))
|
||||
self.label_3.setStatusTip(_translate("MainWindow", "The number of troop drops per transport helicopter flight."))
|
||||
self.label_3.setText(_translate("MainWindow", "Transport Drop Points"))
|
||||
self.apcs_spawn_checkBox.setStatusTip(_translate("MainWindow", "Friendly/enemy APCs will drop infantry when reaching a new conflict zone. Disables infinite troop pickups from conflict zones (you must pick up existing troops)."))
|
||||
self.apcs_spawn_checkBox.setText(_translate("MainWindow", "Dynamic Troops"))
|
||||
self.apcs_spawn_checkBox.setStatusTip(_translate("MainWindow", "Friendly/enemy APCs will drop infantry when reaching a new conflict zone. "))
|
||||
self.apcs_spawn_checkBox.setText(_translate("MainWindow", "APCs Spawn Infantry"))
|
||||
self.generateButton.setStatusTip(_translate("MainWindow", "Click to generate mission."))
|
||||
self.generateButton.setText(_translate("MainWindow", "GENERATE MISSION"))
|
||||
self.farp_always.setStatusTip(_translate("MainWindow", "Always spawn a FARP in defeated conflict zones."))
|
||||
@@ -627,12 +643,15 @@ class Ui_MainWindow(object):
|
||||
self.nextScenario_pushButton.setText(_translate("MainWindow", ">"))
|
||||
self.prevScenario_pushButton.setText(_translate("MainWindow", "<"))
|
||||
self.rateButton1.setStatusTip(_translate("MainWindow", "Submit a review for this mission scenario."))
|
||||
self.hotstart_checkBox.setStatusTip(_translate("MainWindow", "Player helicopters start with engines running on the ground. No effect if player slots says \'Locked to scenario\'"))
|
||||
self.hotstart_checkBox.setStatusTip(_translate("MainWindow", "Player helicopters start with engines running on the ground. No effect for FARP spawns or if player slots says \'Locked to scenario\'"))
|
||||
self.hotstart_checkBox.setText(_translate("MainWindow", "Player Hotstart"))
|
||||
self.rateButton2.setStatusTip(_translate("MainWindow", "Submit a review for this mission scenario."))
|
||||
self.rateButton3.setStatusTip(_translate("MainWindow", "Submit a review for this mission scenario."))
|
||||
self.rateButton4.setStatusTip(_translate("MainWindow", "Submit a review for this mission scenario."))
|
||||
self.rateButton5.setStatusTip(_translate("MainWindow", "Submit a review for this mission scenario."))
|
||||
self.time_comboBox.setStatusTip(_translate("MainWindow", "Mission start time of day. \'Default\' is the start time as defined by the mission template designer."))
|
||||
self.farp_spawn_checkBox.setStatusTip(_translate("MainWindow", "Add helicopter slots where zone FARPs will be built. Helicopters will be empty fuel, requiring the FARP to be established to refuel and rearm."))
|
||||
self.farp_spawn_checkBox.setText(_translate("MainWindow", "Spawns at zone FARPs"))
|
||||
self.menuMap.setTitle(_translate("MainWindow", "Map"))
|
||||
self.menuFilter.setTitle(_translate("MainWindow", "Filter"))
|
||||
self.menuPreferences.setTitle(_translate("MainWindow", "Preferences"))
|
||||
@@ -658,8 +677,8 @@ class Ui_MainWindow(object):
|
||||
self.action_downloadButton.setToolTip(_translate("MainWindow", "_downloadButton"))
|
||||
self.action_rateButton1.setText(_translate("MainWindow", "_rateButton1"))
|
||||
self.action_rateButton1.setToolTip(_translate("MainWindow", "_rateButton1"))
|
||||
self.actionSingle_Player.setText(_translate("MainWindow", "Single-Player"))
|
||||
self.actionCo_Op.setText(_translate("MainWindow", "Co-Op"))
|
||||
self.actionSingle_Player.setText(_translate("MainWindow", "Single-Player Only"))
|
||||
self.actionCo_Op.setText(_translate("MainWindow", "Co-Op Only"))
|
||||
self.actionMapMenu.setText(_translate("MainWindow", "actionMapMenu"))
|
||||
self.actionFilterMenu.setText(_translate("MainWindow", "FilterMenu"))
|
||||
self.action_rateButton2.setText(_translate("MainWindow", "_rateButton2"))
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<widget class="QCheckBox" name="logistics_crates_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>990</x>
|
||||
<x>980</x>
|
||||
<y>211</y>
|
||||
<width>251</width>
|
||||
<height>28</height>
|
||||
@@ -66,10 +66,10 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Enable CTLD logistics crates for building ground units and air defenses. Pickup logistics containers to create new logistics sites.</string>
|
||||
<string>Enable a base or FARP near the start position that can spawn CTLD crates for building ground units and air defenses. Sling load the logistics containers to create new logistics sites.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Logistics</string>
|
||||
<string>Logistics Base</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
@@ -78,7 +78,7 @@
|
||||
<widget class="QCheckBox" name="zone_sams_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>990</x>
|
||||
<x>980</x>
|
||||
<y>320</y>
|
||||
<width>241</width>
|
||||
<height>28</height>
|
||||
@@ -91,10 +91,10 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Inactive conflict zones will be protected by SAMs. When a zone is cleared, SAMs at next active zone will be destroyed.</string>
|
||||
<string>Inactive conflict zones will be protected by SAMs. When a zone is cleared, SAMs at next active zone will be destroyed. No effect if Blue on defense.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Inactive Zone SAMs</string>
|
||||
<string>Protect Inactive Zones</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="red_forces_label">
|
||||
@@ -191,17 +191,20 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>470</x>
|
||||
<y>120</y>
|
||||
<y>130</y>
|
||||
<width>156</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
<pointsize>11</pointsize>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Turn the tables and defend your zones against the enemy's attack.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Blue on Defense</string>
|
||||
</property>
|
||||
@@ -289,8 +292,8 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QComboBox" name="slot_template_comboBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>960</x>
|
||||
<y>384</y>
|
||||
<x>980</x>
|
||||
<y>474</y>
|
||||
<width>271</width>
|
||||
<height>33</height>
|
||||
</rect>
|
||||
@@ -564,7 +567,7 @@ p, li { white-space: pre-wrap; }
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="scenario_label_7">
|
||||
@@ -592,8 +595,8 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>840</x>
|
||||
<y>390</y>
|
||||
<x>860</x>
|
||||
<y>480</y>
|
||||
<width>111</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
@@ -611,8 +614,8 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QLabel" name="scenario_label_9">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>490</x>
|
||||
<y>450</y>
|
||||
<x>480</x>
|
||||
<y>401</y>
|
||||
<width>251</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
@@ -629,7 +632,7 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QCheckBox" name="awacs_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>990</x>
|
||||
<x>980</x>
|
||||
<y>246</y>
|
||||
<width>241</width>
|
||||
<height>28</height>
|
||||
@@ -654,7 +657,7 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QCheckBox" name="tankers_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>990</x>
|
||||
<x>980</x>
|
||||
<y>282</y>
|
||||
<width>241</width>
|
||||
<height>28</height>
|
||||
@@ -679,10 +682,10 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QCheckBox" name="voiceovers_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>960</x>
|
||||
<y>517</y>
|
||||
<x>500</x>
|
||||
<y>594</y>
|
||||
<width>171</width>
|
||||
<height>24</height>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -703,10 +706,10 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QCheckBox" name="smoke_pickup_zone_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>960</x>
|
||||
<y>460</y>
|
||||
<width>271</width>
|
||||
<height>24</height>
|
||||
<x>500</x>
|
||||
<y>541</y>
|
||||
<width>231</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -715,7 +718,7 @@ p, li { white-space: pre-wrap; }
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Infinite troop pickup zones will be marked with blue smoke.</string>
|
||||
<string>Troop pickup zones and FARPs will be marked with blue smoke.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Smoke at Troop Pickup Zones</string>
|
||||
@@ -727,10 +730,10 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QCheckBox" name="game_status_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>960</x>
|
||||
<y>490</y>
|
||||
<width>271</width>
|
||||
<height>24</height>
|
||||
<x>500</x>
|
||||
<y>570</y>
|
||||
<width>221</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -755,7 +758,7 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>570</x>
|
||||
<y>380</y>
|
||||
<y>340</y>
|
||||
<width>261</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
@@ -767,18 +770,18 @@ p, li { white-space: pre-wrap; }
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>This value is multiplied by the number of spawn zones in the mission template.</string>
|
||||
<string>Total number of infantry groups to spawn per game.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Infantry Spawns per zone</string>
|
||||
<string>Infantry Spawns</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="inf_spawn_spinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>510</x>
|
||||
<y>380</y>
|
||||
<width>47</width>
|
||||
<y>340</y>
|
||||
<width>51</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -800,15 +803,15 @@ p, li { white-space: pre-wrap; }
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="troop_drop_spinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>510</x>
|
||||
<y>330</y>
|
||||
<width>47</width>
|
||||
<y>300</y>
|
||||
<width>51</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -833,12 +836,12 @@ p, li { white-space: pre-wrap; }
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="force_offroad_checkBox">
|
||||
<widget class="QCheckBox" name="random_weather_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>960</x>
|
||||
<y>548</y>
|
||||
<width>161</width>
|
||||
<x>980</x>
|
||||
<y>420</y>
|
||||
<width>211</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -848,10 +851,10 @@ p, li { white-space: pre-wrap; }
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>May help prevent long travel times or pathfinding issues. </string>
|
||||
<string>Random weather preset will be applied.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Force Offroad</string>
|
||||
<string>Random Weather</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
@@ -864,7 +867,7 @@ p, li { white-space: pre-wrap; }
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>570</x>
|
||||
<y>330</y>
|
||||
<y>300</y>
|
||||
<width>281</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
@@ -885,7 +888,7 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QCheckBox" name="apcs_spawn_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>990</x>
|
||||
<x>980</x>
|
||||
<y>180</y>
|
||||
<width>251</width>
|
||||
<height>27</height>
|
||||
@@ -898,10 +901,10 @@ p, li { white-space: pre-wrap; }
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Friendly/enemy APCs will drop infantry when reaching a new conflict zone. Disables infinite troop pickups from conflict zones (you must pick up existing troops).</string>
|
||||
<string>Friendly/enemy APCs will drop infantry when reaching a new conflict zone. </string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dynamic Troops</string>
|
||||
<string>APCs Spawn Infantry</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
@@ -913,7 +916,7 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>710</x>
|
||||
<x>750</x>
|
||||
<y>600</y>
|
||||
<width>231</width>
|
||||
<height>51</height>
|
||||
@@ -938,8 +941,8 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QRadioButton" name="farp_always">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>510</x>
|
||||
<y>480</y>
|
||||
<x>500</x>
|
||||
<y>431</y>
|
||||
<width>261</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
@@ -962,8 +965,8 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QRadioButton" name="farp_never">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>510</x>
|
||||
<y>540</y>
|
||||
<x>500</x>
|
||||
<y>491</y>
|
||||
<width>271</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
@@ -986,8 +989,8 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QRadioButton" name="farp_gunits">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>510</x>
|
||||
<y>509</y>
|
||||
<x>500</x>
|
||||
<y>460</y>
|
||||
<width>261</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
@@ -1131,8 +1134,8 @@ p, li { white-space: pre-wrap; }
|
||||
<widget class="QCheckBox" name="hotstart_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>960</x>
|
||||
<y>430</y>
|
||||
<x>980</x>
|
||||
<y>520</y>
|
||||
<width>271</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
@@ -1143,7 +1146,7 @@ p, li { white-space: pre-wrap; }
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Player helicopters start with engines running on the ground. No effect if player slots says 'Locked to scenario'</string>
|
||||
<string>Player helicopters start with engines running on the ground. No effect for FARP spawns or if player slots says 'Locked to scenario'</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Player Hotstart</string>
|
||||
@@ -1263,6 +1266,52 @@ p, li { white-space: pre-wrap; }
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="time_comboBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>980</x>
|
||||
<y>370</y>
|
||||
<width>161</width>
|
||||
<height>33</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Mission start time of day. 'Default' is the start time as defined by the mission template designer.</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="farp_spawn_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>980</x>
|
||||
<y>550</y>
|
||||
<width>271</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Add helicopter slots where zone FARPs will be built. Helicopters will be empty fuel, requiring the FARP to be established to refuel and rearm.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Spawns at zone FARPs</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
@@ -1471,7 +1520,7 @@ p, li { white-space: pre-wrap; }
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Single-Player</string>
|
||||
<string>Single-Player Only</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCo_Op">
|
||||
@@ -1482,7 +1531,7 @@ p, li { white-space: pre-wrap; }
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Co-Op</string>
|
||||
<string>Co-Op Only</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMapMenu">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,6 @@ def triggerSetup(rops, options):
|
||||
# Add the first trigger
|
||||
trig = dcs.triggers.TriggerOnce(comment="RotorOps Setup Scripts")
|
||||
trig.rules.append(dcs.condition.TimeAfter(1))
|
||||
#trig.actions.append(dcs.action.DoScriptFile(rops.scripts["mist_4_4_90.lua"]))
|
||||
trig.actions.append(dcs.action.DoScriptFile(rops.scripts["mist_4_5_107_grimm.lua"]))
|
||||
trig.actions.append(dcs.action.DoScriptFile(rops.scripts["Splash_Damage_2_0.lua"]))
|
||||
trig.actions.append(dcs.action.DoScriptFile(rops.scripts["CTLD.lua"]))
|
||||
@@ -29,11 +28,13 @@ def triggerSetup(rops, options):
|
||||
"RotorOps.voice_overs = " + lb("voiceovers") + "\n\n" +
|
||||
"RotorOps.zone_status_display = " + lb("game_display") + "\n\n" +
|
||||
"RotorOps.inf_spawn_messages = true\n\n" +
|
||||
"RotorOps.inf_spawns_per_zone = " + lb("inf_spawn_qty") + "\n\n" +
|
||||
"RotorOps.inf_spawns_total = " + lb("inf_spawn_qty") + "\n\n" +
|
||||
"RotorOps.apcs_spawn_infantry = " + lb("apc_spawns_inf") + " \n\n")
|
||||
if not options["smoke_pickup_zones"]:
|
||||
script = script + 'RotorOps.pickup_zone_smoke = "none"\n\n'
|
||||
trig.actions.append(dcs.action.DoScript(dcs.action.String((script))))
|
||||
if options["script"]:
|
||||
trig.actions.append(dcs.action.DoScript(dcs.action.String((options["script"]))))
|
||||
rops.m.triggerrules.triggers.append(trig)
|
||||
|
||||
# Add the second trigger
|
||||
@@ -50,11 +51,12 @@ def triggerSetup(rops, options):
|
||||
|
||||
rops.m.triggerrules.triggers.append(trig)
|
||||
|
||||
# Add the third trigger
|
||||
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict Start")
|
||||
trig.rules.append(dcs.condition.TimeAfter(10))
|
||||
trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.startConflict(100)")))
|
||||
rops.m.triggerrules.triggers.append(trig)
|
||||
# Add the start trigger
|
||||
if options["start_trigger"] is not False:
|
||||
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict Start")
|
||||
trig.rules.append(dcs.condition.TimeAfter(10))
|
||||
trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.startConflict(100)")))
|
||||
rops.m.triggerrules.triggers.append(trig)
|
||||
|
||||
# Add generic zone-based triggers
|
||||
for index, zone_name in enumerate(rops.conflict_zones):
|
||||
@@ -81,6 +83,19 @@ def triggerSetup(rops, options):
|
||||
dcs.action.String("Group.destroy(Group.getByName('Static " + zone_name + " Protection SAM'))")))
|
||||
rops.m.triggerrules.triggers.append(z_sams_trig)
|
||||
|
||||
# Deactivate zone FARPs and player slots in defensive mode:
|
||||
# this will also deactivate players already in the air.
|
||||
# if options["defending"]:
|
||||
# for index, zone_name in enumerate(rops.conflict_zones):
|
||||
# z_farps_trig = dcs.triggers.TriggerOnce(comment="Deactivate " + zone_name + " FARP")
|
||||
# z_farps_trig.rules.append(dcs.condition.FlagEquals(game_flag, index + 1))
|
||||
# z_farps_trig.actions.append(dcs.action.DeactivateGroup(rops.m.country(jtf_blue).find_group(zone_name + " FARP Static").id))
|
||||
# for group in rops.all_zones[zone_name].player_helo_spawns:
|
||||
# z_farps_trig.actions.append(
|
||||
# dcs.action.DeactivateGroup(
|
||||
# group.id))
|
||||
# rops.m.triggerrules.triggers.append(z_farps_trig)
|
||||
|
||||
# Zone FARPS always
|
||||
if options["zone_farps"] == "farp_always" and not options["defending"]:
|
||||
for index, zone_name in enumerate(rops.conflict_zones):
|
||||
@@ -92,9 +107,13 @@ def triggerSetup(rops, options):
|
||||
z_farps_trig.rules.append(dcs.condition.FlagEquals(game_flag, index + 1))
|
||||
z_farps_trig.actions.append(
|
||||
dcs.action.ActivateGroup(rops.m.country(jtf_blue).find_group(previous_zone + " FARP Static").id))
|
||||
# z_farps_trig.actions.append(dcs.action.SoundToAll(str(rops.res_map['forward_base_established.ogg'])))
|
||||
# Activate late-activated helicopters at FARPs. Doesn't work consistently
|
||||
# for group in rops.all_zones[previous_zone].player_helo_spawns:
|
||||
# z_farps_trig.actions.append(
|
||||
# dcs.action.ActivateGroup(
|
||||
# group.id))
|
||||
z_farps_trig.actions.append(dcs.action.DoScript(dcs.action.String(
|
||||
"RotorOps.farpEstablished(" + str(index) + ")")))
|
||||
"RotorOps.farpEstablished(" + str(index) + ", '" + previous_zone + "_FARP')")))
|
||||
rops.m.triggerrules.triggers.append(z_farps_trig)
|
||||
|
||||
# Zone FARPS conditional on staged units remaining
|
||||
@@ -111,9 +130,13 @@ def triggerSetup(rops, options):
|
||||
"--The 100 flag indicates which zone is active. The 111 flag value is the percentage of staged units remaining")))
|
||||
z_farps_trig.actions.append(
|
||||
dcs.action.ActivateGroup(rops.m.country(jtf_blue).find_group(previous_zone + " FARP Static").id))
|
||||
# z_farps_trig.actions.append(dcs.action.SoundToAll(str(rops.res_map['forward_base_established.ogg'])))
|
||||
# Activate late-activated helicopters at FARPs. Doesn't work consistently
|
||||
# for group in rops.all_zones[previous_zone].player_helo_spawns:
|
||||
# z_farps_trig.actions.append(
|
||||
# dcs.action.ActivateGroup(
|
||||
# group.id))
|
||||
z_farps_trig.actions.append(dcs.action.DoScript(dcs.action.String(
|
||||
"RotorOps.farpEstablished(" + str(index) + ")")))
|
||||
"RotorOps.farpEstablished(" + str(index) + ", '" + previous_zone + "_FARP')")))
|
||||
rops.m.triggerrules.triggers.append(z_farps_trig)
|
||||
|
||||
# Add attack helos triggers
|
||||
@@ -156,17 +179,23 @@ def triggerSetup(rops, options):
|
||||
rops.m.triggerrules.triggers.append(z_weak_trig)
|
||||
|
||||
# Add game won/lost triggers
|
||||
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict WON")
|
||||
trig.rules.append(dcs.condition.FlagEquals(game_flag, 99))
|
||||
trig.actions.append(
|
||||
dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is WON")))
|
||||
trig.actions.append(
|
||||
dcs.action.DoScript(dcs.action.String("RotorOps.gameMsg(RotorOps.gameMsgs.success)")))
|
||||
rops.m.triggerrules.triggers.append(trig)
|
||||
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict LOST")
|
||||
trig.rules.append(dcs.condition.FlagEquals(game_flag, 98))
|
||||
trig.actions.append(
|
||||
dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is LOST")))
|
||||
trig.actions.append(
|
||||
dcs.action.DoScript(dcs.action.String("RotorOps.gameMsg(RotorOps.gameMsgs.failure)")))
|
||||
rops.m.triggerrules.triggers.append(trig)
|
||||
|
||||
|
||||
# Add game won triggers
|
||||
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict WON")
|
||||
trig.rules.append(dcs.condition.FlagEquals(game_flag, 99))
|
||||
trig.actions.append(
|
||||
dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is WON")))
|
||||
if options["end_trigger"] is not False:
|
||||
trig.actions.append(
|
||||
dcs.action.DoScript(dcs.action.String("RotorOps.gameMsg(RotorOps.gameMsgs.success)")))
|
||||
rops.m.triggerrules.triggers.append(trig)
|
||||
|
||||
# Add game lost triggers
|
||||
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict LOST")
|
||||
trig.rules.append(dcs.condition.FlagEquals(game_flag, 98))
|
||||
trig.actions.append(
|
||||
dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is LOST")))
|
||||
if options["end_trigger"] is not False:
|
||||
trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.gameMsg(RotorOps.gameMsgs.failure)")))
|
||||
rops.m.triggerrules.triggers.append(trig)
|
||||
@@ -1,12 +1,15 @@
|
||||
import math
|
||||
import dcs
|
||||
from MissionGenerator import logger
|
||||
import os
|
||||
|
||||
|
||||
class ImportObjects:
|
||||
|
||||
def __init__(self, mizfile):
|
||||
self.pad_unit = True #todo: use this to hold a unit for helicopter placement on ships ie flight_group_from_unit
|
||||
self.pad_unit = True # todo: use this to hold a unit for helicopter placement on ships ie flight_group_from_unit
|
||||
if not mizfile or not os.path.exists(mizfile):
|
||||
raise Exception("Cannot find required file: " + str(mizfile))
|
||||
logger.info("Importing objects from " + mizfile)
|
||||
self.source_mission = dcs.mission.Mission()
|
||||
self.source_mission.load_file(mizfile)
|
||||
@@ -32,7 +35,6 @@ class ImportObjects:
|
||||
self.copyVehicles(mission, dest_country_name, dest_name, dest_point, dest_heading), \
|
||||
self.copyHelicopters(mission, dest_country_name, dest_name, dest_point, dest_heading)
|
||||
|
||||
|
||||
def anchorByGroupName(self, group_name):
|
||||
group = self.source_mission.find_group(group_name)
|
||||
if group:
|
||||
@@ -49,24 +51,26 @@ class ImportObjects:
|
||||
coalition = self.source_mission.coalition.get(side)
|
||||
for country_name in coalition.countries:
|
||||
|
||||
group_types = [coalition.countries[country_name].static_group, coalition.countries[country_name].vehicle_group, coalition.countries[country_name].helicopter_group, coalition.countries[country_name].plane_group,
|
||||
group_types = [coalition.countries[country_name].static_group,
|
||||
coalition.countries[country_name].vehicle_group,
|
||||
coalition.countries[country_name].helicopter_group,
|
||||
coalition.countries[country_name].plane_group,
|
||||
coalition.countries[country_name].ship_group]
|
||||
|
||||
for index, group_type in enumerate(group_types):
|
||||
for group in group_type:
|
||||
|
||||
if index == 0: # Statics
|
||||
if index == 0: # Statics
|
||||
self.statics.append(group)
|
||||
elif index == 1: # Vehicles
|
||||
self.vehicles.append(group)
|
||||
elif index == 2: # Helicopters
|
||||
elif index == 2: # Helicopters
|
||||
self.helicopters.append(group)
|
||||
elif index == 3:
|
||||
logger.warn(group.name + ": Planes not available for import")
|
||||
elif index == 4:
|
||||
logger.warn(group.name + ": Ships not available for import")
|
||||
|
||||
|
||||
def copyStatics(self, mission, dest_country_name, dest_name, dest_point=None, dest_heading=0):
|
||||
logger.info("Copying " + str(len(self.statics)) + " static objects as " + dest_name)
|
||||
new_groups = []
|
||||
@@ -74,13 +78,11 @@ class ImportObjects:
|
||||
if not dest_point:
|
||||
dest_point = dcs.Point(mission.terrain.bullseye_blue["x"], mission.terrain.bullseye_blue["y"])
|
||||
|
||||
#Statics
|
||||
# Statics
|
||||
statics_copy = self.statics.copy()
|
||||
for group in statics_copy:
|
||||
|
||||
self.groupToPoint(group, self.source_point, dest_point, self.source_heading, dest_heading)
|
||||
|
||||
|
||||
class temp(dcs.unittype.StaticType):
|
||||
id = group.units[0].type
|
||||
name = group.units[0].name
|
||||
@@ -89,7 +91,6 @@ class ImportObjects:
|
||||
can_cargo = group.units[0].can_cargo
|
||||
mass = group.units[0].mass
|
||||
|
||||
|
||||
ng = mission.static_group(mission.country(dest_country_name),
|
||||
dest_name + " " + group.name,
|
||||
temp,
|
||||
@@ -104,9 +105,6 @@ class ImportObjects:
|
||||
|
||||
return new_groups
|
||||
|
||||
|
||||
|
||||
|
||||
def copyVehicles(self, mission, dest_country_name, dest_name, dest_point=None, dest_heading=0):
|
||||
logger.info("Copying " + str(len(self.vehicles)) + " vehicle groups as " + dest_name)
|
||||
new_groups = []
|
||||
@@ -122,30 +120,30 @@ class ImportObjects:
|
||||
for i, unit in enumerate(group.units):
|
||||
if i == 0:
|
||||
ng = mission.vehicle_group(mission.country(dest_country_name),
|
||||
dest_name + " " + group.name,
|
||||
dcs.vehicles.vehicle_map[group.units[0].type],
|
||||
group.units[0].position,
|
||||
group.units[0].heading)
|
||||
dest_name + " " + group.name,
|
||||
dcs.vehicles.vehicle_map[group.units[0].type],
|
||||
group.units[0].position,
|
||||
group.units[0].heading)
|
||||
|
||||
new_groups.append(ng) # will this hold units we add later?
|
||||
# ng.units[0].livery_id = group.units[0].livery_id
|
||||
new_groups.append(ng)
|
||||
|
||||
else:
|
||||
|
||||
u = mission.vehicle(dest_name + " " + group.units[i].name, dcs.vehicles.vehicle_map[group.units[i].type])
|
||||
u.position = group.units[i].position
|
||||
u.heading = group.units[i].heading
|
||||
ng.add_unit(u)
|
||||
u = mission.vehicle(dest_name + " " + group.units[i].name,
|
||||
dcs.vehicles.vehicle_map[group.units[i].type])
|
||||
u.position = group.units[i].position
|
||||
u.heading = group.units[i].heading
|
||||
# u.livery_id = group.units[i].livery_id
|
||||
ng.add_unit(u)
|
||||
|
||||
return new_groups
|
||||
|
||||
|
||||
def copyHelicopters(self, mission, dest_country_name, dest_name, dest_point=None, dest_heading=0):
|
||||
def copyHelicopters(self, mission, dest_country_name, dest_name, dest_point, dest_heading=0,
|
||||
start_type=dcs.mission.StartType.Cold):
|
||||
logger.info("Copying " + str(len(self.helicopters)) + " helicopters as " + dest_name)
|
||||
new_groups = []
|
||||
|
||||
if not dest_point:
|
||||
dest_point = dcs.Point(mission.terrain.bullseye_blue["x"], mission.terrain.bullseye_blue["y"])
|
||||
|
||||
helicopters_copy = self.helicopters.copy()
|
||||
for group in helicopters_copy:
|
||||
|
||||
@@ -158,39 +156,46 @@ class ImportObjects:
|
||||
# trying to move the units into position after adding the flight group moves the 2D graphic of the helicopter, but the unit marker remains stacked on top
|
||||
# of the unit marker in ME
|
||||
# farp = mission.country(country_name).find_group(self.pad_unit.name)
|
||||
#
|
||||
# farp = mission.farp(mission.country(dest_country_name), dest_name + " " + group.name + " Pad", group.units[0].position, hidden=True, dead=False,
|
||||
# farp_type=dcs.unit.InvisibleFARP)
|
||||
#
|
||||
#
|
||||
# ng = mission.flight_group_from_unit(mission.country(dest_country_name),
|
||||
# dest_name + " " + group.name,
|
||||
# dcs.helicopters.helicopter_map[group.units[0].type],
|
||||
# farp,
|
||||
# group_size=1, start_type=start_type)
|
||||
ng = mission.flight_group(mission.country(dest_country_name),
|
||||
dest_name + " " + group.name,
|
||||
dcs.helicopters.helicopter_map[group.units[0].type],
|
||||
airport=None,
|
||||
position=group.units[0].position,
|
||||
group_size=1, start_type=start_type)
|
||||
|
||||
farp = mission.farp(mission.country(dest_country_name), dest_name + " " + group.name + " Pad", group.units[0].position, hidden=True, dead=False,
|
||||
farp_type=dcs.unit.InvisibleFARP)
|
||||
|
||||
|
||||
|
||||
ng = mission.flight_group_from_unit(mission.country(dest_country_name),
|
||||
dest_name + " " + group.name,
|
||||
dcs.helicopters.helicopter_map[group.units[0].type],
|
||||
farp,
|
||||
group_size=1)
|
||||
|
||||
ng.points[0].action = dcs.point.PointAction.FromGroundArea
|
||||
ng.points[0].type = "TakeOffGround"
|
||||
if start_type == dcs.mission.StartType.Warm:
|
||||
ng.points[0].action = dcs.point.PointAction.FromGroundAreaHot
|
||||
ng.points[0].type = "TakeOffGroundHot"
|
||||
else:
|
||||
ng.points[0].action = dcs.point.PointAction.FromGroundArea
|
||||
ng.points[0].type = "TakeOffGround"
|
||||
ng.units[0].heading = group.units[0].heading
|
||||
ng.units[0].skill = group.units[0].skill
|
||||
ng.units[0].livery_id = group.units[0].livery_id
|
||||
ng.units[0].pylons = group.units[0].pylons
|
||||
|
||||
ng.units[0].fuel = group.units[0].fuel
|
||||
ng.units[0].gun = group.units[0].gun
|
||||
ng.units[0].hardpoint_racks = group.units[0].hardpoint_racks
|
||||
new_groups.append(ng)
|
||||
else:
|
||||
logger.warn("No pad unit (ie FARP, carrier) found, so can't add helicopters.")
|
||||
|
||||
return new_groups
|
||||
|
||||
|
||||
def copyVehiclesAsGroup(self, mission, dest_country_name, dest_name, dest_point=None, dest_heading=0):
|
||||
def copyVehiclesAsGroup(self, mission, dest_country_name, dest_name, dest_point, dest_heading=0):
|
||||
logger.info("Copying " + str(len(self.vehicles)) + " vehicle groups as single group name: " + dest_name)
|
||||
new_group = None
|
||||
|
||||
if not dest_point:
|
||||
dest_point = dcs.Point(mission.terrain.bullseye_blue["x"], mission.terrain.bullseye_blue["y"])
|
||||
|
||||
unit_count = 0
|
||||
vehicles_copy = self.vehicles.copy()
|
||||
for group in vehicles_copy:
|
||||
@@ -198,29 +203,32 @@ class ImportObjects:
|
||||
for i, unit in enumerate(group.units):
|
||||
|
||||
if unit_count == 0:
|
||||
print("Group:" + group.name)
|
||||
# print("Group:" + group.name)
|
||||
new_group = mission.vehicle_group(mission.country(dest_country_name),
|
||||
dest_name,
|
||||
dcs.vehicles.vehicle_map[group.units[0].type],
|
||||
group.units[0].position,
|
||||
group.units[0].heading)
|
||||
unit_count = unit_count + 1
|
||||
# new_group.units[0].livery_id = group.units[0].livery_id
|
||||
|
||||
else:
|
||||
|
||||
print("Unit:" + group.units[i].name)
|
||||
u = mission.vehicle(dest_name + " " + group.units[i].name, dcs.vehicles.vehicle_map[group.units[i].type])
|
||||
# print("Unit:" + group.units[i].name)
|
||||
u = mission.vehicle(dest_name + " " + group.units[i].name,
|
||||
dcs.vehicles.vehicle_map[group.units[i].type])
|
||||
u.position = group.units[i].position
|
||||
u.heading = group.units[i].heading
|
||||
|
||||
# u.livery_id = group.units[i].livery_id
|
||||
new_group.add_unit(u)
|
||||
|
||||
unit_count = unit_count + 1
|
||||
print("Made a group with units: " + str(unit_count))
|
||||
print("group actually has units: " + str(len(new_group.units)))
|
||||
# print("group actually has units: " + str(len(new_group.units)))
|
||||
|
||||
return new_group
|
||||
|
||||
|
||||
@staticmethod
|
||||
def groupToPoint(group, src_point, dest_point, src_heading=0, dest_heading=0):
|
||||
for unit in group.units:
|
||||
@@ -230,4 +238,4 @@ class ImportObjects:
|
||||
unit_distance = src_point.distance_to_point(unit.position)
|
||||
unit.position = dest_point.point_from_heading(new_heading_to_unit, unit_distance)
|
||||
unit.heading = unit.heading + dest_heading
|
||||
return group
|
||||
return group
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
11
Generator/tests.py
Normal file
11
Generator/tests.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import dcs
|
||||
import dcs.cloud_presets
|
||||
|
||||
testm = dcs.mission.Mission()
|
||||
|
||||
# testCloudPresets
|
||||
for i in range(0, len(dcs.cloud_presets.CLOUD_PRESETS)):
|
||||
preset_name = list(dcs.cloud_presets.CLOUD_PRESETS)[i]
|
||||
cloud_preset = dcs.weather.CloudPreset.by_name(preset_name)
|
||||
testm.weather.clouds_preset = cloud_preset
|
||||
print("Cloud preset = " + cloud_preset.ui_name)
|
||||
Reference in New Issue
Block a user