From aa7825d4aabf7671dd59e33358c1641d370ab447 Mon Sep 17 00:00:00 2001 From: walterroach <37820425+walterroach@users.noreply.github.com> Date: Mon, 28 Dec 2020 09:27:33 -0600 Subject: [PATCH 1/6] Reproducible unit naming Splits infantry and other unit IDs. Resets IDs to start from zero at each press of "Takeoff" Direct access to the the `Game` class IDs is done on the `Operation` class to preserve save compat --- game/operation/operation.py | 19 ++++++++++++++----- gen/naming.py | 9 +++++++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/game/operation/operation.py b/game/operation/operation.py index ec2a086a..c9f45f27 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -26,12 +26,12 @@ from gen.environmentgen import EnvironmentGenerator from gen.forcedoptionsgen import ForcedOptionsGenerator from gen.groundobjectsgen import GroundObjectsGenerator from gen.kneeboard import KneeboardGenerator +from gen.naming import namegen from gen.radios import RadioFrequency, RadioRegistry from gen.tacan import TacanRegistry from gen.triggergen import TRIGGER_RADIUS_MEDIUM, TriggersGenerator from .. import db -from ..debriefing import Debriefing from ..theater import Airfield from ..unitmap import UnitMap @@ -69,6 +69,7 @@ class Operation: options_dict = loads(f.read())["options"] cls._set_mission(Mission(game.theater.terrain)) cls.game = game + cls.reset_naming_ids() cls._setup_mission_coalitions() cls.current_mission.options.load_from_dict(options_dict) @@ -86,7 +87,7 @@ class Operation: cls.game.enemy_country, frontline.position ) - + @classmethod def air_conflict(cls) -> Conflict: assert cls.game @@ -103,7 +104,7 @@ class Operation: cls.game.enemy_name, cls.game.player_country, cls.game.enemy_country, - mid_point + mid_point ) @classmethod @@ -295,7 +296,7 @@ class Operation: heading=d["orientation"], dead=True, ) - + @classmethod def generate(cls) -> UnitMap: """Build the final Mission to be exported""" @@ -349,7 +350,6 @@ class Operation: cls.jtacs, cls.airgen ) - return cls.unit_map @classmethod @@ -411,6 +411,15 @@ class Operation: ground_conflict_gen.generate() cls.jtacs.extend(ground_conflict_gen.jtacs) + @classmethod + def reset_naming_ids(cls): + if not cls.game: + logging.warning("Game object not initialized before resetting IDs") + return + cls.game.current_group_id = 0 + cls.game.current_unit_id = 0 + namegen.reset_numbers() + @classmethod def generate_lua(cls, airgen: AircraftConflictGenerator, airsupportgen: AirSupportConflictGenerator, diff --git a/gen/naming.py b/gen/naming.py index 40da3a6b..812acad4 100644 --- a/gen/naming.py +++ b/gen/naming.py @@ -9,6 +9,7 @@ ALPHA_MILITARY = ["Alpha","Bravo","Charlie","Delta","Echo","Foxtrot", class NameGenerator: number = 0 + infantry_number = 0 ANIMALS = [ "SHARK", "TORTOISE", "BAT", "PANGOLIN", "AARDWOLF", @@ -45,14 +46,18 @@ class NameGenerator: def reset(self): self.number = 0 self.ANIMALS = NameGenerator.ANIMALS.copy() + + def reset_numbers(self): + self.number = 0 + self.infantry_number = 0 def next_unit_name(self, country, parent_base_id, unit_type): self.number += 1 return "unit|{}|{}|{}|{}|".format(country.id, self.number, parent_base_id, db.unit_type_name(unit_type)) def next_infantry_name(self, country, parent_base_id, unit_type): - self.number += 1 - return "infantry|{}|{}|{}|{}|".format(country.id, self.number, parent_base_id, db.unit_type_name(unit_type)) + self.infantry_number += 1 + return "infantry|{}|{}|{}|{}|".format(country.id, self.infantry_number, parent_base_id, db.unit_type_name(unit_type)) def next_basedefense_name(self): return "basedefense_aa|0|0|" From 9fd5c6f230fab733576b5794a63d3c366615ee61 Mon Sep 17 00:00:00 2001 From: walterroach <37820425+walterroach@users.noreply.github.com> Date: Mon, 28 Dec 2020 09:51:37 -0600 Subject: [PATCH 2/6] Add package info to aircraft names Makes it easier to identify aircraft for client flights --- gen/aircraft.py | 10 +++++----- gen/naming.py | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/gen/aircraft.py b/gen/aircraft.py index 788b969d..c9b46436 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -1039,14 +1039,14 @@ class AircraftConflictGenerator: try: if flight.start_type == "In Flight": group = self._generate_inflight( - name=namegen.next_unit_name(country, cp.id, flight.unit_type), + name=namegen.next_aircraft_name(country, cp.id, flight), side=country, flight=flight, origin=cp) elif isinstance(cp, NavalControlPoint): group_name = cp.get_carrier_group_name() group = self._generate_at_group( - name=namegen.next_unit_name(country, cp.id, flight.unit_type), + name=namegen.next_aircraft_name(country, cp.id, flight), side=country, unit_type=flight.unit_type, count=flight.count, @@ -1057,8 +1057,8 @@ class AircraftConflictGenerator: raise RuntimeError( f"Attempted to spawn at airfield for non-airfield {cp}") group = self._generate_at_airport( - name=namegen.next_unit_name(country, cp.id, - flight.unit_type), + name=namegen.next_aircraft_name(country, cp.id, + flight), side=country, unit_type=flight.unit_type, count=flight.count, @@ -1070,7 +1070,7 @@ class AircraftConflictGenerator: logging.warning("No room on runway or parking slots. Starting from the air.") flight.start_type = "In Flight" group = self._generate_inflight( - name=namegen.next_unit_name(country, cp.id, flight.unit_type), + name=namegen.next_aircraft_name(country, cp.id, flight), side=country, flight=flight, origin=cp) diff --git a/gen/naming.py b/gen/naming.py index 812acad4..2928b17d 100644 --- a/gen/naming.py +++ b/gen/naming.py @@ -1,4 +1,5 @@ from game import db +from gen.flights.flight import Flight import random ALPHA_MILITARY = ["Alpha","Bravo","Charlie","Delta","Echo","Foxtrot", @@ -51,6 +52,11 @@ class NameGenerator: self.number = 0 self.infantry_number = 0 + def next_aircraft_name(self, country: int, parent_base_id: int, flight: Flight): + self.number += 1 + name_str = "{} {}".format(flight.package.target.name, flight.flight_type) + return "{}|{}|{}|{}|{}|".format(name_str, country.id, self.number, parent_base_id, db.unit_type_name(flight.unit_type)) + def next_unit_name(self, country, parent_base_id, unit_type): self.number += 1 return "unit|{}|{}|{}|{}|".format(country.id, self.number, parent_base_id, db.unit_type_name(unit_type)) From d7e48662e02591f9d72dac3f185fa83543e606c9 Mon Sep 17 00:00:00 2001 From: walterroach <37820425+walterroach@users.noreply.github.com> Date: Mon, 28 Dec 2020 10:52:25 -0600 Subject: [PATCH 3/6] Add custom flight names Mildly breaks save compat with 2.3; All existing flight dialogs will be broken, passing the turn or recreating all the flights in the UI will allow you to continue --- gen/armor.py | 6 +-- gen/flights/flight.py | 6 ++- gen/naming.py | 47 ++++++++++++------- qt_ui/widgets/ato.py | 2 +- .../windows/mission/flight/QFlightCreator.py | 16 ++++++- .../mission/flight/settings/QCustomName.py | 16 +++++++ .../settings/QGeneralFlightSettingsTab.py | 6 ++- 7 files changed, 74 insertions(+), 25 deletions(-) create mode 100644 qt_ui/windows/mission/flight/settings/QCustomName.py diff --git a/gen/armor.py b/gen/armor.py index e6b73e54..9cc0c090 100644 --- a/gen/armor.py +++ b/gen/armor.py @@ -206,7 +206,7 @@ class GroundConflictGenerator: u = random.choice(manpads) self.mission.vehicle_group( side, - namegen.next_infantry_name(side, cp, u), u, + namegen.next_infantry_name(side, cp.id, u), u, position=infantry_position, group_size=1, heading=forward_heading, @@ -220,7 +220,7 @@ class GroundConflictGenerator: u = random.choice(possible_infantry_units) self.mission.vehicle_group( side, - namegen.next_infantry_name(side, cp, u), u, + namegen.next_infantry_name(side, cp.id, u), u, position=infantry_position, group_size=1, heading=forward_heading, @@ -231,7 +231,7 @@ class GroundConflictGenerator: position = infantry_position.random_point_within(55, 5) self.mission.vehicle_group( side, - namegen.next_infantry_name(side, cp, u), u, + namegen.next_infantry_name(side, cp.id, u), u, position=position, group_size=1, heading=forward_heading, diff --git a/gen/flights/flight.py b/gen/flights/flight.py index 9b659c5f..0b784025 100644 --- a/gen/flights/flight.py +++ b/gen/flights/flight.py @@ -137,7 +137,8 @@ class Flight: def __init__(self, package: Package, unit_type: Type[FlyingType], count: int, flight_type: FlightType, start_type: str, departure: ControlPoint, arrival: ControlPoint, - divert: Optional[ControlPoint]) -> None: + divert: Optional[ControlPoint], + custom_name: Optional[str] = None) -> None: self.package = package self.unit_type = unit_type self.count = count @@ -151,6 +152,7 @@ class Flight: self.start_type = start_type self.use_custom_loadout = False self.client_count = 0 + self.custom_name = custom_name # Will be replaced with a more appropriate FlightPlan by # FlightPlanBuilder, but an empty flight plan the flight begins with an @@ -172,4 +174,6 @@ class Flight: def __repr__(self): name = db.unit_type_name(self.unit_type) + if self.custom_name: + return f"{self.custom_name} {self.count} x {name}" return f"[{self.flight_type}] {self.count} x {name}" diff --git a/gen/naming.py b/gen/naming.py index 2928b17d..e79223a0 100644 --- a/gen/naming.py +++ b/gen/naming.py @@ -1,12 +1,18 @@ -from game import db -from gen.flights.flight import Flight import random -ALPHA_MILITARY = ["Alpha","Bravo","Charlie","Delta","Echo","Foxtrot", - "Golf","Hotel","India","Juliet","Kilo","Lima","Mike", - "November","Oscar","Papa","Quebec","Romeo","Sierra", - "Tango","Uniform","Victor","Whisky","XRay","Yankee", - "Zulu","Zero"] +from dcs.country import Country +from dcs.unittype import UnitType + +from game import db + +from gen.flights.flight import Flight + +ALPHA_MILITARY = ["Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", + "Golf", "Hotel", "India", "Juliet", "Kilo", "Lima", "Mike", + "November", "Oscar", "Papa", "Quebec", "Romeo", "Sierra", + "Tango", "Uniform", "Victor", "Whisky", "XRay", "Yankee", + "Zulu", "Zero"] + class NameGenerator: number = 0 @@ -47,36 +53,44 @@ class NameGenerator: def reset(self): self.number = 0 self.ANIMALS = NameGenerator.ANIMALS.copy() - + def reset_numbers(self): self.number = 0 self.infantry_number = 0 - def next_aircraft_name(self, country: int, parent_base_id: int, flight: Flight): + def next_aircraft_name(self, country: Country, parent_base_id: int, flight: Flight): self.number += 1 - name_str = "{} {}".format(flight.package.target.name, flight.flight_type) + try: + if flight.custom_name: + name_str = flight.custom_name + else: + name_str = "{} {}".format( + flight.package.target.name, flight.flight_type) + except AttributeError: # Here to maintain save compatibility with 2.3 + name_str = "{} {}".format( + flight.package.target.name, flight.flight_type) return "{}|{}|{}|{}|{}|".format(name_str, country.id, self.number, parent_base_id, db.unit_type_name(flight.unit_type)) - def next_unit_name(self, country, parent_base_id, unit_type): + def next_unit_name(self, country: Country, parent_base_id: int, unit_type: UnitType): self.number += 1 return "unit|{}|{}|{}|{}|".format(country.id, self.number, parent_base_id, db.unit_type_name(unit_type)) - def next_infantry_name(self, country, parent_base_id, unit_type): + def next_infantry_name(self, country: Country, parent_base_id: int, unit_type: UnitType): self.infantry_number += 1 return "infantry|{}|{}|{}|{}|".format(country.id, self.infantry_number, parent_base_id, db.unit_type_name(unit_type)) def next_basedefense_name(self): return "basedefense_aa|0|0|" - def next_awacs_name(self, country): + def next_awacs_name(self, country: Country): self.number += 1 return "awacs|{}|{}|0|".format(country.id, self.number) - def next_tanker_name(self, country, unit_type): + def next_tanker_name(self, country: Country, unit_type: UnitType): self.number += 1 return "tanker|{}|{}|0|{}".format(country.id, self.number, db.unit_type_name(unit_type)) - def next_carrier_name(self, country): + def next_carrier_name(self, country: Country): self.number += 1 return "carrier|{}|{}|0|".format(country.id, self.number) @@ -90,6 +104,3 @@ class NameGenerator: namegen = NameGenerator() - - - diff --git a/qt_ui/widgets/ato.py b/qt_ui/widgets/ato.py index c4c38e22..11cff960 100644 --- a/qt_ui/widgets/ato.py +++ b/qt_ui/widgets/ato.py @@ -65,7 +65,7 @@ class FlightDelegate(QStyledItemDelegate): name = db.unit_type_name(flight.unit_type) estimator = TotEstimator(self.package) delay = estimator.mission_start_time(flight) - return f"[{task}] {count} x {name} in {delay}" + return f"{flight} in {delay}" def second_row_text(self, index: QModelIndex) -> str: flight = self.flight(index) diff --git a/qt_ui/windows/mission/flight/QFlightCreator.py b/qt_ui/windows/mission/flight/QFlightCreator.py index 0e0bf773..8066754f 100644 --- a/qt_ui/windows/mission/flight/QFlightCreator.py +++ b/qt_ui/windows/mission/flight/QFlightCreator.py @@ -1,3 +1,4 @@ +from re import L from typing import Optional from PySide2.QtCore import Qt, Signal @@ -6,6 +7,7 @@ from PySide2.QtWidgets import ( QMessageBox, QPushButton, QVBoxLayout, + QLineEdit, ) from dcs.planes import PlaneType @@ -31,6 +33,7 @@ class QFlightCreator(QDialog): self.game = game self.package = package + self.custom_name_text = None self.setWindowTitle("Create flight") self.setWindowIcon(EVENT_ICONS["strike"]) @@ -88,6 +91,12 @@ class QFlightCreator(QDialog): layout.addLayout( QLabeledWidget("Client Slots:", self.client_slots_spinner)) + self.custom_name = QLineEdit() + self.custom_name.textChanged.connect(self.set_custom_name_text) + layout.addLayout( + QLabeledWidget("Custom Flight Name (Optional)", self.custom_name) + ) + layout.addStretch() self.create_button = QPushButton("Create") @@ -96,6 +105,9 @@ class QFlightCreator(QDialog): self.setLayout(layout) + def set_custom_name_text(self, text: str): + self.custom_name_text = text + def verify_form(self) -> Optional[str]: aircraft: PlaneType = self.aircraft_selector.currentData() origin: ControlPoint = self.departure.currentData() @@ -115,6 +127,8 @@ class QFlightCreator(QDialog): return f"{origin.name} has only {available} {aircraft.id} available." if size <= 0: return f"Flight must have at least one aircraft." + if self.custom_name_text and "|" in self.custom_name_text: + return f"Cannot include | in flight name" return None def create_flight(self) -> None: @@ -141,7 +155,7 @@ class QFlightCreator(QDialog): else: start_type = "Warm" flight = Flight(self.package, aircraft, size, task, start_type, origin, - arrival, divert) + arrival, divert, custom_name=self.custom_name_text) flight.client_count = self.client_slots_spinner.value() # noinspection PyUnresolvedReferences diff --git a/qt_ui/windows/mission/flight/settings/QCustomName.py b/qt_ui/windows/mission/flight/settings/QCustomName.py new file mode 100644 index 00000000..7a22e48d --- /dev/null +++ b/qt_ui/windows/mission/flight/settings/QCustomName.py @@ -0,0 +1,16 @@ +from PySide2.QtWidgets import QGroupBox, QHBoxLayout, QLabel + +from gen.flights.flight import Flight + + +class QFlightCustomName(QGroupBox): + + def __init__(self, flight: Flight): + super(QFlightCustomName, self).__init__() + + self.flight = flight + + self.layout = QHBoxLayout() + self.custom_name_label = QLabel(f"Custom Name: {flight.custom_name}") + self.layout.addWidget(self.custom_name_label) + self.setLayout(self.layout) diff --git a/qt_ui/windows/mission/flight/settings/QGeneralFlightSettingsTab.py b/qt_ui/windows/mission/flight/settings/QGeneralFlightSettingsTab.py index f1419669..71dfc036 100644 --- a/qt_ui/windows/mission/flight/settings/QGeneralFlightSettingsTab.py +++ b/qt_ui/windows/mission/flight/settings/QGeneralFlightSettingsTab.py @@ -1,5 +1,5 @@ from PySide2.QtCore import Signal -from PySide2.QtWidgets import QFrame, QGridLayout, QVBoxLayout +from PySide2.QtWidgets import QFrame, QGridLayout, QVBoxLayout, QLabel from game import Game from gen.ato import Package @@ -12,6 +12,8 @@ from qt_ui.windows.mission.flight.settings.QFlightStartType import \ QFlightStartType from qt_ui.windows.mission.flight.settings.QFlightTypeTaskInfo import \ QFlightTypeTaskInfo +from qt_ui.windows.mission.flight.settings.QCustomName import \ + QFlightCustomName class QGeneralFlightSettingsTab(QFrame): @@ -25,10 +27,12 @@ class QGeneralFlightSettingsTab(QFrame): flight_departure = QFlightDepartureDisplay(package, flight) flight_slots = QFlightSlotEditor(flight, game) flight_start_type = QFlightStartType(flight) + flight_custom_name = QFlightCustomName(flight) layout.addWidget(flight_info, 0, 0) layout.addWidget(flight_departure, 1, 0) layout.addWidget(flight_slots, 2, 0) layout.addWidget(flight_start_type, 3, 0) + layout.addWidget(flight_custom_name, 4, 0) vstretch = QVBoxLayout() vstretch.addStretch() layout.addLayout(vstretch, 3, 0) From 09b7cb3d855fa7671c76c5d8a1cbdc41d92c5976 Mon Sep 17 00:00:00 2001 From: walterroach <37820425+walterroach@users.noreply.github.com> Date: Mon, 28 Dec 2020 11:22:28 -0600 Subject: [PATCH 4/6] Change naming to static class This ensures all generators are using the same ID set. --- gen/naming.py | 86 ++++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/gen/naming.py b/gen/naming.py index e79223a0..112d6b16 100644 --- a/gen/naming.py +++ b/gen/naming.py @@ -13,12 +13,7 @@ ALPHA_MILITARY = ["Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Tango", "Uniform", "Victor", "Whisky", "XRay", "Yankee", "Zulu", "Zero"] - -class NameGenerator: - number = 0 - infantry_number = 0 - - ANIMALS = [ +ANIMALS = [ "SHARK", "TORTOISE", "BAT", "PANGOLIN", "AARDWOLF", "MONKEY", "BUFFALO", "DOG", "BOBCAT", "LYNX", "PANTHER", "TIGER", "LION", "OWL", "BUTTERFLY", "BISON", "DUCK", "COBRA", "MAMBA", @@ -46,20 +41,26 @@ class NameGenerator: "ANACONDA" ] - def __init__(self): - self.number = 0 - self.ANIMALS = NameGenerator.ANIMALS.copy() +class NameGenerator: + number = 0 + infantry_number = 0 - def reset(self): - self.number = 0 - self.ANIMALS = NameGenerator.ANIMALS.copy() + ANIMALS = ANIMALS - def reset_numbers(self): - self.number = 0 - self.infantry_number = 0 + @classmethod + def reset(cls): + cls.number = 0 + cls.infantry_number = 0 + cls.ANIMALS = NameGenerator.ANIMALS.copy() - def next_aircraft_name(self, country: Country, parent_base_id: int, flight: Flight): - self.number += 1 + @classmethod + def reset_numbers(cls): + cls.number = 0 + cls.infantry_number = 0 + + @classmethod + def next_aircraft_name(cls, country: Country, parent_base_id: int, flight: Flight): + cls.number += 1 try: if flight.custom_name: name_str = flight.custom_name @@ -69,38 +70,45 @@ class NameGenerator: except AttributeError: # Here to maintain save compatibility with 2.3 name_str = "{} {}".format( flight.package.target.name, flight.flight_type) - return "{}|{}|{}|{}|{}|".format(name_str, country.id, self.number, parent_base_id, db.unit_type_name(flight.unit_type)) + return "{}|{}|{}|{}|{}|".format(name_str, country.id, cls.number, parent_base_id, db.unit_type_name(flight.unit_type)) - def next_unit_name(self, country: Country, parent_base_id: int, unit_type: UnitType): - self.number += 1 - return "unit|{}|{}|{}|{}|".format(country.id, self.number, parent_base_id, db.unit_type_name(unit_type)) + @classmethod + def next_unit_name(cls, country: Country, parent_base_id: int, unit_type: UnitType): + cls.number += 1 + return "unit|{}|{}|{}|{}|".format(country.id, cls.number, parent_base_id, db.unit_type_name(unit_type)) - def next_infantry_name(self, country: Country, parent_base_id: int, unit_type: UnitType): - self.infantry_number += 1 - return "infantry|{}|{}|{}|{}|".format(country.id, self.infantry_number, parent_base_id, db.unit_type_name(unit_type)) + @classmethod + def next_infantry_name(cls, country: Country, parent_base_id: int, unit_type: UnitType): + cls.infantry_number += 1 + return "infantry|{}|{}|{}|{}|".format(country.id, cls.infantry_number, parent_base_id, db.unit_type_name(unit_type)) - def next_basedefense_name(self): + @staticmethod + def next_basedefense_name(): return "basedefense_aa|0|0|" - def next_awacs_name(self, country: Country): - self.number += 1 - return "awacs|{}|{}|0|".format(country.id, self.number) + @classmethod + def next_awacs_name(cls, country: Country): + cls.number += 1 + return "awacs|{}|{}|0|".format(country.id, cls.number) - def next_tanker_name(self, country: Country, unit_type: UnitType): - self.number += 1 - return "tanker|{}|{}|0|{}".format(country.id, self.number, db.unit_type_name(unit_type)) + @classmethod + def next_tanker_name(cls, country: Country, unit_type: UnitType): + cls.number += 1 + return "tanker|{}|{}|0|{}".format(country.id, cls.number, db.unit_type_name(unit_type)) - def next_carrier_name(self, country: Country): - self.number += 1 - return "carrier|{}|{}|0|".format(country.id, self.number) + @classmethod + def next_carrier_name(cls, country: Country): + cls.number += 1 + return "carrier|{}|{}|0|".format(country.id, cls.number) - def random_objective_name(self): - if len(self.ANIMALS) == 0: + @classmethod + def random_objective_name(cls): + if len(cls.ANIMALS) == 0: return random.choice(ALPHA_MILITARY).upper() + "#" + str(random.randint(0, 100)) else: - animal = random.choice(self.ANIMALS) - self.ANIMALS.remove(animal) + animal = random.choice(cls.ANIMALS) + cls.ANIMALS.remove(animal) return animal -namegen = NameGenerator() +namegen = NameGenerator From c697a3423990ffb0785189b2ca1798816e26ebfe Mon Sep 17 00:00:00 2001 From: walterroach <37820425+walterroach@users.noreply.github.com> Date: Mon, 28 Dec 2020 11:31:04 -0600 Subject: [PATCH 5/6] Correctly reset `ANIMALS` --- gen/naming.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/naming.py b/gen/naming.py index 112d6b16..34bf9003 100644 --- a/gen/naming.py +++ b/gen/naming.py @@ -51,7 +51,7 @@ class NameGenerator: def reset(cls): cls.number = 0 cls.infantry_number = 0 - cls.ANIMALS = NameGenerator.ANIMALS.copy() + cls.ANIMALS = ANIMALS @classmethod def reset_numbers(cls): From daba4ef09e352e1f5dbb3e585aefe82c8ee76bea Mon Sep 17 00:00:00 2001 From: walterroach <37820425+walterroach@users.noreply.github.com> Date: Mon, 28 Dec 2020 14:04:19 -0600 Subject: [PATCH 6/6] Fix aircraft group IDs not being reproducible. --- game/operation/operation.py | 2 +- gen/aircraft.py | 14 +++++++------- gen/naming.py | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/game/operation/operation.py b/game/operation/operation.py index c9f45f27..c24d627a 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -69,7 +69,6 @@ class Operation: options_dict = loads(f.read())["options"] cls._set_mission(Mission(game.theater.terrain)) cls.game = game - cls.reset_naming_ids() cls._setup_mission_coalitions() cls.current_mission.options.load_from_dict(options_dict) @@ -350,6 +349,7 @@ class Operation: cls.jtacs, cls.airgen ) + cls.reset_naming_ids() return cls.unit_map @classmethod diff --git a/gen/aircraft.py b/gen/aircraft.py index c9b46436..3c8065bf 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -971,8 +971,8 @@ class AircraftConflictGenerator: arrival=control_point, divert=None) group = self._generate_at_airport( - name=namegen.next_unit_name(country, control_point.id, - aircraft), + name=namegen.next_aircraft_name(country, control_point.id, + flight), side=country, unit_type=aircraft, count=1, @@ -1036,17 +1036,18 @@ class AircraftConflictGenerator: CoalitionHasAirdrome(coalition, flight.from_cp.id)) def generate_planned_flight(self, cp, country, flight:Flight): + name = namegen.next_aircraft_name(country, cp.id, flight) try: if flight.start_type == "In Flight": group = self._generate_inflight( - name=namegen.next_aircraft_name(country, cp.id, flight), + name=name, side=country, flight=flight, origin=cp) elif isinstance(cp, NavalControlPoint): group_name = cp.get_carrier_group_name() group = self._generate_at_group( - name=namegen.next_aircraft_name(country, cp.id, flight), + name=name, side=country, unit_type=flight.unit_type, count=flight.count, @@ -1057,8 +1058,7 @@ class AircraftConflictGenerator: raise RuntimeError( f"Attempted to spawn at airfield for non-airfield {cp}") group = self._generate_at_airport( - name=namegen.next_aircraft_name(country, cp.id, - flight), + name=name, side=country, unit_type=flight.unit_type, count=flight.count, @@ -1070,7 +1070,7 @@ class AircraftConflictGenerator: logging.warning("No room on runway or parking slots. Starting from the air.") flight.start_type = "In Flight" group = self._generate_inflight( - name=namegen.next_aircraft_name(country, cp.id, flight), + name=name, side=country, flight=flight, origin=cp) diff --git a/gen/naming.py b/gen/naming.py index 34bf9003..9989ef69 100644 --- a/gen/naming.py +++ b/gen/naming.py @@ -44,6 +44,7 @@ ANIMALS = [ class NameGenerator: number = 0 infantry_number = 0 + aircraft_number = 0 ANIMALS = ANIMALS @@ -57,10 +58,11 @@ class NameGenerator: def reset_numbers(cls): cls.number = 0 cls.infantry_number = 0 + cls.aircraft_number = 0 @classmethod def next_aircraft_name(cls, country: Country, parent_base_id: int, flight: Flight): - cls.number += 1 + cls.aircraft_number += 1 try: if flight.custom_name: name_str = flight.custom_name @@ -70,7 +72,7 @@ class NameGenerator: except AttributeError: # Here to maintain save compatibility with 2.3 name_str = "{} {}".format( flight.package.target.name, flight.flight_type) - return "{}|{}|{}|{}|{}|".format(name_str, country.id, cls.number, parent_base_id, db.unit_type_name(flight.unit_type)) + return "{}|{}|{}|{}|{}|".format(name_str, country.id, cls.aircraft_number, parent_base_id, db.unit_type_name(flight.unit_type)) @classmethod def next_unit_name(cls, country: Country, parent_base_id: int, unit_type: UnitType):