mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
feat(radar state): initial scaffolding
This commit is contained in:
parent
16e77087f5
commit
ee15106be1
@ -7,6 +7,7 @@ namespace DataIndex {
|
||||
startOfData = 0,
|
||||
category,
|
||||
alive,
|
||||
radarState,
|
||||
human,
|
||||
controlled,
|
||||
coalition,
|
||||
|
||||
@ -112,10 +112,12 @@ public:
|
||||
virtual void setRacetrackLength(double newValue) { updateValue(racetrackLength, newValue, DataIndex::racetrackLength); }
|
||||
virtual void setRacetrackAnchor(Coords newValue) { updateValue(racetrackAnchor, newValue, DataIndex::racetrackAnchor); }
|
||||
virtual void setRacetrackBearing(double newValue) { updateValue(racetrackBearing, newValue, DataIndex::racetrackBearing); }
|
||||
virtual void setRadarState(string newValue) { updateValue(radarState, newValue, DataIndex::radarState); }
|
||||
|
||||
/********** Getters **********/
|
||||
virtual string getCategory() { return category; };
|
||||
virtual bool getAlive() { return alive; }
|
||||
virtual string getRadarState() { return radarState; }
|
||||
virtual bool getHuman() { return human; }
|
||||
virtual bool getControlled() { return controlled; }
|
||||
virtual unsigned char getCoalition() { return coalition; }
|
||||
@ -178,6 +180,7 @@ protected:
|
||||
string callsign = "";
|
||||
string groupName = "";
|
||||
unsigned char state = State::NONE;
|
||||
string radarState = "";
|
||||
string task = "";
|
||||
bool hasTask = false;
|
||||
Coords position = Coords(NULL);
|
||||
|
||||
@ -152,7 +152,6 @@ void Server::handle_get(http_request request)
|
||||
}
|
||||
/* Drawings data*/
|
||||
else if (URI.compare(DRAWINGS_URI) == 0 && drawingsByLayer.has_object_field(L"drawings")) {
|
||||
log("Trying to answer with drawings...");
|
||||
answer[L"drawings"] = drawingsByLayer[L"drawings"];
|
||||
}
|
||||
|
||||
|
||||
@ -83,6 +83,11 @@ void Unit::update(json::value json, double dt)
|
||||
if (json.has_boolean_field(L"isAlive"))
|
||||
setAlive(json[L"isAlive"].as_bool());
|
||||
|
||||
if (json.has_string_field(L"radarState")) {
|
||||
log("Unit " + to_string(json[L"unitName"]) + " has radarState: " + to_string(json[L"radarState"]));
|
||||
setRadarState(to_string(json[L"radarState"]));
|
||||
}
|
||||
|
||||
if (json.has_boolean_field(L"isHuman"))
|
||||
setHuman(json[L"isHuman"].as_bool());
|
||||
|
||||
@ -208,6 +213,7 @@ void Unit::refreshLeaderData(unsigned long long time) {
|
||||
case DataIndex::operateAs: updateValue(operateAs, leader->operateAs, datumIndex); break;
|
||||
case DataIndex::shotsScatter: updateValue(shotsScatter, leader->shotsScatter, datumIndex); break;
|
||||
case DataIndex::shotsIntensity: updateValue(shotsIntensity, leader->shotsIntensity, datumIndex); break;
|
||||
case DataIndex::radarState: updateValue(radarState, leader->radarState, datumIndex); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -251,6 +257,7 @@ void Unit::getData(stringstream& ss, unsigned long long time)
|
||||
switch (datumIndex) {
|
||||
case DataIndex::category: appendString(ss, datumIndex, category); break;
|
||||
case DataIndex::alive: appendNumeric(ss, datumIndex, alive); break;
|
||||
case DataIndex::radarState: appendNumeric(ss, datumIndex, radarState); break;
|
||||
case DataIndex::human: appendNumeric(ss, datumIndex, human); break;
|
||||
case DataIndex::controlled: appendNumeric(ss, datumIndex, controlled); break;
|
||||
case DataIndex::coalition: appendNumeric(ss, datumIndex, coalition); break;
|
||||
|
||||
@ -96,6 +96,12 @@ export const states: string[] = [
|
||||
UnitState.LAND_AT_POINT,
|
||||
];
|
||||
|
||||
export enum RADAR_STATES {
|
||||
RED = 'red',
|
||||
GREEN = 'green',
|
||||
AUTO = 'auto'
|
||||
}
|
||||
|
||||
export const ROEs: string[] = ["free", "designated", "", "return", "hold"];
|
||||
export const reactionsToThreat: string[] = ["none", "manoeuvre", "passive", "evade"];
|
||||
export const emissionsCountermeasures: string[] = ["silent", "attack", "defend", "free"];
|
||||
@ -448,6 +454,7 @@ export enum DataIndexes {
|
||||
startOfData = 0,
|
||||
category,
|
||||
alive,
|
||||
radarState,
|
||||
human,
|
||||
controlled,
|
||||
coalition,
|
||||
|
||||
@ -83,6 +83,7 @@ export abstract class Unit extends CustomMarker {
|
||||
|
||||
/* Data controlled directly by the backend. No setters are provided to avoid misalignments */
|
||||
#alive: boolean = false;
|
||||
#radarState: string = '';
|
||||
#human: boolean = false;
|
||||
#controlled: boolean = false;
|
||||
#coalition: string = "neutral";
|
||||
@ -488,6 +489,10 @@ export abstract class Unit extends CustomMarker {
|
||||
this.setAlive(dataExtractor.extractBool());
|
||||
updateMarker = true;
|
||||
break;
|
||||
case DataIndexes.radarState:
|
||||
this.setRadarState(dataExtractor.extractString());
|
||||
updateMarker = true;
|
||||
break;
|
||||
case DataIndexes.human:
|
||||
this.#human = dataExtractor.extractBool();
|
||||
break;
|
||||
@ -764,6 +769,15 @@ export abstract class Unit extends CustomMarker {
|
||||
}
|
||||
}
|
||||
|
||||
setRadarState(newRadarState: string) {
|
||||
if (newRadarState != this.#radarState) {
|
||||
this.#radarState = newRadarState;
|
||||
// TODO: check if an event is needed -- surely yes to update the UI
|
||||
console.log('----radar state updated: ', this.#radarState);
|
||||
this.#updateMarker();
|
||||
}
|
||||
}
|
||||
|
||||
/** Set the unit as user-selected
|
||||
*
|
||||
* @param selected (boolean)
|
||||
@ -1542,149 +1556,152 @@ export abstract class Unit extends CustomMarker {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getHidden()) return; // We won't draw the marker if the unit is hidden
|
||||
|
||||
/* Draw the marker */
|
||||
if (!this.getHidden()) {
|
||||
if (this.getLatLng().lat !== this.#position.lat || this.getLatLng().lng !== this.#position.lng) {
|
||||
this.setLatLng(new LatLng(this.#position.lat, this.#position.lng));
|
||||
}
|
||||
if (this.getLatLng().lat !== this.#position.lat || this.getLatLng().lng !== this.#position.lng) {
|
||||
this.setLatLng(new LatLng(this.#position.lat, this.#position.lng));
|
||||
}
|
||||
|
||||
var element = this.getElement();
|
||||
if (element != null) {
|
||||
/* Draw the velocity vector */
|
||||
element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${15 + this.#speed / 5}px;`);
|
||||
var element = this.getElement();
|
||||
if (element != null) {
|
||||
/* Draw the velocity vector */
|
||||
element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${15 + this.#speed / 5}px;`);
|
||||
|
||||
/* Set fuel data */
|
||||
element.querySelector(".unit-fuel-level")?.setAttribute("style", `width: ${this.#fuel}%`);
|
||||
element.querySelector(".unit")?.toggleAttribute("data-has-low-fuel", this.#fuel < 20);
|
||||
/* Set fuel data */
|
||||
element.querySelector(".unit-fuel-level")?.setAttribute("style", `width: ${this.#fuel}%`);
|
||||
element.querySelector(".unit")?.toggleAttribute("data-has-low-fuel", this.#fuel < 20);
|
||||
|
||||
/* Set health data */
|
||||
element.querySelector(".unit-health-level")?.setAttribute("style", `width: ${this.#health}%`);
|
||||
element.querySelector(".unit")?.toggleAttribute("data-has-low-health", this.#health < 20);
|
||||
/* Set health data */
|
||||
element.querySelector(".unit-health-level")?.setAttribute("style", `width: ${this.#health}%`);
|
||||
element.querySelector(".unit")?.toggleAttribute("data-has-low-health", this.#health < 20);
|
||||
|
||||
/* Set dead/alive flag */
|
||||
element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.#alive);
|
||||
/* Set dead/alive flag */
|
||||
element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.#alive);
|
||||
|
||||
/* Set current unit state */
|
||||
if (this.#human) {
|
||||
// Unit is human
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "human");
|
||||
} else if (!this.#controlled) {
|
||||
// Unit is under DCS control (not Olympus)
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "dcs");
|
||||
} else if ((this.getCategory() == "Aircraft" || this.getCategory() == "Helicopter") && !this.#hasTask) {
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "no-task");
|
||||
} else {
|
||||
// Unit is under Olympus control
|
||||
if (this.#onOff) {
|
||||
if (this.#isActiveTanker) element.querySelector(".unit")?.setAttribute("data-state", "tanker");
|
||||
else if (this.#isActiveAWACS) element.querySelector(".unit")?.setAttribute("data-state", "AWACS");
|
||||
else element.querySelector(".unit")?.setAttribute("data-state", this.#state.toLowerCase());
|
||||
} else {
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "off");
|
||||
}
|
||||
}
|
||||
/* Set RED/GREEN state*/
|
||||
if (this.#radarState !== '') element.querySelector(".unit")?.setAttribute("data-radar-state", this.#radarState);
|
||||
|
||||
/* Set altitude and speed */
|
||||
if (element.querySelector(".unit-altitude"))
|
||||
(<HTMLElement>element.querySelector(".unit-altitude")).innerText = "FL" + zeroAppend(Math.floor(mToFt(this.#position.alt as number) / 100), 3);
|
||||
if (element.querySelector(".unit-speed"))
|
||||
(<HTMLElement>element.querySelector(".unit-speed")).innerText = String(Math.floor(msToKnots(this.#speed))) + "GS";
|
||||
|
||||
/* Rotate elements according to heading */
|
||||
element.querySelectorAll("[data-rotate-to-heading]").forEach((el) => {
|
||||
const headingDeg = rad2deg(this.#track);
|
||||
let currentStyle = el.getAttribute("style") || "";
|
||||
el.setAttribute("style", currentStyle + `transform:rotate(${headingDeg}deg);`);
|
||||
});
|
||||
|
||||
/* Turn on ammo indicators */
|
||||
var hasFox1 = element.querySelector(".unit")?.hasAttribute("data-has-fox-1");
|
||||
var hasFox2 = element.querySelector(".unit")?.hasAttribute("data-has-fox-2");
|
||||
var hasFox3 = element.querySelector(".unit")?.hasAttribute("data-has-fox-3");
|
||||
var hasOtherAmmo = element.querySelector(".unit")?.hasAttribute("data-has-other-ammo");
|
||||
|
||||
var newHasFox1 = false;
|
||||
var newHasFox2 = false;
|
||||
var newHasFox3 = false;
|
||||
var newHasOtherAmmo = false;
|
||||
Object.values(this.#ammo).forEach((ammo: Ammo) => {
|
||||
if (ammo.category == 1 && ammo.missileCategory == 1) {
|
||||
if (ammo.guidance == 4 || ammo.guidance == 5) newHasFox1 = true;
|
||||
else if (ammo.guidance == 2) newHasFox2 = true;
|
||||
else if (ammo.guidance == 3) newHasFox3 = true;
|
||||
} else newHasOtherAmmo = true;
|
||||
});
|
||||
|
||||
if (hasFox1 != newHasFox1) element.querySelector(".unit")?.toggleAttribute("data-has-fox-1", newHasFox1);
|
||||
if (hasFox2 != newHasFox2) element.querySelector(".unit")?.toggleAttribute("data-has-fox-2", newHasFox2);
|
||||
if (hasFox3 != newHasFox3) element.querySelector(".unit")?.toggleAttribute("data-has-fox-3", newHasFox3);
|
||||
if (hasOtherAmmo != newHasOtherAmmo) element.querySelector(".unit")?.toggleAttribute("data-has-other-ammo", newHasOtherAmmo);
|
||||
|
||||
/* Draw the hotgroup element */
|
||||
element.querySelector(".unit")?.toggleAttribute("data-is-in-hotgroup", this.#hotgroup != null);
|
||||
if (this.#hotgroup) {
|
||||
const hotgroupEl = element.querySelector(".unit-hotgroup-id") as HTMLElement;
|
||||
if (hotgroupEl) hotgroupEl.innerText = String(this.#hotgroup);
|
||||
}
|
||||
|
||||
/* Set bullseyes positions */
|
||||
const bullseyes = getApp().getMissionManager().getBullseyes();
|
||||
if (Object.keys(bullseyes).length > 0) {
|
||||
const bullseye = `${computeBearingRangeString(bullseyes[coalitionToEnum(getApp().getMap().getOptions().AWACSCoalition)].getLatLng(), this.getPosition())}`;
|
||||
if (element.querySelector(".unit-bullseye")) (<HTMLElement>element.querySelector(".unit-bullseye")).innerText = `${bullseye}`;
|
||||
}
|
||||
|
||||
/* Set BRAA */
|
||||
const reference = getApp().getUnitsManager().getAWACSReference();
|
||||
if (reference && reference !== this && reference.getAlive()) {
|
||||
const BRAA = `${computeBearingRangeString(reference.getPosition(), this.getPosition())}`;
|
||||
if (element.querySelector(".unit-braa")) (<HTMLElement>element.querySelector(".unit-braa")).innerText = `${BRAA}`;
|
||||
} else if (element.querySelector(".unit-braa")) (<HTMLElement>element.querySelector(".unit-braa")).innerText = ``;
|
||||
|
||||
/* Set operate as */
|
||||
element
|
||||
.querySelector(".unit")
|
||||
?.setAttribute(
|
||||
"data-operate-as",
|
||||
this.getState() === UnitState.MISS_ON_PURPOSE || this.getState() === UnitState.SCENIC_AAA || this.getState() === UnitState.SIMULATE_FIRE_FIGHT
|
||||
? this.#operateAs
|
||||
: "neutral"
|
||||
);
|
||||
}
|
||||
|
||||
/* Set vertical offset for altitude stacking */
|
||||
var pos = getApp().getMap().latLngToLayerPoint(this.getLatLng()).round();
|
||||
this.setZIndexOffset(1000 + Math.floor(this.#position.alt as number) - pos.y + (this.#highlighted || this.#selected ? 5000 : 0));
|
||||
|
||||
/* Get the cluster this unit is in to position the label correctly */
|
||||
let cluster = Object.values(getApp().getUnitsManager().getClusters()).find((cluster) => cluster.includes(this));
|
||||
if (cluster && cluster.length > 1) {
|
||||
let clusterMean = turf.centroid(turf.featureCollection(cluster.map((unit) => turf.point([unit.getPosition().lng, unit.getPosition().lat]))));
|
||||
let bearingFromCluster = bearing(
|
||||
clusterMean.geometry.coordinates[1],
|
||||
clusterMean.geometry.coordinates[0],
|
||||
this.getPosition().lat,
|
||||
this.getPosition().lng,
|
||||
false
|
||||
);
|
||||
|
||||
if (bearingFromCluster < 0) bearingFromCluster += 360;
|
||||
let trackIndex = Math.round(bearingFromCluster / 45);
|
||||
|
||||
for (let idx = 0; idx < bearingStrings.length; idx++) element?.querySelector(".unit-summary")?.classList.remove("cluster-" + bearingStrings[idx]);
|
||||
element?.querySelector(".unit-summary")?.classList.add("cluster-" + bearingStrings[trackIndex]);
|
||||
/* Set current unit state */
|
||||
if (this.#human) {
|
||||
// Unit is human
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "human");
|
||||
} else if (!this.#controlled) {
|
||||
// Unit is under DCS control (not Olympus)
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "dcs");
|
||||
} else if ((this.getCategory() == "Aircraft" || this.getCategory() == "Helicopter") && !this.#hasTask) {
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "no-task");
|
||||
} else {
|
||||
for (let idx = 0; idx < bearingStrings.length; idx++) element?.querySelector(".unit-summary")?.classList.remove("cluster-" + bearingStrings[idx]);
|
||||
element?.querySelector(".unit-summary")?.classList.add("cluster-north-east");
|
||||
// Unit is under Olympus control
|
||||
if (this.#onOff) {
|
||||
if (this.#isActiveTanker) element.querySelector(".unit")?.setAttribute("data-state", "tanker");
|
||||
else if (this.#isActiveAWACS) element.querySelector(".unit")?.setAttribute("data-state", "AWACS");
|
||||
else element.querySelector(".unit")?.setAttribute("data-state", this.#state.toLowerCase());
|
||||
} else {
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "off");
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the contact trail */
|
||||
if (/*TODO getApp().getMap().getOptions().AWACSMode*/ false) {
|
||||
this.#trailPolylines = this.#trailPositions.map(
|
||||
(latlng, idx) => new Polyline([latlng, latlng], { color: colors.WHITE, opacity: 1 - (idx + 1) / TRAIL_LENGTH })
|
||||
);
|
||||
this.#trailPolylines.forEach((polyline) => polyline.addTo(getApp().getMap()));
|
||||
/* Set altitude and speed */
|
||||
if (element.querySelector(".unit-altitude"))
|
||||
(<HTMLElement>element.querySelector(".unit-altitude")).innerText = "FL" + zeroAppend(Math.floor(mToFt(this.#position.alt as number) / 100), 3);
|
||||
if (element.querySelector(".unit-speed"))
|
||||
(<HTMLElement>element.querySelector(".unit-speed")).innerText = String(Math.floor(msToKnots(this.#speed))) + "GS";
|
||||
|
||||
/* Rotate elements according to heading */
|
||||
element.querySelectorAll("[data-rotate-to-heading]").forEach((el) => {
|
||||
const headingDeg = rad2deg(this.#track);
|
||||
let currentStyle = el.getAttribute("style") || "";
|
||||
el.setAttribute("style", currentStyle + `transform:rotate(${headingDeg}deg);`);
|
||||
});
|
||||
|
||||
/* Turn on ammo indicators */
|
||||
var hasFox1 = element.querySelector(".unit")?.hasAttribute("data-has-fox-1");
|
||||
var hasFox2 = element.querySelector(".unit")?.hasAttribute("data-has-fox-2");
|
||||
var hasFox3 = element.querySelector(".unit")?.hasAttribute("data-has-fox-3");
|
||||
var hasOtherAmmo = element.querySelector(".unit")?.hasAttribute("data-has-other-ammo");
|
||||
|
||||
var newHasFox1 = false;
|
||||
var newHasFox2 = false;
|
||||
var newHasFox3 = false;
|
||||
var newHasOtherAmmo = false;
|
||||
Object.values(this.#ammo).forEach((ammo: Ammo) => {
|
||||
if (ammo.category == 1 && ammo.missileCategory == 1) {
|
||||
if (ammo.guidance == 4 || ammo.guidance == 5) newHasFox1 = true;
|
||||
else if (ammo.guidance == 2) newHasFox2 = true;
|
||||
else if (ammo.guidance == 3) newHasFox3 = true;
|
||||
} else newHasOtherAmmo = true;
|
||||
});
|
||||
|
||||
if (hasFox1 != newHasFox1) element.querySelector(".unit")?.toggleAttribute("data-has-fox-1", newHasFox1);
|
||||
if (hasFox2 != newHasFox2) element.querySelector(".unit")?.toggleAttribute("data-has-fox-2", newHasFox2);
|
||||
if (hasFox3 != newHasFox3) element.querySelector(".unit")?.toggleAttribute("data-has-fox-3", newHasFox3);
|
||||
if (hasOtherAmmo != newHasOtherAmmo) element.querySelector(".unit")?.toggleAttribute("data-has-other-ammo", newHasOtherAmmo);
|
||||
|
||||
/* Draw the hotgroup element */
|
||||
element.querySelector(".unit")?.toggleAttribute("data-is-in-hotgroup", this.#hotgroup != null);
|
||||
if (this.#hotgroup) {
|
||||
const hotgroupEl = element.querySelector(".unit-hotgroup-id") as HTMLElement;
|
||||
if (hotgroupEl) hotgroupEl.innerText = String(this.#hotgroup);
|
||||
}
|
||||
|
||||
/* Set bullseyes positions */
|
||||
const bullseyes = getApp().getMissionManager().getBullseyes();
|
||||
if (Object.keys(bullseyes).length > 0) {
|
||||
const bullseye = `${computeBearingRangeString(bullseyes[coalitionToEnum(getApp().getMap().getOptions().AWACSCoalition)].getLatLng(), this.getPosition())}`;
|
||||
if (element.querySelector(".unit-bullseye")) (<HTMLElement>element.querySelector(".unit-bullseye")).innerText = `${bullseye}`;
|
||||
}
|
||||
|
||||
/* Set BRAA */
|
||||
const reference = getApp().getUnitsManager().getAWACSReference();
|
||||
if (reference && reference !== this && reference.getAlive()) {
|
||||
const BRAA = `${computeBearingRangeString(reference.getPosition(), this.getPosition())}`;
|
||||
if (element.querySelector(".unit-braa")) (<HTMLElement>element.querySelector(".unit-braa")).innerText = `${BRAA}`;
|
||||
} else if (element.querySelector(".unit-braa")) (<HTMLElement>element.querySelector(".unit-braa")).innerText = ``;
|
||||
|
||||
/* Set operate as */
|
||||
element
|
||||
.querySelector(".unit")
|
||||
?.setAttribute(
|
||||
"data-operate-as",
|
||||
this.getState() === UnitState.MISS_ON_PURPOSE || this.getState() === UnitState.SCENIC_AAA || this.getState() === UnitState.SIMULATE_FIRE_FIGHT
|
||||
? this.#operateAs
|
||||
: "neutral"
|
||||
);
|
||||
}
|
||||
|
||||
/* Set vertical offset for altitude stacking */
|
||||
var pos = getApp().getMap().latLngToLayerPoint(this.getLatLng()).round();
|
||||
this.setZIndexOffset(1000 + Math.floor(this.#position.alt as number) - pos.y + (this.#highlighted || this.#selected ? 5000 : 0));
|
||||
|
||||
/* Get the cluster this unit is in to position the label correctly */
|
||||
let cluster = Object.values(getApp().getUnitsManager().getClusters()).find((cluster) => cluster.includes(this));
|
||||
if (cluster && cluster.length > 1) {
|
||||
let clusterMean = turf.centroid(turf.featureCollection(cluster.map((unit) => turf.point([unit.getPosition().lng, unit.getPosition().lat]))));
|
||||
let bearingFromCluster = bearing(
|
||||
clusterMean.geometry.coordinates[1],
|
||||
clusterMean.geometry.coordinates[0],
|
||||
this.getPosition().lat,
|
||||
this.getPosition().lng,
|
||||
false
|
||||
);
|
||||
|
||||
if (bearingFromCluster < 0) bearingFromCluster += 360;
|
||||
let trackIndex = Math.round(bearingFromCluster / 45);
|
||||
|
||||
for (let idx = 0; idx < bearingStrings.length; idx++) element?.querySelector(".unit-summary")?.classList.remove("cluster-" + bearingStrings[idx]);
|
||||
element?.querySelector(".unit-summary")?.classList.add("cluster-" + bearingStrings[trackIndex]);
|
||||
} else {
|
||||
for (let idx = 0; idx < bearingStrings.length; idx++) element?.querySelector(".unit-summary")?.classList.remove("cluster-" + bearingStrings[idx]);
|
||||
element?.querySelector(".unit-summary")?.classList.add("cluster-north-east");
|
||||
}
|
||||
|
||||
/* Draw the contact trail */
|
||||
if (/*TODO getApp().getMap().getOptions().AWACSMode*/ false) {
|
||||
this.#trailPolylines = this.#trailPositions.map(
|
||||
(latlng, idx) => new Polyline([latlng, latlng], { color: colors.WHITE, opacity: 1 - (idx + 1) / TRAIL_LENGTH })
|
||||
);
|
||||
this.#trailPolylines.forEach((polyline) => polyline.addTo(getApp().getMap()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -241,6 +241,7 @@ export class UnitsManager {
|
||||
if (datumIndex == DataIndexes.category) {
|
||||
const category = dataExtractor.extractString();
|
||||
this.addUnit(ID, category);
|
||||
|
||||
} else {
|
||||
/* Inconsistent data, we need to wait for a refresh */
|
||||
return updateTime;
|
||||
@ -250,6 +251,7 @@ export class UnitsManager {
|
||||
if (ID in this.#units) {
|
||||
this.#units[ID].setData(dataExtractor);
|
||||
this.#units[ID].getAlive() && updatedUnits.push(this.#units[ID]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1072,10 +1072,69 @@ function Olympus.setOnOff(groupName, onOff)
|
||||
end
|
||||
end
|
||||
|
||||
-- Disable the AI of a group on or off entirely
|
||||
function Olympus.setRedGreenAuto(groupName, redGreenAuto)
|
||||
Olympus.debug("Olympus.setRedGreenAuto " .. groupName .. " " .. tostring(redGreenAuto), 2)
|
||||
local group = Group.getByName(groupName)
|
||||
if group ~= nil then
|
||||
|
||||
if redGreenAuto == 'RED' then
|
||||
group:getController():setOption(AI.Option.Ground.id.ALARM_STATE, AI.Option.Ground.val.ALARM_STATE.RED)
|
||||
end
|
||||
|
||||
if redGreenAuto == 'GREEN' then
|
||||
group:getController():setOption(AI.Option.Ground.id.ALARM_STATE, AI.Option.Ground.val.ALARM_STATE.GREEN)
|
||||
end
|
||||
|
||||
if redGreenAuto == 'AUTO' then
|
||||
group:getController():setOption(AI.Option.Ground.id.ALARM_STATE, AI.Option.Ground.val.ALARM_STATE.AUTO)
|
||||
end
|
||||
Olympus.debug("Olympus.setRedGreenAuto completed successfully", 2)
|
||||
end
|
||||
end
|
||||
|
||||
function getUnitDescription(unit)
|
||||
return unit:getDescr()
|
||||
end
|
||||
|
||||
-- This function gets the navpoints from the DCS mission
|
||||
function Olympus.getNavPoints()
|
||||
local function extract_tag(str)
|
||||
return str:match("^%[(.-)%]")
|
||||
end
|
||||
|
||||
local navpoints = {}
|
||||
if mist.DBs.navPoints ~= nil then
|
||||
for coalitionName, coalitionNavpoints in pairs(mist.DBs.navPoints) do
|
||||
if navpoints[coalitionName] == nil then
|
||||
navpoints[coalitionName] = {}
|
||||
end
|
||||
|
||||
for index, navpointDrawingData in pairs(coalitionNavpoints) do
|
||||
local navpointCustomLayer = extract_tag(navpointDrawingData['callsignStr']);
|
||||
|
||||
-- Let's convert DCS coords to lat lon
|
||||
local vec3 = { x = navpointDrawingData['x'], y = 0, z = navpointDrawingData['y'] }
|
||||
local lat, lng = coord.LOtoLL(vec3)
|
||||
navpointDrawingData['lat'] = lat
|
||||
navpointDrawingData['lng'] = lng
|
||||
navpointDrawingData['coalition'] = coalitionName
|
||||
|
||||
if navpointCustomLayer ~= nil then
|
||||
if navpoints[coalitionName][navpointCustomLayer] == nil then
|
||||
navpoints[coalitionName][navpointCustomLayer] = {}
|
||||
end
|
||||
navpoints[coalitionName][navpointCustomLayer][navpointDrawingData['callsignStr']] = navpointDrawingData
|
||||
else
|
||||
navpoints[coalitionName][navpointDrawingData['callsignStr']] = navpointDrawingData
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return navpoints
|
||||
end
|
||||
|
||||
-- This function is periodically called to collect the data of all the existing drawings in the mission to be transmitted to the olympus.dll
|
||||
function Olympus.initializeDrawings()
|
||||
local drawings = {}
|
||||
@ -1129,6 +1188,10 @@ function Olympus.initializeDrawings()
|
||||
end
|
||||
end
|
||||
|
||||
local navpoints = Olympus.getNavPoints()
|
||||
|
||||
drawings['navpoints'] = navpoints
|
||||
|
||||
Olympus.drawingsByLayer["drawings"] = drawings
|
||||
|
||||
-- Send the drawings to the DLL
|
||||
@ -1214,6 +1277,18 @@ function Olympus.setUnitsData(arg, time)
|
||||
end
|
||||
|
||||
table["isAlive"] = unit:isExist() and unit:isActive() and unit:getLife() >= 1
|
||||
|
||||
table["radarState"] = "AUTO"
|
||||
|
||||
if unit:isActive() then
|
||||
if unit:getRadar() then
|
||||
-- Olympus.log:info("radarState: unit active and getRadar is true, setting RED.")
|
||||
table["radarState"] = "RED"
|
||||
else
|
||||
-- Olympus.log:info("radarState: unit active and getRadar is false, setting GREEN.")
|
||||
table["radarState"] = "GREEN"
|
||||
end
|
||||
end
|
||||
|
||||
local group = unit:getGroup()
|
||||
if group ~= nil then
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user