mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
feat(alarm state): refactor to separe alarm state from radar state. Kown issue: alarm state is not correctly mantained
This commit is contained in:
@@ -48,9 +48,9 @@ namespace ROE {
|
|||||||
|
|
||||||
namespace ALARM_STATE {
|
namespace ALARM_STATE {
|
||||||
enum ALARM_STATEs {
|
enum ALARM_STATEs {
|
||||||
AUTO = 0,
|
AUTO = 2,
|
||||||
GREEN = 1,
|
GREEN = 1,
|
||||||
RED = 2,
|
RED = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace DataIndex {
|
|||||||
category,
|
category,
|
||||||
alive,
|
alive,
|
||||||
alarmState,
|
alarmState,
|
||||||
|
radarState,
|
||||||
human,
|
human,
|
||||||
controlled,
|
controlled,
|
||||||
coalition,
|
coalition,
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public:
|
|||||||
virtual void setTargetID(unsigned int newValue) { updateValue(targetID, newValue, DataIndex::targetID); }
|
virtual void setTargetID(unsigned int newValue) { updateValue(targetID, newValue, DataIndex::targetID); }
|
||||||
virtual void setTargetPosition(Coords newValue) { updateValue(targetPosition, newValue, DataIndex::targetPosition); }
|
virtual void setTargetPosition(Coords newValue) { updateValue(targetPosition, newValue, DataIndex::targetPosition); }
|
||||||
virtual void setROE(unsigned char newValue, bool force = false);
|
virtual void setROE(unsigned char newValue, bool force = false);
|
||||||
virtual void commandAlarmState(unsigned char newValue, bool force = false);
|
virtual void setAlarmState(unsigned char newValue, bool force = false);
|
||||||
virtual void setReactionToThreat(unsigned char newValue, bool force = false);
|
virtual void setReactionToThreat(unsigned char newValue, bool force = false);
|
||||||
virtual void setEmissionsCountermeasures(unsigned char newValue, bool force = false);
|
virtual void setEmissionsCountermeasures(unsigned char newValue, bool force = false);
|
||||||
virtual void setTACAN(DataTypes::TACAN newValue, bool force = false);
|
virtual void setTACAN(DataTypes::TACAN newValue, bool force = false);
|
||||||
@@ -126,12 +126,12 @@ public:
|
|||||||
virtual void setTargetingRange(double newValue) { updateValue(targetingRange, newValue, DataIndex::targetingRange); }
|
virtual void setTargetingRange(double newValue) { updateValue(targetingRange, newValue, DataIndex::targetingRange); }
|
||||||
virtual void setAimMethodRange(double newValue) { updateValue(aimMethodRange, newValue, DataIndex::aimMethodRange); }
|
virtual void setAimMethodRange(double newValue) { updateValue(aimMethodRange, newValue, DataIndex::aimMethodRange); }
|
||||||
virtual void setAcquisitionRange(double newValue) { updateValue(acquisitionRange, newValue, DataIndex::acquisitionRange); }
|
virtual void setAcquisitionRange(double newValue) { updateValue(acquisitionRange, newValue, DataIndex::acquisitionRange); }
|
||||||
virtual void setAlarmState(string newValue) { updateValue(alarmState, newValue, DataIndex::alarmState); }
|
virtual void setRadarState(bool newValue) { updateValue(radarState, newValue, DataIndex::radarState); }
|
||||||
|
|
||||||
/********** Getters **********/
|
/********** Getters **********/
|
||||||
virtual string getCategory() { return category; };
|
virtual string getCategory() { return category; };
|
||||||
virtual bool getAlive() { return alive; }
|
virtual bool getAlive() { return alive; }
|
||||||
virtual string getAlarmState() { return alarmState; }
|
virtual unsigned char getAlarmState() { return alarmState; }
|
||||||
virtual bool getHuman() { return human; }
|
virtual bool getHuman() { return human; }
|
||||||
virtual bool getControlled() { return controlled; }
|
virtual bool getControlled() { return controlled; }
|
||||||
virtual unsigned char getCoalition() { return coalition; }
|
virtual unsigned char getCoalition() { return coalition; }
|
||||||
@@ -190,6 +190,7 @@ public:
|
|||||||
virtual double getTargetingRange() { return targetingRange; }
|
virtual double getTargetingRange() { return targetingRange; }
|
||||||
virtual double getAimMethodRange() { return aimMethodRange; }
|
virtual double getAimMethodRange() { return aimMethodRange; }
|
||||||
virtual double getAcquisitionRange() { return acquisitionRange; }
|
virtual double getAcquisitionRange() { return acquisitionRange; }
|
||||||
|
virtual bool getRadarState() { return radarState; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned int ID;
|
unsigned int ID;
|
||||||
@@ -205,7 +206,8 @@ protected:
|
|||||||
string callsign = "";
|
string callsign = "";
|
||||||
string groupName = "";
|
string groupName = "";
|
||||||
unsigned char state = State::NONE;
|
unsigned char state = State::NONE;
|
||||||
string alarmState = "";
|
unsigned char alarmState = ALARM_STATE::AUTO;
|
||||||
|
bool radarState = false;
|
||||||
string task = "";
|
string task = "";
|
||||||
bool hasTask = false;
|
bool hasTask = false;
|
||||||
Coords position = Coords(NULL);
|
Coords position = Coords(NULL);
|
||||||
|
|||||||
@@ -609,7 +609,7 @@ string GroundUnit::aimAtPoint(Coords aimTarget) {
|
|||||||
Geodesic::WGS84().Direct(position.lat, position.lng, bearing1, r, lat, lng);
|
Geodesic::WGS84().Direct(position.lat, position.lng, bearing1, r, lat, lng);
|
||||||
|
|
||||||
taskString = +"Barrel elevation: " + to_string((int) round(barrelElevation)) + "m, bearing: " + to_string((int) round(bearing1)) + "deg";
|
taskString = +"Barrel elevation: " + to_string((int) round(barrelElevation)) + "m, bearing: " + to_string((int) round(bearing1)) + "deg";
|
||||||
log(unitName + "(" + name + ")" + " shooting with aim at point method. Barrel elevation: " + to_string(barrelElevation) + "m, bearing: " + to_string(bearing1) + "°");
|
log(unitName + "(" + name + ")" + " shooting with aim at point method. Barrel elevation: " + to_string(barrelElevation) + "m, bearing: " + to_string(bearing1) + "<EFBFBD>");
|
||||||
|
|
||||||
std::ostringstream taskSS;
|
std::ostringstream taskSS;
|
||||||
taskSS.precision(10);
|
taskSS.precision(10);
|
||||||
|
|||||||
@@ -406,17 +406,17 @@ void Scheduler::handleRequest(string key, json::value value, string username, js
|
|||||||
log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") ROE to " + to_string(ROE), true);
|
log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") ROE to " + to_string(ROE), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (key.compare("commandAlarmState") == 0)
|
else if (key.compare("setAlarmState") == 0)
|
||||||
{
|
{
|
||||||
unsigned int ID = value[L"ID"].as_integer();
|
unsigned int ID = value[L"ID"].as_integer();
|
||||||
unitsManager->acquireControl(ID);
|
unitsManager->acquireControl(ID);
|
||||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||||
if (unit != nullptr) {
|
if (unit != nullptr) {
|
||||||
unsigned char alarmState = value[L"alarmState"].as_integer();
|
unsigned char alarmState = value[L"alarmState"].as_integer();
|
||||||
unit->commandAlarmState(alarmState);
|
unit->setAlarmState(alarmState);
|
||||||
log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") alarm state to " + to_string(alarmState), true);
|
log(username + " set unit " + unit->getUnitName() + "(" + unit->getName() + ") alarm state to " + to_string(alarmState), true);
|
||||||
} else {
|
} else {
|
||||||
log("Error while setting commandAlarmState. Unit does not exist.");
|
log("Error while setting setAlarmState. Unit does not exist.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/************************/
|
/************************/
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ extern UnitsManager* unitsManager;
|
|||||||
Unit::Unit(json::value json, unsigned int ID) :
|
Unit::Unit(json::value json, unsigned int ID) :
|
||||||
ID(ID)
|
ID(ID)
|
||||||
{
|
{
|
||||||
log("Creating unit with ID: " + to_string(ID));
|
// log("Creating unit with ID: " + to_string(ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit::~Unit()
|
Unit::~Unit()
|
||||||
@@ -83,8 +83,8 @@ void Unit::update(json::value json, double dt)
|
|||||||
if (json.has_boolean_field(L"isAlive"))
|
if (json.has_boolean_field(L"isAlive"))
|
||||||
setAlive(json[L"isAlive"].as_bool());
|
setAlive(json[L"isAlive"].as_bool());
|
||||||
|
|
||||||
if (json.has_string_field(L"alarmState")) {
|
if (json.has_boolean_field(L"radarState")) {
|
||||||
setAlarmState(to_string(json[L"alarmState"]));
|
setRadarState(json[L"radarState"].as_bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.has_boolean_field(L"isHuman"))
|
if (json.has_boolean_field(L"isHuman"))
|
||||||
@@ -154,7 +154,7 @@ void Unit::update(json::value json, double dt)
|
|||||||
|
|
||||||
void Unit::setDefaults(bool force)
|
void Unit::setDefaults(bool force)
|
||||||
{
|
{
|
||||||
|
setAlarmState(ALARM_STATE::AUTO, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::runAILoop() {
|
void Unit::runAILoop() {
|
||||||
@@ -256,7 +256,8 @@ void Unit::getData(stringstream& ss, unsigned long long time)
|
|||||||
switch (datumIndex) {
|
switch (datumIndex) {
|
||||||
case DataIndex::category: appendString(ss, datumIndex, category); break;
|
case DataIndex::category: appendString(ss, datumIndex, category); break;
|
||||||
case DataIndex::alive: appendNumeric(ss, datumIndex, alive); break;
|
case DataIndex::alive: appendNumeric(ss, datumIndex, alive); break;
|
||||||
case DataIndex::alarmState: appendString(ss, datumIndex, alarmState); break;
|
case DataIndex::alarmState: appendNumeric(ss, datumIndex, alarmState); break;
|
||||||
|
case DataIndex::radarState: appendNumeric(ss, datumIndex, radarState); break;
|
||||||
case DataIndex::human: appendNumeric(ss, datumIndex, human); break;
|
case DataIndex::human: appendNumeric(ss, datumIndex, human); break;
|
||||||
case DataIndex::controlled: appendNumeric(ss, datumIndex, controlled); break;
|
case DataIndex::controlled: appendNumeric(ss, datumIndex, controlled); break;
|
||||||
case DataIndex::coalition: appendNumeric(ss, datumIndex, coalition); break;
|
case DataIndex::coalition: appendNumeric(ss, datumIndex, coalition); break;
|
||||||
@@ -473,7 +474,7 @@ void Unit::setROE(unsigned char newROE, bool force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::commandAlarmState(unsigned char newAlarmState, bool force)
|
void Unit::setAlarmState(unsigned char newAlarmState, bool force)
|
||||||
{
|
{
|
||||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ALARM_STATE, static_cast<unsigned int>(newAlarmState)));
|
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ALARM_STATE, static_cast<unsigned int>(newAlarmState)));
|
||||||
scheduler->appendCommand(command);
|
scheduler->appendCommand(command);
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ export const states: string[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const ROEs: string[] = ["free", "designated", "", "return", "hold"];
|
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 reactionsToThreat: string[] = ["none", "manoeuvre", "passive", "evade"];
|
||||||
export const emissionsCountermeasures: string[] = ["silent", "attack", "defend", "free"];
|
export const emissionsCountermeasures: string[] = ["silent", "attack", "defend", "free"];
|
||||||
|
|
||||||
@@ -453,6 +452,7 @@ export enum DataIndexes {
|
|||||||
category,
|
category,
|
||||||
alive,
|
alive,
|
||||||
alarmState,
|
alarmState,
|
||||||
|
radarState,
|
||||||
human,
|
human,
|
||||||
controlled,
|
controlled,
|
||||||
coalition,
|
coalition,
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ export interface UnitData {
|
|||||||
markerCategory: string;
|
markerCategory: string;
|
||||||
ID: number;
|
ID: number;
|
||||||
alive: boolean;
|
alive: boolean;
|
||||||
alarmState: AlarmState | undefined;
|
alarmState: AlarmState;
|
||||||
human: boolean;
|
human: boolean;
|
||||||
controlled: boolean;
|
controlled: boolean;
|
||||||
coalition: string;
|
coalition: string;
|
||||||
@@ -417,7 +417,7 @@ export interface Drawing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum AlarmState {
|
export enum AlarmState {
|
||||||
AUTO = 'auto',
|
RED = 'red',
|
||||||
GREEN = 'green',
|
GREEN = 'green',
|
||||||
RED = 'red'
|
AUTO = 'auto'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -660,7 +660,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Unit Radar State */
|
/* Unit Radar State */
|
||||||
.unit-radar-state {
|
.unit-alarm-state {
|
||||||
height: 10px;
|
height: 10px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -670,12 +670,12 @@
|
|||||||
left: 35px;
|
left: 35px;
|
||||||
bottom: 8px;
|
bottom: 8px;
|
||||||
}
|
}
|
||||||
.unit[data-radar-state="green"] .unit-radar-state {
|
.unit[data-alarm-state="green"] .unit-alarm-state {
|
||||||
border: 1px solid white;
|
border: 1px solid white;
|
||||||
background: rgb(0, 226, 0);
|
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;
|
border: 1px solid white;
|
||||||
background: red;
|
background: red;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Circle, LatLng, Polygon } from "leaflet";
|
import { Circle, LatLng, Polygon } from "leaflet";
|
||||||
import * as turf from "@turf/turf";
|
import * as turf from "@turf/turf";
|
||||||
import { ROEs, emissionsCountermeasures, reactionsToThreat, states } from "../constants/constants";
|
import { ROEs, emissionsCountermeasures, reactionsToThreat, states } from "../constants/constants";
|
||||||
import { DateAndTime } from "../interfaces";
|
import { AlarmState, DateAndTime } from "../interfaces";
|
||||||
import { Converter } from "usng";
|
import { Converter } from "usng";
|
||||||
import { MGRS } from "../types/types";
|
import { MGRS } from "../types/types";
|
||||||
import { featureCollection } from "turf";
|
import { featureCollection } from "turf";
|
||||||
@@ -275,6 +275,19 @@ export function enumToROE(ROE: number) {
|
|||||||
else return ROEs[0];
|
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) {
|
export function convertROE(idx: number) {
|
||||||
let roe = 0;
|
let roe = 0;
|
||||||
if (idx === 0) roe = 4;
|
if (idx === 0) roe = 4;
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ export class ServerManager {
|
|||||||
|
|
||||||
setAlarmState(ID: number, alarmState: number, callback: CallableFunction = () => {}) {
|
setAlarmState(ID: number, alarmState: number, callback: CallableFunction = () => {}) {
|
||||||
var command = { ID: ID, alarmState: alarmState };
|
var command = { ID: ID, alarmState: alarmState };
|
||||||
var data = { commandAlarmState: command };
|
var data = { setAlarmState: command };
|
||||||
this.PUT(data, callback);
|
this.PUT(data, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
const [activeRadioSettings, setActiveRadioSettings] = useState(null as null | { radio: Radio; TACAN: TACAN });
|
const [activeRadioSettings, setActiveRadioSettings] = useState(null as null | { radio: Radio; TACAN: TACAN });
|
||||||
const [activeAdvancedSettings, setActiveAdvancedSettings] = useState(null as null | GeneralSettings);
|
const [activeAdvancedSettings, setActiveAdvancedSettings] = useState(null as null | GeneralSettings);
|
||||||
const [lastUpdateTime, setLastUpdateTime] = useState(0);
|
const [lastUpdateTime, setLastUpdateTime] = useState(0);
|
||||||
const [showScenicModes, setShowScenicModes] = useState(true);
|
const [showScenicModes, setShowScenicModes] = useState(false);
|
||||||
const [showEngagementSettings, setShowEngagementSettings] = useState(false);
|
const [showEngagementSettings, setShowEngagementSettings] = useState(false);
|
||||||
const [barrelHeight, setBarrelHeight] = useState(0);
|
const [barrelHeight, setBarrelHeight] = useState(0);
|
||||||
const [muzzleVelocity, setMuzzleVelocity] = 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">
|
<td className="flex gap-2 text-lg text-gray-200">
|
||||||
<FontAwesomeIcon icon={entry[1][0] as IconDefinition} />{" "}
|
<FontAwesomeIcon icon={entry[1][0] as IconDefinition} />{" "}
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`text-sm text-gray-400`}
|
||||||
text-sm text-gray-400
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
{entry[1][1] as string}
|
{entry[1][1] as string}
|
||||||
</div>
|
</div>
|
||||||
@@ -802,9 +800,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsRoeHold}
|
icon={olButtonsRoeHold}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Hold fire: The unit will not shoot in any circumstance
|
Hold fire: The unit will not shoot in any circumstance
|
||||||
</div>
|
</div>
|
||||||
@@ -812,9 +808,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsRoeReturn}
|
icon={olButtonsRoeReturn}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Return fire: The unit will not fire unless fired upon
|
Return fire: The unit will not fire unless fired upon
|
||||||
</div>
|
</div>
|
||||||
@@ -822,17 +816,13 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsRoeDesignated}
|
icon={olButtonsRoeDesignated}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
<div>
|
<div>
|
||||||
{" "}
|
{" "}
|
||||||
Fire on target: The unit will not fire unless fired upon{" "}
|
Fire on target: The unit will not fire unless fired upon{" "}
|
||||||
<p
|
<p
|
||||||
className={`
|
className={`inline font-bold`}
|
||||||
inline font-bold
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
or
|
or
|
||||||
</p>{" "}
|
</p>{" "}
|
||||||
@@ -843,9 +833,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsRoeFree}
|
icon={olButtonsRoeFree}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Free: The unit will fire at any detected enemy in range
|
Free: The unit will fire at any detected enemy in range
|
||||||
</div>
|
</div>
|
||||||
@@ -853,25 +841,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
<div className="flex gap-4">
|
<div className="flex gap-4">
|
||||||
<div className="my-auto">
|
<div className="my-auto">
|
||||||
<FaExclamationCircle
|
<FaExclamationCircle
|
||||||
className={`
|
className={`animate-bounce text-xl`}
|
||||||
animate-bounce text-xl
|
|
||||||
`}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Currently, DCS blue and red ground units do not respect{" "}
|
Currently, DCS blue and red ground units do not respect{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsRoeReturn}
|
icon={olButtonsRoeReturn}
|
||||||
className={`
|
className={`my-auto text-white`}
|
||||||
my-auto text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
and{" "}
|
and{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsRoeDesignated}
|
icon={olButtonsRoeDesignated}
|
||||||
className={`
|
className={`my-auto text-white`}
|
||||||
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
|
rules of engagement, so be careful, they may start shooting when you don't want them to. Use neutral units for finer
|
||||||
control.
|
control.
|
||||||
@@ -957,6 +939,18 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
tooltipRelativeToParent={true}
|
tooltipRelativeToParent={true}
|
||||||
>
|
>
|
||||||
{[olButtonsRoeHold, olButtonsRoeReturn, olButtonsRoeDesignated].map((icon, idx) => {
|
{[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 (
|
return (
|
||||||
<OlButtonGroupItem
|
<OlButtonGroupItem
|
||||||
key={idx}
|
key={idx}
|
||||||
@@ -966,11 +960,11 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
.setAlarmState(idx, null, () =>
|
.setAlarmState(idx, null, () =>
|
||||||
setForcedUnitsData({
|
setForcedUnitsData({
|
||||||
...forcedUnitsData,
|
...forcedUnitsData,
|
||||||
alarmState: Object.values(AlarmState)[idx],
|
alarmState: getAlarmStateByIdx(idx),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
active={selectedUnitsData.alarmState === alarmStates[idx]}
|
active={selectedUnitsData.alarmState === getAlarmStateByIdx(idx)}
|
||||||
icon={icon}
|
icon={icon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -1007,9 +1001,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsThreatNone}
|
icon={olButtonsThreatNone}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
No reaction: The unit will not react in any circumstance
|
No reaction: The unit will not react in any circumstance
|
||||||
</div>
|
</div>
|
||||||
@@ -1017,9 +1009,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsThreatPassive}
|
icon={olButtonsThreatPassive}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Passive: The unit will use counter-measures, but will not alter its course
|
Passive: The unit will use counter-measures, but will not alter its course
|
||||||
</div>
|
</div>
|
||||||
@@ -1027,9 +1017,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsThreatManoeuvre}
|
icon={olButtonsThreatManoeuvre}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Manouevre: The unit will try to evade the threat using manoeuvres, but no counter-measures
|
Manouevre: The unit will try to evade the threat using manoeuvres, but no counter-measures
|
||||||
</div>
|
</div>
|
||||||
@@ -1037,9 +1025,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsThreatEvade}
|
icon={olButtonsThreatEvade}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Full evasion: the unit will try to evade the threat both manoeuvering and using counter-measures
|
Full evasion: the unit will try to evade the threat both manoeuvering and using counter-measures
|
||||||
</div>
|
</div>
|
||||||
@@ -1094,9 +1080,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsEmissionsSilent}
|
icon={olButtonsEmissionsSilent}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Radio silence: No radar or ECM will be used
|
Radio silence: No radar or ECM will be used
|
||||||
</div>
|
</div>
|
||||||
@@ -1104,9 +1088,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsEmissionsDefend}
|
icon={olButtonsEmissionsDefend}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Defensive: The unit will turn radar and ECM on only when threatened
|
Defensive: The unit will turn radar and ECM on only when threatened
|
||||||
</div>
|
</div>
|
||||||
@@ -1114,9 +1096,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsEmissionsAttack}
|
icon={olButtonsEmissionsAttack}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Attack: The unit will use radar and ECM when engaging other units
|
Attack: The unit will use radar and ECM when engaging other units
|
||||||
</div>
|
</div>
|
||||||
@@ -1124,9 +1104,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{" "}
|
{" "}
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={olButtonsEmissionsFree}
|
icon={olButtonsEmissionsFree}
|
||||||
className={`
|
className={`my-auto min-w-8 text-white`}
|
||||||
my-auto min-w-8 text-white
|
|
||||||
`}
|
|
||||||
/>{" "}
|
/>{" "}
|
||||||
Free: the unit will use the radar and ECM all the time
|
Free: the unit will use the radar and ECM all the time
|
||||||
</div>
|
</div>
|
||||||
@@ -1347,9 +1325,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
<div className="flex gap-4">
|
<div className="flex gap-4">
|
||||||
<div className="my-auto">
|
<div className="my-auto">
|
||||||
<FaExclamationCircle
|
<FaExclamationCircle
|
||||||
className={`
|
className={`animate-bounce text-xl`}
|
||||||
animate-bounce text-xl
|
|
||||||
`}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -1529,9 +1505,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
{/* ============== Operate as toggle START ============== */}
|
{/* ============== Operate as toggle START ============== */}
|
||||||
{selectedUnits.every((unit) => unit.getCoalition() === "neutral") && (
|
{selectedUnits.every((unit) => unit.getCoalition() === "neutral") && (
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`flex content-center justify-between`}
|
||||||
flex content-center justify-between
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`
|
className={`
|
||||||
@@ -1573,17 +1547,13 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
>
|
>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Barrel height:{" "}
|
Barrel height:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
decimalPlaces={1}
|
decimalPlaces={1}
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={barrelHeight}
|
value={barrelHeight}
|
||||||
min={0}
|
min={0}
|
||||||
max={100}
|
max={100}
|
||||||
@@ -1598,26 +1568,20 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
m
|
m
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Muzzle velocity:{" "}
|
Muzzle velocity:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
decimalPlaces={0}
|
decimalPlaces={0}
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={muzzleVelocity}
|
value={muzzleVelocity}
|
||||||
min={0}
|
min={0}
|
||||||
max={10000}
|
max={10000}
|
||||||
@@ -1632,26 +1596,20 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
m/s
|
m/s
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Aim time:{" "}
|
Aim time:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
decimalPlaces={2}
|
decimalPlaces={2}
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={aimTime}
|
value={aimTime}
|
||||||
min={0}
|
min={0}
|
||||||
max={100}
|
max={100}
|
||||||
@@ -1666,25 +1624,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
s
|
s
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Shots to fire:{" "}
|
Shots to fire:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={shotsToFire}
|
value={shotsToFire}
|
||||||
min={0}
|
min={0}
|
||||||
max={100}
|
max={100}
|
||||||
@@ -1701,17 +1653,13 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Shots base interval:{" "}
|
Shots base interval:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
decimalPlaces={2}
|
decimalPlaces={2}
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={shotsBaseInterval}
|
value={shotsBaseInterval}
|
||||||
min={0}
|
min={0}
|
||||||
max={100}
|
max={100}
|
||||||
@@ -1726,26 +1674,20 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
s
|
s
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Shots base scatter:{" "}
|
Shots base scatter:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
decimalPlaces={2}
|
decimalPlaces={2}
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={shotsBaseScatter}
|
value={shotsBaseScatter}
|
||||||
min={0}
|
min={0}
|
||||||
max={50}
|
max={50}
|
||||||
@@ -1760,25 +1702,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
deg
|
deg
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Engagement range:{" "}
|
Engagement range:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={engagementRange}
|
value={engagementRange}
|
||||||
min={0}
|
min={0}
|
||||||
max={100000}
|
max={100000}
|
||||||
@@ -1793,25 +1729,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
m
|
m
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Targeting range:{" "}
|
Targeting range:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={targetingRange}
|
value={targetingRange}
|
||||||
min={0}
|
min={0}
|
||||||
max={100000}
|
max={100000}
|
||||||
@@ -1826,25 +1756,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
m
|
m
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Aim method range:{" "}
|
Aim method range:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={aimMethodRange}
|
value={aimMethodRange}
|
||||||
min={0}
|
min={0}
|
||||||
max={100000}
|
max={100000}
|
||||||
@@ -1859,25 +1783,19 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
m
|
m
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex align-center gap-2">
|
<div className="flex align-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
Acquisition range:{" "}
|
Acquisition range:{" "}
|
||||||
</div>
|
</div>
|
||||||
<OlNumberInput
|
<OlNumberInput
|
||||||
className={`
|
className={`ml-auto`}
|
||||||
ml-auto
|
|
||||||
`}
|
|
||||||
value={acquisitionRange}
|
value={acquisitionRange}
|
||||||
min={0}
|
min={0}
|
||||||
max={100000}
|
max={100000}
|
||||||
@@ -1892,9 +1810,7 @@ export function UnitControlMenu(props: { open: boolean; onClose: () => void }) {
|
|||||||
}}
|
}}
|
||||||
></OlNumberInput>
|
></OlNumberInput>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`my-auto`}
|
||||||
my-auto
|
|
||||||
`}
|
|
||||||
>
|
>
|
||||||
m
|
m
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
computeBearingRangeString,
|
computeBearingRangeString,
|
||||||
adjustBrightness,
|
adjustBrightness,
|
||||||
bearingAndDistanceToLatLng,
|
bearingAndDistanceToLatLng,
|
||||||
|
enumToAlarmState,
|
||||||
} from "../other/utils";
|
} from "../other/utils";
|
||||||
import { CustomMarker } from "../map/markers/custommarker";
|
import { CustomMarker } from "../map/markers/custommarker";
|
||||||
import { SVGInjector } from "@tanem/svg-injector";
|
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 */
|
/* Data controlled directly by the backend. No setters are provided to avoid misalignments */
|
||||||
#alive: boolean = false;
|
#alive: boolean = false;
|
||||||
#alarmState: AlarmState | undefined = undefined;
|
#alarmState: AlarmState = AlarmState.AUTO;
|
||||||
|
#radarState: boolean | undefined = undefined;
|
||||||
#human: boolean = false;
|
#human: boolean = false;
|
||||||
#controlled: boolean = false;
|
#controlled: boolean = false;
|
||||||
#coalition: string = "neutral";
|
#coalition: string = "neutral";
|
||||||
@@ -352,6 +354,9 @@ export abstract class Unit extends CustomMarker {
|
|||||||
getAlarmState() {
|
getAlarmState() {
|
||||||
return this.#alarmState;
|
return this.#alarmState;
|
||||||
}
|
}
|
||||||
|
getRadarState() {
|
||||||
|
return this.#radarState;
|
||||||
|
}
|
||||||
getTimeToNextTasking() {
|
getTimeToNextTasking() {
|
||||||
return this.#timeToNextTasking;
|
return this.#timeToNextTasking;
|
||||||
}
|
}
|
||||||
@@ -541,6 +546,7 @@ export abstract class Unit extends CustomMarker {
|
|||||||
var datumIndex = 0;
|
var datumIndex = 0;
|
||||||
while (datumIndex != DataIndexes.endOfData) {
|
while (datumIndex != DataIndexes.endOfData) {
|
||||||
datumIndex = dataExtractor.extractUInt8();
|
datumIndex = dataExtractor.extractUInt8();
|
||||||
|
|
||||||
switch (datumIndex) {
|
switch (datumIndex) {
|
||||||
case DataIndexes.category:
|
case DataIndexes.category:
|
||||||
dataExtractor.extractString();
|
dataExtractor.extractString();
|
||||||
@@ -549,20 +555,8 @@ export abstract class Unit extends CustomMarker {
|
|||||||
this.setAlive(dataExtractor.extractBool());
|
this.setAlive(dataExtractor.extractBool());
|
||||||
updateMarker = true;
|
updateMarker = true;
|
||||||
break;
|
break;
|
||||||
case DataIndexes.alarmState:
|
case DataIndexes.radarState:
|
||||||
let stringAlarmState = dataExtractor.extractString();
|
this.#radarState = dataExtractor.extractBool();
|
||||||
switch (stringAlarmState) {
|
|
||||||
case 'RED':
|
|
||||||
this.setAlarmState(AlarmState.RED);
|
|
||||||
break;
|
|
||||||
case 'GREEN':
|
|
||||||
this.setAlarmState(AlarmState.GREEN);
|
|
||||||
break;
|
|
||||||
case '':
|
|
||||||
this.setAlarmState(AlarmState.AUTO);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
updateMarker = true;
|
updateMarker = true;
|
||||||
break;
|
break;
|
||||||
case DataIndexes.human:
|
case DataIndexes.human:
|
||||||
@@ -670,6 +664,9 @@ export abstract class Unit extends CustomMarker {
|
|||||||
case DataIndexes.ROE:
|
case DataIndexes.ROE:
|
||||||
this.#ROE = enumToROE(dataExtractor.extractUInt8());
|
this.#ROE = enumToROE(dataExtractor.extractUInt8());
|
||||||
break;
|
break;
|
||||||
|
case DataIndexes.alarmState:
|
||||||
|
this.#alarmState = enumToAlarmState(dataExtractor.extractUInt8());
|
||||||
|
break;
|
||||||
case DataIndexes.reactionToThreat:
|
case DataIndexes.reactionToThreat:
|
||||||
this.#reactionToThreat = enumToReactionToThreat(dataExtractor.extractUInt8());
|
this.#reactionToThreat = enumToReactionToThreat(dataExtractor.extractUInt8());
|
||||||
break;
|
break;
|
||||||
@@ -890,10 +887,9 @@ export abstract class Unit extends CustomMarker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setAlarmState(newAlarmState: AlarmState) {
|
setRadarState(newRadarState: boolean) {
|
||||||
if (newAlarmState != this.#alarmState) {
|
if (newRadarState != this.#radarState) {
|
||||||
this.#alarmState = newAlarmState;
|
this.#radarState = newRadarState;
|
||||||
console.log('---- alarm state updated: ', this.#alarmState);
|
|
||||||
this.#updateMarker();
|
this.#updateMarker();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1436,7 +1432,7 @@ export abstract class Unit extends CustomMarker {
|
|||||||
if (!this.#human) getApp().getServerManager().setROE(this.ID, ROE);
|
if (!this.#human) getApp().getServerManager().setROE(this.ID, ROE);
|
||||||
}
|
}
|
||||||
|
|
||||||
commandAlarmState(alarmState: number) {
|
setAlarmState(alarmState: number) {
|
||||||
if (!this.#human) getApp().getServerManager().setAlarmState(this.ID, alarmState);
|
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
|
if (this.getHidden()) return; // We won't draw the marker if the unit is hidden
|
||||||
|
|
||||||
/* Draw the marker */
|
/* Draw the marker */
|
||||||
if (this.getLatLng().lat !== this.#position.lat || this.getLatLng().lng !== 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));
|
this.setLatLng(new LatLng(this.#position.lat, this.#position.lng));
|
||||||
@@ -1777,8 +1773,9 @@ export abstract class Unit extends CustomMarker {
|
|||||||
/* Set dead/alive flag */
|
/* Set dead/alive flag */
|
||||||
element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.#alive);
|
element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.#alive);
|
||||||
|
|
||||||
/* Set RED/GREEN state*/
|
/* Set radar state*/
|
||||||
if (this.#alarmState) element.querySelector(".unit")?.setAttribute("data-radar-state", this.#alarmState);
|
// 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 */
|
/* Set current unit state */
|
||||||
if (this.#human) {
|
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 (hasFox3 != newHasFox3) element.querySelector(".unit")?.toggleAttribute("data-has-fox-3", newHasFox3);
|
||||||
if (hasOtherAmmo != newHasOtherAmmo) element.querySelector(".unit")?.toggleAttribute("data-has-other-ammo", newHasOtherAmmo);
|
if (hasOtherAmmo != newHasOtherAmmo) element.querySelector(".unit")?.toggleAttribute("data-has-other-ammo", newHasOtherAmmo);
|
||||||
|
|
||||||
/* Draw the hotgroup element */
|
/* Draw the hotgroup element */
|
||||||
element.querySelector(".unit")?.toggleAttribute("data-is-in-hotgroup", this.#hotgroup != null);
|
element.querySelector(".unit")?.toggleAttribute("data-is-in-hotgroup", this.#hotgroup != null);
|
||||||
if (this.#hotgroup) {
|
if (this.#hotgroup) {
|
||||||
const hotgroupEl = element.querySelector(".unit-hotgroup-id") as HTMLElement;
|
const hotgroupEl = element.querySelector(".unit-hotgroup-id") as HTMLElement;
|
||||||
if (hotgroupEl) hotgroupEl.innerText = String(this.#hotgroup);
|
if (hotgroupEl) hotgroupEl.innerText = String(this.#hotgroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the cluster element */
|
/* Draw the cluster element */
|
||||||
element
|
element
|
||||||
.querySelector(".unit")
|
.querySelector(".unit")
|
||||||
?.toggleAttribute(
|
?.toggleAttribute(
|
||||||
"data-is-cluster-leader",
|
"data-is-cluster-leader",
|
||||||
this.#isClusterLeader &&
|
this.#isClusterLeader &&
|
||||||
this.#clusterUnits.length > 1 &&
|
this.#clusterUnits.length > 1 &&
|
||||||
getApp().getMap().getOptions().clusterGroundUnits &&
|
getApp().getMap().getOptions().clusterGroundUnits &&
|
||||||
getApp().getMap().getZoom() < CLUSTERING_ZOOM_TRANSITION &&
|
getApp().getMap().getZoom() < CLUSTERING_ZOOM_TRANSITION &&
|
||||||
!this.getSelected()
|
!this.getSelected()
|
||||||
);
|
);
|
||||||
if (this.#isClusterLeader && this.#clusterUnits.length > 1) {
|
if (this.#isClusterLeader && this.#clusterUnits.length > 1) {
|
||||||
const clusterEl = element.querySelector(".unit-cluster-id") as HTMLElement;
|
const clusterEl = element.querySelector(".unit-cluster-id") as HTMLElement;
|
||||||
if (clusterEl) clusterEl.innerText = String(this.#clusterUnits.length);
|
if (clusterEl) clusterEl.innerText = String(this.#clusterUnits.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set bullseyes positions */
|
/* Set bullseyes positions */
|
||||||
const bullseyes = getApp().getMissionManager().getBullseyes();
|
const bullseyes = getApp().getMissionManager().getBullseyes();
|
||||||
|
|||||||
@@ -1,36 +1,14 @@
|
|||||||
import { DomEvent, DomUtil, LatLng, LatLngBounds } from "leaflet";
|
import * as turf from "@turf/turf";
|
||||||
import { getApp } from "../olympusapp";
|
import { LatLng, LatLngBounds } from "leaflet";
|
||||||
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 {
|
import {
|
||||||
BLUE_COMMANDER,
|
BLUE_COMMANDER,
|
||||||
DELETE_CYCLE_TIME,
|
|
||||||
DELETE_SLOW_THRESHOLD,
|
|
||||||
DataIndexes,
|
DataIndexes,
|
||||||
GAME_MASTER,
|
GAME_MASTER,
|
||||||
IADSDensities,
|
IADSDensities,
|
||||||
OlympusState,
|
OlympusState,
|
||||||
RED_COMMANDER,
|
RED_COMMANDER,
|
||||||
UnitControlSubState, alarmStates,
|
UnitControlSubState
|
||||||
} from "../constants/constants";
|
} 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 {
|
import {
|
||||||
AWACSReferenceChangedEvent,
|
AWACSReferenceChangedEvent,
|
||||||
CommandModeOptionsChangedEvent,
|
CommandModeOptionsChangedEvent,
|
||||||
@@ -46,11 +24,30 @@ import {
|
|||||||
UnitsRefreshedEvent,
|
UnitsRefreshedEvent,
|
||||||
UnitsUpdatedEvent,
|
UnitsUpdatedEvent,
|
||||||
} from "../events";
|
} from "../events";
|
||||||
import { UnitDatabase } from "./databases/unitdatabase";
|
import { Contact, GeneralSettings, Radio, TACAN, UnitBlueprint, UnitData, UnitSpawnTable } from "../interfaces";
|
||||||
import * as turf from "@turf/turf";
|
import { CoalitionCircle } from "../map/coalitionarea/coalitioncircle";
|
||||||
|
import { CoalitionPolygon } from "../map/coalitionarea/coalitionpolygon";
|
||||||
import { PathMarker } from "../map/markers/pathmarker";
|
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 { 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
|
/** 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
|
* 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) => {
|
let callback = (units) => {
|
||||||
onExecution();
|
onExecution();
|
||||||
units.forEach((unit: Unit) => unit.commandAlarmState(alarmState));
|
units.forEach((unit: Unit) => unit.setAlarmState(alarmState));
|
||||||
this.#showActionMessage(units, `Alarm State set to ${alarmState.toString()}`);
|
this.#showActionMessage(units, `Alarm State set to ${alarmState.toString()}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1263,16 +1263,10 @@ function Olympus.setUnitsData(arg, time)
|
|||||||
table["isAlive"] = unit:isExist() and unit:isActive() and unit:getLife() >= 1
|
table["isAlive"] = unit:isExist() and unit:isActive() and unit:getLife() >= 1
|
||||||
|
|
||||||
if unit:isActive() and unit:hasSensors(Unit.SensorType.RADAR) then
|
if unit:isActive() and unit:hasSensors(Unit.SensorType.RADAR) then
|
||||||
-- Olympus.log:info("Unit Has Sensor Radar " .. tostring(unit:hasSensors(Unit.SensorType.RADAR)));
|
|
||||||
|
|
||||||
table["alarmState"] = "AUTO"
|
|
||||||
|
|
||||||
if unit:getRadar() then
|
if unit:getRadar() then
|
||||||
-- Olympus.log:info("alarmState: unit active and getRadar is true, setting RED.")
|
table["radarState"] = true
|
||||||
table["alarmState"] = "RED"
|
|
||||||
else
|
else
|
||||||
-- Olympus.log:info("alarmState: unit active and getRadar is false, setting GREEN.")
|
table["radarState"] = false
|
||||||
table["alarmState"] = "GREEN"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user