mirror of
https://github.com/spencershepard/RotorOps.git
synced 2025-11-10 15:45:30 +00:00
Feature/generator (#13)
* Create README.md * Update README.md * Update README.md * Update README.md * .. * .. * .. * .. * .. * .. * .. * added many ui options * stable * release candidate
This commit is contained in:
9
Generator/Forces/_How to add your own templates.txt
Normal file
9
Generator/Forces/_How to add your own templates.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
You can add your own unit templates in this directory and they will appear in the mission generator.
|
||||
|
||||
1) Create an empty mission on Caucasus
|
||||
2) Add ground unit groups.
|
||||
3) Save the mission in this directory.
|
||||
|
||||
Tips:
|
||||
-Drop your templates in the RotorOps Discord if you'd like to have them added in a release for everyone.
|
||||
-The mission generator will only extract blue ground units from the template when selected from the "Blue Forces" menu, and vice versa.
|
||||
BIN
Generator/Forces/blue/BLUE Default Armor.miz
Normal file
BIN
Generator/Forces/blue/BLUE Default Armor.miz
Normal file
Binary file not shown.
BIN
Generator/Forces/red/RED Default Mixed.miz
Normal file
BIN
Generator/Forces/red/RED Default Mixed.miz
Normal file
Binary file not shown.
206
Generator/MissionGenerator.py
Normal file
206
Generator/MissionGenerator.py
Normal file
@@ -0,0 +1,206 @@
|
||||
import math
|
||||
import sys
|
||||
import os
|
||||
import dcs
|
||||
import RotorOpsMission as ROps
|
||||
import RotorOpsUtils
|
||||
import RotorOpsUnits
|
||||
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication, QDialog, QMainWindow, QMessageBox
|
||||
)
|
||||
from PyQt5 import QtGui
|
||||
from MissionGeneratorUI import Ui_MainWindow
|
||||
|
||||
scenarios = []
|
||||
red_forces_files = []
|
||||
blue_forces_files = []
|
||||
|
||||
class Window(QMainWindow, Ui_MainWindow):
|
||||
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
|
||||
print('running in a PyInstaller bundle')
|
||||
home_dir = os.getcwd()
|
||||
os.chdir(home_dir + "/Generator")
|
||||
else:
|
||||
print('running in a normal Python process')
|
||||
|
||||
|
||||
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.populateSlotSelection()
|
||||
|
||||
self.background_label.setPixmap(QtGui.QPixmap(self.m.assets_dir + "/background.PNG"))
|
||||
self.statusbar.setStyleSheet(
|
||||
"QStatusBar{padding-left:5px;color:black;font-weight:bold;}")
|
||||
|
||||
|
||||
def connectSignalsSlots(self):
|
||||
# self.action_Exit.triggered.connect(self.close)
|
||||
self.action_generateMission.triggered.connect(self.generateMissionAction)
|
||||
self.action_scenarioSelected.triggered.connect(self.scenarioChanged)
|
||||
|
||||
def populateScenarios(self):
|
||||
os.chdir(self.m.scenarios_dir)
|
||||
path = os.getcwd()
|
||||
dir_list = os.listdir(path)
|
||||
print("Looking for mission files in '", path, "' :")
|
||||
|
||||
for filename in dir_list:
|
||||
if filename.endswith(".miz"):
|
||||
scenarios.append(filename)
|
||||
self.scenario_comboBox.addItem(filename.removesuffix('.miz'))
|
||||
|
||||
def populateForces(self, side, combobox, files_list):
|
||||
os.chdir(self.m.home_dir)
|
||||
os.chdir(self.m.forces_dir + "/" + side)
|
||||
path = os.getcwd()
|
||||
dir_list = os.listdir(path)
|
||||
print("Looking for " + side + " Forces files in '", os.getcwd(), "' :")
|
||||
|
||||
for filename in dir_list:
|
||||
if filename.endswith(".miz"):
|
||||
files_list.append(filename)
|
||||
combobox.addItem(filename.removesuffix('.miz'))
|
||||
|
||||
def populateSlotSelection(self):
|
||||
self.slot_template_comboBox.addItem("Multiple Slots")
|
||||
for type in RotorOpsUnits.client_helos:
|
||||
self.slot_template_comboBox.addItem(type.id)
|
||||
|
||||
|
||||
def scenarioChanged(self):
|
||||
try:
|
||||
os.chdir(self.m.scenarios_dir)
|
||||
filename = scenarios[self.scenario_comboBox.currentIndex()]
|
||||
source_mission = dcs.mission.Mission()
|
||||
source_mission.load_file(filename)
|
||||
zones = source_mission.triggers.zones()
|
||||
conflict_zones = 0
|
||||
staging_zones = 0
|
||||
conflict_zone_size_sum = 0
|
||||
conflict_zone_distance_sum = 0
|
||||
spawn_zones = 0
|
||||
conflict_zone_positions = []
|
||||
#friendly_airports = source_mission.getCoalitionAirports("blue")
|
||||
#enemy_airports = source_mission.getCoalitionAirports("red")
|
||||
friendly_airports = True
|
||||
enemy_airports = True
|
||||
|
||||
## TODO: we should be creating a new instance of RotorOpsMission each time scenario is changed so we can access all methods and vars
|
||||
|
||||
for zone in zones:
|
||||
if zone.name == "STAGING":
|
||||
staging_zones += 1
|
||||
if zone.name == "ALPHA" or zone.name == "BRAVO" or zone.name == "CHARLIE" or zone.name == "DELTA":
|
||||
conflict_zones += 1
|
||||
conflict_zone_size_sum += zone.radius
|
||||
conflict_zone_positions.append(zone.position)
|
||||
if zone.name.rfind("_SPAWN") > 0:
|
||||
spawn_zones += 1
|
||||
if conflict_zones > 1:
|
||||
for index, position in enumerate(conflict_zone_positions):
|
||||
if index > 0:
|
||||
conflict_zone_distance_sum += RotorOpsUtils.getDistance(conflict_zone_positions[index], conflict_zone_positions[index - 1])
|
||||
|
||||
def validateTemplate():
|
||||
valid = True
|
||||
if len(staging_zones) < 1:
|
||||
valid = False
|
||||
if len(conflict_zones) < 1:
|
||||
valid = False
|
||||
if not friendly_airports:
|
||||
valid = False
|
||||
if not enemy_airports:
|
||||
valid = False
|
||||
return valid
|
||||
|
||||
if conflict_zones and staging_zones :
|
||||
average_zone_size = conflict_zone_size_sum / conflict_zones
|
||||
self.description_textBrowser.setText(
|
||||
"Map: " + source_mission.terrain.name + "\n" +
|
||||
"Conflict Zones: " + str(conflict_zones) + "\n" +
|
||||
"Average Zone Size " + str(math.floor(average_zone_size)) + "m \n" +
|
||||
"Infantry Spawn Zones: " + str(spawn_zones) + "\n" +
|
||||
"Approx Distance: " + str(math.floor(RotorOpsUtils.convertMeterToNM(conflict_zone_distance_sum))) + "nm \n"
|
||||
#"Validity Check:" + str(validateTemplate())
|
||||
)
|
||||
except:
|
||||
self.description_textBrowser.setText("File error occured.")
|
||||
|
||||
|
||||
def generateMissionAction(self):
|
||||
red_forces_filename = red_forces_files[self.redforces_comboBox.currentIndex()]
|
||||
blue_forces_filename = blue_forces_files[self.blueforces_comboBox.currentIndex()]
|
||||
scenario_filename = scenarios[self.scenario_comboBox.currentIndex()]
|
||||
data = {
|
||||
"scenario_filename": scenario_filename,
|
||||
"red_forces_filename": red_forces_filename,
|
||||
"blue_forces_filename": blue_forces_filename,
|
||||
"red_quantity": self.redqty_spinBox.value(),
|
||||
"blue_quantity": self.blueqty_spinBox.value(),
|
||||
"inf_spawn_qty": self.inf_spawn_spinBox.value(),
|
||||
"apc_spawns_inf": self.apcs_spawn_checkBox.isChecked(),
|
||||
"e_transport": self.enemy_transport_checkBox.isChecked(),
|
||||
"e_attack_helos": self.enemy_attack_helos_checkBox.isChecked(),
|
||||
"e_fighters": self.enemy_fighters_checkBox.isChecked(),
|
||||
"e_attack_planes": self.enemy_attack_planes_checkBox.isChecked(),
|
||||
"crates": self.logistics_crates_checkBox.isChecked(),
|
||||
"f_awacs": self.awacs_checkBox.isChecked(),
|
||||
"f_tankers": self.tankers_checkBox.isChecked(),
|
||||
"smoke_zone": self.smoke_checkBox.isChecked(),
|
||||
"voiceovers": self.voiceovers_checkBox.isChecked(),
|
||||
"force_offroad": self.force_offroad_checkBox.isChecked(),
|
||||
"game_display": self.game_status_checkBox.isChecked(),
|
||||
"defending": self.defense_checkBox.isChecked(),
|
||||
"slots": self.slot_template_comboBox.currentText(),
|
||||
}
|
||||
os.chdir(self.m.home_dir + '/Generator')
|
||||
n = ROps.RotorOpsMission()
|
||||
result = n.generateMission(data)
|
||||
print("Generating mission with options:")
|
||||
print(str(data))
|
||||
|
||||
# generate the mission
|
||||
#result = self.m.generateMission(data)
|
||||
|
||||
#display results
|
||||
if result["success"]:
|
||||
print(result["filename"] + "' successfully generated in " + result["directory"])
|
||||
self.statusbar.showMessage(result["filename"] + "' successfully generated in " + result["directory"], 10000)
|
||||
msg = QMessageBox()
|
||||
msg.setWindowTitle("Mission Generated")
|
||||
msg.setText("Awesome, your mission is ready! It's located in this directory: \n" +
|
||||
self.m.output_dir + "\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" +
|
||||
"\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. \n" +
|
||||
"\n" +
|
||||
"Don't forget, you can also create your own templates that can include any mission options, objects, or even scripts. \n" +
|
||||
"\n" +
|
||||
"Have fun! \n"
|
||||
)
|
||||
x = msg.exec_()
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
win = Window()
|
||||
win.show()
|
||||
sys.exit(app.exec())
|
||||
|
||||
|
||||
|
||||
41
Generator/MissionGenerator.spec
Normal file
41
Generator/MissionGenerator.spec
Normal file
@@ -0,0 +1,41 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(['MissionGenerator.py'],
|
||||
pathex=['../'],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='MissionGenerator',
|
||||
icon='assets\\icon.ico',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None )
|
||||
365
Generator/MissionGeneratorUI.py
Normal file
365
Generator/MissionGeneratorUI.py
Normal file
@@ -0,0 +1,365 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'MissionGeneratorUI.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.4
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName("MainWindow")
|
||||
MainWindow.resize(1140, 826)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
MainWindow.setFont(font)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap("assets/icon.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
MainWindow.setWindowIcon(icon)
|
||||
MainWindow.setWindowOpacity(4.0)
|
||||
MainWindow.setAutoFillBackground(False)
|
||||
MainWindow.setStyleSheet("background-color: white;")
|
||||
self.centralwidget = QtWidgets.QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName("centralwidget")
|
||||
self.scenario_comboBox = QtWidgets.QComboBox(self.centralwidget)
|
||||
self.scenario_comboBox.setGeometry(QtCore.QRect(270, 40, 361, 31))
|
||||
self.scenario_comboBox.setToolTip("")
|
||||
self.scenario_comboBox.setToolTipDuration(-1)
|
||||
self.scenario_comboBox.setWhatsThis("")
|
||||
self.scenario_comboBox.setObjectName("scenario_comboBox")
|
||||
self.scenario_label = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_label.setGeometry(QtCore.QRect(60, 30, 181, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.scenario_label.setFont(font)
|
||||
self.scenario_label.setObjectName("scenario_label")
|
||||
self.generateButton = QtWidgets.QPushButton(self.centralwidget)
|
||||
self.generateButton.setGeometry(QtCore.QRect(940, 720, 141, 41))
|
||||
self.generateButton.setStyleSheet("background-color: white;\n"
|
||||
"border-style: outset;\n"
|
||||
"border-width: 2px;\n"
|
||||
"border-radius: 15px;\n"
|
||||
"border-color: black;\n"
|
||||
"padding: 4px;")
|
||||
self.generateButton.setObjectName("generateButton")
|
||||
self.description_textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
|
||||
self.description_textBrowser.setGeometry(QtCore.QRect(710, 20, 331, 131))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.description_textBrowser.setFont(font)
|
||||
self.description_textBrowser.setStyleSheet("border-radius: 5px; color: gray")
|
||||
self.description_textBrowser.setObjectName("description_textBrowser")
|
||||
self.blueforces_comboBox = QtWidgets.QComboBox(self.centralwidget)
|
||||
self.blueforces_comboBox.setGeometry(QtCore.QRect(790, 230, 291, 31))
|
||||
self.blueforces_comboBox.setObjectName("blueforces_comboBox")
|
||||
self.scenario_label_2 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_label_2.setGeometry(QtCore.QRect(690, 180, 141, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.scenario_label_2.setFont(font)
|
||||
self.scenario_label_2.setObjectName("scenario_label_2")
|
||||
self.scenario_label_3 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_label_3.setGeometry(QtCore.QRect(60, 180, 141, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.scenario_label_3.setFont(font)
|
||||
self.scenario_label_3.setObjectName("scenario_label_3")
|
||||
self.redforces_comboBox = QtWidgets.QComboBox(self.centralwidget)
|
||||
self.redforces_comboBox.setGeometry(QtCore.QRect(170, 230, 291, 31))
|
||||
self.redforces_comboBox.setObjectName("redforces_comboBox")
|
||||
self.background_label = QtWidgets.QLabel(self.centralwidget)
|
||||
self.background_label.setGeometry(QtCore.QRect(10, 430, 801, 371))
|
||||
self.background_label.setAutoFillBackground(False)
|
||||
self.background_label.setStyleSheet("")
|
||||
self.background_label.setText("")
|
||||
self.background_label.setPixmap(QtGui.QPixmap("assets/background.PNG"))
|
||||
self.background_label.setObjectName("background_label")
|
||||
self.scenario_hint_label = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_hint_label.setGeometry(QtCore.QRect(250, 80, 381, 16))
|
||||
self.scenario_hint_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.scenario_hint_label.setObjectName("scenario_hint_label")
|
||||
self.forces_hint_label = QtWidgets.QLabel(self.centralwidget)
|
||||
self.forces_hint_label.setGeometry(QtCore.QRect(130, 270, 381, 16))
|
||||
self.forces_hint_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.forces_hint_label.setObjectName("forces_hint_label")
|
||||
self.blueqty_spinBox = QtWidgets.QSpinBox(self.centralwidget)
|
||||
self.blueqty_spinBox.setGeometry(QtCore.QRect(690, 230, 71, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.blueqty_spinBox.setFont(font)
|
||||
self.blueqty_spinBox.setMinimum(0)
|
||||
self.blueqty_spinBox.setMaximum(50)
|
||||
self.blueqty_spinBox.setProperty("value", 3)
|
||||
self.blueqty_spinBox.setObjectName("blueqty_spinBox")
|
||||
self.redqty_spinBox = QtWidgets.QSpinBox(self.centralwidget)
|
||||
self.redqty_spinBox.setGeometry(QtCore.QRect(70, 230, 71, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.redqty_spinBox.setFont(font)
|
||||
self.redqty_spinBox.setMinimum(0)
|
||||
self.redqty_spinBox.setMaximum(50)
|
||||
self.redqty_spinBox.setProperty("value", 2)
|
||||
self.redqty_spinBox.setObjectName("redqty_spinBox")
|
||||
self.scenario_label_4 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_label_4.setGeometry(QtCore.QRect(670, 260, 101, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.scenario_label_4.setFont(font)
|
||||
self.scenario_label_4.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.scenario_label_4.setObjectName("scenario_label_4")
|
||||
self.game_status_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.game_status_checkBox.setGeometry(QtCore.QRect(910, 510, 191, 16))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.game_status_checkBox.setFont(font)
|
||||
self.game_status_checkBox.setChecked(True)
|
||||
self.game_status_checkBox.setTristate(False)
|
||||
self.game_status_checkBox.setObjectName("game_status_checkBox")
|
||||
self.voiceovers_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.voiceovers_checkBox.setGeometry(QtCore.QRect(910, 570, 191, 16))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.voiceovers_checkBox.setFont(font)
|
||||
self.voiceovers_checkBox.setChecked(True)
|
||||
self.voiceovers_checkBox.setObjectName("voiceovers_checkBox")
|
||||
self.logistics_crates_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.logistics_crates_checkBox.setGeometry(QtCore.QRect(910, 320, 251, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.logistics_crates_checkBox.setFont(font)
|
||||
self.logistics_crates_checkBox.setObjectName("logistics_crates_checkBox")
|
||||
self.awacs_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.awacs_checkBox.setGeometry(QtCore.QRect(910, 350, 251, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.awacs_checkBox.setFont(font)
|
||||
self.awacs_checkBox.setStatusTip("")
|
||||
self.awacs_checkBox.setObjectName("awacs_checkBox")
|
||||
self.tankers_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.tankers_checkBox.setGeometry(QtCore.QRect(910, 380, 251, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.tankers_checkBox.setFont(font)
|
||||
self.tankers_checkBox.setObjectName("tankers_checkBox")
|
||||
self.apcs_spawn_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.apcs_spawn_checkBox.setGeometry(QtCore.QRect(470, 400, 251, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
self.apcs_spawn_checkBox.setFont(font)
|
||||
self.apcs_spawn_checkBox.setObjectName("apcs_spawn_checkBox")
|
||||
self.enemy_transport_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.enemy_transport_checkBox.setEnabled(False)
|
||||
self.enemy_transport_checkBox.setGeometry(QtCore.QRect(70, 320, 251, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.enemy_transport_checkBox.setFont(font)
|
||||
self.enemy_transport_checkBox.setObjectName("enemy_transport_checkBox")
|
||||
self.enemy_attack_helos_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.enemy_attack_helos_checkBox.setEnabled(True)
|
||||
self.enemy_attack_helos_checkBox.setGeometry(QtCore.QRect(70, 350, 251, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.enemy_attack_helos_checkBox.setFont(font)
|
||||
self.enemy_attack_helos_checkBox.setObjectName("enemy_attack_helos_checkBox")
|
||||
self.enemy_fighters_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.enemy_fighters_checkBox.setEnabled(False)
|
||||
self.enemy_fighters_checkBox.setGeometry(QtCore.QRect(70, 380, 251, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.enemy_fighters_checkBox.setFont(font)
|
||||
self.enemy_fighters_checkBox.setObjectName("enemy_fighters_checkBox")
|
||||
self.enemy_attack_planes_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.enemy_attack_planes_checkBox.setEnabled(True)
|
||||
self.enemy_attack_planes_checkBox.setGeometry(QtCore.QRect(70, 410, 251, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.enemy_attack_planes_checkBox.setFont(font)
|
||||
self.enemy_attack_planes_checkBox.setObjectName("enemy_attack_planes_checkBox")
|
||||
self.inf_spawn_spinBox = QtWidgets.QSpinBox(self.centralwidget)
|
||||
self.inf_spawn_spinBox.setGeometry(QtCore.QRect(680, 360, 71, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(12)
|
||||
self.inf_spawn_spinBox.setFont(font)
|
||||
self.inf_spawn_spinBox.setMinimum(0)
|
||||
self.inf_spawn_spinBox.setMaximum(50)
|
||||
self.inf_spawn_spinBox.setProperty("value", 2)
|
||||
self.inf_spawn_spinBox.setObjectName("inf_spawn_spinBox")
|
||||
self.smoke_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.smoke_checkBox.setGeometry(QtCore.QRect(910, 540, 191, 16))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.smoke_checkBox.setFont(font)
|
||||
self.smoke_checkBox.setChecked(True)
|
||||
self.smoke_checkBox.setObjectName("smoke_checkBox")
|
||||
self.scenario_label_5 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_label_5.setGeometry(QtCore.QRect(50, 260, 101, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.scenario_label_5.setFont(font)
|
||||
self.scenario_label_5.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.scenario_label_5.setObjectName("scenario_label_5")
|
||||
self.forces_hint_label_2 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.forces_hint_label_2.setGeometry(QtCore.QRect(790, 270, 311, 20))
|
||||
self.forces_hint_label_2.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.forces_hint_label_2.setObjectName("forces_hint_label_2")
|
||||
self.label = QtWidgets.QLabel(self.centralwidget)
|
||||
self.label.setGeometry(QtCore.QRect(470, 360, 191, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
self.label.setFont(font)
|
||||
self.label.setObjectName("label")
|
||||
self.slot_template_comboBox = QtWidgets.QComboBox(self.centralwidget)
|
||||
self.slot_template_comboBox.setGeometry(QtCore.QRect(790, 630, 291, 31))
|
||||
self.slot_template_comboBox.setObjectName("slot_template_comboBox")
|
||||
self.label_2 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.label_2.setGeometry(QtCore.QRect(650, 630, 111, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.label_2.setFont(font)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.scenario_label_6 = QtWidgets.QLabel(self.centralwidget)
|
||||
self.scenario_label_6.setGeometry(QtCore.QRect(470, 320, 141, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.scenario_label_6.setFont(font)
|
||||
self.scenario_label_6.setObjectName("scenario_label_6")
|
||||
self.force_offroad_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.force_offroad_checkBox.setGeometry(QtCore.QRect(910, 480, 191, 16))
|
||||
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.defense_checkBox = QtWidgets.QCheckBox(self.centralwidget)
|
||||
self.defense_checkBox.setGeometry(QtCore.QRect(60, 90, 181, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.defense_checkBox.setFont(font)
|
||||
self.defense_checkBox.setObjectName("defense_checkBox")
|
||||
self.background_label.raise_()
|
||||
self.scenario_comboBox.raise_()
|
||||
self.scenario_label.raise_()
|
||||
self.generateButton.raise_()
|
||||
self.description_textBrowser.raise_()
|
||||
self.blueforces_comboBox.raise_()
|
||||
self.scenario_label_2.raise_()
|
||||
self.scenario_label_3.raise_()
|
||||
self.redforces_comboBox.raise_()
|
||||
self.scenario_hint_label.raise_()
|
||||
self.forces_hint_label.raise_()
|
||||
self.blueqty_spinBox.raise_()
|
||||
self.redqty_spinBox.raise_()
|
||||
self.scenario_label_4.raise_()
|
||||
self.game_status_checkBox.raise_()
|
||||
self.voiceovers_checkBox.raise_()
|
||||
self.logistics_crates_checkBox.raise_()
|
||||
self.awacs_checkBox.raise_()
|
||||
self.tankers_checkBox.raise_()
|
||||
self.apcs_spawn_checkBox.raise_()
|
||||
self.enemy_transport_checkBox.raise_()
|
||||
self.enemy_attack_helos_checkBox.raise_()
|
||||
self.enemy_fighters_checkBox.raise_()
|
||||
self.enemy_attack_planes_checkBox.raise_()
|
||||
self.inf_spawn_spinBox.raise_()
|
||||
self.smoke_checkBox.raise_()
|
||||
self.scenario_label_5.raise_()
|
||||
self.forces_hint_label_2.raise_()
|
||||
self.label.raise_()
|
||||
self.slot_template_comboBox.raise_()
|
||||
self.label_2.raise_()
|
||||
self.scenario_label_6.raise_()
|
||||
self.force_offroad_checkBox.raise_()
|
||||
self.defense_checkBox.raise_()
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QtWidgets.QMenuBar(MainWindow)
|
||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1140, 26))
|
||||
self.menubar.setObjectName("menubar")
|
||||
MainWindow.setMenuBar(self.menubar)
|
||||
self.statusbar = QtWidgets.QStatusBar(MainWindow)
|
||||
self.statusbar.setAcceptDrops(False)
|
||||
self.statusbar.setObjectName("statusbar")
|
||||
MainWindow.setStatusBar(self.statusbar)
|
||||
self.action_generateMission = QtWidgets.QAction(MainWindow)
|
||||
self.action_generateMission.setObjectName("action_generateMission")
|
||||
self.action_scenarioSelected = QtWidgets.QAction(MainWindow)
|
||||
self.action_scenarioSelected.setObjectName("action_scenarioSelected")
|
||||
self.action_blueforcesSelected = QtWidgets.QAction(MainWindow)
|
||||
self.action_blueforcesSelected.setObjectName("action_blueforcesSelected")
|
||||
self.action_redforcesSelected = QtWidgets.QAction(MainWindow)
|
||||
self.action_redforcesSelected.setObjectName("action_redforcesSelected")
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
self.generateButton.clicked.connect(self.action_generateMission.trigger)
|
||||
self.scenario_comboBox.currentIndexChanged['int'].connect(self.action_scenarioSelected.trigger)
|
||||
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MainWindow.setWindowTitle(_translate("MainWindow", "RotorOps Mission Generator"))
|
||||
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.scenario_label.setText(_translate("MainWindow", "Scenario Template:"))
|
||||
self.generateButton.setText(_translate("MainWindow", "Generate Mission"))
|
||||
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"
|
||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||
"p, li { white-space: pre-wrap; }\n"
|
||||
"</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; 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-size:10pt;\">Provide close air support for our convoys as we take back Las Vegas from the enemy!</span></p></body></html>"))
|
||||
self.blueforces_comboBox.setStatusTip(_translate("MainWindow", "Tip: You can create your own custom ground forces groups to be automatically generated."))
|
||||
self.scenario_label_2.setText(_translate("MainWindow", "Friendly Forces:"))
|
||||
self.scenario_label_3.setText(_translate("MainWindow", "Enemy Forces:"))
|
||||
self.redforces_comboBox.setStatusTip(_translate("MainWindow", "Tip: You can create your own custom ground forces groups to be automatically generated."))
|
||||
self.scenario_hint_label.setText(_translate("MainWindow", "Scenario templates are .miz files in \'Generator/Scenarios\'"))
|
||||
self.forces_hint_label.setText(_translate("MainWindow", "Forces templates are .miz files in \'Generator/Forces\'"))
|
||||
self.blueqty_spinBox.setStatusTip(_translate("MainWindow", "How many groups should we generate?"))
|
||||
self.redqty_spinBox.setStatusTip(_translate("MainWindow", "How many groups should we generate?"))
|
||||
self.scenario_label_4.setText(_translate("MainWindow", "Groups Per Zone"))
|
||||
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.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.logistics_crates_checkBox.setStatusTip(_translate("MainWindow", "Enable CTLD logistics crates for building ground units and air defenses."))
|
||||
self.logistics_crates_checkBox.setText(_translate("MainWindow", "Logistics Crates"))
|
||||
self.awacs_checkBox.setText(_translate("MainWindow", "Friendly AWACS"))
|
||||
self.tankers_checkBox.setText(_translate("MainWindow", "Friendly Tankers"))
|
||||
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.enemy_transport_checkBox.setStatusTip(_translate("MainWindow", "Not yet implemented."))
|
||||
self.enemy_transport_checkBox.setText(_translate("MainWindow", "Enemy Transport Helicopters"))
|
||||
self.enemy_attack_helos_checkBox.setStatusTip(_translate("MainWindow", "Not yet implemented."))
|
||||
self.enemy_attack_helos_checkBox.setText(_translate("MainWindow", "Enemy Attack Helicopters"))
|
||||
self.enemy_fighters_checkBox.setStatusTip(_translate("MainWindow", "Not yet implemented."))
|
||||
self.enemy_fighters_checkBox.setText(_translate("MainWindow", "Enemy Fighter Planes"))
|
||||
self.enemy_attack_planes_checkBox.setStatusTip(_translate("MainWindow", "Not yet implemented."))
|
||||
self.enemy_attack_planes_checkBox.setText(_translate("MainWindow", "Enemy Ground Attack Planes"))
|
||||
self.inf_spawn_spinBox.setStatusTip(_translate("MainWindow", "This value is multiplied by the number of spawn zones in the mission template."))
|
||||
self.smoke_checkBox.setStatusTip(_translate("MainWindow", "Not yet implemented."))
|
||||
self.smoke_checkBox.setText(_translate("MainWindow", "Smoke Active Zone"))
|
||||
self.scenario_label_5.setText(_translate("MainWindow", "Groups Per Zone"))
|
||||
self.forces_hint_label_2.setText(_translate("MainWindow", "Forces templates are .miz files in \'Generator/Forces\'"))
|
||||
self.label.setText(_translate("MainWindow", "Infantry Groups per zone:"))
|
||||
self.slot_template_comboBox.setStatusTip(_translate("MainWindow", "Default player/client spawn locations at a friendly airport."))
|
||||
self.label_2.setText(_translate("MainWindow", "Player Slots"))
|
||||
self.scenario_label_6.setText(_translate("MainWindow", "Infantry Spawns:"))
|
||||
self.force_offroad_checkBox.setStatusTip(_translate("MainWindow", "May help prevent long travel times or pathfinding issues. Tip: You can change this dynamically from mission triggers."))
|
||||
self.force_offroad_checkBox.setText(_translate("MainWindow", "Force Offroad"))
|
||||
self.defense_checkBox.setText(_translate("MainWindow", "Defensive Mode"))
|
||||
self.action_generateMission.setText(_translate("MainWindow", "_generateMission"))
|
||||
self.action_scenarioSelected.setText(_translate("MainWindow", "_scenarioSelected"))
|
||||
self.action_blueforcesSelected.setText(_translate("MainWindow", "_blueforcesSelected"))
|
||||
self.action_redforcesSelected.setText(_translate("MainWindow", "_redforcesSelected"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
MainWindow = QtWidgets.QMainWindow()
|
||||
ui = Ui_MainWindow()
|
||||
ui.setupUi(MainWindow)
|
||||
MainWindow.show()
|
||||
sys.exit(app.exec_())
|
||||
846
Generator/MissionGeneratorUI.ui
Normal file
846
Generator/MissionGeneratorUI.ui
Normal file
@@ -0,0 +1,846 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1140</width>
|
||||
<height>826</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>RotorOps Mission Generator</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset>
|
||||
<normaloff>assets/icon.ico</normaloff>assets/icon.ico</iconset>
|
||||
</property>
|
||||
<property name="windowOpacity">
|
||||
<double>4.000000000000000</double>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: white;</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QComboBox" name="scenario_comboBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>270</x>
|
||||
<y>40</y>
|
||||
<width>361</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="toolTipDuration">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Tip: You can create your own templates that include mission options like kneeboards, briefings, weather, static units, triggers, scripts, etc.</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="scenario_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>30</y>
|
||||
<width>181</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scenario Template:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="generateButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>940</x>
|
||||
<y>720</y>
|
||||
<width>141</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: white;
|
||||
border-style: outset;
|
||||
border-width: 2px;
|
||||
border-radius: 15px;
|
||||
border-color: black;
|
||||
padding: 4px;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Generate Mission</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextBrowser" name="description_textBrowser">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>710</x>
|
||||
<y>20</y>
|
||||
<width>331</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-radius: 5px; color: gray</string>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<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-size:10pt;">Provide close air support for our convoys as we take back Las Vegas from the enemy!</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="blueforces_comboBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>790</x>
|
||||
<y>230</y>
|
||||
<width>291</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Tip: You can create your own custom ground forces groups to be automatically generated.</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="scenario_label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>690</x>
|
||||
<y>180</y>
|
||||
<width>141</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Friendly Forces:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="scenario_label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>180</y>
|
||||
<width>141</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enemy Forces:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="redforces_comboBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>170</x>
|
||||
<y>230</y>
|
||||
<width>291</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Tip: You can create your own custom ground forces groups to be automatically generated.</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="background_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>430</y>
|
||||
<width>801</width>
|
||||
<height>371</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>assets/background.PNG</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="scenario_hint_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>250</x>
|
||||
<y>80</y>
|
||||
<width>381</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scenario templates are .miz files in 'Generator/Scenarios'</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="forces_hint_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>270</y>
|
||||
<width>381</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Forces templates are .miz files in 'Generator/Forces'</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="blueqty_spinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>690</x>
|
||||
<y>230</y>
|
||||
<width>71</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>How many groups should we generate?</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="redqty_spinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>230</y>
|
||||
<width>71</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>How many groups should we generate?</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="scenario_label_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>670</x>
|
||||
<y>260</y>
|
||||
<width>101</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Groups Per Zone</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="game_status_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>910</x>
|
||||
<y>510</y>
|
||||
<width>191</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Enable an onscreen zone status display. This helps keep focus on the active conflict zone.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Game Status Display</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="voiceovers_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>910</x>
|
||||
<y>570</y>
|
||||
<width>191</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Voiceovers from the ground commander. Helps keep focus on the active zone.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Voiceovers</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="logistics_crates_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>910</x>
|
||||
<y>320</y>
|
||||
<width>251</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Enable CTLD logistics crates for building ground units and air defenses.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Logistics Crates</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="awacs_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>910</x>
|
||||
<y>350</y>
|
||||
<width>251</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Friendly AWACS</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="tankers_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>910</x>
|
||||
<y>380</y>
|
||||
<width>251</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Friendly Tankers</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="apcs_spawn_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>470</x>
|
||||
<y>400</y>
|
||||
<width>251</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Friendly/enemy APCs will drop infantry when reaching a new conflict zone.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>APCs Spawn Infantry</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="enemy_transport_checkBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>320</y>
|
||||
<width>251</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Not yet implemented.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enemy Transport Helicopters</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="enemy_attack_helos_checkBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>350</y>
|
||||
<width>251</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Not yet implemented.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enemy Attack Helicopters</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="enemy_fighters_checkBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>380</y>
|
||||
<width>251</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Not yet implemented.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enemy Fighter Planes</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="enemy_attack_planes_checkBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>410</y>
|
||||
<width>251</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Not yet implemented.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enemy Ground Attack Planes</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="inf_spawn_spinBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>680</x>
|
||||
<y>360</y>
|
||||
<width>71</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>This value is multiplied by the number of spawn zones in the mission template.</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="smoke_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>910</x>
|
||||
<y>540</y>
|
||||
<width>191</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Not yet implemented.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Smoke Active Zone</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="scenario_label_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>260</y>
|
||||
<width>101</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Groups Per Zone</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="forces_hint_label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>790</x>
|
||||
<y>270</y>
|
||||
<width>311</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Forces templates are .miz files in 'Generator/Forces'</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>470</x>
|
||||
<y>360</y>
|
||||
<width>191</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Infantry Groups per zone:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="slot_template_comboBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>790</x>
|
||||
<y>630</y>
|
||||
<width>291</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>Default player/client spawn locations at a friendly airport.</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>650</x>
|
||||
<y>630</y>
|
||||
<width>111</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Player Slots</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="scenario_label_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>470</x>
|
||||
<y>320</y>
|
||||
<width>141</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Infantry Spawns:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="force_offroad_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>910</x>
|
||||
<y>480</y>
|
||||
<width>191</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="statusTip">
|
||||
<string>May help prevent long travel times or pathfinding issues. Tip: You can change this dynamically from mission triggers.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Force Offroad</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="defense_checkBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>90</y>
|
||||
<width>181</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Defensive Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>background_label</zorder>
|
||||
<zorder>scenario_comboBox</zorder>
|
||||
<zorder>scenario_label</zorder>
|
||||
<zorder>generateButton</zorder>
|
||||
<zorder>description_textBrowser</zorder>
|
||||
<zorder>blueforces_comboBox</zorder>
|
||||
<zorder>scenario_label_2</zorder>
|
||||
<zorder>scenario_label_3</zorder>
|
||||
<zorder>redforces_comboBox</zorder>
|
||||
<zorder>scenario_hint_label</zorder>
|
||||
<zorder>forces_hint_label</zorder>
|
||||
<zorder>blueqty_spinBox</zorder>
|
||||
<zorder>redqty_spinBox</zorder>
|
||||
<zorder>scenario_label_4</zorder>
|
||||
<zorder>game_status_checkBox</zorder>
|
||||
<zorder>voiceovers_checkBox</zorder>
|
||||
<zorder>logistics_crates_checkBox</zorder>
|
||||
<zorder>awacs_checkBox</zorder>
|
||||
<zorder>tankers_checkBox</zorder>
|
||||
<zorder>apcs_spawn_checkBox</zorder>
|
||||
<zorder>enemy_transport_checkBox</zorder>
|
||||
<zorder>enemy_attack_helos_checkBox</zorder>
|
||||
<zorder>enemy_fighters_checkBox</zorder>
|
||||
<zorder>enemy_attack_planes_checkBox</zorder>
|
||||
<zorder>inf_spawn_spinBox</zorder>
|
||||
<zorder>smoke_checkBox</zorder>
|
||||
<zorder>scenario_label_5</zorder>
|
||||
<zorder>forces_hint_label_2</zorder>
|
||||
<zorder>label</zorder>
|
||||
<zorder>slot_template_comboBox</zorder>
|
||||
<zorder>label_2</zorder>
|
||||
<zorder>scenario_label_6</zorder>
|
||||
<zorder>force_offroad_checkBox</zorder>
|
||||
<zorder>defense_checkBox</zorder>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1140</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar">
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<action name="action_generateMission">
|
||||
<property name="text">
|
||||
<string>_generateMission</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_scenarioSelected">
|
||||
<property name="text">
|
||||
<string>_scenarioSelected</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_blueforcesSelected">
|
||||
<property name="text">
|
||||
<string>_blueforcesSelected</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_redforcesSelected">
|
||||
<property name="text">
|
||||
<string>_redforcesSelected</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>generateButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>action_generateMission</receiver>
|
||||
<slot>trigger()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>993</x>
|
||||
<y>591</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>589</x>
|
||||
<y>409</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>scenario_comboBox</sender>
|
||||
<signal>currentIndexChanged(int)</signal>
|
||||
<receiver>action_scenarioSelected</receiver>
|
||||
<slot>trigger()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>285</x>
|
||||
<y>71</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
BIN
Generator/Output/ROps Caucasus Nalchik to Beslan.miz
Normal file
BIN
Generator/Output/ROps Caucasus Nalchik to Beslan.miz
Normal file
Binary file not shown.
BIN
Generator/Output/ROps Conflict_Cauc_Batumi_Kobuleti.miz
Normal file
BIN
Generator/Output/ROps Conflict_Cauc_Batumi_Kobuleti.miz
Normal file
Binary file not shown.
BIN
Generator/Output/ROps Conflict_Cauc_Nalchik_Beslan.miz
Normal file
BIN
Generator/Output/ROps Conflict_Cauc_Nalchik_Beslan.miz
Normal file
Binary file not shown.
BIN
Generator/Output/ROps Nevada Conflict - Vegas Tour.miz
Normal file
BIN
Generator/Output/ROps Nevada Conflict - Vegas Tour.miz
Normal file
Binary file not shown.
BIN
Generator/Output/RotorOpsGenerateMission.miz
Normal file
BIN
Generator/Output/RotorOpsGenerateMission.miz
Normal file
Binary file not shown.
BIN
Generator/Output/g_Conflict_Cauc_Batumi_Kobuleti.miz
Normal file
BIN
Generator/Output/g_Conflict_Cauc_Batumi_Kobuleti.miz
Normal file
Binary file not shown.
BIN
Generator/Output/g_Conflict_Cauc_Nalchik_Beslan.miz
Normal file
BIN
Generator/Output/g_Conflict_Cauc_Nalchik_Beslan.miz
Normal file
Binary file not shown.
406
Generator/RotorOpsMission.py
Normal file
406
Generator/RotorOpsMission.py
Normal file
@@ -0,0 +1,406 @@
|
||||
from tokenize import String
|
||||
|
||||
import dcs
|
||||
import os
|
||||
import random
|
||||
import RotorOpsUnits
|
||||
import time
|
||||
|
||||
|
||||
class RotorOpsMission:
|
||||
|
||||
|
||||
conflict_zones = {}
|
||||
staging_zones = {}
|
||||
spawn_zones = {}
|
||||
scripts = {}
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.m = dcs.mission.Mission()
|
||||
self.old_blue = self.m.coalition.get("blue").dict()
|
||||
self.old_red = self.m.coalition.get("red").dict()
|
||||
os.chdir("../")
|
||||
self.home_dir = os.getcwd()
|
||||
self.scenarios_dir = self.home_dir + "\Generator\Scenarios"
|
||||
self.forces_dir = self.home_dir + "\Generator\Forces"
|
||||
self.script_directory = self.home_dir
|
||||
self.sound_directory = self.home_dir + "\sound\embedded"
|
||||
self.output_dir = self.home_dir + "\Generator\Output"
|
||||
self.assets_dir = self.home_dir + "\Generator/assets"
|
||||
|
||||
|
||||
class RotorOpsZone:
|
||||
def __init__(self, name: str, flag: int, position: dcs.point, size: int):
|
||||
self.name = name
|
||||
self.flag = flag
|
||||
self.position = position
|
||||
self.size = size
|
||||
|
||||
def getMission(self):
|
||||
return self.m
|
||||
|
||||
def addZone(self, zone_dict, zone: RotorOpsZone):
|
||||
zone_dict[zone.name] = zone
|
||||
|
||||
def addResources(self, sound_directory, script_directory):
|
||||
# add all of our required sounds
|
||||
os.chdir(sound_directory)
|
||||
path = os.getcwd()
|
||||
dir_list = os.listdir(path)
|
||||
# print("Files and directories in '", path, "' :")
|
||||
# print(dir_list)
|
||||
|
||||
for filename in dir_list:
|
||||
if filename.endswith(".ogg"):
|
||||
#print(filename)
|
||||
self.m.map_resource.add_resource_file(filename)
|
||||
|
||||
#add all of our lua scripts
|
||||
os.chdir(script_directory)
|
||||
path = os.getcwd()
|
||||
dir_list = os.listdir(path)
|
||||
# print("Files and directories in '", path, "' :")
|
||||
# print(dir_list)
|
||||
|
||||
for filename in dir_list:
|
||||
if filename.endswith(".lua"):
|
||||
print("Adding script to mission: " + filename)
|
||||
self.scripts[filename] = self.m.map_resource.add_resource_file(filename)
|
||||
|
||||
def getUnitsFromMiz(self, filename, side):
|
||||
forces = []
|
||||
os.chdir(self.home_dir)
|
||||
os.chdir(self.forces_dir + "/" + side)
|
||||
print("Looking for " + side + " Forces files in '", os.getcwd(), "' :")
|
||||
source_mission = dcs.mission.Mission()
|
||||
try:
|
||||
source_mission.load_file(filename)
|
||||
|
||||
for country_name in source_mission.coalition.get(side).countries:
|
||||
country_obj = source_mission.coalition.get(side).countries[country_name]
|
||||
for vehicle_group in country_obj.vehicle_group:
|
||||
forces.append(vehicle_group)
|
||||
return forces
|
||||
except:
|
||||
print("Failed to load units from " + filename)
|
||||
|
||||
|
||||
def generateMission(self, options):
|
||||
#get the template mission file
|
||||
|
||||
os.chdir(self.scenarios_dir)
|
||||
print("Looking for mission files in '", os.getcwd(), "' :")
|
||||
|
||||
self.m.load_file(options["scenario_filename"])
|
||||
|
||||
#Load the default coalitions for simplicity
|
||||
self.m.coalition.get("blue").load_from_dict(self.m, self.old_blue)
|
||||
self.m.coalition.get("red").load_from_dict(self.m, self.old_red)
|
||||
|
||||
|
||||
red_forces = self.getUnitsFromMiz(options["red_forces_filename"], "red")
|
||||
blue_forces = self.getUnitsFromMiz(options["blue_forces_filename"], "blue")
|
||||
|
||||
|
||||
|
||||
# add zones to target mission
|
||||
for zone in self.m.triggers.zones():
|
||||
if zone.name == "ALPHA":
|
||||
self.addZone(self.conflict_zones, self.RotorOpsZone("ALPHA", 101, zone.position, zone.radius))
|
||||
elif zone.name == "BRAVO":
|
||||
self.addZone(self.conflict_zones, self.RotorOpsZone("BRAVO", 102, zone.position, zone.radius))
|
||||
elif zone.name == "CHARLIE":
|
||||
self.addZone(self.conflict_zones, self.RotorOpsZone("CHARLIE", 103, zone.position, zone.radius))
|
||||
elif zone.name == "DELTA":
|
||||
self.addZone(self.conflict_zones, self.RotorOpsZone("DELTA", 104, zone.position, zone.radius))
|
||||
elif zone.name.rfind("STAGING") >= 0:
|
||||
self.addZone(self.staging_zones, self.RotorOpsZone(zone.name, None, zone.position, zone.radius))
|
||||
elif zone.name.rfind("SPAWN") >= 0:
|
||||
self.addZone(self.spawn_zones, self.RotorOpsZone(zone.name, None, zone.position, zone.radius))
|
||||
|
||||
#add files and triggers necessary for RotorOps.lua script
|
||||
self.addResources(self.sound_directory, self.script_directory)
|
||||
self.scriptTriggerSetup(options)
|
||||
|
||||
blue_zones = self.staging_zones
|
||||
red_zones = self.conflict_zones
|
||||
if options["defending"]:
|
||||
blue_zones = self.conflict_zones
|
||||
red_zones = self.staging_zones
|
||||
#swap airport sides
|
||||
blue_airports = self.getCoalitionAirports("blue")
|
||||
red_airports = self.getCoalitionAirports("red")
|
||||
for airport_name in blue_airports:
|
||||
self.m.terrain.airports[airport_name].set_red()
|
||||
for airport_name in red_airports:
|
||||
self.m.terrain.airports[airport_name].set_blue()
|
||||
|
||||
|
||||
#Add red ground units
|
||||
for zone_name in red_zones:
|
||||
if red_forces:
|
||||
self.addGroundGroups(red_zones[zone_name], self.m.country('Russia'), red_forces, options["red_quantity"])
|
||||
|
||||
#Add blue ground units
|
||||
for zone_name in blue_zones:
|
||||
if blue_forces:
|
||||
self.addGroundGroups(blue_zones[zone_name], self.m.country('USA'), blue_forces,
|
||||
options["blue_quantity"])
|
||||
|
||||
#Add player slots
|
||||
if options["slots"] == "Multiple Slots":
|
||||
self.addMultiplayerHelos()
|
||||
else:
|
||||
for helicopter in dcs.helicopters.helicopter_map:
|
||||
if helicopter == options["slots"]:
|
||||
self.addSinglePlayerHelos(dcs.helicopters.helicopter_map[helicopter])
|
||||
|
||||
self.addFlights(options)
|
||||
|
||||
#Set the Editor Map View
|
||||
self.m.map.position = self.m.terrain.airports[self.getCoalitionAirports("blue")[0]].position
|
||||
self.m.map.zoom = 100000
|
||||
|
||||
#Save the mission file
|
||||
print(self.m.triggers.zones())
|
||||
os.chdir(self.output_dir)
|
||||
output_filename = options["scenario_filename"].removesuffix('.miz') + " " + time.strftime('%a%H%M%S') + '.miz'
|
||||
success = self.m.save(output_filename)
|
||||
return {"success": success, "filename": output_filename, "directory": self.output_dir} #let the UI know the result
|
||||
|
||||
def addGroundGroups(self, zone, _country, groups, quantity):
|
||||
for a in range(0, quantity):
|
||||
|
||||
group = random.choice(groups)
|
||||
unit_types = []
|
||||
for unit in group.units:
|
||||
if dcs.vehicles.vehicle_map[unit.type]:
|
||||
unit_types.append(dcs.vehicles.vehicle_map[unit.type])
|
||||
country = self.m.country(_country.name)
|
||||
pos1 = zone.position.point_from_heading(5, 500)
|
||||
#for i in range(0, quantity):
|
||||
self.m.vehicle_group_platoon(
|
||||
country,
|
||||
zone.name + '-GND ' + str(a+1),
|
||||
unit_types,
|
||||
pos1.random_point_within(zone.size / 2, 500),
|
||||
heading=random.randint(0, 359),
|
||||
formation=dcs.unitgroup.VehicleGroup.Formation.Scattered,
|
||||
)
|
||||
|
||||
def getCoalitionAirports(self, side: str):
|
||||
coalition_airports = []
|
||||
for airport_name in self.m.terrain.airports:
|
||||
airportobj = self.m.terrain.airports[airport_name]
|
||||
if airportobj.coalition == str.upper(side):
|
||||
coalition_airports.append(airport_name)
|
||||
return coalition_airports
|
||||
|
||||
|
||||
def addSinglePlayerHelos(self, helotype):
|
||||
friendly_airports = self.getCoalitionAirports("blue")
|
||||
for airport_name in friendly_airports:
|
||||
fg = self.m.flight_group_from_airport(self.m.country('USA'), "Player Helos", helotype,
|
||||
self.m.terrain.airports[airport_name], group_size=2)
|
||||
fg.units[0].set_player()
|
||||
|
||||
|
||||
def addMultiplayerHelos(self):
|
||||
friendly_airports = self.getCoalitionAirports("blue")
|
||||
for airport_name in friendly_airports:
|
||||
for helotype in RotorOpsUnits.client_helos:
|
||||
fg = self.m.flight_group_from_airport(self.m.country('USA'), airport_name + " " + helotype.id, helotype,
|
||||
self.m.terrain.airports[airport_name], group_size=1)
|
||||
fg.units[0].set_client()
|
||||
|
||||
|
||||
class TrainingScenario():
|
||||
@staticmethod
|
||||
def random_orbit(rect: dcs.mapping.Rectangle):
|
||||
x1 = random.randrange(int(rect.bottom), int(rect.top))
|
||||
sy = rect.left
|
||||
y1 = random.randrange(int(sy), int(rect.right))
|
||||
heading = 90 if y1 < (sy + (rect.right - sy) / 2) else 270
|
||||
heading = random.randrange(heading - 20, heading + 20)
|
||||
race_dist = random.randrange(80 * 1000, 120 * 1000)
|
||||
return dcs.mapping.Point(x1, y1), heading, race_dist
|
||||
|
||||
|
||||
|
||||
def addFlights(self, options):
|
||||
usa = self.m.country(dcs.countries.USA.name)
|
||||
russia = self.m.country(dcs.countries.Russia.name)
|
||||
friendly_airport = self.m.terrain.airports[self.getCoalitionAirports("blue")[0]]
|
||||
enemy_airport = self.m.terrain.airports[self.getCoalitionAirports("red")[0]]
|
||||
|
||||
|
||||
orbit_rect = dcs.mapping.Rectangle(
|
||||
int(friendly_airport.position.x), int(friendly_airport.position.y - 100 * 1000), int(friendly_airport.position.x - 100 * 1000),
|
||||
int(friendly_airport.position.y))
|
||||
|
||||
if options["f_awacs"]:
|
||||
awacs_name = "AWACS"
|
||||
awacs_freq = 266
|
||||
pos, heading, race_dist = self.TrainingScenario.random_orbit(orbit_rect)
|
||||
awacs = self.m.awacs_flight(
|
||||
usa,
|
||||
awacs_name,
|
||||
plane_type=dcs.planes.E_3A,
|
||||
airport=None,
|
||||
position=pos,
|
||||
race_distance=race_dist, heading=heading,
|
||||
altitude=random.randrange(4000, 5500, 100), frequency=awacs_freq)
|
||||
|
||||
awacs_escort = self.m.escort_flight(usa, "AWACS Escort", dcs.countries.USA.Plane.F_15C, None, awacs, group_size=2)
|
||||
awacs_escort.load_loadout("Combat Air Patrol") #not working for f-15
|
||||
briefing = self.m.description_text() + "\n\n" + awacs_name + " " + str(awacs_freq) + ".00 " + "\n"
|
||||
self.m.set_description_text(briefing)
|
||||
|
||||
if options["f_tankers"]:
|
||||
t1_name = "Tanker KC_130 Basket"
|
||||
t1_freq = 253
|
||||
t1_tac = "61Y"
|
||||
t2_name = "Tanker KC_135 Boom"
|
||||
t2_freq = 256
|
||||
t2_tac = "101Y"
|
||||
pos, heading, race_dist = self.TrainingScenario.random_orbit(orbit_rect)
|
||||
refuel_net = self.m.refuel_flight(
|
||||
usa,
|
||||
t1_name,
|
||||
dcs.planes.KC130,
|
||||
airport=None,
|
||||
position=pos,
|
||||
race_distance=race_dist, heading=heading,
|
||||
altitude=random.randrange(4000, 5500, 100), speed=750, frequency=t1_freq, tacanchannel=t1_tac)
|
||||
|
||||
pos, heading, race_dist = self.TrainingScenario.random_orbit(orbit_rect)
|
||||
refuel_rod = self.m.refuel_flight(
|
||||
usa,
|
||||
t2_name,
|
||||
dcs.planes.KC_135,
|
||||
airport=None,
|
||||
position=pos,
|
||||
race_distance=race_dist, heading=heading,
|
||||
altitude=random.randrange(4000, 5500, 100), frequency=t2_freq, tacanchannel=t2_tac)
|
||||
|
||||
briefing = self.m.description_text() + "\n\n" + t1_name + " " + str(t1_freq) + ".00 " + t1_tac + "\n" + t2_name + " " + str(t2_freq) + ".00 " + t2_tac + "\n"
|
||||
self.m.set_description_text(briefing)
|
||||
|
||||
def zone_attack(fg, unit_type):
|
||||
fg.set_skill(dcs.unit.Skill.Random)
|
||||
fg.late_activation = True
|
||||
#fg.load_loadout(unit_type["loadout"])
|
||||
#task = dcs.task.CAS
|
||||
#loadout = dcs.planes.Su_25.loadout(task)
|
||||
#loadout = dcs.planes.Su_25.loadout_by_name("Ground Attack")
|
||||
#fg.load_task_default_loadout(task)
|
||||
#fg.load_loadout("Ground Attack")
|
||||
#fg.load_task_default_loadout(dcs.task.GroundAttack)
|
||||
|
||||
#fg.load_loadout("2xB-13L+4xATGM 9M114")
|
||||
if options["defending"]:
|
||||
for zone_name in self.conflict_zones:
|
||||
fg.add_waypoint(self.conflict_zones[zone_name].position, 1000)
|
||||
else:
|
||||
for zone_name in reversed(self.conflict_zones):
|
||||
fg.add_waypoint(self.conflict_zones[zone_name].position, 1000)
|
||||
fg.add_runway_waypoint(enemy_airport)
|
||||
fg.land_at(enemy_airport)
|
||||
|
||||
if options["e_attack_helos"]:
|
||||
helo = random.choice(RotorOpsUnits.e_attack_helos)
|
||||
afg = self.m.flight_group_from_airport(
|
||||
russia,
|
||||
"Enemy Attack Helicopters",
|
||||
helo,
|
||||
airport=enemy_airport,
|
||||
maintask=dcs.task.GroundAttack,
|
||||
start_type=dcs.mission.StartType.Warm,
|
||||
group_size=2)
|
||||
zone_attack(afg, helo)
|
||||
|
||||
if options["e_attack_planes"]:
|
||||
plane = random.choice(RotorOpsUnits.e_attack_planes)
|
||||
afg = self.m.flight_group_from_airport(
|
||||
russia, "Enemy Attack Planes", plane["type"],
|
||||
airport=enemy_airport,
|
||||
maintask=dcs.task.GroundAttack,
|
||||
start_type=dcs.mission.StartType.Warm,
|
||||
group_size=2)
|
||||
zone_attack(afg, plane)
|
||||
|
||||
|
||||
def scriptTriggerSetup(self, options):
|
||||
|
||||
#get the boolean value from ui option and convert to lua string
|
||||
def lb(var):
|
||||
return str(options[var]).lower()
|
||||
|
||||
game_flag = 100
|
||||
#Add the first trigger
|
||||
mytrig = dcs.triggers.TriggerOnce(comment="RotorOps Setup Scripts")
|
||||
mytrig.rules.append(dcs.condition.TimeAfter(1))
|
||||
mytrig.actions.append(dcs.action.DoScriptFile(self.scripts["mist_4_4_90.lua"]))
|
||||
mytrig.actions.append(dcs.action.DoScriptFile(self.scripts["Splash_Damage_2_0.lua"]))
|
||||
mytrig.actions.append(dcs.action.DoScriptFile(self.scripts["CTLD.lua"]))
|
||||
mytrig.actions.append(dcs.action.DoScriptFile(self.scripts["RotorOps.lua"]))
|
||||
mytrig.actions.append(dcs.action.DoScript(dcs.action.String((
|
||||
"--OPTIONS HERE!\n\n" +
|
||||
"RotorOps.CTLD_crates = " + lb("crates") + "\n\n" +
|
||||
"RotorOps.CTLD_sound_effects = true\n\n" +
|
||||
"RotorOps.force_offroad = " + lb("force_offroad") + "\n\n" +
|
||||
"RotorOps.voice_overs = " + lb("voiceovers") + "\n\n" +
|
||||
"RotorOps.zone_status_display = " + lb("game_display") + "\n\n" +
|
||||
"RotorOps.inf_spawns_per_zone = " + lb("inf_spawn_qty") + "\n\n" +
|
||||
"RotorOps.apcs_spawn_infantry = " + lb("apc_spawns_inf") + " \n\n"))))
|
||||
self.m.triggerrules.triggers.append(mytrig)
|
||||
|
||||
#Add the second trigger
|
||||
mytrig = dcs.triggers.TriggerOnce(comment="RotorOps Setup Zones")
|
||||
mytrig.rules.append(dcs.condition.TimeAfter(2))
|
||||
for s_zone in self.staging_zones:
|
||||
mytrig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.stagingZone('" + s_zone + "')")))
|
||||
for c_zone in self.conflict_zones:
|
||||
zone_flag = self.conflict_zones[c_zone].flag
|
||||
mytrig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.addZone('" + c_zone + "'," + str(zone_flag) + ")")))
|
||||
|
||||
mytrig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.setupConflict('" + str(game_flag) + "')")))
|
||||
|
||||
self.m.triggerrules.triggers.append(mytrig)
|
||||
|
||||
#Add the third trigger
|
||||
mytrig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict Start")
|
||||
mytrig.rules.append(dcs.condition.TimeAfter(10))
|
||||
mytrig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.startConflict(100)")))
|
||||
self.m.triggerrules.triggers.append(mytrig)
|
||||
|
||||
#Add all zone-based triggers
|
||||
for index, c_zone in enumerate(self.conflict_zones):
|
||||
|
||||
z_active_trig = dcs.triggers.TriggerOnce(comment= c_zone + " Active")
|
||||
z_active_trig.rules.append(dcs.condition.FlagEquals(game_flag, index + 1))
|
||||
z_active_trig.actions.append(dcs.action.DoScript(dcs.action.String("--Add any action you want here!")))
|
||||
self.m.triggerrules.triggers.append(z_active_trig)
|
||||
|
||||
zone_flag = self.conflict_zones[c_zone].flag
|
||||
z_weak_trig = dcs.triggers.TriggerOnce(comment= c_zone + " Weak")
|
||||
z_weak_trig.rules.append(dcs.condition.FlagIsMore(zone_flag, 10))
|
||||
z_weak_trig.rules.append(dcs.condition.FlagIsLess(zone_flag, random.randrange(20, 80)))
|
||||
z_weak_trig.actions.append(dcs.action.DoScript(dcs.action.String("--Add any action you want here!\n\n--Flag value represents the percentage of defending ground units remaining. ")))
|
||||
if options["e_attack_helos"]:
|
||||
z_weak_trig.actions.append(dcs.action.DoScript(dcs.action.String("mist.respawnGroup('Enemy Attack Helicopters', true)")))
|
||||
self.m.triggerrules.triggers.append(z_weak_trig)
|
||||
|
||||
#Add game won/lost triggers
|
||||
mytrig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict WON")
|
||||
mytrig.rules.append(dcs.condition.FlagEquals(game_flag, 99))
|
||||
mytrig.actions.append(dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is WON")))
|
||||
self.m.triggerrules.triggers.append(mytrig)
|
||||
|
||||
mytrig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict LOST")
|
||||
mytrig.rules.append(dcs.condition.FlagEquals(game_flag, 98))
|
||||
mytrig.actions.append(dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is LOST")))
|
||||
self.m.triggerrules.triggers.append(mytrig)
|
||||
|
||||
|
||||
26
Generator/RotorOpsUnits.py
Normal file
26
Generator/RotorOpsUnits.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import dcs
|
||||
|
||||
client_helos = [
|
||||
dcs.helicopters.UH_1H,
|
||||
dcs.helicopters.Mi_8MT,
|
||||
dcs.helicopters.Mi_24P,
|
||||
dcs.helicopters.Ka_50,
|
||||
]
|
||||
|
||||
e_attack_helos = [
|
||||
dcs.helicopters.Mi_24P,
|
||||
dcs.helicopters.Ka_50,
|
||||
dcs.helicopters.Mi_28N,
|
||||
]
|
||||
|
||||
e_transport_helos = [
|
||||
dcs.helicopters.Mi_26,
|
||||
dcs.helicopters.Mi_24P,
|
||||
dcs.helicopters.Mi_8MT,
|
||||
]
|
||||
|
||||
e_attack_planes = [
|
||||
{'type': dcs.planes.Su_34, 'loadout': "APU-8 Vikhr-M*2,Kh-25ML,R-73*2,SPPU-22*2,Mercury LLTV Pod,MPS-410"},
|
||||
{'type': dcs.planes.Su_25, 'loadout': "RKB-250*8,R-60M*2"},
|
||||
|
||||
]
|
||||
17
Generator/RotorOpsUtils.py
Normal file
17
Generator/RotorOpsUtils.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import math
|
||||
import dcs
|
||||
|
||||
|
||||
def getDistance(point1=dcs.Point, point2=dcs.Point):
|
||||
x1 = point1.x
|
||||
y1 = point1.y
|
||||
x2 = point2.x
|
||||
y2 = point2.y
|
||||
dX = abs(x1-x2)
|
||||
dY = abs(y1-y2)
|
||||
distance = math.sqrt(dX*dX + dY*dY)
|
||||
return distance
|
||||
|
||||
def convertMeterToNM(meters=int):
|
||||
nm = meters / 1852
|
||||
return nm
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Generator/Scenarios/Nevada Conflict - Vegas Tour (GRIMM).miz
Normal file
BIN
Generator/Scenarios/Nevada Conflict - Vegas Tour (GRIMM).miz
Normal file
Binary file not shown.
BIN
Generator/Scenarios/PG Conflict - Abu Dhabi to Ras (GRIMM).miz
Normal file
BIN
Generator/Scenarios/PG Conflict - Abu Dhabi to Ras (GRIMM).miz
Normal file
Binary file not shown.
BIN
Generator/Scenarios/Syria Conflict - Aleppo Tour (GRIMM).miz
Normal file
BIN
Generator/Scenarios/Syria Conflict - Aleppo Tour (GRIMM).miz
Normal file
Binary file not shown.
20
Generator/Scenarios/_How to create your own scenarios.txt
Normal file
20
Generator/Scenarios/_How to create your own scenarios.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
You can add your own scenarios in this directory and they will appear in the mission generator.
|
||||
|
||||
A scenario .miz file MUST have:
|
||||
|
||||
1) Between 1-4 trigger zones called "ALPHA", "BRAVO", "CHARLIE", "DELTA"
|
||||
2) At least one trigger zone with a name that starts with "STAGING".
|
||||
3) A blue airport (recommend somewhere near your staging zone).
|
||||
4) A red airport (recommend somewhere near your last conflict zone).
|
||||
|
||||
Optional:
|
||||
You can add smaller infantry spawning zones inside conflict zones. Add near buildings to simulate infantry hiding within. Name them like "ALPHA_SPAWN", "ALPHA_SPAWN_2, etc.
|
||||
|
||||
Tips:
|
||||
-The conflict game type can be played with blue forces on defense. In this mode the last conflict zone is the only troop pickup zone.
|
||||
-Design your template so that it can be played in normal 'attacking' mode or 'defending' the conflict zone from enemy ground units starting from the staging zone.
|
||||
-Keep the zones fairly close together, both for helicopter and ground unit travel times.
|
||||
-You can place static objects and units in a scenario template.
|
||||
-You can change mission briefing and other mission options in the template.
|
||||
-Drop your templates in the RotorOps Discord if you'd like to have them added in a release for everyone. Maintain a similar naming convention and be sure to credit yourself in the .miz name.
|
||||
-Airfields can be captured with ground units. You might consider placing conflict zones over neutral airfields and adding unarmed client slots.
|
||||
BIN
Generator/Scenarios/pg_test.miz
Normal file
BIN
Generator/Scenarios/pg_test.miz
Normal file
Binary file not shown.
BIN
Generator/Scenarios/zone test.miz
Normal file
BIN
Generator/Scenarios/zone test.miz
Normal file
Binary file not shown.
BIN
Generator/assets/background.PNG
Normal file
BIN
Generator/assets/background.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
BIN
Generator/assets/icon.ico
Normal file
BIN
Generator/assets/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 259 KiB |
BIN
Generator/dist/MissionGenerator.exe
vendored
Normal file
BIN
Generator/dist/MissionGenerator.exe
vendored
Normal file
Binary file not shown.
5
Generator/utils/embed sounds/How To Embed Sounds.txt
Normal file
5
Generator/utils/embed sounds/How To Embed Sounds.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
1) Place your .miz file in this directory.
|
||||
2) Run embed_sounds.exe
|
||||
3) A new file will be created in the same directory; a copy of your mission file with RotorOps sound files already embedded so you don't need to add manually.
|
||||
|
||||
Tip: You can use this tool to update your existing RotorOps missions with the current sound files.
|
||||
37
Generator/utils/embed sounds/embed_sounds.py
Normal file
37
Generator/utils/embed sounds/embed_sounds.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import dcs
|
||||
import os
|
||||
|
||||
from tkinter import messagebox as mbox
|
||||
|
||||
mizfound = False
|
||||
path = os.getcwd()
|
||||
dir_list = os.listdir(path)
|
||||
print("Looking for mission files in '", path, "' :")
|
||||
|
||||
|
||||
for filename in dir_list:
|
||||
if filename.endswith(".miz") and not filename == "template_source.miz" and not filename.startswith("SoundsAdded"):
|
||||
mizfound = True
|
||||
print("Attempting to add sound files to: " + filename)
|
||||
m = dcs.mission.Mission()
|
||||
m.load_file(filename)
|
||||
|
||||
# add all of our required sounds
|
||||
os.chdir("../sound/embedded")
|
||||
path = os.getcwd()
|
||||
sound_file_list = os.listdir(path)
|
||||
print("Attempting to add sound files from '", path, "' :")
|
||||
|
||||
for soundfilename in sound_file_list:
|
||||
if soundfilename.endswith(".ogg"):
|
||||
print("Adding " + soundfilename)
|
||||
m.map_resource.add_resource_file(soundfilename)
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
os.chdir("../../Generator")
|
||||
m.save("SoundsAdded_" + filename)
|
||||
|
||||
if not mizfound:
|
||||
print("No valid miz files found!")
|
||||
mbox.showerror('No Source Files Found', 'Error: Place your .miz files in this directory before running the application.')
|
||||
40
Generator/utils/embed sounds/embed_sounds.spec
Normal file
40
Generator/utils/embed sounds/embed_sounds.spec
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(['embed_sounds.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='embed_sounds',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None )
|
||||
Reference in New Issue
Block a user