mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Draw frozen combat on the map.
Very basic display. Draws the engagement footprint for air-to-air combat, a line from the flight to the target for IP, and lines from SAMs to their target for air defense. https://github.com/dcs-liberation/dcs_liberation/issues/1680
This commit is contained in:
@@ -18,14 +18,16 @@ from game.ato.flightstate import (
|
||||
from game.ato.starttype import StartType
|
||||
from gen.flights.traveltime import TotEstimator
|
||||
from .combat import CombatInitiator, FrozenCombat
|
||||
from .gameupdatecallbacks import GameUpdateCallbacks
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
|
||||
|
||||
class AircraftSimulation:
|
||||
def __init__(self, game: Game) -> None:
|
||||
def __init__(self, game: Game, callbacks: GameUpdateCallbacks) -> None:
|
||||
self.game = game
|
||||
self.callbacks = callbacks
|
||||
self.combats: list[FrozenCombat] = []
|
||||
|
||||
def begin_simulation(self) -> None:
|
||||
@@ -38,7 +40,7 @@ class AircraftSimulation:
|
||||
|
||||
# Finish updating all flights before checking for combat so that the new
|
||||
# positions are used.
|
||||
CombatInitiator(self.game, self.combats).update_active_combats()
|
||||
CombatInitiator(self.game, self.combats, self.callbacks).update_active_combats()
|
||||
|
||||
# After updating all combat states, check for halts.
|
||||
for flight in self.iter_flights():
|
||||
|
||||
@@ -12,6 +12,7 @@ from .atip import AtIp
|
||||
from .defendingsam import DefendingSam
|
||||
from .joinablecombat import JoinableCombat
|
||||
from .samengagementzones import SamEngagementZones
|
||||
from ..gameupdatecallbacks import GameUpdateCallbacks
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
@@ -20,9 +21,12 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class CombatInitiator:
|
||||
def __init__(self, game: Game, combats: list[FrozenCombat]) -> None:
|
||||
def __init__(
|
||||
self, game: Game, combats: list[FrozenCombat], callbacks: GameUpdateCallbacks
|
||||
) -> None:
|
||||
self.game = game
|
||||
self.combats = combats
|
||||
self.callbacks = callbacks
|
||||
|
||||
def update_active_combats(self) -> None:
|
||||
blue_a2a = AircraftEngagementZones.from_ato(self.game.blue.ato)
|
||||
@@ -60,6 +64,7 @@ class CombatInitiator:
|
||||
logging.info(f"{flight} is joining existing combat {joined}")
|
||||
joined.join(flight)
|
||||
own_a2a.remove_flight(flight)
|
||||
self.callbacks.on_combat_changed(joined)
|
||||
elif (combat := self.check_flight_for_new_combat(flight, a2a, sam)) is not None:
|
||||
logging.info(f"Interrupting simulation because {combat.because()}")
|
||||
combat.update_flight_states()
|
||||
@@ -70,6 +75,7 @@ class CombatInitiator:
|
||||
a2a.update_for_combat(combat)
|
||||
own_a2a.update_for_combat(combat)
|
||||
self.combats.append(combat)
|
||||
self.callbacks.on_add_combat(combat)
|
||||
|
||||
def check_flight_for_joined_combat(
|
||||
self, flight: Flight
|
||||
|
||||
@@ -3,9 +3,10 @@ from __future__ import annotations
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import Callable, TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .gamelooptimer import GameLoopTimer
|
||||
from .gameupdatecallbacks import GameUpdateCallbacks
|
||||
from .missionsimulation import MissionSimulation, SimulationAlreadyCompletedError
|
||||
from .simspeedsetting import SimSpeedSetting
|
||||
|
||||
@@ -15,11 +16,11 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class GameLoop:
|
||||
def __init__(self, game: Game, on_complete: Callable[[], None]) -> None:
|
||||
def __init__(self, game: Game, callbacks: GameUpdateCallbacks) -> None:
|
||||
self.game = game
|
||||
self.on_complete = on_complete
|
||||
self.callbacks = callbacks
|
||||
self.timer = GameLoopTimer(self.tick)
|
||||
self.sim = MissionSimulation(self.game)
|
||||
self.sim = MissionSimulation(self.game, self.callbacks)
|
||||
self.started = False
|
||||
self.completed = False
|
||||
|
||||
@@ -75,6 +76,6 @@ class GameLoop:
|
||||
if self.completed:
|
||||
self.pause()
|
||||
logging.info(f"Simulation completed at {self.sim.time}")
|
||||
self.on_complete()
|
||||
self.callbacks.on_simulation_complete()
|
||||
except SimulationAlreadyCompletedError:
|
||||
logging.exception("Attempted to tick already completed sim")
|
||||
|
||||
17
game/sim/gameupdatecallbacks.py
Normal file
17
game/sim/gameupdatecallbacks.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.sim.combat import FrozenCombat
|
||||
|
||||
|
||||
# Ought to be frozen but mypy can't handle that:
|
||||
# https://github.com/python/mypy/issues/5485
|
||||
@dataclass
|
||||
class GameUpdateCallbacks:
|
||||
on_simulation_complete: Callable[[], None]
|
||||
on_add_combat: Callable[[FrozenCombat], None]
|
||||
on_combat_changed: Callable[[FrozenCombat], None]
|
||||
@@ -9,6 +9,7 @@ from game.debriefing import Debriefing
|
||||
from game.missiongenerator import MissionGenerator
|
||||
from game.unitmap import UnitMap
|
||||
from .aircraftsimulation import AircraftSimulation
|
||||
from .gameupdatecallbacks import GameUpdateCallbacks
|
||||
from .missionresultsprocessor import MissionResultsProcessor
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -24,10 +25,10 @@ class SimulationAlreadyCompletedError(RuntimeError):
|
||||
|
||||
|
||||
class MissionSimulation:
|
||||
def __init__(self, game: Game) -> None:
|
||||
def __init__(self, game: Game, callbacks: GameUpdateCallbacks) -> None:
|
||||
self.game = game
|
||||
self.unit_map: Optional[UnitMap] = None
|
||||
self.aircraft_simulation = AircraftSimulation(self.game)
|
||||
self.aircraft_simulation = AircraftSimulation(self.game, callbacks)
|
||||
self.completed = False
|
||||
self.time = self.game.conditions.start_time
|
||||
|
||||
|
||||
Reference in New Issue
Block a user