mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Default to aircraft at only appropriate bases.
This commit is contained in:
parent
0eb8ec70d9
commit
ce01ad2083
@ -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.
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user