mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Separate combat as a distinct flight state.
Will be used later to simulate combat. https://github.com/dcs-liberation/dcs_liberation/issues/1680
This commit is contained in:
parent
d9108a7ca6
commit
ce4628b64f
@ -151,5 +151,10 @@ class Flight:
|
|||||||
def on_game_tick(self, time: datetime, duration: timedelta) -> None:
|
def on_game_tick(self, time: datetime, duration: timedelta) -> None:
|
||||||
self.state.on_game_tick(time, duration)
|
self.state.on_game_tick(time, duration)
|
||||||
|
|
||||||
def should_halt_sim(self, enemy_aircraft_coverage: AircraftEngagementZones) -> bool:
|
def check_for_combat(
|
||||||
return self.state.should_halt_sim(enemy_aircraft_coverage)
|
self, enemy_aircraft_coverage: AircraftEngagementZones
|
||||||
|
) -> None:
|
||||||
|
self.state.check_for_combat(enemy_aircraft_coverage)
|
||||||
|
|
||||||
|
def should_halt_sim(self) -> bool:
|
||||||
|
return self.state.should_halt_sim()
|
||||||
|
|||||||
@ -22,7 +22,12 @@ class FlightState(ABC):
|
|||||||
def on_game_tick(self, time: datetime, duration: timedelta) -> None:
|
def on_game_tick(self, time: datetime, duration: timedelta) -> None:
|
||||||
...
|
...
|
||||||
|
|
||||||
def should_halt_sim(self, enemy_aircraft_coverage: AircraftEngagementZones) -> bool:
|
def check_for_combat(
|
||||||
|
self, enemy_aircraft_coverage: AircraftEngagementZones
|
||||||
|
) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def should_halt_sim(self) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
56
game/ato/flightstate/incombat.py
Normal file
56
game/ato/flightstate/incombat.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from dcs import Point
|
||||||
|
|
||||||
|
from game.utils import Distance, Speed
|
||||||
|
from .inflight import InFlight
|
||||||
|
from ..starttype import StartType
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from game.sim.aircraftengagementzones import AircraftEngagementZones
|
||||||
|
|
||||||
|
|
||||||
|
class InCombat(InFlight):
|
||||||
|
def __init__(self, previous_state: InFlight, description: str) -> None:
|
||||||
|
super().__init__(
|
||||||
|
previous_state.flight,
|
||||||
|
previous_state.settings,
|
||||||
|
previous_state.waypoint_index,
|
||||||
|
)
|
||||||
|
self.previous_state = previous_state
|
||||||
|
self._description = description
|
||||||
|
|
||||||
|
def estimate_position(self) -> Point:
|
||||||
|
return self.previous_state.estimate_position()
|
||||||
|
|
||||||
|
def estimate_altitude(self) -> tuple[Distance, str]:
|
||||||
|
return self.previous_state.estimate_altitude()
|
||||||
|
|
||||||
|
def estimate_speed(self) -> Speed:
|
||||||
|
return self.previous_state.estimate_speed()
|
||||||
|
|
||||||
|
def on_game_tick(self, time: datetime, duration: timedelta) -> None:
|
||||||
|
raise RuntimeError("Cannot simulate combat")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_waiting_for_start(self) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def should_halt_sim(self) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def check_for_combat(
|
||||||
|
self, enemy_aircraft_coverage: AircraftEngagementZones
|
||||||
|
) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def spawn_type(self) -> StartType:
|
||||||
|
return StartType.IN_FLIGHT
|
||||||
|
|
||||||
|
@property
|
||||||
|
def description(self) -> str:
|
||||||
|
return self._description
|
||||||
@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ from game.ato.flightstate.flightstate import FlightState
|
|||||||
from game.ato.flightwaypoint import FlightWaypoint
|
from game.ato.flightwaypoint import FlightWaypoint
|
||||||
from game.ato.flightwaypointtype import FlightWaypointType
|
from game.ato.flightwaypointtype import FlightWaypointType
|
||||||
from game.ato.starttype import StartType
|
from game.ato.starttype import StartType
|
||||||
from game.utils import Distance, LBS_TO_KG, Speed, meters, pairwise
|
from game.utils import Distance, LBS_TO_KG, Speed, pairwise
|
||||||
from gen.flights.flightplan import LoiterFlightPlan
|
from gen.flights.flightplan import LoiterFlightPlan
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -20,11 +21,7 @@ if TYPE_CHECKING:
|
|||||||
from game.sim.aircraftengagementzones import AircraftEngagementZones
|
from game.sim.aircraftengagementzones import AircraftEngagementZones
|
||||||
|
|
||||||
|
|
||||||
def lerp(v0: float, v1: float, t: float) -> float:
|
class InFlight(FlightState, ABC):
|
||||||
return (1 - t) * v0 + t * v1
|
|
||||||
|
|
||||||
|
|
||||||
class InFlight(FlightState):
|
|
||||||
def __init__(self, flight: Flight, settings: Settings, waypoint_index: int) -> None:
|
def __init__(self, flight: Flight, settings: Settings, waypoint_index: int) -> None:
|
||||||
super().__init__(flight, settings)
|
super().__init__(flight, settings)
|
||||||
waypoints = self.flight.flight_plan.waypoints
|
waypoints = self.flight.flight_plan.waypoints
|
||||||
@ -52,36 +49,17 @@ class InFlight(FlightState):
|
|||||||
travel_time -= self.flight.flight_plan.hold_duration
|
travel_time -= self.flight.flight_plan.hold_duration
|
||||||
return travel_time
|
return travel_time
|
||||||
|
|
||||||
def progress(self) -> float:
|
@abstractmethod
|
||||||
return (
|
|
||||||
self.elapsed_time.total_seconds()
|
|
||||||
/ self.total_time_to_next_waypoint.total_seconds()
|
|
||||||
)
|
|
||||||
|
|
||||||
def estimate_position(self) -> Point:
|
def estimate_position(self) -> Point:
|
||||||
x0 = self.current_waypoint.position.x
|
...
|
||||||
y0 = self.current_waypoint.position.y
|
|
||||||
x1 = self.next_waypoint.position.x
|
|
||||||
y1 = self.next_waypoint.position.y
|
|
||||||
progress = self.progress()
|
|
||||||
return Point(lerp(x0, x1, progress), lerp(y0, y1, progress))
|
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
def estimate_altitude(self) -> tuple[Distance, str]:
|
def estimate_altitude(self) -> tuple[Distance, str]:
|
||||||
return (
|
...
|
||||||
meters(
|
|
||||||
lerp(
|
|
||||||
self.current_waypoint.alt.meters,
|
|
||||||
self.next_waypoint.alt.meters,
|
|
||||||
self.progress(),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
self.current_waypoint.alt_type,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
def estimate_speed(self) -> Speed:
|
def estimate_speed(self) -> Speed:
|
||||||
return self.flight.flight_plan.speed_between_waypoints(
|
...
|
||||||
self.current_waypoint, self.next_waypoint
|
|
||||||
)
|
|
||||||
|
|
||||||
def estimate_fuel_at_current_waypoint(self) -> float:
|
def estimate_fuel_at_current_waypoint(self) -> float:
|
||||||
initial_fuel = super().estimate_fuel()
|
initial_fuel = super().estimate_fuel()
|
||||||
@ -95,21 +73,10 @@ class InFlight(FlightState):
|
|||||||
initial_fuel -= consumption * LBS_TO_KG
|
initial_fuel -= consumption * LBS_TO_KG
|
||||||
return initial_fuel
|
return initial_fuel
|
||||||
|
|
||||||
def estimate_fuel(self) -> float:
|
|
||||||
initial_fuel = self.estimate_fuel_at_current_waypoint()
|
|
||||||
ppm = self.flight.flight_plan.fuel_rate_to_between_points(
|
|
||||||
self.current_waypoint, self.next_waypoint
|
|
||||||
)
|
|
||||||
if ppm is None:
|
|
||||||
return initial_fuel
|
|
||||||
position = self.estimate_position()
|
|
||||||
distance = meters(self.current_waypoint.position.distance_to_point(position))
|
|
||||||
consumption = distance.nautical_miles * ppm * LBS_TO_KG
|
|
||||||
return initial_fuel - consumption
|
|
||||||
|
|
||||||
def next_waypoint_state(self) -> FlightState:
|
def next_waypoint_state(self) -> FlightState:
|
||||||
from game.ato.flightstate.loiter import Loiter
|
from .loiter import Loiter
|
||||||
from game.ato.flightstate.racetrack import RaceTrack
|
from .racetrack import RaceTrack
|
||||||
|
from .navigating import Navigating
|
||||||
|
|
||||||
new_index = self.waypoint_index + 1
|
new_index = self.waypoint_index + 1
|
||||||
if self.next_waypoint.waypoint_type is FlightWaypointType.LANDING_POINT:
|
if self.next_waypoint.waypoint_type is FlightWaypointType.LANDING_POINT:
|
||||||
@ -118,7 +85,7 @@ class InFlight(FlightState):
|
|||||||
return RaceTrack(self.flight, self.settings, new_index)
|
return RaceTrack(self.flight, self.settings, new_index)
|
||||||
if self.next_waypoint.waypoint_type is FlightWaypointType.LOITER:
|
if self.next_waypoint.waypoint_type is FlightWaypointType.LOITER:
|
||||||
return Loiter(self.flight, self.settings, new_index)
|
return Loiter(self.flight, self.settings, new_index)
|
||||||
return InFlight(self.flight, self.settings, new_index)
|
return Navigating(self.flight, self.settings, new_index)
|
||||||
|
|
||||||
def advance_to_next_waypoint(self) -> None:
|
def advance_to_next_waypoint(self) -> None:
|
||||||
self.flight.set_state(self.next_waypoint_state())
|
self.flight.set_state(self.next_waypoint_state())
|
||||||
@ -128,7 +95,11 @@ class InFlight(FlightState):
|
|||||||
if self.elapsed_time > self.total_time_to_next_waypoint:
|
if self.elapsed_time > self.total_time_to_next_waypoint:
|
||||||
self.advance_to_next_waypoint()
|
self.advance_to_next_waypoint()
|
||||||
|
|
||||||
def should_halt_sim(self, enemy_aircraft_coverage: AircraftEngagementZones) -> bool:
|
def check_for_combat(
|
||||||
|
self, enemy_aircraft_coverage: AircraftEngagementZones
|
||||||
|
) -> None:
|
||||||
|
from game.ato.flightstate.incombat import InCombat
|
||||||
|
|
||||||
contact_types = {
|
contact_types = {
|
||||||
FlightWaypointType.INGRESS_BAI,
|
FlightWaypointType.INGRESS_BAI,
|
||||||
FlightWaypointType.INGRESS_CAS,
|
FlightWaypointType.INGRESS_CAS,
|
||||||
@ -144,7 +115,7 @@ class InFlight(FlightState):
|
|||||||
f"Interrupting simulation because {self.flight} has reached its "
|
f"Interrupting simulation because {self.flight} has reached its "
|
||||||
"ingress point"
|
"ingress point"
|
||||||
)
|
)
|
||||||
return True
|
self.flight.set_state(InCombat(self, "At IP"))
|
||||||
|
|
||||||
threat_zone = self.flight.squadron.coalition.opponent.threat_zone
|
threat_zone = self.flight.squadron.coalition.opponent.threat_zone
|
||||||
if threat_zone.threatened_by_air_defense(self.estimate_position()):
|
if threat_zone.threatened_by_air_defense(self.estimate_position()):
|
||||||
@ -152,16 +123,16 @@ class InFlight(FlightState):
|
|||||||
f"Interrupting simulation because {self.flight} has encountered enemy "
|
f"Interrupting simulation because {self.flight} has encountered enemy "
|
||||||
"air defenses"
|
"air defenses"
|
||||||
)
|
)
|
||||||
return True
|
self.flight.set_state(InCombat(self, "In combat with enemy air defenses"))
|
||||||
|
|
||||||
if enemy_aircraft_coverage.covers(self.estimate_position()):
|
if enemy_aircraft_coverage.covers(self.estimate_position()):
|
||||||
logging.info(
|
logging.info(
|
||||||
f"Interrupting simulation because {self.flight} has encountered enemy "
|
f"Interrupting simulation because {self.flight} has encountered enemy "
|
||||||
"air-to-air patrol"
|
"air-to-air patrol"
|
||||||
)
|
)
|
||||||
return True
|
self.flight.set_state(
|
||||||
|
InCombat(self, "In combat with enemy air-to-air patrol")
|
||||||
return False
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_waiting_for_start(self) -> bool:
|
def is_waiting_for_start(self) -> bool:
|
||||||
|
|||||||
@ -6,6 +6,7 @@ from typing import TYPE_CHECKING
|
|||||||
from dcs import Point
|
from dcs import Point
|
||||||
|
|
||||||
from game.ato.flightstate import FlightState, InFlight
|
from game.ato.flightstate import FlightState, InFlight
|
||||||
|
from game.ato.flightstate.navigating import Navigating
|
||||||
from game.utils import Distance, Speed
|
from game.utils import Distance, Speed
|
||||||
from gen.flights.flightplan import LoiterFlightPlan
|
from gen.flights.flightplan import LoiterFlightPlan
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ class Loiter(InFlight):
|
|||||||
def next_waypoint_state(self) -> FlightState:
|
def next_waypoint_state(self) -> FlightState:
|
||||||
# Do not automatically advance to the next waypoint. Just proceed from the
|
# Do not automatically advance to the next waypoint. Just proceed from the
|
||||||
# current one with the normal flying state.
|
# current one with the normal flying state.
|
||||||
return InFlight(self.flight, self.settings, self.waypoint_index)
|
return Navigating(self.flight, self.settings, self.waypoint_index)
|
||||||
|
|
||||||
def travel_time_between_waypoints(self) -> timedelta:
|
def travel_time_between_waypoints(self) -> timedelta:
|
||||||
return self.hold_duration
|
return self.hold_duration
|
||||||
|
|||||||
73
game/ato/flightstate/navigating.py
Normal file
73
game/ato/flightstate/navigating.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from dcs import Point
|
||||||
|
|
||||||
|
from game.ato.flightstate import InFlight
|
||||||
|
from game.ato.starttype import StartType
|
||||||
|
from game.utils import Distance, LBS_TO_KG, Speed, meters
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def lerp(v0: float, v1: float, t: float) -> float:
|
||||||
|
return (1 - t) * v0 + t * v1
|
||||||
|
|
||||||
|
|
||||||
|
class Navigating(InFlight):
|
||||||
|
def progress(self) -> float:
|
||||||
|
return (
|
||||||
|
self.elapsed_time.total_seconds()
|
||||||
|
/ self.total_time_to_next_waypoint.total_seconds()
|
||||||
|
)
|
||||||
|
|
||||||
|
def estimate_position(self) -> Point:
|
||||||
|
x0 = self.current_waypoint.position.x
|
||||||
|
y0 = self.current_waypoint.position.y
|
||||||
|
x1 = self.next_waypoint.position.x
|
||||||
|
y1 = self.next_waypoint.position.y
|
||||||
|
progress = self.progress()
|
||||||
|
return Point(lerp(x0, x1, progress), lerp(y0, y1, progress))
|
||||||
|
|
||||||
|
def estimate_altitude(self) -> tuple[Distance, str]:
|
||||||
|
return (
|
||||||
|
meters(
|
||||||
|
lerp(
|
||||||
|
self.current_waypoint.alt.meters,
|
||||||
|
self.next_waypoint.alt.meters,
|
||||||
|
self.progress(),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
self.current_waypoint.alt_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
def estimate_speed(self) -> Speed:
|
||||||
|
return self.flight.flight_plan.speed_between_waypoints(
|
||||||
|
self.current_waypoint, self.next_waypoint
|
||||||
|
)
|
||||||
|
|
||||||
|
def estimate_fuel(self) -> float:
|
||||||
|
initial_fuel = self.estimate_fuel_at_current_waypoint()
|
||||||
|
ppm = self.flight.flight_plan.fuel_rate_to_between_points(
|
||||||
|
self.current_waypoint, self.next_waypoint
|
||||||
|
)
|
||||||
|
if ppm is None:
|
||||||
|
return initial_fuel
|
||||||
|
position = self.estimate_position()
|
||||||
|
distance = meters(self.current_waypoint.position.distance_to_point(position))
|
||||||
|
consumption = distance.nautical_miles * ppm * LBS_TO_KG
|
||||||
|
return initial_fuel - consumption
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_waiting_for_start(self) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def spawn_type(self) -> StartType:
|
||||||
|
return StartType.IN_FLIGHT
|
||||||
|
|
||||||
|
@property
|
||||||
|
def description(self) -> str:
|
||||||
|
return f"Flying to {self.next_waypoint.name}"
|
||||||
@ -11,7 +11,6 @@ from ..starttype import StartType
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game.ato.flight import Flight
|
from game.ato.flight import Flight
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
from game.sim.aircraftengagementzones import AircraftEngagementZones
|
|
||||||
|
|
||||||
|
|
||||||
class StartUp(FlightState):
|
class StartUp(FlightState):
|
||||||
@ -32,7 +31,7 @@ class StartUp(FlightState):
|
|||||||
def spawn_type(self) -> StartType:
|
def spawn_type(self) -> StartType:
|
||||||
return StartType.COLD
|
return StartType.COLD
|
||||||
|
|
||||||
def should_halt_sim(self, enemy_aircraft_coverage: AircraftEngagementZones) -> bool:
|
def should_halt_sim(self) -> bool:
|
||||||
if (
|
if (
|
||||||
self.flight.client_count > 0
|
self.flight.client_count > 0
|
||||||
and self.settings.player_mission_interrupts_sim_at is StartType.COLD
|
and self.settings.player_mission_interrupts_sim_at is StartType.COLD
|
||||||
|
|||||||
@ -5,14 +5,13 @@ from datetime import datetime, timedelta
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from .flightstate import FlightState
|
from .flightstate import FlightState
|
||||||
from .inflight import InFlight
|
from .navigating import Navigating
|
||||||
from ..starttype import StartType
|
from ..starttype import StartType
|
||||||
from ...utils import LBS_TO_KG
|
from ...utils import LBS_TO_KG
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game.ato.flight import Flight
|
from game.ato.flight import Flight
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
from game.sim.aircraftengagementzones import AircraftEngagementZones
|
|
||||||
|
|
||||||
|
|
||||||
class Takeoff(FlightState):
|
class Takeoff(FlightState):
|
||||||
@ -24,7 +23,7 @@ class Takeoff(FlightState):
|
|||||||
def on_game_tick(self, time: datetime, duration: timedelta) -> None:
|
def on_game_tick(self, time: datetime, duration: timedelta) -> None:
|
||||||
if time < self.completion_time:
|
if time < self.completion_time:
|
||||||
return
|
return
|
||||||
self.flight.set_state(InFlight(self.flight, self.settings, waypoint_index=0))
|
self.flight.set_state(Navigating(self.flight, self.settings, waypoint_index=0))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_waiting_for_start(self) -> bool:
|
def is_waiting_for_start(self) -> bool:
|
||||||
@ -40,7 +39,7 @@ class Takeoff(FlightState):
|
|||||||
return initial_fuel
|
return initial_fuel
|
||||||
return initial_fuel - self.flight.unit_type.fuel_consumption.taxi * LBS_TO_KG
|
return initial_fuel - self.flight.unit_type.fuel_consumption.taxi * LBS_TO_KG
|
||||||
|
|
||||||
def should_halt_sim(self, enemy_aircraft_coverage: AircraftEngagementZones) -> bool:
|
def should_halt_sim(self) -> bool:
|
||||||
if (
|
if (
|
||||||
self.flight.client_count > 0
|
self.flight.client_count > 0
|
||||||
and self.settings.player_mission_interrupts_sim_at is StartType.RUNWAY
|
and self.settings.player_mission_interrupts_sim_at is StartType.RUNWAY
|
||||||
|
|||||||
@ -11,7 +11,6 @@ from ..starttype import StartType
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game.ato.flight import Flight
|
from game.ato.flight import Flight
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
from game.sim.aircraftengagementzones import AircraftEngagementZones
|
|
||||||
|
|
||||||
|
|
||||||
class Taxi(FlightState):
|
class Taxi(FlightState):
|
||||||
@ -32,7 +31,7 @@ class Taxi(FlightState):
|
|||||||
def spawn_type(self) -> StartType:
|
def spawn_type(self) -> StartType:
|
||||||
return StartType.WARM
|
return StartType.WARM
|
||||||
|
|
||||||
def should_halt_sim(self, enemy_aircraft_coverage: AircraftEngagementZones) -> bool:
|
def should_halt_sim(self) -> bool:
|
||||||
if (
|
if (
|
||||||
self.flight.client_count > 0
|
self.flight.client_count > 0
|
||||||
and self.settings.player_mission_interrupts_sim_at is StartType.WARM
|
and self.settings.player_mission_interrupts_sim_at is StartType.WARM
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
from game.ato.starttype import StartType
|
from game.ato.starttype import StartType
|
||||||
from .flightstate import FlightState
|
from .flightstate import FlightState
|
||||||
from .inflight import InFlight
|
from .navigating import Navigating
|
||||||
from .startup import StartUp
|
from .startup import StartUp
|
||||||
from .takeoff import Takeoff
|
from .takeoff import Takeoff
|
||||||
from .taxi import Taxi
|
from .taxi import Taxi
|
||||||
@ -41,7 +41,7 @@ class WaitingForStart(FlightState):
|
|||||||
elif self.start_type is StartType.RUNWAY:
|
elif self.start_type is StartType.RUNWAY:
|
||||||
new_state = Takeoff(self.flight, self.settings, time)
|
new_state = Takeoff(self.flight, self.settings, time)
|
||||||
else:
|
else:
|
||||||
new_state = InFlight(self.flight, self.settings, waypoint_index=0)
|
new_state = Navigating(self.flight, self.settings, waypoint_index=0)
|
||||||
self.flight.set_state(new_state)
|
self.flight.set_state(new_state)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@ -40,7 +40,11 @@ class AircraftSimulation:
|
|||||||
blue_a2a = AircraftEngagementZones.from_ato(self.game.blue.ato)
|
blue_a2a = AircraftEngagementZones.from_ato(self.game.blue.ato)
|
||||||
red_a2a = AircraftEngagementZones.from_ato(self.game.red.ato)
|
red_a2a = AircraftEngagementZones.from_ato(self.game.red.ato)
|
||||||
for flight in self.iter_flights():
|
for flight in self.iter_flights():
|
||||||
if flight.should_halt_sim(red_a2a if flight.squadron.player else blue_a2a):
|
flight.check_for_combat(red_a2a if flight.squadron.player else blue_a2a)
|
||||||
|
|
||||||
|
# After updating all combat states, check for halts.
|
||||||
|
for flight in self.iter_flights():
|
||||||
|
if flight.should_halt_sim():
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user