#1966 : Added female_pilot_ratio param in squadrons. Also possible to force name or nickname for squadrons in campaign yaml files.

This commit is contained in:
Khopa 2022-02-06 14:40:35 +01:00
parent ac5d20ff82
commit 33a75b5450
5 changed files with 48 additions and 10 deletions

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import logging import logging
from collections import defaultdict from collections import defaultdict
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, TYPE_CHECKING, Union from typing import Any, TYPE_CHECKING, Union, Optional
from game.ato.flighttype import FlightType from game.ato.flighttype import FlightType
from game.theater.controlpoint import ControlPoint from game.theater.controlpoint import ControlPoint
@ -18,6 +18,10 @@ class SquadronConfig:
secondary: list[FlightType] secondary: list[FlightType]
aircraft: list[str] aircraft: list[str]
name: Optional[str]
nickname: Optional[str]
female_pilot_ratio: Optional[int]
@property @property
def auto_assignable(self) -> set[FlightType]: def auto_assignable(self) -> set[FlightType]:
return set(self.secondary) | {self.primary} return set(self.secondary) | {self.primary}
@ -33,7 +37,12 @@ class SquadronConfig:
secondary = [FlightType(s) for s in secondary_raw] secondary = [FlightType(s) for s in secondary_raw]
return SquadronConfig( return SquadronConfig(
FlightType(data["primary"]), secondary, data.get("aircraft", []) FlightType(data["primary"]),
secondary,
data.get("aircraft", []),
data.get("name", None),
data.get("nickname", None),
data.get("female_pilot_ratio", None),
) )
@staticmethod @staticmethod

View File

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import dataclasses
import logging import logging
from typing import Optional, TYPE_CHECKING from typing import Optional, TYPE_CHECKING
@ -48,24 +49,41 @@ class DefaultSquadronAssigner:
def find_squadron_for( def find_squadron_for(
self, config: SquadronConfig, control_point: ControlPoint self, config: SquadronConfig, control_point: ControlPoint
) -> Optional[SquadronDef]: ) -> Optional[SquadronDef]:
squadron_def = None
for preferred_aircraft in config.aircraft: for preferred_aircraft in config.aircraft:
squadron_def = self.find_preferred_squadron( squadron_def = self.find_preferred_squadron(
preferred_aircraft, config.primary, control_point preferred_aircraft, config.primary, control_point
) )
if squadron_def is not None: if squadron_def is not None:
return squadron_def break
# If we didn't find any of the preferred types we should use any squadron # If we didn't find any of the preferred types we should use any squadron
# compatible with the primary task. # compatible with the primary task.
squadron_def = self.find_squadron_for_task(config.primary, control_point) if squadron_def is None:
if squadron_def is not None: squadron_def = self.find_squadron_for_task(config.primary, control_point)
return squadron_def
# If we can't find any squadron matching the requirement, we should # If we can't find any squadron matching the requirement, we should
# create one. # create one.
return self.air_wing.squadron_def_generator.generate_for_task( if squadron_def is None:
config.primary, control_point squadron_def = self.air_wing.squadron_def_generator.generate_for_task(
) config.primary, control_point
)
# Override squadron def with squadron config parameters from campaign file, if defined
if squadron_def is not None:
overrides = {}
if config.name is not None:
overrides["name"] = config.name
if config.nickname is not None:
overrides["nickname"] = config.nickname
if config.female_pilot_ratio is not None:
overrides["female_pilot_ratio"] = config.female_pilot_ratio
squadron_copy = dataclasses.replace(squadron_def, **overrides)
return squadron_copy
else:
return None
def find_preferred_squadron( def find_preferred_squadron(
self, preferred_aircraft: str, task: FlightType, control_point: ControlPoint self, preferred_aircraft: str, task: FlightType, control_point: ControlPoint

View File

@ -50,6 +50,7 @@ class SquadronDefGenerator:
livery=None, livery=None,
mission_types=tuple(tasks_for_aircraft(aircraft)), mission_types=tuple(tasks_for_aircraft(aircraft)),
operating_bases=OperatingBases.default_for_aircraft(aircraft), operating_bases=OperatingBases.default_for_aircraft(aircraft),
female_pilot_ratio=6,
pilot_pool=[], pilot_pool=[],
) )

View File

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
import random
from collections.abc import Iterable from collections.abc import Iterable
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Optional, Sequence, TYPE_CHECKING from typing import Optional, Sequence, TYPE_CHECKING
@ -32,6 +33,7 @@ class Squadron:
livery: Optional[str] livery: Optional[str]
mission_types: tuple[FlightType, ...] mission_types: tuple[FlightType, ...]
operating_bases: OperatingBases operating_bases: OperatingBases
female_pilot_ratio: int
#: The pool of pilots that have not yet been assigned to the squadron. This only #: The pool of pilots that have not yet been assigned to the squadron. This only
#: happens when a preset squadron defines more preset pilots than the squadron limit #: happens when a preset squadron defines more preset pilots than the squadron limit
@ -159,7 +161,11 @@ class Squadron:
new_pilots = self.pilot_pool[:count] new_pilots = self.pilot_pool[:count]
self.pilot_pool = self.pilot_pool[count:] self.pilot_pool = self.pilot_pool[count:]
count -= len(new_pilots) count -= len(new_pilots)
new_pilots.extend([Pilot(self.faker.name()) for _ in range(count)]) for _ in range(count):
if random.randint(1, 100) > self.female_pilot_ratio:
new_pilots.append(Pilot(self.faker.name_male()))
else:
new_pilots.append(Pilot(self.faker.name_female()))
self.current_roster.extend(new_pilots) self.current_roster.extend(new_pilots)
self.available_pilots.extend(new_pilots) self.available_pilots.extend(new_pilots)
@ -428,6 +434,7 @@ class Squadron:
squadron_def.livery, squadron_def.livery,
squadron_def.mission_types, squadron_def.mission_types,
squadron_def.operating_bases, squadron_def.operating_bases,
squadron_def.female_pilot_ratio,
squadron_def.pilot_pool, squadron_def.pilot_pool,
coalition, coalition,
game.settings, game.settings,

View File

@ -27,6 +27,7 @@ class SquadronDef:
livery: Optional[str] livery: Optional[str]
mission_types: tuple[FlightType, ...] mission_types: tuple[FlightType, ...]
operating_bases: OperatingBases operating_bases: OperatingBases
female_pilot_ratio: int
pilot_pool: list[Pilot] pilot_pool: list[Pilot]
claimed: bool = False claimed: bool = False
@ -75,6 +76,7 @@ class SquadronDef:
pilots = [Pilot(n, player=False) for n in data.get("pilots", [])] pilots = [Pilot(n, player=False) for n in data.get("pilots", [])]
pilots.extend([Pilot(n, player=True) for n in data.get("players", [])]) pilots.extend([Pilot(n, player=True) for n in data.get("players", [])])
female_pilot_ratio = data.get("female_pilot_ratio", 6)
mission_types = [FlightType.from_name(n) for n in data["mission_types"]] mission_types = [FlightType.from_name(n) for n in data["mission_types"]]
tasks = tasks_for_aircraft(unit_type) tasks = tasks_for_aircraft(unit_type)
@ -95,5 +97,6 @@ class SquadronDef:
livery=data.get("livery"), livery=data.get("livery"),
mission_types=tuple(mission_types), mission_types=tuple(mission_types),
operating_bases=OperatingBases.from_yaml(unit_type, data.get("bases", {})), operating_bases=OperatingBases.from_yaml(unit_type, data.get("bases", {})),
female_pilot_ratio=female_pilot_ratio,
pilot_pool=pilots, pilot_pool=pilots,
) )