mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Deleted pretense/pretenseflightgroupconfigurator.py since it looks like it's not needed (at least for the time being).
This commit is contained in:
parent
8dfb05b0d1
commit
d8b0283efe
@ -1,288 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import logging
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Any, Optional, TYPE_CHECKING
|
|
||||||
|
|
||||||
from dcs import Mission
|
|
||||||
from dcs.action import DoScript
|
|
||||||
from dcs.flyingunit import FlyingUnit
|
|
||||||
from dcs.task import OptReactOnThreat
|
|
||||||
from dcs.translation import String
|
|
||||||
from dcs.triggers import TriggerStart
|
|
||||||
from dcs.unit import Skill
|
|
||||||
from dcs.unitgroup import FlyingGroup
|
|
||||||
|
|
||||||
from game.ato import Flight, FlightType
|
|
||||||
from game.callsigns import callsign_for_support_unit
|
|
||||||
from game.data.weapons import Pylon, WeaponType as WeaponTypeEnum
|
|
||||||
from game.missiongenerator.lasercoderegistry import LaserCodeRegistry
|
|
||||||
from game.missiongenerator.logisticsgenerator import LogisticsGenerator
|
|
||||||
from game.missiongenerator.missiondata import MissionData, AwacsInfo, TankerInfo
|
|
||||||
from game.radio.radios import RadioFrequency, RadioRegistry
|
|
||||||
from game.radio.tacan import TacanBand, TacanRegistry, TacanUsage
|
|
||||||
from game.runways import RunwayData
|
|
||||||
from game.squadrons import Pilot
|
|
||||||
from .aircraftbehavior import AircraftBehavior
|
|
||||||
from .aircraftpainter import AircraftPainter
|
|
||||||
from .flightdata import FlightData
|
|
||||||
from .waypoints import WaypointGenerator
|
|
||||||
from ...ato.flightplans.aewc import AewcFlightPlan
|
|
||||||
from ...ato.flightplans.packagerefueling import PackageRefuelingFlightPlan
|
|
||||||
from ...ato.flightplans.theaterrefueling import TheaterRefuelingFlightPlan
|
|
||||||
from ...theater import Fob
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from game import Game
|
|
||||||
|
|
||||||
|
|
||||||
class FlightGroupConfigurator:
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
flight: Flight,
|
|
||||||
group: FlyingGroup[Any],
|
|
||||||
game: Game,
|
|
||||||
mission: Mission,
|
|
||||||
time: datetime,
|
|
||||||
radio_registry: RadioRegistry,
|
|
||||||
tacan_registry: TacanRegistry,
|
|
||||||
laser_code_registry: LaserCodeRegistry,
|
|
||||||
mission_data: MissionData,
|
|
||||||
dynamic_runways: dict[str, RunwayData],
|
|
||||||
use_client: bool,
|
|
||||||
) -> None:
|
|
||||||
self.flight = flight
|
|
||||||
self.group = group
|
|
||||||
self.game = game
|
|
||||||
self.mission = mission
|
|
||||||
self.time = time
|
|
||||||
self.radio_registry = radio_registry
|
|
||||||
self.tacan_registry = tacan_registry
|
|
||||||
self.laser_code_registry = laser_code_registry
|
|
||||||
self.mission_data = mission_data
|
|
||||||
self.dynamic_runways = dynamic_runways
|
|
||||||
self.use_client = use_client
|
|
||||||
|
|
||||||
def configure(self) -> FlightData:
|
|
||||||
AircraftBehavior(self.flight.flight_type).apply_to(self.flight, self.group)
|
|
||||||
AircraftPainter(self.flight, self.group).apply_livery()
|
|
||||||
self.setup_props()
|
|
||||||
self.setup_payload()
|
|
||||||
self.setup_fuel()
|
|
||||||
flight_channel = self.setup_radios()
|
|
||||||
|
|
||||||
laser_codes: list[Optional[int]] = []
|
|
||||||
for unit, pilot in zip(self.group.units, self.flight.roster.pilots):
|
|
||||||
self.configure_flight_member(unit, pilot, laser_codes)
|
|
||||||
|
|
||||||
divert = None
|
|
||||||
if self.flight.divert is not None:
|
|
||||||
divert = self.flight.divert.active_runway(
|
|
||||||
self.game.theater, self.game.conditions, self.dynamic_runways
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.flight.flight_type in [
|
|
||||||
FlightType.TRANSPORT,
|
|
||||||
FlightType.AIR_ASSAULT,
|
|
||||||
] and self.game.settings.plugin_option("ctld"):
|
|
||||||
transfer = None
|
|
||||||
if self.flight.flight_type == FlightType.TRANSPORT:
|
|
||||||
coalition = self.game.coalition_for(player=self.flight.blue)
|
|
||||||
transfer = coalition.transfers.transfer_for_flight(self.flight)
|
|
||||||
self.mission_data.logistics.append(
|
|
||||||
LogisticsGenerator(
|
|
||||||
self.flight, self.group, self.mission, self.game.settings, transfer
|
|
||||||
).generate_logistics()
|
|
||||||
)
|
|
||||||
|
|
||||||
mission_start_time, waypoints = WaypointGenerator(
|
|
||||||
self.flight,
|
|
||||||
self.group,
|
|
||||||
self.mission,
|
|
||||||
self.game.conditions.start_time,
|
|
||||||
self.time,
|
|
||||||
self.game.settings,
|
|
||||||
self.mission_data,
|
|
||||||
).create_waypoints()
|
|
||||||
|
|
||||||
# Special handling for landing waypoints when:
|
|
||||||
# 1. It's an AI-only flight
|
|
||||||
# 2. Aircraft are not helicopters/VTOL
|
|
||||||
# 3. Landing waypoint does not point to an airfield
|
|
||||||
if (
|
|
||||||
self.flight.client_count < 1
|
|
||||||
and not self.flight.unit_type.helicopter
|
|
||||||
and not self.flight.unit_type.lha_capable
|
|
||||||
and isinstance(self.flight.squadron.location, Fob)
|
|
||||||
):
|
|
||||||
# Need to set uncontrolled to false, otherwise the AI will skip the mission and just land
|
|
||||||
self.group.uncontrolled = False
|
|
||||||
|
|
||||||
return FlightData(
|
|
||||||
package=self.flight.package,
|
|
||||||
aircraft_type=self.flight.unit_type,
|
|
||||||
squadron=self.flight.squadron,
|
|
||||||
flight_type=self.flight.flight_type,
|
|
||||||
units=self.group.units,
|
|
||||||
size=len(self.group.units),
|
|
||||||
friendly=self.flight.from_cp.captured,
|
|
||||||
departure_delay=mission_start_time,
|
|
||||||
departure=self.flight.departure.active_runway(
|
|
||||||
self.game.theater, self.game.conditions, self.dynamic_runways
|
|
||||||
),
|
|
||||||
arrival=self.flight.arrival.active_runway(
|
|
||||||
self.game.theater, self.game.conditions, self.dynamic_runways
|
|
||||||
),
|
|
||||||
divert=divert,
|
|
||||||
waypoints=waypoints,
|
|
||||||
intra_flight_channel=flight_channel,
|
|
||||||
bingo_fuel=self.flight.flight_plan.bingo_fuel,
|
|
||||||
joker_fuel=self.flight.flight_plan.joker_fuel,
|
|
||||||
custom_name=self.flight.custom_name,
|
|
||||||
laser_codes=laser_codes,
|
|
||||||
)
|
|
||||||
|
|
||||||
def configure_flight_member(
|
|
||||||
self, unit: FlyingUnit, pilot: Optional[Pilot], laser_codes: list[Optional[int]]
|
|
||||||
) -> None:
|
|
||||||
player = pilot is not None and pilot.player
|
|
||||||
self.set_skill(unit, pilot)
|
|
||||||
if self.flight.loadout.has_weapon_of_type(WeaponTypeEnum.TGP) and player:
|
|
||||||
laser_codes.append(self.laser_code_registry.get_next_laser_code())
|
|
||||||
else:
|
|
||||||
laser_codes.append(None)
|
|
||||||
settings = self.flight.coalition.game.settings
|
|
||||||
if not player or not settings.plugins.get("ewrj"):
|
|
||||||
return
|
|
||||||
jammer_required = settings.plugin_option("ewrj.ecm_required")
|
|
||||||
if jammer_required:
|
|
||||||
ecm = WeaponTypeEnum.JAMMER
|
|
||||||
if not self.flight.loadout.has_weapon_of_type(ecm):
|
|
||||||
return
|
|
||||||
ewrj_menu_trigger = TriggerStart(comment=f"EWRJ-{unit.name}")
|
|
||||||
ewrj_menu_trigger.add_action(DoScript(String(f'EWJamming("{unit.name}")')))
|
|
||||||
self.mission.triggerrules.triggers.append(ewrj_menu_trigger)
|
|
||||||
self.group.points[0].tasks[0] = OptReactOnThreat(
|
|
||||||
OptReactOnThreat.Values.PassiveDefense
|
|
||||||
)
|
|
||||||
|
|
||||||
def setup_radios(self) -> RadioFrequency:
|
|
||||||
freq = self.flight.frequency
|
|
||||||
if freq is None and (freq := self.flight.package.frequency) is None:
|
|
||||||
freq = self.radio_registry.alloc_uhf()
|
|
||||||
self.flight.package.frequency = freq
|
|
||||||
if freq not in self.radio_registry.allocated_channels:
|
|
||||||
self.radio_registry.reserve(freq)
|
|
||||||
|
|
||||||
if self.flight.flight_type in {FlightType.AEWC, FlightType.REFUELING}:
|
|
||||||
self.register_air_support(freq)
|
|
||||||
elif self.flight.frequency is None and self.flight.client_count:
|
|
||||||
freq = self.flight.unit_type.alloc_flight_radio(self.radio_registry)
|
|
||||||
|
|
||||||
self.group.set_frequency(freq.mhz)
|
|
||||||
return freq
|
|
||||||
|
|
||||||
def register_air_support(self, channel: RadioFrequency) -> None:
|
|
||||||
callsign = callsign_for_support_unit(self.group)
|
|
||||||
if isinstance(self.flight.flight_plan, AewcFlightPlan):
|
|
||||||
self.mission_data.awacs.append(
|
|
||||||
AwacsInfo(
|
|
||||||
group_name=str(self.group.name),
|
|
||||||
callsign=callsign,
|
|
||||||
freq=channel,
|
|
||||||
depature_location=self.flight.departure.name,
|
|
||||||
start_time=self.flight.flight_plan.patrol_start_time,
|
|
||||||
end_time=self.flight.flight_plan.patrol_end_time,
|
|
||||||
blue=self.flight.departure.captured,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
elif isinstance(
|
|
||||||
self.flight.flight_plan, TheaterRefuelingFlightPlan
|
|
||||||
) or isinstance(self.flight.flight_plan, PackageRefuelingFlightPlan):
|
|
||||||
if self.flight.tacan is None:
|
|
||||||
tacan = self.tacan_registry.alloc_for_band(
|
|
||||||
TacanBand.Y, TacanUsage.AirToAir
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
tacan = self.flight.tacan
|
|
||||||
self.mission_data.tankers.append(
|
|
||||||
TankerInfo(
|
|
||||||
group_name=str(self.group.name),
|
|
||||||
callsign=callsign,
|
|
||||||
variant=self.flight.unit_type.name,
|
|
||||||
freq=channel,
|
|
||||||
tacan=tacan,
|
|
||||||
start_time=self.flight.flight_plan.patrol_start_time,
|
|
||||||
end_time=self.flight.flight_plan.patrol_end_time,
|
|
||||||
blue=self.flight.departure.captured,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def set_skill(self, unit: FlyingUnit, pilot: Optional[Pilot]) -> None:
|
|
||||||
if pilot is None or not pilot.player:
|
|
||||||
unit.skill = self.skill_level_for(unit, pilot)
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.use_client or "Pilot #1" not in unit.name:
|
|
||||||
unit.set_client()
|
|
||||||
else:
|
|
||||||
unit.set_player()
|
|
||||||
|
|
||||||
def skill_level_for(self, unit: FlyingUnit, pilot: Optional[Pilot]) -> Skill:
|
|
||||||
if self.flight.squadron.player:
|
|
||||||
base_skill = Skill(self.game.settings.player_skill)
|
|
||||||
else:
|
|
||||||
base_skill = Skill(self.game.settings.enemy_skill)
|
|
||||||
|
|
||||||
if pilot is None:
|
|
||||||
logging.error(f"Cannot determine skill level: {unit.name} has not pilot")
|
|
||||||
return base_skill
|
|
||||||
|
|
||||||
levels = [
|
|
||||||
Skill.Average,
|
|
||||||
Skill.Good,
|
|
||||||
Skill.High,
|
|
||||||
Skill.Excellent,
|
|
||||||
]
|
|
||||||
current_level = levels.index(base_skill)
|
|
||||||
missions_for_skill_increase = 4
|
|
||||||
increase = pilot.record.missions_flown // missions_for_skill_increase
|
|
||||||
capped_increase = min(current_level + increase, len(levels) - 1)
|
|
||||||
|
|
||||||
if self.game.settings.ai_pilot_levelling:
|
|
||||||
new_level = capped_increase
|
|
||||||
else:
|
|
||||||
new_level = current_level
|
|
||||||
|
|
||||||
return levels[new_level]
|
|
||||||
|
|
||||||
def setup_props(self) -> None:
|
|
||||||
for prop_id, value in self.flight.props.items():
|
|
||||||
for unit in self.group.units:
|
|
||||||
unit.set_property(prop_id, value)
|
|
||||||
|
|
||||||
def setup_payload(self) -> None:
|
|
||||||
for p in self.group.units:
|
|
||||||
p.pylons.clear()
|
|
||||||
|
|
||||||
loadout = self.flight.loadout
|
|
||||||
if self.game.settings.restrict_weapons_by_date:
|
|
||||||
loadout = loadout.degrade_for_date(self.flight.unit_type, self.game.date)
|
|
||||||
|
|
||||||
for pylon_number, weapon in loadout.pylons.items():
|
|
||||||
if weapon is None:
|
|
||||||
continue
|
|
||||||
pylon = Pylon.for_aircraft(self.flight.unit_type, pylon_number)
|
|
||||||
pylon.equip(self.group, weapon)
|
|
||||||
|
|
||||||
def setup_fuel(self) -> None:
|
|
||||||
fuel = self.flight.state.estimate_fuel()
|
|
||||||
if fuel < 0:
|
|
||||||
logging.warning(
|
|
||||||
f"Flight {self.flight} is estimated to have no fuel at mission start. "
|
|
||||||
"This estimate does not account for external fuel tanks. Setting "
|
|
||||||
"starting fuel to 100kg."
|
|
||||||
)
|
|
||||||
fuel = 100
|
|
||||||
for unit, pilot in zip(self.group.units, self.flight.roster.pilots):
|
|
||||||
unit.fuel = fuel
|
|
||||||
Loading…
x
Reference in New Issue
Block a user