Merge pull request #277 from Pax1601/264-add-avanced-unit-control-options

264 add avanced unit control options
This commit is contained in:
Pax1601
2023-05-17 16:17:33 +02:00
committed by GitHub
19 changed files with 838 additions and 398 deletions

View File

@@ -109,7 +109,7 @@ dl.ol-data-grid dd {
}
.ol-panel.ol-dialog {
padding: 20px;
padding: 24px 30px;
}
.ol-dialog-close {
@@ -177,7 +177,7 @@ dl.ol-data-grid dd {
}
.ol-text-input input {
height: 40px;
height: 32px;
border-radius: 5px;
color: var(--background-offwhite);
background-color: var(--background-grey);

View File

@@ -163,7 +163,10 @@ form>div {
align-items: center;
background-color: var(--background-grey);
border-radius: var(--border-radius-sm);
padding: 1em 30px 1em 20px;
height: 32px;
padding-right: 30px;
padding-left: 20px;
width: calc(100%);
overflow: hidden;
text-overflow: ellipsis;
@@ -645,13 +648,15 @@ body[data-hide-navyunit] #unit-visibility-control-navyunit {
}
#roe-buttons-container button.selected,
#reaction-to-threat-buttons-container button.selected {
#reaction-to-threat-buttons-container button.selected,
#emissions-countermeasures-buttons-container button.selected {
background-color: white;
border-color: white;
}
#roe-buttons-container button::before,
#reaction-to-threat-buttons-container button::before {
#reaction-to-threat-buttons-container button::before,
#emissions-countermeasures-buttons-container button::before {
background-position: center;
background-repeat: no-repeat;
content: "";
@@ -660,68 +665,104 @@ body[data-hide-navyunit] #unit-visibility-control-navyunit {
width: 24px;
}
#roe-buttons-container button[title="Hold"]::before {
#roe-buttons-container button[value="Hold"]::before {
background-image: url("/themes/olympus/images/icons_roe_stop_light.svg");
}
#roe-buttons-container button[title="Hold"].selected::before {
#roe-buttons-container button[value="Hold"].selected::before {
background-image: url("/themes/olympus/images/icons_roe_stop_dark.svg");
}
/**/
#roe-buttons-container button[title="Return"]::before {
#roe-buttons-container button[value="Return"]::before {
background-image: url("/themes/olympus/images/icons_roe_defend_light.svg");
}
#roe-buttons-container button[title="Return"].selected::before {
#roe-buttons-container button[value="Return"].selected::before {
background-image: url("/themes/olympus/images/icons_roe_defend_dark.svg");
}
/**/
#roe-buttons-container button[title="Designated"]::before {
#roe-buttons-container button[value="Designated"]::before {
background-image: url("/themes/olympus/images/icons_roe_target_light.svg");
}
#roe-buttons-container button[title="Designated"].selected::before {
#roe-buttons-container button[value="Designated"].selected::before {
background-image: url("/themes/olympus/images/icons_roe_target_dark.svg");
}
/**/
#roe-buttons-container button[title="Free"]::before {
#roe-buttons-container button[value="Free"]::before {
background-image: url("/themes/olympus/images/icons_roe_free_light.svg");
}
#roe-buttons-container button[title="Free"].selected::before {
#roe-buttons-container button[value="Free"].selected::before {
background-image: url("/themes/olympus/images/icons_roe_free_dark.svg");
}
/****************************************************************************************/
#reaction-to-threat-buttons-container button[title="None"]::before {
#reaction-to-threat-buttons-container button[value="None"]::before {
background-image: url("/themes/olympus/images/icons_threat_nothing_light.svg");
}
#reaction-to-threat-buttons-container button[title="None"].selected::before {
#reaction-to-threat-buttons-container button[value="None"].selected::before {
background-image: url("/themes/olympus/images/icons_threat_nothing_dark.svg");
}
/**/
#reaction-to-threat-buttons-container button[title="Passive"]::before {
#reaction-to-threat-buttons-container button[value="Passive"]::before {
background-image: url("/themes/olympus/images/icons_threat_cms_light.svg");
}
#reaction-to-threat-buttons-container button[title="Passive"].selected::before {
#reaction-to-threat-buttons-container button[value="Passive"].selected::before {
background-image: url("/themes/olympus/images/icons_threat_cms_dark.svg");
}
/**/
#reaction-to-threat-buttons-container button[title="Evade"]::before {
#reaction-to-threat-buttons-container button[value="Evade"]::before {
background-image: url("/themes/olympus/images/icons_threat_defend_light.svg");
}
#reaction-to-threat-buttons-container button[title="Evade"].selected::before {
#reaction-to-threat-buttons-container button[value="Evade"].selected::before {
background-image: url("/themes/olympus/images/icons_threat_defend_dark.svg");
}
/****************************************************************************************/
#emissions-countermeasures-buttons-container button[value="Silent"]::before {
background-image: url("/themes/olympus/images/icons_roe_stop_light.svg");
}
#emissions-countermeasures-buttons-container button[value="Silent"].selected::before {
background-image: url("/themes/olympus/images/icons_roe_stop_dark.svg");
}
/**/
#emissions-countermeasures-buttons-container button[value="Defend"]::before {
background-image: url("/themes/olympus/images/icons_roe_defend_light.svg");
}
#emissions-countermeasures-buttons-container button[value="Defend"].selected::before {
background-image: url("/themes/olympus/images/icons_roe_defend_dark.svg");
}
/**/
#emissions-countermeasures-buttons-container button[value="Attack"]::before {
background-image: url("/themes/olympus/images/icons_roe_target_light.svg");
}
#emissions-countermeasures-buttons-container button[value="Attack"].selected::before {
background-image: url("/themes/olympus/images/icons_roe_target_dark.svg");
}
/**/
#emissions-countermeasures-buttons-container button[value="Free"]::before {
background-image: url("/themes/olympus/images/icons_roe_free_light.svg");
}
#emissions-countermeasures-buttons-container button[value="Free"].selected::before {
background-image: url("/themes/olympus/images/icons_roe_free_dark.svg");
}
/****************************************************************************************/
#splash-screen {
background-image: url("/images/splash/splash_pic_ship.png");

View File

@@ -8,7 +8,7 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
left: 10px;
position: absolute;
top: 80px;
width: 250px;
width: 260px;
z-index: 1000;
}
@@ -31,7 +31,7 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
border-radius: var(--border-radius-lg);
display: flex;
font-size: 11px;
height: 30px;
height: 32px;
padding: 8px 0;
position: relative;
width: 100%;
@@ -94,7 +94,8 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
}
#unit-control-panel #threat,
#unit-control-panel #roe {
#unit-control-panel #roe,
#unit-control-panel #emissions-countermeasures {
margin-top: 12px;
}
@@ -102,6 +103,31 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
width: 400px;
}
#advanced-settings-dialog:not([data-show-settings]) #general-settings {
display: none;
}
#advanced-settings-dialog:not([data-show-tasking]) #tasking {
display: none;
}
#advanced-settings-dialog:not([data-show-tanker]) #tanker-checkbox {
display: none;
}
#advanced-settings-dialog:not([data-show-AWACS]) #AWACS-checkbox {
display: none;
}
#advanced-settings-dialog:not([data-show-TACAN]) #TACAN-options {
display: none;
}
#advanced-settings-dialog:not([data-show-radio]) #radio-options {
display: none;
}
#advanced-settings-dialog>.ol-dialog-content {
margin-top: 10px;
margin-bottom: 10px;
@@ -111,6 +137,32 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
row-gap: 10px;
}
#advanced-settings-dialog>.ol-dialog-content>.ol-group {
#advanced-settings-dialog>.ol-dialog-content>div {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
row-gap: 10px;
}
#advanced-settings-dialog>.ol-dialog-content>div>.ol-group {
justify-content: space-between;
}
#advanced-settings-dialog h4 {
white-space: nowrap;
}
#advanced-settings-dialog hr {
margin-top: 15px;
margin-bottom: 10px;
}
#general-settings-grid {
display: grid;
grid-template-columns: 1fr 1fr;
row-gap: 10px;
}
#general-settings-grid>div {
width: 49%;
}

View File

@@ -40,17 +40,15 @@ interface TaskData {
targetAltitude: number;
isTanker: boolean;
isAWACS: boolean;
TACANChannel: number;
TACANXY: string;
TACANCallsign: string;
radioFrequency: number;
radioCallsign: number;
radioCallsignNumber: number;
}
interface OptionsData {
ROE: string;
reactionToThreat: string;
emissionsCountermeasures: string;
TACAN: TACAN;
radio: Radio;
generalSettings: GeneralSettings;
}
interface UnitData {
@@ -61,3 +59,24 @@ interface UnitData {
taskData: TaskData;
optionsData: OptionsData;
}
interface TACAN {
isOn: boolean;
channel: number;
XY: string;
callsign: string;
}
interface Radio {
frequency: number;
callsign: number;
callsignNumber: number;
}
interface GeneralSettings {
prohibitJettison: boolean;
prohibitAA: boolean;
prohibitAG: boolean;
prohibitAfterburner: boolean;
prohibitAirWpn: boolean;
}

View File

@@ -92,7 +92,7 @@ function readConfig(config: any) {
setAddress(address == "*" ? window.location.hostname : address, <number>port);
}
else {
throw new Error('Could not read configuration file!');
throw new Error('Could not read configuration file');
}
}

View File

@@ -1,7 +1,6 @@
import { getUnitsManager } from "..";
import { Dropdown } from "../controls/dropdown";
import { Slider } from "../controls/slider";
import { dataPointMap } from "../other/utils";
import { aircraftDatabase } from "../units/aircraftdatabase";
import { groundUnitsDatabase } from "../units/groundunitsdatabase";
import { Aircraft, GroundUnit, Unit } from "../units/unit";
@@ -10,6 +9,11 @@ import { Panel } from "./panel";
const ROEs: string[] = ["Hold", "Return", "Designated", "Free"];
const reactionsToThreat: string[] = ["None", "Passive", "Evade"];
const emissionsCountermeasures: string[] = ["Silent", "Attack", "Defend", "Free"];
const ROEDescriptions: string[] = ["Hold (Never fire)", "Return (Only fire if fired upon)", "Designated (Attack the designated target only)", "Free (Attack anyone)"];
const reactionsToThreatDescriptions: string[] = ["None (No reaction)", "Passive (Countermeasures only, no manoeuvre)", "Evade (Countermeasures and manoeuvers)"];
const emissionsCountermeasuresDescriptions: string[] = ["Silent (Radar off, no countermeasures)", "Attack (Radar only for targeting, countermeasures only if attacked/locked)", "Defend (Radar for searching, jammer if locked, countermeasures inside WEZ)", "Always on (Radar and jammer always on, countermeasures when hostile detected)"];
const minSpeedValues: { [key: string]: number } = { Aircraft: 100, Helicopter: 0, NavyUnit: 0, GroundUnit: 0 };
const maxSpeedValues: { [key: string]: number } = { Aircraft: 800, Helicopter: 300, NavyUnit: 60, GroundUnit: 60 };
@@ -52,23 +56,20 @@ export class UnitControlPanel extends Panel {
/* Option buttons */
this.#optionButtons["ROE"] = ROEs.map((option: string, index: number) => {
var button = document.createElement("button");
button.title = option;
button.value = option;
button.addEventListener("click", () => { getUnitsManager().selectedUnitsSetROE(button.title); });
return button;
return this.#createOptionButton(option, ROEDescriptions[index], () => { getUnitsManager().selectedUnitsSetROE(option); });
});
this.#optionButtons["reactionToThreat"] = reactionsToThreat.map((option: string, index: number) => {
var button = document.createElement("button");
button.title = option;
button.value = option;
button.addEventListener("click", () => { getUnitsManager().selectedUnitsSetReactionToThreat(button.title); });
return button;
return this.#createOptionButton(option, reactionsToThreatDescriptions[index],() => { getUnitsManager().selectedUnitsSetReactionToThreat(option); });
});
this.#optionButtons["emissionsCountermeasures"] = emissionsCountermeasures.map((option: string, index: number) => {
return this.#createOptionButton(option, emissionsCountermeasuresDescriptions[index],() => { getUnitsManager().selectedUnitsSetEmissionsCountermeasures(option); });
});
this.getElement().querySelector("#roe-buttons-container")?.append(...this.#optionButtons["ROE"]);
this.getElement().querySelector("#reaction-to-threat-buttons-container")?.append(...this.#optionButtons["reactionToThreat"]);
this.getElement().querySelector("#emissions-countermeasures-buttons-container")?.append(...this.#optionButtons["emissionsCountermeasures"]);
this.#advancedSettingsDialog = <HTMLElement> document.querySelector("#advanced-settings-dialog");
@@ -122,7 +123,7 @@ export class UnitControlPanel extends Panel {
}));
} else {
var el = document.createElement("div");
el.innerText = "Too many units selected"
el.innerText = "Too many units selected";
this.getElement().querySelector("#selected-units-container")?.replaceChildren(el);
}
}
@@ -141,11 +142,15 @@ export class UnitControlPanel extends Panel {
this.#optionButtons["reactionToThreat"].forEach((button: HTMLButtonElement) => {
button.classList.toggle("selected", units.every((unit: Unit) => unit.getOptionsData().reactionToThreat === button.value))
});
this.#optionButtons["emissionsCountermeasures"].forEach((button: HTMLButtonElement) => {
button.classList.toggle("selected", units.every((unit: Unit) => unit.getOptionsData().emissionsCountermeasures === button.value))
});
}
}
}
// Update function will only be allowed to update the sliders once it's matched the expected value for the first time (due to lag of Ajax request)
/* Update function will only be allowed to update the sliders once it's matched the expected value for the first time (due to lag of Ajax request) */
#updateCanSetAltitudeSlider(altitude: number) {
if (this.#expectedAltitude < 0 || altitude === this.#expectedAltitude) {
this.#expectedAltitude = -1;
@@ -190,19 +195,15 @@ export class UnitControlPanel extends Panel {
this.#airspeedSlider.setActive(targetSpeed != undefined);
if (targetSpeed != undefined) {
targetSpeed *= 1.94384;
if (this.#updateCanSetSpeedSlider(targetSpeed)) {
this.#airspeedSlider.setValue(targetSpeed);
}
}
this.#altitudeSlider.setActive(targetAltitude != undefined);
if (targetAltitude != undefined) {
targetAltitude /= 0.3048;
if (this.#updateCanSetAltitudeSlider(targetAltitude)) {
this.#altitudeSlider.setValue(targetAltitude);
}
@@ -218,84 +219,134 @@ export class UnitControlPanel extends Panel {
{
if (units.length == 1)
{
/* HTML Elements */
const unitNameEl = this.#advancedSettingsDialog.querySelector("#unit-name") as HTMLElement;
const prohibitJettisonCheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-jettison-checkbox")?.querySelector("input") as HTMLInputElement;
const prohibitAfterburnerCheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-afterburner-checkbox")?.querySelector("input") as HTMLInputElement;
const prohibitAACheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-AA-checkbox")?.querySelector("input") as HTMLInputElement;
const prohibitAGCheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-AG-checkbox")?.querySelector("input") as HTMLInputElement;
const prohibitAirWpnCheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-air-wpn-checkbox")?.querySelector("input") as HTMLInputElement;
const tankerCheckbox = this.#advancedSettingsDialog.querySelector("#tanker-checkbox")?.querySelector("input") as HTMLInputElement;
const AWACSCheckbox = this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.querySelector("input") as HTMLInputElement;
const TACANCheckbox = this.#advancedSettingsDialog.querySelector("#TACAN-checkbox")?.querySelector("input") as HTMLInputElement;
const TACANChannelInput = this.#advancedSettingsDialog.querySelector("#TACAN-channel")?.querySelector("input") as HTMLInputElement;
const TACANCallsignInput = this.#advancedSettingsDialog.querySelector("#tacan-callsign")?.querySelector("input") as HTMLInputElement;
const radioMhzInput = this.#advancedSettingsDialog.querySelector("#radio-mhz")?.querySelector("input") as HTMLInputElement;
const radioCallsignNumberInput = this.#advancedSettingsDialog.querySelector("#radio-callsign-number")?.querySelector("input") as HTMLInputElement;
const unit = units[0];
(<HTMLElement>this.#advancedSettingsDialog.querySelector("#unit-name")).innerText = unit.getBaseData().unitName;
const roles = aircraftDatabase.getByName(unit.getBaseData().name)?.loadouts.map((loadout) => {return loadout.roles})
const tanker = roles != undefined && Array.prototype.concat.apply([], roles)?.includes("Tanker");
const AWACS = roles != undefined && Array.prototype.concat.apply([], roles)?.includes("AWACS");
const radioMHz = Math.floor(unit.getOptionsData().radio.frequency / 1000000);
const radioDecimals = (unit.getOptionsData().radio.frequency / 1000000 - radioMHz) * 1000;
if (getUnitsManager().getSelectedUnits().length == 1)
{
var radioMHz = Math.floor(unit.getTaskData().radioFrequency / 1000000);
var radioDecimals = (unit.getTaskData().radioFrequency / 1000000 - radioMHz) * 1000;
/* Activate the correct options depending on unit type */
this.#advancedSettingsDialog.toggleAttribute("data-show-settings", !tanker && !AWACS);
this.#advancedSettingsDialog.toggleAttribute("data-show-tasking", tanker || AWACS);
this.#advancedSettingsDialog.toggleAttribute("data-show-tanker", tanker);
this.#advancedSettingsDialog.toggleAttribute("data-show-AWACS", AWACS);
this.#advancedSettingsDialog.toggleAttribute("data-show-TACAN", tanker);
this.#advancedSettingsDialog.toggleAttribute("data-show-radio", tanker || AWACS);
// Default values for "normal" units
/* Set common properties */
// Name
unitNameEl.innerText = unit.getBaseData().unitName;
// General settings
prohibitJettisonCheckbox.checked = unit.getOptionsData().generalSettings.prohibitJettison;
prohibitAfterburnerCheckbox.checked = unit.getOptionsData().generalSettings.prohibitAfterburner;
prohibitAACheckbox.checked = unit.getOptionsData().generalSettings.prohibitAA;
prohibitAGCheckbox.checked = unit.getOptionsData().generalSettings.prohibitAG;
prohibitAirWpnCheckbox.checked = unit.getOptionsData().generalSettings.prohibitAirWpn;
// Tasking
tankerCheckbox.checked = unit.getTaskData().isTanker;
AWACSCheckbox.checked = unit.getTaskData().isAWACS;
// TACAN
TACANCheckbox.checked = unit.getOptionsData().TACAN.isOn;
TACANChannelInput.value = String(unit.getOptionsData().TACAN.channel);
TACANCallsignInput.value = String(unit.getOptionsData().TACAN.callsign);
this.#TACANXYDropdown.setValue(unit.getOptionsData().TACAN.XY);
// Radio
radioMhzInput.value = String(radioMHz);
radioCallsignNumberInput.value = String(unit.getOptionsData().radio.callsignNumber);
this.#radioDecimalsDropdown.setValue("." + radioDecimals);
if (tanker) /* Set tanker specific options */
this.#radioCallsignDropdown.setOptions(["Texaco", "Arco", "Shell"]);
else if (AWACS) /* Set AWACS specific options */
this.#radioCallsignDropdown.setOptions(["Overlord", "Magic", "Wizard", "Focus", "Darkstar"]);
else
this.#radioCallsignDropdown.setOptions(["Enfield", "Springfield", "Uzi", "Colt", "Dodge", "Ford", "Chevy", "Pontiac"]);
this.#radioCallsignDropdown.selectValue(unit.getTaskData().radioCallsign - 1);
// Input values
var tankerCheckbox = this.#advancedSettingsDialog.querySelector("#tanker-checkbox")?.querySelector("input")
var AWACSCheckbox = this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.querySelector("input")
var TACANChannelInput = this.#advancedSettingsDialog.querySelector("#TACAN-channel")?.querySelector("input");
var TACANCallsignInput = this.#advancedSettingsDialog.querySelector("#tacan-callsign")?.querySelector("input");
var radioMhzInput = this.#advancedSettingsDialog.querySelector("#radio-mhz")?.querySelector("input");
var radioCallsignNumberInput = this.#advancedSettingsDialog.querySelector("#radio-callsign-number")?.querySelector("input");
if (tankerCheckbox) tankerCheckbox.checked = unit.getTaskData().isTanker;
if (AWACSCheckbox) AWACSCheckbox.checked = unit.getTaskData().isAWACS;
if (TACANChannelInput) TACANChannelInput.value = String(unit.getTaskData().TACANChannel);
if (TACANCallsignInput) TACANCallsignInput.value = String(unit.getTaskData().TACANCallsign);
if (radioMhzInput) radioMhzInput.value = String(radioMHz);
if (radioCallsignNumberInput) radioCallsignNumberInput.value = String(unit.getTaskData().radioCallsignNumber);
this.#TACANXYDropdown.setValue(unit.getTaskData().TACANXY);
this.#radioDecimalsDropdown.setValue("." + radioDecimals);
// Make sure its in the valid range
if (!this.#radioCallsignDropdown.selectValue(unit.getTaskData().radioCallsign - 1))
this.#radioCallsignDropdown.selectValue(0);
// Set options for tankers
var roles = aircraftDatabase.getByName(unit.getBaseData().name)?.loadouts.map((loadout) => {return loadout.roles})
if (roles != undefined && Array.prototype.concat.apply([], roles)?.includes("Tanker")){
this.#advancedSettingsDialog.querySelector("#tanker-checkbox")?.classList.remove("hide");
this.#radioCallsignDropdown.setOptions(["Texaco", "Arco", "Shell"]);
this.#radioCallsignDropdown.selectValue(unit.getTaskData().radioCallsign - 1);
}
else {
this.#advancedSettingsDialog.querySelector("#tanker-checkbox")?.classList.add("hide");
}
// Set options for AWACS
if (roles != undefined && Array.prototype.concat.apply([], roles)?.includes("AWACS")){
this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.classList.remove("hide");
this.#radioCallsignDropdown.setOptions(["Overlord", "Magic", "Wizard", "Focus", "Darkstar"]);
this.#radioCallsignDropdown.selectValue(unit.getTaskData().radioCallsign - 1);
} else {
this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.classList.add("hide");
}
}
// This must be done after setting the options
if (!this.#radioCallsignDropdown.selectValue(unit.getOptionsData().radio.callsign - 1)) // Ensure the selected value is in the acceptable range
this.#radioCallsignDropdown.selectValue(0);
}
}
#applyAdvancedSettings()
{
const isTanker = this.#advancedSettingsDialog.querySelector("#tanker-checkbox")?.querySelector("input")?.checked? true: false;
const isAWACS = this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.querySelector("input")?.checked? true: false;
/* HTML Elements */
const prohibitJettisonCheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-jettison-checkbox")?.querySelector("input") as HTMLInputElement;
const prohibitAfterburnerCheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-afterburner-checkbox")?.querySelector("input") as HTMLInputElement;
const prohibitAACheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-AA-checkbox")?.querySelector("input") as HTMLInputElement;
const prohibitAGCheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-AG-checkbox")?.querySelector("input") as HTMLInputElement;
const prohibitAirWpnCheckbox = this.#advancedSettingsDialog.querySelector("#prohibit-air-wpn-checkbox")?.querySelector("input") as HTMLInputElement;
const tankerCheckbox = this.#advancedSettingsDialog.querySelector("#tanker-checkbox")?.querySelector("input") as HTMLInputElement;
const AWACSCheckbox = this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.querySelector("input") as HTMLInputElement;
const TACANCheckbox = this.#advancedSettingsDialog.querySelector("#TACAN-checkbox")?.querySelector("input") as HTMLInputElement;
const TACANChannelInput = this.#advancedSettingsDialog.querySelector("#TACAN-channel")?.querySelector("input") as HTMLInputElement;
const TACANCallsignInput = this.#advancedSettingsDialog.querySelector("#tacan-callsign")?.querySelector("input") as HTMLInputElement;
const radioMhzInput = this.#advancedSettingsDialog.querySelector("#radio-mhz")?.querySelector("input") as HTMLInputElement;
const radioCallsignNumberInput = this.#advancedSettingsDialog.querySelector("#radio-callsign-number")?.querySelector("input") as HTMLInputElement;
const TACANChannel = Number(this.#advancedSettingsDialog.querySelector("#TACAN-channel")?.querySelector("input")?.value);
const TACANXY = this.#TACANXYDropdown.getValue();
const TACANCallsign = <string> this.#advancedSettingsDialog.querySelector("#tacan-callsign")?.querySelector("input")?.value
const radioMHz = Number(this.#advancedSettingsDialog.querySelector("#radio-mhz")?.querySelector("input")?.value);
/* Tasking */
const isTanker = tankerCheckbox.checked? true: false;
const isAWACS = AWACSCheckbox.checked? true: false;
/* TACAN */
const TACAN: TACAN = {
isOn: TACANCheckbox.checked? true: false,
channel: Number(TACANChannelInput.value),
XY: this.#TACANXYDropdown.getValue(),
callsign: TACANCallsignInput.value as string
}
/* Radio */
const radioMHz = Number(radioMhzInput.value);
const radioDecimals = this.#radioDecimalsDropdown.getValue();
const radioCallsign = this.#radioCallsignDropdown.getIndex() + 1;
const radioCallsignNumber = Number(this.#advancedSettingsDialog.querySelector("#radio-callsign-number")?.querySelector("input")?.value);
var radioFrequency = (radioMHz * 1000 + Number(radioDecimals.substring(1))) * 1000;
const radio: Radio = {
frequency: (radioMHz * 1000 + Number(radioDecimals.substring(1))) * 1000,
callsign: this.#radioCallsignDropdown.getIndex() + 1,
callsignNumber: Number(radioCallsignNumberInput.value)
}
/* General settings */
const generalSettings: GeneralSettings = {
prohibitJettison: prohibitJettisonCheckbox.checked? true: false,
prohibitAfterburner: prohibitAfterburnerCheckbox.checked? true: false,
prohibitAA: prohibitAACheckbox.checked? true: false,
prohibitAG: prohibitAGCheckbox.checked? true: false,
prohibitAirWpn: prohibitAirWpnCheckbox.checked? true: false
}
/* Send command and close */
var units = getUnitsManager().getSelectedUnits();
if (units.length > 0)
units[0].setAdvancedOptions(isTanker, isAWACS, TACANChannel, TACANXY, TACANCallsign, radioFrequency, radioCallsign, radioCallsignNumber);
units[0].setAdvancedOptions(isTanker, isAWACS, TACAN, radio, generalSettings);
this.#advancedSettingsDialog.classList.add("hide");
}
#createOptionButton(option: string, title: string, callback: EventListenerOrEventListenerObject) {
var button = document.createElement("button");
button.value = option;
button.title = title;
button.addEventListener("click", callback);
return button;
}
}

View File

@@ -209,23 +209,26 @@ export function setReactionToThreat(ID: number, reactionToThreat: string) {
POST(data, () => { });
}
export function setEmissionsCountermeasures(ID: number, emissionCountermeasure: string) {
var command = {"ID": ID, "emissionsCountermeasures": emissionCountermeasure}
var data = {"setEmissionsCountermeasures": command}
POST(data, () => { });
}
export function refuel(ID: number) {
var command = { "ID": ID };
var data = { "refuel": command }
POST(data, () => { });
}
export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACANChannel: number, TACANXY: string, TACANCallsign: string, radioFrequency: number, radioCallsign: number, radioCallsignNumber: number)
export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings)
{
var command = { "ID": ID,
"isTanker": isTanker,
"isAWACS": isAWACS,
"TACANChannel": TACANChannel,
"TACANXY": TACANXY,
"TACANCallsign": TACANCallsign,
"radioFrequency": radioFrequency,
"radioCallsign": radioCallsign,
"radioCallsignNumber": radioCallsignNumber
"TACAN": TACAN,
"radio": radio,
"generalSettings": generalSettings
};
var data = { "setAdvancedOptions": command };

View File

@@ -1,10 +1,9 @@
import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map } from 'leaflet';
import { getMap, getUnitsManager } from '..';
import { rad2deg } from '../other/utils';
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, getUnits, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit } from '../server/server';
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, getUnits, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures } from '../server/server';
import { aircraftDatabase } from './aircraftdatabase';
import { groundUnitsDatabase } from './groundunitsdatabase';
import { field } from 'geomag'
var pathIcon = new Icon({
iconUrl: 'images/marker-icon.png',
@@ -43,23 +42,21 @@ export class Unit extends Marker {
leaderID: 0
},
taskData: {
currentState: "IDLE",
currentState: "NONE",
currentTask: "",
activePath: {},
targetSpeed: 0,
targetAltitude: 0,
isTanker: false,
isAWACS: false,
TACANChannel: 0,
TACANXY: "X",
TACANCallsign: "",
radioFrequency: 0,
radioCallsign: 0,
radioCallsignNumber: 0
},
optionsData: {
ROE: "",
reactionToThreat: "",
emissionsCountermeasures: "",
TACAN: { isOn: false, channel: 0, XY: "X", callsign: "" },
radio: { frequency: 0, callsign: 1, callsignNumber: 1},
generalSettings: { prohibitJettison: false, prohibitAA: false, prohibitAG: false, prohibitAfterburner: false, prohibitAirWpn: false}
}
};
@@ -379,6 +376,11 @@ export class Unit extends Marker {
setReactionToThreat(this.ID, reactionToThreat);
}
setEmissionsCountermeasures(emissionCountermeasure: string) {
if (!this.getMissionData().flags.Human)
setEmissionsCountermeasures(this.ID, emissionCountermeasure);
}
setLeader(isLeader: boolean, wingmenIDs: number[] = []) {
if (!this.getMissionData().flags.Human)
setLeader(this.ID, isLeader, wingmenIDs);
@@ -394,9 +396,9 @@ export class Unit extends Marker {
refuel(this.ID);
}
setAdvancedOptions(isTanker: boolean, isAWACS: boolean, TACANChannel: number, TACANXY: string, TACANcallsign: string, radioFrequency: number, radioCallsign: number, radioCallsignNumber: number) {
setAdvancedOptions(isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings) {
if (!this.getMissionData().flags.Human)
setAdvacedOptions(this.ID, isTanker, isAWACS, TACANChannel, TACANXY, TACANcallsign, radioFrequency, radioCallsign, radioCallsignNumber);
setAdvacedOptions(this.ID, isTanker, isAWACS, TACAN, radio, generalSettings);
}
/***********************************************/

View File

@@ -250,6 +250,15 @@ export class UnitsManager {
this.#showActionMessage(selectedUnits, `reaction to threat set to ${reactionToThreat}`);
}
selectedUnitsSetEmissionsCountermeasures(emissionCountermeasure: string) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
for (let idx in selectedUnits) {
selectedUnits[idx].setEmissionsCountermeasures(emissionCountermeasure);
}
this.#showActionMessage(selectedUnits, `reaction to threat set to ${emissionCountermeasure}`);
}
selectedUnitsAttackUnit(ID: number) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
for (let idx in selectedUnits) {

View File

@@ -30,109 +30,147 @@
</div>
<div class="ol-dialog-content">
<!--
<div class="ol-checkbox">
<label>
<input type="checkbox" />
Use ECM when available
</label>
</div>
<div class="ol-checkbox">
<label>
<input type="checkbox" />
Prohibit jettison
</label>
</div>
<div class="ol-checkbox">
<label>
<input type="checkbox" />
Prohibit afterburner
</label>
</div>
<div class="ol-checkbox">
<label>
<input type="checkbox" />
Prohibit A/A
</label>
</div>
<div class="ol-checkbox">
<label>
<input type="checkbox" />
Prohibit A/G
</label>
</div>
-->
<div id="tanker-checkbox" class="ol-checkbox">
<label>
<input type="checkbox" />
Operate as AAR tanker
</label>
</div>
<div id="AWACS-checkbox" class="ol-checkbox">
<label>
<input type="checkbox" />
Operate as AWACS
</label>
</div>
<div class="ol-group">
<label>A/A TACAN: </label>
<!-- General settings -->
<div id="general-settings">
<div class="ol-group">
<div id="TACAN-channel" class="ol-text-input">
<input type="number" min="1" max="126" step="1" value="40">
<h4>General settings</h4>
<hr>
</div>
<div id="general-settings-grid">
<div id="prohibit-jettison-checkbox" class="ol-checkbox">
<label title="The unit will not jettison external stores">
<input type="checkbox"/>
Prohibit jettison
</label>
</div>
<div id="TACAN-XY" class="ol-select">
<div class="ol-select-value">X</div>
<div class="ol-select-options">
</div>
<div id="prohibit-afterburner-checkbox" class="ol-checkbox">
<label title="The unit will not engage the afterburner">
<input type="checkbox" />
Prohibit afterburner
</label>
</div>
<div id="prohibit-AA-checkbox" class="ol-checkbox">
<label title="The unit will not engage airborne targets">
<input type="checkbox" />
Prohibit A/A
</label>
</div>
<div id="prohibit-AG-checkbox" class="ol-checkbox">
<label title="The unit will not engage ground targets">
<input type="checkbox" />
Prohibit A/G
</label>
</div>
<div id="TACAN-callsign" class="ol-text-input">
<input type="text" maxlength="3" value="TKR" style="width: 50px">
<div id="prohibit-air-wpn-checkbox" class="ol-checkbox">
<label title="The unit will not engage A/A weapons (e.g. SAM sites will not engage HARMs)">
<input type="checkbox" />
Prohibit air wpn engage
</label>
</div>
</div>
</div>
<div class="ol-group">
<label> Radio frequency: </label>
<!-- Tasking -->
<div id="tasking">
<div class="ol-group">
<div id="radio-mhz" class="ol-text-input">
<input type="number" min="1" max="999" step="1" value="260">
</div>
<div id="radio-decimals" class="ol-select">
<div class="ol-select-value">.000</div>
<div class="ol-select-options">
</div>
</div>
<h4>Tasking</h4>
<hr>
</div>
</div>
<div class="ol-group">
<label> Radio callsign: </label>
<div class="ol-group">
<div id="radio-callsign" class="ol-select">
<div class="ol-select-value"></div>
<div class="ol-select-options">
</div>
</div>
<label>
-
<div id="tanker-checkbox" class="ol-checkbox">
<label title="The unit will operate as Air to Air Refueling tanker for airplanes that have a compatible refueling system">
<input type="checkbox" />
Operate as AAR tanker
</label>
</div>
<div id="AWACS-checkbox" class="ol-checkbox">
<label title="The unit will operate as AWACS on datalink">
<input type="checkbox" />
Operate as AWACS
</label>
</div>
</div>
<!-- TACAN options -->
<div id="TACAN-options">
<div class="ol-group">
<h4>TACAN options</h4>
<hr>
</div>
<div id="TACAN-checkbox" class="ol-checkbox">
<label title="Turn ON the A/A TACAN">
<input type="checkbox" />
Use A/A TACAN
</label>
</div>
<div class="ol-group">
<label>A/A TACAN: </label>
<div class="ol-group">
<div id="TACAN-channel" class="ol-text-input">
<input type="number" min="1" max="126" step="1" value="40">
</div>
<div id="TACAN-XY" class="ol-select">
<div class="ol-select-value">X</div>
<div class="ol-select-options">
</div>
</div>
<div id="TACAN-callsign" class="ol-text-input">
<input type="text" maxlength="3" value="TKR" style="width: 50px">
</div>
</div>
</div>
</div>
<!-- Radio options -->
<div id="radio-options">
<div class="ol-group">
<h4>Radio options</h4>
<hr>
</div>
<div class="ol-group">
<label> Radio frequency: </label>
<div id="radio-callsign-number" class="ol-text-input">
<input type="number" min="1" max="999" step="1" value="1">
<div class="ol-group">
<div id="radio-mhz" class="ol-text-input">
<input type="number" min="1" max="999" step="1" value="260">
</div>
<div id="radio-decimals" class="ol-select">
<div class="ol-select-value">.000</div>
<div class="ol-select-options">
</div>
</div>
</div>
</div>
<div class="ol-group">
<label> Radio callsign: </label>
<div class="ol-group">
<div id="radio-callsign" class="ol-select">
<div class="ol-select-value"></div>
<div class="ol-select-options">
</div>
</div>
<label>
-
</label>
<div id="radio-callsign-number" class="ol-text-input">
<input type="number" min="1" max="999" step="1" value="1">
</div>
</div>
</div>
</div>

View File

@@ -52,6 +52,13 @@
</div>
</div>
<div id="emissions-countermeasures">
<h4>Emissions & countermeasures</h4>
<div id="emissions-countermeasures-buttons-container" class="ol-group ol-button-box">
<!-- This is where the emissions/countermeasures buttons will be shown -->
</div>
</div>
<hr />
<div id="advanced-settings-div">