feat(alarm state): refactor to separe alarm state from radar state. Kown issue: alarm state is not correctly mantained

This commit is contained in:
MarcoJayUsai
2025-03-24 18:42:04 +01:00
parent f7e9fc5cbc
commit 1622d663bb
15 changed files with 174 additions and 253 deletions

View File

@@ -97,7 +97,6 @@ export const states: string[] = [
];
export const ROEs: string[] = ["free", "designated", "", "return", "hold"];
export const alarmStates: string[] = ["auto", "green", "red"];
export const reactionsToThreat: string[] = ["none", "manoeuvre", "passive", "evade"];
export const emissionsCountermeasures: string[] = ["silent", "attack", "defend", "free"];
@@ -453,6 +452,7 @@ export enum DataIndexes {
category,
alive,
alarmState,
radarState,
human,
controlled,
coalition,

View File

@@ -220,7 +220,7 @@ export interface UnitData {
markerCategory: string;
ID: number;
alive: boolean;
alarmState: AlarmState | undefined;
alarmState: AlarmState;
human: boolean;
controlled: boolean;
coalition: string;
@@ -417,7 +417,7 @@ export interface Drawing {
}
export enum AlarmState {
AUTO = 'auto',
RED = 'red',
GREEN = 'green',
RED = 'red'
AUTO = 'auto'
}

View File

@@ -660,7 +660,7 @@
}
/* Unit Radar State */
.unit-radar-state {
.unit-alarm-state {
height: 10px;
width: 10px;
position: absolute;
@@ -670,12 +670,12 @@
left: 35px;
bottom: 8px;
}
.unit[data-radar-state="green"] .unit-radar-state {
.unit[data-alarm-state="green"] .unit-alarm-state {
border: 1px solid white;
background: rgb(0, 226, 0);
}
.unit[data-radar-state="red"] .unit-radar-state {
.unit[data-alarm-state="red"] .unit-alarm-state {
border: 1px solid white;
background: red;
}

View File

@@ -1,7 +1,7 @@
import { Circle, LatLng, Polygon } from "leaflet";
import * as turf from "@turf/turf";
import { ROEs, emissionsCountermeasures, reactionsToThreat, states } from "../constants/constants";
import { DateAndTime } from "../interfaces";
import { AlarmState, DateAndTime } from "../interfaces";
import { Converter } from "usng";
import { MGRS } from "../types/types";
import { featureCollection } from "turf";
@@ -275,6 +275,19 @@ export function enumToROE(ROE: number) {
else return ROEs[0];
}
export function enumToAlarmState(alarmState: number) {
switch (alarmState) {
case 0:
return AlarmState.RED;
case 1:
return AlarmState.GREEN;
case 2:
return AlarmState.AUTO;
default:
return AlarmState.AUTO;
}
}
export function convertROE(idx: number) {
let roe = 0;
if (idx === 0) roe = 4;

View File

@@ -421,7 +421,7 @@ export class ServerManager {
setAlarmState(ID: number, alarmState: number, callback: CallableFunction = () => {}) {
var command = { ID: ID, alarmState: alarmState };
var data = { commandAlarmState: command };
var data = { setAlarmState: command };
this.PUT(data, callback);
}

View File

@@ -132,7 +132,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
const [activeRadioSettings, setActiveRadioSettings] = useState(null as null | { radio: Radio; TACAN: TACAN });
const [activeAdvancedSettings, setActiveAdvancedSettings] = useState(null as null | GeneralSettings);
const [lastUpdateTime, setLastUpdateTime] = useState(0);
const [showScenicModes, setShowScenicModes] = useState(true);
const [showScenicModes, setShowScenicModes] = useState(false);
const [showEngagementSettings, setShowEngagementSettings] = useState(false);
const [barrelHeight, setBarrelHeight] = useState(0);
const [muzzleVelocity, setMuzzleVelocity] = useState(0);
@@ -420,9 +420,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
<td className="flex gap-2 text-lg text-gray-200">
<FontAwesomeIcon icon={entry[1][0] as IconDefinition} />{" "}
<div
className={`
text-sm text-gray-400
`}
className={`text-sm text-gray-400`}
>
{entry[1][1] as string}
</div>
@@ -802,9 +800,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsRoeHold}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Hold fire: The unit will not shoot in any circumstance
</div>
@@ -812,9 +808,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsRoeReturn}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Return fire: The unit will not fire unless fired upon
</div>
@@ -822,17 +816,13 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsRoeDesignated}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
<div>
{" "}
Fire on target: The unit will not fire unless fired upon{" "}
<p
className={`
inline font-bold
`}
className={`inline font-bold`}
>
or
</p>{" "}
@@ -843,9 +833,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsRoeFree}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Free: The unit will fire at any detected enemy in range
</div>
@@ -853,25 +841,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
<div className="flex gap-4">
<div className="my-auto">
<FaExclamationCircle
className={`
animate-bounce text-xl
`}
className={`animate-bounce text-xl`}
/>
</div>
<div>
Currently, DCS blue and red ground units do not respect{" "}
<FontAwesomeIcon
icon={olButtonsRoeReturn}
className={`
my-auto text-white
`}
className={`my-auto text-white`}
/>{" "}
and{" "}
<FontAwesomeIcon
icon={olButtonsRoeDesignated}
className={`
my-auto text-white
`}
className={`my-auto text-white`}
/>{" "}
rules of engagement, so be careful, they may start shooting when you don't want them to. Use neutral units for finer
control.
@@ -957,6 +939,18 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
tooltipRelativeToParent={true}
>
{[olButtonsRoeHold, olButtonsRoeReturn, olButtonsRoeDesignated].map((icon, idx) => {
const getAlarmStateByIdx = (idx) => {
switch (idx) {
case 0:
return AlarmState.AUTO;
case 1:
return AlarmState.GREEN;
case 2:
return AlarmState.RED;
}
}
return (
<OlButtonGroupItem
key={idx}
@@ -966,11 +960,11 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
.setAlarmState(idx, null, () =>
setForcedUnitsData({
...forcedUnitsData,
alarmState: Object.values(AlarmState)[idx],
alarmState: getAlarmStateByIdx(idx),
})
);
}}
active={selectedUnitsData.alarmState === alarmStates[idx]}
active={selectedUnitsData.alarmState === getAlarmStateByIdx(idx)}
icon={icon}
/>
);
@@ -1007,9 +1001,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsThreatNone}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
No reaction: The unit will not react in any circumstance
</div>
@@ -1017,9 +1009,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsThreatPassive}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Passive: The unit will use counter-measures, but will not alter its course
</div>
@@ -1027,9 +1017,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsThreatManoeuvre}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Manouevre: The unit will try to evade the threat using manoeuvres, but no counter-measures
</div>
@@ -1037,9 +1025,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsThreatEvade}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Full evasion: the unit will try to evade the threat both manoeuvering and using counter-measures
</div>
@@ -1094,9 +1080,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsEmissionsSilent}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Radio silence: No radar or ECM will be used
</div>
@@ -1104,9 +1088,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsEmissionsDefend}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Defensive: The unit will turn radar and ECM on only when threatened
</div>
@@ -1114,9 +1096,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsEmissionsAttack}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Attack: The unit will use radar and ECM when engaging other units
</div>
@@ -1124,9 +1104,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{" "}
<FontAwesomeIcon
icon={olButtonsEmissionsFree}
className={`
my-auto min-w-8 text-white
`}
className={`my-auto min-w-8 text-white`}
/>{" "}
Free: the unit will use the radar and ECM all the time
</div>
@@ -1347,9 +1325,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
<div className="flex gap-4">
<div className="my-auto">
<FaExclamationCircle
className={`
animate-bounce text-xl
`}
className={`animate-bounce text-xl`}
/>
</div>
<div>
@@ -1529,9 +1505,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
{/* ============== Operate as toggle START ============== */}
{selectedUnits.every((unit) => unit.getCoalition() === "neutral") && (
<div
className={`
flex content-center justify-between
`}
className={`flex content-center justify-between`}
>
<span
className={`
@@ -1573,17 +1547,13 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Barrel height:{" "}
</div>
<OlNumberInput
decimalPlaces={1}
className={`
ml-auto
`}
className={`ml-auto`}
value={barrelHeight}
min={0}
max={100}
@@ -1598,26 +1568,20 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
m
</div>
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Muzzle velocity:{" "}
</div>
<OlNumberInput
decimalPlaces={0}
className={`
ml-auto
`}
className={`ml-auto`}
value={muzzleVelocity}
min={0}
max={10000}
@@ -1632,26 +1596,20 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
m/s
</div>
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Aim time:{" "}
</div>
<OlNumberInput
decimalPlaces={2}
className={`
ml-auto
`}
className={`ml-auto`}
value={aimTime}
min={0}
max={100}
@@ -1666,25 +1624,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
s
</div>
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Shots to fire:{" "}
</div>
<OlNumberInput
className={`
ml-auto
`}
className={`ml-auto`}
value={shotsToFire}
min={0}
max={100}
@@ -1701,17 +1653,13 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Shots base interval:{" "}
</div>
<OlNumberInput
decimalPlaces={2}
className={`
ml-auto
`}
className={`ml-auto`}
value={shotsBaseInterval}
min={0}
max={100}
@@ -1726,26 +1674,20 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
s
</div>
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Shots base scatter:{" "}
</div>
<OlNumberInput
decimalPlaces={2}
className={`
ml-auto
`}
className={`ml-auto`}
value={shotsBaseScatter}
min={0}
max={50}
@@ -1760,25 +1702,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
deg
</div>
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Engagement range:{" "}
</div>
<OlNumberInput
className={`
ml-auto
`}
className={`ml-auto`}
value={engagementRange}
min={0}
max={100000}
@@ -1793,25 +1729,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
m
</div>
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Targeting range:{" "}
</div>
<OlNumberInput
className={`
ml-auto
`}
className={`ml-auto`}
value={targetingRange}
min={0}
max={100000}
@@ -1826,25 +1756,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
m
</div>
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Aim method range:{" "}
</div>
<OlNumberInput
className={`
ml-auto
`}
className={`ml-auto`}
value={aimMethodRange}
min={0}
max={100000}
@@ -1859,25 +1783,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
m
</div>
</div>
<div className="flex align-center gap-2">
<div
className={`
my-auto
`}
className={`my-auto`}
>
Acquisition range:{" "}
</div>
<OlNumberInput
className={`
ml-auto
`}
className={`ml-auto`}
value={acquisitionRange}
min={0}
max={100000}
@@ -1892,9 +1810,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
}}
></OlNumberInput>
<div
className={`
my-auto
`}
className={`my-auto`}
>
m
</div>

View File

@@ -18,6 +18,7 @@ import {
computeBearingRangeString,
adjustBrightness,
bearingAndDistanceToLatLng,
enumToAlarmState,
} from "../other/utils";
import { CustomMarker } from "../map/markers/custommarker";
import { SVGInjector } from "@tanem/svg-injector";
@@ -84,7 +85,8 @@ export abstract class Unit extends CustomMarker {
/* Data controlled directly by the backend. No setters are provided to avoid misalignments */
#alive: boolean = false;
#alarmState: AlarmState | undefined = undefined;
#alarmState: AlarmState = AlarmState.AUTO;
#radarState: boolean | undefined = undefined;
#human: boolean = false;
#controlled: boolean = false;
#coalition: string = "neutral";
@@ -352,6 +354,9 @@ export abstract class Unit extends CustomMarker {
getAlarmState() {
return this.#alarmState;
}
getRadarState() {
return this.#radarState;
}
getTimeToNextTasking() {
return this.#timeToNextTasking;
}
@@ -541,6 +546,7 @@ export abstract class Unit extends CustomMarker {
var datumIndex = 0;
while (datumIndex != DataIndexes.endOfData) {
datumIndex = dataExtractor.extractUInt8();
switch (datumIndex) {
case DataIndexes.category:
dataExtractor.extractString();
@@ -549,20 +555,8 @@ export abstract class Unit extends CustomMarker {
this.setAlive(dataExtractor.extractBool());
updateMarker = true;
break;
case DataIndexes.alarmState:
let stringAlarmState = dataExtractor.extractString();
switch (stringAlarmState) {
case 'RED':
this.setAlarmState(AlarmState.RED);
break;
case 'GREEN':
this.setAlarmState(AlarmState.GREEN);
break;
case '':
this.setAlarmState(AlarmState.AUTO);
default:
break;
}
case DataIndexes.radarState:
this.#radarState = dataExtractor.extractBool();
updateMarker = true;
break;
case DataIndexes.human:
@@ -670,6 +664,9 @@ export abstract class Unit extends CustomMarker {
case DataIndexes.ROE:
this.#ROE = enumToROE(dataExtractor.extractUInt8());
break;
case DataIndexes.alarmState:
this.#alarmState = enumToAlarmState(dataExtractor.extractUInt8());
break;
case DataIndexes.reactionToThreat:
this.#reactionToThreat = enumToReactionToThreat(dataExtractor.extractUInt8());
break;
@@ -890,10 +887,9 @@ export abstract class Unit extends CustomMarker {
}
}
setAlarmState(newAlarmState: AlarmState) {
if (newAlarmState != this.#alarmState) {
this.#alarmState = newAlarmState;
console.log('---- alarm state updated: ', this.#alarmState);
setRadarState(newRadarState: boolean) {
if (newRadarState != this.#radarState) {
this.#radarState = newRadarState;
this.#updateMarker();
}
}
@@ -1436,7 +1432,7 @@ export abstract class Unit extends CustomMarker {
if (!this.#human) getApp().getServerManager().setROE(this.ID, ROE);
}
commandAlarmState(alarmState: number) {
setAlarmState(alarmState: number) {
if (!this.#human) getApp().getServerManager().setAlarmState(this.ID, alarmState);
}
@@ -1755,7 +1751,7 @@ 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.getLatLng().lat !== this.#position.lat || this.getLatLng().lng !== this.#position.lng) {
this.setLatLng(new LatLng(this.#position.lat, this.#position.lng));
@@ -1777,8 +1773,9 @@ export abstract class Unit extends CustomMarker {
/* Set dead/alive flag */
element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.#alive);
/* Set RED/GREEN state*/
if (this.#alarmState) element.querySelector(".unit")?.setAttribute("data-radar-state", this.#alarmState);
/* Set radar state*/
// if (this.#radarState !== undefined) element.querySelector(".unit")?.setAttribute("data-radar-state", (this.#radarState === true ? 'on' : 'off'));
if (this.#alarmState !== AlarmState.AUTO) element.querySelector(".unit")?.setAttribute("data-alarm-state", (this.#alarmState === AlarmState.RED ? 'red' : 'green'));
/* Set current unit state */
if (this.#human) {
@@ -1836,28 +1833,28 @@ export abstract class Unit extends CustomMarker {
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);
}
/* 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);
}
/* Draw the cluster element */
element
.querySelector(".unit")
?.toggleAttribute(
"data-is-cluster-leader",
this.#isClusterLeader &&
this.#clusterUnits.length > 1 &&
getApp().getMap().getOptions().clusterGroundUnits &&
getApp().getMap().getZoom() < CLUSTERING_ZOOM_TRANSITION &&
!this.getSelected()
);
if (this.#isClusterLeader && this.#clusterUnits.length > 1) {
const clusterEl = element.querySelector(".unit-cluster-id") as HTMLElement;
if (clusterEl) clusterEl.innerText = String(this.#clusterUnits.length);
}
/* Draw the cluster element */
element
.querySelector(".unit")
?.toggleAttribute(
"data-is-cluster-leader",
this.#isClusterLeader &&
this.#clusterUnits.length > 1 &&
getApp().getMap().getOptions().clusterGroundUnits &&
getApp().getMap().getZoom() < CLUSTERING_ZOOM_TRANSITION &&
!this.getSelected()
);
if (this.#isClusterLeader && this.#clusterUnits.length > 1) {
const clusterEl = element.querySelector(".unit-cluster-id") as HTMLElement;
if (clusterEl) clusterEl.innerText = String(this.#clusterUnits.length);
}
/* Set bullseyes positions */
const bullseyes = getApp().getMissionManager().getBullseyes();

View File

@@ -1,36 +1,14 @@
import { DomEvent, DomUtil, LatLng, LatLngBounds } from "leaflet";
import { getApp } from "../olympusapp";
import { AirUnit, GroundUnit, NavyUnit, Unit } from "./unit";
import {
areaContains,
bearingAndDistanceToLatLng,
deepCopyTable,
deg2rad,
getGroundElevation,
latLngToMercator,
mToFt,
mercatorToLatLng,
msToKnots,
} from "../other/utils";
import { CoalitionPolygon } from "../map/coalitionarea/coalitionpolygon";
import * as turf from "@turf/turf";
import { LatLng, LatLngBounds } from "leaflet";
import {
BLUE_COMMANDER,
DELETE_CYCLE_TIME,
DELETE_SLOW_THRESHOLD,
DataIndexes,
GAME_MASTER,
IADSDensities,
OlympusState,
RED_COMMANDER,
UnitControlSubState, alarmStates,
UnitControlSubState
} from "../constants/constants";
import { DataExtractor } from "../server/dataextractor";
import { citiesDatabase } from "./databases/citiesdatabase";
import { TemporaryUnitMarker } from "../map/markers/temporaryunitmarker";
import { AlarmState, Contact, GeneralSettings, Radio, TACAN, UnitBlueprint, UnitData, UnitSpawnTable } from "../interfaces";
import { Group } from "./group";
import { CoalitionCircle } from "../map/coalitionarea/coalitioncircle";
import { ContextActionSet } from "./contextactionset";
import {
AWACSReferenceChangedEvent,
CommandModeOptionsChangedEvent,
@@ -46,11 +24,30 @@ import {
UnitsRefreshedEvent,
UnitsUpdatedEvent,
} from "../events";
import { UnitDatabase } from "./databases/unitdatabase";
import * as turf from "@turf/turf";
import { Contact, GeneralSettings, Radio, TACAN, UnitBlueprint, UnitData, UnitSpawnTable } from "../interfaces";
import { CoalitionCircle } from "../map/coalitionarea/coalitioncircle";
import { CoalitionPolygon } from "../map/coalitionarea/coalitionpolygon";
import { PathMarker } from "../map/markers/pathmarker";
import { TemporaryUnitMarker } from "../map/markers/temporaryunitmarker";
import { getApp } from "../olympusapp";
import {
areaContains,
bearingAndDistanceToLatLng,
deepCopyTable,
deg2rad,
getGroundElevation,
latLngToMercator,
mToFt,
mercatorToLatLng,
msToKnots,
} from "../other/utils";
import { DataExtractor } from "../server/dataextractor";
import { Coalition } from "../types/types";
import { ClusterMarker } from "../map/markers/clustermarker";
import { ContextActionSet } from "./contextactionset";
import { citiesDatabase } from "./databases/citiesdatabase";
import { UnitDatabase } from "./databases/unitdatabase";
import { Group } from "./group";
import { AirUnit, GroundUnit, NavyUnit, Unit } from "./unit";
/** The UnitsManager handles the creation, update, and control of units. Data is strictly updated by the server ONLY. This means that any interaction from the user will always and only
* result in a command to the server, executed by means of a REST PUT request. Any subsequent change in data will be reflected only when the new data is sent back by the server. This strategy allows
@@ -787,7 +784,7 @@ export class UnitsManager {
let callback = (units) => {
onExecution();
units.forEach((unit: Unit) => unit.commandAlarmState(alarmState));
units.forEach((unit: Unit) => unit.setAlarmState(alarmState));
this.#showActionMessage(units, `Alarm State set to ${alarmState.toString()}`);
};