diff --git a/game/theater/controlpoint.py b/game/theater/controlpoint.py
index f2e96a88..341df02e 100644
--- a/game/theater/controlpoint.py
+++ b/game/theater/controlpoint.py
@@ -786,6 +786,11 @@ class ControlPoint(MissionTarget, ABC):
def strike_targets(self) -> List[Union[MissionTarget, Unit]]:
return []
+ @property
+ @abstractmethod
+ def category(self) -> str:
+ ...
+
class Airfield(ControlPoint):
def __init__(
@@ -863,6 +868,10 @@ class Airfield(ControlPoint):
def income_per_turn(self) -> int:
return 20
+ @property
+ def category(self) -> str:
+ return "airfield"
+
class NavalControlPoint(ControlPoint, ABC):
@property
@@ -956,6 +965,10 @@ class Carrier(NavalControlPoint):
def total_aircraft_parking(self) -> int:
return 90
+ @property
+ def category(self) -> str:
+ return "cv"
+
class Lha(NavalControlPoint):
def __init__(self, name: str, at: Point, cp_id: int):
@@ -986,6 +999,10 @@ class Lha(NavalControlPoint):
def total_aircraft_parking(self) -> int:
return 20
+ @property
+ def category(self) -> str:
+ return "lha"
+
class OffMapSpawn(ControlPoint):
def runway_is_operational(self) -> bool:
@@ -1036,6 +1053,10 @@ class OffMapSpawn(ControlPoint):
def can_deploy_ground_units(self) -> bool:
return False
+ @property
+ def category(self) -> str:
+ return "offmap"
+
class Fob(ControlPoint):
def __init__(self, name: str, at: Point, cp_id: int):
@@ -1100,3 +1121,7 @@ class Fob(ControlPoint):
@property
def income_per_turn(self) -> int:
return 10
+
+ @property
+ def category(self) -> str:
+ return "fob"
diff --git a/qt_ui/widgets/map/mapmodel.py b/qt_ui/widgets/map/mapmodel.py
index bdb379d3..4f82f533 100644
--- a/qt_ui/widgets/map/mapmodel.py
+++ b/qt_ui/widgets/map/mapmodel.py
@@ -19,6 +19,8 @@ from game.theater import (
TheaterGroundObject,
FrontLine,
LatLon,
+ Airfield,
+ Carrier,
)
from game.transfers import MultiGroupTransport, TransportMap
from game.utils import meters, nautical_miles
@@ -63,6 +65,7 @@ class ControlPointJs(QObject):
positionChanged = Signal()
mobileChanged = Signal()
destinationChanged = Signal(list)
+ categoryChanged = Signal()
def __init__(
self,
@@ -84,6 +87,10 @@ class ControlPointJs(QObject):
def blue(self) -> bool:
return self.control_point.captured
+ @Property(str, notify=categoryChanged)
+ def category(self) -> str:
+ return self.control_point.category
+
@Property(list, notify=positionChanged)
def position(self) -> LeafletLatLon:
ll = self.theater.point_to_ll(self.control_point.position)
diff --git a/resources/ui/ground_assets/airfield_blue_alive.svg b/resources/ui/ground_assets/airfield_blue_alive.svg
new file mode 100644
index 00000000..dcc9a38e
--- /dev/null
+++ b/resources/ui/ground_assets/airfield_blue_alive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/airfield_blue_damaged.svg b/resources/ui/ground_assets/airfield_blue_damaged.svg
new file mode 100644
index 00000000..107f6b62
--- /dev/null
+++ b/resources/ui/ground_assets/airfield_blue_damaged.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/airfield_blue_destroyed.svg b/resources/ui/ground_assets/airfield_blue_destroyed.svg
new file mode 100644
index 00000000..7d49ff30
--- /dev/null
+++ b/resources/ui/ground_assets/airfield_blue_destroyed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/airfield_red_alive.svg b/resources/ui/ground_assets/airfield_red_alive.svg
new file mode 100644
index 00000000..1b481dd0
--- /dev/null
+++ b/resources/ui/ground_assets/airfield_red_alive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/airfield_red_damaged.svg b/resources/ui/ground_assets/airfield_red_damaged.svg
new file mode 100644
index 00000000..39693c44
--- /dev/null
+++ b/resources/ui/ground_assets/airfield_red_damaged.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/airfield_red_destroyed.svg b/resources/ui/ground_assets/airfield_red_destroyed.svg
new file mode 100644
index 00000000..1a2303a1
--- /dev/null
+++ b/resources/ui/ground_assets/airfield_red_destroyed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/cv_blue_alive.svg b/resources/ui/ground_assets/cv_blue_alive.svg
new file mode 100644
index 00000000..4ae3a57c
--- /dev/null
+++ b/resources/ui/ground_assets/cv_blue_alive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/cv_blue_damaged.svg b/resources/ui/ground_assets/cv_blue_damaged.svg
new file mode 100644
index 00000000..33b0c0bb
--- /dev/null
+++ b/resources/ui/ground_assets/cv_blue_damaged.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/cv_blue_destination.svg b/resources/ui/ground_assets/cv_blue_destination.svg
new file mode 100644
index 00000000..9e4ae54f
--- /dev/null
+++ b/resources/ui/ground_assets/cv_blue_destination.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/cv_blue_destroyed.svg b/resources/ui/ground_assets/cv_blue_destroyed.svg
new file mode 100644
index 00000000..55ef5cc2
--- /dev/null
+++ b/resources/ui/ground_assets/cv_blue_destroyed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/cv_red_alive.svg b/resources/ui/ground_assets/cv_red_alive.svg
new file mode 100644
index 00000000..b71d1366
--- /dev/null
+++ b/resources/ui/ground_assets/cv_red_alive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/cv_red_damaged.svg b/resources/ui/ground_assets/cv_red_damaged.svg
new file mode 100644
index 00000000..22e50f5f
--- /dev/null
+++ b/resources/ui/ground_assets/cv_red_damaged.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/cv_red_destination.svg b/resources/ui/ground_assets/cv_red_destination.svg
new file mode 100644
index 00000000..3e92f8e3
--- /dev/null
+++ b/resources/ui/ground_assets/cv_red_destination.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/cv_red_destroyed.svg b/resources/ui/ground_assets/cv_red_destroyed.svg
new file mode 100644
index 00000000..b8a8e243
--- /dev/null
+++ b/resources/ui/ground_assets/cv_red_destroyed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/lha_blue_alive.svg b/resources/ui/ground_assets/lha_blue_alive.svg
new file mode 100644
index 00000000..e01cc213
--- /dev/null
+++ b/resources/ui/ground_assets/lha_blue_alive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/lha_blue_damaged.svg b/resources/ui/ground_assets/lha_blue_damaged.svg
new file mode 100644
index 00000000..4aeffeeb
--- /dev/null
+++ b/resources/ui/ground_assets/lha_blue_damaged.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/lha_blue_destination.svg b/resources/ui/ground_assets/lha_blue_destination.svg
new file mode 100644
index 00000000..ff80f36a
--- /dev/null
+++ b/resources/ui/ground_assets/lha_blue_destination.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/lha_blue_destroyed.svg b/resources/ui/ground_assets/lha_blue_destroyed.svg
new file mode 100644
index 00000000..2d0092c3
--- /dev/null
+++ b/resources/ui/ground_assets/lha_blue_destroyed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/lha_red_alive.svg b/resources/ui/ground_assets/lha_red_alive.svg
new file mode 100644
index 00000000..f3960157
--- /dev/null
+++ b/resources/ui/ground_assets/lha_red_alive.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/lha_red_damaged.svg b/resources/ui/ground_assets/lha_red_damaged.svg
new file mode 100644
index 00000000..4c3c6aa3
--- /dev/null
+++ b/resources/ui/ground_assets/lha_red_damaged.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/lha_red_destination.svg b/resources/ui/ground_assets/lha_red_destination.svg
new file mode 100644
index 00000000..9ef1411b
--- /dev/null
+++ b/resources/ui/ground_assets/lha_red_destination.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/ground_assets/lha_red_destroyed.svg b/resources/ui/ground_assets/lha_red_destroyed.svg
new file mode 100644
index 00000000..87ff95ac
--- /dev/null
+++ b/resources/ui/ground_assets/lha_red_destroyed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/ui/map/map.js b/resources/ui/map/map.js
index 3e1056b2..a68c5716 100644
--- a/resources/ui/map/map.js
+++ b/resources/ui/map/map.js
@@ -45,6 +45,49 @@ const UnitState = Object.freeze({
Destroyed: "destroyed",
});
+class CpIcons {
+ constructor() {
+ this.icons = {};
+ for (const player of [true, false]) {
+ this.icons[player] = {};
+ for (const state of Object.values(UnitState)) {
+ this.icons[player][state] = {
+ airfield: this.loadIcon("airfield", player, state),
+ cv: this.loadIcon("cv", player, state),
+ fob: this.loadLegacyIcon(player),
+ lha: this.loadIcon("lha", player, state),
+ offmap: this.loadLegacyIcon(player),
+ };
+ }
+ }
+ }
+
+ icon(category, player, state) {
+ return this.icons[player][state][category];
+ }
+
+ loadIcon(category, player, state) {
+ const color = player ? "blue" : "red";
+ return new L.Icon({
+ iconUrl: `../ground_assets/${category}_${color}_${state}.svg`,
+ iconSize: [32, 32],
+ });
+ }
+
+ loadLegacyIcon(player) {
+ const color = player ? "blue" : "red";
+ return new L.Icon({
+ iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-${color}.png`,
+ shadowUrl:
+ "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png",
+ iconSize: [25, 41],
+ iconAnchor: [12, 41],
+ popupAnchor: [1, -34],
+ shadowSize: [41, 41],
+ });
+ }
+}
+
class TgoIcons {
constructor() {
this.icons = {};
@@ -84,26 +127,7 @@ class TgoIcons {
}
const Icons = Object.freeze({
- BlueControlPoint: new L.Icon({
- iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-blue.png`,
- shadowUrl:
- "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png",
- iconSize: [25, 41],
- iconAnchor: [12, 41],
- popupAnchor: [1, -34],
- shadowSize: [41, 41],
- }),
-
- RedControlPoint: new L.Icon({
- iconUrl: `https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png`,
- shadowUrl:
- "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png",
- iconSize: [25, 41],
- iconAnchor: [12, 41],
- popupAnchor: [1, -34],
- shadowSize: [41, 41],
- }),
-
+ ControlPoints: new CpIcons(),
Objectives: new TgoIcons(),
});
@@ -212,10 +236,13 @@ class ControlPoint {
}
icon() {
- if (this.cp.blue) {
- return Icons.BlueControlPoint;
- }
- return Icons.RedControlPoint;
+ // TODO: Runway status.
+ // https://github.com/dcs-liberation/dcs_liberation/issues/1105
+ return Icons.ControlPoints.icon(
+ this.cp.category,
+ this.cp.blue,
+ UnitState.Alive
+ );
}
hasDestination() {