mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Set up icons for TGOs.
These are just the old icons, but it's better than nothing.
This commit is contained in:
parent
4e37666037
commit
af3b8a9902
@ -154,6 +154,8 @@ class GroundObjectJs(QObject):
|
|||||||
positionChanged = Signal()
|
positionChanged = Signal()
|
||||||
samThreatRangesChanged = Signal()
|
samThreatRangesChanged = Signal()
|
||||||
samDetectionRangesChanged = Signal()
|
samDetectionRangesChanged = Signal()
|
||||||
|
categoryChanged = Signal()
|
||||||
|
deadChanged = Signal()
|
||||||
|
|
||||||
def __init__(self, tgo: TheaterGroundObject, game: Game) -> None:
|
def __init__(self, tgo: TheaterGroundObject, game: Game) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -189,6 +191,10 @@ class GroundObjectJs(QObject):
|
|||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return self.tgo.name
|
return self.tgo.name
|
||||||
|
|
||||||
|
@Property(str, notify=categoryChanged)
|
||||||
|
def category(self) -> str:
|
||||||
|
return self.tgo.category
|
||||||
|
|
||||||
def make_unit_name(self, unit: Unit, dead: bool) -> str:
|
def make_unit_name(self, unit: Unit, dead: bool) -> str:
|
||||||
dead_label = " [DEAD]" if dead else ""
|
dead_label = " [DEAD]" if dead else ""
|
||||||
unit_display_name = unit.type
|
unit_display_name = unit.type
|
||||||
@ -225,6 +231,12 @@ class GroundObjectJs(QObject):
|
|||||||
ll = self.theater.point_to_ll(self.tgo.position)
|
ll = self.theater.point_to_ll(self.tgo.position)
|
||||||
return [ll.latitude, ll.longitude]
|
return [ll.latitude, ll.longitude]
|
||||||
|
|
||||||
|
@Property(bool, notify=deadChanged)
|
||||||
|
def dead(self) -> bool:
|
||||||
|
if not self.tgo.groups:
|
||||||
|
return all(b.is_dead for b in self.buildings)
|
||||||
|
return not any(g.units for g in self.tgo.groups)
|
||||||
|
|
||||||
@Property(list, notify=samThreatRangesChanged)
|
@Property(list, notify=samThreatRangesChanged)
|
||||||
def samThreatRanges(self) -> List[float]:
|
def samThreatRanges(self) -> List[float]:
|
||||||
if not self.tgo.might_have_aa:
|
if not self.tgo.might_have_aa:
|
||||||
|
|||||||
@ -18,6 +18,81 @@ const Colors = Object.freeze({
|
|||||||
Highlight: "#ffff00",
|
Highlight: "#ffff00",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const Categories = Object.freeze([
|
||||||
|
"aa",
|
||||||
|
"allycamp",
|
||||||
|
"ammo",
|
||||||
|
"armor",
|
||||||
|
"coastal",
|
||||||
|
"comms",
|
||||||
|
"derrick",
|
||||||
|
"factory",
|
||||||
|
"farp",
|
||||||
|
"fob",
|
||||||
|
"fuel",
|
||||||
|
"ewr",
|
||||||
|
"missile",
|
||||||
|
"oil",
|
||||||
|
"ship",
|
||||||
|
"power",
|
||||||
|
"village",
|
||||||
|
"ware",
|
||||||
|
"ww2bunker",
|
||||||
|
]);
|
||||||
|
|
||||||
|
function makeTgoIcons(player) {
|
||||||
|
const icons = {};
|
||||||
|
const playerSuffix = player ? "_blue" : "";
|
||||||
|
Categories.forEach((category) => {
|
||||||
|
const iconName = `${category}${playerSuffix}`;
|
||||||
|
icons[category] = new L.Icon({
|
||||||
|
iconUrl: `../ground_assets/${iconName}.png`,
|
||||||
|
});
|
||||||
|
if (!icons[category]) {
|
||||||
|
console.log(`Failed to load icon for ${iconName}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.freeze(icons);
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeIcons(player) {
|
||||||
|
const color = player ? "blue" : "red";
|
||||||
|
const playerSuffix = player ? "_blue" : "";
|
||||||
|
const icons = {
|
||||||
|
ControlPoint: 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],
|
||||||
|
}),
|
||||||
|
|
||||||
|
Objectives: makeTgoIcons(player),
|
||||||
|
|
||||||
|
Destroyed: new L.Icon({
|
||||||
|
iconUrl: "../ground_assets/destroyed.png",
|
||||||
|
}),
|
||||||
|
|
||||||
|
NoThreat: new L.icon({
|
||||||
|
iconUrl: `../ground_assets/nothreat${playerSuffix}.png`,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Object.freeze(icons);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Icons = Object.freeze({
|
||||||
|
Friendly: makeIcons(true),
|
||||||
|
Enemy: makeIcons(false),
|
||||||
|
|
||||||
|
for(player) {
|
||||||
|
return player ? this.Friendly : this.Enemy;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
function metersToNauticalMiles(meters) {
|
function metersToNauticalMiles(meters) {
|
||||||
return meters * 0.000539957;
|
return meters * 0.000539957;
|
||||||
}
|
}
|
||||||
@ -91,28 +166,6 @@ L.control
|
|||||||
)
|
)
|
||||||
.addTo(map);
|
.addTo(map);
|
||||||
|
|
||||||
const friendlyCpIcon = 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],
|
|
||||||
});
|
|
||||||
|
|
||||||
const enemyCpIcon = 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],
|
|
||||||
});
|
|
||||||
|
|
||||||
let game;
|
let game;
|
||||||
new QWebChannel(qt.webChannelTransport, function (channel) {
|
new QWebChannel(qt.webChannelTransport, function (channel) {
|
||||||
game = channel.objects.game;
|
game = channel.objects.game;
|
||||||
@ -130,14 +183,6 @@ function recenterMap(center) {
|
|||||||
map.setView(center, 8, { animate: true, duration: 1 });
|
map.setView(center, 8, { animate: true, duration: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
function iconFor(player) {
|
|
||||||
if (player) {
|
|
||||||
return friendlyCpIcon;
|
|
||||||
} else {
|
|
||||||
return enemyCpIcon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const SHOW_BASE_NAME_AT_ZOOM = 8;
|
const SHOW_BASE_NAME_AT_ZOOM = 8;
|
||||||
|
|
||||||
class ControlPoint {
|
class ControlPoint {
|
||||||
@ -156,6 +201,10 @@ class ControlPoint {
|
|||||||
this.cp.destinationChanged.connect(() => this.onDestinationChanged());
|
this.cp.destinationChanged.connect(() => this.onDestinationChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
icon() {
|
||||||
|
return Icons.for(this.cp.blue).ControlPoint;
|
||||||
|
}
|
||||||
|
|
||||||
hasDestination() {
|
hasDestination() {
|
||||||
return this.cp.destination.length > 0;
|
return this.cp.destination.length > 0;
|
||||||
}
|
}
|
||||||
@ -256,7 +305,7 @@ class ControlPoint {
|
|||||||
// markers are helpful so we want to keep them, but make sure the CP is
|
// markers are helpful so we want to keep them, but make sure the CP is
|
||||||
// always the clickable thing.
|
// always the clickable thing.
|
||||||
return L.marker(location, {
|
return L.marker(location, {
|
||||||
icon: iconFor(this.cp.blue),
|
icon: this.icon(),
|
||||||
zIndexOffset: 1000,
|
zIndexOffset: 1000,
|
||||||
draggable: this.cp.mobile,
|
draggable: this.cp.mobile,
|
||||||
autoPan: true,
|
autoPan: true,
|
||||||
@ -280,7 +329,7 @@ class ControlPoint {
|
|||||||
|
|
||||||
makeSecondaryMarker() {
|
makeSecondaryMarker() {
|
||||||
return L.marker(this.cp.position, {
|
return L.marker(this.cp.position, {
|
||||||
icon: iconFor(this.cp.blue),
|
icon: this.icon(),
|
||||||
zIndexOffset: 1000,
|
zIndexOffset: 1000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -327,16 +376,42 @@ function drawControlPoints() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawSamThreatsAt(tgo) {
|
class TheaterGroundObject {
|
||||||
const detectionLayer = tgo.blue
|
constructor(tgo) {
|
||||||
|
this.tgo = tgo;
|
||||||
|
}
|
||||||
|
|
||||||
|
samIsThreat() {
|
||||||
|
for (const range of this.tgo.samThreatRanges) {
|
||||||
|
if (range > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
icon() {
|
||||||
|
const iconSet = Icons.for(this.tgo.blue);
|
||||||
|
if (this.tgo.category == "aa" && !this.samIsThreat()) {
|
||||||
|
return iconSet.NoThreat;
|
||||||
|
} else if (this.tgo.dead) {
|
||||||
|
return iconSet.Destroyed;
|
||||||
|
} else {
|
||||||
|
return iconSet.Objectives[this.tgo.category];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawSamThreats() {
|
||||||
|
const detectionLayer = this.tgo.blue
|
||||||
? blueSamDetectionLayer
|
? blueSamDetectionLayer
|
||||||
: redSamDetectionLayer;
|
: redSamDetectionLayer;
|
||||||
const threatLayer = tgo.blue ? blueSamThreatLayer : redSamThreatLayer;
|
const threatLayer = this.tgo.blue ? blueSamThreatLayer : redSamThreatLayer;
|
||||||
const threatColor = tgo.blue ? Colors.Blue : Colors.Red;
|
const threatColor = this.tgo.blue ? Colors.Blue : Colors.Red;
|
||||||
const detectionColor = tgo.blue ? "#bb89ff" : "#eee17b";
|
const detectionColor = this.tgo.blue ? "#bb89ff" : "#eee17b";
|
||||||
|
|
||||||
tgo.samDetectionRanges.forEach((range) => {
|
this.tgo.samDetectionRanges.forEach((range) => {
|
||||||
L.circle(tgo.position, {
|
L.circle(this.tgo.position, {
|
||||||
radius: range,
|
radius: range,
|
||||||
color: detectionColor,
|
color: detectionColor,
|
||||||
fill: false,
|
fill: false,
|
||||||
@ -344,8 +419,8 @@ function drawSamThreatsAt(tgo) {
|
|||||||
}).addTo(detectionLayer);
|
}).addTo(detectionLayer);
|
||||||
});
|
});
|
||||||
|
|
||||||
tgo.samThreatRanges.forEach((range) => {
|
this.tgo.samThreatRanges.forEach((range) => {
|
||||||
L.circle(tgo.position, {
|
L.circle(this.tgo.position, {
|
||||||
radius: range,
|
radius: range,
|
||||||
color: threatColor,
|
color: threatColor,
|
||||||
fill: false,
|
fill: false,
|
||||||
@ -354,6 +429,16 @@ function drawSamThreatsAt(tgo) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
L.marker(this.tgo.position, { icon: this.icon() })
|
||||||
|
.bindTooltip(`${this.tgo.name}<br />${this.tgo.units.join("<br />")}`)
|
||||||
|
.on("click", () => this.tgo.showInfoDialog())
|
||||||
|
.on("contextmenu", () => this.tgo.showPackageDialog())
|
||||||
|
.addTo(groundObjectsLayer);
|
||||||
|
this.drawSamThreats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function drawGroundObjects() {
|
function drawGroundObjects() {
|
||||||
groundObjectsLayer.clearLayers();
|
groundObjectsLayer.clearLayers();
|
||||||
blueSamDetectionLayer.clearLayers();
|
blueSamDetectionLayer.clearLayers();
|
||||||
@ -361,16 +446,7 @@ function drawGroundObjects() {
|
|||||||
blueSamThreatLayer.clearLayers();
|
blueSamThreatLayer.clearLayers();
|
||||||
redSamThreatLayer.clearLayers();
|
redSamThreatLayer.clearLayers();
|
||||||
game.groundObjects.forEach((tgo) => {
|
game.groundObjects.forEach((tgo) => {
|
||||||
L.marker(tgo.position, { icon: iconFor(tgo.blue) })
|
new TheaterGroundObject(tgo).draw();
|
||||||
.bindTooltip(`${tgo.name}<br />${tgo.units.join("<br />")}`)
|
|
||||||
.on("click", function () {
|
|
||||||
tgo.showInfoDialog();
|
|
||||||
})
|
|
||||||
.on("contextmenu", function () {
|
|
||||||
tgo.showPackageDialog();
|
|
||||||
})
|
|
||||||
.addTo(groundObjectsLayer);
|
|
||||||
drawSamThreatsAt(tgo);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user