mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +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:
@@ -9,22 +9,29 @@ from dcs import Point
|
||||
from game import Game
|
||||
from game.ato.airtaaskingorder import AirTaskingOrder
|
||||
from game.profiling import logged_duration
|
||||
from game.sim.combat import FrozenCombat
|
||||
from game.sim.combat.aircombat import AirCombat
|
||||
from game.sim.combat.atip import AtIp
|
||||
from game.sim.combat.defendingsam import DefendingSam
|
||||
from game.theater import (
|
||||
ConflictTheater,
|
||||
)
|
||||
from qt_ui.models import GameModel
|
||||
from qt_ui.simcontroller import SimController
|
||||
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
|
||||
from .aircombatjs import AirCombatJs
|
||||
from .controlpointjs import ControlPointJs
|
||||
from .flightjs import FlightJs
|
||||
from .frontlinejs import FrontLineJs
|
||||
from .groundobjectjs import GroundObjectJs
|
||||
from .holdzonesjs import HoldZonesJs
|
||||
from .ipcombatjs import IpCombatJs
|
||||
from .ipzonesjs import IpZonesJs
|
||||
from .joinzonesjs import JoinZonesJs
|
||||
from .leaflet import LeafletLatLon
|
||||
from .mapzonesjs import MapZonesJs
|
||||
from .navmeshjs import NavMeshJs
|
||||
from .samcombatjs import SamCombatJs
|
||||
from .supplyroutejs import SupplyRouteJs
|
||||
from .threatzonecontainerjs import ThreatZoneContainerJs
|
||||
from .threatzonesjs import ThreatZonesJs
|
||||
@@ -63,6 +70,9 @@ class MapModel(QObject):
|
||||
ipZonesChanged = Signal()
|
||||
joinZonesChanged = Signal()
|
||||
holdZonesChanged = Signal()
|
||||
airCombatsChanged = Signal()
|
||||
samCombatsChanged = Signal()
|
||||
ipCombatsChanged = Signal()
|
||||
|
||||
def __init__(self, game_model: GameModel, sim_controller: SimController) -> None:
|
||||
super().__init__()
|
||||
@@ -83,6 +93,10 @@ class MapModel(QObject):
|
||||
self._join_zones = JoinZonesJs.empty()
|
||||
self._hold_zones = HoldZonesJs.empty()
|
||||
self._selected_flight_index: Optional[Tuple[int, int]] = None
|
||||
self._air_combats = []
|
||||
self._sam_combats = []
|
||||
self._ip_combats = []
|
||||
|
||||
GameUpdateSignal.get_instance().game_loaded.connect(self.on_game_load)
|
||||
GameUpdateSignal.get_instance().flight_paths_changed.connect(self.reset_atos)
|
||||
GameUpdateSignal.get_instance().package_selection_changed.connect(
|
||||
@@ -92,6 +106,8 @@ class MapModel(QObject):
|
||||
self.set_flight_selection
|
||||
)
|
||||
sim_controller.sim_update.connect(self.on_sim_update)
|
||||
sim_controller.on_add_combat.connect(self.on_add_combat)
|
||||
sim_controller.on_combat_changed.connect(self.on_combat_changed)
|
||||
self.reset()
|
||||
|
||||
def clear(self) -> None:
|
||||
@@ -107,6 +123,9 @@ class MapModel(QObject):
|
||||
self._map_zones = MapZonesJs([], [], [])
|
||||
self._unculled_zones = []
|
||||
self._ip_zones = IpZonesJs.empty()
|
||||
self._air_combats = []
|
||||
self._sam_combats = []
|
||||
self._ip_combats = []
|
||||
self.cleared.emit()
|
||||
|
||||
def on_sim_update(self) -> None:
|
||||
@@ -180,6 +199,7 @@ class MapModel(QObject):
|
||||
self.reset_navmeshes()
|
||||
self.reset_map_zones()
|
||||
self.reset_unculled_zones()
|
||||
self.reset_combats()
|
||||
|
||||
def on_game_load(self, game: Optional[Game]) -> None:
|
||||
if game is not None:
|
||||
@@ -367,6 +387,79 @@ class MapModel(QObject):
|
||||
def holdZones(self) -> HoldZonesJs:
|
||||
return self._hold_zones
|
||||
|
||||
def reset_combats(self) -> None:
|
||||
self._air_combats = []
|
||||
self._sam_combats = []
|
||||
self._ip_combats = []
|
||||
self.airCombatsChanged.emit()
|
||||
self.samCombatsChanged.emit()
|
||||
self.ipCombatsChanged.emit()
|
||||
|
||||
def on_add_combat(self, combat: FrozenCombat) -> None:
|
||||
if isinstance(combat, AirCombat):
|
||||
self.add_air_combat(combat)
|
||||
elif isinstance(combat, DefendingSam):
|
||||
self.add_sam_combat(combat)
|
||||
elif isinstance(combat, AtIp):
|
||||
self.add_ip_combat(combat)
|
||||
else:
|
||||
logging.error(f"Unhandled FrozenCombat type: {combat.__class__}")
|
||||
|
||||
def add_air_combat(self, combat: AirCombat) -> None:
|
||||
self._air_combats.append(AirCombatJs(combat, self.game.theater))
|
||||
self.airCombatsChanged.emit()
|
||||
|
||||
def add_sam_combat(self, combat: DefendingSam) -> None:
|
||||
self._sam_combats.append(SamCombatJs(combat, self.game_model))
|
||||
self.samCombatsChanged.emit()
|
||||
|
||||
def add_ip_combat(self, combat: AtIp) -> None:
|
||||
self._ip_combats.append(IpCombatJs(combat, self.game_model))
|
||||
self.ipCombatsChanged.emit()
|
||||
|
||||
def on_combat_changed(self, combat: FrozenCombat) -> None:
|
||||
if isinstance(combat, AirCombat):
|
||||
self.refresh_air_combat(combat)
|
||||
elif isinstance(combat, DefendingSam):
|
||||
self.refresh_sam_combat(combat)
|
||||
elif isinstance(combat, AtIp):
|
||||
self.refresh_ip_combat(combat)
|
||||
else:
|
||||
logging.error(f"Unhandled FrozenCombat type: {combat.__class__}")
|
||||
|
||||
def refresh_air_combat(self, combat: AirCombat) -> None:
|
||||
for js in self._air_combats:
|
||||
if js.combat == combat:
|
||||
js.refresh()
|
||||
return
|
||||
logging.error(f"Could not find existing combat model to update for {combat}")
|
||||
|
||||
def refresh_sam_combat(self, combat: DefendingSam) -> None:
|
||||
for js in self._sam_combats:
|
||||
if js.combat == combat:
|
||||
js.refresh()
|
||||
return
|
||||
logging.error(f"Could not find existing combat model to update for {combat}")
|
||||
|
||||
def refresh_ip_combat(self, combat: AtIp) -> None:
|
||||
for js in self._ip_combats:
|
||||
if js.combat == combat:
|
||||
js.refresh()
|
||||
return
|
||||
logging.error(f"Could not find existing combat model to update for {combat}")
|
||||
|
||||
@Property(list, notify=airCombatsChanged)
|
||||
def airCombats(self) -> list[AirCombatJs]:
|
||||
return self._air_combats
|
||||
|
||||
@Property(list, notify=samCombatsChanged)
|
||||
def samCombats(self) -> list[SamCombatJs]:
|
||||
return self._sam_combats
|
||||
|
||||
@Property(list, notify=ipCombatsChanged)
|
||||
def ipCombats(self) -> list[IpCombatJs]:
|
||||
return self._ip_combats
|
||||
|
||||
@property
|
||||
def game(self) -> Game:
|
||||
if self.game_model.game is None:
|
||||
|
||||
Reference in New Issue
Block a user