From 52ac32c6ce4d0d70eb92ad1e367fa79d9278c24a Mon Sep 17 00:00:00 2001 From: spencer-ki Date: Wed, 29 Jun 2022 23:57:23 -0700 Subject: [PATCH] advanced defenses feature -allow disabling spinboxes in scenario config -enemy units with radar can be designated to deploy intercept fighters on detection -zone protect SAMs are now part of Advanced Defenses option -Harrier now available in player selection and template imports --- Generator/MissionGenerator.py | 14 +- Generator/MissionGeneratorUI.py | 42 ++--- Generator/MissionGeneratorUI.ui | 42 ++--- Generator/RotorOpsConflict.py | 55 +++--- Generator/RotorOpsImport.py | 2 + Generator/RotorOpsMission.py | 320 ++++++++++++++++++-------------- Generator/RotorOpsUnits.py | 9 + Generator/requirements.txt | Bin 1230 -> 1196 bytes config/blue_player_loadouts.miz | Bin 33318 -> 33360 bytes scripts/RotorOps.lua | 312 +++++++++++++++++++++++++++++-- 10 files changed, 572 insertions(+), 224 deletions(-) diff --git a/Generator/MissionGenerator.py b/Generator/MissionGenerator.py index 89ab13e..51be48c 100644 --- a/Generator/MissionGenerator.py +++ b/Generator/MissionGenerator.py @@ -29,8 +29,8 @@ import qtmodern.windows # UPDATE BUILD VERSION maj_version = 1 -minor_version = 2 -patch_version = 0 +minor_version = 3 +patch_version = 1 modules_version = 2 modules_url = 'https://dcs-helicopters.com/user-files/modules/' @@ -421,6 +421,12 @@ class Window(QMainWindow, Ui_MainWindow): if qobj: qobj.setValue(config['spinboxes'][box]) + for box in QObject.findChildren(self, QSpinBox): + if 'disable_spinboxes' in config and config['disable_spinboxes'] is not None and box.objectName() in config['disable_spinboxes']: + box.setEnabled(False) + else: + box.setEnabled(True) + for button in QObject.findChildren(self, QRadioButton): if 'radiobuttons' in config and button.objectName() in config['radiobuttons']: button.setChecked(True) @@ -570,7 +576,6 @@ class Window(QMainWindow, Ui_MainWindow): "game_display": self.game_status_checkBox.isChecked(), "defending": self.defense_checkBox.isChecked(), "slots": self.slot_template_comboBox.currentText(), - "zone_protect_sams": self.zone_sams_checkBox.isChecked(), "zone_farps": self.farp_buttonGroup.checkedButton().objectName(), "e_transport_helos": self.e_transport_helos_spinBox.value(), "transport_drop_qty": self.troop_drop_spinBox.value(), @@ -588,6 +593,9 @@ class Window(QMainWindow, Ui_MainWindow): "logistics_farp_file": self.scenario.getConfigValue("logistics_farp_file", default=None), "zone_protect_file": self.scenario.getConfigValue("zone_protect_file", default=None), "script": self.scenario.getConfigValue("script", default=None), + "advanced_defenses": self.advanced_defenses_checkBox.isChecked(), + "red_cap": self.scenario.getConfigValue("red_cap", default=True), + "blue_cap": self.scenario.getConfigValue("blue_cap", default=True), } logger.info("Generating mission with options:") diff --git a/Generator/MissionGeneratorUI.py b/Generator/MissionGeneratorUI.py index 2a2dacf..19250cf 100644 --- a/Generator/MissionGeneratorUI.py +++ b/Generator/MissionGeneratorUI.py @@ -34,20 +34,20 @@ class Ui_MainWindow(object): self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.logistics_crates_checkBox = QtWidgets.QCheckBox(self.centralwidget) - self.logistics_crates_checkBox.setGeometry(QtCore.QRect(980, 211, 251, 28)) + self.logistics_crates_checkBox.setGeometry(QtCore.QRect(980, 231, 251, 28)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) self.logistics_crates_checkBox.setFont(font) self.logistics_crates_checkBox.setChecked(True) self.logistics_crates_checkBox.setObjectName("logistics_crates_checkBox") - self.zone_sams_checkBox = QtWidgets.QCheckBox(self.centralwidget) - self.zone_sams_checkBox.setGeometry(QtCore.QRect(980, 320, 241, 28)) + self.advanced_defenses_checkBox = QtWidgets.QCheckBox(self.centralwidget) + self.advanced_defenses_checkBox.setGeometry(QtCore.QRect(510, 350, 241, 28)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) - self.zone_sams_checkBox.setFont(font) - self.zone_sams_checkBox.setObjectName("zone_sams_checkBox") + self.advanced_defenses_checkBox.setFont(font) + self.advanced_defenses_checkBox.setObjectName("advanced_defenses_checkBox") self.red_forces_label = QtWidgets.QLabel(self.centralwidget) self.red_forces_label.setGeometry(QtCore.QRect(470, 80, 171, 27)) font = QtGui.QFont() @@ -79,7 +79,7 @@ class Ui_MainWindow(object): self.description_textBrowser.setObjectName("description_textBrowser") self.defense_checkBox = QtWidgets.QCheckBox(self.centralwidget) self.defense_checkBox.setEnabled(True) - self.defense_checkBox.setGeometry(QtCore.QRect(470, 130, 156, 28)) + self.defense_checkBox.setGeometry(QtCore.QRect(980, 140, 156, 28)) font = QtGui.QFont() font.setPointSize(11) font.setBold(False) @@ -109,7 +109,7 @@ class Ui_MainWindow(object): self.redforces_comboBox.setFont(font) self.redforces_comboBox.setObjectName("redforces_comboBox") self.scenario_label_8 = QtWidgets.QLabel(self.centralwidget) - self.scenario_label_8.setGeometry(QtCore.QRect(570, 220, 271, 24)) + self.scenario_label_8.setGeometry(QtCore.QRect(570, 180, 271, 24)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) @@ -165,14 +165,14 @@ class Ui_MainWindow(object): self.version_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.version_label.setObjectName("version_label") self.scenario_label_10 = QtWidgets.QLabel(self.centralwidget) - self.scenario_label_10.setGeometry(QtCore.QRect(570, 260, 271, 24)) + self.scenario_label_10.setGeometry(QtCore.QRect(570, 220, 271, 24)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) self.scenario_label_10.setFont(font) self.scenario_label_10.setObjectName("scenario_label_10") self.e_transport_helos_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.e_transport_helos_spinBox.setGeometry(QtCore.QRect(510, 260, 51, 31)) + self.e_transport_helos_spinBox.setGeometry(QtCore.QRect(510, 220, 51, 31)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -187,7 +187,7 @@ class Ui_MainWindow(object): self.e_transport_helos_spinBox.setProperty("value", 1) self.e_transport_helos_spinBox.setObjectName("e_transport_helos_spinBox") self.e_attack_planes_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.e_attack_planes_spinBox.setGeometry(QtCore.QRect(510, 220, 51, 31)) + self.e_attack_planes_spinBox.setGeometry(QtCore.QRect(510, 180, 51, 31)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -202,7 +202,7 @@ class Ui_MainWindow(object): self.e_attack_planes_spinBox.setProperty("value", 1) self.e_attack_planes_spinBox.setObjectName("e_attack_planes_spinBox") self.e_attack_helos_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.e_attack_helos_spinBox.setGeometry(QtCore.QRect(510, 180, 51, 31)) + self.e_attack_helos_spinBox.setGeometry(QtCore.QRect(510, 140, 51, 31)) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -219,7 +219,7 @@ class Ui_MainWindow(object): self.e_attack_helos_spinBox.setProperty("value", 1) self.e_attack_helos_spinBox.setObjectName("e_attack_helos_spinBox") self.scenario_label_7 = QtWidgets.QLabel(self.centralwidget) - self.scenario_label_7.setGeometry(QtCore.QRect(570, 180, 271, 24)) + self.scenario_label_7.setGeometry(QtCore.QRect(570, 140, 271, 24)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) @@ -239,7 +239,7 @@ class Ui_MainWindow(object): self.scenario_label_9.setFont(font) self.scenario_label_9.setObjectName("scenario_label_9") self.awacs_checkBox = QtWidgets.QCheckBox(self.centralwidget) - self.awacs_checkBox.setGeometry(QtCore.QRect(980, 246, 241, 28)) + self.awacs_checkBox.setGeometry(QtCore.QRect(980, 266, 241, 28)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) @@ -247,7 +247,7 @@ class Ui_MainWindow(object): self.awacs_checkBox.setChecked(True) self.awacs_checkBox.setObjectName("awacs_checkBox") self.tankers_checkBox = QtWidgets.QCheckBox(self.centralwidget) - self.tankers_checkBox.setGeometry(QtCore.QRect(980, 282, 241, 28)) + self.tankers_checkBox.setGeometry(QtCore.QRect(980, 302, 241, 28)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) @@ -277,14 +277,14 @@ class Ui_MainWindow(object): self.game_status_checkBox.setTristate(False) self.game_status_checkBox.setObjectName("game_status_checkBox") self.label = QtWidgets.QLabel(self.centralwidget) - self.label.setGeometry(QtCore.QRect(570, 340, 261, 23)) + self.label.setGeometry(QtCore.QRect(570, 300, 261, 23)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) self.label.setFont(font) self.label.setObjectName("label") self.inf_spawn_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.inf_spawn_spinBox.setGeometry(QtCore.QRect(510, 340, 51, 31)) + self.inf_spawn_spinBox.setGeometry(QtCore.QRect(510, 300, 51, 31)) font = QtGui.QFont() font.setPointSize(12) self.inf_spawn_spinBox.setFont(font) @@ -294,7 +294,7 @@ class Ui_MainWindow(object): self.inf_spawn_spinBox.setProperty("value", 0) self.inf_spawn_spinBox.setObjectName("inf_spawn_spinBox") self.troop_drop_spinBox = QtWidgets.QSpinBox(self.centralwidget) - self.troop_drop_spinBox.setGeometry(QtCore.QRect(510, 300, 51, 31)) + self.troop_drop_spinBox.setGeometry(QtCore.QRect(510, 260, 51, 31)) font = QtGui.QFont() font.setPointSize(12) self.troop_drop_spinBox.setFont(font) @@ -312,14 +312,14 @@ class Ui_MainWindow(object): self.random_weather_checkBox.setTristate(False) self.random_weather_checkBox.setObjectName("random_weather_checkBox") self.label_3 = QtWidgets.QLabel(self.centralwidget) - self.label_3.setGeometry(QtCore.QRect(570, 300, 281, 23)) + self.label_3.setGeometry(QtCore.QRect(570, 260, 281, 23)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) self.label_3.setFont(font) self.label_3.setObjectName("label_3") self.apcs_spawn_checkBox = QtWidgets.QCheckBox(self.centralwidget) - self.apcs_spawn_checkBox.setGeometry(QtCore.QRect(980, 180, 251, 27)) + self.apcs_spawn_checkBox.setGeometry(QtCore.QRect(980, 200, 251, 27)) font = QtGui.QFont() font.setPointSize(10) font.setBold(False) @@ -581,8 +581,8 @@ class Ui_MainWindow(object): MainWindow.setWindowTitle(_translate("MainWindow", "RotorOps Mission Generator")) self.logistics_crates_checkBox.setStatusTip(_translate("MainWindow", "Enable a base or FARP near the start position that can spawn CTLD crates for building ground units and air defenses. Sling load the logistics containers to create new logistics sites.")) self.logistics_crates_checkBox.setText(_translate("MainWindow", "Logistics Base")) - self.zone_sams_checkBox.setStatusTip(_translate("MainWindow", "Inactive conflict zones will be protected by SAMs. When a zone is cleared, SAMs at next active zone will be destroyed. No effect if Blue on defense.")) - self.zone_sams_checkBox.setText(_translate("MainWindow", "Protect Inactive Zones")) + self.advanced_defenses_checkBox.setStatusTip(_translate("MainWindow", "Each enemy conflict zone spawns a template of AA defenses and radar units that may spawn fighter intercepts for detected aircraft. A good difficulty multiplier for multiplayer.")) + self.advanced_defenses_checkBox.setText(_translate("MainWindow", "Enemy Advanced Defenses")) self.red_forces_label.setText(_translate("MainWindow", "Red Forces:")) self.scenario_comboBox.setStatusTip(_translate("MainWindow", "Tip: You can create your own templates that include mission options like kneeboards, briefings, weather, static units, triggers, scripts, etc.")) self.description_textBrowser.setHtml(_translate("MainWindow", "\n" diff --git a/Generator/MissionGeneratorUI.ui b/Generator/MissionGeneratorUI.ui index 9efcc07..73380cd 100644 --- a/Generator/MissionGeneratorUI.ui +++ b/Generator/MissionGeneratorUI.ui @@ -54,7 +54,7 @@ 980 - 211 + 231 251 28 @@ -75,11 +75,11 @@ true - + - 980 - 320 + 510 + 350 241 28 @@ -91,10 +91,10 @@ - Inactive conflict zones will be protected by SAMs. When a zone is cleared, SAMs at next active zone will be destroyed. No effect if Blue on defense. + Each enemy conflict zone spawns a template of AA defenses and radar units that may spawn fighter intercepts for detected aircraft. A good difficulty multiplier for multiplayer. - Protect Inactive Zones + Enemy Advanced Defenses @@ -190,8 +190,8 @@ p, li { white-space: pre-wrap; } - 470 - 130 + 980 + 140 156 28 @@ -271,7 +271,7 @@ p, li { white-space: pre-wrap; } 570 - 220 + 180 271 24 @@ -438,7 +438,7 @@ p, li { white-space: pre-wrap; } 570 - 260 + 220 271 24 @@ -460,7 +460,7 @@ p, li { white-space: pre-wrap; } 510 - 260 + 220 51 31 @@ -496,7 +496,7 @@ p, li { white-space: pre-wrap; } 510 - 220 + 180 51 31 @@ -532,7 +532,7 @@ p, li { white-space: pre-wrap; } 510 - 180 + 140 51 31 @@ -574,7 +574,7 @@ p, li { white-space: pre-wrap; } 570 - 180 + 140 271 24 @@ -633,7 +633,7 @@ p, li { white-space: pre-wrap; } 980 - 246 + 266 241 28 @@ -658,7 +658,7 @@ p, li { white-space: pre-wrap; } 980 - 282 + 302 241 28 @@ -758,7 +758,7 @@ p, li { white-space: pre-wrap; } 570 - 340 + 300 261 23 @@ -780,7 +780,7 @@ p, li { white-space: pre-wrap; } 510 - 340 + 300 51 31 @@ -810,7 +810,7 @@ p, li { white-space: pre-wrap; } 510 - 300 + 260 51 31 @@ -867,7 +867,7 @@ p, li { white-space: pre-wrap; } 570 - 300 + 260 281 23 @@ -889,7 +889,7 @@ p, li { white-space: pre-wrap; } 980 - 180 + 200 251 27 diff --git a/Generator/RotorOpsConflict.py b/Generator/RotorOpsConflict.py index 55f1d86..3e5fc71 100644 --- a/Generator/RotorOpsConflict.py +++ b/Generator/RotorOpsConflict.py @@ -74,14 +74,14 @@ def triggerSetup(rops, options): # dcs.action.DoScript(dcs.action.String("ctld.createRadioBeaconAtZone('" + c_zone + "','blue', 1440,'" + c_zone + "')"))) # rops.m.triggerrules.triggers.append(trig) - # Zone protection SAMs - if options["zone_protect_sams"]: - for index, zone_name in enumerate(rops.conflict_zones): - z_sams_trig = dcs.triggers.TriggerOnce(comment="Deactivate " + zone_name + " SAMs") - z_sams_trig.rules.append(dcs.condition.FlagEquals(game_flag, index + 1)) - z_sams_trig.actions.append(dcs.action.DoScript( - dcs.action.String("Group.destroy(Group.getByName('Static " + zone_name + " Protection SAM'))"))) - rops.m.triggerrules.triggers.append(z_sams_trig) + # # Zone protection SAMs + # if options["zone_protect_sams"]: + # for index, zone_name in enumerate(rops.conflict_zones): + # z_sams_trig = dcs.triggers.TriggerOnce(comment="Deactivate " + zone_name + " SAMs") + # z_sams_trig.rules.append(dcs.condition.FlagEquals(game_flag, index + 1)) + # z_sams_trig.actions.append(dcs.action.DoScript( + # dcs.action.String("Group.destroy(Group.getByName('" + zone_name + " Protect Static'))"))) + # rops.m.triggerrules.triggers.append(z_sams_trig) # Deactivate zone FARPs and player slots in defensive mode: # this will also deactivate players already in the air. @@ -178,24 +178,31 @@ def triggerSetup(rops, options): dcs.action.String("RotorOps.spawnTranspHelos(8," + str(options["transport_drop_qty"]) + ")"))) rops.m.triggerrules.triggers.append(z_weak_trig) + # Add enemy CAP spawn trigger + cap_trig = dcs.triggers.TriggerContinious(comment="Spawn Enemy CAP") + cap_trig.rules.append(dcs.condition.TimeAfter(10)) + cap_trig.rules.append(dcs.condition.Predicate(dcs.action.String("return RotorOps.predSpawnRedCap()"))) + cap_trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.deployFighters()"))) + rops.m.triggerrules.triggers.append(cap_trig) + # Add game won/lost triggers - # Add game won triggers - trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict WON") - trig.rules.append(dcs.condition.FlagEquals(game_flag, 99)) + # Add game won triggers + trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict WON") + trig.rules.append(dcs.condition.FlagEquals(game_flag, 99)) + trig.actions.append( + dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is WON"))) + if options["end_trigger"] is not False: trig.actions.append( - dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is WON"))) - if options["end_trigger"] is not False: - trig.actions.append( - dcs.action.DoScript(dcs.action.String("RotorOps.gameMsg(RotorOps.gameMsgs.success)"))) - rops.m.triggerrules.triggers.append(trig) + dcs.action.DoScript(dcs.action.String("RotorOps.gameMsg(RotorOps.gameMsgs.success)"))) + rops.m.triggerrules.triggers.append(trig) - # Add game lost triggers - trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict LOST") - trig.rules.append(dcs.condition.FlagEquals(game_flag, 98)) - trig.actions.append( - dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is LOST"))) - if options["end_trigger"] is not False: - trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.gameMsg(RotorOps.gameMsgs.failure)"))) - rops.m.triggerrules.triggers.append(trig) \ No newline at end of file + # Add game lost triggers + trig = dcs.triggers.TriggerOnce(comment="RotorOps Conflict LOST") + trig.rules.append(dcs.condition.FlagEquals(game_flag, 98)) + trig.actions.append( + dcs.action.DoScript(dcs.action.String("---Add an action you want to happen when the game is LOST"))) + if options["end_trigger"] is not False: + trig.actions.append(dcs.action.DoScript(dcs.action.String("RotorOps.gameMsg(RotorOps.gameMsgs.failure)"))) + rops.m.triggerrules.triggers.append(trig) \ No newline at end of file diff --git a/Generator/RotorOpsImport.py b/Generator/RotorOpsImport.py index b5c347d..c1dcbea 100644 --- a/Generator/RotorOpsImport.py +++ b/Generator/RotorOpsImport.py @@ -126,6 +126,7 @@ class ImportObjects: group.units[0].heading) # ng.units[0].livery_id = group.units[0].livery_id + ng.units[0].name = dest_name + " " + group.units[i].name new_groups.append(ng) else: @@ -211,6 +212,7 @@ class ImportObjects: group.units[0].heading) unit_count = unit_count + 1 # new_group.units[0].livery_id = group.units[0].livery_id + new_group.units[0].name = dest_name + " " + group.units[i].name else: diff --git a/Generator/RotorOpsMission.py b/Generator/RotorOpsMission.py index 3e054b6..18eb338 100644 --- a/Generator/RotorOpsMission.py +++ b/Generator/RotorOpsMission.py @@ -32,6 +32,10 @@ class RotorOpsMission: self.res_map = {} self.config = None # not used self.imports = None + self.red_zones = {} + self.blue_zones = {} + self.primary_e_airport = None + class RotorOpsZone: def __init__(self, name: str, flag: int, position: dcs.point, size: int): @@ -215,11 +219,11 @@ class RotorOpsMission: elif zone.name.rfind("SPAWN") >= 0: self.addZone(self.spawn_zones, self.RotorOpsZone(zone.name, None, zone.position, zone.radius)) - blue_zones = self.staging_zones - red_zones = self.conflict_zones + self.blue_zones = self.staging_zones + self.red_zones = self.conflict_zones if options["defending"]: - blue_zones = self.conflict_zones - red_zones = self.staging_zones + self.blue_zones = self.conflict_zones + self.red_zones = self.staging_zones # swap airport sides self.swapSides(options) @@ -229,119 +233,10 @@ class RotorOpsMission: if options["player_hotstart"]: start_type = dcs.mission.StartType.Warm - # Adds vehicles as a single group (for easy late activation), and helicopters if enabled in settings - # def addZoneFARP(_zone_name, country, file): - # - # farp_flag = self.m.find_group(_zone_name) - # - # if farp_flag: - # farp_position = farp_flag.units[0].position - # farp_heading = farp_flag.units[0].heading - # else: - # farp_position = self.all_zones[_zone_name].position - # farp_heading = 0 - # - # # Add the basic invisible farp object - # farp = self.m.farp(self.m.country(country), _zone_name + " FARP", farp_position, - # hidden=False, dead=False, - # farp_type=dcs.unit.InvisibleFARP) - # - # # Use alternate template file if it has been defined in scenario config - # if options["zone_farp_file"]: - # - # for i in imports: - # if i.filename.removesuffix('.miz') == options["zone_farp_file"]: - # file = i.path - # # if multiple files found, we want the latest file to override the first - # - # i = ImportObjects(file) - # i.anchorByGroupName("ANCHOR") - # farp_group = i.copyVehiclesAsGroup(self.m, country, _zone_name + " FARP Static", farp_position, - # farp_heading) - # # Add client helicopters - # if options["farp_spawns"]: - # helicopter_groups = i.copyHelicopters(self.m, jtf_blue, "ZONE " + _zone_name + " EMPTY ", farp_position, farp_heading) - # for group in helicopter_groups: - # self.all_zones[_zone_name].player_helo_spawns.append(group) - # - # return farp_group - # # Adds statics, vehicles, and helicopters. Late activation is not possible - # def addLogisticsZone(_zone_name, country, file, config_name, helicopters=False): - # flag = self.m.find_group(_zone_name) - # if flag: - # position = flag.units[0].position - # heading = flag.units[0].heading - # else: - # position = self.all_zones[_zone_name].position - # heading = 0 - # - # # Use alternate template file if it has been defined in scenario config - # if options[config_name]: - # - # for i in imports: - # if i.filename.removesuffix('.miz') == options[config_name]: - # file = i.path - # # if multiple files found, we want the latest file to override the first - # - # # Import statics and vehicles - # i = ImportObjects(file) - # i.anchorByGroupName("ANCHOR") - # i.copyStatics(self.m, country, _zone_name + " Logistics Zone", - # position, heading) - # i.copyVehicles(self.m, country, _zone_name + " Logistics Zone", - # position, heading) - # - # # Add client helicopters - # if helicopters: - # helicopter_groups = i.copyHelicopters(self.m, jtf_blue, "ZONE " + _zone_name + " EMPTY ", position, - # heading) - # for group in helicopter_groups: - # self.all_zones[_zone_name].player_helo_spawns.append(group) - - # Adds statics, vehicles, and helicopters (if enabled). Late activation is not possible. - # def addDefensiveFARP(_zone_name, country, file): - # - # farp_flag = self.m.find_group(_zone_name) - # - # if farp_flag: - # farp_position = farp_flag.units[0].position - # farp_heading = farp_flag.units[0].heading - # else: - # farp_position = self.all_zones[_zone_name].position - # farp_heading = 0 - # - # # Add the basic invisible farp object - # farp = self.m.farp(self.m.country(country), _zone_name + " FARP", farp_position, - # hidden=False, dead=False, - # farp_type=dcs.unit.InvisibleFARP) - # - # # Use alternate template file if it has been defined in scenario config - # if options["defensive_farp_file"]: - # - # for i in imports: - # if i.filename.removesuffix('.miz') == options["defensive_farp_file"]: - # file = i.path - # # if multiple files found, we want the latest file to override the first - # - # # Import statics and vehicles - # i = ImportObjects(file) - # i.anchorByGroupName("ANCHOR") - # i.copyStatics(self.m, country, _zone_name + " Logistics Zone", - # farp_position, farp_heading) - # i.copyVehicles(self.m, country, _zone_name + " Logistics Zone", - # farp_position, farp_heading) - # - # # Import player helicopters - # if options["farp_spawns"]: - # helicopter_groups = i.copyHelicopters(self.m, jtf_blue, "ZONE " + _zone_name + " EMPTY ", farp_position, - # farp_heading) - # for group in helicopter_groups: - # self.all_zones[_zone_name].player_helo_spawns.append(group) - - for zone_name in red_zones: + for zone_name in self.red_zones: if red_forces["vehicles"]: - self.addGroundGroups(red_zones[zone_name], self.m.country(jtf_red), red_forces["vehicles"], + self.addGroundGroups(self.red_zones[zone_name], self.m.country(jtf_red), red_forces["vehicles"], options["red_quantity"]) if options["zone_farps"] != "farp_never" and not options["defending"]: @@ -367,34 +262,21 @@ class RotorOpsMission: ) vehicle_group.late_activation = True - # For SAMs: Add vehicles as a single group (for easy late activation) - if options["zone_protect_sams"]: + + if options["advanced_defenses"]: sam_group = self.addZoneBase(options, zone_name, jtf_red, file=zone_protect, config_name="zone_protect_file", copy_vehicles=True, - vehicles_name=zone_name + " Protect Static", - vehicles_single_group=True + vehicles_name=zone_name + " Defense Static", + vehicles_single_group=False ) - # farp_flag = self.m.find_group(zone_name) - # - # if farp_flag: - # farp_position = farp_flag.units[0].position - # farp_heading = farp_flag.units[0].heading - # else: - # farp_position = self.all_zones[zone_name].position - # farp_heading = 0 - # - # i = ImportObjects(zone_protect) - # i.anchorByGroupName("ANCHOR") - # farp_group = i.copyVehiclesAsGroup(self.m, jtf_red, "Static " + zone_name + " Protection SAM", - # farp_position, - # farp_heading) + # Populate Blue zones with ground units - for i, zone_name in enumerate(blue_zones): + for i, zone_name in enumerate(self.blue_zones): if blue_forces["vehicles"]: - self.addGroundGroups(blue_zones[zone_name], self.m.country(jtf_blue), blue_forces["vehicles"], + self.addGroundGroups(self.blue_zones[zone_name], self.m.country(jtf_blue), blue_forces["vehicles"], options["blue_quantity"]) # Add blue zone FARPS (not late activated) for defensive mode @@ -404,7 +286,7 @@ class RotorOpsMission: if options["farp_spawns"]: helicopters = True - if options["crates"] and i == len(blue_zones) - 1: + if options["crates"] and i == len(self.blue_zones) - 1: # add a logistics zone to the last conflict zone # addLogisticsZone(zone_name, jtf_blue, logistics_farp, "logistics_farp_file", helicopters) self.addZoneBase(options, zone_name, jtf_blue, @@ -458,7 +340,9 @@ class RotorOpsMission: # Add player slots window.statusBar().showMessage("Adding flights to mission...", 10000) - if options["slots"] != "Locked to Scenario" and options["slots"] != "None": + if options["slots"] == "Locked to Scenario" or options["slots"] == "None": + pass + else: self.addPlayerHelos(options) # Add AI Flights @@ -728,7 +612,7 @@ class RotorOpsMission: for helicopter in dcs.helicopters.helicopter_map: if helicopter == options["slots"]: client_helos = [dcs.helicopters.helicopter_map[ - helicopter]] # if out ui slot option matches a specific helicopter type name + helicopter]] # if our ui slot option matches a specific helicopter type name # get loadouts from miz file and put into a simple dict default_loadouts = {} @@ -782,6 +666,8 @@ class RotorOpsMission: helotype = None if helicopter_id in dcs.helicopters.helicopter_map: helotype = dcs.helicopters.helicopter_map[helicopter_id] + elif helicopter_id in dcs.planes.plane_map: + helotype = dcs.planes.plane_map[helicopter_id] else: continue if carrier: @@ -871,7 +757,7 @@ class RotorOpsMission: heading = enemy_heading + random.randrange(70, 110) race_dist = random.randrange(40 * 1000, 80 * 1000) center_pt = dcs.mapping.point_from_heading(friendly_pt.x, friendly_pt.y, - enemy_heading - random.randrange(140, 220), 10000) + enemy_heading - random.randrange(140, 220), 20000) pt1 = dcs.mapping.point_from_heading(center_pt[0], center_pt[1], enemy_heading - 90, random.randrange(20 * 1000, 40 * 1000)) return dcs.mapping.Point(pt1[0], pt1[1], terrain), heading, race_dist @@ -882,6 +768,7 @@ class RotorOpsMission: friendly_airports, primary_f_airport = self.getCoalitionAirports("blue") enemy_airports, primary_e_airport = self.getCoalitionAirports("red") + # find enemy carriers and farps carrier = self.m.country(jtf_red).find_ship_group(name="HELO_CARRIER") if not carrier: @@ -901,6 +788,27 @@ class RotorOpsMission: primary_f_airport.position.y ) + self.primary_e_airport = primary_e_airport + self.m.triggers.add_triggerzone(primary_e_airport.position, 1500, hidden=True, name="RED_AIRBASE") + + if options["red_cap"]: + scenario_red_cap_spawn_zone = None + for zone in self.m.triggers.zones(): + if zone.name == "RED_CAP_SPAWN": + scenario_red_cap_spawn_zone = True + if not scenario_red_cap_spawn_zone: + e_cap_spawn_point = primary_e_airport.position.point_from_heading(e_airport_heading, 100000) + self.m.triggers.add_triggerzone(e_cap_spawn_point, 30000, hidden=True, name="RED_CAP_SPAWN") + + if options["blue_cap"]: + scenario_blue_cap_spawn_zone = None + for zone in self.m.triggers.zones(): + if zone.name == "BLUE_CAP_SPAWN": + scenario_blue_cap_spawn_zone = True + if not scenario_blue_cap_spawn_zone: + f_cap_spawn_point = primary_f_airport.position.point_from_heading(e_airport_heading + 180, 100000) + self.m.triggers.add_triggerzone(f_cap_spawn_point, 30000, hidden=True, name="BLUE_CAP_SPAWN") + if options["f_awacs"]: awacs_name = "AWACS" awacs_freq = 266 @@ -987,6 +895,7 @@ class RotorOpsMission: t1_freq) + ".00 " + t1_tac + "\n" + t2_name + " " + str(t2_freq) + ".00 " + t2_tac + "\n\n" self.m.set_description_text(briefing) + def zone_attack(fg, airport): fg.set_skill(dcs.unit.Skill.High) fg.late_activation = True @@ -1118,6 +1027,139 @@ class RotorOpsMission: unit.pylons = source_helo.pylons unit.livery_id = source_helo.livery_id + if False: + for i in range(1,4): + randzone = random.choice(list(self.red_zones)) + pt2 = self.red_zones[randzone].position + source_plane = None + if red_forces["fighter_planes"]: + source_group = random.choice(red_forces["fighter_planes"]) + source_plane = source_group.units[0] + plane_type = source_plane.unit_type + group_size = random.randrange(1, 2) + + else: + group_size = random.randrange(1, 2) + plane_type = random.choice(RotorOpsUnits.e_attack_helos) + + airport = self.getParking(primary_e_airport, plane_type, enemy_airports, group_size) + + enemy_cap = self.m.patrol_flight(airport=airport, + name="Enemy CAP " + str(i), + country=combinedJointTaskForcesRed, + patrol_type=plane_type, + pos1=primary_e_airport.position, + pos2=pt2, + altitude=3000, + group_size=group_size, + max_engage_distance=40 * 1000 + ) + + # enemy_cap.points[0].tasks[0] = dcs.task.EngageTargets(max_engage_distance, [dcs.task.Targets.All.Air.Planes]) + + for unit in enemy_cap.units: + unit.skill = dcs.unit.Skill.Random + + if source_plane: + for unit in enemy_cap.units: + unit.pylons = source_plane.pylons + unit.livery_id = source_plane.livery_id + + if options["red_cap"]: + + if red_forces["fighter_planes"]: + for fighter_plane_group in red_forces["fighter_planes"]: + source_group = random.choice(red_forces["fighter_planes"]) + source_plane = source_group.units[0] + plane_type = source_plane.unit_type + + enemy_cap = self.m.flight_group( + country=combinedJointTaskForcesRed, + name="RED CAP", + aircraft_type=plane_type, + airport=None, + maintask=dcs.task.CAP, + group_size=1, + position=e_cap_spawn_point, + altitude=5000, + speed=300 + ) + + enemy_cap.late_activation = True + + for unit in enemy_cap.units: + unit.skill = dcs.unit.Skill.Random + unit.pylons = source_plane.pylons + unit.livery_id = source_plane.livery_id + + else: + plane_type = random.choice(RotorOpsUnits.e_fighter_planes) + + enemy_cap = self.m.flight_group( + country=combinedJointTaskForcesRed, + name="RED CAP", + aircraft_type=plane_type, + airport=None, + maintask=dcs.task.CAP, + group_size=1, + position=e_cap_spawn_point, + altitude=5000, + speed=300 + ) + + enemy_cap.late_activation = True + + for unit in enemy_cap.units: + unit.skill = dcs.unit.Skill.Random + + if options["blue_cap"]: + + if blue_forces["fighter_planes"]: + for fighter_plane_group in blue_forces["fighter_planes"]: + source_group = random.choice(blue_forces["fighter_planes"]) + source_plane = source_group.units[0] + plane_type = source_plane.unit_type + + friendly_cap = self.m.flight_group( + country=combinedJointTaskForcesBlue, + name="BLUE CAP", + aircraft_type=plane_type, + airport=None, + maintask=dcs.task.CAP, + group_size=1, + position=f_cap_spawn_point, + altitude=5000, + speed=300 + ) + + friendly_cap.late_activation = True + + for unit in friendly_cap.units: + unit.skill = dcs.unit.Skill.Random + unit.pylons = source_plane.pylons + unit.livery_id = source_plane.livery_id + + else: + plane_type = random.choice(RotorOpsUnits.f_fighter_planes) + + friendly_cap = self.m.flight_group( + country=combinedJointTaskForcesBlue, + name="BLUE CAP", + aircraft_type=plane_type, + airport=None, + maintask=dcs.task.CAP, + group_size=1, + position=f_cap_spawn_point, + altitude=5000, + speed=300 + ) + + friendly_cap.late_activation = True + + for unit in friendly_cap.units: + unit.skill = dcs.unit.Skill.Random + + def importObjects(self, data): imports = data["objects"]["imports"] diff --git a/Generator/RotorOpsUnits.py b/Generator/RotorOpsUnits.py index e0449f7..b92a9b6 100644 --- a/Generator/RotorOpsUnits.py +++ b/Generator/RotorOpsUnits.py @@ -20,6 +20,7 @@ player_helos = [ dcs.helicopters.SA342Mistral, dcs.helicopters.UH_1H, aircraftMods.UH_60L, + dcs.planes.AV8BNA, ] e_attack_helos = [ @@ -39,6 +40,14 @@ e_attack_planes = [ dcs.planes.A_10C, ] +e_fighter_planes = [ + dcs.planes.Su_27, +] + +f_fighter_planes = [ + dcs.planes.FA_18C_hornet, +] + e_zone_sams = [ dcs.vehicles.AirDefence.Strela_10M3, ] \ No newline at end of file diff --git a/Generator/requirements.txt b/Generator/requirements.txt index 43c09aaca0f524712d10fa0a5e8c37d30d3a6627..3dd3e048e0c114e1e188d967ab40f7c9c86469a3 100644 GIT binary patch delta 78 zcmX@dxrTGYJx0f3h609EhCGI3AX&sv%#Z=33m6iC>=XulAWjB~IRJV23?)Deq6>f` PxjV@q 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 b%FNTV@q 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 Z|L+Y 90) then + RotorOps.gameMsg(RotorOps.gameMsgs.enemy_fighters_inbound) + cooldown["e_fighters_inbound_msg"] = RotorOps.getTime() + end + --debugTable(fighters_by_detected_unitname) + env.info(target_unit .. " was detected and we spawned a new fighter group: " .. fighter) + end + end + + local function rtb(group_name) + + local grp = Group.getByName(group_name) + if grp then + local coal_airbases = coalition.getAirbases(grp:getCoalition()) + --debugTable(coal_airbases) + random_airbase = coal_airbases[math.random(1, #coal_airbases)] + + local airbase_pos = mist.utils.makeVec2(random_airbase:getPoint()) + local airbase_id = random_airbase:getID() + local rtb = { + id = 'Mission', + params = { + route = { + points = { + [1] = { + alt = 2000, + alt_type = "RADIO", + speed = 300, + x = airbase_pos.x, + y = airbase_pos.y, + aerodromeId = airbase_id, + type = "Land", + action = "Landing", + } + } + } + } + } + + grp:getController():setTask(rtb) + env.info(group_name .. " is RTB to ".. random_airbase:getName()) + end + end + + + --fighter respawning and rtb + for target_name, fighter_group_data in pairs(fighters_by_detected_unitname) do + local group = Group.getByName(fighter_group_data.name) + if group then --if group alive + if fighter_group_data.rtb_time < RotorOps.getTime() then + env.info(fighter_group_data.name .. " is RTB. Removing from table.") + rtb(fighter_group_data.name) + fighters_by_detected_unitname[target_name] = nil + end + else --if group dead + if fighter_group_data.respawn_time < RotorOps.getTime() then + env.info(fighter_group_data.name .. " has hit respawn_time limit. Removing from table to allow another group to spawn.") + fighters_by_detected_unitname[target_name] = nil + end + end + end + + + + + for uName, uData in pairs(mist.DBs.unitsByName) do + local str_index = string.find(uName, RotorOps.fighter_radar_unit_string) + if str_index then + --trigger.action.outText("Found radar unit: " .. uData.unitName, 2) + local radar_unit = Unit.getByName(uData.unitName) + local max_distance = RotorOps.fighter_max_detection_dist + local dist_str = string.sub(uName, str_index + #RotorOps.fighter_radar_unit_string + 1) + if #dist_str > 3 then + --env.info("Radar unit name has the max detection distance property:".. dist_str) + max_distance = tonumber(dist_str) + end + + if radar_unit and radar_unit:getLife() > 0 then + --trigger.action.outText(uData.unitName .. " is searching for targets. life=" .. radar_unit:getLife(), 2) + + raw_detected_units = radar_unit:getController():getDetectedTargets(Controller.Detection.RADAR) + if raw_detected_units then + for i, target in pairs(raw_detected_units) do + --debugTable(target) + if target.object then + local detected_unitname = target.object:getName() + local target_pos = target.object:getPosition().p + local target_distance = mist.utils.get2DDist(radar_unit:getPosition().p, target_pos) + local terrain_height = land.getHeight({x = target_pos.x, y = target_pos.z}) + local target_agl = target_pos.y - terrain_height + + --trigger.action.outText(uData.unitName .. "detected " .. detected_unitname .. " at " .. target_distance .. " agl:" .. target_agl, 2) + + if target_distance <= max_distance and target_agl >= RotorOps.fighter_min_detection_alt then + --trigger.action.outText(uData.unitName .. " has detected "..detected_unitname, 2) + + if tableHasKey(fighters_by_detected_unitname, detected_unitname) then + --trigger.action.outText(detected_unitname .. " already in table with " .. fighters_by_detected_unitname[detected_unitname], 2) + + else + spawn(target_pos, detected_unitname, radar_unit:getCoalition()) + end + + end + end --end if target.object + end --end of raw_detected targets loop + end + + end --end of radar_unit + end + end --end of all units by name loop + +end --- USEFUL PUBLIC 'LUA PREDICATE' FUNCTIONS FOR MISSION EDITOR TRIGGERS (don't forget that DCS lua predicate functions should 'return' these function calls) @@ -1928,3 +2203,8 @@ function RotorOps.predPlayerInZone(zone_name) end end +--determine if enemy CAP is needed +function RotorOps.predSpawnRedCap() + return true +end +