diff --git a/README.md b/README.md index d29644a7..4d51bd19 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ ![GitHub stars](https://img.shields.io/github/stars/khopa/dcs_liberation?style=social) ## About DCS Liberation -DCS Liberation is a [DCS World](https://www.digitalcombatsimulator.com/en/products/world/) turn based single-player semi dynamic campaign. +DCS Liberation is a [DCS World](https://www.digitalcombatsimulator.com/en/products/world/) turn based single-player or co-op dynamic campaign. It is an external program that generates full and complex DCS missions and manage a persistent combat environment. -![Logo](https://imgur.com/B6tvlBJ.png) +![Logo](https://i.imgur.com/4hq0rLq.png) ## Downloads diff --git a/gen/aircraft.py b/gen/aircraft.py index d1e93e37..7c4eac80 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -115,6 +115,11 @@ GERMAN_WW2_CHANNEL = MHz(40) HELICOPTER_CHANNEL = MHz(127) UHF_FALLBACK_CHANNEL = MHz(251) +TARGET_WAYPOINTS = ( + FlightWaypointType.TARGET_GROUP_LOC, + FlightWaypointType.TARGET_POINT, + FlightWaypointType.TARGET_SHIP, + ) # TODO: Get radio information for all the special cases. def get_fallback_channel(unit_type: UnitType) -> RadioFrequency: @@ -1142,12 +1147,28 @@ class AircraftConflictGenerator: flight.from_cp) self.set_takeoff_time(takeoff_point, package, flight, group) - filtered_points = [] + filtered_points = [] # type: List[FlightWaypoint] + for point in flight.points: if point.only_for_player and not flight.client_count: continue filtered_points.append(point) - + # Only add 1 target waypoint for Viggens. This only affects player flights, + # the Viggen can't have more than 9 waypoints which leaves us with two target point + # under the current flight plans. + # TODO: Make this smarter, it currently selects a random unit in the group for target, + # this could be updated to make it pick the "best" two targets in the group. + if flight.unit_type is AJS37 and flight.client_count: + viggen_target_points = [ + (idx, point) for idx, point in enumerate(filtered_points) if point.waypoint_type in TARGET_WAYPOINTS + ] + keep_target = viggen_target_points[random.randint(0, len(viggen_target_points) - 1)] + filtered_points = [ + point for idx, point in enumerate(filtered_points) if ( + point.waypoint_type not in TARGET_WAYPOINTS or idx == keep_target[0] + ) + ] + for idx, point in enumerate(filtered_points): PydcsWaypointBuilder.for_waypoint( point, group, package, flight, self.m @@ -1265,14 +1286,9 @@ class PydcsWaypointBuilder: """Viggen player aircraft consider any waypoint with a TOT set to be a target ("M") waypoint. If the flight is a player controlled Viggen flight, no TOT should be set on any waypoint except actual target waypoints. """ - target_waypoints = ( - FlightWaypointType.TARGET_GROUP_LOC, - FlightWaypointType.TARGET_POINT, - FlightWaypointType.TARGET_SHIP, - ) if ( (self.flight.client_count > 0 and self.flight.unit_type == AJS37) and - (self.waypoint.waypoint_type not in target_waypoints) + (self.waypoint.waypoint_type not in TARGET_WAYPOINTS) ): return True else: @@ -1285,8 +1301,6 @@ class PydcsWaypointBuilder: self.group.add_nav_target_point(t.position, "PP" + str(i + 1)) if self.group.units[0].unit_type == F_14B and i == 0: self.group.add_nav_target_point(t.position, "ST") - if self.group.units[0].unit_type == AJS37 and i < 9: - self.group.add_nav_target_point(t.position, "M" + str(i + 1)) class DefaultWaypointBuilder(PydcsWaypointBuilder): @@ -1387,7 +1401,7 @@ class SeadIngressBuilder(PydcsWaypointBuilder): class StrikeIngressBuilder(PydcsWaypointBuilder): def build(self) -> MovingPoint: - if self.group.units[0].unit_type in [B_17G, A_20G, B_52H, Tu_22M3]: + if self.group.units[0].unit_type in [B_17G, B_52H, Tu_22M3]: return self.build_bombing() else: return self.build_strike() diff --git a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py index 2dbba2f3..a01aaaa9 100644 --- a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py @@ -6,6 +6,7 @@ from PySide2.QtWidgets import ( QGridLayout, QHBoxLayout, QLabel, + QMessageBox, QScrollArea, QVBoxLayout, QWidget, @@ -88,7 +89,21 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): super().buy(unit_type) self.hangar_status.update_label(self.total_units, self.cp.available_aircraft_slots) - def sell(self, unit_type): + def sell(self, unit_type: UnitType): + # Don't need to remove aircraft from the inventory if we're canceling + # orders. + if self.deliveryEvent.units.get(unit_type, 0) <= 0: + global_inventory = self.game_model.game.aircraft_inventory + inventory = global_inventory.for_control_point(self.cp) + try: + inventory.remove_aircraft(unit_type, 1) + except ValueError: + QMessageBox.critical( + self, "Could not sell aircraft", + f"Attempted to sell one {unit_type.id} at {self.cp.name} " + "but none are available. Are all aircraft currently " + "assigned to a mission?", QMessageBox.Ok) + return super().sell(unit_type) self.hangar_status.update_label(self.total_units, self.cp.available_aircraft_slots) diff --git a/qt_ui/windows/mission/flight/QFlightCreator.py b/qt_ui/windows/mission/flight/QFlightCreator.py index 7b9808f7..ee4b3354 100644 --- a/qt_ui/windows/mission/flight/QFlightCreator.py +++ b/qt_ui/windows/mission/flight/QFlightCreator.py @@ -3,6 +3,7 @@ from typing import Optional from PySide2.QtCore import Qt, Signal from PySide2.QtWidgets import ( QDialog, + QMessageBox, QPushButton, QVBoxLayout, ) @@ -95,7 +96,8 @@ class QFlightCreator(QDialog): def create_flight(self) -> None: error = self.verify_form() if error is not None: - self.error_box("Could not create flight", error) + QMessageBox.critical(self, "Could not create flight", error, + QMessageBox.Ok) return task = self.task_selector.currentData() diff --git a/resources/mizdata/persiangulf/Al Ain International Airport.miz b/resources/mizdata/persiangulf/Al Ain International Airport.miz new file mode 100644 index 00000000..810f6349 Binary files /dev/null and b/resources/mizdata/persiangulf/Al Ain International Airport.miz differ diff --git a/resources/mizdata/persiangulf/Fujairah.miz b/resources/mizdata/persiangulf/Fujairah.miz new file mode 100644 index 00000000..a2e48ea8 Binary files /dev/null and b/resources/mizdata/persiangulf/Fujairah.miz differ