Show runway status on the new map.

Fixes https://github.com/dcs-liberation/dcs_liberation/issues/1105
This commit is contained in:
Dan Albert 2021-05-31 14:17:57 -07:00
parent 355e6e1d15
commit 284f2bc323
3 changed files with 67 additions and 15 deletions

View File

@ -6,7 +6,7 @@ import logging
from abc import ABC, abstractmethod
from collections import defaultdict
from dataclasses import dataclass, field
from enum import Enum
from enum import Enum, unique, auto, IntEnum
from functools import total_ordering, cached_property
from typing import (
Any,
@ -219,6 +219,13 @@ class GroundUnitDestination:
return self.total_value < other.total_value
@unique
class ControlPointStatus(IntEnum):
Functional = auto()
Damaged = auto()
Destroyed = auto()
class ControlPoint(MissionTarget, ABC):
position = None # type: Point
@ -710,6 +717,11 @@ class ControlPoint(MissionTarget, ABC):
def category(self) -> str:
...
@property
@abstractmethod
def status(self) -> ControlPointStatus:
...
class Airfield(ControlPoint):
def __init__(
@ -794,6 +806,15 @@ class Airfield(ControlPoint):
def category(self) -> str:
return "airfield"
@property
def status(self) -> ControlPointStatus:
runway_staus = self.runway_status
if runway_staus.needs_repair:
return ControlPointStatus.Destroyed
elif runway_staus.damaged:
return ControlPointStatus.Damaged
return ControlPointStatus.Functional
class NavalControlPoint(ControlPoint, ABC):
@property
@ -818,20 +839,24 @@ class NavalControlPoint(ControlPoint, ABC):
def heading(self) -> int:
return 0 # TODO compute heading
def find_main_tgo(self) -> TheaterGroundObject:
for g in self.ground_objects:
if g.dcs_identifier in ["CARRIER", "LHA"]:
return g
raise RuntimeError(f"Found no carrier/LHA group for {self.name}")
def runway_is_operational(self) -> bool:
# Necessary because it's possible for the carrier itself to have sunk
# while its escorts are still alive.
for g in self.ground_objects:
if g.dcs_identifier in ["CARRIER", "LHA"]:
for group in g.groups:
for u in group.units:
if db.unit_type_from_name(u.type) in [
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
CV_1143_5_Admiral_Kuznetsov,
Type_071_Amphibious_Transport_Dock,
]:
return True
for group in self.find_main_tgo().groups:
for u in group.units:
if db.unit_type_from_name(u.type) in [
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
CV_1143_5_Admiral_Kuznetsov,
Type_071_Amphibious_Transport_Dock,
]:
return True
return False
def active_runway(
@ -857,6 +882,14 @@ class NavalControlPoint(ControlPoint, ABC):
def can_deploy_ground_units(self) -> bool:
return False
@property
def status(self) -> ControlPointStatus:
if not self.runway_is_operational():
return ControlPointStatus.Destroyed
if self.find_main_tgo().dead_units:
return ControlPointStatus.Damaged
return ControlPointStatus.Functional
class Carrier(NavalControlPoint):
def __init__(self, name: str, at: Point, cp_id: int):
@ -986,6 +1019,10 @@ class OffMapSpawn(ControlPoint):
def category(self) -> str:
return "offmap"
@property
def status(self) -> ControlPointStatus:
return ControlPointStatus.Functional
class Fob(ControlPoint):
def __init__(self, name: str, at: Point, cp_id: int):
@ -1046,3 +1083,7 @@ class Fob(ControlPoint):
@property
def category(self) -> str:
return "fob"
@property
def status(self) -> ControlPointStatus:
return ControlPointStatus.Functional

View File

@ -20,6 +20,7 @@ from game.theater import (
TheaterGroundObject,
FrontLine,
LatLon,
ControlPointStatus,
)
from game.threatzones import ThreatZones
from game.transfers import MultiGroupTransport, TransportMap
@ -79,6 +80,7 @@ class ControlPointJs(QObject):
mobileChanged = Signal()
destinationChanged = Signal(list)
categoryChanged = Signal()
statusChanged = Signal()
def __init__(
self,
@ -104,6 +106,17 @@ class ControlPointJs(QObject):
def category(self) -> str:
return self.control_point.category
@Property(str, notify=statusChanged)
def status(self) -> str:
status = self.control_point.status
if status is ControlPointStatus.Functional:
return "alive"
elif status is ControlPointStatus.Damaged:
return "damaged"
elif status is ControlPointStatus.Destroyed:
return "destroyed"
raise ValueError(f"Unhandled ControlPointStatus: {status.name}")
@Property(list, notify=positionChanged)
def position(self) -> LeafletLatLon:
ll = self.theater.point_to_ll(self.control_point.position)

View File

@ -290,12 +290,10 @@ class ControlPoint {
}
icon() {
// TODO: Runway status.
// https://github.com/dcs-liberation/dcs_liberation/issues/1105
return Icons.ControlPoints.icon(
this.cp.category,
this.cp.blue,
UnitState.Alive
this.cp.status
);
}