diff --git a/game/ato/flightplans/custom.py b/game/ato/flightplans/custom.py index 3f89eee9..41e01fa2 100644 --- a/game/ato/flightplans/custom.py +++ b/game/ato/flightplans/custom.py @@ -48,7 +48,7 @@ class CustomFlightPlan(FlightPlan[CustomLayout]): def tot_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None: if waypoint == self.tot_waypoint: - return self.package.time_over_target + self.tot_offset + return self.tot return None def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None: diff --git a/game/ato/flightplans/flightplan.py b/game/ato/flightplans/flightplan.py index fbba3833..1b7384c9 100644 --- a/game/ato/flightplans/flightplan.py +++ b/game/ato/flightplans/flightplan.py @@ -249,11 +249,15 @@ class FlightPlan(ABC, Generic[LayoutT]): self._travel_time_to_waypoint(self.tot_waypoint) + self.estimate_startup() + self.estimate_ground_ops() + + self.estimate_takeoff_time() ) def startup_time(self) -> datetime: return ( - self.takeoff_time() - self.estimate_startup() - self.estimate_ground_ops() + self.takeoff_time() + - self.estimate_startup() + - self.estimate_ground_ops() + - self.estimate_takeoff_time() ) def estimate_startup(self) -> timedelta: @@ -273,6 +277,10 @@ class FlightPlan(ABC, Generic[LayoutT]): else: return timedelta(minutes=8) + @staticmethod + def estimate_takeoff_time() -> timedelta: + return timedelta(seconds=30) + @property def is_airassault(self) -> bool: return False diff --git a/game/ato/flightplans/formation.py b/game/ato/flightplans/formation.py index cd90b493..3d42ac04 100644 --- a/game/ato/flightplans/formation.py +++ b/game/ato/flightplans/formation.py @@ -85,9 +85,9 @@ class FormationFlightPlan(LoiterFlightPlan, ABC): def tot_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None: if waypoint == self.layout.join: - return self.join_time + self.tot_offset + return self.join_time elif waypoint == self.layout.split: - return self.split_time + self.tot_offset + return self.split_time return None @property diff --git a/game/ato/flightplans/loiter.py b/game/ato/flightplans/loiter.py index 32d753c7..65698002 100644 --- a/game/ato/flightplans/loiter.py +++ b/game/ato/flightplans/loiter.py @@ -31,7 +31,7 @@ class LoiterFlightPlan(StandardFlightPlan[Any], ABC): def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None: if waypoint == self.layout.hold: - return self.push_time + self.tot_offset + return self.push_time return None def total_time_between_waypoints( diff --git a/game/ato/flightplans/sweep.py b/game/ato/flightplans/sweep.py index 428d3e6d..9229519b 100644 --- a/game/ato/flightplans/sweep.py +++ b/game/ato/flightplans/sweep.py @@ -66,14 +66,14 @@ class SweepFlightPlan(LoiterFlightPlan): def tot_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None: if waypoint == self.layout.sweep_start: - return self.sweep_start_time + self.tot_offset + return self.sweep_start_time if waypoint == self.layout.sweep_end: - return self.sweep_end_time + self.tot_offset + return self.sweep_end_time return None def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None: if waypoint == self.layout.hold: - return self.push_time + self.tot_offset + return self.push_time return None @property diff --git a/game/ato/flightstate/flightstate.py b/game/ato/flightstate/flightstate.py index ad8d8649..2c6c8887 100644 --- a/game/ato/flightstate/flightstate.py +++ b/game/ato/flightstate/flightstate.py @@ -26,7 +26,7 @@ class FlightState(ABC): start_time = self.flight.flight_plan.startup_time() if start_time <= now: - self._set_active_flight_state(now) + self._set_active_flight_state(start_time) else: self.flight.set_state( WaitingForStart(self.flight, self.settings, start_time) diff --git a/game/ato/flightstate/inflight.py b/game/ato/flightstate/inflight.py index 53e4f852..00b391f4 100644 --- a/game/ato/flightstate/inflight.py +++ b/game/ato/flightstate/inflight.py @@ -26,6 +26,7 @@ class InFlight(FlightState, ABC): settings: Settings, waypoint_index: int, has_aborted: bool = False, + elapsed_time: timedelta = timedelta(), ) -> None: super().__init__(flight, settings) waypoints = self.flight.flight_plan.waypoints @@ -35,7 +36,7 @@ class InFlight(FlightState, ABC): # TODO: Error checking for flight plans without landing waypoints. self.next_waypoint = waypoints[self.waypoint_index + 1] self.total_time_to_next_waypoint = self.travel_time_between_waypoints() - self.elapsed_time = timedelta() + self.elapsed_time = elapsed_time self.current_waypoint_elapsed = False @property diff --git a/game/ato/flightstate/startup.py b/game/ato/flightstate/startup.py index f9f7c25d..5de5aede 100644 --- a/game/ato/flightstate/startup.py +++ b/game/ato/flightstate/startup.py @@ -24,7 +24,7 @@ class StartUp(AtDeparture): ) -> None: if time < self.completion_time: return - self.flight.set_state(Taxi(self.flight, self.settings, time)) + self.flight.set_state(Taxi(self.flight, self.settings, self.completion_time)) @property def is_waiting_for_start(self) -> bool: diff --git a/game/ato/flightstate/takeoff.py b/game/ato/flightstate/takeoff.py index 8d99d540..1ff2facf 100644 --- a/game/ato/flightstate/takeoff.py +++ b/game/ato/flightstate/takeoff.py @@ -19,14 +19,19 @@ class Takeoff(AtDeparture): def __init__(self, flight: Flight, settings: Settings, now: datetime) -> None: super().__init__(flight, settings) # TODO: Not accounted for in FlightPlan, can cause discrepancy without loiter. - self.completion_time = now + timedelta(seconds=30) + self.completion_time = now + flight.flight_plan.estimate_takeoff_time() def on_game_tick( self, events: GameUpdateEvents, time: datetime, duration: timedelta ) -> None: if time < self.completion_time: return - self.flight.set_state(Navigating(self.flight, self.settings, waypoint_index=0)) + rollover = time - self.completion_time + self.flight.set_state( + Navigating( + self.flight, self.settings, waypoint_index=0, elapsed_time=rollover + ) + ) @property def is_waiting_for_start(self) -> bool: diff --git a/game/ato/flightstate/taxi.py b/game/ato/flightstate/taxi.py index 0ae35dbe..3f44f174 100644 --- a/game/ato/flightstate/taxi.py +++ b/game/ato/flightstate/taxi.py @@ -24,7 +24,7 @@ class Taxi(AtDeparture): ) -> None: if time < self.completion_time: return - self.flight.set_state(Takeoff(self.flight, self.settings, time)) + self.flight.set_state(Takeoff(self.flight, self.settings, self.completion_time)) @property def is_waiting_for_start(self) -> bool: diff --git a/game/ato/traveltime.py b/game/ato/traveltime.py index e7457a58..66afa547 100644 --- a/game/ato/traveltime.py +++ b/game/ato/traveltime.py @@ -60,5 +60,4 @@ class TotEstimator: The earliest possible TOT for the given flight. """ flight_time = flight.flight_plan.minimum_duration_from_start_to_tot() - offset = flight.flight_plan.tot_offset - return now + flight_time - offset + return now + flight_time diff --git a/qt_ui/windows/mission/flight/QFlightPlanner.py b/qt_ui/windows/mission/flight/QFlightPlanner.py index 7ca1f127..362c41e7 100644 --- a/qt_ui/windows/mission/flight/QFlightPlanner.py +++ b/qt_ui/windows/mission/flight/QFlightPlanner.py @@ -14,9 +14,10 @@ class QFlightPlanner(QTabWidget): super().__init__() self.payload_tab = QFlightPayloadTab(flight, gm.game) - self.waypoint_tab = QFlightWaypointTab(gm.game, package_model.package, flight) - self.payload_tab = QFlightPayloadTab(flight, gm.game) + self.waypoint_tab = QFlightWaypointTab(gm.game, package_model.package, flight) + self.waypoint_tab.loadout_changed.connect(self.payload_tab.reload_from_flight) + self.general_settings_tab = QGeneralFlightSettingsTab( gm, package_model, @@ -27,8 +28,6 @@ class QFlightPlanner(QTabWidget): self.general_settings_tab.flight_size_changed.connect( self.payload_tab.resize_for_flight ) - self.waypoint_tab = QFlightWaypointTab(gm.game, package_model.package, flight) - self.waypoint_tab.loadout_changed.connect(self.payload_tab.reload_from_flight) self.addTab(self.general_settings_tab, "General Flight settings") self.addTab(self.payload_tab, "Payload") self.addTab(self.waypoint_tab, "Waypoints")