import React, { 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 { 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 } from "../components/olicons"; import { Coalition } from "../../types/types"; import { ftToM, knotsToMs, mToFt, msToKnots } from "../../other/utils"; export function UnitControlMenu() { var [open, setOpen] = useState(false); var [selectedUnits, setSelectedUnits] = useState([] as Unit[]); var [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 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) => { setOpen(true); 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 selected clean the view */ document.addEventListener("clearSelection", () => { setOpen(false); 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() ?? []; return { }} > {/* Units list */}
{ <> { ['blue', 'red', 'neutral'].map((coalition) => { return Object.keys(unitOccurences[coalition]).map((name) => { return
{name} x{unitOccurences[coalition][name]}
}) }) } }
{/* Altitude selector */ selectedCategories.every((category) => { return ['Aircraft', 'Helicopter'].includes(category) }) &&
Altitude {selectedUnitsData.desiredAltitude !== undefined ? (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} />
} {/* Airspeed selector */}
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} />
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} /> }) }
{ selectedCategories.every((category) => { return ['Aircraft', 'Helicopter'].includes(category) }) && <>
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} /> }) }
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} /> }) }
} { getApp()?.getUnitsManager()?.getSelectedUnitsVariable((unit) => { return unit.isTanker() }) &&
Act as tanker { 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() }) &&
Act as AWACS { selectedUnits.forEach((unit) => { unit.setAdvancedOptions(unit.getIsActiveTanker(), !selectedUnitsData.isActiveAWACS, unit.getTACAN(), unit.getRadio(), unit.getGeneralSettings()); setSelectedUnitsData({ ...selectedUnitsData, isActiveAWACS: !selectedUnitsData.isActiveAWACS }) }) }} />
} { selectedCategories.every((category) => { return ['GroundUnit', 'NavyUnit'].includes(category) }) && <>
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 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} /> }) }
Operate as { selectedUnits.forEach((unit) => { unit.setOperateAs(selectedUnitsData.operateAs === 'blue' ? 'red' : 'blue'); setSelectedUnitsData({ ...selectedUnitsData, operateAs: selectedUnitsData.operateAs === 'blue' ? 'red' : 'blue' }) }) }} />
Follow roads { selectedUnits.forEach((unit) => { unit.setFollowRoads(!selectedUnitsData.followRoads); setSelectedUnitsData({ ...selectedUnitsData, followRoads: !selectedUnitsData.followRoads }) }) }} />
Unit active { selectedUnits.forEach((unit) => { unit.setOnOff(!selectedUnitsData.onOff); setSelectedUnitsData({ ...selectedUnitsData, onOff: !selectedUnitsData.onOff }) }) }} />
}
}