mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
This doesn't do anything yet, but sets up the data model handling for frozen combat. The next step is to show combat in the map view, since that will be helpful when debugging the step after that one: resolving frozen combat. This would benefit from caching the Shapely data for SAM threat zones. Right now it's generating them once per tick and the stuttering is visible at max speed. https://github.com/dcs-liberation/dcs_liberation/issues/1680
61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
from __future__ import annotations
|
|
|
|
from collections.abc import Iterator
|
|
from typing import Optional, TYPE_CHECKING
|
|
|
|
from dcs import Point
|
|
from shapely.ops import unary_union
|
|
|
|
from game.utils import dcs_to_shapely_point
|
|
|
|
if TYPE_CHECKING:
|
|
from game.ato import Flight
|
|
from game.ato.airtaaskingorder import AirTaskingOrder
|
|
from game.threatzones import ThreatPoly
|
|
from game.sim.combat import FrozenCombat
|
|
|
|
|
|
class AircraftEngagementZones:
|
|
def __init__(self, individual_zones: dict[Flight, ThreatPoly]) -> None:
|
|
self.individual_zones = individual_zones
|
|
self.threat_zones = self._make_combined_zone()
|
|
|
|
def update_for_combat(self, combat: FrozenCombat) -> None:
|
|
for flight in combat.iter_flights():
|
|
try:
|
|
del self.individual_zones[flight]
|
|
except KeyError:
|
|
pass
|
|
self.threat_zones = self._make_combined_zone()
|
|
|
|
def remove_flight(self, flight: Flight) -> None:
|
|
try:
|
|
del self.individual_zones[flight]
|
|
except KeyError:
|
|
pass
|
|
self.threat_zones = self._make_combined_zone()
|
|
|
|
def _make_combined_zone(self) -> ThreatPoly:
|
|
return unary_union(self.individual_zones.values())
|
|
|
|
def covers(self, position: Point) -> bool:
|
|
return self.threat_zones.intersects(dcs_to_shapely_point(position))
|
|
|
|
def iter_intercepting_flights(self, position: Point) -> Iterator[Flight]:
|
|
for flight, zone in self.individual_zones.items():
|
|
if zone.intersects(dcs_to_shapely_point(position)):
|
|
yield flight
|
|
|
|
@classmethod
|
|
def from_ato(cls, ato: AirTaskingOrder) -> AircraftEngagementZones:
|
|
zones = {}
|
|
for package in ato.packages:
|
|
for flight in package.flights:
|
|
if (region := cls.commit_region(flight)) is not None:
|
|
zones[flight] = region
|
|
return AircraftEngagementZones(zones)
|
|
|
|
@classmethod
|
|
def commit_region(cls, flight: Flight) -> Optional[ThreatPoly]:
|
|
return flight.state.a2a_commit_region()
|