import React, { MutableRefObject, useEffect, useRef, useState } from "react"; import { Menu } from "./components/menu"; import { Unit } from "../../unit/unit"; import { OlLabelToggle } from "../components/ollabeltoggle"; import { OlRangeSlider } from "../components/olrangeslider"; import { getApp } from "../../olympusapp"; import { OlButtonGroup, OlButtonGroupItem } from "../components/olbuttongroup"; import { OlCheckbox } from "../components/olcheckbox"; import { ROEs, emissionsCountermeasures, reactionsToThreat } from "../../constants/constants"; import { OlToggle } from "../components/oltoggle"; import { OlCoalitionToggle } from "../components/olcoalitiontoggle"; import { olButtonsEmissionsAttack, olButtonsEmissionsDefend, olButtonsEmissionsFree, olButtonsEmissionsSilent, olButtonsIntensity1, olButtonsIntensity2, olButtonsIntensity3, olButtonsRoeDesignated, olButtonsRoeFree, olButtonsRoeHold, olButtonsRoeReturn, olButtonsScatter1, olButtonsScatter2, olButtonsScatter3, olButtonsThreatEvade, olButtonsThreatManoeuvre, olButtonsThreatNone, olButtonsThreatPassive, olButtonsVisibilityAircraft, olButtonsVisibilityDcs, olButtonsVisibilityGroundunit, olButtonsVisibilityGroundunitSam, olButtonsVisibilityHelicopter, olButtonsVisibilityHuman, olButtonsVisibilityNavyunit, olButtonsVisibilityOlympus, } from "../components/olicons"; import { Coalition } from "../../types/types"; import { ftToM, getUnitsByLabel, knotsToMs, mToFt, msToKnots } from "../../other/utils"; import { FaCog, FaGasPump, FaSignal, FaTag } from "react-icons/fa"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { OlSearchBar } from "../components/olsearchbar"; import { OlDropdown, OlDropdownItem } from "../components/oldropdown"; import { UnitBlueprint } from "../../interfaces"; import { FaRadio } from "react-icons/fa6"; import { OlNumberInput } from "../components/olnumberinput"; import { Radio, TACAN } from "../../interfaces"; import { OlStringInput } from "../components/olstringinput"; export function UnitControlMenu(props: { open: boolean; onClose: () => void }) { const [selectedUnits, setSelectedUnits] = useState([] as Unit[]); const [selectedUnitsData, setSelectedUnitsData] = useState({ desiredAltitude: undefined as undefined | number, desiredAltitudeType: undefined as undefined | string, desiredSpeed: undefined as undefined | number, desiredSpeedType: undefined as undefined | string, ROE: undefined as undefined | string, reactionToThreat: undefined as undefined | string, emissionsCountermeasures: undefined as undefined | string, shotsScatter: undefined as undefined | number, shotsIntensity: undefined as undefined | number, operateAs: undefined as undefined | string, followRoads: undefined as undefined | boolean, isActiveAWACS: undefined as undefined | boolean, isActiveTanker: undefined as undefined | boolean, onOff: undefined as undefined | boolean, }); const [selectionFilter, setSelectionFilter] = useState({ control: { human: true, dcs: true, olympus: true, }, blue: { aircraft: true, helicopter: true, "groundunit-sam": true, groundunit: true, navyunit: true, }, neutral: { aircraft: true, helicopter: true, "groundunit-sam": true, groundunit: true, navyunit: true, }, red: { aircraft: true, helicopter: true, "groundunit-sam": true, groundunit: true, navyunit: true, }, }); const [selectionBlueprint, setSelectionBlueprint] = useState(null as null | UnitBlueprint); const [searchBarRefState, setSearchBarRefState] = useState(null as MutableRefObject | null); const [filterString, setFilterString] = useState(""); const [showAdvancedSettings, setShowAdvancedSettings] = useState(false); const [activeAdvancedSettings, setActiveAdvancedSettings] = useState(null as null | { radio: Radio; TACAN: TACAN }); var searchBarRef = useRef(null); useEffect(() => { if (!searchBarRefState) setSearchBarRefState(searchBarRef); if (!props.open && selectionBlueprint !== null) setSelectionBlueprint(null); if (!props.open && filterString !== "") setFilterString(""); }); /* */ const minAltitude = 0; const maxAltitude = getApp() ?.getUnitsManager() ?.getSelectedUnitsCategories() .every((category) => { return category === "Helicopter"; }) ? 20000 : 60000; const altitudeStep = getApp() ?.getUnitsManager() ?.getSelectedUnitsCategories() .every((category) => { return category === "Helicopter"; }) ? 100 : 500; const minSpeed = 0; const maxSpeed = getApp() ?.getUnitsManager() ?.getSelectedUnitsCategories() .every((category) => { return category === "Helicopter"; }) ? 200 : 800; const speedStep = getApp() ?.getUnitsManager() ?.getSelectedUnitsCategories() .every((category) => { return category === "Helicopter"; }) ? 5 : 10; /* When a unit is selected, open the menu */ document.addEventListener("unitsSelection", (ev: CustomEventInit) => { setSelectedUnits(ev.detail as Unit[]); updateData(); }); /* When a unit is deselected, refresh the view */ document.addEventListener("unitDeselection", (ev: CustomEventInit) => { /* TODO add delay to avoid doing it too many times */ updateData(); }); /* When all units are deselected clean the view */ document.addEventListener("clearSelection", () => { setSelectedUnits([]); }); /* Update the current values of the shown data */ function updateData() { const getters = { desiredAltitude: (unit: Unit) => { return Math.round(mToFt(unit.getDesiredAltitude())); }, desiredAltitudeType: (unit: Unit) => { return unit.getDesiredAltitudeType(); }, desiredSpeed: (unit: Unit) => { return Math.round(msToKnots(unit.getDesiredSpeed())); }, desiredSpeedType: (unit: Unit) => { return unit.getDesiredSpeedType(); }, ROE: (unit: Unit) => { return unit.getROE(); }, reactionToThreat: (unit: Unit) => { return unit.getReactionToThreat(); }, emissionsCountermeasures: (unit: Unit) => { return unit.getEmissionsCountermeasures(); }, shotsScatter: (unit: Unit) => { return unit.getShotsScatter(); }, shotsIntensity: (unit: Unit) => { return unit.getShotsIntensity(); }, operateAs: (unit: Unit) => { return unit.getOperateAs(); }, followRoads: (unit: Unit) => { return unit.getFollowRoads(); }, isActiveAWACS: (unit: Unit) => { return unit.getIsActiveAWACS(); }, isActiveTanker: (unit: Unit) => { return unit.getIsActiveTanker(); }, onOff: (unit: Unit) => { return unit.getOnOff(); }, } as { [key in keyof typeof selectedUnitsData]: (unit: Unit) => void }; var updatedData = selectedUnitsData; Object.entries(getters).forEach(([key, getter]) => { updatedData[key] = getApp()?.getUnitsManager()?.getSelectedUnitsVariable(getter); }); setSelectedUnitsData(updatedData); } /* Count how many units are selected of each type, divided by coalition */ var unitOccurences = { blue: {}, red: {}, neutral: {}, }; selectedUnits.forEach((unit) => { if (!(unit.getName() in unitOccurences[unit.getCoalition()])) unitOccurences[unit.getCoalition()][unit.getName()] = 1; else unitOccurences[unit.getCoalition()][unit.getName()]++; }); const selectedCategories = getApp()?.getUnitsManager()?.getSelectedUnitsCategories() ?? []; const [filteredAircraft, filteredHelicopters, filteredAirDefense, filteredGroundUnits, filteredNavyUnits] = getUnitsByLabel(filterString); const mergedFilteredUnits = Object.assign({}, filteredAircraft, filteredHelicopters, filteredAirDefense, filteredGroundUnits, filteredNavyUnits) as { [key: string]: UnitBlueprint; }; return ( 0 ? `Units selected (x${selectedUnits.length})` : `No units selected`} onClose={props.onClose} canBeHidden={true} > <> {/* ============== Selection tool START ============== */} {selectedUnits.length == 0 && (
Selection tool
The selection tools allows you to select units depending on their category, coalition, and control mode. You can also select units depending on their specific type by using the search input.
Control mode
{Object.entries({ human: ["Human", olButtonsVisibilityHuman], olympus: ["Olympus controlled", olButtonsVisibilityOlympus], dcs: ["From DCS mission", olButtonsVisibilityDcs], }).map((entry) => { return (
{entry[1][0] as string} { selectionFilter["control"][entry[0]] = !selectionFilter["control"][entry[0]]; setSelectionFilter(JSON.parse(JSON.stringify(selectionFilter))); }} toggled={selectionFilter["control"][entry[0]]} />
); })}
Types and coalitions
{selectionBlueprint === null && Object.entries({ aircraft: olButtonsVisibilityAircraft, helicopter: olButtonsVisibilityHelicopter, "groundunit-sam": olButtonsVisibilityGroundunitSam, groundunit: olButtonsVisibilityGroundunit, navyunit: olButtonsVisibilityNavyunit, }).map((entry) => { return ( {["blue", "neutral", "red"].map((coalition) => { return ( ); })} ); })}
BLUE NEUTRAL RED
{ selectionFilter[coalition][entry[0]] = !selectionFilter[coalition][entry[0]]; setSelectionFilter(JSON.parse(JSON.stringify(selectionFilter))); }} />
value)} onChange={() => { const newValue = !Object.values(selectionFilter["blue"]).some((value) => value); Object.keys(selectionFilter["blue"]).forEach((key) => { selectionFilter["blue"][key] = newValue; }); setSelectionFilter(JSON.parse(JSON.stringify(selectionFilter))); }} /> value)} onChange={() => { const newValue = !Object.values(selectionFilter["neutral"]).some((value) => value); Object.keys(selectionFilter["neutral"]).forEach((key) => { selectionFilter["neutral"][key] = newValue; }); setSelectionFilter(JSON.parse(JSON.stringify(selectionFilter))); }} /> value)} onChange={() => { const newValue = !Object.values(selectionFilter["red"]).some((value) => value); Object.keys(selectionFilter["red"]).forEach((key) => { selectionFilter["red"][key] = newValue; }); setSelectionFilter(JSON.parse(JSON.stringify(selectionFilter))); }} />
{ setFilterString(value); selectionBlueprint && setSelectionBlueprint(null); }} text={selectionBlueprint ? selectionBlueprint.label : filterString} />
{filterString !== "" && Object.keys(mergedFilteredUnits).length > 0 && Object.entries(mergedFilteredUnits).map((entry) => { const blueprint = entry[1]; return ( { setSelectionBlueprint(blueprint); }} > {blueprint.label} ); })} {Object.keys(mergedFilteredUnits).length == 0 && No results}
)} {/* ============== Selection tool END ============== */} {/* */} {/* */} {/* */} {/* */} {/* */} {/* */} <> {/* ============== Unit control menu START ============== */} {selectedUnits.length > 0 && ( <> {/* ============== Units list START ============== */}
{ <> {["blue", "red", "neutral"].map((coalition) => { return Object.keys(unitOccurences[coalition]).map((name) => { return (
{name} x{unitOccurences[coalition][name]}
); }); })} }
{/* ============== Units list END ============== */} {/* ============== Unit basic options START ============== */} <> {!showAdvancedSettings && (
{/* ============== Altitude selector START ============== */} {selectedCategories.every((category) => { return ["Aircraft", "Helicopter"].includes(category); }) && (
Altitude {selectedUnitsData.desiredAltitude !== undefined ? Intl.NumberFormat("en-US").format(selectedUnitsData.desiredAltitude) + " FT" : "Different values"}
{ selectedUnits.forEach((unit) => { unit.setAltitudeType(selectedUnitsData.desiredAltitudeType === "ASL" ? "AGL" : "ASL"); setSelectedUnitsData({ ...selectedUnitsData, desiredAltitudeType: selectedUnitsData.desiredAltitudeType === "ASL" ? "AGL" : "ASL", }); }); }} />
{ selectedUnits.forEach((unit) => { unit.setAltitude(ftToM(Number(ev.target.value))); setSelectedUnitsData({ ...selectedUnitsData, desiredAltitude: Number(ev.target.value), }); }); }} value={selectedUnitsData.desiredAltitude} min={minAltitude} max={maxAltitude} step={altitudeStep} />
)} {/* ============== Altitude selector END ============== */} {/* ============== Airspeed selector START ============== */}
Speed {selectedUnitsData.desiredSpeed !== undefined ? selectedUnitsData.desiredSpeed + " KTS" : "Different values"}
{ selectedUnits.forEach((unit) => { unit.setSpeedType(selectedUnitsData.desiredSpeedType === "CAS" ? "GS" : "CAS"); setSelectedUnitsData({ ...selectedUnitsData, desiredSpeedType: selectedUnitsData.desiredSpeedType === "CAS" ? "GS" : "CAS", }); }); }} />
{ selectedUnits.forEach((unit) => { unit.setSpeed(knotsToMs(Number(ev.target.value))); setSelectedUnitsData({ ...selectedUnitsData, desiredSpeed: Number(ev.target.value), }); }); }} value={selectedUnitsData.desiredSpeed} min={minSpeed} max={maxSpeed} step={speedStep} />
{/* ============== Airspeed selector END ============== */} {/* ============== Rules of Engagement START ============== */} {!(selectedUnits.length === 1 && selectedUnits[0].isTanker()) && !(selectedUnits.length === 1 && selectedUnits[0].isAWACS()) && (
Rules of engagement {[olButtonsRoeHold, olButtonsRoeReturn, olButtonsRoeDesignated, olButtonsRoeFree].map((icon, idx) => { return ( { selectedUnits.forEach((unit) => { unit.setROE(ROEs[idx]); setSelectedUnitsData({ ...selectedUnitsData, ROE: ROEs[idx], }); }); }} active={selectedUnitsData.ROE === ROEs[idx]} icon={icon} /> ); })}
)} {/* ============== Rules of Engagement END ============== */} {selectedCategories.every((category) => { return ["Aircraft", "Helicopter"].includes(category); }) && ( <> {/* ============== Threat Reaction START ============== */}
Threat reaction {[olButtonsThreatNone, olButtonsThreatPassive, olButtonsThreatManoeuvre, olButtonsThreatEvade].map((icon, idx) => { return ( { selectedUnits.forEach((unit) => { unit.setReactionToThreat(reactionsToThreat[idx]); setSelectedUnitsData({ ...selectedUnitsData, reactionToThreat: reactionsToThreat[idx], }); }); }} active={selectedUnitsData.reactionToThreat === reactionsToThreat[idx]} icon={icon} /> ); })}
{/* ============== Threat Reaction END ============== */} {/* ============== Radar and ECM START ============== */}
Radar and ECM {[olButtonsEmissionsSilent, olButtonsEmissionsDefend, olButtonsEmissionsAttack, olButtonsEmissionsFree].map((icon, idx) => { return ( { selectedUnits.forEach((unit) => { unit.setEmissionsCountermeasures(emissionsCountermeasures[idx]); setSelectedUnitsData({ ...selectedUnitsData, emissionsCountermeasures: emissionsCountermeasures[idx], }); }); }} active={selectedUnitsData.emissionsCountermeasures === emissionsCountermeasures[idx]} icon={icon} /> ); })}
{/* ============== Radar and ECM END ============== */} )} {/* ============== Tanker and AWACS available button START ============== */} {getApp() ?.getUnitsManager() ?.getSelectedUnitsVariable((unit) => { return unit.isTanker(); }) && (
Make tanker available { selectedUnits.forEach((unit) => { unit.setAdvancedOptions( !selectedUnitsData.isActiveTanker, unit.getIsActiveAWACS(), unit.getTACAN(), unit.getRadio(), unit.getGeneralSettings() ); setSelectedUnitsData({ ...selectedUnitsData, isActiveTanker: !selectedUnitsData.isActiveTanker, }); }); }} />
)} {getApp() ?.getUnitsManager() ?.getSelectedUnitsVariable((unit) => { return unit.isAWACS(); }) && (
Make AWACS available { selectedUnits.forEach((unit) => { unit.setAdvancedOptions( unit.getIsActiveTanker(), !selectedUnitsData.isActiveAWACS, unit.getTACAN(), unit.getRadio(), unit.getGeneralSettings() ); setSelectedUnitsData({ ...selectedUnitsData, isActiveAWACS: !selectedUnitsData.isActiveAWACS, }); }); }} />
)} {/* ============== Tanker and AWACS available button END ============== */} {/* ============== Advanced settings buttons START ============== */} {selectedUnits.length === 1 && (selectedUnits[0].isTanker() || selectedUnits[0].isAWACS()) && (
)} {/* ============== Advanced settings buttons END ============== */} {selectedCategories.every((category) => { return ["GroundUnit", "NavyUnit"].includes(category); }) && ( <> {/* ============== Shots scatter START ============== */}
Shots scatter {[olButtonsScatter1, olButtonsScatter2, olButtonsScatter3].map((icon, idx) => { return ( { selectedUnits.forEach((unit) => { unit.setShotsScatter(idx + 1); setSelectedUnitsData({ ...selectedUnitsData, shotsScatter: idx + 1, }); }); }} active={selectedUnitsData.shotsScatter === idx + 1} icon={icon} /> ); })}
{/* ============== Shots scatter END ============== */} {/* ============== Shots intensity START ============== */}
Shots intensity {[olButtonsIntensity1, olButtonsIntensity2, olButtonsIntensity3].map((icon, idx) => { return ( { selectedUnits.forEach((unit) => { unit.setShotsIntensity(idx + 1); setSelectedUnitsData({ ...selectedUnitsData, shotsIntensity: idx + 1, }); }); }} active={selectedUnitsData.shotsIntensity === idx + 1} icon={icon} /> ); })}
{/* ============== Shots intensity END ============== */} {/* ============== Operate as toggle START ============== */}
Operate as { selectedUnits.forEach((unit) => { unit.setOperateAs(selectedUnitsData.operateAs === "blue" ? "red" : "blue"); setSelectedUnitsData({ ...selectedUnitsData, operateAs: selectedUnitsData.operateAs === "blue" ? "red" : "blue", }); }); }} />
{/* ============== Operate as toggle END ============== */} {/* ============== Follow roads toggle START ============== */}
Follow roads { selectedUnits.forEach((unit) => { unit.setFollowRoads(!selectedUnitsData.followRoads); setSelectedUnitsData({ ...selectedUnitsData, followRoads: !selectedUnitsData.followRoads, }); }); }} />
{/* ============== Follow roads toggle END ============== */} {/* ============== Unit active toggle START ============== */}
Unit active { selectedUnits.forEach((unit) => { unit.setOnOff(!selectedUnitsData.onOff); setSelectedUnitsData({ ...selectedUnitsData, onOff: !selectedUnitsData.onOff, }); }); }} />
{/* ============== Unit active toggle END ============== */} )}
)} {/* ============== Advanced settings START ============== */} {showAdvancedSettings && (
Advanced settings
Callsign
<> {selectedUnits[0].isAWACS() && ( <> {["Overlord", "Magic", "Wizard", "Focus", "Darkstar"].map((name, idx) => { return ( { if (activeAdvancedSettings) activeAdvancedSettings.radio.callsign = idx + 1; setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} > {name} ); })} )} <> {selectedUnits[0].isTanker() && ( <> {["Texaco", "Arco", "Shell"].map((name, idx) => { return ( { if (activeAdvancedSettings) activeAdvancedSettings.radio.callsign = idx + 1; setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} > {name} ); })} )}
-
{ if (activeAdvancedSettings) activeAdvancedSettings.radio.callsignNumber = Math.max(Math.min(Number(e.target.value), 9), 1); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} onDecrease={() => { if (activeAdvancedSettings) activeAdvancedSettings.radio.callsignNumber = Math.max(Math.min(Number(activeAdvancedSettings.radio.callsignNumber - 1), 9), 1); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} onIncrease={() => { if (activeAdvancedSettings) activeAdvancedSettings.radio.callsignNumber = Math.max(Math.min(Number(activeAdvancedSettings.radio.callsignNumber + 1), 9), 1); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} value={activeAdvancedSettings ? activeAdvancedSettings.radio.callsignNumber : 1} >
TACAN
{ if (activeAdvancedSettings) activeAdvancedSettings.TACAN.channel = Math.max(Math.min(Number(e.target.value), 126), 1); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} onDecrease={() => { if (activeAdvancedSettings) activeAdvancedSettings.TACAN.channel = Math.max(Math.min(Number(activeAdvancedSettings.TACAN.channel - 1), 126), 1); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} onIncrease={() => { if (activeAdvancedSettings) activeAdvancedSettings.TACAN.channel = Math.max(Math.min(Number(activeAdvancedSettings.TACAN.channel + 1), 126), 1); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} value={activeAdvancedSettings ? activeAdvancedSettings.TACAN.channel : 1} > { if (activeAdvancedSettings) activeAdvancedSettings.TACAN.XY = "X"; setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} > X { if (activeAdvancedSettings) activeAdvancedSettings.TACAN.XY = "Y"; setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} > Y { if (activeAdvancedSettings) { activeAdvancedSettings.TACAN.callsign = e.target.value; if (activeAdvancedSettings.TACAN.callsign.length > 3) activeAdvancedSettings.TACAN.callsign = activeAdvancedSettings.TACAN.callsign.slice(0, 3); } setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} />
Enabled{" "} {}} />
Radio frequency
{ let newValue = Math.max(Math.min(Number(e.target.value), 400), 1) * 1000000; if (activeAdvancedSettings) { let decimalPart = activeAdvancedSettings.radio.frequency - Math.floor(activeAdvancedSettings.radio.frequency / 1000000) * 1000000; activeAdvancedSettings.radio.frequency = newValue + decimalPart; } setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} onDecrease={() => { if (activeAdvancedSettings) activeAdvancedSettings.radio.frequency = Math.max( Math.min(Number(activeAdvancedSettings.radio.frequency - 1000000), 400000000), 1000000 ); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} onIncrease={() => { if (activeAdvancedSettings) activeAdvancedSettings.radio.frequency = Math.max( Math.min(Number(activeAdvancedSettings.radio.frequency + 1000000), 400000000), 1000000 ); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} value={activeAdvancedSettings ? Math.floor(activeAdvancedSettings.radio.frequency / 1000000) : 124} >
.
{ let newValue = Math.max(Math.min(Number(e.target.value), 990), 0) * 1000; if (activeAdvancedSettings) { let integerPart = Math.floor(activeAdvancedSettings.radio.frequency / 1000000) * 1000000; activeAdvancedSettings.radio.frequency = newValue + integerPart; } setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} onDecrease={() => { if (activeAdvancedSettings) activeAdvancedSettings.radio.frequency = Math.max( Math.min(Number(activeAdvancedSettings.radio.frequency - 25000), 400000000), 1000000 ); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} onIncrease={() => { if (activeAdvancedSettings) activeAdvancedSettings.radio.frequency = Math.max( Math.min(Number(activeAdvancedSettings.radio.frequency + 25000), 400000000), 1000000 ); setActiveAdvancedSettings(JSON.parse(JSON.stringify(activeAdvancedSettings))); }} value={ activeAdvancedSettings ? (activeAdvancedSettings.radio.frequency - Math.floor(activeAdvancedSettings.radio.frequency / 1000000) * 1000000) / 1000 : 0 } >
MHz
)} {/* ============== Advanced settings END ============== */} {/* ============== Unit basic options END ============== */} <> {/* ============== Fuel/payload/radio section START ============== */} {selectedUnits.length === 1 && (
40 && `bg-green-700`} ${ selectedUnits[0].getFuel() > 10 && selectedUnits[0].getFuel() <= 40 && `bg-yellow-700` } ${selectedUnits[0].getFuel() <= 10 && `bg-red-700`} px-2 py-1 text-sm font-bold text-white `} > {selectedUnits[0].getFuel()}%
{selectedUnits[0].isControlledByOlympus() && selectedUnits[0].isTanker() && ( <> {/* ============== Radio section START ============== */}
{`${["Texaco", "Arco", "Shell"][selectedUnits[0].getRadio().callsign]}-${selectedUnits[0].getRadio().callsignNumber}`}
{`${(selectedUnits[0].getRadio().frequency / 1000000).toFixed(3)} MHz`}
{selectedUnits[0].getTACAN().isOn ? `${selectedUnits[0].getTACAN().channel}${selectedUnits[0].getTACAN().XY} ${selectedUnits[0].getTACAN().callsign}` : "TACAN OFF"}
{/* ============== Radio section END ============== */}
)} {/* ============== Payload section START ============== */} {!selectedUnits[0].isTanker() && !selectedUnits[0].isAWACS() && selectedUnits[0].getAmmo().map((ammo) => { return (
{ammo.quantity}
{ammo.name}
); })} {/* ============== Payload section END ============== */}
)} {/* ============== Fuel/payload/radio section END ============== */} )} {/* ============== Unit control menu END ============== */}
); }