mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Merge remote-tracking branch 'remotes/dcs-retribution/dcs-retribution/dev' into pretense-generator
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Literal, TYPE_CHECKING
|
||||
from typing import Literal, TYPE_CHECKING, Any, Dict, Optional
|
||||
|
||||
from dcs import Point
|
||||
|
||||
@@ -56,3 +57,17 @@ class FlightWaypoint:
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(id(self))
|
||||
|
||||
def __deepcopy__(self, memo: Optional[Dict[int, Any]] = None) -> FlightWaypoint:
|
||||
obj = FlightWaypoint(self.name, self.waypoint_type, self.position)
|
||||
for attr in dir(self):
|
||||
if attr == "control_point":
|
||||
obj.control_point = self.control_point
|
||||
elif attr == "targets":
|
||||
obj.targets = self.targets
|
||||
elif "__" in attr or attr not in obj.__dataclass_fields__:
|
||||
continue
|
||||
else:
|
||||
attr_copy = deepcopy(getattr(self, attr))
|
||||
setattr(obj, attr, attr_copy)
|
||||
return obj
|
||||
|
||||
@@ -235,6 +235,7 @@ class Package(RadioFrequencyContainer):
|
||||
clone.time_over_target = deepcopy(package.time_over_target)
|
||||
for f in package.flights:
|
||||
cf = Flight.clone_flight(f)
|
||||
cf.flight_plan.layout = deepcopy(f.flight_plan.layout)
|
||||
cf.package = clone
|
||||
clone.add_flight(cf)
|
||||
return clone
|
||||
|
||||
@@ -74,6 +74,8 @@ class MizCampaignLoader:
|
||||
AirDefence.Hawk_ln.id,
|
||||
AirDefence.S_75M_Volhov.id,
|
||||
AirDefence.x_5p73_s_125_ln.id,
|
||||
AirDefence.NASAMS_LN_B.id,
|
||||
AirDefence.NASAMS_LN_C.id,
|
||||
}
|
||||
|
||||
SHORT_RANGE_SAM_UNIT_TYPES = {
|
||||
|
||||
@@ -78,7 +78,11 @@ class PackageBuilder:
|
||||
)
|
||||
# If this is a client flight, set the start_type again to match the configured default
|
||||
# https://github.com/dcs-liberation/dcs_liberation/issues/1567
|
||||
if flight.roster is not None and flight.roster.player_count > 0:
|
||||
if (
|
||||
squadron.location.required_aircraft_start_type is None
|
||||
and flight.roster is not None
|
||||
and flight.roster.player_count > 0
|
||||
):
|
||||
flight.start_type = (
|
||||
squadron.coalition.game.settings.default_start_type_client
|
||||
)
|
||||
|
||||
@@ -133,6 +133,21 @@ class PackageFulfiller:
|
||||
threats[EscortType.Sead] = True
|
||||
return threats
|
||||
|
||||
def can_plan_escort(self, type: EscortType) -> bool:
|
||||
if type == EscortType.AirToAir:
|
||||
return self.air_wing_can_plan(FlightType.ESCORT)
|
||||
elif type == EscortType.Sead:
|
||||
for task in [
|
||||
FlightType.SEAD,
|
||||
FlightType.SEAD_ESCORT,
|
||||
FlightType.SEAD_SWEEP,
|
||||
]:
|
||||
if self.air_wing_can_plan(task):
|
||||
return True
|
||||
elif type == EscortType.Refuel:
|
||||
return self.air_wing_can_plan(FlightType.REFUELING)
|
||||
return False
|
||||
|
||||
def plan_mission(
|
||||
self,
|
||||
mission: ProposedMission,
|
||||
@@ -207,7 +222,9 @@ class PackageFulfiller:
|
||||
# This list was generated from the not None set, so this should be
|
||||
# impossible.
|
||||
assert escort.escort_type is not None
|
||||
if needed_escorts[escort.escort_type]:
|
||||
if needed_escorts[escort.escort_type] and self.can_plan_escort(
|
||||
escort.escort_type
|
||||
):
|
||||
with tracer.trace("Flight planning"):
|
||||
self.plan_flight(
|
||||
mission, escort, builder, missing_types, purchase_multiplier
|
||||
|
||||
@@ -40,6 +40,7 @@ from game.radio.channels import (
|
||||
ViperChannelNamer,
|
||||
WarthogChannelNamer,
|
||||
PhantomChannelNamer,
|
||||
KiowaChannelNamer,
|
||||
)
|
||||
from game.utils import (
|
||||
Distance,
|
||||
@@ -116,6 +117,7 @@ class RadioConfig:
|
||||
"a10c-legacy": LegacyWarthogChannelNamer,
|
||||
"a10c-ii": WarthogChannelNamer,
|
||||
"phantom": PhantomChannelNamer,
|
||||
"kiowa": KiowaChannelNamer,
|
||||
}[config.get("namer", "default")]
|
||||
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ class AircraftGenerator:
|
||||
if not package.flights:
|
||||
continue
|
||||
for flight in package.flights:
|
||||
if flight.alive:
|
||||
if flight.alive and not isinstance(flight.state, Completed):
|
||||
if not flight.squadron.location.runway_is_operational():
|
||||
logging.warning(
|
||||
f"Runway not operational, skipping flight: {flight.flight_type}"
|
||||
|
||||
@@ -93,7 +93,6 @@ class MigrationUnpickler(pickle.Unpickler):
|
||||
except AttributeError:
|
||||
alternate = name.split('.')[:-1] + [name.split('.')[-1][0].lower() + name.split('.')[-1][1:]]
|
||||
name = '.'.join(alternate)
|
||||
print(name)
|
||||
return super().find_class(module, name)
|
||||
# fmt: on
|
||||
|
||||
|
||||
@@ -421,3 +421,16 @@ class PhantomChannelNamer(ChannelNamer):
|
||||
@classmethod
|
||||
def name(cls) -> str:
|
||||
return "phantom"
|
||||
|
||||
|
||||
class KiowaChannelNamer(ChannelNamer):
|
||||
"""Channel namer for OH58D Kiowa Warrior"""
|
||||
|
||||
@staticmethod
|
||||
def channel_name(radio_id: int, channel_id: int) -> str:
|
||||
radio_name = ["UHF AM", "VHF AM", "VHF FM1", "VHF FM2"][radio_id - 1]
|
||||
return f"{radio_name} Ch {channel_id}"
|
||||
|
||||
@classmethod
|
||||
def name(cls) -> str:
|
||||
return "kiowa"
|
||||
|
||||
@@ -661,10 +661,16 @@ class PendingTransfers:
|
||||
def _cancel_transport_air(
|
||||
self, transport: Airlift, _transfer: TransferOrder
|
||||
) -> None:
|
||||
from game.sim import GameUpdateEvents
|
||||
from game.server import EventStream
|
||||
|
||||
flight = transport.flight
|
||||
flight.package.remove_flight(flight)
|
||||
events = GameUpdateEvents().delete_flight(flight)
|
||||
if not flight.package.flights:
|
||||
self.game.ato_for(self.player).remove_package(flight.package)
|
||||
events = events.delete_flights_in_package(flight.package)
|
||||
EventStream().put_nowait(events)
|
||||
|
||||
@cancel_transport.register
|
||||
def _cancel_transport_convoy(
|
||||
|
||||
Reference in New Issue
Block a user