Default to aircraft at only appropriate bases.

This commit is contained in:
Dan Albert 2021-07-18 17:12:34 -07:00
parent 0eb8ec70d9
commit ce01ad2083
4 changed files with 49 additions and 2 deletions

View File

@ -10,6 +10,7 @@ Saves from 3.x are not compatible with 5.0.
* **[Campaign AI]** Player front line stances can now be automated. Improved stance selection for AI. * **[Campaign AI]** Player front line stances can now be automated. Improved stance selection for AI.
* **[Campaign AI]** Reworked layout of hold, join, split, and ingress points. Should result in much shorter flight plans in general while still maintaining safe join/split/hold points. * **[Campaign AI]** Reworked layout of hold, join, split, and ingress points. Should result in much shorter flight plans in general while still maintaining safe join/split/hold points.
* **[Campaign AI]** Auto-planning mission range limits are now specified per-aircraft. On average this means that longer range missions will now be plannable. The limit only accounts for the direct distance to the target, not the path taken. * **[Campaign AI]** Auto-planning mission range limits are now specified per-aircraft. On average this means that longer range missions will now be plannable. The limit only accounts for the direct distance to the target, not the path taken.
* **[Campaign AI]** Aircraft will now only be automatically purchased or assigned at appropriate bases. Naval aircraft will default to only operating from carriers, Harriers will default to LHAs and shore bases, helicopters will operate from anywhere. This can be customized per-squadron.
* **[Kneeboard]** Minimum required fuel estimates have been added to the kneeboard for aircraft with supporting data (currently only the Hornet). * **[Kneeboard]** Minimum required fuel estimates have been added to the kneeboard for aircraft with supporting data (currently only the Hornet).
* **[New Game Wizard]** Can now customize the player's air wing before campaign start to disable or rename squadrons. * **[New Game Wizard]** Can now customize the player's air wing before campaign start to disable or rename squadrons.

View File

@ -70,7 +70,9 @@ class AircraftAllocator:
aircraft, task aircraft, task
) )
for squadron in squadrons: for squadron in squadrons:
if squadron.can_provide_pilots(flight.num_aircraft): if squadron.operates_from(airfield) and squadron.can_provide_pilots(
flight.num_aircraft
):
inventory.remove_aircraft(aircraft, flight.num_aircraft) inventory.remove_aircraft(aircraft, flight.num_aircraft)
return airfield, squadron return airfield, squadron
return None return None

View File

@ -226,7 +226,11 @@ class ProcurementAi:
continue continue
for squadron in self.air_wing.squadrons_for(unit): for squadron in self.air_wing.squadrons_for(unit):
if request.task_capability in squadron.auto_assignable_mission_types: if (
squadron.operates_from(airbase)
and request.task_capability
in squadron.auto_assignable_mission_types
):
break break
else: else:
continue continue

View File

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import dataclasses
import itertools import itertools
import logging import logging
import random import random
@ -26,6 +27,7 @@ if TYPE_CHECKING:
from game import Game from game import Game
from game.coalition import Coalition from game.coalition import Coalition
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
from game.theater import ControlPoint
@dataclass @dataclass
@ -73,6 +75,33 @@ class Pilot:
return Pilot(faker.name()) return Pilot(faker.name())
@dataclass(frozen=True)
class OperatingBases:
shore: bool
carrier: bool
lha: bool
@classmethod
def default_for_aircraft(cls, aircraft: AircraftType) -> OperatingBases:
if aircraft.dcs_unit_type.helicopter:
# Helicopters operate from anywhere by default.
return OperatingBases(shore=True, carrier=True, lha=True)
if aircraft.lha_capable:
# Marine aircraft operate from LHAs and the shore by default.
return OperatingBases(shore=True, carrier=False, lha=True)
if aircraft.carrier_capable:
# Carrier aircraft operate from carriers by default.
return OperatingBases(shore=False, carrier=True, lha=False)
# And the rest are only capable of shore operation.
return OperatingBases(shore=True, carrier=False, lha=False)
@classmethod
def from_yaml(cls, aircraft: AircraftType, data: dict[str, bool]) -> OperatingBases:
return dataclasses.replace(
OperatingBases.default_for_aircraft(aircraft), **data
)
@dataclass @dataclass
class Squadron: class Squadron:
name: str name: str
@ -82,6 +111,7 @@ class Squadron:
aircraft: AircraftType aircraft: AircraftType
livery: Optional[str] livery: Optional[str]
mission_types: tuple[FlightType, ...] mission_types: tuple[FlightType, ...]
operating_bases: OperatingBases
#: 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
@ -252,6 +282,14 @@ class Squadron:
def can_auto_assign(self, task: FlightType) -> bool: def can_auto_assign(self, task: FlightType) -> bool:
return task in self.auto_assignable_mission_types return task in self.auto_assignable_mission_types
def operates_from(self, control_point: ControlPoint) -> bool:
if control_point.is_carrier:
return self.operating_bases.carrier
elif control_point.is_lha:
return self.operating_bases.lha
else:
return self.operating_bases.shore
def pilot_at_index(self, index: int) -> Pilot: def pilot_at_index(self, index: int) -> Pilot:
return self.current_roster[index] return self.current_roster[index]
@ -290,6 +328,7 @@ class Squadron:
aircraft=unit_type, aircraft=unit_type,
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", {})),
pilot_pool=pilots, pilot_pool=pilots,
coalition=coalition, coalition=coalition,
settings=game.settings, settings=game.settings,
@ -379,6 +418,7 @@ class AirWing:
aircraft=aircraft, aircraft=aircraft,
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),
pilot_pool=[], pilot_pool=[],
coalition=coalition, coalition=coalition,
settings=game.settings, settings=game.settings,