From e537396fec52a82eff26de82ee2d2234c2241eac Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 6 Oct 2020 21:48:13 -0700 Subject: [PATCH] Stagger package start times. Avoids crowding the taxiways, and adds some life to the end of the mission. Later on, this will happen more naturally because we can delay takeoffs to align with the package's DTOT. --- gen/ato.py | 2 ++ gen/flights/ai_flight_planner.py | 34 +++++++++++++++++++ .../windows/mission/flight/QFlightCreator.py | 2 ++ 3 files changed, 38 insertions(+) diff --git a/gen/ato.py b/gen/ato.py index ff1bb5a9..ee3a3c55 100644 --- a/gen/ato.py +++ b/gen/ato.py @@ -40,6 +40,8 @@ class Package: #: The set of flights in the package. flights: List[Flight] = field(default_factory=list) + delay: int = field(default=0) + join_point: Optional[Point] = field(default=None, init=False, hash=False) split_point: Optional[Point] = field(default=None, init=False, hash=False) ingress_point: Optional[Point] = field(default=None, init=False, hash=False) diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 5deb0c38..7bc3fd26 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -1,6 +1,7 @@ from __future__ import annotations import logging +import random import operator from dataclasses import dataclass from typing import Iterator, List, Optional, Set, TYPE_CHECKING, Tuple, Type @@ -384,6 +385,9 @@ class CoalitionMissionPlanner: MAX_SEAD_RANGE = nm_to_meter(150) MAX_STRIKE_RANGE = nm_to_meter(150) + NON_CAP_MIN_DELAY = 1 + NON_CAP_MAX_DELAY = 5 + def __init__(self, game: Game, is_player: bool) -> None: self.game = game self.is_player = is_player @@ -430,6 +434,8 @@ class CoalitionMissionPlanner: for proposed_mission in self.propose_missions(): self.plan_mission(proposed_mission) + self.stagger_missions() + for cp in self.objective_finder.friendly_control_points(): inventory = self.game.aircraft_inventory.for_control_point(cp) for aircraft, available in inventory.all_aircraft: @@ -467,6 +473,34 @@ class CoalitionMissionPlanner: flight_plan_builder.populate_flight_plan(flight) self.ato.add_package(package) + def stagger_missions(self) -> None: + def start_time_generator(count: int, earliest: int, latest: int, + margin: int) -> Iterator[int]: + interval = latest // count + for time in range(earliest, latest, interval): + error = random.randint(-margin, margin) + yield max(0, time + error) + + dca_types = ( + FlightType.BARCAP, + FlightType.CAP, + FlightType.INTERCEPTION, + ) + + non_dca_packages = [p for p in self.ato.packages if + p.primary_task not in dca_types] + + start_time = start_time_generator( + count=len(non_dca_packages), + earliest=5, + latest=90, + margin=5 + ) + for package in non_dca_packages: + package.delay = next(start_time) + for flight in package.flights: + flight.scheduled_in = package.delay + def message(self, title, text) -> None: """Emits a planning message to the player. diff --git a/qt_ui/windows/mission/flight/QFlightCreator.py b/qt_ui/windows/mission/flight/QFlightCreator.py index fc3f9415..2c8c7dfe 100644 --- a/qt_ui/windows/mission/flight/QFlightCreator.py +++ b/qt_ui/windows/mission/flight/QFlightCreator.py @@ -27,6 +27,7 @@ class QFlightCreator(QDialog): super().__init__() self.game = game + self.package = package self.setWindowTitle("Create flight") self.setWindowIcon(EVENT_ICONS["strike"]) @@ -90,6 +91,7 @@ class QFlightCreator(QDialog): size = self.flight_size_spinner.value() flight = Flight(aircraft, size, origin, task) + flight.scheduled_in = self.package.delay # noinspection PyUnresolvedReferences self.created.emit(flight)