diff --git a/.gitignore b/.gitignore index 9cbe684..aea95bd 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ MissionGenerator.exe incoming templates/ Generator/utils/extract units/source.miz Generator/utils/extract units/units.txt +generator.log diff --git a/Generator/Forces/blue/BLUE Default Armor.miz b/Generator/Forces/blue/BLUE Default Armor.miz index ffd71fd..fc9903a 100644 Binary files a/Generator/Forces/blue/BLUE Default Armor.miz and b/Generator/Forces/blue/BLUE Default Armor.miz differ diff --git a/Generator/Forces/red/RED Armor (Hard).miz b/Generator/Forces/red/RED Armor (Hard).miz index 17e12e3..b599356 100644 Binary files a/Generator/Forces/red/RED Armor (Hard).miz and b/Generator/Forces/red/RED Armor (Hard).miz differ diff --git a/Generator/Forces/red/RED Armor, Infantry & Artillery (Med).miz b/Generator/Forces/red/RED Armor, Infantry & Artillery (Med).miz index fa4ada1..b2eec21 100644 Binary files a/Generator/Forces/red/RED Armor, Infantry & Artillery (Med).miz and b/Generator/Forces/red/RED Armor, Infantry & Artillery (Med).miz differ diff --git a/Generator/MissionGenerator.py b/Generator/MissionGenerator.py index 41a21a4..ccb4384 100644 --- a/Generator/MissionGenerator.py +++ b/Generator/MissionGenerator.py @@ -171,6 +171,8 @@ class Window(QMainWindow, Ui_MainWindow): "Infantry Spawn Zones: " + str(spawn_zones) + "\n" + "Approx Distance: " + str(math.floor(RotorOpsUtils.convertMeterToNM(conflict_zone_distance_sum))) + "nm \n" #"Validity Check:" + str(validateTemplate()) + + "\n== BRIEFING ==\n\n" + + source_mission.description_text() ) #self.description_textBrowser.setText("File error occured.") @@ -202,6 +204,7 @@ class Window(QMainWindow, Ui_MainWindow): "inf_spawn_msgs": self.inf_spawn_voiceovers_checkBox.isChecked(), "e_transport_helos": self.e_transport_helos_spinBox.value(), "transport_drop_qty": self.troop_drop_spinBox.value(), + "smoke_pickup_zones": self.smoke_pickup_zone_checkBox.isChecked(), } os.chdir(self.m.home_dir + '/Generator') n = ROps.RotorOpsMission() diff --git a/Generator/MissionGeneratorUI.py b/Generator/MissionGeneratorUI.py index 19e4f58..fafade2 100644 --- a/Generator/MissionGeneratorUI.py +++ b/Generator/MissionGeneratorUI.py @@ -48,7 +48,7 @@ class Ui_MainWindow(object): "padding: 4px;") self.generateButton.setObjectName("generateButton") self.description_textBrowser = QtWidgets.QTextBrowser(self.centralwidget) - self.description_textBrowser.setGeometry(QtCore.QRect(710, 20, 331, 131)) + self.description_textBrowser.setGeometry(QtCore.QRect(670, 30, 501, 131)) font = QtGui.QFont() font.setPointSize(9) self.description_textBrowser.setFont(font) @@ -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(810, 790, 191, 16)) + self.game_status_checkBox.setGeometry(QtCore.QRect(810, 760, 191, 16)) font = QtGui.QFont() font.setPointSize(9) self.game_status_checkBox.setFont(font) @@ -121,7 +121,7 @@ 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(810, 820, 191, 16)) + self.voiceovers_checkBox.setGeometry(QtCore.QRect(810, 790, 191, 16)) font = QtGui.QFont() font.setPointSize(9) self.voiceovers_checkBox.setFont(font) @@ -154,6 +154,7 @@ class Ui_MainWindow(object): font = QtGui.QFont() font.setPointSize(10) self.apcs_spawn_checkBox.setFont(font) + self.apcs_spawn_checkBox.setChecked(True) self.apcs_spawn_checkBox.setObjectName("apcs_spawn_checkBox") self.inf_spawn_spinBox = QtWidgets.QSpinBox(self.centralwidget) self.inf_spawn_spinBox.setGeometry(QtCore.QRect(670, 340, 51, 31)) @@ -191,7 +192,7 @@ class Ui_MainWindow(object): self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.force_offroad_checkBox = QtWidgets.QCheckBox(self.centralwidget) - self.force_offroad_checkBox.setGeometry(QtCore.QRect(810, 760, 191, 16)) + self.force_offroad_checkBox.setGeometry(QtCore.QRect(810, 820, 191, 16)) font = QtGui.QFont() font.setPointSize(9) self.force_offroad_checkBox.setFont(font) @@ -311,6 +312,13 @@ class Ui_MainWindow(object): self.troop_drop_spinBox.setMaximum(10) self.troop_drop_spinBox.setProperty("value", 4) self.troop_drop_spinBox.setObjectName("troop_drop_spinBox") + self.smoke_pickup_zone_checkBox = QtWidgets.QCheckBox(self.centralwidget) + self.smoke_pickup_zone_checkBox.setGeometry(QtCore.QRect(810, 690, 251, 31)) + font = QtGui.QFont() + font.setPointSize(9) + self.smoke_pickup_zone_checkBox.setFont(font) + self.smoke_pickup_zone_checkBox.setChecked(True) + self.smoke_pickup_zone_checkBox.setObjectName("smoke_pickup_zone_checkBox") self.background_label.raise_() self.scenario_comboBox.raise_() self.scenario_label.raise_() @@ -354,6 +362,7 @@ class Ui_MainWindow(object): self.e_transport_helos_spinBox.raise_() self.label_3.raise_() self.troop_drop_spinBox.raise_() + self.smoke_pickup_zone_checkBox.raise_() MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1209, 26)) @@ -417,7 +426,7 @@ class Ui_MainWindow(object): self.label.setText(_translate("MainWindow", "Infantry Spawns per zone:")) self.slot_template_comboBox.setStatusTip(_translate("MainWindow", "Default player/client spawn locations at a friendly airport.")) self.label_2.setText(_translate("MainWindow", "Player Slots")) - self.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.setStatusTip(_translate("MainWindow", "May help prevent long travel times or pathfinding issues. ")) 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.")) @@ -444,6 +453,8 @@ class Ui_MainWindow(object): self.label_3.setStatusTip(_translate("MainWindow", "The number of troop drops per transport helicopter flight.")) self.label_3.setText(_translate("MainWindow", "Transport Drop Points:")) self.troop_drop_spinBox.setStatusTip(_translate("MainWindow", "The number of troop drops per transport helicopter flight.")) + self.smoke_pickup_zone_checkBox.setStatusTip(_translate("MainWindow", "Infinite troop pickup zones will be marked with blue smoke.")) + self.smoke_pickup_zone_checkBox.setText(_translate("MainWindow", "Smoke at Troop Pickup Zones")) self.action_generateMission.setText(_translate("MainWindow", "_generateMission")) self.action_scenarioSelected.setText(_translate("MainWindow", "_scenarioSelected")) self.action_blueforcesSelected.setText(_translate("MainWindow", "_blueforcesSelected")) diff --git a/Generator/MissionGeneratorUI.ui b/Generator/MissionGeneratorUI.ui index b749532..1898384 100644 --- a/Generator/MissionGeneratorUI.ui +++ b/Generator/MissionGeneratorUI.ui @@ -96,9 +96,9 @@ padding: 4px; - 710 - 20 - 331 + 670 + 30 + 501 131 @@ -313,7 +313,7 @@ p, li { white-space: pre-wrap; } 810 - 790 + 760 191 16 @@ -340,7 +340,7 @@ p, li { white-space: pre-wrap; } 810 - 820 + 790 191 16 @@ -449,6 +449,9 @@ p, li { white-space: pre-wrap; } APCs Spawn Infantry + + true + @@ -570,7 +573,7 @@ p, li { white-space: pre-wrap; } 810 - 760 + 820 191 16 @@ -581,7 +584,7 @@ p, li { white-space: pre-wrap; } - May help prevent long travel times or pathfinding issues. Tip: You can change this dynamically from mission triggers. + May help prevent long travel times or pathfinding issues. Force Offroad @@ -957,6 +960,30 @@ p, li { white-space: pre-wrap; } 4 + + + + 810 + 690 + 251 + 31 + + + + + 9 + + + + Infinite troop pickup zones will be marked with blue smoke. + + + Smoke at Troop Pickup Zones + + + true + + background_label scenario_comboBox scenario_label @@ -1000,6 +1027,7 @@ p, li { white-space: pre-wrap; } e_transport_helos_spinBox label_3 troop_drop_spinBox + smoke_pickup_zone_checkBox diff --git a/Generator/RotorOpsGroups.py b/Generator/RotorOpsGroups.py index 33cdefb..25bc383 100644 --- a/Generator/RotorOpsGroups.py +++ b/Generator/RotorOpsGroups.py @@ -11,7 +11,7 @@ import random class VehicleTemplate: - class USA: + class CombinedJointTaskForcesBlue: @staticmethod def zone_farp(mission, country, farp_country, position, heading, name, late_activation): @@ -24,7 +24,8 @@ class VehicleTemplate: [ dcs.vehicles.Unarmed.M_818, dcs.vehicles.AirDefence.Vulcan, - dcs.vehicles.Unarmed.Ural_375 + dcs.vehicles.Unarmed.Ural_375, + dcs.vehicles.Unarmed.M978_HEMTT_Tanker ], position.point_from_heading(45, 7), heading=random.randint(0, 359), diff --git a/Generator/RotorOpsMission.py b/Generator/RotorOpsMission.py index 328309f..d92cf6c 100644 --- a/Generator/RotorOpsMission.py +++ b/Generator/RotorOpsMission.py @@ -75,7 +75,7 @@ class RotorOpsMission: forces = {} vehicles = [] attack_helos = [] - transp_helos = [] + transport_helos = [] attack_planes = [] fighter_planes = [] @@ -95,7 +95,7 @@ class RotorOpsMission: if helicopter_group.task == 'CAS': attack_helos.append(helicopter_group) elif helicopter_group.task == 'Transport': - transp_helos.append(helicopter_group) + transport_helos.append(helicopter_group) for plane_group in country_obj.plane_group: if plane_group.task == 'CAS': attack_planes.append(plane_group) @@ -104,7 +104,7 @@ class RotorOpsMission: forces["vehicles"] = vehicles forces["attack_helos"] = attack_helos - forces["transp_helos"] = transp_helos + forces["transport_helos"] = transport_helos forces["attack_planes"] = attack_planes forces["fighter_planes"] = fighter_planes @@ -119,13 +119,21 @@ class RotorOpsMission: self.m.load_file(options["scenario_filename"]) - 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 + if not self.m.country("Combined Joint Task Forces Red") or not self.m.country("Combined Joint Task Forces Blue"): + failure_msg = "You must include a CombinedJointTaskForcesBlue and CombinedJointTaskForcesRed 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") blue_forces = self.getUnitsFromMiz(options["blue_forces_filename"], "blue") + # Add coalitions (we may be able to add CJTF here instead of requiring templates to have objects of those coalitions) + self.m.coalition.get("red").add_country(dcs.countries.Russia()) + self.m.coalition.get("blue").add_country(dcs.countries.USA()) + + self.m.add_picture_blue(self.assets_dir + '/briefing1.png') + self.m.add_picture_blue(self.assets_dir + '/briefing2.png') + + # add zones to target mission zone_names = ["ALPHA", "BRAVO", "CHARLIE", "DELTA"] @@ -157,18 +165,18 @@ class RotorOpsMission: #Populate Red zones with ground units for zone_name in red_zones: if red_forces["vehicles"]: - self.addGroundGroups(red_zones[zone_name], self.m.country('Russia'), red_forces["vehicles"], options["red_quantity"]) + self.addGroundGroups(red_zones[zone_name], self.m.country('Combined Joint Task Forces Red'), red_forces["vehicles"], options["red_quantity"]) #Add red FARPS if options["zone_farps"] != "farp_never" and not options["defending"]: - RotorOpsGroups.VehicleTemplate.USA.zone_farp(self.m, self.m.country('USA'), - self.m.country('Russia'), + RotorOpsGroups.VehicleTemplate.CombinedJointTaskForcesBlue.zone_farp(self.m, self.m.country('Combined Joint Task Forces Blue'), + self.m.country('Combined Joint Task Forces Blue'), red_zones[zone_name].position, 180, zone_name + " FARP", late_activation=True) if options["zone_protect_sams"]: self.m.vehicle_group( - self.m.country('Russia'), + self.m.country('Combined Joint Task Forces Red'), "Static " + zone_name + " Protection SAM", random.choice(RotorOpsUnits.e_zone_sams), red_zones[zone_name].position, @@ -182,18 +190,18 @@ class RotorOpsMission: #Populate Blue zones with ground units for zone_name in blue_zones: if blue_forces["vehicles"]: - self.addGroundGroups(blue_zones[zone_name], self.m.country('USA'), blue_forces["vehicles"], + self.addGroundGroups(blue_zones[zone_name], self.m.country('Combined Joint Task Forces Blue'), blue_forces["vehicles"], options["blue_quantity"]) #Add blue FARPS if options["zone_farps"] != "farp_never" and options["defending"]: - RotorOpsGroups.VehicleTemplate.USA.zone_farp(self.m, self.m.country('USA'), - self.m.country('USA'), + RotorOpsGroups.VehicleTemplate.CombinedJointTaskForcesBlue.zone_farp(self.m, self.m.country('Combined Joint Task Forces Blue'), + self.m.country('Combined Joint Task Forces Blue'), blue_zones[zone_name].position, - 180, zone_name + " FARP", late_activation=True) + 180, zone_name + " FARP", late_activation=False) #add logistics sites if options["crates"] and zone_name in self.staging_zones: - RotorOpsGroups.VehicleTemplate.USA.logistics_site(self.m, self.m.country('USA'), + RotorOpsGroups.VehicleTemplate.CombinedJointTaskForcesBlue.logistics_site(self.m, self.m.country('Combined Joint Task Forces Blue'), blue_zones[zone_name].position, 180, zone_name) @@ -203,7 +211,7 @@ class RotorOpsMission: if options["zone_protect_sams"] and options["defending"]: vg = self.m.vehicle_group( - self.m.country('USA'), + self.m.country('Combined Joint Task Forces Blue'), "Static " + zone_name + " Protection SAM", random.choice(RotorOpsUnits.e_zone_sams), blue_zones[zone_name].position, @@ -213,7 +221,6 @@ class RotorOpsMission: ) - #Add player slots self.addPlayerHelos(options) @@ -302,80 +309,81 @@ class RotorOpsMission: for airport in red_airports: self.m.terrain.airports[airport.name].set_blue() - usa = self.m.country("USA") - russia = self.m.country("Russia") + combinedJointTaskForcesBlue = self.m.country("Combined Joint Task Forces Blue") + combinedJointTaskForcesRed = self.m.country("Combined Joint Task Forces Red") #Swap ships - blue_ships = usa.ship_group.copy() - red_ships = russia.ship_group.copy() + blue_ships = combinedJointTaskForcesBlue.ship_group.copy() + red_ships = combinedJointTaskForcesRed.ship_group.copy() for group in blue_ships: - russia.add_ship_group(group) - usa.ship_group.remove(group) + group.points[0].tasks.append(dcs.task.OptROE(dcs.task.OptROE.Values.ReturnFire)) + combinedJointTaskForcesRed.add_ship_group(group) + combinedJointTaskForcesBlue.ship_group.remove(group) for group in red_ships: - usa.add_ship_group(group) - russia.ship_group.remove(group) + combinedJointTaskForcesBlue.add_ship_group(group) + combinedJointTaskForcesRed.ship_group.remove(group) #Swap statics - blue_statics = usa.static_group.copy() - red_statics = russia.static_group.copy() + blue_statics = combinedJointTaskForcesBlue.static_group.copy() + red_statics = combinedJointTaskForcesRed.static_group.copy() for group in blue_statics: - usa.static_group.remove(group) - russia.add_static_group(group) + combinedJointTaskForcesBlue.static_group.remove(group) + combinedJointTaskForcesRed.add_static_group(group) for group in red_statics: - russia.static_group.remove(group) - usa.add_static_group(group) + combinedJointTaskForcesRed.static_group.remove(group) + combinedJointTaskForcesBlue.add_static_group(group) #Swap vehicles - blue_vehicles = usa.vehicle_group.copy() - red_vehicles = russia.vehicle_group.copy() + blue_vehicles = combinedJointTaskForcesBlue.vehicle_group.copy() + red_vehicles = combinedJointTaskForcesRed.vehicle_group.copy() for group in blue_vehicles: - usa.vehicle_group.remove(group) - russia.add_vehicle_group(group) + combinedJointTaskForcesBlue.vehicle_group.remove(group) + combinedJointTaskForcesRed.add_vehicle_group(group) for group in red_vehicles: - russia.vehicle_group.remove(group) - usa.add_vehicle_group(group) + combinedJointTaskForcesRed.vehicle_group.remove(group) + combinedJointTaskForcesBlue.add_vehicle_group(group) #Swap planes - blue_planes = usa.plane_group.copy() - red_planes = russia.plane_group.copy() + blue_planes = combinedJointTaskForcesBlue.plane_group.copy() + red_planes = combinedJointTaskForcesRed.plane_group.copy() for group in blue_planes: - usa.plane_group.remove(group) - russia.add_plane_group(group) + combinedJointTaskForcesBlue.plane_group.remove(group) + combinedJointTaskForcesRed.add_plane_group(group) for group in red_planes: - russia.plane_group.remove(group) - usa.add_plane_group(group) + combinedJointTaskForcesRed.plane_group.remove(group) + combinedJointTaskForcesBlue.add_plane_group(group) # Swap helicopters - blue_helos = usa.helicopter_group.copy() - red_helos = russia.helicopter_group.copy() + blue_helos = combinedJointTaskForcesBlue.helicopter_group.copy() + red_helos = combinedJointTaskForcesRed.helicopter_group.copy() for group in blue_helos: - usa.helicopter_group.remove(group) - russia.add_helicopter_group(group) + combinedJointTaskForcesBlue.helicopter_group.remove(group) + combinedJointTaskForcesRed.add_helicopter_group(group) for group in red_helos: - russia.helicopter_group.remove(group) - usa.add_helicopter_group(group) + combinedJointTaskForcesRed.helicopter_group.remove(group) + combinedJointTaskForcesBlue.add_helicopter_group(group) def addPlayerHelos(self, options): @@ -385,13 +393,13 @@ class RotorOpsMission: client_helos = [dcs.helicopters.helicopter_map[helicopter]] #find friendly carriers and farps - carrier = self.m.country("USA").find_ship_group(name="HELO_CARRIER") + carrier = self.m.country("Combined Joint Task Forces Blue").find_ship_group(name="HELO_CARRIER") if not carrier: - carrier = self.m.country("USA").find_ship_group(name="HELO_CARRIER_1") + carrier = self.m.country("Combined Joint Task Forces Blue").find_ship_group(name="HELO_CARRIER_1") - farp = self.m.country("USA").find_static_group("HELO_FARP") + farp = self.m.country("Combined Joint Task Forces Blue").find_static_group("HELO_FARP") if not farp: - farp = self.m.country("USA").find_static_group("HELO_FARP_1") + farp = self.m.country("Combined Joint Task Forces Blue").find_static_group("HELO_FARP_1") friendly_airports, primary_f_airport = self.getCoalitionAirports("blue") @@ -402,10 +410,10 @@ class RotorOpsMission: for helotype in client_helos: if carrier: - fg = self.m.flight_group_from_unit(self.m.country('USA'), "CARRIER " + helotype.id, helotype, carrier, + fg = self.m.flight_group_from_unit(self.m.country('Combined Joint Task Forces Blue'), "CARRIER " + helotype.id, helotype, carrier, dcs.task.CAS, group_size=group_size) elif farp: - fg = self.m.flight_group_from_unit(self.m.country('USA'), "FARP " + helotype.id, helotype, farp, + fg = self.m.flight_group_from_unit(self.m.country('Combined Joint Task Forces Blue'), "FARP " + helotype.id, helotype, farp, dcs.task.CAS, group_size=group_size) #invisible farps need manual unit placement for multiple units @@ -415,7 +423,7 @@ class RotorOpsMission: fg.units[0].position = fg.units[0].position.point_from_heading(heading, 30) heading += 90 else: - fg = self.m.flight_group_from_airport(self.m.country('USA'), primary_f_airport.name + " " + helotype.id, helotype, + fg = self.m.flight_group_from_airport(self.m.country('Combined Joint Task Forces Blue'), primary_f_airport.name + " " + helotype.id, helotype, self.getParking(primary_f_airport, helotype), group_size=group_size) fg.units[0].set_client() fg.load_task_default_loadout(dcs.task.CAS) @@ -445,19 +453,19 @@ class RotorOpsMission: return dcs.mapping.Point(pt1[0], pt1[1]), heading, race_dist def addFlights(self, options, red_forces, blue_forces): - usa = self.m.country(dcs.countries.USA.name) - russia = self.m.country(dcs.countries.Russia.name) + combinedJointTaskForcesBlue = self.m.country(dcs.countries.CombinedJointTaskForcesBlue.name) + combinedJointTaskForcesRed = self.m.country(dcs.countries.CombinedJointTaskForcesRed.name) 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("Russia").find_ship_group(name="HELO_CARRIER") + carrier = self.m.country("Combined Joint Task Forces Red").find_ship_group(name="HELO_CARRIER") if not carrier: - carrier = self.m.country("Russia").find_ship_group(name="HELO_CARRIER_1") + carrier = self.m.country("Combined Joint Task Forces Red").find_ship_group(name="HELO_CARRIER_1") - farp = self.m.country("Russia").find_static_group("HELO_FARP") + farp = self.m.country("Combined Joint Task Forces Red").find_static_group("HELO_FARP") if not farp: - farp = self.m.country("Russia").find_static_group("HELO_FARP_1") + farp = self.m.country("Combined Joint Task Forces Red").find_static_group("HELO_FARP_1") e_airport_heading = dcs.mapping.heading_between_points( friendly_airports[0].position.x, friendly_airports[0].position.y, enemy_airports[0].position.x, primary_e_airport.position.y @@ -467,73 +475,6 @@ class RotorOpsMission: primary_f_airport.position.x, primary_f_airport.position.y, primary_f_airport.position.x, primary_f_airport.position.y ) - center_x, center_y = dcs.mapping.point_from_heading(primary_f_airport.position.x, primary_f_airport.position.y, e_airport_heading - 180, 5000) - center_pt = dcs.mapping.Point(center_x, center_y) - - # add some objects to illustrate the bounds on the map - # RotorOpsGroups.VehicleTemplate.USA.zone_farp(self.m, self.m.country('USA'), self.m.country('Russia'), - # center_pt, 180, "CENTER", late_activation=True) - - # orbit_rect = dcs.mapping.Rectangle( - # int(primary_f_airport.position.x), int(primary_f_airport.position.y - 100 * 1000), int(primary_f_airport.position.x - 100 * 1000), - # int(primary_f_airport.position.y)) - - - # def pointFromHeading(point, heading, distance): - # pos = dcs.mapping.point_from_heading(point.x, point.y, heading, distance) - # return dcs.mapping.Point(pos[0], pos[1]) - - - - # flight_box = [ - # pointFromHeading(center_pt, e_airport_heading - 90, 100000), - # pointFromHeading(center_pt, e_airport_heading - 180, 50000), - # pointFromHeading(center_pt, e_airport_heading + 90, 100000), - # pointFromHeading(center_pt, e_airport_heading + 0, 50000), - # ] - - # flight_box = dcs.mapping.Rectangle( - # dcs.mapping.point_from_heading(center_pt.x, center_pt.y, 0, 50000), - # dcs.mapping.point_from_heading(center_pt.x, center_pt.y, 270, 100000), - # dcs.mapping.point_from_heading(center_pt.x, center_pt.y, 180, 50000), - # dcs.mapping.point_from_heading(center_pt.x, center_pt.y, 90, 10000), - # ) - - # flight_box = dcs.mapping.Rectangle( - # center_pt.y + 5000, - # center_pt.x - 10000, - # center_pt.y - 5000, - # center_pt.x + 10000, - # ) - - - - # for point in flight_box: - # #add some objects to illustrate the bounds on the map - # RotorOpsGroups.VehicleTemplate.USA.zone_farp(self.m, self.m.country('USA'), self.m.country('Russia'), - # point, 180, "CENTER", late_activation=True) - - # flight_box = [ - # dcs.mapping.point_from_heading(center_pt.x, center_pt.y, e_airport_heading - 90, 100000), - # dcs.mapping.point_from_heading(center_pt.x, center_pt.y, e_airport_heading - 180, 50000), - # dcs.mapping.point_from_heading(center_pt.x, center_pt.y, e_airport_heading + 90, 100000), - # dcs.mapping.point_from_heading(center_pt.x, center_pt.y, e_airport_heading + 0, 50000), - # ] - # - # a = int(min(flight_box.top, self.m.terrain.bounds.top)) - # b = int(max(flight_box.left, self.m.terrain.bounds.left)) - # c = int(max(flight_box.bottom, self.m.terrain.bounds.bottom)) - # d = int(min(flight_box.right, self.m.terrain.bounds.right)) - # - # - # orbit_rect = dcs.mapping.Rectangle( - # int(min(flight_box.top, self.m.terrain.bounds.top)), - # int(max(flight_box.left, self.m.terrain.bounds.left)), - # int(max(flight_box.bottom, self.m.terrain.bounds.bottom)), - # int(min(flight_box.right, self.m.terrain.bounds.right)), - # ) - - if options["f_awacs"]: awacs_name = "AWACS" @@ -541,7 +482,7 @@ class RotorOpsMission: #pos, heading, race_dist = self.TrainingScenario.random_orbit(orbit_rect) pos, heading, race_dist = self.TrainingScenario.perpRacetrack(e_airport_heading, primary_f_airport.position) awacs = self.m.awacs_flight( - usa, + combinedJointTaskForcesBlue, awacs_name, plane_type=dcs.planes.E_3A, airport=self.getParking(primary_f_airport, dcs.planes.E_3A, friendly_airports), @@ -549,13 +490,29 @@ class RotorOpsMission: race_distance=race_dist, heading=heading, altitude=random.randrange(4000, 5500, 100), frequency=awacs_freq) + # AWACS Escort flight + source_plane = None + if blue_forces["fighter_planes"]: + source_group = random.choice(blue_forces["fighter_planes"]) + source_plane = source_group.units[0] + plane_type = source_plane.unit_type + else: + plane_type = dcs.countries.CombinedJointTaskForcesBlue.Plane.F_15C + awacs_escort = self.m.escort_flight( - usa, "AWACS Escort", - dcs.countries.USA.Plane.F_15C, - airport=self.getParking(primary_f_airport, dcs.countries.USA.Plane.F_15C, friendly_airports), + combinedJointTaskForcesBlue, "AWACS Escort", + plane_type, + airport=self.getParking(primary_f_airport, plane_type, friendly_airports), group_to_escort=awacs, group_size=2) - awacs_escort.load_loadout(dcs.task.CAP) + + awacs_escort.points[0].tasks.append(dcs.task.OptROE(dcs.task.OptROE.Values.WeaponFree)) + + if source_plane: + for unit in awacs_escort.units: + unit.pylons = source_plane.pylons + unit.livery_id = source_plane.livery_id + #add text to mission briefing with radio freq briefing = self.m.description_text() + "\n\n" + awacs_name + " " + str(awacs_freq) + ".00 " + "\n" @@ -571,7 +528,7 @@ class RotorOpsMission: #pos, heading, race_dist = self.TrainingScenario.random_orbit(orbit_rect) pos, heading, race_dist = self.TrainingScenario.perpRacetrack(e_airport_heading, primary_f_airport.position) refuel_net = self.m.refuel_flight( - usa, + combinedJointTaskForcesBlue, t1_name, dcs.planes.KC130, airport=self.getParking(primary_f_airport, dcs.planes.KC130, friendly_airports), @@ -587,7 +544,7 @@ class RotorOpsMission: #pos, heading, race_dist = self.TrainingScenario.random_orbit(orbit_rect) pos, heading, race_dist = self.TrainingScenario.perpRacetrack(e_airport_heading, primary_f_airport.position) refuel_rod = self.m.refuel_flight( - usa, + combinedJointTaskForcesBlue, t2_name, dcs.planes.KC_135, airport=self.getParking(primary_f_airport, dcs.planes.KC_135, friendly_airports), @@ -603,7 +560,7 @@ class RotorOpsMission: self.m.set_description_text(briefing) def zone_attack(fg, airport): - fg.set_skill(dcs.unit.Skill.Random) + fg.set_skill(dcs.unit.Skill.High) fg.late_activation = True if options["defending"]: @@ -616,6 +573,9 @@ class RotorOpsMission: fg.add_runway_waypoint(airport) if airport: fg.land_at(airport) + fg.points[0].tasks.append(dcs.task.OptReactOnThreat(dcs.task.OptReactOnThreat.Values.EvadeFire)) + fg.points[0].tasks.append(dcs.task.OptROE(dcs.task.OptROE.Values.OpenFire)) + @@ -637,7 +597,7 @@ class RotorOpsMission: if carrier: afg = self.m.flight_group_from_unit( - russia, + combinedJointTaskForcesRed, "Enemy Attack Helicopters", helo_type, carrier, @@ -648,7 +608,7 @@ class RotorOpsMission: elif farp: afg = self.m.flight_group_from_unit( - russia, + combinedJointTaskForcesRed, "Enemy Attack Helicopters", helo_type, farp, @@ -659,7 +619,7 @@ class RotorOpsMission: elif airport: afg = self.m.flight_group_from_airport( - russia, + combinedJointTaskForcesRed, "Enemy Attack Helicopters", helo_type, airport=airport, @@ -675,7 +635,6 @@ class RotorOpsMission: for unit in afg.units: unit.pylons = source_helo.pylons unit.livery_id = source_helo.livery_id - unit.skill = source_helo.skill @@ -695,7 +654,7 @@ class RotorOpsMission: airport = self.getParking(primary_e_airport, plane_type, enemy_airports, group_size) if airport: afg = self.m.flight_group_from_airport( - russia, "Enemy Attack Planes", plane_type, + combinedJointTaskForcesRed, "Enemy Attack Planes", plane_type, airport=airport, maintask=dcs.task.CAS, start_type=dcs.mission.StartType.Cold, @@ -706,22 +665,35 @@ class RotorOpsMission: for unit in afg.units: unit.pylons = source_plane.pylons unit.livery_id = source_plane.livery_id - unit.skill = source_plane.skill if options["e_transport_helos"]: - group_size = 1 - helo_type = dcs.helicopters.Mi_26 + source_helo = None + if red_forces["transport_helos"]: + source_group = random.choice(red_forces["transport_helos"]) + source_helo = source_group.units[0] + helo_type = source_helo.unit_type + group_size = len(source_group.units) + if group_size > 2: + group_size = 2 + else: + group_size = 1 + helo_type = random.choice(RotorOpsUnits.e_transport_helos) + airport = self.getParking(primary_e_airport, helo_type, enemy_airports, group_size) if airport: afg = self.m.flight_group_from_airport( - russia, "Enemy Transport Helicopters", helo_type, + combinedJointTaskForcesRed, "Enemy Transport Helicopters", helo_type, airport=airport, maintask=dcs.task.Transport, start_type=dcs.mission.StartType.Cold, group_size=group_size) afg.late_activation = True + afg.units[0].skill = dcs.unit.Skill.Excellent - + if source_helo: + for unit in afg.units: + unit.pylons = source_helo.pylons + unit.livery_id = source_helo.livery_id def scriptTriggerSetup(self, options): @@ -737,8 +709,8 @@ class RotorOpsMission: 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" + + script = "" + script = ("--OPTIONS HERE!\n\n" + "RotorOps.CTLD_crates = " + lb("crates") + "\n\n" + "RotorOps.CTLD_sound_effects = true\n\n" + "RotorOps.force_offroad = " + lb("force_offroad") + "\n\n" + @@ -746,7 +718,10 @@ class RotorOpsMission: "RotorOps.zone_status_display = " + lb("game_display") + "\n\n" + "RotorOps.inf_spawn_messages = " + lb("inf_spawn_msgs") + "\n\n" + "RotorOps.inf_spawns_per_zone = " + lb("inf_spawn_qty") + "\n\n" + - "RotorOps.apcs_spawn_infantry = " + lb("apc_spawns_inf") + " \n\n")))) + "RotorOps.apcs_spawn_infantry = " + lb("apc_spawns_inf") + " \n\n") + if not options["smoke_pickup_zones"]: + script = script + 'RotorOps.pickup_zone_smoke = "none"\n\n' + trig.actions.append(dcs.action.DoScript(dcs.action.String((script)))) self.m.triggerrules.triggers.append(trig) #Add the second trigger @@ -783,15 +758,15 @@ class RotorOpsMission: self.m.triggerrules.triggers.append(z_sams_trig) #Zone FARPS always - if options["zone_farps"] == "farp_always" and not options["defending"] and index > 0: + if options["zone_farps"] == "farp_always" and not options["defending"]: 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 Static"): + if not self.m.country("Combined Joint Task Forces Blue").find_group(previous_zone + " FARP Static"): 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 Static").id)) + z_farps_trig.actions.append(dcs.action.ActivateGroup(self.m.country("Combined Joint Task Forces Blue").find_group(previous_zone + " FARP Static").id)) #z_farps_trig.actions.append(dcs.action.SoundToAll(str(self.res_map['forward_base_established.ogg']))) z_farps_trig.actions.append(dcs.action.DoScript(dcs.action.String( "RotorOps.farpEstablished(" + str(index) + ")"))) @@ -799,18 +774,18 @@ class RotorOpsMission: #Zone FARPS conditional on staged units remaining - if options["zone_farps"] == "farp_gunits": + if options["zone_farps"] == "farp_gunits" and not options["defending"]: 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 Static"): + if not self.m.country("Combined Joint Task Forces Blue").find_group(previous_zone + " FARP Static"): 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 Static").id)) + dcs.action.ActivateGroup(self.m.country("Combined Joint Task Forces Blue").find_group(previous_zone + " FARP Static").id)) #z_farps_trig.actions.append(dcs.action.SoundToAll(str(self.res_map['forward_base_established.ogg']))) z_farps_trig.actions.append(dcs.action.DoScript(dcs.action.String( "RotorOps.farpEstablished(" + str(index) + ")"))) diff --git a/Generator/RotorOpsUnits.py b/Generator/RotorOpsUnits.py index 8a9700b..4bfda12 100644 --- a/Generator/RotorOpsUnits.py +++ b/Generator/RotorOpsUnits.py @@ -14,9 +14,10 @@ e_attack_helos = [ ] e_transport_helos = [ - dcs.helicopters.Mi_26, - dcs.helicopters.Mi_24P, - dcs.helicopters.Mi_8MT, + #dcs.helicopters.Mi_26, + #dcs.helicopters.Mi_24P, + #dcs.helicopters.Mi_8MT, + dcs.helicopters.CH_47D, ] e_attack_planes = [ diff --git a/Generator/Scenarios/Caucasus Conflict - Batumi to Kobuleti (GRIMM).miz b/Generator/Scenarios/Caucasus Conflict - Batumi to Kobuleti (GRIMM).miz index f44a18e..e3734cf 100644 Binary files a/Generator/Scenarios/Caucasus Conflict - Batumi to Kobuleti (GRIMM).miz and b/Generator/Scenarios/Caucasus Conflict - Batumi to Kobuleti (GRIMM).miz differ diff --git a/Generator/Scenarios/Caucasus Conflict - Nalchik to Beslan (GRIMM).miz b/Generator/Scenarios/Caucasus Conflict - Nalchik to Beslan (GRIMM).miz index d55089b..22aaf14 100644 Binary files a/Generator/Scenarios/Caucasus Conflict - Nalchik to Beslan (GRIMM).miz and b/Generator/Scenarios/Caucasus Conflict - Nalchik to Beslan (GRIMM).miz differ diff --git a/Generator/Scenarios/Mariana Conflict - Anderson to Won Pat (GRIMM).miz b/Generator/Scenarios/Mariana Conflict - Anderson to Won Pat (GRIMM).miz index a1bed71..8f0b814 100644 Binary files a/Generator/Scenarios/Mariana Conflict - Anderson to Won Pat (GRIMM).miz and b/Generator/Scenarios/Mariana Conflict - Anderson to Won Pat (GRIMM).miz differ diff --git a/Generator/Scenarios/Mariana Conflict - Rota Landing (Mr Nobody).miz b/Generator/Scenarios/Mariana Conflict - Rota Landing (Mr Nobody).miz index 9779c30..8d032c6 100644 Binary files a/Generator/Scenarios/Mariana Conflict - Rota Landing (Mr Nobody).miz and b/Generator/Scenarios/Mariana Conflict - Rota Landing (Mr Nobody).miz differ diff --git a/Generator/Scenarios/Nevada Conflict - Vegas Tour (GRIMM).miz b/Generator/Scenarios/Nevada Conflict - Vegas Tour (GRIMM).miz index 38828de..9235775 100644 Binary files a/Generator/Scenarios/Nevada Conflict - Vegas Tour (GRIMM).miz and b/Generator/Scenarios/Nevada Conflict - Vegas Tour (GRIMM).miz differ diff --git a/Generator/Scenarios/PG Conflict - Abu Dhabi to Ras (GRIMM).miz b/Generator/Scenarios/PG Conflict - Abu Dhabi to Ras (GRIMM).miz deleted file mode 100644 index 68638fb..0000000 Binary files a/Generator/Scenarios/PG Conflict - Abu Dhabi to Ras (GRIMM).miz and /dev/null differ diff --git a/Generator/Scenarios/PG Conflict - Dubai Tour (GRIMM).miz b/Generator/Scenarios/PG Conflict - Dubai Tour (GRIMM).miz new file mode 100644 index 0000000..39550a1 Binary files /dev/null and b/Generator/Scenarios/PG Conflict - Dubai Tour (GRIMM).miz differ diff --git a/Generator/Scenarios/Syria Conflict - Aleppo Tour (GRIMM).miz b/Generator/Scenarios/Syria Conflict - Aleppo Tour (GRIMM).miz index 0083bbb..4de763d 100644 Binary files a/Generator/Scenarios/Syria Conflict - Aleppo Tour (GRIMM).miz and b/Generator/Scenarios/Syria Conflict - Aleppo Tour (GRIMM).miz differ diff --git a/Generator/Scenarios/_How to create your own scenarios.txt b/Generator/Scenarios/_How to create your own scenarios.txt index 19fbc86..fa6dbc3 100644 --- a/Generator/Scenarios/_How to create your own scenarios.txt +++ b/Generator/Scenarios/_How to create your own scenarios.txt @@ -17,6 +17,8 @@ Optional: 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. +Testing: +You should test your scenarios to ensure that vehicals move between zones as you expect. In some circumstances, vehicles may not be able to calculate a valid route to the next zone, and they will stop. Make sure they can route correctly by testing your scenario in fast forward, with few defending units. You can also get a good idea as to how long your scenario will take to complete. Tips: @@ -36,3 +38,4 @@ Tips: -Late activation FARPs might be useful for rearming far from the player spawn point. -In "Defense" or with "Swap sides" option, USA and Russia ships, helicopters, planes, and ground units will swap countries. Static objects may not. Test it out. -Turn off or limit civilian road traffic. +-Pay attention to rivers and bridges, as a far away bridge crossing may break routing if it's the only way across. See the testing notes above. diff --git a/Generator/assets/briefing1.png b/Generator/assets/briefing1.png new file mode 100644 index 0000000..2fc2585 Binary files /dev/null and b/Generator/assets/briefing1.png differ diff --git a/Generator/assets/briefing2.png b/Generator/assets/briefing2.png new file mode 100644 index 0000000..e5d661b Binary files /dev/null and b/Generator/assets/briefing2.png differ diff --git a/MissionGenerator.bat b/MissionGenerator.bat deleted file mode 100644 index e35707d..0000000 --- a/MissionGenerator.bat +++ /dev/null @@ -1,4 +0,0 @@ -cd Generator -pip install -r requirements.txt -python MissionGenerator.py -log.txt -cmd /k diff --git a/MissionGenerator.exe b/MissionGenerator.exe index cb34568..0f309bf 100644 Binary files a/MissionGenerator.exe and b/MissionGenerator.exe differ diff --git a/RotorOps.lua b/RotorOps.lua index d0ce876..6e2b9a2 100644 --- a/RotorOps.lua +++ b/RotorOps.lua @@ -3,6 +3,7 @@ RotorOps.version = "1.2.6" local debug = true + ---[[ROTOROPS OPTIONS]]--- --- Protip: change these options from the mission editor rather than changing the script file itself. See documentation on github for details. @@ -15,6 +16,7 @@ RotorOps.max_units_left = 0 --allow clearing the zone when a few units are left RotorOps.force_offroad = false --affects "move_to_zone" tasks only RotorOps.apcs_spawn_infantry = false --apcs will unload troops when arriving to a new zone RotorOps.auto_push = true --should attacking ground units move to the next zone after clearing? +RotorOps.defending_vehicles_disperse = true RotorOps.inf_spawns_avail = 0 --this is the number of infantry group spawn events remaining in the active zone RotorOps.inf_spawn_chance = 25 -- 0-100 the chance of spawning infantry in an active zone spawn zone, per 'assessUnitsInZone' loop (10 seconds) @@ -182,7 +184,7 @@ RotorOps.gameMsgs = { local sound_effects = { - ["troop_pickup"] = {'troops_load_ao.ogg', 'troops_load_ready.ogg', 'troops_load_to_action.ogg',force_offroad = true}, + ["troop_pickup"] = {'troops_load_ao.ogg', 'troops_load_ready.ogg', 'troops_load_to_action.ogg',}, ["troop_dropoff"] = {'troops_unload_thanks.ogg', 'troops_unload_everybody_off.ogg', 'troops_unload_get_off.ogg', 'troops_unload_here_we_go.ogg', 'troops_unload_moving_out.ogg',}, } @@ -246,11 +248,7 @@ function RotorOps.eventHandler:onEvent(event) ---BASE CAPTURE EVENTS --doesn't work with FARPs.. if (world.event.S_EVENT_BASE_CAPTURED == event.id) then - env.info("Base captured") - if (event.initiator:getCoalition() == 2) then - --RotorOps.gameMsg(RotorOps.gameMsgs.farp_established) - env.info("Blue forces captured a base") - end + env.info("Base captured") if (event.place:getCoalition() == 2) then env.info("Blue forces captured a base via place attribute") end @@ -394,6 +392,7 @@ local function processMsgBuffer(vars) if #game_message_buffer > 0 then local message = table.remove(game_message_buffer, 1) trigger.action.outText(message[1], 10, true) + env.info("RotorOps: "..message[1]) if RotorOps.voice_overs then trigger.action.outSound(message[2]) end @@ -476,7 +475,7 @@ function RotorOps.deployTroops(quantity, target_group, announce) local side = "red" if coalition == 2 then side = "blue" end local point = valid_unit:getPoint() - ctld.spawnGroupAtPoint(side, quantity, point, 3000) + ctld.spawnGroupAtPoint(side, quantity, point, 1000) -- voiceover trigger stuff for index, zone in pairs(RotorOps.zones) @@ -883,6 +882,14 @@ function RotorOps.assessUnitsInZone(var) RotorOps.aiTask(group, "clear_zone", RotorOps.active_zone) end end + + for index, group in pairs(RotorOps.ai_defending_vehicle_groups) do + if group then + Group.getByName(group):getController():setOption(AI.Option.Ground.id.DISPERSE_ON_ATTACK , RotorOps.defending_vehicles_disperse) + end + end + + --FIRES ONCE PER ZONE ACTIVATION @@ -1177,7 +1184,8 @@ function RotorOps.setActiveZone(new_index) local staged_groups = RotorOps.groupsFromUnits(RotorOps.staged_units) for index, group in pairs(staged_groups) do - RotorOps.aiTask(group,"move_to_active_zone", RotorOps.zones[RotorOps.active_zone_index].name) --send vehicles to next zone; use move_to_active_zone so units don't get stuck if the active zone moves before they arrive + timer.scheduleFunction(function()RotorOps.aiTask(group,"move_to_active_zone", RotorOps.zones[RotorOps.active_zone_index].name) end, {}, timer.getTime() + index) --add a second between calling aitask + --RotorOps.aiTask(group,"move_to_active_zone", RotorOps.zones[RotorOps.active_zone_index].name) --send vehicles to next zone; use move_to_active_zone so units don't get stuck if the active zone moves before they arrive end @@ -1197,7 +1205,7 @@ function RotorOps.setupCTLD() return end - ctld.Debug = false + --ctld.Debug = false ctld.enableCrates = RotorOps.CTLD_crates ctld.enabledFOBBuilding = false ctld.JTAC_lock = "vehicle" @@ -1233,15 +1241,6 @@ function RotorOps.setupCTLD() {name = "Platoon (24)", inf = 10, mg = 5, at = 6, aa = 3 }, } --- ctld.dropOffZones = { --- { "ALPHA", "none", 1 }, --- { "BRAVO", "none", 1 }, --- { "CHARLIE", "none", 1 }, --- { "DELTA", "none", 1 }, --- } --- --- ctld.transportPilotNames[#ctld.transportPilotNames + 1] = "Enemy Transport Helicopters Pilot #1" --- ctld.transportPilotNames[#ctld.transportPilotNames + 1] = "Enemy Transport Helicopters Pilot #2" end @@ -1272,7 +1271,7 @@ function RotorOps.stagingZone(_name) trigger.action.outText(_name.." trigger zone missing! Check RotorOps setup!", 60) env.warning(_name.." trigger zone missing! Check RotorOps setup!") end - RotorOps.addPickupZone(_name, "blue", -1, "no", 0) + RotorOps.addPickupZone(_name, RotorOps.pickup_zone_smoke, -1, "no", 0) RotorOps.staging_zone = _name end @@ -1381,7 +1380,7 @@ end function RotorOps.farpEstablished(index) - env.info("RotorOps FARP established at"..RotorOps.zones[index].name) + env.info("RotorOps FARP established at "..RotorOps.zones[index].name) timer.scheduleFunction(function()RotorOps.gameMsg(RotorOps.gameMsgs.farp_established, index) end, {}, timer.getTime() + 15) end @@ -1393,7 +1392,7 @@ function RotorOps.getEnemyZones() for index, zone in pairs(RotorOps.zones) do if index <= RotorOps.active_zone_index then - enemy_zones[#enemy_zones + 1] = zone + enemy_zones[#enemy_zones + 1] = zone.name end end @@ -1413,7 +1412,23 @@ end function RotorOps.spawnTranspHelos(troops, max_drops) + local script_string = [[local this_grp = ... + this_grp:getController():setOption(AI.Option.Air.id.REACTION_ON_THREAT , AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE) + this_grp:getController():setOption(AI.Option.Air.id.FLARE_USING , AI.Option.Air.val.FLARE_USING.WHEN_FLYING_NEAR_ENEMIES)]] + local setOptions = { + id = 'WrappedAction', + params = { + action = { + id = 'Script', + params = { + command = script_string, + + }, + }, + }, + } + local dropTroops = { id = 'WrappedAction', params = { @@ -1433,8 +1448,14 @@ function RotorOps.spawnTranspHelos(troops, max_drops) --debugTable(gp) local drop_zones = RotorOps.getEnemyZones() + if RotorOps.defending then + drop_zones = {RotorOps.active_zone} + end gp.route = {points = {}} - gp.route.points[#gp.route.points + 1] = mist.heli.buildWP(initial_point, 'flyover', 80, 400, 'agl') + gp.route.points[1] = mist.heli.buildWP(initial_point, initial, 'flyover', 0, 0, 'agl') + gp.route.points[2] = mist.heli.buildWP(initial_point, initial, 'flyover', 100, 100, 'agl') + gp.route.points[2].task = setOptions + local failsafe = 100 local drop_qty = 0 @@ -1446,7 +1467,7 @@ function RotorOps.spawnTranspHelos(troops, max_drops) local drop_point = mist.getRandomPointInZone(zone_name, 300) if mist.isTerrainValid(drop_point, {'LAND', 'ROAD'}) == true then --if the point looks like a good drop point - gp.route.points[#gp.route.points + 1] = mist.heli.buildWP(zone_point, 'flyover', 80, 400, 'agl') + gp.route.points[#gp.route.points + 1] = mist.heli.buildWP(zone_point, 'flyover', 100, 400, 'agl') gp.route.points[#gp.route.points + 1] = mist.heli.buildWP(zone_point, 'flyover', 20, 200, 'agl') gp.route.points[#gp.route.points + 1] = mist.heli.buildWP(drop_point, 'turning point', 10, 70, 'agl') gp.route.points[#gp.route.points].task = dropTroops @@ -1463,10 +1484,15 @@ function RotorOps.spawnTranspHelos(troops, max_drops) end end - - gp.route.points[#gp.route.points + 1] = mist.heli.buildWP(initial_point, 'flyover', 80, 400, 'agl') + gp.route.points[#gp.route.points + 1] = mist.heli.buildWP(initial_point, 'flyover', 100, 400, 'agl') gp.clone = true - mist.dynAdd(gp) + local new_group_data = mist.dynAdd(gp) --returns a mist group data table + debugTable(new_group_data) +-- local new_group = Group.getByName(new_group_data.groupName) +-- local grp_controller = new_group:getController() --controller for aircraft can be group or unit level +-- grp_controller:setOption(AI.Option.Air.id.REACTION_ON_THREAT , AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE) +-- grp_controller:setOption(AI.Option.Air.id.FLARE_USING , AI.Option.Air.val.FLARE_USING.WHEN_FLYING_NEAR_ENEMIES) + env.info("ROTOROPS: TRANSPORT HELICOPTER DEPARTING WITH "..drop_qty.." PLANNED TROOP DROPS.")