mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
132 lines
4.7 KiB
JavaScript
132 lines
4.7 KiB
JavaScript
// src/data/tr3bRegistry.js
|
|
/**
|
|
* @module tr3bRegistry
|
|
* @description Session-scoped registry of contacts the operator has converted
|
|
* into a TR-3B (the black-triangle Easter egg).
|
|
*
|
|
* Shared, module-level, cross-layer state — the same pattern as
|
|
* `militaryRegistry.js`: identity is the ICAO 24-bit address, so a contact
|
|
* stays converted whether the civil `flights` layer or the `military` layer
|
|
* happens to own it, and a layer handoff never loses (or duplicates) the
|
|
* conversion.
|
|
*
|
|
* DELIBERATELY NOT PERSISTED. No localStorage, no share-link param, no schema
|
|
* change: the conversion lives for the page session and dies with a reload.
|
|
* Layer teardown also leaves the set intact ON PURPOSE — the set holds nothing
|
|
* but hex strings the user personally clicked (bounded by their own clicks),
|
|
* and re-tracking the same aircraft after a layer restart should still show the
|
|
* triangle. Only a reload resets it.
|
|
*/
|
|
|
|
/** @type {Set<string>} Converted contact ids, lower-cased ICAO 24-bit hex. */
|
|
const _converted = new Set();
|
|
|
|
/** The class/type label a converted contact reports in place of its real type. */
|
|
export const TR3B_TYPE_LABEL = 'TR-3B';
|
|
|
|
/**
|
|
* The `aircraftClass` a converted contact reports to the analyst engine.
|
|
*
|
|
* Lower-case and hyphen-free to match the `classifyAircraft()` vocabulary
|
|
* (`airliner`, `fastjet`, …) that every other analyst record uses — the engine
|
|
* treats `aircraftClass` as a free-text field, so this is just one more value
|
|
* to filter and group on, never an enum it has to know about. Deliberately the
|
|
* STYLE-INDEPENDENT id, not the `tr3bHot` sprite variant: a query must return
|
|
* the same answer in FLIR as in Normal.
|
|
*/
|
|
export const TR3B_CLASS = 'tr3b';
|
|
|
|
/** @param {*} id Raw contact id. @returns {string} Normalized registry key. */
|
|
function key(id) {
|
|
return String(id ?? '')
|
|
.trim()
|
|
.toLowerCase();
|
|
}
|
|
|
|
/**
|
|
* Whether a contact is currently rendered as a TR-3B.
|
|
* @param {string} id ICAO 24-bit address (any case).
|
|
* @returns {boolean}
|
|
*/
|
|
export function isTr3b(id) {
|
|
const k = key(id);
|
|
return k ? _converted.has(k) : false;
|
|
}
|
|
|
|
/**
|
|
* Explicitly set a contact's conversion state.
|
|
* @param {string} id ICAO 24-bit address.
|
|
* @param {boolean} on True to convert, false to restore.
|
|
* @returns {boolean} The resulting state (false for an unusable id).
|
|
*/
|
|
export function setTr3b(id, on) {
|
|
const k = key(id);
|
|
if (!k) return false;
|
|
if (on === true) _converted.add(k);
|
|
else _converted.delete(k);
|
|
return _converted.has(k);
|
|
}
|
|
|
|
/**
|
|
* Flip a contact between its real silhouette and the TR-3B.
|
|
* @param {string} id ICAO 24-bit address.
|
|
* @returns {boolean} The resulting state (false for an unusable id).
|
|
*/
|
|
export function toggleTr3b(id) {
|
|
return setTr3b(id, !isTr3b(id));
|
|
}
|
|
|
|
/** @returns {string[]} Every currently converted id (lower-case hex). */
|
|
export function tr3bConvertedIds() {
|
|
return [..._converted];
|
|
}
|
|
|
|
/** @returns {number} How many contacts are converted right now. */
|
|
export function tr3bCount() {
|
|
return _converted.size;
|
|
}
|
|
|
|
/** Drop every conversion. Test/reset seam — production has no caller. */
|
|
export function clearTr3bRegistry() {
|
|
_converted.clear();
|
|
}
|
|
|
|
/**
|
|
* Resolve the sprite kind a contact's billboard should draw.
|
|
*
|
|
* Returns the aircraft's own class untouched for an unconverted contact, so
|
|
* layers can route every `aircraftIcon()` call through this without changing
|
|
* ordinary behaviour. Only the IMAGE is swapped: billboard scale still follows
|
|
* the real class, so a converted 737 keeps a 737's on-screen footprint.
|
|
* @param {string} id ICAO 24-bit address.
|
|
* @param {string|undefined} klass The contact's classifyAircraft() kind.
|
|
* @param {{hot?: boolean}} [options] `hot` = an IR/thermal style is active.
|
|
* @returns {string|undefined} Sprite kind for `aircraftIcon()`.
|
|
*/
|
|
export function tr3bIconKind(id, klass, { hot = false } = {}) {
|
|
if (!isTr3b(id)) return klass;
|
|
return hot === true ? 'tr3bHot' : 'tr3b';
|
|
}
|
|
|
|
/**
|
|
* Class/type label override for a converted contact.
|
|
* @param {string} id ICAO 24-bit address.
|
|
* @param {*} [fallback=null] Real label to use when the contact is not converted.
|
|
* @returns {*} `'TR-3B'` when converted, else `fallback`.
|
|
*/
|
|
export function tr3bTypeLabel(id, fallback = null) {
|
|
return isTr3b(id) ? TR3B_TYPE_LABEL : fallback;
|
|
}
|
|
|
|
/**
|
|
* Analyst-record `aircraftClass` override for a converted contact, so a query
|
|
* or superlative agrees with the triangle on screen instead of reporting the
|
|
* airframe the conversion replaced.
|
|
* @param {string} id ICAO 24-bit address.
|
|
* @param {*} [fallback=null] Real class to use when the contact is not converted.
|
|
* @returns {*} `'tr3b'` when converted, else `fallback`.
|
|
*/
|
|
export function tr3bAircraftClass(id, fallback = null) {
|
|
return isTr3b(id) ? TR3B_CLASS : fallback;
|
|
}
|