From a1886e37f82beb0f6ebab4c2dbe0d7a0d0cec21e Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Sun, 4 Oct 2020 12:48:35 -0700 Subject: [PATCH 1/7] Fix save issues after aborting mission. When the mission is aborted the pending mission is still in the event list, which is part of the game option. That event has a reference to the operation, which in turn contains all the mission generator objects. Two of these objects are the radio/TACAN allocators, which use a generator to track the next free channel. Generators cannot be picked, so because these are transitively part of the game object the game cannot be saved. Aside from the briefing generator, none of those objects are actually needed outside the generation function itself, so just make them locals instead. This probably needs a larger refactor at some point. It doesn't look like we need so many calls into the operation type (it has an initialize, a prepare, and a generate, and it doesn't seem to need anything but the last one). The only reason breifinggen needs to remain a part of the class is because the briefing title and description are filled in from the derived class, where title and description should probably be overridden properties instead. I'm also not sure if we need to make the event list a part of game at all, and also don't think that the mission needs to be one of these events. --- game/operation/operation.py | 98 ++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/game/operation/operation.py b/game/operation/operation.py index c0ce5e67..b23c219e 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -68,26 +68,8 @@ class Operation: def initialize(self, mission: Mission, conflict: Conflict): self.current_mission = mission self.conflict = conflict - self.radio_registry = RadioRegistry() - self.tacan_registry = TacanRegistry() - self.airgen = AircraftConflictGenerator( - mission, conflict, self.game.settings, self.game, - self.radio_registry) - self.airsupportgen = AirSupportConflictGenerator( - mission, conflict, self.game, self.radio_registry, - self.tacan_registry) - self.triggersgen = TriggersGenerator(mission, conflict, self.game) - self.visualgen = VisualGenerator(mission, conflict, self.game) - self.envgen = EnviromentGenerator(mission, conflict, self.game) - self.forcedoptionsgen = ForcedOptionsGenerator(mission, conflict, self.game) - self.groundobjectgen = GroundObjectsGenerator( - mission, - conflict, - self.game, - self.radio_registry, - self.tacan_registry - ) - self.briefinggen = BriefingGenerator(mission, conflict, self.game) + self.briefinggen = BriefingGenerator(self.current_mission, + self.conflict, self.game) def prepare(self, terrain: Terrain, is_quick: bool): with open("resources/default_options.lua", "r") as f: @@ -127,6 +109,9 @@ class Operation: self.defenders_starting_position = self.to_cp.at def generate(self): + radio_registry = RadioRegistry() + tacan_registry = TacanRegistry() + # Dedup beacon/radio frequencies, since some maps have some frequencies # used multiple times. beacons = load_beacons_for_terrain(self.game.theater.terrain.name) @@ -138,7 +123,7 @@ class Operation: logging.error( f"TACAN beacon has no channel: {beacon.callsign}") else: - self.tacan_registry.reserve(beacon.tacan_channel) + tacan_registry.reserve(beacon.tacan_channel) for airfield, data in AIRFIELD_DATA.items(): if data.theater == self.game.theater.terrain.name: @@ -150,16 +135,26 @@ class Operation: # beacon list. for frequency in unique_map_frequencies: - self.radio_registry.reserve(frequency) + radio_registry.reserve(frequency) # Generate meteo + envgen = EnviromentGenerator(self.current_mission, self.conflict, + self.game) if self.environment_settings is None: - self.environment_settings = self.envgen.generate() + self.environment_settings = envgen.generate() else: - self.envgen.load(self.environment_settings) + envgen.load(self.environment_settings) # Generate ground object first - self.groundobjectgen.generate() + + groundobjectgen = GroundObjectsGenerator( + self.current_mission, + self.conflict, + self.game, + radio_registry, + tacan_registry + ) + groundobjectgen.generate() # Generate destroyed units for d in self.game.get_destroyed_units(): @@ -180,11 +175,16 @@ class Operation: dead=True, ) - # Air Support (Tanker & Awacs) - self.airsupportgen.generate(self.is_awacs_enabled) + airsupportgen = AirSupportConflictGenerator( + self.current_mission, self.conflict, self.game, radio_registry, + tacan_registry) + airsupportgen.generate(self.is_awacs_enabled) # Generate Activity on the map + airgen = AircraftConflictGenerator( + self.current_mission, self.conflict, self.game.settings, self.game, + radio_registry) for cp in self.game.theater.controlpoints: side = cp.captured if side: @@ -192,11 +192,11 @@ class Operation: else: country = self.current_mission.country(self.game.enemy_country) if cp.id in self.game.planners.keys(): - self.airgen.generate_flights( + airgen.generate_flights( cp, country, self.game.planners[cp.id], - self.groundobjectgen.runways + groundobjectgen.runways ) # Generate ground units on frontline everywhere @@ -221,18 +221,20 @@ class Operation: self.current_mission.groundControl.red_tactical_commander = self.ca_slots # Triggers - if self.game.is_player_attack(self.conflict.attackers_country): - cp = self.conflict.from_cp - else: - cp = self.conflict.to_cp - self.triggersgen.generate() + triggersgen = TriggersGenerator(self.current_mission, self.conflict, + self.game) + triggersgen.generate() # Options - self.forcedoptionsgen.generate() + forcedoptionsgen = ForcedOptionsGenerator(self.current_mission, + self.conflict, self.game) + forcedoptionsgen.generate() # Generate Visuals Smoke Effects + visualgen = VisualGenerator(self.current_mission, self.conflict, + self.game) if self.game.settings.perf_smoke_gen: - self.visualgen.generate() + visualgen.generate() # Inject Plugins Lua Scripts listOfPluginsScripts = [] @@ -327,19 +329,20 @@ class Operation: trigger.add_action(DoScript(String(lua))) self.current_mission.triggerrules.triggers.append(trigger) - self.assign_channels_to_flights() + self.assign_channels_to_flights(airgen.flights, + airsupportgen.air_support) kneeboard_generator = KneeboardGenerator(self.current_mission) - for dynamic_runway in self.groundobjectgen.runways.values(): + for dynamic_runway in groundobjectgen.runways.values(): self.briefinggen.add_dynamic_runway(dynamic_runway) - for tanker in self.airsupportgen.air_support.tankers: + for tanker in airsupportgen.air_support.tankers: self.briefinggen.add_tanker(tanker) kneeboard_generator.add_tanker(tanker) if self.is_awacs_enabled: - for awacs in self.airsupportgen.air_support.awacs: + for awacs in airsupportgen.air_support.awacs: self.briefinggen.add_awacs(awacs) kneeboard_generator.add_awacs(awacs) @@ -347,21 +350,23 @@ class Operation: self.briefinggen.add_jtac(jtac) kneeboard_generator.add_jtac(jtac) - for flight in self.airgen.flights: + for flight in airgen.flights: self.briefinggen.add_flight(flight) kneeboard_generator.add_flight(flight) self.briefinggen.generate() kneeboard_generator.generate() - def assign_channels_to_flights(self) -> None: + def assign_channels_to_flights(self, flights: List[FlightData], + air_support: AirSupport) -> None: """Assigns preset radio channels for client flights.""" - for flight in self.airgen.flights: + for flight in flights: if not flight.client_units: continue - self.assign_channels_to_flight(flight) + self.assign_channels_to_flight(flight, air_support) - def assign_channels_to_flight(self, flight: FlightData) -> None: + def assign_channels_to_flight(self, flight: FlightData, + air_support: AirSupport) -> None: """Assigns preset radio channels for a client flight.""" airframe = flight.aircraft_type @@ -372,4 +377,5 @@ class Operation: return aircraft_data.channel_allocator.assign_channels_for_flight( - flight, self.airsupportgen.air_support) + flight, air_support + ) From f5c32c6b98192829a354ee47ea7660d7e07a3a4e Mon Sep 17 00:00:00 2001 From: Khopa Date: Mon, 5 Oct 2020 19:26:07 +0200 Subject: [PATCH 2/7] Version 2.1.5 --- changelog.md | 5 +++++ qt_ui/uiconstants.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 59a20d76..11eef5d0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,8 @@ +# 2.1.5 + +## Fixes : +* **[UI]** Fixed an issue that prevent saving after aborting a mission + # 2.1.4 ## Fixes : diff --git a/qt_ui/uiconstants.py b/qt_ui/uiconstants.py index 30f61ef1..1c6e84bc 100644 --- a/qt_ui/uiconstants.py +++ b/qt_ui/uiconstants.py @@ -8,7 +8,7 @@ from game.event import UnitsDeliveryEvent, FrontlineAttackEvent from theater.theatergroundobject import CATEGORY_MAP from userdata.liberation_theme import get_theme_icons -VERSION_STRING = "2.1.4" +VERSION_STRING = "2.1.5" URLS : Dict[str, str] = { "Manual": "https://github.com/khopa/dcs_liberation/wiki", From c41ecb6735118af57f5ac0277b450d0946f3a9cd Mon Sep 17 00:00:00 2001 From: Khopa Date: Sun, 4 Oct 2020 14:27:13 +0200 Subject: [PATCH 3/7] Fix aircrafts landing point --- gen/aircraft.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gen/aircraft.py b/gen/aircraft.py index ec5dec26..fb485e0a 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -952,6 +952,7 @@ class AircraftConflictGenerator: # pt.tasks.append(engagetgt) elif point.waypoint_type == FlightWaypointType.LANDING_POINT: pt.type = "Land" + pt.action = PointAction.Landing elif point.waypoint_type == FlightWaypointType.INGRESS_STRIKE: if group.units[0].unit_type == B_17G: From 262ba6c113c4e83e86a9b635a13b07f6cffb3b14 Mon Sep 17 00:00:00 2001 From: Khopa Date: Mon, 5 Oct 2020 19:28:55 +0200 Subject: [PATCH 4/7] Chery picked another fix for this release, so updated changelog --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 11eef5d0..918abd4d 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,7 @@ ## Fixes : * **[UI]** Fixed an issue that prevent saving after aborting a mission +* **[Mission Generator]** Fixed aircraft landing point type being wrong # 2.1.4 From efbc6fe3ae0585e4766047782ffed4131cc373bc Mon Sep 17 00:00:00 2001 From: Khopa Date: Sat, 3 Oct 2020 16:18:12 +0200 Subject: [PATCH 5/7] Enable EPLRS for ground units that can use it. --- gen/armor.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gen/armor.py b/gen/armor.py index 5042149f..10a54b4b 100644 --- a/gen/armor.py +++ b/gen/armor.py @@ -183,6 +183,11 @@ class GroundConflictGenerator: return for dcs_group, group in ally_groups: + + if hasattr(group.unit_type, 'eplrs'): + if group.unit_type.eplrs: + group.points[0].tasks.append(EPLRS(group.id)) + if group.role == CombatGroupRole.ARTILLERY: # Fire on any ennemy in range if self.game.settings.perf_artillery: From 819d7752825f440bc87145fbc2bfadd2f7dc5e0e Mon Sep 17 00:00:00 2001 From: Khopa Date: Sun, 4 Oct 2020 14:11:28 +0200 Subject: [PATCH 6/7] EPLRS for 2.1.5 --- gen/groundobjectsgen.py | 4 +++ pydcs_extensions/frenchpack/frenchpack.py | 42 +++++++++++------------ 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/gen/groundobjectsgen.py b/gen/groundobjectsgen.py index d1cd5378..ddf2706e 100644 --- a/gen/groundobjectsgen.py +++ b/gen/groundobjectsgen.py @@ -80,6 +80,10 @@ class GroundObjectsGenerator: vehicle.heading = u.heading vehicle.player_can_drive = True vg.add_unit(vehicle) + + if hasattr(utype, 'eplrs'): + if utype.eplrs: + vg.points[0].tasks.append(EPLRS(vg.id)) else: vg = self.m.ship_group(side, g.name, utype, position=g.position, heading=g.units[0].heading) diff --git a/pydcs_extensions/frenchpack/frenchpack.py b/pydcs_extensions/frenchpack/frenchpack.py index 12d51827..2d5f5433 100644 --- a/pydcs_extensions/frenchpack/frenchpack.py +++ b/pydcs_extensions/frenchpack/frenchpack.py @@ -25,7 +25,7 @@ class ERC_90(unittype.VehicleType): detection_range = 0 threat_range = 4000 air_weapon_dist = 4000 - eprls = True + eplrs = True class VAB__50(unittype.VehicleType): @@ -34,7 +34,7 @@ class VAB__50(unittype.VehicleType): detection_range = 0 threat_range = 1200 air_weapon_dist = 1200 - eprls = True + eplrs = True class VAB_T20_13(unittype.VehicleType): @@ -43,7 +43,7 @@ class VAB_T20_13(unittype.VehicleType): detection_range = 0 threat_range = 2000 air_weapon_dist = 2000 - eprls = True + eplrs = True class VAB_MEPHISTO(unittype.VehicleType): @@ -52,7 +52,7 @@ class VAB_MEPHISTO(unittype.VehicleType): detection_range = 0 threat_range = 4000 air_weapon_dist = 4000 - eprls = True + eplrs = True class VBL__50(unittype.VehicleType): @@ -61,7 +61,7 @@ class VBL__50(unittype.VehicleType): detection_range = 0 threat_range = 1200 air_weapon_dist = 1200 - eprls = True + eplrs = True class VBL_AANF1(unittype.VehicleType): @@ -70,7 +70,7 @@ class VBL_AANF1(unittype.VehicleType): detection_range = 0 threat_range = 1000 air_weapon_dist = 1000 - eprls = True + eplrs = True class VBAE_CRAB(unittype.VehicleType): @@ -79,7 +79,7 @@ class VBAE_CRAB(unittype.VehicleType): detection_range = 0 threat_range = 3500 air_weapon_dist = 3500 - eprls = True + eplrs = True class VBAE_CRAB_MMP(unittype.VehicleType): @@ -88,7 +88,7 @@ class VBAE_CRAB_MMP(unittype.VehicleType): detection_range = 0 threat_range = 3500 air_weapon_dist = 3500 - eprls = True + eplrs = True class AMX_30B2(unittype.VehicleType): @@ -121,7 +121,7 @@ class DIM__TOYOTA_BLUE(unittype.VehicleType): detection_range = 0 threat_range = 1200 air_weapon_dist = 1200 - eprls = True + eplrs = True class DIM__TOYOTA_GREEN(unittype.VehicleType): @@ -130,7 +130,7 @@ class DIM__TOYOTA_GREEN(unittype.VehicleType): detection_range = 0 threat_range = 1200 air_weapon_dist = 1200 - eprls = True + eplrs = True class DIM__TOYOTA_DESERT(unittype.VehicleType): @@ -139,7 +139,7 @@ class DIM__TOYOTA_DESERT(unittype.VehicleType): detection_range = 0 threat_range = 1200 air_weapon_dist = 1200 - eprls = True + eplrs = True class DIM__KAMIKAZE(unittype.VehicleType): @@ -148,7 +148,7 @@ class DIM__KAMIKAZE(unittype.VehicleType): detection_range = 0 threat_range = 50 air_weapon_dist = 50 - eprls = True + eplrs = True ## FORTIFICATION @@ -187,7 +187,7 @@ class TRM_2000(unittype.VehicleType): detection_range = 3500 threat_range = 0 air_weapon_dist = 0 - eprls = True + eplrs = True class TRM_2000_Fuel(unittype.VehicleType): id = "TRM2000_Citerne" @@ -195,7 +195,7 @@ class TRM_2000_Fuel(unittype.VehicleType): detection_range = 3500 threat_range = 0 air_weapon_dist = 0 - eprls = True + eplrs = True class VAB_MEDICAL(unittype.VehicleType): id = "VABH" @@ -203,7 +203,7 @@ class VAB_MEDICAL(unittype.VehicleType): detection_range = 0 threat_range = 0 air_weapon_dist = 0 - eprls = True + eplrs = True class VAB(unittype.VehicleType): id = "VAB_RADIO" @@ -211,7 +211,7 @@ class VAB(unittype.VehicleType): detection_range = 0 threat_range = 0 air_weapon_dist = 0 - eprls = True + eplrs = True class VBL(unittype.VehicleType): id = "VBL-Radio" @@ -219,7 +219,7 @@ class VBL(unittype.VehicleType): detection_range = 0 threat_range = 0 air_weapon_dist = 0 - eprls = True + eplrs = True class Tracma_TD_1500(unittype.VehicleType): id = "Tracma" @@ -236,7 +236,7 @@ class SMOKE_SAM_IR(unittype.VehicleType): detection_range = 20000 threat_range = 20000 air_weapon_dist = 20000 - eprls = True + eplrs = True class _53T2(unittype.VehicleType): id = "AA20" @@ -251,7 +251,7 @@ class TRM_2000_53T2(unittype.VehicleType): detection_range = 6000 threat_range = 2000 air_weapon_dist = 2000 - eprls = True + eplrs = True class TRM_2000_PAMELA(unittype.VehicleType): id = "TRMMISTRAL" @@ -259,7 +259,7 @@ class TRM_2000_PAMELA(unittype.VehicleType): detection_range = 8000 threat_range = 10000 air_weapon_dist = 10000 - eprls = True + eplrs = True ## INFANTRY @@ -285,4 +285,4 @@ class VAB_MORTIER(unittype.VehicleType): detection_range = 0 threat_range = 15000 air_weapon_dist = 15000 - eprls = True \ No newline at end of file + eplrs = True \ No newline at end of file From 2a3bf9821b2c26c0c76e50c569e35e5a37aa34e4 Mon Sep 17 00:00:00 2001 From: Khopa Date: Mon, 5 Oct 2020 19:33:48 +0200 Subject: [PATCH 7/7] Fixed EPLRS cherry pick merge. --- changelog.md | 3 +++ gen/armor.py | 6 +++--- pydcs | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index 918abd4d..e2c69706 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,8 @@ # 2.1.5 +## Features/Improvements : +* **[Units/Factions]** Enabled EPLRS for ground units that supports it (so they appear on A-10C II TAD and Helmet) + ## Fixes : * **[UI]** Fixed an issue that prevent saving after aborting a mission * **[Mission Generator]** Fixed aircraft landing point type being wrong diff --git a/gen/armor.py b/gen/armor.py index 10a54b4b..463d7571 100644 --- a/gen/armor.py +++ b/gen/armor.py @@ -184,9 +184,9 @@ class GroundConflictGenerator: for dcs_group, group in ally_groups: - if hasattr(group.unit_type, 'eplrs'): - if group.unit_type.eplrs: - group.points[0].tasks.append(EPLRS(group.id)) + if hasattr(group.units[0], 'eplrs'): + if group.units[0].eplrs: + dcs_group.points[0].tasks.append(EPLRS(dcs_group.id)) if group.role == CombatGroupRole.ARTILLERY: # Fire on any ennemy in range diff --git a/pydcs b/pydcs index ceea62a8..c203e5a1 160000 --- a/pydcs +++ b/pydcs @@ -1 +1 @@ -Subproject commit ceea62a8e0731c21b3e1a3e90682aa0affc168f1 +Subproject commit c203e5a1b8d5eb42d559dab074e668bf37fa5158