This commit is contained in:
spencer-ki 2022-02-05 20:25:41 -08:00
parent a28bc7ff5b
commit d2f413a126
15 changed files with 490 additions and 111 deletions

View File

@ -13,6 +13,9 @@ from PyQt5.QtWidgets import (
from PyQt5 import QtGui from PyQt5 import QtGui
from MissionGeneratorUI import Ui_MainWindow from MissionGeneratorUI import Ui_MainWindow
maj_version = 0
minor_version = 3
version_string = str(maj_version) + "." + str(minor_version)
scenarios = [] scenarios = []
red_forces_files = [] red_forces_files = []
blue_forces_files = [] blue_forces_files = []
@ -43,6 +46,8 @@ class Window(QMainWindow, Ui_MainWindow):
self.statusbar.setStyleSheet( self.statusbar.setStyleSheet(
"QStatusBar{padding-left:5px;color:black;font-weight:bold;}") "QStatusBar{padding-left:5px;color:black;font-weight:bold;}")
self.version_label.setText("Version " + version_string)
def connectSignalsSlots(self): def connectSignalsSlots(self):
# self.action_Exit.triggered.connect(self.close) # self.action_Exit.triggered.connect(self.close)
@ -155,14 +160,13 @@ class Window(QMainWindow, Ui_MainWindow):
"crates": self.logistics_crates_checkBox.isChecked(), "crates": self.logistics_crates_checkBox.isChecked(),
"f_awacs": self.awacs_checkBox.isChecked(), "f_awacs": self.awacs_checkBox.isChecked(),
"f_tankers": self.tankers_checkBox.isChecked(), "f_tankers": self.tankers_checkBox.isChecked(),
"smoke_zone": self.smoke_checkBox.isChecked(),
"voiceovers": self.voiceovers_checkBox.isChecked(), "voiceovers": self.voiceovers_checkBox.isChecked(),
"force_offroad": self.force_offroad_checkBox.isChecked(), "force_offroad": self.force_offroad_checkBox.isChecked(),
"game_display": self.game_status_checkBox.isChecked(), "game_display": self.game_status_checkBox.isChecked(),
"defending": self.defense_checkBox.isChecked(), "defending": self.defense_checkBox.isChecked(),
"slots": self.slot_template_comboBox.currentText(), "slots": self.slot_template_comboBox.currentText(),
"smoke_zone": self.smoke_checkBox.isChecked(),
"zone_protect_sams": self.zone_sams_checkBox.isChecked(), "zone_protect_sams": self.zone_sams_checkBox.isChecked(),
"zone_farps": self.farp_buttonGroup.checkedButton().objectName(),
} }
os.chdir(self.m.home_dir + '/Generator') os.chdir(self.m.home_dir + '/Generator')
n = ROps.RotorOpsMission() n = ROps.RotorOpsMission()

View File

@ -73,7 +73,7 @@ class Ui_MainWindow(object):
self.redforces_comboBox.setGeometry(QtCore.QRect(170, 230, 291, 31)) self.redforces_comboBox.setGeometry(QtCore.QRect(170, 230, 291, 31))
self.redforces_comboBox.setObjectName("redforces_comboBox") self.redforces_comboBox.setObjectName("redforces_comboBox")
self.background_label = QtWidgets.QLabel(self.centralwidget) self.background_label = QtWidgets.QLabel(self.centralwidget)
self.background_label.setGeometry(QtCore.QRect(-30, 490, 801, 371)) self.background_label.setGeometry(QtCore.QRect(-40, 440, 801, 371))
self.background_label.setAutoFillBackground(False) self.background_label.setAutoFillBackground(False)
self.background_label.setStyleSheet("") self.background_label.setStyleSheet("")
self.background_label.setText("") self.background_label.setText("")
@ -113,7 +113,7 @@ class Ui_MainWindow(object):
self.scenario_label_4.setAlignment(QtCore.Qt.AlignCenter) self.scenario_label_4.setAlignment(QtCore.Qt.AlignCenter)
self.scenario_label_4.setObjectName("scenario_label_4") self.scenario_label_4.setObjectName("scenario_label_4")
self.game_status_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.game_status_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.game_status_checkBox.setGeometry(QtCore.QRect(1000, 590, 191, 16)) self.game_status_checkBox.setGeometry(QtCore.QRect(810, 790, 191, 16))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.game_status_checkBox.setFont(font) self.game_status_checkBox.setFont(font)
@ -121,20 +121,21 @@ class Ui_MainWindow(object):
self.game_status_checkBox.setTristate(False) self.game_status_checkBox.setTristate(False)
self.game_status_checkBox.setObjectName("game_status_checkBox") self.game_status_checkBox.setObjectName("game_status_checkBox")
self.voiceovers_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.voiceovers_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.voiceovers_checkBox.setGeometry(QtCore.QRect(1000, 650, 191, 16)) self.voiceovers_checkBox.setGeometry(QtCore.QRect(810, 820, 191, 16))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.voiceovers_checkBox.setFont(font) self.voiceovers_checkBox.setFont(font)
self.voiceovers_checkBox.setChecked(True) self.voiceovers_checkBox.setChecked(True)
self.voiceovers_checkBox.setObjectName("voiceovers_checkBox") self.voiceovers_checkBox.setObjectName("voiceovers_checkBox")
self.logistics_crates_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.logistics_crates_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.logistics_crates_checkBox.setGeometry(QtCore.QRect(970, 390, 251, 31)) self.logistics_crates_checkBox.setGeometry(QtCore.QRect(920, 320, 251, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(11) font.setPointSize(11)
self.logistics_crates_checkBox.setFont(font) self.logistics_crates_checkBox.setFont(font)
self.logistics_crates_checkBox.setChecked(True)
self.logistics_crates_checkBox.setObjectName("logistics_crates_checkBox") self.logistics_crates_checkBox.setObjectName("logistics_crates_checkBox")
self.awacs_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.awacs_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.awacs_checkBox.setGeometry(QtCore.QRect(970, 420, 251, 31)) self.awacs_checkBox.setGeometry(QtCore.QRect(920, 350, 251, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(11) font.setPointSize(11)
self.awacs_checkBox.setFont(font) self.awacs_checkBox.setFont(font)
@ -142,20 +143,20 @@ class Ui_MainWindow(object):
self.awacs_checkBox.setChecked(True) self.awacs_checkBox.setChecked(True)
self.awacs_checkBox.setObjectName("awacs_checkBox") self.awacs_checkBox.setObjectName("awacs_checkBox")
self.tankers_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.tankers_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.tankers_checkBox.setGeometry(QtCore.QRect(970, 450, 251, 31)) self.tankers_checkBox.setGeometry(QtCore.QRect(920, 380, 251, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(11) font.setPointSize(11)
self.tankers_checkBox.setFont(font) self.tankers_checkBox.setFont(font)
self.tankers_checkBox.setChecked(True) self.tankers_checkBox.setChecked(True)
self.tankers_checkBox.setObjectName("tankers_checkBox") self.tankers_checkBox.setObjectName("tankers_checkBox")
self.apcs_spawn_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.apcs_spawn_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.apcs_spawn_checkBox.setGeometry(QtCore.QRect(500, 400, 251, 31)) self.apcs_spawn_checkBox.setGeometry(QtCore.QRect(470, 400, 251, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(10) font.setPointSize(10)
self.apcs_spawn_checkBox.setFont(font) self.apcs_spawn_checkBox.setFont(font)
self.apcs_spawn_checkBox.setObjectName("apcs_spawn_checkBox") self.apcs_spawn_checkBox.setObjectName("apcs_spawn_checkBox")
self.inf_spawn_spinBox = QtWidgets.QSpinBox(self.centralwidget) self.inf_spawn_spinBox = QtWidgets.QSpinBox(self.centralwidget)
self.inf_spawn_spinBox.setGeometry(QtCore.QRect(710, 360, 71, 31)) self.inf_spawn_spinBox.setGeometry(QtCore.QRect(680, 360, 71, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(12) font.setPointSize(12)
self.inf_spawn_spinBox.setFont(font) self.inf_spawn_spinBox.setFont(font)
@ -163,13 +164,6 @@ class Ui_MainWindow(object):
self.inf_spawn_spinBox.setMaximum(50) self.inf_spawn_spinBox.setMaximum(50)
self.inf_spawn_spinBox.setProperty("value", 2) self.inf_spawn_spinBox.setProperty("value", 2)
self.inf_spawn_spinBox.setObjectName("inf_spawn_spinBox") self.inf_spawn_spinBox.setObjectName("inf_spawn_spinBox")
self.smoke_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.smoke_checkBox.setGeometry(QtCore.QRect(1000, 620, 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 = QtWidgets.QLabel(self.centralwidget)
self.scenario_label_5.setGeometry(QtCore.QRect(50, 260, 101, 31)) self.scenario_label_5.setGeometry(QtCore.QRect(50, 260, 101, 31))
font = QtGui.QFont() font = QtGui.QFont()
@ -182,28 +176,28 @@ class Ui_MainWindow(object):
self.forces_hint_label_2.setAlignment(QtCore.Qt.AlignCenter) self.forces_hint_label_2.setAlignment(QtCore.Qt.AlignCenter)
self.forces_hint_label_2.setObjectName("forces_hint_label_2") self.forces_hint_label_2.setObjectName("forces_hint_label_2")
self.label = QtWidgets.QLabel(self.centralwidget) self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(500, 360, 191, 31)) self.label.setGeometry(QtCore.QRect(470, 360, 191, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(10) font.setPointSize(10)
self.label.setFont(font) self.label.setFont(font)
self.label.setObjectName("label") self.label.setObjectName("label")
self.slot_template_comboBox = QtWidgets.QComboBox(self.centralwidget) self.slot_template_comboBox = QtWidgets.QComboBox(self.centralwidget)
self.slot_template_comboBox.setGeometry(QtCore.QRect(870, 700, 291, 31)) self.slot_template_comboBox.setGeometry(QtCore.QRect(870, 640, 291, 31))
self.slot_template_comboBox.setObjectName("slot_template_comboBox") self.slot_template_comboBox.setObjectName("slot_template_comboBox")
self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(750, 700, 111, 31)) self.label_2.setGeometry(QtCore.QRect(750, 640, 111, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(11) font.setPointSize(11)
self.label_2.setFont(font) self.label_2.setFont(font)
self.label_2.setObjectName("label_2") self.label_2.setObjectName("label_2")
self.scenario_label_6 = QtWidgets.QLabel(self.centralwidget) self.scenario_label_6 = QtWidgets.QLabel(self.centralwidget)
self.scenario_label_6.setGeometry(QtCore.QRect(500, 320, 141, 31)) self.scenario_label_6.setGeometry(QtCore.QRect(470, 320, 141, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(11) font.setPointSize(11)
self.scenario_label_6.setFont(font) self.scenario_label_6.setFont(font)
self.scenario_label_6.setObjectName("scenario_label_6") self.scenario_label_6.setObjectName("scenario_label_6")
self.force_offroad_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.force_offroad_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.force_offroad_checkBox.setGeometry(QtCore.QRect(1000, 560, 191, 16)) self.force_offroad_checkBox.setGeometry(QtCore.QRect(810, 760, 191, 16))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(9) font.setPointSize(9)
self.force_offroad_checkBox.setFont(font) self.force_offroad_checkBox.setFont(font)
@ -226,13 +220,13 @@ class Ui_MainWindow(object):
self.e_attack_helos_spinBox.setProperty("value", 2) self.e_attack_helos_spinBox.setProperty("value", 2)
self.e_attack_helos_spinBox.setObjectName("e_attack_helos_spinBox") self.e_attack_helos_spinBox.setObjectName("e_attack_helos_spinBox")
self.scenario_label_7 = QtWidgets.QLabel(self.centralwidget) self.scenario_label_7 = QtWidgets.QLabel(self.centralwidget)
self.scenario_label_7.setGeometry(QtCore.QRect(140, 330, 231, 31)) self.scenario_label_7.setGeometry(QtCore.QRect(140, 330, 211, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(11) font.setPointSize(11)
self.scenario_label_7.setFont(font) self.scenario_label_7.setFont(font)
self.scenario_label_7.setObjectName("scenario_label_7") self.scenario_label_7.setObjectName("scenario_label_7")
self.scenario_label_8 = QtWidgets.QLabel(self.centralwidget) self.scenario_label_8 = QtWidgets.QLabel(self.centralwidget)
self.scenario_label_8.setGeometry(QtCore.QRect(140, 370, 231, 31)) self.scenario_label_8.setGeometry(QtCore.QRect(140, 370, 201, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(11) font.setPointSize(11)
self.scenario_label_8.setFont(font) self.scenario_label_8.setFont(font)
@ -247,11 +241,51 @@ class Ui_MainWindow(object):
self.e_attack_planes_spinBox.setProperty("value", 1) self.e_attack_planes_spinBox.setProperty("value", 1)
self.e_attack_planes_spinBox.setObjectName("e_attack_planes_spinBox") self.e_attack_planes_spinBox.setObjectName("e_attack_planes_spinBox")
self.zone_sams_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.zone_sams_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.zone_sams_checkBox.setGeometry(QtCore.QRect(970, 480, 201, 31)) self.zone_sams_checkBox.setGeometry(QtCore.QRect(920, 410, 201, 31))
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(11) font.setPointSize(11)
self.zone_sams_checkBox.setFont(font) self.zone_sams_checkBox.setFont(font)
self.zone_sams_checkBox.setObjectName("zone_sams_checkBox") self.zone_sams_checkBox.setObjectName("zone_sams_checkBox")
self.scenario_label_9 = QtWidgets.QLabel(self.centralwidget)
self.scenario_label_9.setGeometry(QtCore.QRect(740, 490, 171, 31))
font = QtGui.QFont()
font.setPointSize(10)
self.scenario_label_9.setFont(font)
self.scenario_label_9.setObjectName("scenario_label_9")
self.inf_spawn_voiceovers_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.inf_spawn_voiceovers_checkBox.setGeometry(QtCore.QRect(470, 430, 251, 31))
font = QtGui.QFont()
font.setPointSize(10)
self.inf_spawn_voiceovers_checkBox.setFont(font)
self.inf_spawn_voiceovers_checkBox.setObjectName("inf_spawn_voiceovers_checkBox")
self.farp_never = QtWidgets.QRadioButton(self.centralwidget)
self.farp_never.setGeometry(QtCore.QRect(950, 500, 95, 20))
font = QtGui.QFont()
font.setPointSize(9)
self.farp_never.setFont(font)
self.farp_never.setObjectName("farp_never")
self.farp_buttonGroup = QtWidgets.QButtonGroup(MainWindow)
self.farp_buttonGroup.setObjectName("farp_buttonGroup")
self.farp_buttonGroup.addButton(self.farp_never)
self.farp_gunits = QtWidgets.QRadioButton(self.centralwidget)
self.farp_gunits.setGeometry(QtCore.QRect(950, 530, 221, 21))
font = QtGui.QFont()
font.setPointSize(9)
self.farp_gunits.setFont(font)
self.farp_gunits.setChecked(True)
self.farp_gunits.setObjectName("farp_gunits")
self.farp_buttonGroup.addButton(self.farp_gunits)
self.farp_always = QtWidgets.QRadioButton(self.centralwidget)
self.farp_always.setGeometry(QtCore.QRect(950, 560, 221, 21))
font = QtGui.QFont()
font.setPointSize(9)
self.farp_always.setFont(font)
self.farp_always.setObjectName("farp_always")
self.farp_buttonGroup.addButton(self.farp_always)
self.version_label = QtWidgets.QLabel(self.centralwidget)
self.version_label.setGeometry(QtCore.QRect(920, 840, 241, 21))
self.version_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.version_label.setObjectName("version_label")
self.background_label.raise_() self.background_label.raise_()
self.scenario_comboBox.raise_() self.scenario_comboBox.raise_()
self.scenario_label.raise_() self.scenario_label.raise_()
@ -273,7 +307,6 @@ class Ui_MainWindow(object):
self.tankers_checkBox.raise_() self.tankers_checkBox.raise_()
self.apcs_spawn_checkBox.raise_() self.apcs_spawn_checkBox.raise_()
self.inf_spawn_spinBox.raise_() self.inf_spawn_spinBox.raise_()
self.smoke_checkBox.raise_()
self.scenario_label_5.raise_() self.scenario_label_5.raise_()
self.forces_hint_label_2.raise_() self.forces_hint_label_2.raise_()
self.label.raise_() self.label.raise_()
@ -287,6 +320,12 @@ class Ui_MainWindow(object):
self.scenario_label_8.raise_() self.scenario_label_8.raise_()
self.e_attack_planes_spinBox.raise_() self.e_attack_planes_spinBox.raise_()
self.zone_sams_checkBox.raise_() self.zone_sams_checkBox.raise_()
self.scenario_label_9.raise_()
self.inf_spawn_voiceovers_checkBox.raise_()
self.farp_never.raise_()
self.farp_gunits.raise_()
self.farp_always.raise_()
self.version_label.raise_()
MainWindow.setCentralWidget(self.centralwidget) MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1209, 26)) self.menubar.setGeometry(QtCore.QRect(0, 0, 1209, 26))
@ -334,15 +373,13 @@ class Ui_MainWindow(object):
self.game_status_checkBox.setText(_translate("MainWindow", "Game Status Display")) 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.setStatusTip(_translate("MainWindow", "Voiceovers from the ground commander. Helps keep focus on the active zone."))
self.voiceovers_checkBox.setText(_translate("MainWindow", "Voiceovers")) 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.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 Crates")) self.logistics_crates_checkBox.setText(_translate("MainWindow", "Logistics"))
self.awacs_checkBox.setText(_translate("MainWindow", "Friendly AWACS")) self.awacs_checkBox.setText(_translate("MainWindow", "Friendly AWACS"))
self.tankers_checkBox.setText(_translate("MainWindow", "Friendly Tankers")) 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.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.apcs_spawn_checkBox.setText(_translate("MainWindow", "APCs Spawn Infantry"))
self.inf_spawn_spinBox.setStatusTip(_translate("MainWindow", "This value is multiplied by the number of spawn zones in the mission template.")) 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.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.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.label.setText(_translate("MainWindow", "Infantry Groups per zone:"))
@ -358,6 +395,16 @@ class Ui_MainWindow(object):
self.e_attack_planes_spinBox.setStatusTip(_translate("MainWindow", "Approximate number of enemy attack plane group spawns.")) self.e_attack_planes_spinBox.setStatusTip(_translate("MainWindow", "Approximate number of enemy attack plane group spawns."))
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.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.zone_sams_checkBox.setText(_translate("MainWindow", "Inactive Zone SAMs"))
self.scenario_label_9.setText(_translate("MainWindow", "Zone FARP Conditions:"))
self.inf_spawn_voiceovers_checkBox.setStatusTip(_translate("MainWindow", "Friendly/enemy APCs will drop infantry when reaching a new conflict zone."))
self.inf_spawn_voiceovers_checkBox.setText(_translate("MainWindow", "Voiceovers on Infantry Spawn"))
self.farp_never.setStatusTip(_translate("MainWindow", "Never spawn FARPs in defeated conflict zones."))
self.farp_never.setText(_translate("MainWindow", "Never"))
self.farp_gunits.setStatusTip(_translate("MainWindow", "Only spawn FARPs in defeated conflict zones if we have sufficient ground units remaining."))
self.farp_gunits.setText(_translate("MainWindow", "20% Ground Units Remaining"))
self.farp_always.setStatusTip(_translate("MainWindow", "Always spawn a FARP in defeated conflict zones."))
self.farp_always.setText(_translate("MainWindow", "Always"))
self.version_label.setText(_translate("MainWindow", "Version string"))
self.action_generateMission.setText(_translate("MainWindow", "_generateMission")) self.action_generateMission.setText(_translate("MainWindow", "_generateMission"))
self.action_scenarioSelected.setText(_translate("MainWindow", "_scenarioSelected")) self.action_scenarioSelected.setText(_translate("MainWindow", "_scenarioSelected"))
self.action_blueforcesSelected.setText(_translate("MainWindow", "_blueforcesSelected")) self.action_blueforcesSelected.setText(_translate("MainWindow", "_blueforcesSelected"))

View File

@ -183,8 +183,8 @@ p, li { white-space: pre-wrap; }
<widget class="QLabel" name="background_label"> <widget class="QLabel" name="background_label">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>-30</x> <x>-40</x>
<y>490</y> <y>440</y>
<width>801</width> <width>801</width>
<height>371</height> <height>371</height>
</rect> </rect>
@ -312,8 +312,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="game_status_checkBox"> <widget class="QCheckBox" name="game_status_checkBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>1000</x> <x>810</x>
<y>590</y> <y>790</y>
<width>191</width> <width>191</width>
<height>16</height> <height>16</height>
</rect> </rect>
@ -339,8 +339,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="voiceovers_checkBox"> <widget class="QCheckBox" name="voiceovers_checkBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>1000</x> <x>810</x>
<y>650</y> <y>820</y>
<width>191</width> <width>191</width>
<height>16</height> <height>16</height>
</rect> </rect>
@ -363,8 +363,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="logistics_crates_checkBox"> <widget class="QCheckBox" name="logistics_crates_checkBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>970</x> <x>920</x>
<y>390</y> <y>320</y>
<width>251</width> <width>251</width>
<height>31</height> <height>31</height>
</rect> </rect>
@ -375,17 +375,20 @@ p, li { white-space: pre-wrap; }
</font> </font>
</property> </property>
<property name="statusTip"> <property name="statusTip">
<string>Enable CTLD logistics crates for building ground units and air defenses.</string> <string>Enable CTLD logistics crates for building ground units and air defenses. Pickup logistics containers to create new logistics sites.</string>
</property> </property>
<property name="text"> <property name="text">
<string>Logistics Crates</string> <string>Logistics</string>
</property>
<property name="checked">
<bool>true</bool>
</property> </property>
</widget> </widget>
<widget class="QCheckBox" name="awacs_checkBox"> <widget class="QCheckBox" name="awacs_checkBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>970</x> <x>920</x>
<y>420</y> <y>350</y>
<width>251</width> <width>251</width>
<height>31</height> <height>31</height>
</rect> </rect>
@ -408,8 +411,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="tankers_checkBox"> <widget class="QCheckBox" name="tankers_checkBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>970</x> <x>920</x>
<y>450</y> <y>380</y>
<width>251</width> <width>251</width>
<height>31</height> <height>31</height>
</rect> </rect>
@ -429,7 +432,7 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="apcs_spawn_checkBox"> <widget class="QCheckBox" name="apcs_spawn_checkBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>500</x> <x>470</x>
<y>400</y> <y>400</y>
<width>251</width> <width>251</width>
<height>31</height> <height>31</height>
@ -450,7 +453,7 @@ p, li { white-space: pre-wrap; }
<widget class="QSpinBox" name="inf_spawn_spinBox"> <widget class="QSpinBox" name="inf_spawn_spinBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>710</x> <x>680</x>
<y>360</y> <y>360</y>
<width>71</width> <width>71</width>
<height>31</height> <height>31</height>
@ -474,30 +477,6 @@ p, li { white-space: pre-wrap; }
<number>2</number> <number>2</number>
</property> </property>
</widget> </widget>
<widget class="QCheckBox" name="smoke_checkBox">
<property name="geometry">
<rect>
<x>1000</x>
<y>620</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"> <widget class="QLabel" name="scenario_label_5">
<property name="geometry"> <property name="geometry">
<rect> <rect>
@ -538,7 +517,7 @@ p, li { white-space: pre-wrap; }
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>500</x> <x>470</x>
<y>360</y> <y>360</y>
<width>191</width> <width>191</width>
<height>31</height> <height>31</height>
@ -557,7 +536,7 @@ p, li { white-space: pre-wrap; }
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>870</x> <x>870</x>
<y>700</y> <y>640</y>
<width>291</width> <width>291</width>
<height>31</height> <height>31</height>
</rect> </rect>
@ -570,7 +549,7 @@ p, li { white-space: pre-wrap; }
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>750</x> <x>750</x>
<y>700</y> <y>640</y>
<width>111</width> <width>111</width>
<height>31</height> <height>31</height>
</rect> </rect>
@ -587,7 +566,7 @@ p, li { white-space: pre-wrap; }
<widget class="QLabel" name="scenario_label_6"> <widget class="QLabel" name="scenario_label_6">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>500</x> <x>470</x>
<y>320</y> <y>320</y>
<width>141</width> <width>141</width>
<height>31</height> <height>31</height>
@ -605,8 +584,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="force_offroad_checkBox"> <widget class="QCheckBox" name="force_offroad_checkBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>1000</x> <x>810</x>
<y>560</y> <y>760</y>
<width>191</width> <width>191</width>
<height>16</height> <height>16</height>
</rect> </rect>
@ -679,7 +658,7 @@ p, li { white-space: pre-wrap; }
<rect> <rect>
<x>140</x> <x>140</x>
<y>330</y> <y>330</y>
<width>231</width> <width>211</width>
<height>31</height> <height>31</height>
</rect> </rect>
</property> </property>
@ -697,7 +676,7 @@ p, li { white-space: pre-wrap; }
<rect> <rect>
<x>140</x> <x>140</x>
<y>370</y> <y>370</y>
<width>231</width> <width>201</width>
<height>31</height> <height>31</height>
</rect> </rect>
</property> </property>
@ -740,8 +719,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="zone_sams_checkBox"> <widget class="QCheckBox" name="zone_sams_checkBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>970</x> <x>920</x>
<y>480</y> <y>410</y>
<width>201</width> <width>201</width>
<height>31</height> <height>31</height>
</rect> </rect>
@ -758,6 +737,136 @@ p, li { white-space: pre-wrap; }
<string>Inactive Zone SAMs</string> <string>Inactive Zone SAMs</string>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="scenario_label_9">
<property name="geometry">
<rect>
<x>740</x>
<y>490</y>
<width>171</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Zone FARP Conditions:</string>
</property>
</widget>
<widget class="QCheckBox" name="inf_spawn_voiceovers_checkBox">
<property name="geometry">
<rect>
<x>470</x>
<y>430</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>Voiceovers on Infantry Spawn</string>
</property>
</widget>
<widget class="QRadioButton" name="farp_never">
<property name="geometry">
<rect>
<x>950</x>
<y>500</y>
<width>95</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="statusTip">
<string>Never spawn FARPs in defeated conflict zones.</string>
</property>
<property name="text">
<string>Never</string>
</property>
<attribute name="buttonGroup">
<string notr="true">farp_buttonGroup</string>
</attribute>
</widget>
<widget class="QRadioButton" name="farp_gunits">
<property name="geometry">
<rect>
<x>950</x>
<y>530</y>
<width>221</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="statusTip">
<string>Only spawn FARPs in defeated conflict zones if we have sufficient ground units remaining.</string>
</property>
<property name="text">
<string>20% Ground Units Remaining</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">farp_buttonGroup</string>
</attribute>
</widget>
<widget class="QRadioButton" name="farp_always">
<property name="geometry">
<rect>
<x>950</x>
<y>560</y>
<width>221</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="statusTip">
<string>Always spawn a FARP in defeated conflict zones.</string>
</property>
<property name="text">
<string>Always</string>
</property>
<attribute name="buttonGroup">
<string notr="true">farp_buttonGroup</string>
</attribute>
</widget>
<widget class="QLabel" name="version_label">
<property name="geometry">
<rect>
<x>920</x>
<y>840</y>
<width>241</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Version string</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<zorder>background_label</zorder> <zorder>background_label</zorder>
<zorder>scenario_comboBox</zorder> <zorder>scenario_comboBox</zorder>
<zorder>scenario_label</zorder> <zorder>scenario_label</zorder>
@ -779,7 +888,6 @@ p, li { white-space: pre-wrap; }
<zorder>tankers_checkBox</zorder> <zorder>tankers_checkBox</zorder>
<zorder>apcs_spawn_checkBox</zorder> <zorder>apcs_spawn_checkBox</zorder>
<zorder>inf_spawn_spinBox</zorder> <zorder>inf_spawn_spinBox</zorder>
<zorder>smoke_checkBox</zorder>
<zorder>scenario_label_5</zorder> <zorder>scenario_label_5</zorder>
<zorder>forces_hint_label_2</zorder> <zorder>forces_hint_label_2</zorder>
<zorder>label</zorder> <zorder>label</zorder>
@ -793,6 +901,12 @@ p, li { white-space: pre-wrap; }
<zorder>scenario_label_8</zorder> <zorder>scenario_label_8</zorder>
<zorder>e_attack_planes_spinBox</zorder> <zorder>e_attack_planes_spinBox</zorder>
<zorder>zone_sams_checkBox</zorder> <zorder>zone_sams_checkBox</zorder>
<zorder>scenario_label_9</zorder>
<zorder>inf_spawn_voiceovers_checkBox</zorder>
<zorder>farp_never</zorder>
<zorder>farp_gunits</zorder>
<zorder>farp_always</zorder>
<zorder>version_label</zorder>
</widget> </widget>
<widget class="QMenuBar" name="menubar"> <widget class="QMenuBar" name="menubar">
<property name="geometry"> <property name="geometry">
@ -865,4 +979,7 @@ p, li { white-space: pre-wrap; }
</hints> </hints>
</connection> </connection>
</connections> </connections>
<buttongroups>
<buttongroup name="farp_buttonGroup"/>
</buttongroups>
</ui> </ui>

116
Generator/RotorOpsGroups.py Normal file
View File

@ -0,0 +1,116 @@
from dcs.countries import Russia, USA
import dcs.unit as unit
from dcs.mission import Mission
import dcs.mapping as mapping
import dcs.ships
import dcs.vehicles
import dcs.statics
import dcs.unit
import random
class VehicleTemplate:
class USA:
@staticmethod
def invisible_farp(mission, country, position, heading, name, late_activation):
farp = mission.farp(country, name, position, hidden=False, dead=False, farp_type=dcs.unit.InvisibleFARP)
vg = mission.vehicle_group_platoon(
country,
name,
[
dcs.vehicles.Unarmed.M_818,
dcs.vehicles.AirDefence.Vulcan,
dcs.vehicles.Unarmed.Ural_375
],
position.point_from_heading(45, 7),
heading=random.randint(0, 359),
formation=dcs.unitgroup.VehicleGroup.Formation.Star,
)
vg.late_activation = late_activation
return vg
@staticmethod
def logistics_site(mission, country, position, heading, prefix=""):
farp = mission.farp(country, "Logistics FARP", position, hidden=False, dead=False, farp_type=dcs.unit.InvisibleFARP)
sg = mission.static_group(
country,
prefix + " Logistics",
dcs.statics.Fortification.TV_tower,
position.point_from_heading(heading, 80),
heading
)
dist_from_center = 30
for i in range(1,4):
u = mission.static("logistic" + str(i), dcs.statics.Cargo.Iso_container_small)
u.position = position.point_from_heading(heading + 90, dist_from_center + (i * 15))
u.heading = 10
sg.add_unit(u)
for i in range(5,8):
u = mission.static("logistic" + str(i), dcs.statics.Cargo.Iso_container_small)
u.position = position.point_from_heading(heading + 270, dist_from_center + (i * 15))
u.heading = 10
sg.add_unit(u)
a_pos = position.point_from_heading(heading + 180, dist_from_center)
u = mission.static("Ammo Dump", dcs.statics.Fortification.FARP_Ammo_Dump_Coating)
u.position = a_pos.point_from_heading(heading + 90, 1)
u.heading = heading
sg.add_unit(u)
u = mission.static("FARP Tent", dcs.statics.Fortification.FARP_Tent)
u.position = a_pos.point_from_heading(heading + 90, dist_from_center + 20)
u.heading = heading
sg.add_unit(u)
u = mission.static("Fuel Depot", dcs.statics.Fortification.FARP_Fuel_Depot)
u.position = a_pos.point_from_heading(heading + 90, dist_from_center + 40)
u.heading = heading
sg.add_unit(u)
return sg
@staticmethod
def sa6_site(mission, country, position, heading, prefix="", skill=unit.Skill.Average):
vg = mission.vehicle_group(
country,
prefix + "SA6 site",
dcs.vehicles.AirDefence.Kub_1S91_str,
position,
heading
)
u = mission.vehicle("Launcher 1", dcs.vehicles.AirDefence.Kub_2P25_ln)
u.position = position.point_from_heading(heading + 140, 30)
u.heading = heading
vg.add_unit(u)
u = mission.vehicle("Launcher 2", dcs.vehicles.AirDefence.Kub_2P25_ln)
u.position = position.point_from_heading(heading + 210, 30)
u.heading = heading
vg.add_unit(u)
u = mission.vehicle("Rearm Truck", dcs.vehicles.Unarmed.Ural_375)
u.position = position.point_from_heading(heading + 0, 40)
u.heading = heading
vg.add_unit(u)
for u in vg.units:
u.skill = skill
return vg

View File

@ -3,6 +3,8 @@ from tokenize import String
import dcs import dcs
import os import os
import random import random
import RotorOpsGroups
import RotorOpsUnits import RotorOpsUnits
import time import time
@ -119,9 +121,6 @@ class RotorOpsMission:
elif zone.name.rfind("SPAWN") >= 0: elif zone.name.rfind("SPAWN") >= 0:
self.addZone(self.spawn_zones, self.RotorOpsZone(zone.name, None, zone.position, zone.radius)) 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 blue_zones = self.staging_zones
red_zones = self.conflict_zones red_zones = self.conflict_zones
@ -137,16 +136,21 @@ class RotorOpsMission:
self.m.terrain.airports[airport_name].set_blue() self.m.terrain.airports[airport_name].set_blue()
#Add red ground units #Populate Red zones with ground units
for zone_name in red_zones: for zone_name in red_zones:
if red_forces: if red_forces:
self.addGroundGroups(red_zones[zone_name], self.m.country('Russia'), red_forces, options["red_quantity"]) self.addGroundGroups(red_zones[zone_name], self.m.country('Russia'), red_forces, options["red_quantity"])
if options["zone_protect_sams"]: #Add blue FARPS
for zone_name in red_zones: if options["zone_farps"] != "farp_never" and not options["defending"]:
RotorOpsGroups.VehicleTemplate.USA.invisible_farp(self.m, self.m.country('USA'),
red_zones[zone_name].position,
180, zone_name + " FARP", late_activation=True)
if options["zone_protect_sams"]:
self.m.vehicle_group( self.m.vehicle_group(
self.m.country('Russia'), self.m.country('Russia'),
zone_name + " Protection SAM NOAI", "Static " + zone_name + " Protection SAM",
random.choice(RotorOpsUnits.e_zone_sams), random.choice(RotorOpsUnits.e_zone_sams),
red_zones[zone_name].position, red_zones[zone_name].position,
heading=random.randint(0, 359), heading=random.randint(0, 359),
@ -154,17 +158,28 @@ class RotorOpsMission:
formation=dcs.unitgroup.VehicleGroup.Formation.Star formation=dcs.unitgroup.VehicleGroup.Formation.Star
) )
#Add blue ground units
#Populate Blue zones with ground units
for zone_name in blue_zones: for zone_name in blue_zones:
if blue_forces: if blue_forces:
self.addGroundGroups(blue_zones[zone_name], self.m.country('USA'), blue_forces, self.addGroundGroups(blue_zones[zone_name], self.m.country('USA'), blue_forces,
options["blue_quantity"]) options["blue_quantity"])
if options["zone_protect_sams"]: #add logistics sites
for zone_name in blue_zones: if options["crates"] and zone_name in self.staging_zones:
self.m.vehicle_group( RotorOpsGroups.VehicleTemplate.USA.logistics_site(self.m, self.m.country('USA'),
blue_zones[zone_name].position,
180, zone_name)
if options["zone_protect_sams"] and options["defending"]:
vg = self.m.vehicle_group(
self.m.country('USA'), self.m.country('USA'),
zone_name + " Protection SAM NOAI", "Static " + zone_name + " Protection SAM",
random.choice(RotorOpsUnits.e_zone_sams), random.choice(RotorOpsUnits.e_zone_sams),
blue_zones[zone_name].position, blue_zones[zone_name].position,
heading=random.randint(0, 359), heading=random.randint(0, 359),
@ -172,6 +187,8 @@ class RotorOpsMission:
formation=dcs.unitgroup.VehicleGroup.Formation.Star formation=dcs.unitgroup.VehicleGroup.Formation.Star
) )
#Add player slots #Add player slots
if options["slots"] == "Multiple Slots": if options["slots"] == "Multiple Slots":
self.addMultiplayerHelos() self.addMultiplayerHelos()
@ -187,6 +204,10 @@ class RotorOpsMission:
self.m.map.position = self.m.terrain.airports[self.getCoalitionAirports("blue")[0]].position self.m.map.position = self.m.terrain.airports[self.getCoalitionAirports("blue")[0]].position
self.m.map.zoom = 100000 self.m.map.zoom = 100000
#add files and triggers necessary for RotorOps.lua script
self.addResources(self.sound_directory, self.script_directory)
self.scriptTriggerSetup(options)
#Save the mission file #Save the mission file
print(self.m.triggers.zones()) print(self.m.triggers.zones())
os.chdir(self.output_dir) os.chdir(self.output_dir)
@ -414,7 +435,7 @@ class RotorOpsMission:
helo, helo,
airport=enemy_airport, airport=enemy_airport,
maintask=dcs.task.CAS, maintask=dcs.task.CAS,
start_type=dcs.mission.StartType.Warm, start_type=dcs.mission.StartType.Cold,
group_size=2) group_size=2)
zone_attack(afg, helo) zone_attack(afg, helo)
@ -473,23 +494,50 @@ class RotorOpsMission:
trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.startConflict(100)"))) trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.startConflict(100)")))
self.m.triggerrules.triggers.append(trig) self.m.triggerrules.triggers.append(trig)
#Add all zone-based triggers #Add generic zone-based triggers
for index, zone_name in enumerate(self.conflict_zones): for index, zone_name in enumerate(self.conflict_zones):
z_active_trig = dcs.triggers.TriggerOnce(comment= zone_name + " Active") z_active_trig = dcs.triggers.TriggerOnce(comment= zone_name + " Active")
z_active_trig.rules.append(dcs.condition.FlagEquals(game_flag, index + 1)) 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!"))) z_active_trig.actions.append(dcs.action.DoScript(dcs.action.String("--Add any action you want here!")))
#Smoke action not working
# if options["smoke_zone"]:
# z_active_trig.actions.append(dcs.action.Smoke(zone=zone_name, density=1, preset=1))
# if index > 0:
# previous_zone = list(self.conflict_zones)[index - 1]
# z_active_trig.actions.append(dcs.action.Smoke(zone=previous_zone, density=1, preset=0))
#Zone protection SAMs
if options["zone_protect_sams"]:
z_active_trig.actions.append(dcs.action.DoScript(dcs.action.String("Group.destroy(Group.getByName('" + zone_name + " Protection SAM'))")))
self.m.triggerrules.triggers.append(z_active_trig) self.m.triggerrules.triggers.append(z_active_trig)
#Zone protection SAMs
if options["zone_protect_sams"]:
for index, zone_name in enumerate(self.conflict_zones):
z_sams_trig = dcs.triggers.TriggerOnce(comment="Deactivate " + zone_name + " SAMs")
z_sams_trig.actions.append(dcs.action.DoScript(dcs.action.String("Group.destroy(Group.getByName('" + zone_name + " Protection SAM'))")))
self.m.triggerrules.triggers.append(z_sams_trig)
#Zone FARPS always
if options["zone_farps"] == "farp_always" and not options["defending"] and index > 0:
for index, zone_name in enumerate(self.conflict_zones):
if index > 0:
previous_zone = list(self.conflict_zones)[index - 1]
if not self.m.country("USA").find_group(previous_zone + " FARP"):
continue
z_farps_trig = dcs.triggers.TriggerOnce(comment="Activate " + previous_zone + " FARP")
z_farps_trig.rules.append(dcs.condition.FlagEquals(game_flag, index + 1))
z_farps_trig.actions.append(dcs.action.ActivateGroup(self.m.country("USA").find_group(previous_zone + " FARP").id))
self.m.triggerrules.triggers.append(z_farps_trig)
#Zone FARPS conditional on staged units remaining
if options["zone_farps"] == "farp_gunits":
for index, zone_name in enumerate(self.conflict_zones):
if index > 0:
previous_zone = list(self.conflict_zones)[index - 1]
if not self.m.country("USA").find_group(previous_zone + " FARP"):
continue
z_farps_trig = dcs.triggers.TriggerOnce(comment= "Activate " + previous_zone + " FARP")
z_farps_trig.rules.append(dcs.condition.FlagEquals(game_flag, index + 1))
z_farps_trig.rules.append(dcs.condition.FlagIsMore(111, 20))
z_farps_trig.actions.append(dcs.action.DoScript(dcs.action.String("--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(self.m.country("USA").find_group(previous_zone + " FARP").id))
self.m.triggerrules.triggers.append(z_farps_trig)
#Add attack helos triggers #Add attack helos triggers
for index in range(options["e_attack_helos"]): for index in range(options["e_attack_helos"]):
random_zone_obj = random.choice(list(self.conflict_zones.items())) random_zone_obj = random.choice(list(self.conflict_zones.items()))

View File

@ -21,6 +21,7 @@ Optional:
Tips: Tips:
-Position the center of conflict zones over an open area, as this position may be used to spawn units. -Position the center of conflict zones over an open area, as this position may be used to spawn units.
-Position the center of staging zones over an open area of at least 1000 x 1000ft to provide space for logistics units.
-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. -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. -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. -Keep the zones fairly close together, both for helicopter and ground unit travel times.

View File

@ -1,6 +1,6 @@
RotorOps = {} RotorOps = {}
RotorOps.version = "1.2.4" RotorOps.version = "1.2.5"
local debug = false local debug = true
---[[ROTOROPS OPTIONS]]--- ---[[ROTOROPS OPTIONS]]---
@ -20,13 +20,14 @@ RotorOps.inf_spawns_avail = 0 --this is the number of infantry group spawn event
RotorOps.inf_spawn_chance = 25 -- 0-100 the chance of spawning infantry in an active zone spawn zone, per 'assessUnitsInZone' loop (10 seconds) RotorOps.inf_spawn_chance = 25 -- 0-100 the chance of spawning infantry in an active zone spawn zone, per 'assessUnitsInZone' loop (10 seconds)
RotorOps.inf_spawn_trigger_percent = 70 --infantry has a chance of spawning if the percentage of defenders remaining in zone is less than this value RotorOps.inf_spawn_trigger_percent = 70 --infantry has a chance of spawning if the percentage of defenders remaining in zone is less than this value
RotorOps.inf_spawns_per_zone = 3 --number of infantry groups to spawn per zone RotorOps.inf_spawns_per_zone = 3 --number of infantry groups to spawn per zone
RotorOps.inf_spawn_messages = true --voiceovers and messages for infantry spawns
--RotorOps settings that are safe to change only before calling setupConflict() --RotorOps settings that are safe to change only before calling setupConflict()
RotorOps.transports = {'UH-1H', 'Mi-8MT', 'Mi-24P', 'SA342M', 'SA342L', 'SA342Mistral', 'UH-60L'} --players flying these will have ctld transport access RotorOps.transports = {'UH-1H', 'Mi-8MT', 'Mi-24P', 'SA342M', 'SA342L', 'SA342Mistral', 'UH-60L'} --players flying these will have ctld transport access
RotorOps.CTLD_crates = false RotorOps.CTLD_crates = false
RotorOps.CTLD_sound_effects = true --sound effects for troop pickup/dropoffs RotorOps.CTLD_sound_effects = true --sound effects for troop pickup/dropoffs
RotorOps.exclude_ai_group_name = "noai" --include this somewhere in a group name to exclude the group from being tasked in the active zone RotorOps.exclude_ai_group_name = "Static" --include this somewhere in a group name to exclude the group from being tasked in the active zone
---[[END OF OPTIONS]]--- ---[[END OF OPTIONS]]---
@ -49,6 +50,7 @@ RotorOps.ai_defending_vehicle_groups = {}
RotorOps.ai_attacking_vehicle_groups = {} RotorOps.ai_attacking_vehicle_groups = {}
RotorOps.ai_tasks = {} RotorOps.ai_tasks = {}
RotorOps.defending = false RotorOps.defending = false
RotorOps.staged_units_flag = 111
trigger.action.outText("ROTOR OPS STARTED: "..RotorOps.version, 5) trigger.action.outText("ROTOR OPS STARTED: "..RotorOps.version, 5)
env.info("ROTOR OPS STARTED: "..RotorOps.version) env.info("ROTOR OPS STARTED: "..RotorOps.version)
@ -58,6 +60,7 @@ RotorOps.eventHandler = {}
local commandDB = {} local commandDB = {}
local game_message_buffer = {} local game_message_buffer = {}
local active_zone_initial_defenders local active_zone_initial_defenders
local initial_stage_units
local apcs = {} --table to keep track of infantry vehicles local apcs = {} --table to keep track of infantry vehicles
local low_units_message_fired = false local low_units_message_fired = false
local inf_spawn_zones = {} local inf_spawn_zones = {}
@ -144,6 +147,20 @@ RotorOps.gameMsgs = {
attack_planes = { attack_planes = {
{'ENEMY ATTACK PLANES INBOUND!', 'enemy_attack_planes.ogg'}, {'ENEMY ATTACK PLANES INBOUND!', 'enemy_attack_planes.ogg'},
}, },
attack_helos_prep = {
{'ENEMY ATTACK HELICOPTERS PREPARING FOR TAKEOFF!', 'e_attack_helicopters_preparing.ogg'},
},
attack_planes_prep = {
{'ENEMY ATTACK PLANES PREPARING FOR TAKEOFF!', 'e_attack_planes_preparing.ogg'},
},
infantry_spawned = {
{'ENEMY CONTACTS IN THE OPEN!', 'e_infantry_spawn1.ogg'},
{'ENEMY TROOPS LEAVING COVER!', 'e_infantry_spawn2.ogg'},
{'VISUAL ON ENEMY INFANTRY!', 'e_infantry_spawn3.ogg'},
{'ENEMY CONTACTS IN THE ACTIVE!', 'e_infantry_spawn4.ogg'},
{'ENEMY TROOPS IN THE ACTIVE!', 'e_infantry_spawn5.ogg'},
{'VISUAL ON ENEMY TROOPS!', 'e_infantry_spawn6.ogg'},
},
} }
@ -155,6 +172,7 @@ local sound_effects = {
} }
function RotorOps.eventHandler:onEvent(event) function RotorOps.eventHandler:onEvent(event)
if (world.event.S_EVENT_ENGINE_STARTUP == event.id) then --play some sound files when a player starts engines if (world.event.S_EVENT_ENGINE_STARTUP == event.id) then --play some sound files when a player starts engines
local initaitor = event.initiator:getGroup():getID() local initaitor = event.initiator:getGroup():getID()
if RotorOps.defending then if RotorOps.defending then
@ -163,6 +181,16 @@ function RotorOps.eventHandler:onEvent(event)
trigger.action.outSoundForGroup(initaitor , RotorOps.gameMsgs.push[RotorOps.active_zone_index + 1][2]) trigger.action.outSoundForGroup(initaitor , RotorOps.gameMsgs.push[RotorOps.active_zone_index + 1][2])
end end
end end
if (world.event.S_EVENT_TAKEOFF == event.id) then
local initiator_name = event.initiator:getGroup()
if initiator_name == "Enemy Attack Helicopters" then
RotorOps.gameMsg(RotorOps.gameMsgs.attack_helos)
elseif initiator_name == "Enemy Attack Planes" then
RotorOps.gameMsg(RotorOps.gameMsgs.attack_planes)
end
end
end end
@ -872,6 +900,19 @@ function RotorOps.assessUnitsInZone(var)
end end
end end
--update staged units remaining flag
local staged_units_remaining = {}
for index, unit in pairs(RotorOps.staged_units) do
if unit:isExist() then
staged_units_remaining[#staged_units_remaining] = unit
end
end
local percent_staged_remain = 0
percent_staged_remain = math.floor((#staged_units_remaining / #RotorOps.staged_units) * 100)
trigger.action.setUserFlag(RotorOps.staged_units_flag, percent_staged_remain)
debug("Staged units remaining: " + percent_staged_remain + "%")
--is the game finished? --is the game finished?
if all_zones_clear then if all_zones_clear then
if RotorOps.defending == true then if RotorOps.defending == true then
@ -957,7 +998,7 @@ function RotorOps.assessUnitsInZone(var)
else else
ctld.spawnGroupAtTrigger("red", 5, zone, 1000) ctld.spawnGroupAtTrigger("red", 5, zone, 1000)
end end
RotorOps.gameMsg(RotorOps.gameMsgs.infantry_spawned, math.random(1, #RotorOps.gameMsgs.infantry_spawned))
RotorOps.inf_spawns_avail = RotorOps.inf_spawns_avail - 1 RotorOps.inf_spawns_avail = RotorOps.inf_spawns_avail - 1
env.info("ROTOR OPS: Spawned infantry. "..RotorOps.inf_spawns_avail.." spawns remaining in "..zone) env.info("ROTOR OPS: Spawned infantry. "..RotorOps.inf_spawns_avail.." spawns remaining in "..zone)
end end
@ -1126,6 +1167,11 @@ function RotorOps.setupCTLD()
ctld.numberOfTroops = 24 --max loading size ctld.numberOfTroops = 24 --max loading size
ctld.maximumSearchDistance = 4000 -- max distance for troops to search for enemy ctld.maximumSearchDistance = 4000 -- max distance for troops to search for enemy
ctld.maximumMoveDistance = 0 -- max distance for troops to move from drop point if no enemy is nearby ctld.maximumMoveDistance = 0 -- max distance for troops to move from drop point if no enemy is nearby
ctld.maximumDistanceLogistic = 300
ctld.minimumHoverHeight = 5.0 -- Lowest allowable height for crate hover
ctld.maximumHoverHeight = 15.0 -- Highest allowable height for crate hover
ctld.maxDistanceFromCrate = 7 -- Maximum distance from from crate for hover
ctld.hoverTime = 5 -- Time to hold hover above a crate for loading in seconds
ctld.unitLoadLimits = { ctld.unitLoadLimits = {
-- Remove the -- below to turn on options -- Remove the -- below to turn on options
@ -1269,12 +1315,12 @@ end
function RotorOps.spawnAttackHelos() function RotorOps.spawnAttackHelos()
RotorOps.triggerSpawn("Enemy Attack Helicopters", RotorOps.gameMsgs.attack_helos) RotorOps.triggerSpawn("Enemy Attack Helicopters", RotorOps.gameMsgs.attack_helos_prep)
end end
function RotorOps.spawnAttackPlanes() function RotorOps.spawnAttackPlanes()
RotorOps.triggerSpawn("Enemy Attack Planes", RotorOps.gameMsgs.attack_planes) RotorOps.triggerSpawn("Enemy Attack Planes", RotorOps.gameMsgs.attack_planes_prep)
end end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.