mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge pull request #277 from Pax1601/264-add-avanced-unit-control-options
264 add avanced unit control options
This commit is contained in:
commit
0b490e4ce2
@ -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);
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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%;
|
||||
}
|
||||
31
client/src/@types/unit.d.ts
vendored
31
client/src/@types/unit.d.ts
vendored
@ -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;
|
||||
}
|
||||
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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 };
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/***********************************************/
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
local version = "v0.2.1-alpha"
|
||||
|
||||
local debug = false
|
||||
local debug = true
|
||||
|
||||
Olympus.unitCounter = 1
|
||||
Olympus.payloadRegistry = {}
|
||||
@ -427,7 +427,7 @@ function Olympus.setCommand(ID, command)
|
||||
end
|
||||
|
||||
function Olympus.setOption(ID, optionID, optionValue)
|
||||
Olympus.debug("Olympus.setOption " .. ID .. " " .. optionID .. " " .. optionValue, 2)
|
||||
Olympus.debug("Olympus.setOption " .. ID .. " " .. optionID .. " " .. tostring(optionValue), 2)
|
||||
local unit = Olympus.getUnitByID(ID)
|
||||
if unit then
|
||||
unit:getGroup():getController():setOption(optionID, optionValue)
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "framework.h"
|
||||
#include "luatools.h"
|
||||
#include "utils.h"
|
||||
#include "logger.h"
|
||||
|
||||
namespace CommandPriority {
|
||||
enum CommandPriorities { LOW, MEDIUM, HIGH };
|
||||
@ -24,6 +25,7 @@ namespace SetCommandType {
|
||||
PROHIBIT_AG = 17,
|
||||
MISSILE_ATTACK = 18,
|
||||
PROHIBIT_WP_PASS_REPORT = 19,
|
||||
ENGAGE_AIR_WEAPONS = 20,
|
||||
OPTION_RADIO_USAGE_CONTACT = 21,
|
||||
OPTION_RADIO_USAGE_ENGAGE = 22,
|
||||
OPTION_RADIO_USAGE_KILL = 23,
|
||||
@ -43,7 +45,7 @@ namespace ROE {
|
||||
}
|
||||
|
||||
namespace ReactionToThreat {
|
||||
enum ReactionToThreats {
|
||||
enum ReactionsToThreat {
|
||||
NO_REACTION = 0,
|
||||
PASSIVE_DEFENCE = 1,
|
||||
EVADE_FIRE = 2,
|
||||
@ -52,6 +54,35 @@ namespace ReactionToThreat {
|
||||
};
|
||||
}
|
||||
|
||||
namespace RadarUse {
|
||||
enum RadarUses {
|
||||
NEVER = 0,
|
||||
FOR_ATTACK_ONLY = 1,
|
||||
FOR_SEARCH_IF_REQUIRED = 2,
|
||||
FOR_CONTINUOUS_SEARCH = 3
|
||||
};
|
||||
}
|
||||
|
||||
namespace FlareUse {
|
||||
enum FlareUses {
|
||||
NEVER = 0,
|
||||
AGAINST_FIRED_MISSILE = 1,
|
||||
WHEN_FLYING_IN_SAM_WEZ = 2,
|
||||
WHEN_FLYING_NEAR_ENEMIES = 3
|
||||
};
|
||||
}
|
||||
|
||||
namespace ECMUse {
|
||||
enum ECMUses {
|
||||
NEVER_USE = 0,
|
||||
USE_IF_ONLY_LOCK_BY_RADAR = 1,
|
||||
USE_IF_DETECTED_LOCK_BY_RADAR = 2,
|
||||
ALWAYS_USE = 3
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Base command class */
|
||||
class Command
|
||||
{
|
||||
@ -243,7 +274,19 @@ public:
|
||||
SetOption(int ID, int optionID, int optionValue) :
|
||||
ID(ID),
|
||||
optionID(optionID),
|
||||
optionValue(optionValue)
|
||||
optionValue(optionValue),
|
||||
optionBool(false),
|
||||
isBoolean(false)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
|
||||
SetOption(int ID, int optionID, bool optionBool) :
|
||||
ID(ID),
|
||||
optionID(optionID),
|
||||
optionValue(0),
|
||||
optionBool(optionBool),
|
||||
isBoolean(true)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
@ -254,4 +297,6 @@ private:
|
||||
const int ID;
|
||||
const int optionID;
|
||||
const int optionValue;
|
||||
const bool optionBool;
|
||||
const bool isBoolean;
|
||||
};
|
||||
@ -9,20 +9,44 @@ namespace State
|
||||
{
|
||||
enum States
|
||||
{
|
||||
NONE = 0,
|
||||
IDLE,
|
||||
REACH_DESTINATION,
|
||||
ATTACK,
|
||||
WINGMAN,
|
||||
FOLLOW,
|
||||
LAND,
|
||||
REFUEL,
|
||||
AWACS,
|
||||
EWR,
|
||||
TANKER,
|
||||
RUN_AWAY
|
||||
TANKER
|
||||
};
|
||||
};
|
||||
|
||||
namespace Options {
|
||||
struct TACAN
|
||||
{
|
||||
bool isOn = false;
|
||||
int channel = 40;
|
||||
wstring XY = L"X";
|
||||
wstring callsign = L"TKR";
|
||||
};
|
||||
|
||||
struct Radio
|
||||
{
|
||||
int frequency = 124000000; // MHz
|
||||
int callsign = 1;
|
||||
int callsignNumber = 1;
|
||||
};
|
||||
|
||||
struct GeneralSettings
|
||||
{
|
||||
bool prohibitJettison = false;
|
||||
bool prohibitAA = false;
|
||||
bool prohibitAG = false;
|
||||
bool prohibitAfterburner = false;
|
||||
bool prohibitAirWpn = false;
|
||||
};
|
||||
}
|
||||
|
||||
class Unit
|
||||
{
|
||||
public:
|
||||
@ -30,6 +54,7 @@ public:
|
||||
~Unit();
|
||||
|
||||
/********** Public methods **********/
|
||||
void initialize(json::value json);
|
||||
int getID() { return ID; }
|
||||
void updateExportData(json::value json);
|
||||
void updateMissionData(json::value json);
|
||||
@ -98,15 +123,7 @@ public:
|
||||
void setTargetID(int newTargetID) { targetID = newTargetID; addMeasure(L"targetID", json::value(newTargetID));}
|
||||
void setIsTanker(bool newIsTanker);
|
||||
void setIsAWACS(bool newIsAWACS);
|
||||
void setTACANChannel(int newTACANChannel);
|
||||
void setTACANXY(wstring newTACANXY);
|
||||
void setTACANCallsign(wstring newTACANCallsign);
|
||||
void setTACAN();
|
||||
void setEPLRS(bool state);
|
||||
void setRadioFrequency(int newRadioFrequency);
|
||||
void setRadioCallsign(int newRadioCallsign);
|
||||
void setRadioCallsignNumber(int newRadioCallsignNumber);
|
||||
void setRadio();
|
||||
|
||||
wstring getCurrentTask() { return currentTask; }
|
||||
virtual double getTargetSpeed() { return targetSpeed; };
|
||||
virtual double getTargetAltitude() { return targetAltitude; };
|
||||
@ -115,18 +132,22 @@ public:
|
||||
int getTargetID() { return targetID; }
|
||||
bool getIsTanker() { return isTanker; }
|
||||
bool getIsAWACS() { return isAWACS; }
|
||||
int getTACANChannel() { return TACANChannel; }
|
||||
wstring getTACANXY() { return TACANXY; }
|
||||
wstring getTACANCallsign() { return TACANCallsign; }
|
||||
int getRadioFrequency() { return radioFrequency; }
|
||||
int getRadioCallsign() { return radioCallsign; }
|
||||
int getRadioCallsignNumber() { return radioCallsignNumber; }
|
||||
|
||||
/********** Options data **********/
|
||||
void setROE(wstring newROE);
|
||||
void setReactionToThreat(wstring newReactionToThreat);
|
||||
void setEmissionsCountermeasures(wstring newEmissionsCountermeasures);
|
||||
void setTACAN(Options::TACAN newTACAN);
|
||||
void setRadio(Options::Radio newradio);
|
||||
void setGeneralSettings(Options::GeneralSettings newGeneralSettings);
|
||||
void setEPLRS(bool newEPLRS);
|
||||
wstring getROE() { return ROE; }
|
||||
wstring getReactionToThreat() {return reactionToThreat;}
|
||||
wstring getReactionToThreat() { return reactionToThreat; }
|
||||
wstring getEmissionsCountermeasures() { return emissionsCountermeasures; };
|
||||
Options::TACAN getTACAN() { return TACAN; }
|
||||
Options::Radio getRadio() { return radio; }
|
||||
Options::GeneralSettings getGeneralSettings() { return generalSettings; }
|
||||
bool getEPLRS() { return EPLRS; }
|
||||
|
||||
/********** Control functions **********/
|
||||
void landAt(Coords loc);
|
||||
@ -179,19 +200,18 @@ protected:
|
||||
int targetID = NULL;
|
||||
bool isTanker = false;
|
||||
bool isAWACS = false;
|
||||
int TACANChannel = 40;
|
||||
wstring TACANXY = L"X";
|
||||
wstring TACANCallsign = L"TKR";
|
||||
int radioFrequency = 260000000; // MHz
|
||||
int radioCallsign = 1;
|
||||
int radioCallsignNumber = 1;
|
||||
|
||||
|
||||
/********** Options data **********/
|
||||
wstring ROE = L"";
|
||||
wstring reactionToThreat = L"";
|
||||
wstring ROE = L"Designated";
|
||||
wstring reactionToThreat = L"Evade";
|
||||
wstring emissionsCountermeasures = L"Defend";
|
||||
Options::TACAN TACAN;
|
||||
Options::Radio radio;
|
||||
Options::GeneralSettings generalSettings;
|
||||
bool EPLRS = false;
|
||||
|
||||
/********** State machine **********/
|
||||
int state = State::IDLE;
|
||||
int state = State::NONE;
|
||||
|
||||
/********** Other **********/
|
||||
Coords oldPosition = Coords(0); // Used to approximate speed
|
||||
|
||||
@ -185,7 +185,7 @@ void AirUnit::AIloop()
|
||||
}
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
hasTask = true;
|
||||
setHasTask(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -290,7 +290,7 @@ void AirUnit::AIloop()
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
hasTask = true;
|
||||
setHasTask(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -306,7 +306,7 @@ void AirUnit::AIloop()
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
hasTask = true;
|
||||
setHasTask(true);
|
||||
}
|
||||
else {
|
||||
setState(State::IDLE);
|
||||
|
||||
@ -62,7 +62,7 @@ wstring SpawnAircraft::getString(lua_State* L)
|
||||
optionsSS.precision(10);
|
||||
optionsSS << "{"
|
||||
<< "payloadName = \"" << payloadName << "\", "
|
||||
<< "airbaseName = \"" << airbaseName << "\","
|
||||
<< "airbaseName = \"" << airbaseName << "\", "
|
||||
<< "}";
|
||||
|
||||
std::wostringstream commandSS;
|
||||
@ -71,7 +71,7 @@ wstring SpawnAircraft::getString(lua_State* L)
|
||||
<< "\"" << coalition << "\"" << ", "
|
||||
<< "\"" << unitType << "\"" << ", "
|
||||
<< location.lat << ", "
|
||||
<< location.lng << ","
|
||||
<< location.lng << ", "
|
||||
<< optionsSS.str();
|
||||
return commandSS.str();
|
||||
}
|
||||
@ -113,7 +113,7 @@ wstring SetTask::getString(lua_State* L)
|
||||
std::wostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.setTask, "
|
||||
<< ID << ","
|
||||
<< ID << ", "
|
||||
<< task;
|
||||
|
||||
return commandSS.str();
|
||||
@ -136,7 +136,7 @@ wstring SetCommand::getString(lua_State* L)
|
||||
std::wostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.setCommand, "
|
||||
<< ID << ","
|
||||
<< ID << ", "
|
||||
<< command;
|
||||
|
||||
return commandSS.str();
|
||||
@ -147,10 +147,17 @@ wstring SetOption::getString(lua_State* L)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.setOption, "
|
||||
<< ID << ","
|
||||
<< optionID << ","
|
||||
<< optionValue;
|
||||
|
||||
if (!isBoolean) {
|
||||
commandSS << "Olympus.setOption, "
|
||||
<< ID << ", "
|
||||
<< optionID << ", "
|
||||
<< optionValue;
|
||||
} else {
|
||||
commandSS << "Olympus.setOption, "
|
||||
<< ID << ", "
|
||||
<< optionID << ", "
|
||||
<< (optionBool? "true": "false");
|
||||
}
|
||||
return commandSS.str();
|
||||
}
|
||||
@ -222,6 +222,13 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
wstring reactionToThreat = value[L"reactionToThreat"].as_string();
|
||||
unit->setReactionToThreat(reactionToThreat);
|
||||
}
|
||||
else if (key.compare(L"setEmissionsCountermeasures") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
wstring emissionsCountermeasures = value[L"emissionsCountermeasures"].as_string();
|
||||
unit->setEmissionsCountermeasures(emissionsCountermeasures);
|
||||
}
|
||||
else if (key.compare(L"landAt") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
@ -248,18 +255,33 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
if (unit != nullptr)
|
||||
{
|
||||
/* Advanced tasking */
|
||||
unit->setIsTanker(value[L"isTanker"].as_bool());
|
||||
unit->setIsAWACS(value[L"isAWACS"].as_bool());
|
||||
|
||||
unit->setTACANChannel(value[L"TACANChannel"].as_number().to_int32());
|
||||
unit->setTACANXY(value[L"TACANXY"].as_string());
|
||||
unit->setTACANCallsign(value[L"TACANCallsign"].as_string());
|
||||
unit->setTACAN();
|
||||
/* TACAN Options */
|
||||
auto TACAN = value[L"TACAN"];
|
||||
unit->setTACAN({ TACAN[L"isOn"].as_bool(),
|
||||
TACAN[L"channel"].as_number().to_int32(),
|
||||
TACAN[L"XY"].as_string(),
|
||||
TACAN[L"callsign"].as_string()
|
||||
});
|
||||
|
||||
unit->setRadioFrequency(value[L"radioFrequency"].as_number().to_int32());
|
||||
unit->setRadioCallsign(value[L"radioCallsign"].as_number().to_int32());
|
||||
unit->setRadioCallsignNumber(value[L"radioCallsignNumber"].as_number().to_int32());
|
||||
unit->setRadio();
|
||||
/* Radio Options */
|
||||
auto radio = value[L"radio"];
|
||||
unit->setRadio({ radio[L"frequency"].as_number().to_int32(),
|
||||
radio[L"callsign"].as_number().to_int32(),
|
||||
radio[L"callsignNumber"].as_number().to_int32()
|
||||
});
|
||||
|
||||
/* General Settings */
|
||||
auto generalSettings = value[L"generalSettings"];
|
||||
unit->setGeneralSettings({ generalSettings[L"prohibitJettison"].as_bool(),
|
||||
generalSettings[L"prohibitAA"].as_bool(),
|
||||
generalSettings[L"prohibitAG"].as_bool(),
|
||||
generalSettings[L"prohibitAfterburner"].as_bool(),
|
||||
generalSettings[L"prohibitAirWpn"].as_bool(),
|
||||
});
|
||||
|
||||
unit->resetActiveDestination();
|
||||
}
|
||||
|
||||
@ -15,22 +15,27 @@ using namespace GeographicLib;
|
||||
extern Scheduler* scheduler;
|
||||
extern UnitsManager* unitsManager;
|
||||
|
||||
// TODO: Make dedicated file
|
||||
bool operator==(const Options::TACAN& lhs, const Options::TACAN& rhs)
|
||||
{
|
||||
return lhs.isOn == rhs.isOn && lhs.channel == rhs.channel && lhs.XY == rhs.XY && lhs.callsign == rhs.callsign;
|
||||
}
|
||||
|
||||
bool operator==(const Options::Radio& lhs, const Options::Radio& rhs)
|
||||
{
|
||||
return lhs.frequency == rhs.frequency && lhs.callsign == rhs.callsign && lhs.callsignNumber == rhs.callsignNumber;
|
||||
}
|
||||
|
||||
bool operator==(const Options::GeneralSettings& lhs, const Options::GeneralSettings& rhs)
|
||||
{
|
||||
return lhs.prohibitAA == rhs.prohibitAA && lhs.prohibitAfterburner == rhs.prohibitAfterburner && lhs.prohibitAG == rhs.prohibitAG &&
|
||||
lhs.prohibitAirWpn == rhs.prohibitAirWpn && lhs.prohibitJettison == rhs.prohibitJettison;
|
||||
}
|
||||
|
||||
Unit::Unit(json::value json, int ID) :
|
||||
ID(ID)
|
||||
{
|
||||
log("Creating unit with ID: " + to_string(ID));
|
||||
addMeasure(L"currentState", json::value(L"Idle"));
|
||||
|
||||
addMeasure(L"TACANChannel", json::value(TACANChannel));
|
||||
addMeasure(L"TACANXY", json::value(TACANXY));
|
||||
addMeasure(L"TACANCallsign", json::value(TACANCallsign));
|
||||
|
||||
addMeasure(L"radioFrequency", json::value(radioFrequency));
|
||||
addMeasure(L"radioCallsign", json::value(radioCallsign));
|
||||
addMeasure(L"radioCallsignNumber", json::value(radioCallsignNumber));
|
||||
|
||||
addMeasure(L"ROE", json::value(L"Designated"));
|
||||
addMeasure(L"reactionToThreat", json::value(L"Evade"));
|
||||
}
|
||||
|
||||
Unit::~Unit()
|
||||
@ -38,6 +43,25 @@ Unit::~Unit()
|
||||
|
||||
}
|
||||
|
||||
void Unit::initialize(json::value json)
|
||||
{
|
||||
updateExportData(json);
|
||||
|
||||
if (getAI()) {
|
||||
/* Set the default IDLE state */
|
||||
setState(State::IDLE);
|
||||
|
||||
/* Set the default options (these are all defaults so will only affect the export data, no DCS command will be sent) */
|
||||
setROE(L"Designated");
|
||||
setReactionToThreat(L"Evade");
|
||||
setEmissionsCountermeasures(L"Defend");
|
||||
setTACAN(TACAN);
|
||||
setRadio(radio);
|
||||
setEPLRS(EPLRS);
|
||||
setGeneralSettings(generalSettings);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::addMeasure(wstring key, json::value value)
|
||||
{
|
||||
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
|
||||
@ -155,7 +179,7 @@ json::value Unit::getData(long long time)
|
||||
|
||||
/********** Task data **********/
|
||||
json[L"taskData"] = json::value::object();
|
||||
for (auto key : { L"currentState", L"currentTask", L"targetSpeed", L"targetAltitude", L"activePath", L"isTanker", L"isAWACS", L"TACANChannel", L"TACANXY", L"TACANCallsign", L"radioFrequency", L"radioCallsign", L"radioCallsignNumber" })
|
||||
for (auto key : { L"currentState", L"currentTask", L"targetSpeed", L"targetAltitude", L"activePath", L"isTanker", L"isAWACS" })
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"taskData"][key] = measures[key]->getValue();
|
||||
@ -165,7 +189,7 @@ json::value Unit::getData(long long time)
|
||||
|
||||
/********** Options data **********/
|
||||
json[L"optionsData"] = json::value::object();
|
||||
for (auto key : { L"ROE", L"reactionToThreat" })
|
||||
for (auto key : { L"ROE", L"reactionToThreat", L"emissionsCountermeasures", L"TACAN", L"radio", L"generalSettings"})
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"optionsData"][key] = measures[key]->getValue();
|
||||
@ -309,43 +333,102 @@ void Unit::setFormationOffset(Offset newFormationOffset)
|
||||
}
|
||||
|
||||
void Unit::setROE(wstring newROE) {
|
||||
ROE = newROE;
|
||||
int ROEEnum;
|
||||
if (newROE.compare(L"Free") == 0)
|
||||
ROEEnum = ROE::WEAPON_FREE;
|
||||
else if (newROE.compare(L"Designated free") == 0)
|
||||
ROEEnum = ROE::OPEN_FIRE_WEAPON_FREE;
|
||||
else if (newROE.compare(L"Designated") == 0)
|
||||
ROEEnum = ROE::OPEN_FIRE;
|
||||
else if (newROE.compare(L"Return") == 0)
|
||||
ROEEnum = ROE::RETURN_FIRE;
|
||||
else if (newROE.compare(L"Hold") == 0)
|
||||
ROEEnum = ROE::WEAPON_HOLD;
|
||||
else
|
||||
return;
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ROE, ROEEnum));
|
||||
scheduler->appendCommand(command);
|
||||
addMeasure(L"ROE", json::value(newROE));
|
||||
|
||||
if (ROE != newROE) {
|
||||
ROE = newROE;
|
||||
|
||||
int ROEEnum;
|
||||
if (ROE.compare(L"Free") == 0)
|
||||
ROEEnum = ROE::WEAPON_FREE;
|
||||
else if (ROE.compare(L"Designated free") == 0)
|
||||
ROEEnum = ROE::OPEN_FIRE_WEAPON_FREE;
|
||||
else if (ROE.compare(L"Designated") == 0)
|
||||
ROEEnum = ROE::OPEN_FIRE;
|
||||
else if (ROE.compare(L"Return") == 0)
|
||||
ROEEnum = ROE::RETURN_FIRE;
|
||||
else if (ROE.compare(L"Hold") == 0)
|
||||
ROEEnum = ROE::WEAPON_HOLD;
|
||||
else
|
||||
return;
|
||||
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ROE, ROEEnum));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setReactionToThreat(wstring newReactionToThreat) {
|
||||
reactionToThreat = newReactionToThreat;
|
||||
int reactionToThreatEnum;
|
||||
if (newReactionToThreat.compare(L"None") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::NO_REACTION;
|
||||
else if (newReactionToThreat.compare(L"Passive") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::PASSIVE_DEFENCE;
|
||||
else if (newReactionToThreat.compare(L"Evade") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::EVADE_FIRE;
|
||||
else if (newReactionToThreat.compare(L"Escape") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::BYPASS_AND_ESCAPE;
|
||||
else if (newReactionToThreat.compare(L"Abort") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::ALLOW_ABORT_MISSION;
|
||||
else
|
||||
return;
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::REACTION_ON_THREAT, reactionToThreatEnum));
|
||||
scheduler->appendCommand(command);
|
||||
addMeasure(L"reactionToThreat", json::value(newReactionToThreat));
|
||||
|
||||
if (reactionToThreat != newReactionToThreat) {
|
||||
reactionToThreat = newReactionToThreat;
|
||||
|
||||
int reactionToThreatEnum;
|
||||
if (reactionToThreat.compare(L"None") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::NO_REACTION;
|
||||
else if (reactionToThreat.compare(L"Passive") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::PASSIVE_DEFENCE;
|
||||
else if (reactionToThreat.compare(L"Evade") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::EVADE_FIRE;
|
||||
else if (reactionToThreat.compare(L"Escape") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::BYPASS_AND_ESCAPE;
|
||||
else if (reactionToThreat.compare(L"Abort") == 0)
|
||||
reactionToThreatEnum = ReactionToThreat::ALLOW_ABORT_MISSION;
|
||||
else
|
||||
return;
|
||||
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::REACTION_ON_THREAT, reactionToThreatEnum));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setEmissionsCountermeasures(wstring newEmissionsCountermeasures) {
|
||||
addMeasure(L"emissionsCountermeasures", json::value(newEmissionsCountermeasures));
|
||||
|
||||
if (emissionsCountermeasures != newEmissionsCountermeasures) {
|
||||
emissionsCountermeasures = newEmissionsCountermeasures;
|
||||
|
||||
int radarEnum;
|
||||
int flareEnum;
|
||||
int ECMEnum;
|
||||
if (emissionsCountermeasures.compare(L"Silent") == 0)
|
||||
{
|
||||
radarEnum = RadarUse::NEVER;
|
||||
flareEnum = FlareUse::NEVER;
|
||||
ECMEnum = ECMUse::NEVER_USE;
|
||||
}
|
||||
else if (emissionsCountermeasures.compare(L"Attack") == 0)
|
||||
{
|
||||
radarEnum = RadarUse::FOR_ATTACK_ONLY;
|
||||
flareEnum = FlareUse::AGAINST_FIRED_MISSILE;
|
||||
ECMEnum = ECMUse::USE_IF_ONLY_LOCK_BY_RADAR;
|
||||
}
|
||||
else if (emissionsCountermeasures.compare(L"Defend") == 0)
|
||||
{
|
||||
radarEnum = RadarUse::FOR_SEARCH_IF_REQUIRED;
|
||||
flareEnum = FlareUse::WHEN_FLYING_IN_SAM_WEZ;
|
||||
ECMEnum = ECMUse::USE_IF_DETECTED_LOCK_BY_RADAR;
|
||||
}
|
||||
else if (emissionsCountermeasures.compare(L"Free") == 0)
|
||||
{
|
||||
radarEnum = RadarUse::FOR_CONTINUOUS_SEARCH;
|
||||
flareEnum = FlareUse::WHEN_FLYING_NEAR_ENEMIES;
|
||||
ECMEnum = ECMUse::ALWAYS_USE;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
Command* command;
|
||||
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::RADAR_USING, radarEnum));
|
||||
scheduler->appendCommand(command);
|
||||
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::FLARE_USING, flareEnum));
|
||||
scheduler->appendCommand(command);
|
||||
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ECM_USING, ECMEnum));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::landAt(Coords loc) {
|
||||
@ -364,93 +447,131 @@ void Unit::setIsAWACS(bool newIsAWACS) {
|
||||
isAWACS = newIsAWACS;
|
||||
resetTask();
|
||||
addMeasure(L"isAWACS", json::value(newIsAWACS));
|
||||
setEPLRS(true);
|
||||
setEPLRS(isAWACS);
|
||||
}
|
||||
|
||||
void Unit::setTACANChannel(int newTACANChannel) {
|
||||
TACANChannel = newTACANChannel;
|
||||
addMeasure(L"TACANChannel", json::value(newTACANChannel));
|
||||
}
|
||||
void Unit::setTACAN(Options::TACAN newTACAN) {
|
||||
auto json = json::value();
|
||||
json[L"isOn"] = json::value(newTACAN.isOn);
|
||||
json[L"channel"] = json::value(newTACAN.channel);
|
||||
json[L"XY"] = json::value(newTACAN.XY);
|
||||
json[L"callsign"] = json::value(newTACAN.callsign);
|
||||
addMeasure(L"TACAN", json);
|
||||
|
||||
void Unit::setTACANXY(wstring newTACANXY) {
|
||||
TACANXY = newTACANXY;
|
||||
addMeasure(L"TACANXY", json::value(newTACANXY));
|
||||
}
|
||||
void Unit::setTACANCallsign(wstring newTACANCallsign) {
|
||||
TACANCallsign = newTACANCallsign;
|
||||
addMeasure(L"TACANCallsign", json::value(newTACANCallsign));
|
||||
}
|
||||
|
||||
void Unit::setRadioFrequency(int newRadioFrequency) {
|
||||
radioFrequency = newRadioFrequency;
|
||||
addMeasure(L"radioFrequency", json::value(newRadioFrequency));
|
||||
}
|
||||
|
||||
void Unit::setRadioCallsign(int newRadioCallsign) {
|
||||
radioCallsign = newRadioCallsign;
|
||||
addMeasure(L"radioCallsign", json::value(newRadioCallsign));
|
||||
}
|
||||
|
||||
void Unit::setRadioCallsignNumber(int newRadioCallsignNumber) {
|
||||
radioCallsignNumber = newRadioCallsignNumber;
|
||||
addMeasure(L"radioCallsignNumber", json::value(newRadioCallsignNumber));
|
||||
}
|
||||
|
||||
void Unit::setEPLRS(bool state)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
commandSS << "{"
|
||||
<< "id = 'EPLRS',"
|
||||
<< "params = {"
|
||||
<< "value = " << (state? "true": "false") << ", "
|
||||
<< "}"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
|
||||
void Unit::setTACAN()
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
commandSS << "{"
|
||||
<< "id = 'ActivateBeacon',"
|
||||
<< "params = {"
|
||||
<< "type = " << ((TACANXY.compare(L"X") == 0)? 4: 5) << ","
|
||||
<< "system = 3,"
|
||||
<< "name = \"Olympus_TACAN\","
|
||||
<< "callsign = \"" << TACANCallsign << "\", "
|
||||
<< "frequency = " << TACANChannelToFrequency(TACANChannel, TACANXY) << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
|
||||
void Unit::setRadio()
|
||||
{
|
||||
if (TACAN != newTACAN)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
commandSS << "{"
|
||||
<< "id = 'SetFrequency',"
|
||||
<< "params = {"
|
||||
<< "modulation = 0," // TODO Allow selection
|
||||
<< "frequency = " << radioFrequency << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
TACAN = newTACAN;
|
||||
if (TACAN.isOn) {
|
||||
std::wostringstream commandSS;
|
||||
commandSS << "{"
|
||||
<< "id = 'ActivateBeacon',"
|
||||
<< "params = {"
|
||||
<< "type = " << ((TACAN.XY.compare(L"X") == 0) ? 4 : 5) << ","
|
||||
<< "system = 3,"
|
||||
<< "name = \"Olympus_TACAN\","
|
||||
<< "callsign = \"" << TACAN.callsign << "\", "
|
||||
<< "frequency = " << TACANChannelToFrequency(TACAN.channel, TACAN.XY) << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
else {
|
||||
std::wostringstream commandSS;
|
||||
commandSS << "{"
|
||||
<< "id = 'DeactivateBeacon',"
|
||||
<< "params = {"
|
||||
<< "}"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setRadio(Options::Radio newRadio) {
|
||||
|
||||
auto json = json::value();
|
||||
json[L"frequency"] = json::value(newRadio.frequency);
|
||||
json[L"callsign"] = json::value(newRadio.callsign);
|
||||
json[L"callsignNumber"] = json::value(newRadio.callsignNumber);
|
||||
addMeasure(L"radio", json);
|
||||
|
||||
if (radio != newRadio)
|
||||
{
|
||||
radio = newRadio;
|
||||
|
||||
std::wostringstream commandSS;
|
||||
Command* command;
|
||||
|
||||
commandSS << "{"
|
||||
<< "id = 'SetCallsign',"
|
||||
<< "params = {"
|
||||
<< "callname = " << radioCallsign << ","
|
||||
<< "number = " << radioCallsignNumber << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
<< "id = 'SetFrequency',"
|
||||
<< "params = {"
|
||||
<< "modulation = 0," // TODO Allow selection
|
||||
<< "frequency = " << radio.frequency << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
|
||||
// Clear the stringstream
|
||||
commandSS.str(wstring());
|
||||
|
||||
commandSS << "{"
|
||||
<< "id = 'SetCallsign',"
|
||||
<< "params = {"
|
||||
<< "callname = " << radio.callsign << ","
|
||||
<< "number = " << radio.callsignNumber << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::setEPLRS(bool newEPLRS)
|
||||
{
|
||||
//addMeasure(L"EPLRS", json::value(newEPLRS));
|
||||
//
|
||||
//if (EPLRS != newEPLRS) {
|
||||
// EPLRS = newEPLRS;
|
||||
//
|
||||
// std::wostringstream commandSS;
|
||||
// commandSS << "{"
|
||||
// << "id = 'EPLRS',"
|
||||
// << "params = {"
|
||||
// << "value = " << (EPLRS ? "true" : "false") << ", "
|
||||
// << "}"
|
||||
// << "}";
|
||||
// Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
// scheduler->appendCommand(command);
|
||||
//}
|
||||
}
|
||||
|
||||
void Unit::setGeneralSettings(Options::GeneralSettings newGeneralSettings) {
|
||||
|
||||
auto json = json::value();
|
||||
json[L"prohibitJettison"] = json::value(newGeneralSettings.prohibitJettison);
|
||||
json[L"prohibitAA"] = json::value(newGeneralSettings.prohibitAA);
|
||||
json[L"prohibitAG"] = json::value(newGeneralSettings.prohibitAG);
|
||||
json[L"prohibitAfterburner"] = json::value(newGeneralSettings.prohibitAfterburner);
|
||||
json[L"prohibitAirWpn"] = json::value(newGeneralSettings.prohibitAirWpn);
|
||||
addMeasure(L"generalSettings", json);
|
||||
|
||||
if (generalSettings != newGeneralSettings)
|
||||
{
|
||||
generalSettings = newGeneralSettings;
|
||||
|
||||
Command* command;
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AA, generalSettings.prohibitAA));
|
||||
scheduler->appendCommand(command);
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AG, generalSettings.prohibitAG));
|
||||
scheduler->appendCommand(command);
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_JETT, generalSettings.prohibitJettison));
|
||||
scheduler->appendCommand(command);
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AB, generalSettings.prohibitAfterburner));
|
||||
scheduler->appendCommand(command);
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ENGAGE_AIR_WEAPONS, !generalSettings.prohibitAirWpn));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,11 +64,14 @@ void UnitsManager::updateExportData(lua_State* L)
|
||||
units[ID] = dynamic_cast<Unit*>(new Bomb(p.second, ID));
|
||||
}
|
||||
}
|
||||
/* Initialize the unit if creation was successfull */
|
||||
if (units.count(ID) != 0)
|
||||
units[ID]->initialize(p.second);
|
||||
}
|
||||
/* Update the unit if present*/
|
||||
if (units.count(ID) != 0)
|
||||
{
|
||||
units[ID]->updateExportData(p.second);
|
||||
else {
|
||||
/* Update the unit if present*/
|
||||
if (units.count(ID) != 0)
|
||||
units[ID]->updateExportData(p.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user