Skip to content

Commit 1668925

Browse files
authored
Make termination of fast forward more robust (#3544)
This PR implements more robust checks to stopping fast forward by: - If the termination condition is that a player reaches a certain state, do not fast forward if there are no players - If the termination condition is that a player reaches a certain state, do not fast forward if the player is already beyond that state - If the termination condition is that a player reaches the IP, do not fast forward if there is no IP or similar waypoint in the flight plan.
1 parent 7d9ce09 commit 1668925

File tree

6 files changed

+106
-14
lines changed

6 files changed

+106
-14
lines changed

game/ato/flightstate/inflight.py

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,76 @@ def spawn_type(self) -> StartType:
168168
return StartType.IN_FLIGHT
169169

170170
def should_halt_sim(self) -> bool:
171-
if (
172-
self.flight.client_count > 0
173-
and self.settings.fast_forward_stop_condition
174-
== FastForwardStopCondition.PLAYER_AT_IP
175-
and self.is_at_ip
176-
):
171+
if self._halt_sim_for_player_at_ip():
177172
logging.info(
178173
f"Interrupting simulation because {self.flight} has players and has "
179174
"reached IP"
180175
)
181176
return True
177+
178+
if self.settings.fast_forward_stop_condition in {
179+
FastForwardStopCondition.PLAYER_TAKEOFF,
180+
FastForwardStopCondition.PLAYER_TAXI,
181+
FastForwardStopCondition.PLAYER_STARTUP,
182+
}:
183+
logging.info(
184+
f"Interrupting simulation because {self.flight} has players and is already inflight "
185+
)
186+
return True
182187
return False
188+
189+
def _halt_sim_for_player_at_ip(self) -> bool:
190+
if (
191+
self.settings.fast_forward_stop_condition
192+
!= FastForwardStopCondition.PLAYER_AT_IP
193+
):
194+
return False
195+
196+
if self.flight.client_count == 0:
197+
return False
198+
199+
ingress_waypoint_types = {
200+
FlightWaypointType.INGRESS_BAI,
201+
FlightWaypointType.INGRESS_CAS,
202+
FlightWaypointType.INGRESS_DEAD,
203+
FlightWaypointType.INGRESS_OCA_AIRCRAFT,
204+
FlightWaypointType.INGRESS_OCA_RUNWAY,
205+
FlightWaypointType.INGRESS_SEAD,
206+
FlightWaypointType.INGRESS_STRIKE,
207+
FlightWaypointType.INGRESS_AIR_ASSAULT,
208+
}
209+
210+
flight_plan_has_ip = False
211+
flight_plan_has_patrol_start = False # BARCAP plans don't have IP, just a PATROL_TRACK at the start waypoint
212+
flight_plan_has_nav = False # CAS plans don't have IP, but has NAV points.
213+
for waypoint_index in range(
214+
self.waypoint_index, len(self.flight.flight_plan.waypoints)
215+
):
216+
if (
217+
self.flight.flight_plan.waypoints[waypoint_index].waypoint_type
218+
in ingress_waypoint_types
219+
):
220+
flight_plan_has_ip = True
221+
break
222+
if (
223+
self.flight.flight_plan.waypoints[waypoint_index].waypoint_type
224+
== FlightWaypointType.PATROL_TRACK
225+
):
226+
flight_plan_has_patrol_start = True
227+
if (
228+
self.flight.flight_plan.waypoints[waypoint_index].waypoint_type
229+
== FlightWaypointType.NAV
230+
):
231+
flight_plan_has_nav = True
232+
233+
if flight_plan_has_ip:
234+
return self.current_waypoint.waypoint_type in ingress_waypoint_types
235+
if flight_plan_has_patrol_start:
236+
return (
237+
self.current_waypoint.waypoint_type == FlightWaypointType.PATROL_TRACK
238+
)
239+
if flight_plan_has_nav:
240+
return self.current_waypoint.waypoint_type == FlightWaypointType.NAV
241+
242+
# Not a recognized flight plan type, stop sim to be on the safe side.
243+
return True

game/ato/flightstate/takeoff.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ def should_halt_sim(self) -> bool:
5555
"reached takeoff time"
5656
)
5757
return True
58+
59+
if self.settings.fast_forward_stop_condition in {
60+
FastForwardStopCondition.PLAYER_TAXI,
61+
FastForwardStopCondition.PLAYER_STARTUP,
62+
}:
63+
logging.info(
64+
f"Interrupting simulation because {self.flight} has players and is already taking off "
65+
)
66+
return True
5867
return False
5968

6069
@property

game/ato/flightstate/taxi.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ def should_halt_sim(self) -> bool:
4747
"reached taxi time"
4848
)
4949
return True
50+
if self.settings.fast_forward_stop_condition in {
51+
FastForwardStopCondition.PLAYER_STARTUP,
52+
}:
53+
logging.info(
54+
f"Interrupting simulation because {self.flight} has players and is already taxiing "
55+
)
56+
return True
5057
return False
5158

5259
@property

game/game.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,3 +613,10 @@ def process_win_loss(self, turn_state: TurnState) -> None:
613613
)
614614
elif turn_state is TurnState.LOSS:
615615
self.message("Game Over, you lose. Start a new campaign to continue.")
616+
617+
def ato_has_clients(self) -> bool:
618+
for package in self.blue.ato.packages:
619+
for flight in package.flights:
620+
if flight.client_count > 0:
621+
return True
622+
return False

game/sim/missionsimulation.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ def tick(
5656
):
5757
events.complete_simulation()
5858
return events
59+
60+
# Stop fast forward if there are no clients and the settings require a player to reach a certain state.
61+
if (
62+
not self.game.ato_has_clients()
63+
and self.game.settings.fast_forward_stop_condition
64+
in {
65+
FastForwardStopCondition.PLAYER_TAKEOFF,
66+
FastForwardStopCondition.PLAYER_TAXI,
67+
FastForwardStopCondition.PLAYER_STARTUP,
68+
FastForwardStopCondition.PLAYER_AT_IP,
69+
}
70+
):
71+
events.complete_simulation()
72+
return events
73+
5974
self.aircraft_simulation.on_game_tick(
6075
events, self.time, TICK, combat_resolution_method, force_continue
6176
)

qt_ui/widgets/QTopPanel.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,6 @@ def fix_tots(packages: List[Package], now: datetime) -> None:
149149
estimator = TotEstimator(package)
150150
package.time_over_target = estimator.earliest_tot(now)
151151

152-
def ato_has_clients(self) -> bool:
153-
for package in self.game.blue.ato.packages:
154-
for flight in package.flights:
155-
if flight.client_count > 0:
156-
return True
157-
return False
158-
159152
def confirm_no_client_launch(self) -> bool:
160153
result = QMessageBox.question(
161154
self,
@@ -248,7 +241,7 @@ def check_no_missing_pilots(self) -> bool:
248241

249242
def launch_mission(self):
250243
"""Finishes planning and waits for mission completion."""
251-
if not self.ato_has_clients() and not self.confirm_no_client_launch():
244+
if not self.game.ato_has_clients() and not self.confirm_no_client_launch():
252245
return
253246

254247
if self.check_no_missing_pilots():

0 commit comments

Comments
 (0)