From 316261e01e6b725f760f40adb8317d8953df5907 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Tue, 11 Apr 2023 20:30:59 +0200 Subject: [PATCH] Started to implement advanced settings --- client/demo.js | 5 +- client/public/stylesheets/layout.css | 17 ++++-- client/src/@types/unit.d.ts | 6 ++ client/src/panels/unitcontrolpanel.ts | 88 ++++++++++++++++----------- client/src/units/unit.ts | 20 ++---- client/views/dialogs.ejs | 37 ++++++----- client/views/unitcontrolpanel.ejs | 7 ++- src/core/include/unit.h | 20 +++++- src/core/src/scheduler.cpp | 21 ++++--- 9 files changed, 137 insertions(+), 84 deletions(-) diff --git a/client/demo.js b/client/demo.js index d00a6e8f..be18be2f 100644 --- a/client/demo.js +++ b/client/demo.js @@ -3,7 +3,7 @@ const DEMO_UNIT_DATA = { ["1"]:{ baseData: { AI: true, - name: "F-5E", + name: "KC-135", unitName: "Olympus 1-1", groupName: "Group 1", alive: true, @@ -49,7 +49,8 @@ const DEMO_UNIT_DATA = { currentTask: "Holding", activePath: undefined, targetSpeed: 400, - targetAltitude: 3000 + targetAltitude: 3000, + isTanker: true }, optionsData: { ROE: "Designated", diff --git a/client/public/stylesheets/layout.css b/client/public/stylesheets/layout.css index ed682be4..afa76477 100644 --- a/client/public/stylesheets/layout.css +++ b/client/public/stylesheets/layout.css @@ -138,16 +138,16 @@ dl.ol-data-grid dd { } .ol-dialog-footer { - border-top:1px solid var( --background-grey ); - padding-top:15px; + border-top: 1px solid var( --background-grey ); + padding-top: 15px; + display: flex; + row-gap: 10px; } .ol-dialog.scrollable .ol-dialog-content { overflow-y: auto; } - - .ol-checkbox label { align-items: center; cursor: pointer; @@ -203,6 +203,15 @@ dl.ol-data-grid dd { content: "\d7"; } +.ol-button-apply { + background: transparent; + border: 1px solid white; +} + +.ol-button-apply::before { + content: "\2713"; +} + .ol-button-settings { background-color: var( --background-slate-blue ); } diff --git a/client/src/@types/unit.d.ts b/client/src/@types/unit.d.ts index ad14a6ec..fca60a3b 100644 --- a/client/src/@types/unit.d.ts +++ b/client/src/@types/unit.d.ts @@ -43,6 +43,12 @@ interface TaskData { targetAltitude: number; isTanker: boolean; isAWACS: boolean; + radioOn: boolean; + TACANOn: boolean; + radioFrequency: number; + TACANChannel: number; + TACANXY: string; + TACANCallsign: string; } interface OptionsData { diff --git a/client/src/panels/unitcontrolpanel.ts b/client/src/panels/unitcontrolpanel.ts index 91550e75..f3c28d63 100644 --- a/client/src/panels/unitcontrolpanel.ts +++ b/client/src/panels/unitcontrolpanel.ts @@ -7,11 +7,8 @@ import { Aircraft, GroundUnit, Unit } from "../units/unit"; import { UnitDatabase } from "../units/unitdatabase"; import { Panel } from "./panel"; -// const ROEs: string[] = ["Free", "Designated free", "Designated", "Return", "Hold"]; // Full list -// const reactionsToThreat: string[] = ["None", "Passive", "Evade", "Escape", "Abort"]; // Full list - -const ROEs: string[] = [ "Hold", "Return", "Designated", "Free" ]; -const reactionsToThreat: string[] = [ "None", "Passive", "Evade" ]; +const ROEs: string[] = ["Hold", "Return", "Designated", "Free"]; +const reactionsToThreat: string[] = ["None", "Passive", "Evade"]; 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 }; @@ -23,9 +20,10 @@ const altitudeIncrements: { [key: string]: number } = { Aircraft: 2500, Helicopt export class UnitControlPanel extends Panel { #altitudeSlider: Slider; #airspeedSlider: Slider; - #expectedAltitude:number = -1; - #expectedSpeed: number = -1; + #expectedAltitude: number = -1; + #expectedSpeed: number = -1; #optionButtons: { [key: string]: HTMLButtonElement[] } = {} + #advancedSettingsDialog: HTMLElement; constructor(ID: string) { super(ID); @@ -35,7 +33,7 @@ export class UnitControlPanel extends Panel { this.#expectedAltitude = value; getUnitsManager().selectedUnitsSetAltitude(value * 0.3048) }); - + this.#airspeedSlider = new Slider("airspeed-slider", 0, 100, "kts", (value: number) => { this.#expectedSpeed = value; getUnitsManager().selectedUnitsSetSpeed(value / 1.94384) @@ -61,6 +59,8 @@ export class UnitControlPanel extends Panel { this.getElement().querySelector("#roe-buttons-container")?.append(...this.#optionButtons["ROE"]); this.getElement().querySelector("#reaction-to-threat-buttons-container")?.append(...this.#optionButtons["reactionToThreat"]); + this.#advancedSettingsDialog = document.querySelector("#advanced-settings-dialog"); + document.addEventListener("unitUpdated", (e: CustomEvent) => { if (e.detail.getSelected()) this.update() }); document.addEventListener("unitsSelection", (e: CustomEvent) => { this.show(); this.update() }); document.addEventListener("clearSelection", () => { this.hide() }); @@ -72,39 +72,32 @@ export class UnitControlPanel extends Panel { // Do this after panel is hidden (make sure there's a reset) protected onHide() { this.#expectedAltitude = -1; - this.#expectedSpeed = -1; + this.#expectedSpeed = -1; } // 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 ) { + #updateCanSetAltitudeSlider(altitude: number) { + if (this.#expectedAltitude < 0 || altitude === this.#expectedAltitude) { this.#expectedAltitude = -1; return true; } - return false; - } - - #updateCanSetSpeedSlider( altitude:number ) { - - if ( this.#expectedSpeed < 0 || altitude === this.#expectedSpeed ) { + #updateCanSetSpeedSlider(altitude: number) { + if (this.#expectedSpeed < 0 || altitude === this.#expectedSpeed) { this.#expectedSpeed = -1; return true; } - return false; - } - update() { var units = getUnitsManager().getSelectedUnits(); if (this.getElement() != null && units.length > 0) { this.#showFlightControlSliders(units); + this.#updateAdvancedSettingsDialog(units); this.getElement().querySelector("#selected-units-container")?.replaceChildren(...units.map((unit: Unit, index: number) => { let database: UnitDatabase | null; @@ -115,7 +108,7 @@ export class UnitControlPanel extends Panel { else database = null; // TODO add databases for other unit types - console.log( unit.getBaseData() ); + console.log(unit.getBaseData()); var button = document.createElement("button"); var callsign = unit.getBaseData().unitName || ""; @@ -140,16 +133,14 @@ export class UnitControlPanel extends Panel { } } - - #showFlightControlSliders(units: Unit[]) - { - if (getUnitsManager().getSelectedUnitsType() !== undefined) - this.#airspeedSlider.show() + #showFlightControlSliders(units: Unit[]) { + if (getUnitsManager().getSelectedUnitsType() !== undefined) + this.#airspeedSlider.show() else this.#airspeedSlider.hide(); - - if (getUnitsManager().getSelectedUnitsType() === "Aircraft" || getUnitsManager().getSelectedUnitsType() === "Helicopter") - this.#altitudeSlider.show() + + if (getUnitsManager().getSelectedUnitsType() === "Aircraft" || getUnitsManager().getSelectedUnitsType() === "Helicopter") + this.#altitudeSlider.show() else this.#altitudeSlider.hide(); @@ -173,8 +164,8 @@ export class UnitControlPanel extends Panel { targetSpeed *= 1.94384; - if ( this.#updateCanSetSpeedSlider( targetSpeed ) ) { - this.#airspeedSlider.setValue( targetSpeed ); + if (this.#updateCanSetSpeedSlider(targetSpeed)) { + this.#airspeedSlider.setValue(targetSpeed); } } @@ -183,8 +174,8 @@ export class UnitControlPanel extends Panel { if (targetAltitude != undefined) { targetAltitude /= 0.3048; - if ( this.#updateCanSetAltitudeSlider( targetAltitude ) ) { - this.#altitudeSlider.setValue( targetAltitude ); + if (this.#updateCanSetAltitudeSlider(targetAltitude)) { + this.#altitudeSlider.setValue(targetAltitude); } } } @@ -193,4 +184,33 @@ export class UnitControlPanel extends Panel { this.#altitudeSlider.setActive(false); } } + + #updateAdvancedSettingsDialog(units: Unit[]) + { + this.getElement().querySelector("#advanced-settings-div")?.classList.toggle("hide", units.length != 1); + + if (units.length == 1) + { + const unit = units[0]; + (this.#advancedSettingsDialog.querySelector("#unit-name")).innerText = unit.getBaseData().unitName; + + if (getUnitsManager().getSelectedUnits().length == 1){ + 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")?.querySelector("input")?.setAttribute('checked', String(unit.getTaskData().isTanker)); + this.#advancedSettingsDialog.querySelector("#tanker-checkbox")?.classList.remove("hide"); + } + else { + this.#advancedSettingsDialog.querySelector("#tanker-checkbox")?.classList.add("hide"); + } + + if (roles != undefined && Array.prototype.concat.apply([], roles)?.includes("AWACS")){ + this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.querySelector("input")?.setAttribute('checked', String(unit.getTaskData().isAWACS)); + this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.classList.remove("hide"); + } else { + this.#advancedSettingsDialog.querySelector("#AWACS-checkbox")?.classList.add("hide"); + } + } + } + } } \ No newline at end of file diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index 41efeeb5..b58114b8 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -52,6 +52,12 @@ export class Unit extends Marker { targetAltitude: 0, isTanker: false, isAWACS: false, + radioOn: false, + TACANOn: false, + radioFrequency: 0, + TACANChannel: 0, + TACANXY: "X", + TACANCallsign: "", }, optionsData: { ROE: "", @@ -409,16 +415,6 @@ export class Unit extends Marker { if (this.getBaseData().category == "Aircraft") { options.push("Refuel"); // TODO Add some way of knowing which aircraft can AAR - - if (getUnitsManager().getSelectedUnits().length == 1){ - var roles = aircraftDatabase.getByName(this.getBaseData().name)?.loadouts.map((loadout) => {return loadout.roles}) - if (roles != undefined && Array.prototype.concat.apply([], roles)?.includes("Tanker")){ - options.push(this.getTaskData().isTanker? "Stop tanker": "Start tanker"); - } - if (roles != undefined && Array.prototype.concat.apply([], roles)?.includes("AWACS")){ - options.push(this.getTaskData().isAWACS? "Stop AWACS": "Start AWACS"); - } - } } } @@ -437,10 +433,6 @@ export class Unit extends Marker { getUnitsManager().selectedUnitsAttackUnit(this.ID); if (action === "Refuel") getUnitsManager().selectedUnitsRefuel(); - if (action === "Start tanker" || action === "Stop tanker") - getUnitsManager().selectedUnitsToggleTanker(); - if (action === "Start AWACS" || action === "Stop AWACS") - getUnitsManager().selectedUnitsToggleAWACS(); } #updateMarker() { diff --git a/client/views/dialogs.ejs b/client/views/dialogs.ejs index f285d098..45615680 100644 --- a/client/views/dialogs.ejs +++ b/client/views/dialogs.ejs @@ -19,18 +19,16 @@ -
- +
-

Olympus 1-1

+

Olympus 1-1

-
- + + +
+ +
+ +
+ +
-
+
-
40
@@ -111,10 +123,9 @@
-
-
+
-
120
@@ -163,19 +173,14 @@
-
-
- -
\ No newline at end of file diff --git a/client/views/unitcontrolpanel.ejs b/client/views/unitcontrolpanel.ejs index fd37c1ff..62f781dd 100644 --- a/client/views/unitcontrolpanel.ejs +++ b/client/views/unitcontrolpanel.ejs @@ -54,9 +54,10 @@
- +
+ +
+
diff --git a/src/core/include/unit.h b/src/core/include/unit.h index 5dc3913f..2c3c15d4 100644 --- a/src/core/include/unit.h +++ b/src/core/include/unit.h @@ -105,6 +105,12 @@ public: void setTargetID(int newTargetID) { targetID = newTargetID; addMeasure(L"targetID", json::value(newTargetID));} void setIsTanker(bool newIsTanker) { isTanker = newIsTanker; addMeasure(L"isTanker", json::value(newIsTanker));} void setIsAWACS(bool newIsAWACS) { isAWACS = newIsAWACS; addMeasure(L"isAWACS", json::value(newIsAWACS));} + void setRadioOn(bool newRadioOn) { radioOn = newRadioOn; addMeasure(L"radioOn", json::value(newRadioOn)); } + void setTACANOn(bool newTACANOn) { TACANOn = newTACANOn; addMeasure(L"TACANOn", json::value(newTACANOn)); } + void setRadioFrequency(int newRadioFrequency) { radioFrequency = newRadioFrequency; addMeasure(L"radioFrequency", json::value(newRadioFrequency)); } + void setTACANChannel(int newTACANChannel) { TACANChannel = newTACANChannel; addMeasure(L"TACANChannel", json::value(newTACANChannel)); } + void setTACANXY(wstring newTACANXY) { TACANXY = newTACANXY; addMeasure(L"TACANXY", json::value(newTACANXY)); } + void setTACANCallsign(wstring newTACANCallsign) { TACANCallsign = newTACANCallsign; addMeasure(L"TACANCallsign", json::value(newTACANCallsign)); } wstring getCurrentTask() { return currentTask; } virtual double getTargetSpeed() { return targetSpeed; }; virtual double getTargetAltitude() { return targetAltitude; }; @@ -113,7 +119,13 @@ public: int getTargetID() { return targetID; } bool getIsTanker() { return isTanker; } bool getIsAWACS() { return isAWACS; } - + bool setRadioOn() { return radioOn; } + bool setTACANOn() { return TACANOn; } + int setRadioFrequency() { return radioFrequency; } + int setTACANChannel() { return TACANChannel; } + wstring setTACANXY() { return TACANXY; } + wstring setTACANCallsign() { return TACANCallsign; } + /********** Options data **********/ void setROE(wstring newROE); void setReactionToThreat(wstring newReactionToThreat); @@ -174,6 +186,12 @@ protected: int targetID = NULL; bool isTanker = false; bool isAWACS = false; + bool radioOn = false; + bool TACANOn = false; + int radioFrequency = 0; + int TACANChannel = 0; + wstring TACANXY = "X"; + wstring TACANCallsign = "TKR"; /********** Options data **********/ wstring ROE = L""; diff --git a/src/core/src/scheduler.cpp b/src/core/src/scheduler.cpp index db4e83f1..aa5a5475 100644 --- a/src/core/src/scheduler.cpp +++ b/src/core/src/scheduler.cpp @@ -256,19 +256,20 @@ void Scheduler::handleRequest(wstring key, json::value value) Unit* unit = unitsManager->getUnit(ID); unit->setState(State::REFUEL); } - else if (key.compare(L"setIsTanker") == 0) + else if (key.compare(L"setAdvancedOptions") == 0) { int ID = value[L"ID"].as_integer(); - bool state = value[L"state"].as_bool(); Unit* unit = unitsManager->getUnit(ID); - unit->setIsTanker(state); - } - else if (key.compare(L"setIsAWACS") == 0) - { - int ID = value[L"ID"].as_integer(); - bool state = value[L"state"].as_bool(); - Unit* unit = unitsManager->getUnit(ID); - unit->setIsAWACS(state); + if (unit != nullptr) + { + unit->setIsTanker(value[L"isTanker"].as_bool()); + unit->setIsAWACS(value[L"isAWACS"].as_bool()); + unit->setRadioOn(value[L"radioOn"].as_bool()); + unit->setTACANOn(value[L"TACANOn"].as_bool()); + unit->setTACANCallsign(value[L"TACANCallsign"].as_string()); + unit->setTACANChannel(value[L"TACANChannel"].as_number().to_int32()); + unit->setTACANXY(value[L"TACANXY"].as_string()); + } } else {