Set up icons for TGOs.

These are just the old icons, but it's better than nothing.
This commit is contained in:
Dan Albert 2021-05-18 21:43:49 -07:00
parent 4e37666037
commit af3b8a9902
2 changed files with 153 additions and 65 deletions

View File

@ -154,6 +154,8 @@ class GroundObjectJs(QObject):
positionChanged = Signal()
samThreatRangesChanged = Signal()
samDetectionRangesChanged = Signal()
categoryChanged = Signal()
deadChanged = Signal()
def __init__(self, tgo: TheaterGroundObject, game: Game) -> None:
super().__init__()
@ -189,6 +191,10 @@ class GroundObjectJs(QObject):
def name(self) -> str:
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:
dead_label = " [DEAD]" if dead else ""
unit_display_name = unit.type
@ -225,6 +231,12 @@ class GroundObjectJs(QObject):
ll = self.theater.point_to_ll(self.tgo.position)
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)
def samThreatRanges(self) -> List[float]:
if not self.tgo.might_have_aa:

View File

@ -18,6 +18,81 @@ const Colors = Object.freeze({
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) {
return meters * 0.000539957;
}
@ -91,28 +166,6 @@ L.control
)
.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;
new QWebChannel(qt.webChannelTransport, function (channel) {
game = channel.objects.game;
@ -130,14 +183,6 @@ function recenterMap(center) {
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;
class ControlPoint {
@ -156,6 +201,10 @@ class ControlPoint {
this.cp.destinationChanged.connect(() => this.onDestinationChanged());
}
icon() {
return Icons.for(this.cp.blue).ControlPoint;
}
hasDestination() {
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
// always the clickable thing.
return L.marker(location, {
icon: iconFor(this.cp.blue),
icon: this.icon(),
zIndexOffset: 1000,
draggable: this.cp.mobile,
autoPan: true,
@ -280,7 +329,7 @@ class ControlPoint {
makeSecondaryMarker() {
return L.marker(this.cp.position, {
icon: iconFor(this.cp.blue),
icon: this.icon(),
zIndexOffset: 1000,
});
}
@ -327,31 +376,67 @@ function drawControlPoints() {
});
}
function drawSamThreatsAt(tgo) {
const detectionLayer = tgo.blue
? blueSamDetectionLayer
: redSamDetectionLayer;
const threatLayer = tgo.blue ? blueSamThreatLayer : redSamThreatLayer;
const threatColor = tgo.blue ? Colors.Blue : Colors.Red;
const detectionColor = tgo.blue ? "#bb89ff" : "#eee17b";
class TheaterGroundObject {
constructor(tgo) {
this.tgo = tgo;
}
tgo.samDetectionRanges.forEach((range) => {
L.circle(tgo.position, {
radius: range,
color: detectionColor,
fill: false,
weight: 1,
}).addTo(detectionLayer);
});
samIsThreat() {
for (const range of this.tgo.samThreatRanges) {
if (range > 0) {
return true;
}
}
tgo.samThreatRanges.forEach((range) => {
L.circle(tgo.position, {
radius: range,
color: threatColor,
fill: false,
weight: 2,
}).addTo(threatLayer);
});
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
: redSamDetectionLayer;
const threatLayer = this.tgo.blue ? blueSamThreatLayer : redSamThreatLayer;
const threatColor = this.tgo.blue ? Colors.Blue : Colors.Red;
const detectionColor = this.tgo.blue ? "#bb89ff" : "#eee17b";
this.tgo.samDetectionRanges.forEach((range) => {
L.circle(this.tgo.position, {
radius: range,
color: detectionColor,
fill: false,
weight: 1,
}).addTo(detectionLayer);
});
this.tgo.samThreatRanges.forEach((range) => {
L.circle(this.tgo.position, {
radius: range,
color: threatColor,
fill: false,
weight: 2,
}).addTo(threatLayer);
});
}
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() {
@ -361,16 +446,7 @@ function drawGroundObjects() {
blueSamThreatLayer.clearLayers();
redSamThreatLayer.clearLayers();
game.groundObjects.forEach((tgo) => {
L.marker(tgo.position, { icon: iconFor(tgo.blue) })
.bindTooltip(`${tgo.name}<br />${tgo.units.join("<br />")}`)
.on("click", function () {
tgo.showInfoDialog();
})
.on("contextmenu", function () {
tgo.showPackageDialog();
})
.addTo(groundObjectsLayer);
drawSamThreatsAt(tgo);
new TheaterGroundObject(tgo).draw();
});
}