Merge pull request #17 from spencershepard/feature/zone-protect-sams

This commit is contained in:
spencershepard 2022-02-04 22:13:35 -08:00 committed by GitHub
commit bcaff119ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 489 additions and 276 deletions

Binary file not shown.

View File

@ -150,10 +150,8 @@ class Window(QMainWindow, Ui_MainWindow):
"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(),
"e_attack_helos": self.e_attack_helos_spinBox.value(),
"e_attack_planes": self.e_attack_planes_spinBox.value(),
"crates": self.logistics_crates_checkBox.isChecked(),
"f_awacs": self.awacs_checkBox.isChecked(),
"f_tankers": self.tankers_checkBox.isChecked(),
@ -163,6 +161,8 @@ class Window(QMainWindow, Ui_MainWindow):
"game_display": self.game_status_checkBox.isChecked(),
"defending": self.defense_checkBox.isChecked(),
"slots": self.slot_template_comboBox.currentText(),
"smoke_zone": self.smoke_checkBox.isChecked(),
"zone_protect_sams": self.zone_sams_checkBox.isChecked(),
}
os.chdir(self.m.home_dir + '/Generator')
n = ROps.RotorOpsMission()
@ -177,22 +177,28 @@ class Window(QMainWindow, Ui_MainWindow):
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_()
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_()
elif not result["success"]:
print(result["failure_msg"])
msg = QMessageBox()
msg.setWindowTitle("Error")
msg.setText(result["failure_msg"])
x = msg.exec_()

View File

@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1140, 826)
MainWindow.resize(1209, 900)
font = QtGui.QFont()
font.setPointSize(10)
MainWindow.setFont(font)
@ -39,7 +39,7 @@ class Ui_MainWindow(object):
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.setGeometry(QtCore.QRect(1020, 790, 141, 41))
self.generateButton.setStyleSheet("background-color: white;\n"
"border-style: outset;\n"
"border-width: 2px;\n"
@ -73,7 +73,7 @@ class Ui_MainWindow(object):
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.setGeometry(QtCore.QRect(-30, 490, 801, 371))
self.background_label.setAutoFillBackground(False)
self.background_label.setStyleSheet("")
self.background_label.setText("")
@ -113,7 +113,7 @@ class Ui_MainWindow(object):
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))
self.game_status_checkBox.setGeometry(QtCore.QRect(1000, 590, 191, 16))
font = QtGui.QFont()
font.setPointSize(9)
self.game_status_checkBox.setFont(font)
@ -121,67 +121,41 @@ class Ui_MainWindow(object):
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))
self.voiceovers_checkBox.setGeometry(QtCore.QRect(1000, 650, 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))
self.logistics_crates_checkBox.setGeometry(QtCore.QRect(970, 390, 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))
self.awacs_checkBox.setGeometry(QtCore.QRect(970, 420, 251, 31))
font = QtGui.QFont()
font.setPointSize(11)
self.awacs_checkBox.setFont(font)
self.awacs_checkBox.setStatusTip("")
self.awacs_checkBox.setChecked(True)
self.awacs_checkBox.setObjectName("awacs_checkBox")
self.tankers_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.tankers_checkBox.setGeometry(QtCore.QRect(910, 380, 251, 31))
self.tankers_checkBox.setGeometry(QtCore.QRect(970, 450, 251, 31))
font = QtGui.QFont()
font.setPointSize(11)
self.tankers_checkBox.setFont(font)
self.tankers_checkBox.setChecked(True)
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))
self.apcs_spawn_checkBox.setGeometry(QtCore.QRect(500, 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))
self.inf_spawn_spinBox.setGeometry(QtCore.QRect(710, 360, 71, 31))
font = QtGui.QFont()
font.setPointSize(12)
self.inf_spawn_spinBox.setFont(font)
@ -190,7 +164,7 @@ class Ui_MainWindow(object):
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))
self.smoke_checkBox.setGeometry(QtCore.QRect(1000, 620, 191, 16))
font = QtGui.QFont()
font.setPointSize(9)
self.smoke_checkBox.setFont(font)
@ -208,28 +182,28 @@ class Ui_MainWindow(object):
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))
self.label.setGeometry(QtCore.QRect(500, 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.setGeometry(QtCore.QRect(870, 700, 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))
self.label_2.setGeometry(QtCore.QRect(750, 700, 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))
self.scenario_label_6.setGeometry(QtCore.QRect(500, 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))
self.force_offroad_checkBox.setGeometry(QtCore.QRect(1000, 560, 191, 16))
font = QtGui.QFont()
font.setPointSize(9)
self.force_offroad_checkBox.setFont(font)
@ -242,6 +216,42 @@ class Ui_MainWindow(object):
font.setPointSize(11)
self.defense_checkBox.setFont(font)
self.defense_checkBox.setObjectName("defense_checkBox")
self.e_attack_helos_spinBox = QtWidgets.QSpinBox(self.centralwidget)
self.e_attack_helos_spinBox.setGeometry(QtCore.QRect(70, 330, 51, 31))
font = QtGui.QFont()
font.setPointSize(12)
self.e_attack_helos_spinBox.setFont(font)
self.e_attack_helos_spinBox.setMinimum(0)
self.e_attack_helos_spinBox.setMaximum(50)
self.e_attack_helos_spinBox.setProperty("value", 2)
self.e_attack_helos_spinBox.setObjectName("e_attack_helos_spinBox")
self.scenario_label_7 = QtWidgets.QLabel(self.centralwidget)
self.scenario_label_7.setGeometry(QtCore.QRect(140, 330, 231, 31))
font = QtGui.QFont()
font.setPointSize(11)
self.scenario_label_7.setFont(font)
self.scenario_label_7.setObjectName("scenario_label_7")
self.scenario_label_8 = QtWidgets.QLabel(self.centralwidget)
self.scenario_label_8.setGeometry(QtCore.QRect(140, 370, 231, 31))
font = QtGui.QFont()
font.setPointSize(11)
self.scenario_label_8.setFont(font)
self.scenario_label_8.setObjectName("scenario_label_8")
self.e_attack_planes_spinBox = QtWidgets.QSpinBox(self.centralwidget)
self.e_attack_planes_spinBox.setGeometry(QtCore.QRect(70, 370, 51, 31))
font = QtGui.QFont()
font.setPointSize(12)
self.e_attack_planes_spinBox.setFont(font)
self.e_attack_planes_spinBox.setMinimum(0)
self.e_attack_planes_spinBox.setMaximum(50)
self.e_attack_planes_spinBox.setProperty("value", 1)
self.e_attack_planes_spinBox.setObjectName("e_attack_planes_spinBox")
self.zone_sams_checkBox = QtWidgets.QCheckBox(self.centralwidget)
self.zone_sams_checkBox.setGeometry(QtCore.QRect(970, 480, 201, 31))
font = QtGui.QFont()
font.setPointSize(11)
self.zone_sams_checkBox.setFont(font)
self.zone_sams_checkBox.setObjectName("zone_sams_checkBox")
self.background_label.raise_()
self.scenario_comboBox.raise_()
self.scenario_label.raise_()
@ -262,10 +272,6 @@ class Ui_MainWindow(object):
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_()
@ -276,9 +282,14 @@ class Ui_MainWindow(object):
self.scenario_label_6.raise_()
self.force_offroad_checkBox.raise_()
self.defense_checkBox.raise_()
self.e_attack_helos_spinBox.raise_()
self.scenario_label_7.raise_()
self.scenario_label_8.raise_()
self.e_attack_planes_spinBox.raise_()
self.zone_sams_checkBox.raise_()
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1140, 26))
self.menubar.setGeometry(QtCore.QRect(0, 0, 1209, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
@ -329,14 +340,6 @@ class Ui_MainWindow(object):
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"))
@ -349,6 +352,12 @@ class Ui_MainWindow(object):
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.e_attack_helos_spinBox.setStatusTip(_translate("MainWindow", "Approximate number of enemy attack helicopter group spawns."))
self.scenario_label_7.setText(_translate("MainWindow", "Enemy Attack Helicopters"))
self.scenario_label_8.setText(_translate("MainWindow", "Enemy Attack Planes"))
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.setText(_translate("MainWindow", "Inactive Zone SAMs"))
self.action_generateMission.setText(_translate("MainWindow", "_generateMission"))
self.action_scenarioSelected.setText(_translate("MainWindow", "_scenarioSelected"))
self.action_blueforcesSelected.setText(_translate("MainWindow", "_blueforcesSelected"))

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1140</width>
<height>826</height>
<width>1209</width>
<height>900</height>
</rect>
</property>
<property name="font">
@ -75,8 +75,8 @@
<widget class="QPushButton" name="generateButton">
<property name="geometry">
<rect>
<x>940</x>
<y>720</y>
<x>1020</x>
<y>790</y>
<width>141</width>
<height>41</height>
</rect>
@ -183,8 +183,8 @@ p, li { white-space: pre-wrap; }
<widget class="QLabel" name="background_label">
<property name="geometry">
<rect>
<x>10</x>
<y>430</y>
<x>-30</x>
<y>490</y>
<width>801</width>
<height>371</height>
</rect>
@ -312,8 +312,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="game_status_checkBox">
<property name="geometry">
<rect>
<x>910</x>
<y>510</y>
<x>1000</x>
<y>590</y>
<width>191</width>
<height>16</height>
</rect>
@ -339,8 +339,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="voiceovers_checkBox">
<property name="geometry">
<rect>
<x>910</x>
<y>570</y>
<x>1000</x>
<y>650</y>
<width>191</width>
<height>16</height>
</rect>
@ -363,8 +363,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="logistics_crates_checkBox">
<property name="geometry">
<rect>
<x>910</x>
<y>320</y>
<x>970</x>
<y>390</y>
<width>251</width>
<height>31</height>
</rect>
@ -384,8 +384,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="awacs_checkBox">
<property name="geometry">
<rect>
<x>910</x>
<y>350</y>
<x>970</x>
<y>420</y>
<width>251</width>
<height>31</height>
</rect>
@ -401,12 +401,15 @@ p, li { white-space: pre-wrap; }
<property name="text">
<string>Friendly AWACS</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QCheckBox" name="tankers_checkBox">
<property name="geometry">
<rect>
<x>910</x>
<y>380</y>
<x>970</x>
<y>450</y>
<width>251</width>
<height>31</height>
</rect>
@ -419,11 +422,14 @@ p, li { white-space: pre-wrap; }
<property name="text">
<string>Friendly Tankers</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QCheckBox" name="apcs_spawn_checkBox">
<property name="geometry">
<rect>
<x>470</x>
<x>500</x>
<y>400</y>
<width>251</width>
<height>31</height>
@ -441,106 +447,10 @@ p, li { white-space: pre-wrap; }
<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>
<x>710</x>
<y>360</y>
<width>71</width>
<height>31</height>
@ -567,8 +477,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="smoke_checkBox">
<property name="geometry">
<rect>
<x>910</x>
<y>540</y>
<x>1000</x>
<y>620</y>
<width>191</width>
<height>16</height>
</rect>
@ -628,7 +538,7 @@ p, li { white-space: pre-wrap; }
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>470</x>
<x>500</x>
<y>360</y>
<width>191</width>
<height>31</height>
@ -646,8 +556,8 @@ p, li { white-space: pre-wrap; }
<widget class="QComboBox" name="slot_template_comboBox">
<property name="geometry">
<rect>
<x>790</x>
<y>630</y>
<x>870</x>
<y>700</y>
<width>291</width>
<height>31</height>
</rect>
@ -659,8 +569,8 @@ p, li { white-space: pre-wrap; }
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>650</x>
<y>630</y>
<x>750</x>
<y>700</y>
<width>111</width>
<height>31</height>
</rect>
@ -677,7 +587,7 @@ p, li { white-space: pre-wrap; }
<widget class="QLabel" name="scenario_label_6">
<property name="geometry">
<rect>
<x>470</x>
<x>500</x>
<y>320</y>
<width>141</width>
<height>31</height>
@ -695,8 +605,8 @@ p, li { white-space: pre-wrap; }
<widget class="QCheckBox" name="force_offroad_checkBox">
<property name="geometry">
<rect>
<x>910</x>
<y>480</y>
<x>1000</x>
<y>560</y>
<width>191</width>
<height>16</height>
</rect>
@ -737,6 +647,117 @@ p, li { white-space: pre-wrap; }
<string>Defensive Mode</string>
</property>
</widget>
<widget class="QSpinBox" name="e_attack_helos_spinBox">
<property name="geometry">
<rect>
<x>70</x>
<y>330</y>
<width>51</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="statusTip">
<string>Approximate number of enemy attack helicopter group spawns.</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_7">
<property name="geometry">
<rect>
<x>140</x>
<y>330</y>
<width>231</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Enemy Attack Helicopters</string>
</property>
</widget>
<widget class="QLabel" name="scenario_label_8">
<property name="geometry">
<rect>
<x>140</x>
<y>370</y>
<width>231</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Enemy Attack Planes</string>
</property>
</widget>
<widget class="QSpinBox" name="e_attack_planes_spinBox">
<property name="geometry">
<rect>
<x>70</x>
<y>370</y>
<width>51</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="statusTip">
<string>Approximate number of enemy attack plane group spawns.</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
<widget class="QCheckBox" name="zone_sams_checkBox">
<property name="geometry">
<rect>
<x>970</x>
<y>480</y>
<width>201</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="statusTip">
<string>Inactive conflict zones will be protected by SAMs. When a zone is cleared, SAMs at next active zone will be destroyed.</string>
</property>
<property name="text">
<string>Inactive Zone SAMs</string>
</property>
</widget>
<zorder>background_label</zorder>
<zorder>scenario_comboBox</zorder>
<zorder>scenario_label</zorder>
@ -757,10 +778,6 @@ p, li { white-space: pre-wrap; }
<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>
@ -771,13 +788,18 @@ p, li { white-space: pre-wrap; }
<zorder>scenario_label_6</zorder>
<zorder>force_offroad_checkBox</zorder>
<zorder>defense_checkBox</zorder>
<zorder>e_attack_helos_spinBox</zorder>
<zorder>scenario_label_7</zorder>
<zorder>scenario_label_8</zorder>
<zorder>e_attack_planes_spinBox</zorder>
<zorder>zone_sams_checkBox</zorder>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1140</width>
<width>1209</width>
<height>26</height>
</rect>
</property>

View File

@ -10,16 +10,11 @@ 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"
@ -29,6 +24,11 @@ class RotorOpsMission:
self.output_dir = self.home_dir + "\Generator\Output"
self.assets_dir = self.home_dir + "\Generator/assets"
self.conflict_zones = {}
self.staging_zones = {}
self.spawn_zones = {}
self.scripts = {}
class RotorOpsZone:
def __init__(self, name: str, flag: int, position: dcs.point, size: int):
@ -94,9 +94,9 @@ class RotorOpsMission:
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)
if not self.m.country("Russia") or not self.m.country("USA"):
failure_msg = "You must include a USA and Russia unit in the scenario template. See the instructions in " + self.scenarios_dir
return {"success": False, "failure_msg": failure_msg}
red_forces = self.getUnitsFromMiz(options["red_forces_filename"], "red")
@ -142,12 +142,36 @@ class RotorOpsMission:
if red_forces:
self.addGroundGroups(red_zones[zone_name], self.m.country('Russia'), red_forces, options["red_quantity"])
if options["zone_protect_sams"]:
for zone_name in red_zones:
self.m.vehicle_group(
self.m.country('Russia'),
zone_name + " Protection SAM NOAI",
random.choice(RotorOpsUnits.e_zone_sams),
red_zones[zone_name].position,
heading=random.randint(0, 359),
group_size=6,
formation=dcs.unitgroup.VehicleGroup.Formation.Star
)
#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"])
if options["zone_protect_sams"]:
for zone_name in blue_zones:
self.m.vehicle_group(
self.m.country('USA'),
zone_name + " Protection SAM NOAI",
random.choice(RotorOpsUnits.e_zone_sams),
blue_zones[zone_name].position,
heading=random.randint(0, 359),
group_size=6,
formation=dcs.unitgroup.VehicleGroup.Formation.Star
)
#Add player slots
if options["slots"] == "Multiple Slots":
self.addMultiplayerHelos()
@ -156,6 +180,7 @@ class RotorOpsMission:
if helicopter == options["slots"]:
self.addSinglePlayerHelos(dcs.helicopters.helicopter_map[helicopter])
#Add AI Flights
self.addFlights(options)
#Set the Editor Map View
@ -178,17 +203,19 @@ class RotorOpsMission:
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)
#pos1 = zone.position.point_from_heading(5, 200)
#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),
zone.position.random_point_within(zone.size / 1.2, 100),
#pos1.random_point_within(zone.size / 2.5, 100),
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:
@ -197,22 +224,72 @@ class RotorOpsMission:
coalition_airports.append(airport_name)
return coalition_airports
def getParking(self, airport, aircraft):
slot = airport.free_parking_slot(aircraft)
slots = airport.free_parking_slots(aircraft)
if slot:
return airport
else:
print("No parking available for " + aircraft.id + " at " + airport.name)
return None
#Find parking spots on FARPs and carriers
def getUnitParking(self, aircraft):
return
def addSinglePlayerHelos(self, helotype):
carrier = self.m.country("USA").find_ship_group(name="HELO_CARRIER")
farp = self.m.country("USA").find_static_group("HELO_FARP")
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()
if carrier:
fg = self.m.flight_group_from_unit(self.m.country('USA'), "CARRIER " + helotype.id, helotype, carrier, dcs.task.CAS, group_size=2)
elif farp:
fg = self.m.flight_group_from_unit(self.m.country('USA'), "FARP " + helotype.id, helotype, farp, dcs.task.CAS, group_size=2)
fg.units[0].position = fg.units[0].position.point_from_heading(90, 30)
# invisible farps need manual unit placement for multiple units
if farp.units[0].type == 'Invisible FARP':
fg.points[0].action = dcs.point.PointAction.FromGroundArea
fg.points[0].type = "TakeOffGround"
fg.units[0].position = fg.units[0].position.point_from_heading(0, 30)
else:
for airport_name in friendly_airports:
fg = self.m.flight_group_from_airport(self.m.country('USA'), airport_name + " " + helotype.id, helotype,
self.getParking(self.m.terrain.airports[airport_name], helotype), group_size=2)
fg.units[0].set_player()
def addMultiplayerHelos(self):
carrier = self.m.country("USA").find_ship_group(name="HELO_CARRIER")
farp = self.m.country("USA").find_static_group("HELO_FARP")
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()
heading = 0
for helotype in RotorOpsUnits.client_helos:
if carrier:
fg = self.m.flight_group_from_unit(self.m.country('USA'), "CARRIER " + helotype.id, helotype, carrier,
dcs.task.CAS, group_size=1)
elif farp:
fg = self.m.flight_group_from_unit(self.m.country('USA'), "FARP " + helotype.id, helotype, farp,
dcs.task.CAS, group_size=1)
#invisible farps need manual unit placement for multiple units
if farp.units[0].type == 'Invisible FARP':
fg.points[0].action = dcs.point.PointAction.FromGroundArea
fg.points[0].type = "TakeOffGround"
fg.units[0].position = fg.units[0].position.point_from_heading(heading, 30)
heading += 90
else:
for airport_name in friendly_airports:
fg = self.m.flight_group_from_airport(self.m.country('USA'), airport_name + " " + helotype.id, helotype,
self.getParking(self.m.terrain.airports[airport_name], helotype), group_size=1)
fg.units[0].set_client()
class TrainingScenario():
@ -239,6 +316,8 @@ class RotorOpsMission:
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
@ -247,13 +326,20 @@ class RotorOpsMission:
usa,
awacs_name,
plane_type=dcs.planes.E_3A,
airport=None,
airport=self.getParking(friendly_airport, dcs.planes.E_3A),
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 = self.m.escort_flight(
usa, "AWACS Escort",
dcs.countries.USA.Plane.F_15C,
airport=self.getParking(friendly_airport, dcs.countries.USA.Plane.F_15C),
group_to_escort=awacs,
group_size=2)
awacs_escort.load_loadout("Combat Air Patrol") #not working for f-15
#add text to mission briefing with radio freq
briefing = self.m.description_text() + "\n\n" + awacs_name + " " + str(awacs_freq) + ".00 " + "\n"
self.m.set_description_text(briefing)
@ -269,21 +355,30 @@ class RotorOpsMission:
usa,
t1_name,
dcs.planes.KC130,
airport=None,
airport=self.getParking(friendly_airport, dcs.planes.KC130),
position=pos,
race_distance=race_dist, heading=heading,
altitude=random.randrange(4000, 5500, 100), speed=750, frequency=t1_freq, tacanchannel=t1_tac)
race_distance=race_dist,
heading=heading,
altitude=random.randrange(4000, 5500, 100),
start_type=dcs.mission.StartType.Warm,
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,
airport=self.getParking(friendly_airport, dcs.planes.KC_135),
position=pos,
race_distance=race_dist, heading=heading,
altitude=random.randrange(4000, 5500, 100), frequency=t2_freq, tacanchannel=t2_tac)
altitude=random.randrange(4000, 5500, 100),
start_type=dcs.mission.StartType.Warm,
frequency=t2_freq,
tacanchannel=t2_tac)
#add text to mission briefing
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)
@ -309,6 +404,8 @@ class RotorOpsMission:
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(
@ -340,13 +437,13 @@ class RotorOpsMission:
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((
trig = dcs.triggers.TriggerOnce(comment="RotorOps Setup Scripts")
trig.rules.append(dcs.condition.TimeAfter(1))
trig.actions.append(dcs.action.DoScriptFile(self.scripts["mist_4_4_90.lua"]))
trig.actions.append(dcs.action.DoScriptFile(self.scripts["Splash_Damage_2_0.lua"]))
trig.actions.append(dcs.action.DoScriptFile(self.scripts["CTLD.lua"]))
trig.actions.append(dcs.action.DoScriptFile(self.scripts["RotorOps.lua"]))
trig.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" +
@ -355,53 +452,75 @@ class RotorOpsMission:
"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)
self.m.triggerrules.triggers.append(trig)
#Add the second trigger
mytrig = dcs.triggers.TriggerOnce(comment="RotorOps Setup Zones")
mytrig.rules.append(dcs.condition.TimeAfter(2))
trig = dcs.triggers.TriggerOnce(comment="RotorOps Setup Zones")
trig.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 + "')")))
trig.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) + ")")))
trig.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) + "')")))
trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.setupConflict('" + str(game_flag) + "')")))
self.m.triggerrules.triggers.append(mytrig)
self.m.triggerrules.triggers.append(trig)
#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)
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict Start")
trig.rules.append(dcs.condition.TimeAfter(10))
trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.startConflict(100)")))
self.m.triggerrules.triggers.append(trig)
#Add all zone-based triggers
for index, c_zone in enumerate(self.conflict_zones):
for index, zone_name in enumerate(self.conflict_zones):
z_active_trig = dcs.triggers.TriggerOnce(comment= c_zone + " 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.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)
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)")))
#Add attack helos triggers
for index in range(options["e_attack_helos"]):
random_zone_obj = random.choice(list(self.conflict_zones.items()))
zone = random_zone_obj[1]
z_weak_trig = dcs.triggers.TriggerOnce(comment=zone.name + " Attack Helo")
z_weak_trig.rules.append(dcs.condition.FlagIsMore(zone.flag, 1))
z_weak_trig.rules.append(dcs.condition.FlagIsLess(zone.flag, random.randrange(20, 90)))
z_weak_trig.actions.append(dcs.action.DoScript(dcs.action.String("---Flag value represents the percentage of defending ground units remaining in zone. ")))
z_weak_trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.spawnAttackHelos()")))
self.m.triggerrules.triggers.append(z_weak_trig)
#Add attack plane triggers
for index in range(options["e_attack_planes"]):
random_zone_obj = random.choice(list(self.conflict_zones.items()))
zone = random_zone_obj[1]
z_weak_trig = dcs.triggers.TriggerOnce(comment=zone.name + " Attack Plane")
z_weak_trig.rules.append(dcs.condition.FlagIsMore(zone.flag, 1))
z_weak_trig.rules.append(dcs.condition.FlagIsLess(zone.flag, random.randrange(20, 90)))
z_weak_trig.actions.append(dcs.action.DoScript(dcs.action.String("---Flag value represents the percentage of defending ground units remaining in zone. ")))
z_weak_trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.spawnAttackPlanes()")))
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)
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict WON")
trig.rules.append(dcs.condition.FlagEquals(game_flag, 99))
trig.actions.append(dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is WON")))
self.m.triggerrules.triggers.append(trig)
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)
trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict LOST")
trig.rules.append(dcs.condition.FlagEquals(game_flag, 98))
trig.actions.append(dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is LOST")))
self.m.triggerrules.triggers.append(trig)

View File

@ -23,5 +23,8 @@ 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"},
{'type': dcs.planes.A_10C, 'loadout': ""}
]
e_zone_sams = [
dcs.vehicles.AirDefence.Strela_10M3,
]

View File

@ -1,20 +1,35 @@
You can add your own scenarios in this directory and they will appear in the mission generator.
You can add your own scenarios in this directory and they will appear in the mission generator. See the other scenario .miz files for examples of what to include in your template.
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).
3) A blue airport (recommend somewhere near/on-side your staging zone).
4) A red airport (recommend somewhere near/on-side your last conflict zone).
5) At least one Russian unit or static object. Anything will work, even a cow. You can set "HIDDEN ON MAP".
6) At least one USA unit or static object. See previous point.
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.
7) USA FARP called "HELO_FARP" for automatic player placement.
8) USA Carrier called "HELO_CARRIER" for automatic player placement.
9) Infantry spawn zones inside conflict zones. Add near buildings to simulate infantry hiding within. Name trigger zones like "ALPHA_SPAWN", "ALPHA_SPAWN_2, etc.
Tips:
-Position the center of conflict zones over an open area, as this position may be used to spawn 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.
-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.
-Airfields can be captured with ground units. You might consider placing conflict zones over neutral airfields for a rearming area, or perhaps unarmed client slots.
-Player/client slots are placed in this priority order: Carrier named "HELO_CARRIER", FARP named "HELO_FARP", and the blue airfield.
-Friendly AWACs and tankers will be placed at the blue airport if parking is available, otherwise they will start in the air.
-Enemy helicopters and planes will spawn at the red airport.
-Late activation FARPs might be useful for rearming far from the player spawn point.

View File

@ -0,0 +1,5 @@
#build UI files
pyuic5 -x MissionGeneratorUI.ui -o MissionGeneratorUI.py
#build exe
pyinstaller MissionGenerator.spec --distpath ..\ -i='assets\icon.ico'

Binary file not shown.

View File

@ -1,6 +1,6 @@
RotorOps = {}
RotorOps.version = "1.2.3"
local debug = true
RotorOps.version = "1.2.4"
local debug = false
---[[ROTOROPS OPTIONS]]---
@ -23,7 +23,7 @@ RotorOps.inf_spawns_per_zone = 3 --number of infantry groups to spawn per zone
--RotorOps settings that are safe to change only before calling setupConflict()
RotorOps.transports = {'UH-1H', 'Mi-8MT', 'Mi-24P', 'SA342M', 'SA342L', 'SA342Mistral'} --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_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
@ -138,6 +138,13 @@ RotorOps.gameMsgs = {
{'ENEMY TOOK CHARLIE!', 'enemy_destroying_us.ogg'},
{'ENEMY TOOK DELTA!', 'enemy_destroying_us.ogg'},
},
attack_helos = {
{'ENEMY ATTACK HELICOPTERS INBOUND!', 'enemy_attack_choppers.ogg'},
},
attack_planes = {
{'ENEMY ATTACK PLANES INBOUND!', 'enemy_attack_planes.ogg'},
},
}
@ -1243,6 +1250,32 @@ function RotorOps.startConflict()
end
function RotorOps.triggerSpawn(groupName, msg)
local group = Group.getByName(groupName)
if group and group:isExist() == true and #group:getUnits() > 0 and group:getUnits()[1]:getLife() > 1 and group:getUnits()[1]:isActive() then
env.info("RotorOps tried to respawn "..groupName.." but it's already active.")
else
local new_group = mist.respawnGroup(groupName, true)
if new_group then
RotorOps.gameMsg(msg)
env.info("RotorOps spawned "..groupName)
return new_group
end
end
return nil
end
function RotorOps.spawnAttackHelos()
RotorOps.triggerSpawn("Enemy Attack Helicopters", RotorOps.gameMsgs.attack_helos)
end
function RotorOps.spawnAttackPlanes()
RotorOps.triggerSpawn("Enemy Attack Planes", RotorOps.gameMsgs.attack_planes)
end

View File

@ -438,6 +438,7 @@ end
if (script_enable == 1) then
gameMsg("SPLASH DAMAGE 2 SCRIPT RUNNING")
env.info("SPLASH DAMAGE 2 SCRIPT RUNNING")
timer.scheduleFunction(function()
protectedCall(track_wpns)
return timer.getTime() + refreshRate

Binary file not shown.

BIN
sound/downed_pilot.ogg Normal file

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.