mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Added configuration constants for flights generated for Pretense. Fixed a bug which caused only one squadron per CP to be generated. Will now not generate Pretense cargo flights from Retribution off-map spawns, but instead will generate own air spawn points for them. Added a helper function initialize_pretense_data_structures().
This commit is contained in:
parent
d0ff363bb5
commit
aa641e1ff6
@ -11,6 +11,7 @@ from .ibuilder import IBuilder
|
|||||||
from .planningerror import PlanningError
|
from .planningerror import PlanningError
|
||||||
from .standard import StandardFlightPlan, StandardLayout
|
from .standard import StandardFlightPlan, StandardLayout
|
||||||
from .waypointbuilder import WaypointBuilder
|
from .waypointbuilder import WaypointBuilder
|
||||||
|
from ...theater import OffMapSpawn
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..flightwaypoint import FlightWaypoint
|
from ..flightwaypoint import FlightWaypoint
|
||||||
@ -48,6 +49,8 @@ class Builder(IBuilder[PretenseCargoFlightPlan, FerryLayout]):
|
|||||||
heading_from_flot = 0.0
|
heading_from_flot = 0.0
|
||||||
offmap_transport_cp_id = self.flight.departure.id
|
offmap_transport_cp_id = self.flight.departure.id
|
||||||
for front_line_cp in self.coalition.game.theater.controlpoints:
|
for front_line_cp in self.coalition.game.theater.controlpoints:
|
||||||
|
if isinstance(front_line_cp, OffMapSpawn):
|
||||||
|
continue
|
||||||
for front_line in self.coalition.game.theater.conflicts():
|
for front_line in self.coalition.game.theater.conflicts():
|
||||||
if front_line_cp.captured == self.flight.coalition.player:
|
if front_line_cp.captured == self.flight.coalition.player:
|
||||||
if (
|
if (
|
||||||
|
|||||||
@ -27,6 +27,7 @@ from game.radio.radios import RadioRegistry
|
|||||||
from game.radio.tacan import TacanRegistry
|
from game.radio.tacan import TacanRegistry
|
||||||
from game.runways import RunwayData
|
from game.runways import RunwayData
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
|
from game.squadrons import AirWing
|
||||||
from game.theater.controlpoint import (
|
from game.theater.controlpoint import (
|
||||||
ControlPoint,
|
ControlPoint,
|
||||||
OffMapSpawn,
|
OffMapSpawn,
|
||||||
@ -42,6 +43,13 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
PRETENSE_SQUADRON_DEF_RETRIES = 100
|
PRETENSE_SQUADRON_DEF_RETRIES = 100
|
||||||
|
PRETENSE_SEAD_FLIGHTS_PER_CP = 1
|
||||||
|
PRETENSE_CAS_FLIGHTS_PER_CP = 1
|
||||||
|
PRETENSE_STRIKE_FLIGHTS_PER_CP = 1
|
||||||
|
PRETENSE_BARCAP_FLIGHTS_PER_CP = 1
|
||||||
|
PRETENSE_AI_AIRCRAFT_PER_FLIGHT = 2
|
||||||
|
PRETENSE_AI_AWACS_PER_FLIGHT = 1
|
||||||
|
PRETENSE_AI_TANKERS_PER_FLIGHT = 1
|
||||||
|
|
||||||
|
|
||||||
class PretenseAircraftGenerator:
|
class PretenseAircraftGenerator:
|
||||||
@ -108,6 +116,8 @@ class PretenseAircraftGenerator:
|
|||||||
fixed_wing=True, fixed_wing_stol=True, rotary_wing=False
|
fixed_wing=True, fixed_wing_stol=True, rotary_wing=False
|
||||||
)
|
)
|
||||||
for front_line_cp in self.game.theater.controlpoints:
|
for front_line_cp in self.game.theater.controlpoints:
|
||||||
|
if isinstance(front_line_cp, OffMapSpawn):
|
||||||
|
continue
|
||||||
for front_line in self.game.theater.conflicts():
|
for front_line in self.game.theater.conflicts():
|
||||||
if front_line_cp.captured == cp.captured:
|
if front_line_cp.captured == cp.captured:
|
||||||
if (
|
if (
|
||||||
@ -124,7 +134,7 @@ class PretenseAircraftGenerator:
|
|||||||
return self.game.theater.find_control_point_by_id(offmap_transport_cp_id)
|
return self.game.theater.find_control_point_by_id(offmap_transport_cp_id)
|
||||||
|
|
||||||
def should_generate_pretense_transports(
|
def should_generate_pretense_transports(
|
||||||
self, cp: ControlPoint
|
self, air_wing: AirWing
|
||||||
) -> tuple[bool, bool]:
|
) -> tuple[bool, bool]:
|
||||||
"""
|
"""
|
||||||
Returns a tuple of booleans, telling whether transport helicopter and aircraft
|
Returns a tuple of booleans, telling whether transport helicopter and aircraft
|
||||||
@ -136,17 +146,16 @@ class PretenseAircraftGenerator:
|
|||||||
"""
|
"""
|
||||||
autogenerate_transport_helicopter_squadron = True
|
autogenerate_transport_helicopter_squadron = True
|
||||||
autogenerate_cargo_plane_squadron = True
|
autogenerate_cargo_plane_squadron = True
|
||||||
for aircraft_type in cp.coalition.air_wing.squadrons:
|
for aircraft_type in air_wing.squadrons:
|
||||||
for squadron in cp.coalition.air_wing.squadrons[aircraft_type]:
|
for squadron in air_wing.squadrons[aircraft_type]:
|
||||||
mission_types = squadron.auto_assignable_mission_types
|
|
||||||
if squadron.aircraft.helicopter and (
|
if squadron.aircraft.helicopter and (
|
||||||
FlightType.TRANSPORT in mission_types
|
squadron.aircraft.capable_of(FlightType.TRANSPORT)
|
||||||
or FlightType.AIR_ASSAULT in mission_types
|
or squadron.aircraft.capable_of(FlightType.AIR_ASSAULT)
|
||||||
):
|
):
|
||||||
autogenerate_transport_helicopter_squadron = False
|
autogenerate_transport_helicopter_squadron = False
|
||||||
elif not squadron.aircraft.helicopter and (
|
elif not squadron.aircraft.helicopter and (
|
||||||
FlightType.TRANSPORT in mission_types
|
squadron.aircraft.capable_of(FlightType.TRANSPORT)
|
||||||
or FlightType.AIR_ASSAULT in mission_types
|
or squadron.aircraft.capable_of(FlightType.AIR_ASSAULT)
|
||||||
):
|
):
|
||||||
autogenerate_cargo_plane_squadron = False
|
autogenerate_cargo_plane_squadron = False
|
||||||
return (
|
return (
|
||||||
@ -181,7 +190,7 @@ class PretenseAircraftGenerator:
|
|||||||
f"Generating a squadron definition for fixed-wing {fixed_wing} squadron at {cp}"
|
f"Generating a squadron definition for fixed-wing {fixed_wing} squadron at {cp}"
|
||||||
)
|
)
|
||||||
for retries in range(num_retries):
|
for retries in range(num_retries):
|
||||||
if squadron_def is None or fixed_wing != squadron_def.aircraft.helicopter:
|
if squadron_def is None or fixed_wing == squadron_def.aircraft.helicopter:
|
||||||
squadron_def = (
|
squadron_def = (
|
||||||
cp.coalition.air_wing.squadron_def_generator.generate_for_task(
|
cp.coalition.air_wing.squadron_def_generator.generate_for_task(
|
||||||
flight_type, cp
|
flight_type, cp
|
||||||
@ -200,7 +209,8 @@ class PretenseAircraftGenerator:
|
|||||||
cp.coalition,
|
cp.coalition,
|
||||||
self.game,
|
self.game,
|
||||||
)
|
)
|
||||||
cp.coalition.air_wing.squadrons[squadron.aircraft] = list()
|
if squadron.aircraft not in cp.coalition.air_wing.squadrons:
|
||||||
|
cp.coalition.air_wing.squadrons[squadron.aircraft] = list()
|
||||||
cp.coalition.air_wing.add_squadron(squadron)
|
cp.coalition.air_wing.add_squadron(squadron)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -229,10 +239,11 @@ class PretenseAircraftGenerator:
|
|||||||
if isinstance(squadron.location, OffMapSpawn):
|
if isinstance(squadron.location, OffMapSpawn):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
squadron.owned_aircraft += 1
|
squadron.owned_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||||
squadron.untasked_aircraft += 1
|
squadron.untasked_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||||
package = Package(cp, squadron.flight_db, auto_asap=False)
|
package = Package(cp, squadron.flight_db, auto_asap=False)
|
||||||
mission_types = squadron.auto_assignable_mission_types
|
mission_types = squadron.auto_assignable_mission_types
|
||||||
|
aircraft_per_flight = 1
|
||||||
if squadron.aircraft.helicopter and (
|
if squadron.aircraft.helicopter and (
|
||||||
FlightType.TRANSPORT in mission_types
|
FlightType.TRANSPORT in mission_types
|
||||||
or FlightType.AIR_ASSAULT in mission_types
|
or FlightType.AIR_ASSAULT in mission_types
|
||||||
@ -247,39 +258,54 @@ class PretenseAircraftGenerator:
|
|||||||
FlightType.SEAD in mission_types
|
FlightType.SEAD in mission_types
|
||||||
or FlightType.SEAD_SWEEP in mission_types
|
or FlightType.SEAD_SWEEP in mission_types
|
||||||
or FlightType.SEAD_ESCORT in mission_types
|
or FlightType.SEAD_ESCORT in mission_types
|
||||||
) and num_of_sead < 2:
|
) and num_of_sead < PRETENSE_SEAD_FLIGHTS_PER_CP:
|
||||||
flight_type = FlightType.SEAD
|
flight_type = FlightType.SEAD
|
||||||
num_of_sead += 1
|
num_of_sead += 1
|
||||||
elif FlightType.DEAD in mission_types and num_of_sead < 2:
|
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||||
|
elif (
|
||||||
|
FlightType.DEAD in mission_types
|
||||||
|
and num_of_sead < PRETENSE_SEAD_FLIGHTS_PER_CP
|
||||||
|
):
|
||||||
flight_type = FlightType.DEAD
|
flight_type = FlightType.DEAD
|
||||||
num_of_sead += 1
|
num_of_sead += 1
|
||||||
|
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||||
elif (
|
elif (
|
||||||
FlightType.CAS in mission_types or FlightType.BAI in mission_types
|
FlightType.CAS in mission_types or FlightType.BAI in mission_types
|
||||||
) and num_of_cas < 2:
|
) and num_of_cas < PRETENSE_CAS_FLIGHTS_PER_CP:
|
||||||
flight_type = FlightType.CAS
|
flight_type = FlightType.CAS
|
||||||
num_of_cas += 1
|
num_of_cas += 1
|
||||||
|
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||||
elif (
|
elif (
|
||||||
FlightType.STRIKE in mission_types
|
FlightType.STRIKE in mission_types
|
||||||
or FlightType.OCA_RUNWAY in mission_types
|
or FlightType.OCA_RUNWAY in mission_types
|
||||||
or FlightType.OCA_AIRCRAFT in mission_types
|
or FlightType.OCA_AIRCRAFT in mission_types
|
||||||
) and num_of_strike < 2:
|
) and num_of_strike < PRETENSE_STRIKE_FLIGHTS_PER_CP:
|
||||||
flight_type = FlightType.STRIKE
|
flight_type = FlightType.STRIKE
|
||||||
num_of_strike += 1
|
num_of_strike += 1
|
||||||
|
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||||
elif (
|
elif (
|
||||||
FlightType.BARCAP in mission_types
|
FlightType.BARCAP in mission_types
|
||||||
or FlightType.TARCAP in mission_types
|
or FlightType.TARCAP in mission_types
|
||||||
or FlightType.ESCORT in mission_types
|
or FlightType.ESCORT in mission_types
|
||||||
) and num_of_cap < 2:
|
) and num_of_cap < PRETENSE_BARCAP_FLIGHTS_PER_CP:
|
||||||
flight_type = FlightType.BARCAP
|
flight_type = FlightType.BARCAP
|
||||||
num_of_cap += 1
|
num_of_cap += 1
|
||||||
|
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||||
|
elif FlightType.AEWC in mission_types:
|
||||||
|
aircraft_per_flight = PRETENSE_AI_AWACS_PER_FLIGHT
|
||||||
|
elif FlightType.REFUELING in mission_types:
|
||||||
|
aircraft_per_flight = PRETENSE_AI_TANKERS_PER_FLIGHT
|
||||||
else:
|
else:
|
||||||
flight_type = random.choice(list(mission_types))
|
flight_type = random.choice(list(mission_types))
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"Generating flight of {aircraft_per_flight} for {flight_type}: {squadron.aircraft}"
|
||||||
|
)
|
||||||
if flight_type == FlightType.TRANSPORT:
|
if flight_type == FlightType.TRANSPORT:
|
||||||
flight = Flight(
|
flight = Flight(
|
||||||
package,
|
package,
|
||||||
squadron,
|
squadron,
|
||||||
1,
|
aircraft_per_flight,
|
||||||
FlightType.PRETENSE_CARGO,
|
FlightType.PRETENSE_CARGO,
|
||||||
StartType.IN_FLIGHT,
|
StartType.IN_FLIGHT,
|
||||||
divert=cp,
|
divert=cp,
|
||||||
@ -288,7 +314,12 @@ class PretenseAircraftGenerator:
|
|||||||
flight.state = Navigating(flight, self.game.settings, waypoint_index=1)
|
flight.state = Navigating(flight, self.game.settings, waypoint_index=1)
|
||||||
else:
|
else:
|
||||||
flight = Flight(
|
flight = Flight(
|
||||||
package, squadron, 1, flight_type, StartType.COLD, divert=cp
|
package,
|
||||||
|
squadron,
|
||||||
|
aircraft_per_flight,
|
||||||
|
flight_type,
|
||||||
|
StartType.COLD,
|
||||||
|
divert=cp,
|
||||||
)
|
)
|
||||||
package.add_flight(flight)
|
package.add_flight(flight)
|
||||||
flight.state = WaitingForStart(
|
flight.state = WaitingForStart(
|
||||||
@ -296,7 +327,34 @@ class PretenseAircraftGenerator:
|
|||||||
)
|
)
|
||||||
|
|
||||||
ato.add_package(package)
|
ato.add_package(package)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def initialize_pretense_data_structures(
|
||||||
|
self, cp: ControlPoint, flight: Flight
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Ensures that the data structures used to pass flight group information
|
||||||
|
to the Pretense init script lua are initialized for use in
|
||||||
|
PretenseFlightGroupSpawner and PretenseLuaGenerator.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cp: Control point to generate aircraft for.
|
||||||
|
flight: The current flight being generated.
|
||||||
|
"""
|
||||||
|
flight_type = flight.flight_type.name
|
||||||
|
cp_side = 2 if cp.captured else 1
|
||||||
|
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||||
|
|
||||||
|
if cp_name_trimmed not in flight.coalition.game.pretense_air[cp_side]:
|
||||||
|
flight.coalition.game.pretense_air[cp_side][cp_name_trimmed] = {}
|
||||||
|
if (
|
||||||
|
flight_type
|
||||||
|
not in flight.coalition.game.pretense_air[cp_side][cp_name_trimmed]
|
||||||
|
):
|
||||||
|
flight.coalition.game.pretense_air[cp_side][cp_name_trimmed][
|
||||||
|
flight_type
|
||||||
|
] = list()
|
||||||
|
return
|
||||||
|
|
||||||
def generate_flights(
|
def generate_flights(
|
||||||
self,
|
self,
|
||||||
@ -319,7 +377,7 @@ class PretenseAircraftGenerator:
|
|||||||
(
|
(
|
||||||
autogenerate_transport_helicopter_squadron,
|
autogenerate_transport_helicopter_squadron,
|
||||||
autogenerate_cargo_plane_squadron,
|
autogenerate_cargo_plane_squadron,
|
||||||
) = self.should_generate_pretense_transports(cp)
|
) = self.should_generate_pretense_transports(cp.coalition.air_wing)
|
||||||
|
|
||||||
if autogenerate_transport_helicopter_squadron:
|
if autogenerate_transport_helicopter_squadron:
|
||||||
self.generate_pretense_transport_squadron(
|
self.generate_pretense_transport_squadron(
|
||||||
@ -345,6 +403,8 @@ class PretenseAircraftGenerator:
|
|||||||
if not package.flights:
|
if not package.flights:
|
||||||
continue
|
continue
|
||||||
for flight in package.flights:
|
for flight in package.flights:
|
||||||
|
self.initialize_pretense_data_structures(cp, flight)
|
||||||
|
|
||||||
if flight.alive:
|
if flight.alive:
|
||||||
if not flight.squadron.location.runway_is_operational():
|
if not flight.squadron.location.runway_is_operational():
|
||||||
logging.warning(
|
logging.warning(
|
||||||
|
|||||||
@ -75,16 +75,6 @@ class PretenseFlightGroupSpawner(FlightGroupSpawner):
|
|||||||
name = namegen.next_pretense_aircraft_name(cp, self.flight)
|
name = namegen.next_pretense_aircraft_name(cp, self.flight)
|
||||||
cp_side = 2 if cp.captured else 1
|
cp_side = 2 if cp.captured else 1
|
||||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||||
flight_type = self.flight.flight_type.name
|
|
||||||
if cp_name_trimmed not in self.flight.coalition.game.pretense_air[cp_side]:
|
|
||||||
self.flight.coalition.game.pretense_air[cp_side][cp_name_trimmed] = {}
|
|
||||||
if (
|
|
||||||
flight_type
|
|
||||||
not in self.flight.coalition.game.pretense_air[cp_side][cp_name_trimmed]
|
|
||||||
):
|
|
||||||
self.flight.coalition.game.pretense_air[cp_side][cp_name_trimmed][
|
|
||||||
flight_type
|
|
||||||
] = list()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.start_type is StartType.IN_FLIGHT:
|
if self.start_type is StartType.IN_FLIGHT:
|
||||||
@ -171,6 +161,10 @@ class PretenseFlightGroupSpawner(FlightGroupSpawner):
|
|||||||
def generate_mid_mission(self) -> FlyingGroup[Any]:
|
def generate_mid_mission(self) -> FlyingGroup[Any]:
|
||||||
assert isinstance(self.flight.state, InFlight)
|
assert isinstance(self.flight.state, InFlight)
|
||||||
name = namegen.next_pretense_aircraft_name(self.flight.departure, self.flight)
|
name = namegen.next_pretense_aircraft_name(self.flight.departure, self.flight)
|
||||||
|
cp_side = 2 if self.flight.departure.captured else 1
|
||||||
|
cp_name_trimmed = "".join(
|
||||||
|
[i for i in self.flight.departure.name.lower() if i.isalnum()]
|
||||||
|
)
|
||||||
speed = self.flight.state.estimate_speed()
|
speed = self.flight.state.estimate_speed()
|
||||||
pos = self.flight.state.estimate_position()
|
pos = self.flight.state.estimate_position()
|
||||||
pos += Vector2(random.randint(100, 1000), random.randint(100, 1000))
|
pos += Vector2(random.randint(100, 1000), random.randint(100, 1000))
|
||||||
@ -192,6 +186,9 @@ class PretenseFlightGroupSpawner(FlightGroupSpawner):
|
|||||||
alt = self.mission_data.cp_stack[cp]
|
alt = self.mission_data.cp_stack[cp]
|
||||||
self.mission_data.cp_stack[cp] += STACK_SEPARATION
|
self.mission_data.cp_stack[cp] += STACK_SEPARATION
|
||||||
|
|
||||||
|
self.flight.coalition.game.pretense_air[cp_side][cp_name_trimmed][
|
||||||
|
self.flight.flight_type.name
|
||||||
|
].append(name)
|
||||||
group = self.mission.flight_group(
|
group = self.mission.flight_group(
|
||||||
country=self.country,
|
country=self.country,
|
||||||
name=name,
|
name=name,
|
||||||
|
|||||||
@ -361,7 +361,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
|||||||
continue
|
continue
|
||||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||||
for mission_type in self.game.pretense_air[cp_side][cp_name_trimmed]:
|
for mission_type in self.game.pretense_air[cp_side][cp_name_trimmed]:
|
||||||
if mission_type == FlightType.TRANSPORT.name:
|
if mission_type == FlightType.PRETENSE_CARGO.name:
|
||||||
for air_group in self.game.pretense_air[cp_side][
|
for air_group in self.game.pretense_air[cp_side][
|
||||||
cp_name_trimmed
|
cp_name_trimmed
|
||||||
][mission_type]:
|
][mission_type]:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user