Add icons for CPs.

This commit is contained in:
Dan Albert 2021-05-21 21:43:02 -07:00
parent f8cb9e2bd3
commit c0ead4a484
25 changed files with 105 additions and 24 deletions

View File

@ -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"

View File

@ -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)

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="158" height="118" viewBox="21 36 158 118"><path d="M25,50 l150,0 0,100 -150,0 z" stroke-width="4" stroke="black" fill="rgb(0,107,140)" fill-opacity="1" ></path><path d="M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M80,70 l40,0 M80,80 l25,-25 M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M85,48 85,40 115,40 115,48 100,46 Z" stroke-width="4" stroke="black" fill="black" ></path></svg>

After

Width:  |  Height:  |  Size: 767 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="158" height="148" viewBox="21 36 158 148"><path d="M25,50 l150,0 0,100 -150,0 z" stroke-width="4" stroke="black" fill="rgb(0,107,140)" fill-opacity="1" ></path><path d="M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M80,70 l40,0 M80,80 l25,-25 M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M85,48 85,40 115,40 115,48 100,46 Z" stroke-width="4" stroke="black" fill="black" ></path><path d="M25,155 l150,0 0,25 -150,0 z" stroke-width="4" stroke="black" fill="rgb(255,255,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 868 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="158" height="148" viewBox="21 36 158 148"><path d="M25,50 l150,0 0,100 -150,0 z" stroke-width="4" stroke="black" fill="rgb(0,107,140)" fill-opacity="1" ></path><path d="M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M80,70 l40,0 M80,80 l25,-25 M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M85,48 85,40 115,40 115,48 100,46 Z" stroke-width="4" stroke="black" fill="black" ></path><path d="M25,155 l150,0 0,25 -150,0 z" stroke-width="4" stroke="black" fill="rgb(255,0,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 866 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="162" viewBox="24 14 152 162"><path d="M 100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(200,0,0)" fill-opacity="1" ></path><path d="M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M80,70 l40,0 M80,80 l25,-25 M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M85,40 85,18 115,18 115,40 100,24 Z" stroke-width="4" stroke="black" fill="black" ></path></svg>

After

Width:  |  Height:  |  Size: 778 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="192" viewBox="24 14 152 192"><path d="M 100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(200,0,0)" fill-opacity="1" ></path><path d="M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M80,70 l40,0 M80,80 l25,-25 M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M85,40 85,18 115,18 115,40 100,24 Z" stroke-width="4" stroke="black" fill="black" ></path><path d="M28,177 l144,0 0,25 -144,0 z" stroke-width="4" stroke="black" fill="rgb(255,255,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 879 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="192" viewBox="24 14 152 192"><path d="M 100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(200,0,0)" fill-opacity="1" ></path><path d="M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M80,70 l40,0 M80,80 l25,-25 M100,80 l0,40 M81,90.5 l38,19 M81,109.5 l38,-19" stroke-width="4" stroke="black" fill="none" ></path><circle cx="100" cy="100" r="20" stroke-width="4" stroke="black" fill="none" ></circle><path d="M85,40 85,18 115,18 115,40 100,24 Z" stroke-width="4" stroke="black" fill="black" ></path><path d="M28,177 l144,0 0,25 -144,0 z" stroke-width="4" stroke="black" fill="rgb(255,0,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 877 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="128" height="128" viewBox="36 36 128 128"><circle cx="100" cy="100" r="60" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></circle><path d="m 80,100 20,20 20,-20 -20,0 0,-20 -20,0 z" stroke-width="4" stroke="black" fill="black" ></path></svg>

After

Width:  |  Height:  |  Size: 349 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="128" height="158" viewBox="36 36 128 158"><circle cx="100" cy="100" r="60" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></circle><path d="m 80,100 20,20 20,-20 -20,0 0,-20 -20,0 z" stroke-width="4" stroke="black" fill="black" ></path><path d="M40,165 l120,0 0,25 -120,0 z" stroke-width="4" stroke="black" fill="rgb(255,255,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 450 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="128" height="128" viewBox="36 36 128 128"><circle cx="100" cy="100" r="60" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></circle><circle cx="100" cy="100" r="60" stroke-width="5" stroke-dasharray="8,12" stroke="rgb(239, 239, 239)" fill="none" ></circle><path d="m 80,100 20,20 20,-20 -20,0 0,-20 -20,0 z" stroke-width="4" stroke="black" fill="black" ></path></svg>

After

Width:  |  Height:  |  Size: 473 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="128" height="158" viewBox="36 36 128 158"><circle cx="100" cy="100" r="60" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></circle><path d="m 80,100 20,20 20,-20 -20,0 0,-20 -20,0 z" stroke-width="4" stroke="black" fill="black" ></path><path d="M40,165 l120,0 0,25 -120,0 z" stroke-width="4" stroke="black" fill="rgb(255,0,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 448 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="152" viewBox="24 24 152 152"><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(255,128,128)" fill-opacity="1" ></path><path d="m 80,100 20,20 20,-20 -20,0 0,-20 -20,0 z" stroke-width="4" stroke="black" fill="black" ></path></svg>

After

Width:  |  Height:  |  Size: 365 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="182" viewBox="24 24 152 182"><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(255,128,128)" fill-opacity="1" ></path><path d="m 80,100 20,20 20,-20 -20,0 0,-20 -20,0 z" stroke-width="4" stroke="black" fill="black" ></path><path d="M28,177 l144,0 0,25 -144,0 z" stroke-width="4" stroke="black" fill="rgb(255,255,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 466 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="152" viewBox="24 24 152 152"><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(255,128,128)" fill-opacity="1" ></path><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="5" stroke-dasharray="8,12" stroke="rgb(239, 239, 239)" fill="none" ></path><path d="m 80,100 20,20 20,-20 -20,0 0,-20 -20,0 z" stroke-width="4" stroke="black" fill="black" ></path></svg>

After

Width:  |  Height:  |  Size: 505 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="182" viewBox="24 24 152 182"><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(255,128,128)" fill-opacity="1" ></path><path d="m 80,100 20,20 20,-20 -20,0 0,-20 -20,0 z" stroke-width="4" stroke="black" fill="black" ></path><path d="M28,177 l144,0 0,25 -144,0 z" stroke-width="4" stroke="black" fill="rgb(255,0,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 464 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="128" height="128" viewBox="36 36 128 128"><circle cx="100" cy="100" r="60" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></circle><text x="100" y="110" text-anchor="middle" font-size="35" font-family="Arial" font-weight="bold" stroke-width="4" stroke="none" fill="black" >LHA</text></svg>

After

Width:  |  Height:  |  Size: 396 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="128" height="158" viewBox="36 36 128 158"><circle cx="100" cy="100" r="60" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></circle><text x="100" y="110" text-anchor="middle" font-size="35" font-family="Arial" font-weight="bold" stroke-width="4" stroke="none" fill="black" >LHA</text><path d="M40,165 l120,0 0,25 -120,0 z" stroke-width="4" stroke="black" fill="rgb(255,255,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="128" height="128" viewBox="36 36 128 128"><circle cx="100" cy="100" r="60" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></circle><circle cx="100" cy="100" r="60" stroke-width="5" stroke-dasharray="8,12" stroke="rgb(239, 239, 239)" fill="none" ></circle><text x="100" y="110" text-anchor="middle" font-size="35" font-family="Arial" font-weight="bold" stroke-width="4" stroke="none" fill="black" >LHA</text></svg>

After

Width:  |  Height:  |  Size: 520 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="128" height="158" viewBox="36 36 128 158"><circle cx="100" cy="100" r="60" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></circle><text x="100" y="110" text-anchor="middle" font-size="35" font-family="Arial" font-weight="bold" stroke-width="4" stroke="none" fill="black" >LHA</text><path d="M40,165 l120,0 0,25 -120,0 z" stroke-width="4" stroke="black" fill="rgb(255,0,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 495 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="152" viewBox="24 24 152 152"><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(255,128,128)" fill-opacity="1" ></path><text x="100" y="110" text-anchor="middle" font-size="35" font-family="Arial" font-weight="bold" stroke-width="4" stroke="none" fill="black" >LHA</text></svg>

After

Width:  |  Height:  |  Size: 412 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="182" viewBox="24 24 152 182"><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(255,128,128)" fill-opacity="1" ></path><text x="100" y="110" text-anchor="middle" font-size="35" font-family="Arial" font-weight="bold" stroke-width="4" stroke="none" fill="black" >LHA</text><path d="M28,177 l144,0 0,25 -144,0 z" stroke-width="4" stroke="black" fill="rgb(255,255,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 513 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="152" viewBox="24 24 152 152"><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(255,128,128)" fill-opacity="1" ></path><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="5" stroke-dasharray="8,12" stroke="rgb(239, 239, 239)" fill="none" ></path><text x="100" y="110" text-anchor="middle" font-size="35" font-family="Arial" font-weight="bold" stroke-width="4" stroke="none" fill="black" >LHA</text></svg>

After

Width:  |  Height:  |  Size: 552 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="152" height="182" viewBox="24 24 152 182"><path d="M100,28 L172,100 100,172 28,100 100,28 Z" stroke-width="4" stroke="black" fill="rgb(255,128,128)" fill-opacity="1" ></path><text x="100" y="110" text-anchor="middle" font-size="35" font-family="Arial" font-weight="bold" stroke-width="4" stroke="none" fill="black" >LHA</text><path d="M28,177 l144,0 0,25 -144,0 z" stroke-width="4" stroke="black" fill="rgb(255,0,0)" ></path></svg>

After

Width:  |  Height:  |  Size: 511 B

View File

@ -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() {