mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Preferred aircraft per task are now determined by a ranking of weights stored in the aircraft yaml files. To aid in visualizing the priorities across aircraft, Liberation can be run with the argument dump-task-priorities to dump a yaml file in Saved Games/DCS/Liberation/Debug/priorities.yaml, which will show each task along with priority sorted aircraft and their weights. The current weights in the data were exported from the existing lists, where each position from the bottom of the list was worth 10 (to allow some games for less shuffling later). Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2809.
326 lines
8.9 KiB
Python
326 lines
8.9 KiB
Python
from __future__ import annotations
|
|
|
|
import itertools
|
|
import random
|
|
from typing import Optional, TYPE_CHECKING
|
|
|
|
from game.ato.flighttype import FlightType
|
|
from game.dcs.aircrafttype import AircraftType
|
|
from game.squadrons.operatingbases import OperatingBases
|
|
from game.squadrons.squadrondef import SquadronDef
|
|
from game.theater import ControlPoint
|
|
|
|
if TYPE_CHECKING:
|
|
from game.factions.faction import Faction
|
|
|
|
|
|
class SquadronDefGenerator:
|
|
def __init__(self, faction: Faction) -> None:
|
|
self.faction = faction
|
|
self.count = itertools.count(1)
|
|
self.used_nicknames: set[str] = set()
|
|
|
|
def generate_for_task(
|
|
self, task: FlightType, control_point: ControlPoint
|
|
) -> Optional[SquadronDef]:
|
|
aircraft_choice: Optional[AircraftType] = None
|
|
for aircraft in AircraftType.priority_list_for_task(task):
|
|
if aircraft not in self.faction.aircrafts:
|
|
continue
|
|
if not control_point.can_operate(aircraft):
|
|
continue
|
|
aircraft_choice = aircraft
|
|
# 50/50 chance to keep looking for an aircraft that isn't as far up the
|
|
# priority list to maintain some unit variety.
|
|
if random.choice([True, False]):
|
|
break
|
|
|
|
if aircraft_choice is None:
|
|
return None
|
|
return self.generate_for_aircraft(aircraft_choice)
|
|
|
|
def generate_for_aircraft(self, aircraft: AircraftType) -> SquadronDef:
|
|
return SquadronDef(
|
|
name=f"Squadron {next(self.count):03}",
|
|
nickname=self.random_nickname(),
|
|
country=self.faction.country,
|
|
role="Flying Squadron",
|
|
aircraft=aircraft,
|
|
livery=None,
|
|
auto_assignable_mission_types=set(aircraft.iter_task_capabilities()),
|
|
operating_bases=OperatingBases.default_for_aircraft(aircraft),
|
|
female_pilot_percentage=6,
|
|
pilot_pool=[],
|
|
)
|
|
|
|
@staticmethod
|
|
def _make_random_nickname() -> str:
|
|
from game.naming import ANIMALS
|
|
|
|
animal = random.choice(ANIMALS)
|
|
adjective = random.choice(
|
|
(
|
|
None,
|
|
"Aggressive",
|
|
"Alpha",
|
|
"Ancient",
|
|
"Angelic",
|
|
"Angry",
|
|
"Apoplectic",
|
|
"Aquamarine",
|
|
"Astral",
|
|
"Avenging",
|
|
"Azure",
|
|
"Badass",
|
|
"Barbaric",
|
|
"Battle",
|
|
"Battling",
|
|
"Bellicose",
|
|
"Belligerent",
|
|
"Big",
|
|
"Bionic",
|
|
"Black",
|
|
"Bladed",
|
|
"Blazoned",
|
|
"Blood",
|
|
"Bloody",
|
|
"Blue",
|
|
"Bold",
|
|
"Boxing",
|
|
"Brash",
|
|
"Brass",
|
|
"Brave",
|
|
"Brazen",
|
|
"Bronze",
|
|
"Brown",
|
|
"Brutal",
|
|
"Burning",
|
|
"Buzzing",
|
|
"Celestial",
|
|
"Clever",
|
|
"Cloud",
|
|
"Cobalt",
|
|
"Copper",
|
|
"Coral",
|
|
"Crazy",
|
|
"Crimson",
|
|
"Crouching",
|
|
"Cursed",
|
|
"Cyan",
|
|
"Danger",
|
|
"Dangerous",
|
|
"Dapper",
|
|
"Daring",
|
|
"Dark",
|
|
"Dawn",
|
|
"Day",
|
|
"Deadly",
|
|
"Death",
|
|
"Defiant",
|
|
"Demon",
|
|
"Desert",
|
|
"Devil",
|
|
"Devil's",
|
|
"Diabolical",
|
|
"Diamond",
|
|
"Dire",
|
|
"Dirty",
|
|
"Doom",
|
|
"Doomed",
|
|
"Double",
|
|
"Drunken",
|
|
"Dusk",
|
|
"Dusty",
|
|
"Eager",
|
|
"Ebony",
|
|
"Electric",
|
|
"Emerald",
|
|
"Eternal",
|
|
"Evil",
|
|
"Faithful",
|
|
"Famous",
|
|
"Fanged",
|
|
"Fearless",
|
|
"Feisty",
|
|
"Ferocious",
|
|
"Fierce",
|
|
"Fiery",
|
|
"Fighting",
|
|
"Fire",
|
|
"First",
|
|
"Flame",
|
|
"Flaming",
|
|
"Flying",
|
|
"Forest",
|
|
"Frenzied",
|
|
"Frosty",
|
|
"Frozen",
|
|
"Furious",
|
|
"Gallant",
|
|
"Ghost",
|
|
"Giant",
|
|
"Gigantic",
|
|
"Glaring",
|
|
"Global",
|
|
"Gold",
|
|
"Golden",
|
|
"Green",
|
|
"Grey",
|
|
"Grim",
|
|
"Grizzly",
|
|
"Growling",
|
|
"Grumpy",
|
|
"Hammer",
|
|
"Hard",
|
|
"Hardy",
|
|
"Heavy",
|
|
"Hell",
|
|
"Hell's",
|
|
"Hidden",
|
|
"Homicidal",
|
|
"Hostile",
|
|
"Howling",
|
|
"Hyper",
|
|
"Ice",
|
|
"Icy",
|
|
"Immortal",
|
|
"Indignant",
|
|
"Infamous",
|
|
"Invincible",
|
|
"Iron",
|
|
"Jolly",
|
|
"Laser",
|
|
"Lava",
|
|
"Lavender",
|
|
"Lethal",
|
|
"Light",
|
|
"Lightning",
|
|
"Livid",
|
|
"Lucky",
|
|
"Mad",
|
|
"Magenta",
|
|
"Magma",
|
|
"Maroon",
|
|
"Menacing",
|
|
"Merciless",
|
|
"Metal",
|
|
"Midnight",
|
|
"Mighty",
|
|
"Mithril",
|
|
"Mocking",
|
|
"Moon",
|
|
"Mountain",
|
|
"Muddy",
|
|
"Nasty",
|
|
"Naughty",
|
|
"Night",
|
|
"Nova",
|
|
"Nutty",
|
|
"Obsidian",
|
|
"Ocean",
|
|
"Oddball",
|
|
"Old",
|
|
"Omega",
|
|
"Onyx",
|
|
"Orange",
|
|
"Perky",
|
|
"Pink",
|
|
"Power",
|
|
"Prickly",
|
|
"Proud",
|
|
"Puckered",
|
|
"Pugnacious",
|
|
"Puking",
|
|
"Purple",
|
|
"Ragged",
|
|
"Raging",
|
|
"Rainbow",
|
|
"Rampant",
|
|
"Razor",
|
|
"Ready",
|
|
"Reaper",
|
|
"Reckless",
|
|
"Red",
|
|
"Roaring",
|
|
"Rocky",
|
|
"Rolling",
|
|
"Royal",
|
|
"Rusty",
|
|
"Sable",
|
|
"Salty",
|
|
"Sand",
|
|
"Sarcastic",
|
|
"Saucy",
|
|
"Scarlet",
|
|
"Scarred",
|
|
"Scary",
|
|
"Screaming",
|
|
"Scythed",
|
|
"Shadow",
|
|
"Shiny",
|
|
"Shocking",
|
|
"Silver",
|
|
"Sky",
|
|
"Smoke",
|
|
"Smokin'",
|
|
"Snapping",
|
|
"Snappy",
|
|
"Snarling",
|
|
"Snow",
|
|
"Soaring",
|
|
"Space",
|
|
"Spiky",
|
|
"Spiny",
|
|
"Star",
|
|
"Steady",
|
|
"Steel",
|
|
"Stone",
|
|
"Storm",
|
|
"Striking",
|
|
"Strong",
|
|
"Stubborn",
|
|
"Sun",
|
|
"Super",
|
|
"Terrible",
|
|
"Thorny",
|
|
"Thunder",
|
|
"Top",
|
|
"Tough",
|
|
"Toxic",
|
|
"Tricky",
|
|
"Turquoise",
|
|
"Typhoon",
|
|
"Ultimate",
|
|
"Ultra",
|
|
"Ultramarine",
|
|
"Vengeful",
|
|
"Venom",
|
|
"Vermillion",
|
|
"Vicious",
|
|
"Victorious",
|
|
"Vigilant",
|
|
"Violent",
|
|
"Violet",
|
|
"War",
|
|
"Water",
|
|
"Whistling",
|
|
"White",
|
|
"Wicked",
|
|
"Wild",
|
|
"Wizard",
|
|
"Wrathful",
|
|
"Yellow",
|
|
"Young",
|
|
)
|
|
)
|
|
if adjective is None:
|
|
return animal.title()
|
|
return f"{adjective} {animal}".title()
|
|
|
|
def random_nickname(self) -> str:
|
|
while True:
|
|
nickname = self._make_random_nickname()
|
|
if nickname not in self.used_nicknames:
|
|
self.used_nicknames.add(nickname)
|
|
return nickname
|