mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
commit
362caa6ac1
@ -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
|
||||
|
||||
@ -86,7 +86,7 @@ class Operation:
|
||||
cls.game.enemy_country,
|
||||
frontline.position
|
||||
)
|
||||
|
||||
|
||||
@classmethod
|
||||
def air_conflict(cls) -> Conflict:
|
||||
assert cls.game
|
||||
@ -103,7 +103,7 @@ class Operation:
|
||||
cls.game.enemy_name,
|
||||
cls.game.player_country,
|
||||
cls.game.enemy_country,
|
||||
mid_point
|
||||
mid_point
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -295,7 +295,7 @@ class Operation:
|
||||
heading=d["orientation"],
|
||||
dead=True,
|
||||
)
|
||||
|
||||
|
||||
@classmethod
|
||||
def generate(cls) -> UnitMap:
|
||||
"""Build the final Mission to be exported"""
|
||||
@ -349,7 +349,7 @@ class Operation:
|
||||
cls.jtacs,
|
||||
cls.airgen
|
||||
)
|
||||
|
||||
cls.reset_naming_ids()
|
||||
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,
|
||||
|
||||
@ -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_unit_name(country, cp.id, flight.unit_type),
|
||||
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_unit_name(country, cp.id, flight.unit_type),
|
||||
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_unit_name(country, cp.id,
|
||||
flight.unit_type),
|
||||
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_unit_name(country, cp.id, flight.unit_type),
|
||||
name=name,
|
||||
side=country,
|
||||
flight=flight,
|
||||
origin=cp)
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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}"
|
||||
|
||||
110
gen/naming.py
110
gen/naming.py
@ -1,16 +1,19 @@
|
||||
from game import db
|
||||
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
|
||||
|
||||
class NameGenerator:
|
||||
number = 0
|
||||
from game import db
|
||||
|
||||
ANIMALS = [
|
||||
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"]
|
||||
|
||||
ANIMALS = [
|
||||
"SHARK", "TORTOISE", "BAT", "PANGOLIN", "AARDWOLF",
|
||||
"MONKEY", "BUFFALO", "DOG", "BOBCAT", "LYNX", "PANTHER", "TIGER",
|
||||
"LION", "OWL", "BUTTERFLY", "BISON", "DUCK", "COBRA", "MAMBA",
|
||||
@ -38,47 +41,76 @@ class NameGenerator:
|
||||
"ANACONDA"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
self.number = 0
|
||||
self.ANIMALS = NameGenerator.ANIMALS.copy()
|
||||
class NameGenerator:
|
||||
number = 0
|
||||
infantry_number = 0
|
||||
aircraft_number = 0
|
||||
|
||||
def reset(self):
|
||||
self.number = 0
|
||||
self.ANIMALS = NameGenerator.ANIMALS.copy()
|
||||
ANIMALS = ANIMALS
|
||||
|
||||
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))
|
||||
@classmethod
|
||||
def reset(cls):
|
||||
cls.number = 0
|
||||
cls.infantry_number = 0
|
||||
cls.ANIMALS = ANIMALS
|
||||
|
||||
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))
|
||||
@classmethod
|
||||
def reset_numbers(cls):
|
||||
cls.number = 0
|
||||
cls.infantry_number = 0
|
||||
cls.aircraft_number = 0
|
||||
|
||||
def next_basedefense_name(self):
|
||||
@classmethod
|
||||
def next_aircraft_name(cls, country: Country, parent_base_id: int, flight: Flight):
|
||||
cls.aircraft_number += 1
|
||||
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, 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):
|
||||
cls.number += 1
|
||||
return "unit|{}|{}|{}|{}|".format(country.id, cls.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))
|
||||
|
||||
@staticmethod
|
||||
def next_basedefense_name():
|
||||
return "basedefense_aa|0|0|"
|
||||
|
||||
def next_awacs_name(self, 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, unit_type):
|
||||
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):
|
||||
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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
16
qt_ui/windows/mission/flight/settings/QCustomName.py
Normal file
16
qt_ui/windows/mission/flight/settings/QCustomName.py
Normal file
@ -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)
|
||||
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user