mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Added new options in settings: - Carriers steam into wind - Navmesh to use for Pretense carrier zones - Remove ground spawn statics, including invisible FARPs, at airbases. - Percentage of randomly selected aircraft types (only for generated squadrons) intended to allow the user to increase aircraft variety. Will now store the ICLS channel and Link4 frequency in missiondata.py CarrierInfo. Implemented artillery groups as Pretense garrisons. Artillery groups are spawned by the Artillery Bunker. Will now also ensure that the logistics units spawned as part of Pretense garrisons are actually capable of ammo resupply. Fixed the Pretense generator generating a bit too many missions per squadron. Ground spawns: Also hot start aircraft which require ground crew support (ground air or chock removal) which might not be available at roadbases. Also, pretensetgogenerator.py will now correctly handle air defence units in ground_unit_of_class(). Added Roland groups in the Pretense generator.
327 lines
9.0 KiB
Python
327 lines
9.0 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, squadron_random_chance: int
|
|
) -> Optional[SquadronDef]:
|
|
aircraft_choice: Optional[AircraftType] = None
|
|
for aircraft in AircraftType.priority_list_for_task(task):
|
|
if aircraft not in self.faction.all_aircrafts:
|
|
continue
|
|
if not control_point.can_operate(aircraft):
|
|
continue
|
|
aircraft_choice = aircraft
|
|
# squadron_random_chance percent chance to keep looking for an aircraft that isn't as far up the
|
|
# priority list to maintain some unit variety.
|
|
if squadron_random_chance >= random.randint(1, 100):
|
|
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()),
|
|
radio_presets={},
|
|
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
|