mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'main' into 499-spawn-menu-reorganisation
This commit is contained in:
@@ -48,6 +48,18 @@ export const emissionsCountermeasuresDescriptions: string[] = [
|
||||
"Always on (Radar and ECM always on)"
|
||||
];
|
||||
|
||||
export const shotsScatterDescriptions: string[] = [
|
||||
"When performing scenic shooting tasks like simulated firefights, will shoot with a large scatter",
|
||||
"When performing scenic shooting tasks like simulated firefights, will shoot with a medium scatter",
|
||||
"When performing scenic shooting tasks like simulated firefights, will shoot with a small scatter (Radar guided units will track shots when the enemy unit is close)"
|
||||
];
|
||||
|
||||
export const shotsIntensityDescriptions: string[] = [
|
||||
"When performing scenic shooting tasks like simulated firefights, will shoot with a low rate of fire",
|
||||
"When performing scenic shooting tasks like simulated firefights, will shoot with a medium rate of fire",
|
||||
"When performing scenic shooting tasks like simulated firefights, will shoot with a high rate of fire"
|
||||
];
|
||||
|
||||
export const minSpeedValues: { [key: string]: number } = { Aircraft: 100, Helicopter: 0, NavyUnit: 0, GroundUnit: 0 };
|
||||
export const maxSpeedValues: { [key: string]: number } = { Aircraft: 800, Helicopter: 300, NavyUnit: 60, GroundUnit: 60 };
|
||||
export const speedIncrements: { [key: string]: number } = { Aircraft: 25, Helicopter: 10, NavyUnit: 5, GroundUnit: 5 };
|
||||
@@ -221,6 +233,8 @@ export enum DataIndexes {
|
||||
hasTask,
|
||||
position,
|
||||
speed,
|
||||
horizontalVelocity,
|
||||
verticalVelocity,
|
||||
heading,
|
||||
isActiveTanker,
|
||||
isActiveAWACS,
|
||||
@@ -246,6 +260,8 @@ export enum DataIndexes {
|
||||
activePath,
|
||||
isLeader,
|
||||
operateAs,
|
||||
shotsScatter,
|
||||
shotsIntensity,
|
||||
endOfData = 255
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
export interface ContextInterface {
|
||||
|
||||
useSpawnMenu?: boolean;
|
||||
useUnitControlPanel?: boolean;
|
||||
useUnitInfoPanel?: boolean;
|
||||
}
|
||||
|
||||
export class Context {
|
||||
|
||||
constructor( config:ContextInterface ) {
|
||||
#useSpawnMenu:boolean;
|
||||
#useUnitControlPanel:boolean;
|
||||
#useUnitInfoPanel:boolean;
|
||||
|
||||
constructor( config:ContextInterface ) {
|
||||
this.#useSpawnMenu = ( config.useSpawnMenu !== false );
|
||||
this.#useUnitControlPanel = ( config.useUnitControlPanel !== false );
|
||||
this.#useUnitInfoPanel = ( config.useUnitInfoPanel !== false );
|
||||
}
|
||||
|
||||
getUseSpawnMenu() {
|
||||
return this.#useSpawnMenu;
|
||||
}
|
||||
|
||||
getUseUnitControlPanel() {
|
||||
return this.#useUnitControlPanel;
|
||||
}
|
||||
|
||||
getUseUnitInfoPanel() {
|
||||
return this.#useUnitInfoPanel;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -105,6 +105,9 @@ export class MapContextMenu extends ContextMenu {
|
||||
* @param latlng Leaflet latlng object of the mouse click
|
||||
*/
|
||||
show(x: number, y: number, latlng: LatLng) {
|
||||
if (!getApp().getCurrentContext().getUseSpawnMenu())
|
||||
return false;
|
||||
|
||||
super.show(x, y, latlng);
|
||||
|
||||
this.#aircraftSpawnMenu.setLatLng(latlng);
|
||||
|
||||
@@ -152,6 +152,8 @@ export interface UnitData {
|
||||
hasTask: boolean;
|
||||
position: LatLng;
|
||||
speed: number;
|
||||
horizontalVelocity: number;
|
||||
verticalVelocity: number;
|
||||
heading: number;
|
||||
isActiveTanker: boolean;
|
||||
isActiveAWACS: boolean;
|
||||
@@ -177,6 +179,8 @@ export interface UnitData {
|
||||
activePath: LatLng[];
|
||||
isLeader: boolean;
|
||||
operateAs: string;
|
||||
shotsScatter: number;
|
||||
shotsIntensity: number;
|
||||
}
|
||||
|
||||
export interface LoadoutItemBlueprint {
|
||||
@@ -210,12 +214,19 @@ export interface UnitBlueprint {
|
||||
muzzleVelocity?: number;
|
||||
aimTime?: number;
|
||||
shotsToFire?: number;
|
||||
shotsBaseInterval?: number;
|
||||
shotsBaseScatter?: number;
|
||||
description?: string;
|
||||
abilities?: string;
|
||||
acquisitionRange?: number;
|
||||
engagementRange?: number;
|
||||
targetingRange?: number;
|
||||
aimMethodRange?: number;
|
||||
alertnessTimeConstant?: number;
|
||||
canTargetPoint?: boolean;
|
||||
canRearm?: boolean;
|
||||
canAAA?: boolean;
|
||||
indirectFire?: boolean;
|
||||
}
|
||||
|
||||
export interface UnitSpawnOptions {
|
||||
|
||||
@@ -734,7 +734,7 @@ export class Map extends L.Map {
|
||||
const makeTitle = (isProtected:boolean) => {
|
||||
return ( isProtected ) ? "Unit type is protected and will ignore orders" : "Unit is NOT protected and will respond to orders";
|
||||
}
|
||||
this.#mapMarkerControls.forEach( (control:MapMarkerControl) => {
|
||||
this.getMapMarkerControls().forEach( (control:MapMarkerControl) => {
|
||||
const toggles = `["${control.toggles.join('","')}"]`;
|
||||
const div = document.createElement("div");
|
||||
div.className = control.protectable === true ? "protectable" : "";
|
||||
@@ -901,5 +901,9 @@ export class Map extends L.Map {
|
||||
this.#visibilityOptions[option] = ev.currentTarget.checked;
|
||||
document.dispatchEvent(new CustomEvent("mapVisibilityOptionsChanged"));
|
||||
}
|
||||
|
||||
getMapMarkerControls() {
|
||||
return this.#mapMarkerControls;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -403,19 +403,26 @@ export class OlympusApp {
|
||||
});
|
||||
|
||||
/* Try and connect with the Olympus REST server */
|
||||
document.addEventListener("tryConnection", () => {
|
||||
const form = document.querySelector("#splash-content")?.querySelector("#authentication-form");
|
||||
const username = (form?.querySelector("#username") as HTMLInputElement).value;
|
||||
const password = (form?.querySelector("#password") as HTMLInputElement).value;
|
||||
const loginForm = document.getElementById("authentication-form");
|
||||
if (loginForm instanceof HTMLFormElement) {
|
||||
loginForm.addEventListener("submit", (ev:SubmitEvent) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
const username = (loginForm.querySelector("#username") as HTMLInputElement).value;
|
||||
const password = (loginForm.querySelector("#password") as HTMLInputElement).value;
|
||||
|
||||
/* Update the user credentials */
|
||||
this.getServerManager().setCredentials(username, password);
|
||||
// Update the user credentials
|
||||
this.getServerManager().setCredentials(username, password);
|
||||
|
||||
/* Start periodically requesting updates */
|
||||
this.getServerManager().startUpdate();
|
||||
// Start periodically requesting updates
|
||||
this.getServerManager().startUpdate();
|
||||
|
||||
this.setLoginStatus("connecting");
|
||||
});
|
||||
} else {
|
||||
console.error("Unable to find login form.");
|
||||
}
|
||||
|
||||
this.setLoginStatus("connecting");
|
||||
})
|
||||
|
||||
/* Reload the page, used to mimic a restart of the app */
|
||||
document.addEventListener("reloadPage", () => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import { aircraftDatabase } from "../unit/databases/aircraftdatabase";
|
||||
import { Unit } from "../unit/unit";
|
||||
import { Panel } from "./panel";
|
||||
import { Switch } from "../controls/switch";
|
||||
import { ROEDescriptions, ROEs, altitudeIncrements, emissionsCountermeasures, emissionsCountermeasuresDescriptions, maxAltitudeValues, maxSpeedValues, minAltitudeValues, minSpeedValues, reactionsToThreat, reactionsToThreatDescriptions, speedIncrements } from "../constants/constants";
|
||||
import { ROEDescriptions, ROEs, altitudeIncrements, emissionsCountermeasures, emissionsCountermeasuresDescriptions, maxAltitudeValues, maxSpeedValues, minAltitudeValues, minSpeedValues, reactionsToThreat, reactionsToThreatDescriptions, shotsIntensityDescriptions, shotsScatterDescriptions, speedIncrements } from "../constants/constants";
|
||||
import { ftToM, knotsToMs, mToFt, msToKnots } from "../other/utils";
|
||||
import { GeneralSettings, Radio, TACAN } from "../interfaces";
|
||||
|
||||
@@ -56,9 +56,19 @@ export class UnitControlPanel extends Panel {
|
||||
return this.#createOptionButton(option, `emissions/${option.toLowerCase()}.svg`, emissionsCountermeasuresDescriptions[index],() => { getApp().getUnitsManager().selectedUnitsSetEmissionsCountermeasures(option); });
|
||||
});
|
||||
|
||||
this.#optionButtons["shotsScatter"] = [1, 2, 3].map((option: number, index: number) => {
|
||||
return this.#createOptionButton(option.toString(), `scatter/${option.toString().toLowerCase()}.svg`, shotsScatterDescriptions[index],() => { getApp().getUnitsManager().selectedUnitsSetShotsScatter(option); });
|
||||
});
|
||||
|
||||
this.#optionButtons["shotsIntensity"] = [1, 2, 3].map((option: number, index: number) => {
|
||||
return this.#createOptionButton(option.toString(), `intensity/${option.toString().toLowerCase()}.svg`, shotsIntensityDescriptions[index],() => { getApp().getUnitsManager().selectedUnitsSetShotsIntensity(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.getElement().querySelector("#shots-scatter-buttons-container")?.append(...this.#optionButtons["shotsScatter"]);
|
||||
this.getElement().querySelector("#shots-intensity-buttons-container")?.append(...this.#optionButtons["shotsIntensity"]);
|
||||
|
||||
/* Tanker */
|
||||
this.#tankerSwitch = new Switch("tanker-on-switch", (value: boolean) => {
|
||||
@@ -131,6 +141,10 @@ export class UnitControlPanel extends Panel {
|
||||
}
|
||||
|
||||
show() {
|
||||
const context = getApp().getCurrentContext();
|
||||
if ( !context.getUseUnitControlPanel() )
|
||||
return;
|
||||
|
||||
super.show();
|
||||
this.#speedTypeSwitch.resetExpectedValue();
|
||||
this.#altitudeTypeSwitch.resetExpectedValue();
|
||||
@@ -195,6 +209,8 @@ export class UnitControlPanel extends Panel {
|
||||
element.toggleAttribute("data-show-roe", !isTanker && !isAWACS);
|
||||
element.toggleAttribute("data-show-threat", (this.#selectedUnitsTypes.includes("Aircraft") || this.#selectedUnitsTypes.includes("Helicopter")) && !(this.#selectedUnitsTypes.includes("GroundUnit") || this.#selectedUnitsTypes.includes("NavyUnit")));
|
||||
element.toggleAttribute("data-show-emissions-countermeasures", (this.#selectedUnitsTypes.includes("Aircraft") || this.#selectedUnitsTypes.includes("Helicopter")) && !(this.#selectedUnitsTypes.includes("GroundUnit") || this.#selectedUnitsTypes.includes("NavyUnit")));
|
||||
element.toggleAttribute("data-show-shots-scatter", this.#selectedUnitsTypes.includes("GroundUnit")); //TODO: more refined
|
||||
element.toggleAttribute("data-show-shots-intensity", this.#selectedUnitsTypes.includes("GroundUnit")); //TODO: more refined
|
||||
element.toggleAttribute("data-show-tanker-button", getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.isTanker();}) === true);
|
||||
element.toggleAttribute("data-show-AWACS-button", getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.isAWACS();}) === true);
|
||||
element.toggleAttribute("data-show-on-off", (this.#selectedUnitsTypes.includes("GroundUnit") || this.#selectedUnitsTypes.includes("NavyUnit")) && !(this.#selectedUnitsTypes.includes("Aircraft") || this.#selectedUnitsTypes.includes("Helicopter")));
|
||||
@@ -256,6 +272,14 @@ export class UnitControlPanel extends Panel {
|
||||
button.classList.toggle("selected", this.#units.every((unit: Unit) => unit.getEmissionsCountermeasures() === button.value))
|
||||
});
|
||||
|
||||
this.#optionButtons["shotsScatter"].forEach((button: HTMLButtonElement) => {
|
||||
button.classList.toggle("selected", this.#units.every((unit: Unit) => unit.getShotsScatter().toString() === button.value))
|
||||
});
|
||||
|
||||
this.#optionButtons["shotsIntensity"].forEach((button: HTMLButtonElement) => {
|
||||
button.classList.toggle("selected", this.#units.every((unit: Unit) => unit.getShotsIntensity().toString() === button.value))
|
||||
});
|
||||
|
||||
this.#tankerSwitch.setValue(isActiveTanker, false);
|
||||
this.#AWACSSwitch.setValue(isActiveAWACAS, false);
|
||||
this.#onOffSwitch.setValue(onOff, false);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getApp } from "..";
|
||||
import { Ammo } from "../interfaces";
|
||||
import { aircraftDatabase } from "../unit/databases/aircraftdatabase";
|
||||
import { Unit } from "../unit/unit";
|
||||
@@ -92,4 +93,12 @@ export class UnitInfoPanel extends Panel {
|
||||
else
|
||||
this.hide();
|
||||
}
|
||||
|
||||
show() {
|
||||
const context = getApp().getCurrentContext();
|
||||
if ( !context.getUseUnitInfoPanel() )
|
||||
return;
|
||||
|
||||
super.show();
|
||||
}
|
||||
}
|
||||
@@ -357,6 +357,18 @@ export class ServerManager {
|
||||
this.PUT(data, callback);
|
||||
}
|
||||
|
||||
setShotsScatter(ID: number, shotsScatter: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "shotsScatter": shotsScatter }
|
||||
var data = { "setShotsScatter": command }
|
||||
this.PUT(data, callback);
|
||||
}
|
||||
|
||||
setShotsIntensity(ID: number, shotsIntensity: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "shotsIntensity": shotsIntensity }
|
||||
var data = { "setShotsIntensity": command }
|
||||
this.PUT(data, callback);
|
||||
}
|
||||
|
||||
setAdvacedOptions(ID: number, isActiveTanker: boolean, isActiveAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) {
|
||||
var command = {
|
||||
"ID": ID,
|
||||
|
||||
@@ -34,6 +34,8 @@ export class Unit extends CustomMarker {
|
||||
#hasTask: boolean = false;
|
||||
#position: LatLng = new LatLng(0, 0, 0);
|
||||
#speed: number = 0;
|
||||
#horizontalVelocity: number = 0;
|
||||
#verticalVelocity: number = 0;
|
||||
#heading: number = 0;
|
||||
#isActiveTanker: boolean = false;
|
||||
#isActiveAWACS: boolean = false;
|
||||
@@ -78,6 +80,8 @@ export class Unit extends CustomMarker {
|
||||
#activePath: LatLng[] = [];
|
||||
#isLeader: boolean = false;
|
||||
#operateAs: string = "blue";
|
||||
#shotsScatter: number = 2;
|
||||
#shotsIntensity: number = 2;
|
||||
|
||||
#selectable: boolean;
|
||||
#selected: boolean = false;
|
||||
@@ -95,47 +99,49 @@ export class Unit extends CustomMarker {
|
||||
#doubleClickTimer: number = 0;
|
||||
#hotgroup: number | null = null;
|
||||
#detectionMethods: number[] = [];
|
||||
#isProtected:boolean = false;
|
||||
|
||||
getActivePath() { return this.#activePath };
|
||||
getAlive() { return this.#alive };
|
||||
getAmmo() { return this.#ammo };
|
||||
getCoalition() { return this.#coalition };
|
||||
getContacts() { return this.#contacts };
|
||||
getHuman() { return this.#human };
|
||||
getControlled() { return this.#controlled };
|
||||
getCoalition() { return this.#coalition };
|
||||
getCountry() { return this.#country };
|
||||
getDesiredAltitude() { return this.#desiredAltitude };
|
||||
getDesiredAltitudeType() { return this.#desiredAltitudeType };
|
||||
getName() { return this.#name };
|
||||
getUnitName() { return this.#unitName };
|
||||
getGroupName() { return this.#groupName };
|
||||
getState() { return this.#state };
|
||||
getTask() { return this.#task };
|
||||
getHasTask() { return this.#hasTask };
|
||||
getPosition() { return this.#position };
|
||||
getSpeed() { return this.#speed };
|
||||
getHorizontalVelocity() { return this.#horizontalVelocity };
|
||||
getVerticalVelocity() { return this.#verticalVelocity };
|
||||
getHeading() { return this.#heading };
|
||||
getIsActiveTanker() { return this.#isActiveTanker };
|
||||
getIsActiveAWACS() { return this.#isActiveAWACS };
|
||||
getOnOff() { return this.#onOff };
|
||||
getFollowRoads() { return this.#followRoads };
|
||||
getFuel() { return this.#fuel };
|
||||
getDesiredSpeed() { return this.#desiredSpeed };
|
||||
getDesiredSpeedType() { return this.#desiredSpeedType };
|
||||
getEmissionsCountermeasures() { return this.#emissionsCountermeasures };
|
||||
getFollowRoads() { return this.#followRoads };
|
||||
getFormationOffset() { return this.#formationOffset };
|
||||
getFuel() { return this.#fuel };
|
||||
getGeneralSettings() { return this.#generalSettings };
|
||||
getGroupName() { return this.#groupName };
|
||||
getHasTask() { return this.#hasTask };
|
||||
getHeading() { return this.#heading };
|
||||
getHuman() { return this.#human };
|
||||
getIsActiveAWACS() { return this.#isActiveAWACS };
|
||||
getIsActiveTanker() { return this.#isActiveTanker };
|
||||
getIsLeader() { return this.#isLeader };
|
||||
getDesiredAltitude() { return this.#desiredAltitude };
|
||||
getDesiredAltitudeType() { return this.#desiredAltitudeType };
|
||||
getLeaderID() { return this.#leaderID };
|
||||
getName() { return this.#name };
|
||||
getOnOff() { return this.#onOff };
|
||||
getOperateAs() { return this.#operateAs };
|
||||
getPosition() { return this.#position };
|
||||
getIsProtected() { return this.#isProtected };
|
||||
getRadio() { return this.#radio };
|
||||
getReactionToThreat() { return this.#reactionToThreat };
|
||||
getROE() { return this.#ROE };
|
||||
getSpeed() { return this.#speed };
|
||||
getState() { return this.#state };
|
||||
getTACAN() { return this.#TACAN };
|
||||
getFormationOffset() { return this.#formationOffset };
|
||||
getTargetID() { return this.#targetID };
|
||||
getTargetPosition() { return this.#targetPosition };
|
||||
getTask() { return this.#task };
|
||||
getUnitName() { return this.#unitName };
|
||||
getROE() { return this.#ROE };
|
||||
getReactionToThreat() { return this.#reactionToThreat };
|
||||
getEmissionsCountermeasures() { return this.#emissionsCountermeasures };
|
||||
getTACAN() { return this.#TACAN };
|
||||
getRadio() { return this.#radio };
|
||||
getGeneralSettings() { return this.#generalSettings };
|
||||
getAmmo() { return this.#ammo };
|
||||
getContacts() { return this.#contacts };
|
||||
getActivePath() { return this.#activePath };
|
||||
getIsLeader() { return this.#isLeader };
|
||||
getOperateAs() { return this.#operateAs };
|
||||
getShotsScatter() { return this.#shotsScatter};
|
||||
getShotsIntensity() { return this.#shotsIntensity};
|
||||
|
||||
static getConstructor(type: string) {
|
||||
if (type === "GroundUnit") return GroundUnit;
|
||||
@@ -222,6 +228,8 @@ export class Unit extends CustomMarker {
|
||||
case DataIndexes.hasTask: this.#hasTask = dataExtractor.extractBool(); break;
|
||||
case DataIndexes.position: this.#position = dataExtractor.extractLatLng(); updateMarker = true; break;
|
||||
case DataIndexes.speed: this.#speed = dataExtractor.extractFloat64(); updateMarker = true; break;
|
||||
case DataIndexes.horizontalVelocity: this.#horizontalVelocity = dataExtractor.extractFloat64(); break;
|
||||
case DataIndexes.verticalVelocity: this.#verticalVelocity = dataExtractor.extractFloat64(); break;
|
||||
case DataIndexes.heading: this.#heading = dataExtractor.extractFloat64(); updateMarker = true; break;
|
||||
case DataIndexes.isActiveTanker: this.#isActiveTanker = dataExtractor.extractBool(); break;
|
||||
case DataIndexes.isActiveAWACS: this.#isActiveAWACS = dataExtractor.extractBool(); break;
|
||||
@@ -247,6 +255,8 @@ export class Unit extends CustomMarker {
|
||||
case DataIndexes.activePath: this.#activePath = dataExtractor.extractActivePath(); break;
|
||||
case DataIndexes.isLeader: this.#isLeader = dataExtractor.extractBool(); updateMarker = true; break;
|
||||
case DataIndexes.operateAs: this.#operateAs = enumToCoalition(dataExtractor.extractUInt8()); break;
|
||||
case DataIndexes.shotsScatter: this.#shotsScatter = dataExtractor.extractUInt8(); break;
|
||||
case DataIndexes.shotsIntensity: this.#shotsIntensity = dataExtractor.extractUInt8(); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,6 +296,8 @@ export class Unit extends CustomMarker {
|
||||
hasTask: this.#hasTask,
|
||||
position: this.#position,
|
||||
speed: this.#speed,
|
||||
horizontalVelocity: this.#horizontalVelocity,
|
||||
verticalVelocity: this.#verticalVelocity,
|
||||
heading: this.#heading,
|
||||
isActiveTanker: this.#isActiveTanker,
|
||||
isActiveAWACS: this.#isActiveAWACS,
|
||||
@@ -310,7 +322,9 @@ export class Unit extends CustomMarker {
|
||||
contacts: this.#contacts,
|
||||
activePath: this.#activePath,
|
||||
isLeader: this.#isLeader,
|
||||
operateAs: this.#operateAs
|
||||
operateAs: this.#operateAs,
|
||||
shotsScatter: this.#shotsScatter,
|
||||
shotsIntensity: this.#shotsIntensity
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,10 +352,6 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
}
|
||||
|
||||
setIsProtected(isProtected:boolean) {
|
||||
this.#isProtected = isProtected;
|
||||
}
|
||||
|
||||
setAlive(newAlive: boolean) {
|
||||
if (newAlive != this.#alive)
|
||||
document.dispatchEvent(new CustomEvent("unitDeath", { detail: this }));
|
||||
@@ -437,7 +447,6 @@ export class Unit extends CustomMarker {
|
||||
return this.getDatabase()?.getSpawnPointsByName(this.getName());
|
||||
}
|
||||
|
||||
|
||||
/********************** Icon *************************/
|
||||
createIcon(): void {
|
||||
/* Set the icon */
|
||||
@@ -636,10 +645,6 @@ export class Unit extends CustomMarker {
|
||||
return getApp().getMap().getBounds().contains(this.getPosition());
|
||||
}
|
||||
|
||||
canLandAtPoint() {
|
||||
return this.getCategory() === "Helicopter"; // Only choppers can do this currently
|
||||
}
|
||||
|
||||
canTargetPoint() {
|
||||
return this.getDatabase()?.getByName(this.#name)?.canTargetPoint === true;
|
||||
}
|
||||
@@ -648,6 +653,18 @@ export class Unit extends CustomMarker {
|
||||
return this.getDatabase()?.getByName(this.#name)?.canRearm === true;
|
||||
}
|
||||
|
||||
canLandAtPoint() {
|
||||
return this.getCategory() === "Helicopter";
|
||||
}
|
||||
|
||||
canAAA() {
|
||||
return this.getDatabase()?.getByName(this.#name)?.canAAA === true;
|
||||
}
|
||||
|
||||
indirectFire() {
|
||||
return this.getDatabase()?.getByName(this.#name)?.indirectFire === true;
|
||||
}
|
||||
|
||||
isTanker() {
|
||||
return this.canFulfillRole("Tanker");
|
||||
}
|
||||
@@ -823,6 +840,16 @@ export class Unit extends CustomMarker {
|
||||
getApp().getServerManager().landAtPoint(this.ID, latlng);
|
||||
}
|
||||
|
||||
setShotsScatter(shotsScatter: number) {
|
||||
if (!this.#human)
|
||||
getApp().getServerManager().setShotsScatter(this.ID, shotsScatter);
|
||||
}
|
||||
|
||||
setShotsIntensity(shotsIntensity: number) {
|
||||
if (!this.#human)
|
||||
getApp().getServerManager().setShotsIntensity(this.ID, shotsIntensity);
|
||||
}
|
||||
|
||||
/***********************************************/
|
||||
getActions(): { [key: string]: { text: string, tooltip: string, type: string } } {
|
||||
/* To be implemented by child classes */ // TODO make Unit an abstract class
|
||||
@@ -1446,7 +1473,7 @@ export class GroundUnit extends Unit {
|
||||
options["group-ground"] = { text: "Create group", tooltip: "Create a group from the selected units", type: "and" };
|
||||
}
|
||||
|
||||
if (["AAA", "flak"].includes(this.getType())) {
|
||||
if (this.canAAA()) {
|
||||
options["scenic-aaa"] = { text: "Scenic AAA", tooltip: "Shoot AAA in the air without aiming at any target, when a enemy unit gets close enough. WARNING: works correctly only on neutral units, blue or red units will aim", type: "and" };
|
||||
options["miss-aaa"] = { text: "Miss on purpose AAA", tooltip: "Shoot AAA towards the closest enemy unit, but don't aim precisely. WARNING: works correctly only on neutral units, blue or red units will aim", type: "and" };
|
||||
}
|
||||
|
||||
@@ -708,6 +708,30 @@ export class UnitsManager {
|
||||
this.#showActionMessage(selectedUnits, `unit landing at point`);
|
||||
}
|
||||
|
||||
/** Set a specific shots scatter to all the selected units
|
||||
*
|
||||
* @param shotsScatter Value to set
|
||||
*/
|
||||
selectedUnitsSetShotsScatter(shotsScatter: number) {
|
||||
var selectedUnits = this.getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: true });
|
||||
for (let idx in selectedUnits) {
|
||||
selectedUnits[idx].setShotsScatter(shotsScatter);
|
||||
}
|
||||
this.#showActionMessage(selectedUnits, `shots scatter set to ${shotsScatter}`);
|
||||
}
|
||||
|
||||
/** Set a specific shots intensity to all the selected units
|
||||
*
|
||||
* @param shotsScatter Value to set
|
||||
*/
|
||||
selectedUnitsSetShotsIntensity(shotsIntensity: number) {
|
||||
var selectedUnits = this.getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: true });
|
||||
for (let idx in selectedUnits) {
|
||||
selectedUnits[idx].setShotsIntensity(shotsIntensity);
|
||||
}
|
||||
this.#showActionMessage(selectedUnits, `shots intensity set to ${shotsIntensity}`);
|
||||
}
|
||||
|
||||
/*********************** Control operations on selected units ************************/
|
||||
/** See getUnitsCategories for more info
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user