mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'main' into 524-units-will-not-perform-scenic-aaa-until-the-operate-as-toggle-is-toggled
This commit is contained in:
579
client/@types/olympus/index.d.ts
vendored
579
client/@types/olympus/index.d.ts
vendored
@@ -13,11 +13,11 @@ declare module "contextmenus/contextmenu" {
|
||||
constructor(ID: string);
|
||||
/** Show the contextmenu on top of the map, usually at the location where the user has clicked on it.
|
||||
*
|
||||
* @param x X screen coordinate of the top left corner of the context menu
|
||||
* @param y Y screen coordinate of the top left corner of the context menu
|
||||
* @param latlng Leaflet latlng object of the mouse click
|
||||
* @param x X screen coordinate of the top left corner of the context menu. If undefined, use the old value
|
||||
* @param y Y screen coordinate of the top left corner of the context menu. If undefined, use the old value
|
||||
* @param latlng Leaflet latlng object of the mouse click. If undefined, use the old value
|
||||
*/
|
||||
show(x: number, y: number, latlng: LatLng): void;
|
||||
show(x?: number | undefined, y?: number | undefined, latlng?: LatLng | undefined): void;
|
||||
/** Hide the contextmenu
|
||||
*
|
||||
*/
|
||||
@@ -83,7 +83,7 @@ declare module "controls/switch" {
|
||||
}
|
||||
declare module "constants/constants" {
|
||||
import { LatLng, LatLngBounds } from "leaflet";
|
||||
import { MapMarkerControl } from "map/map";
|
||||
import { MapMarkerVisibilityControl } from "map/map";
|
||||
export const UNITS_URI = "units";
|
||||
export const WEAPONS_URI = "weapons";
|
||||
export const LOGS_URI = "logs";
|
||||
@@ -195,7 +195,7 @@ declare module "constants/constants" {
|
||||
export const visibilityControls: string[];
|
||||
export const visibilityControlsTypes: string[][];
|
||||
export const visibilityControlsTooltips: string[];
|
||||
export const MAP_MARKER_CONTROLS: MapMarkerControl[];
|
||||
export const MAP_MARKER_CONTROLS: MapMarkerVisibilityControl[];
|
||||
export const IADSTypes: string[];
|
||||
export const IADSDensities: {
|
||||
[key: string]: number;
|
||||
@@ -264,6 +264,7 @@ declare module "constants/constants" {
|
||||
export const MGRS_PRECISION_1M = 6;
|
||||
export const DELETE_CYCLE_TIME = 0.05;
|
||||
export const DELETE_SLOW_THRESHOLD = 50;
|
||||
export const GROUPING_ZOOM_TRANSITION = 13;
|
||||
}
|
||||
declare module "map/markers/custommarker" {
|
||||
import { Map, Marker } from "leaflet";
|
||||
@@ -651,14 +652,14 @@ declare module "interfaces" {
|
||||
declare module "unit/databases/unitdatabase" {
|
||||
import { LatLng } from "leaflet";
|
||||
import { UnitBlueprint } from "interfaces";
|
||||
export class UnitDatabase {
|
||||
export abstract class UnitDatabase {
|
||||
#private;
|
||||
blueprints: {
|
||||
[key: string]: UnitBlueprint;
|
||||
};
|
||||
constructor(url?: string);
|
||||
load(callback: CallableFunction): void;
|
||||
getCategory(): string;
|
||||
abstract getCategory(): string;
|
||||
getByName(name: string): UnitBlueprint | null;
|
||||
getByLabel(label: string): UnitBlueprint | null;
|
||||
getBlueprints(includeDisabled?: boolean): {
|
||||
@@ -679,6 +680,7 @@ declare module "unit/databases/unitdatabase" {
|
||||
generateTestGrid(initialPosition: LatLng): void;
|
||||
getSpawnPointsByLabel(label: string): number;
|
||||
getSpawnPointsByName(name: string): number;
|
||||
getUnkownUnit(name: string): UnitBlueprint;
|
||||
}
|
||||
}
|
||||
declare module "unit/databases/aircraftdatabase" {
|
||||
@@ -774,7 +776,7 @@ declare module "other/utils" {
|
||||
ranges?: string[];
|
||||
eras?: string[];
|
||||
}): UnitBlueprint | null;
|
||||
export function getMarkerCategoryByName(name: string): "aircraft" | "helicopter" | "groundunit-other" | "navyunit" | "groundunit";
|
||||
export function getMarkerCategoryByName(name: string): "aircraft" | "helicopter" | "groundunit-sam" | "navyunit" | "groundunit-other";
|
||||
export function getUnitDatabaseByCategory(category: string): import("unit/databases/aircraftdatabase").AircraftDatabase | import("unit/databases/helicopterdatabase").HelicopterDatabase | import("unit/databases/groundunitdatabase").GroundUnitDatabase | import("unit/databases/navyunitdatabase").NavyUnitDatabase | null;
|
||||
export function base64ToBytes(base64: string): ArrayBufferLike;
|
||||
export function enumToState(state: number): string;
|
||||
@@ -918,28 +920,6 @@ declare module "contextmenus/mapcontextmenu" {
|
||||
setCoalitionArea(coalitionArea: CoalitionArea): void;
|
||||
}
|
||||
}
|
||||
declare module "contextmenus/unitcontextmenu" {
|
||||
import { ContextMenu } from "contextmenus/contextmenu";
|
||||
/** The UnitContextMenu is shown when the user rightclicks on a unit. It dynamically presents the user with possible actions to perform on the unit. */
|
||||
export class UnitContextMenu extends ContextMenu {
|
||||
/**
|
||||
*
|
||||
* @param ID - the ID of the HTML element which will contain the context menu
|
||||
*/
|
||||
constructor(ID: string);
|
||||
/** Set the options that will be presented to the user in the contextmenu
|
||||
*
|
||||
* @param options Dictionary element containing the text and tooltip of the options shown in the menu
|
||||
* @param callback Callback that will be called when the user clicks on one of the options
|
||||
*/
|
||||
setOptions(options: {
|
||||
[key: string]: {
|
||||
text: string;
|
||||
tooltip: string;
|
||||
};
|
||||
}, callback: CallableFunction): void;
|
||||
}
|
||||
}
|
||||
declare module "map/markers/targetmarker" {
|
||||
import { LatLngExpression, MarkerOptions } from "leaflet";
|
||||
import { CustomMarker } from "map/markers/custommarker";
|
||||
@@ -1069,18 +1049,30 @@ declare module "map/rangecircle" {
|
||||
_updatePath(): void;
|
||||
}
|
||||
}
|
||||
declare module "unit/group" {
|
||||
import { Unit } from "unit/unit";
|
||||
export class Group {
|
||||
#private;
|
||||
constructor(name: string);
|
||||
getName(): string;
|
||||
addMember(member: Unit): void;
|
||||
removeMember(member: Unit): void;
|
||||
getMembers(): Unit[];
|
||||
getLeader(): Unit | undefined;
|
||||
}
|
||||
}
|
||||
declare module "unit/unit" {
|
||||
import { LatLng, Map } from 'leaflet';
|
||||
import { CustomMarker } from "map/markers/custommarker";
|
||||
import { UnitDatabase } from "unit/databases/unitdatabase";
|
||||
import { DataExtractor } from "server/dataextractor";
|
||||
import { Ammo, Contact, GeneralSettings, ObjectIconOptions, Offset, Radio, TACAN, UnitData } from "interfaces";
|
||||
import { Group } from "unit/group";
|
||||
import { ContextActionSet } from "unit/contextactionset";
|
||||
/**
|
||||
* Unit class which controls unit behaviour
|
||||
*
|
||||
* Just about everything is a unit - even missiles!
|
||||
*/
|
||||
export class Unit extends CustomMarker {
|
||||
export abstract class Unit extends CustomMarker {
|
||||
#private;
|
||||
ID: number;
|
||||
getAlive(): boolean;
|
||||
@@ -1126,33 +1118,50 @@ declare module "unit/unit" {
|
||||
getShotsScatter(): number;
|
||||
getShotsIntensity(): number;
|
||||
getHealth(): number;
|
||||
static getConstructor(type: string): typeof GroundUnit | undefined;
|
||||
static getConstructor(type: string): typeof Aircraft | undefined;
|
||||
constructor(ID: number);
|
||||
getCategory(): string;
|
||||
/********************** Unit data *************************/
|
||||
setData(dataExtractor: DataExtractor): void;
|
||||
drawLines(): void;
|
||||
/** Get unit data collated into an object
|
||||
/********************** Abstract methods *************************/
|
||||
/** Get the unit category string
|
||||
*
|
||||
* @returns object populated by unit information which can also be retrieved using getters
|
||||
* @returns string The unit category
|
||||
*/
|
||||
getData(): UnitData;
|
||||
/**
|
||||
*
|
||||
* @returns string containing the marker category
|
||||
*/
|
||||
getMarkerCategory(): string;
|
||||
/** Get a database of information also in this unit's category
|
||||
*
|
||||
* @returns UnitDatabase
|
||||
*/
|
||||
getDatabase(): UnitDatabase | null;
|
||||
abstract getCategory(): string;
|
||||
/** Get the icon options
|
||||
* Used to configure how the marker appears on the map
|
||||
*
|
||||
* @returns ObjectIconOptions
|
||||
*/
|
||||
getIconOptions(): ObjectIconOptions;
|
||||
abstract getIconOptions(): ObjectIconOptions;
|
||||
/** Get the actions that this unit can perform
|
||||
*
|
||||
*/
|
||||
abstract appendContextActions(contextActionSet: ContextActionSet, targetUnit: Unit | null, targetPosition: LatLng | null): void;
|
||||
/**
|
||||
*
|
||||
* @returns string containing the marker category
|
||||
*/
|
||||
abstract getMarkerCategory(): string;
|
||||
/**
|
||||
*
|
||||
* @returns string containing the default marker
|
||||
*/
|
||||
abstract getDefaultMarker(): string;
|
||||
/********************** Unit data *************************/
|
||||
/** This function is called by the units manager to update all the data coming from the backend. It reads the binary raw data using a DataExtractor
|
||||
*
|
||||
* @param dataExtractor The DataExtractor object pointing to the binary buffer which contains the raw data coming from the backend
|
||||
*/
|
||||
setData(dataExtractor: DataExtractor): void;
|
||||
/** Get unit data collated into an object
|
||||
*
|
||||
* @returns object populated by unit information which can also be retrieved using getters
|
||||
*/
|
||||
getData(): UnitData;
|
||||
/** Get a database of information also in this unit's category
|
||||
*
|
||||
* @returns UnitDatabase
|
||||
*/
|
||||
getDatabase(): UnitDatabase | null;
|
||||
/** Set the unit as alive or dead
|
||||
*
|
||||
* @param newAlive (boolean) true = alive, false = dead
|
||||
@@ -1168,17 +1177,7 @@ declare module "unit/unit" {
|
||||
* @returns boolean
|
||||
*/
|
||||
getSelected(): boolean;
|
||||
/** Set whether this unit is selectable
|
||||
*
|
||||
* @param selectable (boolean)
|
||||
*/
|
||||
setSelectable(selectable: boolean): void;
|
||||
/** Get whether this unit is selectable
|
||||
*
|
||||
* @returns boolean
|
||||
*/
|
||||
getSelectable(): boolean;
|
||||
/** Set the number of the hotgroup to which the unit belongs
|
||||
/** Set the number of the hotgroup to which the unit belongss
|
||||
*
|
||||
* @param hotgroup (number)
|
||||
*/
|
||||
@@ -1203,6 +1202,11 @@ declare module "unit/unit" {
|
||||
* @returns Unit[]
|
||||
*/
|
||||
getGroupMembers(): Unit[];
|
||||
/** Return the leader of the group
|
||||
*
|
||||
* @returns Unit The leader of the group
|
||||
*/
|
||||
getGroupLeader(): Unit | null | undefined;
|
||||
/** Returns whether the user is allowed to command this unit, based on coalition
|
||||
*
|
||||
* @returns boolean
|
||||
@@ -1210,6 +1214,11 @@ declare module "unit/unit" {
|
||||
belongsToCommandedCoalition(): boolean;
|
||||
getType(): string;
|
||||
getSpawnPoints(): number | undefined;
|
||||
getDatabaseEntry(): import("interfaces").UnitBlueprint | undefined;
|
||||
getGroup(): Group | null;
|
||||
setGroup(group: Group | null): void;
|
||||
drawLines(): void;
|
||||
checkZoomRedraw(): boolean;
|
||||
/********************** Icon *************************/
|
||||
createIcon(): void;
|
||||
/********************** Visibility *************************/
|
||||
@@ -1223,9 +1232,8 @@ declare module "unit/unit" {
|
||||
isInViewport(): boolean;
|
||||
canTargetPoint(): boolean;
|
||||
canRearm(): boolean;
|
||||
canLandAtPoint(): boolean;
|
||||
canAAA(): boolean;
|
||||
indirectFire(): boolean;
|
||||
isIndirectFire(): boolean;
|
||||
isTanker(): boolean;
|
||||
isAWACS(): boolean;
|
||||
/********************** Unit commands *************************/
|
||||
@@ -1264,19 +1272,12 @@ declare module "unit/unit" {
|
||||
setShotsScatter(shotsScatter: number): void;
|
||||
setShotsIntensity(shotsIntensity: number): void;
|
||||
/***********************************************/
|
||||
getActions(): {
|
||||
[key: string]: {
|
||||
text: string;
|
||||
tooltip: string;
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
executeAction(e: any, action: string): void;
|
||||
/***********************************************/
|
||||
onAdd(map: Map): this;
|
||||
getActionOptions(): {};
|
||||
onGroupChanged(member: Unit): void;
|
||||
showFollowOptions(units: Unit[]): void;
|
||||
applyFollowOptions(formation: string, units: Unit[]): void;
|
||||
}
|
||||
export class AirUnit extends Unit {
|
||||
export abstract class AirUnit extends Unit {
|
||||
getIconOptions(): {
|
||||
showState: boolean;
|
||||
showVvi: boolean;
|
||||
@@ -1290,21 +1291,21 @@ declare module "unit/unit" {
|
||||
showCallsign: boolean;
|
||||
rotateToHeading: boolean;
|
||||
};
|
||||
getActions(): {
|
||||
[key: string]: {
|
||||
text: string;
|
||||
tooltip: string;
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
appendContextActions(contextActionSet: ContextActionSet, targetUnit: Unit | null, targetPosition: LatLng | null): void;
|
||||
}
|
||||
export class Aircraft extends AirUnit {
|
||||
constructor(ID: number);
|
||||
getCategory(): string;
|
||||
appendContextActions(contextActionSet: ContextActionSet, targetUnit: Unit | null, targetPosition: LatLng | null): void;
|
||||
getMarkerCategory(): string;
|
||||
getDefaultMarker(): string;
|
||||
}
|
||||
export class Helicopter extends AirUnit {
|
||||
constructor(ID: number);
|
||||
getCategory(): string;
|
||||
appendContextActions(contextActionSet: ContextActionSet, targetUnit: Unit | null, targetPosition: LatLng | null): void;
|
||||
getMarkerCategory(): string;
|
||||
getDefaultMarker(): string;
|
||||
}
|
||||
export class GroundUnit extends Unit {
|
||||
constructor(ID: number);
|
||||
@@ -1321,15 +1322,13 @@ declare module "unit/unit" {
|
||||
showCallsign: boolean;
|
||||
rotateToHeading: boolean;
|
||||
};
|
||||
getActions(): {
|
||||
[key: string]: {
|
||||
text: string;
|
||||
tooltip: string;
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
appendContextActions(contextActionSet: ContextActionSet, targetUnit: Unit | null, targetPosition: LatLng | null): void;
|
||||
getCategory(): string;
|
||||
getType(): string;
|
||||
getDatabaseEntry(): import("interfaces").UnitBlueprint | undefined;
|
||||
checkZoomRedraw(): boolean;
|
||||
getMarkerCategory(): "groundunit-sam" | "groundunit";
|
||||
getDefaultMarker(): string;
|
||||
}
|
||||
export class NavyUnit extends Unit {
|
||||
constructor(ID: number);
|
||||
@@ -1346,16 +1345,59 @@ declare module "unit/unit" {
|
||||
showCallsign: boolean;
|
||||
rotateToHeading: boolean;
|
||||
};
|
||||
getActions(): {
|
||||
[key: string]: {
|
||||
text: string;
|
||||
tooltip: string;
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
getMarkerCategory(): string;
|
||||
appendContextActions(contextActionSet: ContextActionSet, targetUnit: Unit | null, targetPosition: LatLng | null): void;
|
||||
getCategory(): string;
|
||||
getType(): string;
|
||||
getMarkerCategory(): string;
|
||||
getDefaultMarker(): string;
|
||||
}
|
||||
}
|
||||
declare module "unit/contextaction" {
|
||||
import { Unit } from "unit/unit";
|
||||
export interface ContextActionOptions {
|
||||
isScenic?: boolean;
|
||||
}
|
||||
export class ContextAction {
|
||||
#private;
|
||||
constructor(id: string, label: string, description: string, callback: CallableFunction, hideContextAfterExecution: boolean | undefined, options: ContextActionOptions);
|
||||
addUnit(unit: Unit): void;
|
||||
getId(): string;
|
||||
getLabel(): string;
|
||||
getOptions(): ContextActionOptions;
|
||||
getDescription(): string;
|
||||
getCallback(): CallableFunction | null;
|
||||
executeCallback(): void;
|
||||
getHideContextAfterExecution(): boolean;
|
||||
}
|
||||
}
|
||||
declare module "unit/contextactionset" {
|
||||
import { ContextAction, ContextActionOptions } from "unit/contextaction";
|
||||
import { Unit } from "unit/unit";
|
||||
export class ContextActionSet {
|
||||
#private;
|
||||
constructor();
|
||||
addContextAction(unit: Unit, id: string, label: string, description: string, callback: CallableFunction, hideContextAfterExecution?: boolean, options?: ContextActionOptions): void;
|
||||
getContextActions(): {
|
||||
[key: string]: ContextAction;
|
||||
};
|
||||
}
|
||||
}
|
||||
declare module "contextmenus/unitcontextmenu" {
|
||||
import { ContextActionSet } from "unit/contextactionset";
|
||||
import { ContextMenu } from "contextmenus/contextmenu";
|
||||
/** The UnitContextMenu is shown when the user rightclicks on a unit. It dynamically presents the user with possible actions to perform on the unit. */
|
||||
export class UnitContextMenu extends ContextMenu {
|
||||
/**
|
||||
*
|
||||
* @param ID - the ID of the HTML element which will contain the context menu
|
||||
*/
|
||||
constructor(ID: string);
|
||||
/** Set the options that will be presented to the user in the contextmenu
|
||||
*
|
||||
* @param options Dictionary element containing the text and tooltip of the options shown in the menu
|
||||
* @param callback Callback that will be called when the user clicks on one of the options
|
||||
*/
|
||||
setContextActions(contextActionSet: ContextActionSet): void;
|
||||
}
|
||||
}
|
||||
declare module "contextmenus/airbasecontextmenu" {
|
||||
@@ -1457,7 +1499,7 @@ declare module "contextmenus/airbasespawnmenu" {
|
||||
* @param x X screen coordinate of the top left corner of the context menu
|
||||
* @param y Y screen coordinate of the top left corner of the context menu
|
||||
*/
|
||||
show(x: number, y: number): void;
|
||||
show(x: number | undefined, y: number | undefined): void;
|
||||
/** Sets the airbase at which the new unit will be spawned
|
||||
*
|
||||
* @param airbase The airbase at which the new unit will be spawned. Note: if the airbase has no suitable parking spots, the airplane may be spawned on the runway, or spawning may fail.
|
||||
@@ -1465,8 +1507,100 @@ declare module "contextmenus/airbasespawnmenu" {
|
||||
setAirbase(airbase: Airbase): void;
|
||||
}
|
||||
}
|
||||
declare module "map/touchboxselect" {
|
||||
export var TouchBoxSelect: (new (...args: any[]) => any) & typeof import("leaflet").Class;
|
||||
}
|
||||
declare module "map/markers/destinationpreviewHandle" {
|
||||
import { LatLng } from "leaflet";
|
||||
import { CustomMarker } from "map/markers/custommarker";
|
||||
export class DestinationPreviewHandle extends CustomMarker {
|
||||
constructor(latlng: LatLng);
|
||||
createIcon(): void;
|
||||
}
|
||||
}
|
||||
declare module "map/map" {
|
||||
import * as L from "leaflet";
|
||||
import { MapContextMenu } from "contextmenus/mapcontextmenu";
|
||||
import { UnitContextMenu } from "contextmenus/unitcontextmenu";
|
||||
import { AirbaseContextMenu } from "contextmenus/airbasecontextmenu";
|
||||
import { Airbase } from "mission/airbase";
|
||||
import { Unit } from "unit/unit";
|
||||
import { TemporaryUnitMarker } from "map/markers/temporaryunitmarker";
|
||||
import { CoalitionArea } from "map/coalitionarea/coalitionarea";
|
||||
import { CoalitionAreaContextMenu } from "contextmenus/coalitionareacontextmenu";
|
||||
import { AirbaseSpawnContextMenu } from "contextmenus/airbasespawnmenu";
|
||||
export type MapMarkerVisibilityControl = {
|
||||
"image": string;
|
||||
"isProtected"?: boolean;
|
||||
"name": string;
|
||||
"protectable"?: boolean;
|
||||
"toggles": string[];
|
||||
"tooltip": string;
|
||||
};
|
||||
export class Map extends L.Map {
|
||||
#private;
|
||||
/**
|
||||
*
|
||||
* @param ID - the ID of the HTML element which will contain the context menu
|
||||
*/
|
||||
constructor(ID: string);
|
||||
addVisibilityOption(option: string, defaultValue: boolean): void;
|
||||
setLayer(layerName: string): void;
|
||||
getLayers(): string[];
|
||||
setState(state: string): void;
|
||||
getState(): string;
|
||||
deselectAllCoalitionAreas(): void;
|
||||
deleteCoalitionArea(coalitionArea: CoalitionArea): void;
|
||||
setHiddenType(key: string, value: boolean): void;
|
||||
getHiddenTypes(): string[];
|
||||
hideAllContextMenus(): void;
|
||||
showMapContextMenu(x: number, y: number, latlng: L.LatLng): void;
|
||||
hideMapContextMenu(): void;
|
||||
getMapContextMenu(): MapContextMenu;
|
||||
showUnitContextMenu(x?: number | undefined, y?: number | undefined, latlng?: L.LatLng | undefined): void;
|
||||
getUnitContextMenu(): UnitContextMenu;
|
||||
hideUnitContextMenu(): void;
|
||||
showAirbaseContextMenu(airbase: Airbase, x?: number | undefined, y?: number | undefined, latlng?: L.LatLng | undefined): void;
|
||||
getAirbaseContextMenu(): AirbaseContextMenu;
|
||||
hideAirbaseContextMenu(): void;
|
||||
showAirbaseSpawnMenu(airbase: Airbase, x?: number | undefined, y?: number | undefined, latlng?: L.LatLng | undefined): void;
|
||||
getAirbaseSpawnMenu(): AirbaseSpawnContextMenu;
|
||||
hideAirbaseSpawnMenu(): void;
|
||||
showCoalitionAreaContextMenu(x: number, y: number, latlng: L.LatLng, coalitionArea: CoalitionArea): void;
|
||||
getCoalitionAreaContextMenu(): CoalitionAreaContextMenu;
|
||||
hideCoalitionAreaContextMenu(): void;
|
||||
getMousePosition(): L.Point;
|
||||
getMouseCoordinates(): L.LatLng;
|
||||
centerOnUnit(ID: number | null): void;
|
||||
getCenteredOnUnit(): Unit | null;
|
||||
setTheatre(theatre: string): void;
|
||||
getMiniMapLayerGroup(): L.LayerGroup<any>;
|
||||
handleMapPanning(e: any): void;
|
||||
addTemporaryMarker(latlng: L.LatLng, name: string, coalition: string, commandHash?: string): TemporaryUnitMarker;
|
||||
getSelectedCoalitionArea(): CoalitionArea | undefined;
|
||||
bringCoalitionAreaToBack(coalitionArea: CoalitionArea): void;
|
||||
getVisibilityOptions(): {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
isZooming(): boolean;
|
||||
getPreviousZoom(): number;
|
||||
getIsUnitProtected(unit: Unit): boolean;
|
||||
getMapMarkerVisibilityControls(): MapMarkerVisibilityControl[];
|
||||
}
|
||||
}
|
||||
declare module "mission/bullseye" {
|
||||
import { CustomMarker } from "map/markers/custommarker";
|
||||
export class Bullseye extends CustomMarker {
|
||||
#private;
|
||||
createIcon(): void;
|
||||
setCoalition(coalition: string): void;
|
||||
getCoalition(): string;
|
||||
}
|
||||
}
|
||||
declare module "context/context" {
|
||||
export interface ContextInterface {
|
||||
allowUnitCopying?: boolean;
|
||||
allowUnitPasting?: boolean;
|
||||
useSpawnMenu?: boolean;
|
||||
useUnitControlPanel?: boolean;
|
||||
useUnitInfoPanel?: boolean;
|
||||
@@ -1474,6 +1608,8 @@ declare module "context/context" {
|
||||
export class Context {
|
||||
#private;
|
||||
constructor(config: ContextInterface);
|
||||
getAllowUnitCopying(): boolean;
|
||||
getAllowUnitPasting(): boolean;
|
||||
getUseSpawnMenu(): boolean;
|
||||
getUseUnitControlPanel(): boolean;
|
||||
getUseUnitInfoPanel(): boolean;
|
||||
@@ -1532,96 +1668,6 @@ declare module "popups/popup" {
|
||||
setText(text: string): void;
|
||||
}
|
||||
}
|
||||
declare module "map/touchboxselect" {
|
||||
export var TouchBoxSelect: (new (...args: any[]) => any) & typeof import("leaflet").Class;
|
||||
}
|
||||
declare module "map/markers/destinationpreviewHandle" {
|
||||
import { LatLng } from "leaflet";
|
||||
import { CustomMarker } from "map/markers/custommarker";
|
||||
export class DestinationPreviewHandle extends CustomMarker {
|
||||
constructor(latlng: LatLng);
|
||||
createIcon(): void;
|
||||
}
|
||||
}
|
||||
declare module "map/map" {
|
||||
import * as L from "leaflet";
|
||||
import { MapContextMenu } from "contextmenus/mapcontextmenu";
|
||||
import { UnitContextMenu } from "contextmenus/unitcontextmenu";
|
||||
import { AirbaseContextMenu } from "contextmenus/airbasecontextmenu";
|
||||
import { Airbase } from "mission/airbase";
|
||||
import { Unit } from "unit/unit";
|
||||
import { TemporaryUnitMarker } from "map/markers/temporaryunitmarker";
|
||||
import { CoalitionArea } from "map/coalitionarea/coalitionarea";
|
||||
import { CoalitionAreaContextMenu } from "contextmenus/coalitionareacontextmenu";
|
||||
import { AirbaseSpawnContextMenu } from "contextmenus/airbasespawnmenu";
|
||||
export type MapMarkerControl = {
|
||||
"image": string;
|
||||
"isProtected"?: boolean;
|
||||
"name": string;
|
||||
"protectable"?: boolean;
|
||||
"toggles": string[];
|
||||
"tooltip": string;
|
||||
};
|
||||
export class Map extends L.Map {
|
||||
#private;
|
||||
/**
|
||||
*
|
||||
* @param ID - the ID of the HTML element which will contain the context menu
|
||||
*/
|
||||
constructor(ID: string);
|
||||
addVisibilityOption(option: string, defaultValue: boolean): void;
|
||||
setLayer(layerName: string): void;
|
||||
getLayers(): string[];
|
||||
setState(state: string): void;
|
||||
getState(): string;
|
||||
deselectAllCoalitionAreas(): void;
|
||||
deleteCoalitionArea(coalitionArea: CoalitionArea): void;
|
||||
setHiddenType(key: string, value: boolean): void;
|
||||
getHiddenTypes(): string[];
|
||||
hideAllContextMenus(): void;
|
||||
showMapContextMenu(x: number, y: number, latlng: L.LatLng): void;
|
||||
hideMapContextMenu(): void;
|
||||
getMapContextMenu(): MapContextMenu;
|
||||
showUnitContextMenu(x: number, y: number, latlng: L.LatLng): void;
|
||||
getUnitContextMenu(): UnitContextMenu;
|
||||
hideUnitContextMenu(): void;
|
||||
showAirbaseContextMenu(x: number, y: number, latlng: L.LatLng, airbase: Airbase): void;
|
||||
getAirbaseContextMenu(): AirbaseContextMenu;
|
||||
hideAirbaseContextMenu(): void;
|
||||
showAirbaseSpawnMenu(x: number, y: number, latlng: L.LatLng, airbase: Airbase): void;
|
||||
getAirbaseSpawnMenu(): AirbaseSpawnContextMenu;
|
||||
hideAirbaseSpawnMenu(): void;
|
||||
showCoalitionAreaContextMenu(x: number, y: number, latlng: L.LatLng, coalitionArea: CoalitionArea): void;
|
||||
getCoalitionAreaContextMenu(): CoalitionAreaContextMenu;
|
||||
hideCoalitionAreaContextMenu(): void;
|
||||
isZooming(): boolean;
|
||||
getMousePosition(): L.Point;
|
||||
getMouseCoordinates(): L.LatLng;
|
||||
spawnFromAirbase(e: any): void;
|
||||
centerOnUnit(ID: number | null): void;
|
||||
getCenterUnit(): Unit | null;
|
||||
setTheatre(theatre: string): void;
|
||||
getMiniMapLayerGroup(): L.LayerGroup<any>;
|
||||
handleMapPanning(e: any): void;
|
||||
addTemporaryMarker(latlng: L.LatLng, name: string, coalition: string, commandHash?: string): TemporaryUnitMarker;
|
||||
getSelectedCoalitionArea(): CoalitionArea | undefined;
|
||||
bringCoalitionAreaToBack(coalitionArea: CoalitionArea): void;
|
||||
getVisibilityOptions(): {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
unitIsProtected(unit: Unit): boolean;
|
||||
getMapMarkerControls(): MapMarkerControl[];
|
||||
}
|
||||
}
|
||||
declare module "mission/bullseye" {
|
||||
import { CustomMarker } from "map/markers/custommarker";
|
||||
export class Bullseye extends CustomMarker {
|
||||
#private;
|
||||
createIcon(): void;
|
||||
setCoalition(coalition: string): void;
|
||||
getCoalition(): string;
|
||||
}
|
||||
}
|
||||
declare module "mission/missionmanager" {
|
||||
import { Airbase } from "mission/airbase";
|
||||
import { Bullseye } from "mission/bullseye";
|
||||
@@ -1708,30 +1754,6 @@ declare module "panels/serverstatuspanel" {
|
||||
update(frameRate: number, load: number): void;
|
||||
}
|
||||
}
|
||||
declare module "toolbars/toolbar" {
|
||||
export class Toolbar {
|
||||
#private;
|
||||
/**
|
||||
*
|
||||
* @param ID - the ID of the HTML element which will contain the context menu
|
||||
*/
|
||||
constructor(ID: string);
|
||||
show(): void;
|
||||
hide(): void;
|
||||
toggle(): void;
|
||||
getElement(): HTMLElement;
|
||||
getVisible(): boolean;
|
||||
}
|
||||
}
|
||||
declare module "toolbars/primarytoolbar" {
|
||||
import { Dropdown } from "controls/dropdown";
|
||||
import { Toolbar } from "toolbars/toolbar";
|
||||
export class PrimaryToolbar extends Toolbar {
|
||||
#private;
|
||||
constructor(ID: string);
|
||||
getMainDropdown(): Dropdown;
|
||||
}
|
||||
}
|
||||
declare module "panels/unitcontrolpanel" {
|
||||
import { Panel } from "panels/panel";
|
||||
export class UnitControlPanel extends Panel {
|
||||
@@ -1794,12 +1816,36 @@ declare module "shortcut/shortcutmanager" {
|
||||
onKeyUp(callback: CallableFunction): void;
|
||||
}
|
||||
}
|
||||
declare module "toolbars/toolbar" {
|
||||
export class Toolbar {
|
||||
#private;
|
||||
/**
|
||||
*
|
||||
* @param ID - the ID of the HTML element which will contain the context menu
|
||||
*/
|
||||
constructor(ID: string);
|
||||
show(): void;
|
||||
hide(): void;
|
||||
toggle(): void;
|
||||
getElement(): HTMLElement;
|
||||
getVisible(): boolean;
|
||||
}
|
||||
}
|
||||
declare module "toolbars/commandmodetoolbar" {
|
||||
import { Toolbar } from "toolbars/toolbar";
|
||||
export class CommandModeToolbar extends Toolbar {
|
||||
}
|
||||
}
|
||||
declare module "unit/citiesDatabase" {
|
||||
declare module "toolbars/primarytoolbar" {
|
||||
import { Dropdown } from "controls/dropdown";
|
||||
import { Toolbar } from "toolbars/toolbar";
|
||||
export class PrimaryToolbar extends Toolbar {
|
||||
#private;
|
||||
constructor(ID: string);
|
||||
getMainDropdown(): Dropdown;
|
||||
}
|
||||
}
|
||||
declare module "unit/databases/citiesdatabase" {
|
||||
export var citiesDatabase: {
|
||||
lat: number;
|
||||
lng: number;
|
||||
@@ -1921,140 +1967,163 @@ declare module "unit/unitsmanager" {
|
||||
* @param latlng Position of the new destination
|
||||
* @param mantainRelativePosition If true, the selected units will mantain their relative positions when reaching the target. This is useful to maintain a formation for groun/navy units
|
||||
* @param rotation Rotation in radians by which the formation will be rigidly rotated. E.g. a ( V ) formation will look like this ( < ) if rotated pi/4 radians (90 degrees)
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsAddDestination(latlng: L.LatLng, mantainRelativePosition: boolean, rotation: number): void;
|
||||
addDestination(latlng: L.LatLng, mantainRelativePosition: boolean, rotation: number, units?: Unit[] | null): void;
|
||||
/** Clear the destinations of all the selected units
|
||||
*
|
||||
*/
|
||||
selectedUnitsClearDestinations(): void;
|
||||
clearDestinations(units?: Unit[] | null): void;
|
||||
/** Instruct all the selected units to land at a specific location
|
||||
*
|
||||
* @param latlng Location where to land at
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsLandAt(latlng: LatLng): void;
|
||||
landAt(latlng: LatLng, units?: Unit[] | null): void;
|
||||
/** Instruct all the selected units to change their speed
|
||||
*
|
||||
* @param speedChange Speed change, either "stop", "slow", or "fast". The specific value depends on the unit category
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsChangeSpeed(speedChange: string): void;
|
||||
changeSpeed(speedChange: string, units?: Unit[] | null): void;
|
||||
/** Instruct all the selected units to change their altitude
|
||||
*
|
||||
* @param altitudeChange Altitude change, either "climb" or "descend". The specific value depends on the unit category
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsChangeAltitude(altitudeChange: string): void;
|
||||
changeAltitude(altitudeChange: string, units?: Unit[] | null): void;
|
||||
/** Set a specific speed to all the selected units
|
||||
*
|
||||
* @param speed Value to set, in m/s
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetSpeed(speed: number): void;
|
||||
setSpeed(speed: number, units?: Unit[] | null): void;
|
||||
/** Set a specific speed type to all the selected units
|
||||
*
|
||||
* @param speedType Value to set, either "CAS" or "GS". If "CAS" is selected, the unit will try to maintain the selected Calibrated Air Speed, but DCS will still only maintain a Ground Speed value so errors may arise depending on wind.
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetSpeedType(speedType: string): void;
|
||||
setSpeedType(speedType: string, units?: Unit[] | null): void;
|
||||
/** Set a specific altitude to all the selected units
|
||||
*
|
||||
* @param altitude Value to set, in m
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetAltitude(altitude: number): void;
|
||||
setAltitude(altitude: number, units?: Unit[] | null): void;
|
||||
/** Set a specific altitude type to all the selected units
|
||||
*
|
||||
* @param altitudeType Value to set, either "ASL" or "AGL". If "AGL" is selected, the unit will try to maintain the selected Above Ground Level altitude. Due to a DCS bug, this will only be true at the final position.
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetAltitudeType(altitudeType: string): void;
|
||||
setAltitudeType(altitudeType: string, units?: Unit[] | null): void;
|
||||
/** Set a specific ROE to all the selected units
|
||||
*
|
||||
* @param ROE Value to set, see constants for acceptable values
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetROE(ROE: string): void;
|
||||
setROE(ROE: string, units?: Unit[] | null): void;
|
||||
/** Set a specific reaction to threat to all the selected units
|
||||
*
|
||||
* @param reactionToThreat Value to set, see constants for acceptable values
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetReactionToThreat(reactionToThreat: string): void;
|
||||
setReactionToThreat(reactionToThreat: string, units?: Unit[] | null): void;
|
||||
/** Set a specific emissions & countermeasures to all the selected units
|
||||
*
|
||||
* @param emissionCountermeasure Value to set, see constants for acceptable values
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetEmissionsCountermeasures(emissionCountermeasure: string): void;
|
||||
setEmissionsCountermeasures(emissionCountermeasure: string, units?: Unit[] | null): void;
|
||||
/** Turn selected units on or off, only works on ground and navy units
|
||||
*
|
||||
* @param onOff If true, the unit will be turned on
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetOnOff(onOff: boolean): void;
|
||||
setOnOff(onOff: boolean, units?: Unit[] | null): void;
|
||||
/** Instruct the selected units to follow roads, only works on ground units
|
||||
*
|
||||
* @param followRoads If true, units will follow roads
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetFollowRoads(followRoads: boolean): void;
|
||||
setFollowRoads(followRoads: boolean, units?: Unit[] | null): void;
|
||||
/** Instruct selected units to operate as a certain coalition
|
||||
*
|
||||
* @param operateAsBool If true, units will operate as blue
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetOperateAs(operateAsBool: boolean): void;
|
||||
setOperateAs(operateAsBool: boolean, units?: Unit[] | null): void;
|
||||
/** Instruct units to attack a specific unit
|
||||
*
|
||||
* @param ID ID of the unit to attack
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsAttackUnit(ID: number): void;
|
||||
attackUnit(ID: number, units?: Unit[] | null): void;
|
||||
/** Instruct units to refuel at the nearest tanker, if possible. Else units will RTB
|
||||
*
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsRefuel(): void;
|
||||
refuel(units?: Unit[] | null): void;
|
||||
/** Instruct the selected units to follow another unit in a formation. Only works for aircrafts and helicopters.
|
||||
*
|
||||
* @param ID ID of the unit to follow
|
||||
* @param offset Optional parameter, defines a static offset. X: front-rear, positive front, Y: top-bottom, positive top, Z: left-right, positive right
|
||||
* @param formation Optional parameter, defines a predefined formation type. Values are: "trail", "echelon-lh", "echelon-rh", "line-abreast-lh", "line-abreast-rh", "front", "diamond"
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsFollowUnit(ID: number, offset?: {
|
||||
followUnit(ID: number, offset?: {
|
||||
"x": number;
|
||||
"y": number;
|
||||
"z": number;
|
||||
}, formation?: string): void;
|
||||
}, formation?: string, units?: Unit[] | null): void;
|
||||
/** Instruct the selected units to perform precision bombing of specific coordinates
|
||||
*
|
||||
* @param latlng Location to bomb
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsBombPoint(latlng: LatLng): void;
|
||||
bombPoint(latlng: LatLng, units?: Unit[] | null): void;
|
||||
/** Instruct the selected units to perform carpet bombing of specific coordinates
|
||||
*
|
||||
* @param latlng Location to bomb
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsCarpetBomb(latlng: LatLng): void;
|
||||
carpetBomb(latlng: LatLng, units?: Unit[] | null): void;
|
||||
/** Instruct the selected units to fire at specific coordinates
|
||||
*
|
||||
* @param latlng Location to fire at
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsFireAtArea(latlng: LatLng): void;
|
||||
fireAtArea(latlng: LatLng, units?: Unit[] | null): void;
|
||||
/** Instruct the selected units to simulate a fire fight at specific coordinates
|
||||
*
|
||||
* @param latlng Location to fire at
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSimulateFireFight(latlng: LatLng): void;
|
||||
simulateFireFight(latlng: LatLng, units?: Unit[] | null): void;
|
||||
/** Instruct units to enter into scenic AAA mode. Units will shoot in the air without aiming
|
||||
*
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsScenicAAA(): void;
|
||||
scenicAAA(units?: Unit[] | null): void;
|
||||
/** Instruct units to enter into miss on purpose mode. Units will aim to the nearest enemy unit but not precisely.
|
||||
*
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsMissOnPurpose(): void;
|
||||
missOnPurpose(units?: Unit[] | null): void;
|
||||
/** Instruct units to land at specific point
|
||||
*
|
||||
* @param latlng Point where to land
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsLandAtPoint(latlng: LatLng): void;
|
||||
landAtPoint(latlng: LatLng, units?: Unit[] | null): void;
|
||||
/** Set a specific shots scatter to all the selected units
|
||||
*
|
||||
* @param shotsScatter Value to set
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetShotsScatter(shotsScatter: number): void;
|
||||
setShotsScatter(shotsScatter: number, units?: Unit[] | null): void;
|
||||
/** Set a specific shots intensity to all the selected units
|
||||
*
|
||||
* @param shotsScatter Value to set
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetShotsIntensity(shotsIntensity: number): void;
|
||||
setShotsIntensity(shotsIntensity: number, units?: Unit[] | null): void;
|
||||
/*********************** Control operations on selected units ************************/
|
||||
/** See getUnitsCategories for more info
|
||||
*
|
||||
@@ -2070,42 +2139,46 @@ declare module "unit/unitsmanager" {
|
||||
/** Groups the selected units in a single (DCS) group, if all the units have the same category
|
||||
*
|
||||
*/
|
||||
selectedUnitsCreateGroup(): void;
|
||||
createGroup(units?: Unit[] | null): void;
|
||||
/** Set the hotgroup for the selected units. It will be the only hotgroup of the unit
|
||||
*
|
||||
* @param hotgroup Hotgroup number
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsSetHotgroup(hotgroup: number): void;
|
||||
setHotgroup(hotgroup: number, units?: Unit[] | null): void;
|
||||
/** Add the selected units to a hotgroup. Units can be in multiple hotgroups at the same type
|
||||
*
|
||||
* @param hotgroup Hotgroup number
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
selectedUnitsAddToHotgroup(hotgroup: number): void;
|
||||
addToHotgroup(hotgroup: number, units?: Unit[] | null): void;
|
||||
/** Delete the selected units
|
||||
*
|
||||
* @param explosion If true, the unit will be deleted using an explosion
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
* @returns
|
||||
*/
|
||||
selectedUnitsDelete(explosion?: boolean, explosionType?: string): void;
|
||||
delete(explosion?: boolean, explosionType?: string, units?: Unit[] | null): void;
|
||||
/** Compute the destinations of every unit in the selected units. This function preserves the relative positions of the units, and rotates the whole formation by rotation.
|
||||
*
|
||||
* @param latlng Center of the group after the translation
|
||||
* @param rotation Rotation of the group, in radians
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
* @returns Array of positions for each unit, in order
|
||||
*/
|
||||
selectedUnitsComputeGroupDestination(latlng: LatLng, rotation: number): {
|
||||
computeGroupDestination(latlng: LatLng, rotation: number, units?: Unit[] | null): {
|
||||
[key: number]: LatLng;
|
||||
};
|
||||
/** Copy the selected units and store their properties in memory
|
||||
*
|
||||
*/
|
||||
selectedUnitsCopy(): void;
|
||||
copy(units?: Unit[] | null): void;
|
||||
/*********************** Unit manipulation functions ************************/
|
||||
/** Paste the copied units
|
||||
*
|
||||
* @returns True if units were pasted successfully
|
||||
*/
|
||||
pasteUnits(): false | undefined;
|
||||
paste(): false | undefined;
|
||||
/** Automatically create an Integrated Air Defence System from a CoalitionArea object. The units will be mostly focused around big cities. The bigger the city, the larger the amount of units created next to it.
|
||||
* If the CoalitionArea does not contain any city, no units will be created
|
||||
*
|
||||
|
||||
@@ -43,7 +43,7 @@ if (config["server"] != undefined)
|
||||
module.exports = app;
|
||||
|
||||
const DemoDataGenerator = require('./demo.js');
|
||||
var demoDataGenerator = new DemoDataGenerator(app);
|
||||
var demoDataGenerator = new DemoDataGenerator(app, config);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
console.log('\x1b[36m%s\x1b[0m', "*********************************************************************");
|
||||
console.log('\x1b[36m%s\x1b[0m', "* _____ _____ _____ ____ _ *");
|
||||
console.log('\x1b[36m%s\x1b[0m', "* | __ \\ / ____|/ ____| / __ \\| | *");
|
||||
console.log('\x1b[36m%s\x1b[0m', "* | | | | | | (___ | | | | |_ _ _ __ ___ _ __ _ _ ___ *");
|
||||
console.log('\x1b[36m%s\x1b[0m', "* | | | | | \\___ \\ | | | | | | | | '_ ` _ \\| '_ \\| | | / __| *");
|
||||
console.log('\x1b[36m%s\x1b[0m', "* | |__| | |____ ____) | | |__| | | |_| | | | | | | |_) | |_| \\__ \\ *");
|
||||
console.log('\x1b[36m%s\x1b[0m', "* |_____/ \\_____|_____/ \\____/|_|\\__, |_| |_| |_| .__/ \\__,_|___/ *");
|
||||
console.log('\x1b[36m%s\x1b[0m', "* __/ | | | *");
|
||||
console.log('\x1b[36m%s\x1b[0m', "* |___/ |_| *");
|
||||
console.log('\x1b[36m%s\x1b[0m', "*********************************************************************");
|
||||
console.log('\x1b[36m%s\x1b[0m', "");
|
||||
console.log("Please wait while DCS Olympus Server starts up...");
|
||||
|
||||
var fs = require('fs');
|
||||
let rawdata = fs.readFileSync('../olympus.json');
|
||||
let config = JSON.parse(rawdata);
|
||||
@@ -98,3 +111,6 @@ function onListening() {
|
||||
: 'port ' + addr.port;
|
||||
debug('Listening on ' + bind);
|
||||
}
|
||||
|
||||
console.log("DCS Olympus server v0.4.7 started correctly!")
|
||||
console.log("Waiting for connections...")
|
||||
|
||||
@@ -14,7 +14,7 @@ const DEMO_WEAPONS_DATA = {
|
||||
}
|
||||
|
||||
class DemoDataGenerator {
|
||||
constructor(app)
|
||||
constructor(app, config)
|
||||
{
|
||||
app.get('/demo/units', (req, res) => this.units(req, res));
|
||||
app.get('/demo/weapons', (req, res) => this.weapons(req, res));
|
||||
@@ -27,9 +27,9 @@ class DemoDataGenerator {
|
||||
|
||||
app.use('/demo', basicAuth({
|
||||
users: {
|
||||
'admin': 'password',
|
||||
'blue': 'bluepassword',
|
||||
'red': 'redpassword'
|
||||
'admin': config["authentication"]["gameMasterPassword"],
|
||||
'blue': config["authentication"]["blueCommanderPassword"],
|
||||
'red': config["authentication"]["redCommanderPassword"]
|
||||
},
|
||||
}))
|
||||
|
||||
@@ -52,9 +52,9 @@ class DemoDataGenerator {
|
||||
isLeader: true
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
***************** UNCOMMENT TO TEST ALL UNITS ****************
|
||||
// UNCOMMENT TO TEST ALL UNITS ****************
|
||||
|
||||
var databases = Object.assign({}, aircraftDatabase, helicopterDatabase, groundUnitDatabase, navyUnitDatabase);
|
||||
var t = Object.keys(databases).length;
|
||||
@@ -91,6 +91,7 @@ class DemoDataGenerator {
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
let idx = 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
DEMO_UNIT_DATA[idx].name = "S_75M_Volhov";
|
||||
@@ -114,6 +115,7 @@ class DemoDataGenerator {
|
||||
DEMO_UNIT_DATA[idx].position.lat += idx / 100;
|
||||
DEMO_UNIT_DATA[idx].category = "GroundUnit";
|
||||
DEMO_UNIT_DATA[idx].isLeader = false;
|
||||
|
||||
|
||||
idx += 1;
|
||||
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
|
||||
|
||||
6357
client/package-lock.json
generated
6357
client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,8 @@
|
||||
"version": "v0.4.7-alpha",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "browserify .\\src\\index.ts --debug -o .\\public\\javascripts\\bundle.js -t [ babelify --global true --presets [ @babel/preset-env ] --extensions '.js'] -p [ tsify --noImplicitAny ] && copy.bat",
|
||||
"build": "browserify .\\src\\index.ts --debug -o .\\public\\javascripts\\bundle.js -t [ babelify --global true --presets [ @babel/preset-env ] --extensions '.js'] -p [ tsify --noImplicitAny ] && copy.bat",
|
||||
"build-release": "browserify .\\src\\index.ts -o .\\public\\javascripts\\bundle.js -t [ babelify --global true --presets [ @babel/preset-env ] --extensions '.js'] -p [ tsify --noImplicitAny ] -p [ tinyify ] && copy.bat",
|
||||
"emit-declarations": "tsc --project tsconfig.json --declaration --emitDeclarationOnly --outfile ./@types/olympus/index.d.ts",
|
||||
"copy": "copy.bat",
|
||||
"start": "node ./bin/www",
|
||||
@@ -20,6 +21,7 @@
|
||||
"ejs": "^3.1.8",
|
||||
"express": "~4.16.1",
|
||||
"express-basic-auth": "^1.2.1",
|
||||
"js-sha256": "^0.10.1",
|
||||
"leaflet-gesture-handling": "^1.2.2",
|
||||
"morgan": "~1.9.1",
|
||||
"save": "^2.9.0",
|
||||
@@ -48,10 +50,9 @@
|
||||
"nodemon": "^2.0.20",
|
||||
"requirejs": "^2.3.6",
|
||||
"sortablejs": "^1.15.0",
|
||||
"tinyify": "^4.0.0",
|
||||
"tsify": "^5.0.4",
|
||||
"tslib": "latest",
|
||||
"typedoc": "^0.24.8",
|
||||
"typedoc-umlclass": "^0.7.1",
|
||||
"typescript": "^4.9.4",
|
||||
"usng.js": "^0.4.5",
|
||||
"watchify": "^4.0.0"
|
||||
|
||||
@@ -1,384 +0,0 @@
|
||||
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
||||
"use strict";
|
||||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
||||
if (kind === "m") throw new TypeError("Private method is not writable");
|
||||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
||||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
||||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
||||
};
|
||||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
||||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
||||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
||||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
||||
};
|
||||
var _ControlTipsPlugin_instances, _ControlTipsPlugin_element, _ControlTipsPlugin_app, _ControlTipsPlugin_shortcutManager, _ControlTipsPlugin_cursorIsHoveringOverUnit, _ControlTipsPlugin_cursorIsHoveringOverAirbase, _ControlTipsPlugin_mouseoverElement, _ControlTipsPlugin_updateTips;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ControlTipsPlugin = void 0;
|
||||
const SHOW_CONTROL_TIPS = "Show control tips";
|
||||
class ControlTipsPlugin {
|
||||
constructor() {
|
||||
_ControlTipsPlugin_instances.add(this);
|
||||
_ControlTipsPlugin_element.set(this, void 0);
|
||||
_ControlTipsPlugin_app.set(this, void 0);
|
||||
_ControlTipsPlugin_shortcutManager.set(this, void 0);
|
||||
_ControlTipsPlugin_cursorIsHoveringOverUnit.set(this, false);
|
||||
_ControlTipsPlugin_cursorIsHoveringOverAirbase.set(this, false);
|
||||
_ControlTipsPlugin_mouseoverElement.set(this, void 0);
|
||||
__classPrivateFieldSet(this, _ControlTipsPlugin_element, document.createElement("div"), "f");
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_element, "f").id = "control-tips-panel";
|
||||
document.body.appendChild(__classPrivateFieldGet(this, _ControlTipsPlugin_element, "f"));
|
||||
}
|
||||
getName() {
|
||||
return "Control Tips Plugin";
|
||||
}
|
||||
initialize(app) {
|
||||
__classPrivateFieldSet(this, _ControlTipsPlugin_app, app, "f");
|
||||
__classPrivateFieldSet(this, _ControlTipsPlugin_shortcutManager, __classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getShortcutManager(), "f");
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_shortcutManager, "f").onKeyDown(() => {
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_shortcutManager, "f").onKeyUp(() => {
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
document.addEventListener("airbaseMouseover", (ev) => {
|
||||
__classPrivateFieldSet(this, _ControlTipsPlugin_cursorIsHoveringOverAirbase, true, "f");
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
document.addEventListener("airbaseMouseout", (ev) => {
|
||||
__classPrivateFieldSet(this, _ControlTipsPlugin_cursorIsHoveringOverAirbase, false, "f");
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
document.addEventListener("unitDeselection", (ev) => {
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
document.addEventListener("unitMouseover", (ev) => {
|
||||
__classPrivateFieldSet(this, _ControlTipsPlugin_cursorIsHoveringOverUnit, true, "f");
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
document.addEventListener("unitMouseout", (ev) => {
|
||||
__classPrivateFieldSet(this, _ControlTipsPlugin_cursorIsHoveringOverUnit, false, "f");
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
document.addEventListener("unitsSelection", (ev) => {
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
document.addEventListener("mapVisibilityOptionsChanged", () => {
|
||||
this.toggle(!__classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getMap().getVisibilityOptions()[SHOW_CONTROL_TIPS]);
|
||||
});
|
||||
document.addEventListener("mouseover", (ev) => {
|
||||
if (ev.target instanceof HTMLElement) {
|
||||
__classPrivateFieldSet(this, _ControlTipsPlugin_mouseoverElement, ev.target, "f");
|
||||
}
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
document.addEventListener("mouseup", (ev) => {
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
});
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_instances, "m", _ControlTipsPlugin_updateTips).call(this);
|
||||
__classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getMap().addVisibilityOption(SHOW_CONTROL_TIPS, true);
|
||||
return true;
|
||||
}
|
||||
getElement() {
|
||||
return __classPrivateFieldGet(this, _ControlTipsPlugin_element, "f");
|
||||
}
|
||||
toggle(bool) {
|
||||
this.getElement().classList.toggle("hide", bool);
|
||||
}
|
||||
}
|
||||
exports.ControlTipsPlugin = ControlTipsPlugin;
|
||||
_ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap(), _ControlTipsPlugin_shortcutManager = new WeakMap(), _ControlTipsPlugin_cursorIsHoveringOverUnit = new WeakMap(), _ControlTipsPlugin_cursorIsHoveringOverAirbase = new WeakMap(), _ControlTipsPlugin_mouseoverElement = new WeakMap(), _ControlTipsPlugin_instances = new WeakSet(), _ControlTipsPlugin_updateTips = function _ControlTipsPlugin_updateTips() {
|
||||
const combos = [
|
||||
{
|
||||
"keys": [],
|
||||
"tips": [
|
||||
{
|
||||
"key": `SHIFT`,
|
||||
"action": `Box select`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false,
|
||||
"showIfUnitSelected": false
|
||||
},
|
||||
{
|
||||
"key": `Mouse1`,
|
||||
"action": `Deselect`,
|
||||
"showIfUnitSelected": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse1+drag`,
|
||||
"action": `Move map`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false,
|
||||
"showIfUnitSelected": false
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Spawn menu`,
|
||||
"showIfUnitSelected": false,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Quick options`,
|
||||
"showIfUnitSelected": false,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Airbase menu`,
|
||||
"showIfUnitSelected": false,
|
||||
"showIfHoveringOverAirbase": true,
|
||||
"showIfHoveringOverUnit": false
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Set first waypoint`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfUnitSelected": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2 (hold)`,
|
||||
"action": `Interact (ground)`,
|
||||
"showIfUnitSelected": true,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Shift`,
|
||||
"action": "<em> in formation...</em>",
|
||||
"showIfUnitSelected": true,
|
||||
"minSelectedUnits": 2
|
||||
},
|
||||
{
|
||||
"key": "CTRL",
|
||||
"action": "<em> ... more</em>",
|
||||
"showIfUnitSelected": true,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": "CTRL",
|
||||
"action": " Pin tool",
|
||||
"showIfUnitSelected": false,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": "CTRL+Mouse2",
|
||||
"action": " Airbase menu",
|
||||
"showIfUnitSelected": true,
|
||||
"showIfHoveringOverAirbase": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse1`,
|
||||
"action": "Toggle Blue/Red",
|
||||
"mouseoverSelector": "#coalition-switch .ol-switch-fill"
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": "Set Neutral",
|
||||
"mouseoverSelector": "#coalition-switch .ol-switch-fill"
|
||||
},
|
||||
{
|
||||
"key": `Mouse1`,
|
||||
"action": "Toggle time display",
|
||||
"mouseoverSelector": "#connection-status-panel[data-is-connected] #connection-status-message abbr"
|
||||
},
|
||||
{
|
||||
"key": `Mouse1 or Z`,
|
||||
"action": "Change location system",
|
||||
"mouseoverSelector": "#coordinates-tool, #coordinates-tool *"
|
||||
},
|
||||
{
|
||||
"key": `Comma`,
|
||||
"action": "Decrease precision",
|
||||
"mouseoverSelector": `#coordinates-tool[data-location-system="MGRS"], #coordinates-tool[data-location-system="MGRS"] *`
|
||||
},
|
||||
{
|
||||
"key": `Period`,
|
||||
"action": "Increase precision",
|
||||
"mouseoverSelector": `#coordinates-tool[data-location-system="MGRS"], #coordinates-tool[data-location-system="MGRS"] *`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": ["ControlLeft"],
|
||||
"tips": [
|
||||
{
|
||||
"key": `Mouse1`,
|
||||
"action": "Toggle pin",
|
||||
"showIfUnitSelected": false,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false
|
||||
},
|
||||
{
|
||||
"key": `Mouse1`,
|
||||
"action": "Toggle selection",
|
||||
"showIfUnitSelected": true,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Add waypoint`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false,
|
||||
"showIfUnitSelected": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Interact (airbase)`,
|
||||
"showIfHoveringOverAirbase": true,
|
||||
"showIfUnitSelected": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Interact (unit)`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": true,
|
||||
"showIfUnitSelected": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Shift`,
|
||||
"action": "<em> in formation...</em>",
|
||||
"showIfUnitSelected": true,
|
||||
"minSelectedUnits": 2
|
||||
},
|
||||
{
|
||||
"key": `[Num 1-9]`,
|
||||
"action": "Set hotgroup",
|
||||
"showIfUnitSelected": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": ["ShiftLeft"],
|
||||
"tips": [
|
||||
{
|
||||
"key": `Mouse1+drag`,
|
||||
"action": "Box select",
|
||||
"showIfUnitSelected": false
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": "Set first formation waypoint",
|
||||
"showIfUnitSelected": true,
|
||||
"minSelectedUnits": 2
|
||||
},
|
||||
{
|
||||
"key": `[Num 1-9]`,
|
||||
"action": "Add to hotgroup",
|
||||
"showIfUnitSelected": true
|
||||
},
|
||||
{
|
||||
"key": "CTRL",
|
||||
"action": "<em> ... more</em>",
|
||||
"minSelectedUnits": 2,
|
||||
"showIfUnitSelected": true,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"unitsMustBeControlled": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": ["ControlLeft", "ShiftLeft"],
|
||||
"tips": [
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": "Add formation waypoint",
|
||||
"showIfUnitSelected": true,
|
||||
"minSelectedUnits": 2,
|
||||
"unitsMustBeControlled": true
|
||||
}, {
|
||||
"key": `[Num 1-9]`,
|
||||
"action": "Add hotgroup to selection",
|
||||
"callback": (tip) => {
|
||||
return (Object.values(__classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getUnitsManager().getUnits()).some((unit) => {
|
||||
return unit.getHotgroup();
|
||||
}));
|
||||
},
|
||||
"showIfUnitSelected": true,
|
||||
"minSelectedUnits": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
const currentCombo = combos.find((combo) => __classPrivateFieldGet(this, _ControlTipsPlugin_shortcutManager, "f").keyComboMatches(combo.keys)) || combos[0];
|
||||
const element = this.getElement();
|
||||
element.innerHTML = "";
|
||||
let numSelectedUnits = 0;
|
||||
let numSelectedControlledUnits = 0;
|
||||
let unitSelectionContainsControlled = false;
|
||||
if (__classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getUnitsManager()) {
|
||||
let selectedUnits = Object.values(__classPrivateFieldGet(this, _ControlTipsPlugin_app, "f").getUnitsManager().getSelectedUnits());
|
||||
numSelectedUnits = selectedUnits.length;
|
||||
numSelectedControlledUnits = selectedUnits.filter((unit) => unit.getControlled()).length;
|
||||
unitSelectionContainsControlled = numSelectedControlledUnits > 0;
|
||||
}
|
||||
const tipsIncludesActiveMouseover = (currentCombo.tips.some((tip) => {
|
||||
if (!tip.mouseoverSelector) {
|
||||
return false;
|
||||
}
|
||||
if (__classPrivateFieldGet(this, _ControlTipsPlugin_mouseoverElement, "f") instanceof HTMLElement === false) {
|
||||
return false;
|
||||
}
|
||||
if (!__classPrivateFieldGet(this, _ControlTipsPlugin_mouseoverElement, "f").matches(tip.mouseoverSelector)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
currentCombo.tips.filter((tip) => {
|
||||
if (numSelectedUnits > 0) {
|
||||
if (tip.showIfUnitSelected === false) {
|
||||
return false;
|
||||
}
|
||||
if (tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false) {
|
||||
return false;
|
||||
}
|
||||
if (typeof tip.minSelectedUnits === "number" && numSelectedControlledUnits < tip.minSelectedUnits) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (numSelectedUnits === 0 && tip.showIfUnitSelected === true) {
|
||||
return false;
|
||||
}
|
||||
if (typeof tip.showIfHoveringOverAirbase === "boolean") {
|
||||
if (tip.showIfHoveringOverAirbase !== __classPrivateFieldGet(this, _ControlTipsPlugin_cursorIsHoveringOverAirbase, "f")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (typeof tip.showIfHoveringOverUnit === "boolean") {
|
||||
if (tip.showIfHoveringOverUnit !== __classPrivateFieldGet(this, _ControlTipsPlugin_cursorIsHoveringOverUnit, "f")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (tipsIncludesActiveMouseover && (typeof tip.mouseoverSelector !== "string" || !__classPrivateFieldGet(this, _ControlTipsPlugin_mouseoverElement, "f").matches(tip.mouseoverSelector))) {
|
||||
return false;
|
||||
}
|
||||
if (!tipsIncludesActiveMouseover && typeof tip.mouseoverSelector === "string") {
|
||||
return false;
|
||||
}
|
||||
if (typeof tip.callback === "function" && !tip.callback(tip)) {
|
||||
return false;
|
||||
}
|
||||
element.innerHTML += `<div><span class="key">${tip.key}</span><span class="action">${tip.action}</span></div>`;
|
||||
});
|
||||
};
|
||||
|
||||
},{}],2:[function(require,module,exports){
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const controltipsplugin_1 = require("./controltipsplugin");
|
||||
globalThis.getOlympusPlugin = () => {
|
||||
return new controltipsplugin_1.ControlTipsPlugin();
|
||||
};
|
||||
|
||||
},{"./controltipsplugin":1}]},{},[2]);
|
||||
4816
client/plugins/controltips/package-lock.json
generated
4816
client/plugins/controltips/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,27 @@
|
||||
"version": "v0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "browserify ./src/index.ts -p [ tsify --noImplicitAny] > index.js && copy.bat"
|
||||
"build": "browserify ./src/index.ts -p [ tsify --noImplicitAny] > index.js && copy.bat",
|
||||
"build-release": "browserify ./src/index.ts -p [ tsify --noImplicitAny] -p [ tinyify ] > index.js && copy.bat"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {}
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.21.4",
|
||||
"@types/node": "^18.16.1",
|
||||
"@types/sortablejs": "^1.15.0",
|
||||
"babelify": "^10.0.0",
|
||||
"browserify": "^17.0.0",
|
||||
"concurrently": "^7.6.0",
|
||||
"cp": "^0.2.0",
|
||||
"esmify": "^2.1.1",
|
||||
"nodemon": "^2.0.20",
|
||||
"requirejs": "^2.3.6",
|
||||
"sortablejs": "^1.15.0",
|
||||
"tinyify": "^4.0.0",
|
||||
"tsify": "^5.0.4",
|
||||
"tslib": "latest",
|
||||
"typescript": "^4.9.4",
|
||||
"usng.js": "^0.4.5",
|
||||
"watchify": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
this.#updateTips();
|
||||
});
|
||||
|
||||
document.addEventListener("mapVisibilityOptionsChanged", () => {
|
||||
document.addEventListener("mapOptionsChanged", () => {
|
||||
this.toggle( !this.#app.getMap().getVisibilityOptions()[SHOW_CONTROL_TIPS] );
|
||||
});
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ const navyuniteditor_1 = require("./navyuniteditor");
|
||||
class DatabaseManagerPlugin {
|
||||
constructor() {
|
||||
_DatabaseManagerPlugin_instances.add(this);
|
||||
_DatabaseManagerPlugin_app.set(this, null);
|
||||
_DatabaseManagerPlugin_app.set(this, void 0);
|
||||
_DatabaseManagerPlugin_element.set(this, void 0);
|
||||
_DatabaseManagerPlugin_mainContentContainer.set(this, void 0);
|
||||
_DatabaseManagerPlugin_contentDiv1.set(this, void 0);
|
||||
@@ -263,6 +263,14 @@ class DatabaseManagerPlugin {
|
||||
initialize(app) {
|
||||
var _a;
|
||||
__classPrivateFieldSet(this, _DatabaseManagerPlugin_app, app, "f");
|
||||
const contextManager = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f").getContextManager();
|
||||
contextManager.add("databaseManager", {
|
||||
"allowUnitCopying": false,
|
||||
"allowUnitPasting": false,
|
||||
"useSpawnMenu": false,
|
||||
"useUnitControlPanel": false,
|
||||
"useUnitInfoPanel": false
|
||||
});
|
||||
/* Load the databases and initialize the editors */
|
||||
__classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_loadDatabases).call(this);
|
||||
/* Add a button to the main Olympus App to allow the users to open the dialog */
|
||||
@@ -273,7 +281,7 @@ class DatabaseManagerPlugin {
|
||||
var toolbar = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getToolbarsManager().get("primaryToolbar");
|
||||
var elements = toolbar.getMainDropdown().getOptionElements();
|
||||
var arr = Array.prototype.slice.call(elements);
|
||||
arr.splice(arr.length - 1, 0, mainButtonDiv);
|
||||
arr.splice(arr.length - 3, 0, mainButtonDiv);
|
||||
toolbar.getMainDropdown().setOptionsElements(arr);
|
||||
mainButton.onclick = () => {
|
||||
var _a;
|
||||
@@ -299,6 +307,8 @@ class DatabaseManagerPlugin {
|
||||
this.getElement().classList.toggle("hide", !bool);
|
||||
else
|
||||
this.getElement().classList.toggle("hide");
|
||||
if (__classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f"))
|
||||
__classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f").getContextManager().setContext(this.getElement().classList.contains("hide") ? "olympus" : "databaseManager");
|
||||
}
|
||||
}
|
||||
exports.DatabaseManagerPlugin = DatabaseManagerPlugin;
|
||||
|
||||
@@ -4,10 +4,29 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "browserify ./src/index.ts -p [ tsify --noImplicitAny] > index.js && copy.bat",
|
||||
"build-release": "browserify ./src/index.ts -p [ tsify --noImplicitAny] -p [ tinyify ] > index.js && copy.bat",
|
||||
"start": "npm run copy & concurrently --kill-others \"npm run watch\"",
|
||||
"copy": "copy.bat",
|
||||
"watch": "watchify ./src/index.ts --debug -o ../../public/plugins/databasemanager/index.js -t [ babelify --global true --presets [ @babel/preset-env ] --extensions '.js'] -p [ tsify --noImplicitAny ]"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {}
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.21.4",
|
||||
"@types/node": "^18.16.1",
|
||||
"@types/sortablejs": "^1.15.0",
|
||||
"babelify": "^10.0.0",
|
||||
"browserify": "^17.0.0",
|
||||
"concurrently": "^7.6.0",
|
||||
"cp": "^0.2.0",
|
||||
"esmify": "^2.1.1",
|
||||
"nodemon": "^2.0.20",
|
||||
"requirejs": "^2.3.6",
|
||||
"sortablejs": "^1.15.0",
|
||||
"tinyify": "^4.0.0",
|
||||
"tsify": "^5.0.4",
|
||||
"tslib": "latest",
|
||||
"typescript": "^4.9.4",
|
||||
"usng.js": "^0.4.5",
|
||||
"watchify": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { NavyUnitEditor } from "./navyuniteditor";
|
||||
*/
|
||||
|
||||
export class DatabaseManagerPlugin implements OlympusPlugin {
|
||||
#app: OlympusApp | null = null;
|
||||
#app!: OlympusApp;
|
||||
|
||||
#element: HTMLElement;
|
||||
#mainContentContainer: HTMLElement;
|
||||
@@ -157,6 +157,15 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
|
||||
*/
|
||||
initialize(app: any) {
|
||||
this.#app = app;
|
||||
|
||||
const contextManager = this.#app.getContextManager();
|
||||
contextManager.add( "databaseManager", {
|
||||
"allowUnitCopying": false,
|
||||
"allowUnitPasting": false,
|
||||
"useSpawnMenu": false,
|
||||
"useUnitControlPanel": false,
|
||||
"useUnitInfoPanel": false
|
||||
});
|
||||
|
||||
/* Load the databases and initialize the editors */
|
||||
this.#loadDatabases();
|
||||
@@ -169,7 +178,7 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
|
||||
var toolbar: PrimaryToolbar = this.#app?.getToolbarsManager().get("primaryToolbar") as PrimaryToolbar;
|
||||
var elements = toolbar.getMainDropdown().getOptionElements();
|
||||
var arr = Array.prototype.slice.call(elements);
|
||||
arr.splice(arr.length - 1, 0, mainButtonDiv);
|
||||
arr.splice(arr.length - 3, 0, mainButtonDiv);
|
||||
toolbar.getMainDropdown().setOptionsElements(arr);
|
||||
mainButton.onclick = () => {
|
||||
toolbar.getMainDropdown().close();
|
||||
@@ -197,6 +206,9 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
|
||||
this.getElement().classList.toggle("hide", !bool);
|
||||
else
|
||||
this.getElement().classList.toggle("hide");
|
||||
|
||||
if ( this.#app )
|
||||
this.#app.getContextManager().setContext( this.getElement().classList.contains("hide") ? "olympus" : "databaseManager" );
|
||||
}
|
||||
|
||||
/** Hide all the editors
|
||||
|
||||
@@ -264,6 +264,20 @@ body.feature-forceShowUnitControlPanel #unit-control-panel {
|
||||
content: "GS";
|
||||
}
|
||||
|
||||
#unit-control-panel .switch-control .ol-switch {
|
||||
height: 23px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
#unit-control-panel .switch-control .ol-switch[data-value="true"]>.ol-switch-fill::before {
|
||||
content: "YES";
|
||||
}
|
||||
|
||||
#unit-control-panel .switch-control .ol-switch[data-value="false"]>.ol-switch-fill::before {
|
||||
content: "NO";
|
||||
}
|
||||
|
||||
|
||||
#unit-control-panel .ol-slider-value {
|
||||
color: var(--accent-light-blue);
|
||||
cursor: pointer;
|
||||
|
||||
@@ -23,7 +23,7 @@ body {
|
||||
}
|
||||
|
||||
.hidden-cursor {
|
||||
cursor: none !important;
|
||||
/*cursor: none !important;*/
|
||||
}
|
||||
|
||||
.hidden-cursor * {
|
||||
@@ -67,10 +67,6 @@ button>img:first-child {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ol-box-shadow {
|
||||
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
form {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -230,13 +226,13 @@ form {
|
||||
}
|
||||
|
||||
.ol-select.is-open[data-position="top"]>.ol-select-options {
|
||||
box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25);
|
||||
top: 0;
|
||||
translate: 0 -100%;
|
||||
}
|
||||
|
||||
.ol-select>.ol-select-options>div {
|
||||
background-color: var(--background-grey);
|
||||
box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25);
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
padding: 2px 15px;
|
||||
@@ -266,6 +262,7 @@ form {
|
||||
color: white;
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
height: 32px;
|
||||
padding: 6px 2px;
|
||||
padding: 5px;
|
||||
@@ -718,6 +715,62 @@ nav.ol-panel> :last-child {
|
||||
}
|
||||
|
||||
|
||||
|
||||
#roe-buttons-container button,
|
||||
#reaction-to-threat-buttons-container button,
|
||||
#emissions-countermeasures-buttons-container button,
|
||||
#shots-scatter-buttons-container button
|
||||
#shots-intensity-buttons-container button {
|
||||
align-items: center;
|
||||
background-color: transparent;
|
||||
border: 1px solid var(--accent-light-blue);
|
||||
display: flex;
|
||||
height: 30px;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
#reaction-to-threat-buttons-container button:not(:first-child) svg {
|
||||
width: 150%;
|
||||
margin: -5px;
|
||||
}
|
||||
|
||||
#unit-control-panel .ol-option-button button.selected {
|
||||
background-color: white;
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
#unit-control-panel .ol-option-button button.selected svg * {
|
||||
fill: var(--background-steel);
|
||||
stroke: var(--background-steel);
|
||||
}
|
||||
|
||||
#rapid-controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 5px;
|
||||
height: fit-content;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#rapid-controls button {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
#rapid-controls svg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
fill: white;
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
#rapid-controls button:before {
|
||||
display: inline-block;
|
||||
filter: invert(100%);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
#splash-screen {
|
||||
border-radius: var(--border-radius-md);
|
||||
@@ -823,6 +876,43 @@ nav.ol-panel> :last-child {
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
#loading-screen {
|
||||
display: flex;
|
||||
background-image: linear-gradient(var(--background-steel), var(--background-grey));
|
||||
height: 100%;
|
||||
left: 0px;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
z-index: 999999;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
row-gap: 20px;
|
||||
}
|
||||
|
||||
#loading-screen img {
|
||||
height: 300px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
#loading-screen div {
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
animation: blinker 3s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes blinker {
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-out {
|
||||
opacity: 0%;
|
||||
transition: opacity 1s;
|
||||
}
|
||||
|
||||
#authentication-form {
|
||||
align-items: end;
|
||||
column-gap: 10px;
|
||||
@@ -1272,12 +1362,13 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
align-items: center;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
font-weight: normal;
|
||||
padding: 8px 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
[class|="ol-button"]::before {
|
||||
margin-right: 4px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.ol-button-close {
|
||||
@@ -1314,12 +1405,10 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
}
|
||||
|
||||
.ol-switch {
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
height: 25px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.ol-switch-input {
|
||||
@@ -1355,7 +1444,7 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
display: flex;
|
||||
font-size: 11px;
|
||||
height: 100%;
|
||||
padding: 0px 6px;
|
||||
padding: 0px 7px;
|
||||
position: absolute;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
@@ -1394,27 +1483,6 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
content: "NO";
|
||||
}
|
||||
|
||||
|
||||
.ol-contexmenu-panel {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.ol-coalition-switch[data-value="false"]>.ol-switch-fill {
|
||||
background-color: var(--primary-blue);
|
||||
}
|
||||
|
||||
.ol-coalition-switch[data-value="true"]>.ol-switch-fill {
|
||||
background-color: var(--primary-red);
|
||||
}
|
||||
|
||||
.ol-coalition-switch[data-value="undefined"]>.ol-switch-fill {
|
||||
background-color: var(--primary-neutral);
|
||||
}
|
||||
/*
|
||||
#unit-control-panel .switch-control .ol-switch-fill::after {
|
||||
background-color: white;
|
||||
}
|
||||
*/
|
||||
.switch-control.coalition [data-value="true"] .ol-switch-fill {
|
||||
background-color: var(--accent-light-blue);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
@@ -1,5 +1,5 @@
|
||||
import { LatLng, LatLngBounds } from "leaflet";
|
||||
import { MapMarkerControl } from "../map/map";
|
||||
import { MapMarkerVisibilityControl } from "../map/map";
|
||||
|
||||
export const UNITS_URI = "units";
|
||||
export const WEAPONS_URI = "weapons";
|
||||
@@ -157,10 +157,10 @@ export const mapLayers = {
|
||||
export const IDLE = "Idle";
|
||||
export const MOVE_UNIT = "Move unit";
|
||||
export const COALITIONAREA_DRAW_POLYGON = "Draw Coalition Area";
|
||||
export const visibilityControls: string[] = ["human", "dcs", "aircraft", "helicopter", "groundunit-sam", "groundunit-other", "navyunit", "airbase"];
|
||||
export const visibilityControlsTypes: string[][] = [["human"], ["dcs"], ["aircraft"], ["helicopter"], ["groundunit-sam", "groundunit-sam-radar", "groundunit-sam-launcher"], ["groundunit-other", "groundunit-ewr"], ["navyunit"], ["airbase"]];
|
||||
export const visibilityControls: string[] = ["human", "dcs", "aircraft", "helicopter", "groundunit-sam", "groundunit", "navyunit", "airbase"];
|
||||
export const visibilityControlsTypes: string[][] = [["human"], ["dcs"], ["aircraft"], ["helicopter"], ["groundunit-sam"], ["groundunit"], ["navyunit"], ["airbase"]];
|
||||
export const visibilityControlsTooltips: string[] = ["Toggle human players visibility", "Toggle DCS controlled units visibility", "Toggle aircrafts visibility", "Toggle helicopter visibility", "Toggle SAM units visibility", "Toggle ground units (not SAM) visibility", "Toggle navy units visibility", "Toggle airbases visibility"];
|
||||
export const MAP_MARKER_CONTROLS: MapMarkerControl[] = [{
|
||||
export const MAP_MARKER_CONTROLS: MapMarkerVisibilityControl[] = [{
|
||||
"name": "Human",
|
||||
"image": "visibility/human.svg",
|
||||
"toggles": ["human"],
|
||||
@@ -188,9 +188,9 @@ export const MAP_MARKER_CONTROLS: MapMarkerControl[] = [{
|
||||
"toggles": ["groundunit-sam"],
|
||||
"tooltip": "Toggle air defence units' visibility"
|
||||
}, {
|
||||
"image": "visibility/groundunit-other.svg",
|
||||
"image": "visibility/groundunit.svg",
|
||||
"name": "Ground units",
|
||||
"toggles": ["groundunit-other"],
|
||||
"toggles": ["groundunit"],
|
||||
"tooltip": "Toggle ground units' visibility"
|
||||
}, {
|
||||
"image": "visibility/navyunit.svg",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export interface ContextInterface {
|
||||
allowUnitCopying?: boolean;
|
||||
allowUnitPasting?: boolean;
|
||||
useSpawnMenu?: boolean;
|
||||
useUnitControlPanel?: boolean;
|
||||
useUnitInfoPanel?: boolean;
|
||||
@@ -6,16 +8,28 @@ export interface ContextInterface {
|
||||
|
||||
export class Context {
|
||||
|
||||
#allowUnitCopying:boolean;
|
||||
#allowUnitPasting:boolean;
|
||||
#useSpawnMenu:boolean;
|
||||
#useUnitControlPanel:boolean;
|
||||
#useUnitInfoPanel:boolean;
|
||||
|
||||
constructor( config:ContextInterface ) {
|
||||
this.#allowUnitCopying = ( config.allowUnitCopying !== false );
|
||||
this.#allowUnitPasting = ( config.allowUnitPasting !== false );
|
||||
this.#useSpawnMenu = ( config.useSpawnMenu !== false );
|
||||
this.#useUnitControlPanel = ( config.useUnitControlPanel !== false );
|
||||
this.#useUnitInfoPanel = ( config.useUnitInfoPanel !== false );
|
||||
}
|
||||
|
||||
getAllowUnitCopying() {
|
||||
return this.#allowUnitCopying;
|
||||
}
|
||||
|
||||
getAllowUnitPasting() {
|
||||
return this.#allowUnitPasting;
|
||||
}
|
||||
|
||||
getUseSpawnMenu() {
|
||||
return this.#useSpawnMenu;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ export class Dropdown {
|
||||
#optionsList: string[] = [];
|
||||
#index: number = 0;
|
||||
#hidden: boolean = false;
|
||||
#text!:HTMLElement;
|
||||
|
||||
constructor(ID: string | null, callback: CallableFunction, options: string[] | null = null, defaultText?: string) {
|
||||
if (ID === null)
|
||||
@@ -15,7 +16,10 @@ export class Dropdown {
|
||||
this.#container = document.getElementById(ID) as HTMLElement;
|
||||
|
||||
this.#options = this.#container.querySelector(".ol-select-options") as HTMLElement;
|
||||
this.#value = this.#container.querySelector(".ol-select-value") as HTMLElement;
|
||||
|
||||
const text = this.#container.querySelector(".ol-select-value-text");
|
||||
this.#value = ( text instanceof HTMLElement ) ? text : this.#container.querySelector(".ol-select-value") as HTMLElement;
|
||||
|
||||
this.#defaultValue = this.#value.innerText;
|
||||
this.#callback = callback;
|
||||
|
||||
|
||||
2
client/src/dom.d.ts
vendored
2
client/src/dom.d.ts
vendored
@@ -18,7 +18,7 @@ interface CustomEventMap {
|
||||
"groupDeletion": CustomEvent<Unit[]>,
|
||||
"mapStateChanged": CustomEvent<string>,
|
||||
"mapContextMenu": CustomEvent<>,
|
||||
"mapVisibilityOptionsChanged": CustomEvent<>,
|
||||
"mapOptionsChanged": CustomEvent<>,
|
||||
"commandModeOptionsChanged": CustomEvent<>,
|
||||
"contactsUpdated": CustomEvent<Unit>,
|
||||
"activeCoalitionChanged": CustomEvent<>
|
||||
|
||||
@@ -13,7 +13,6 @@ import { TemporaryUnitMarker } from "./markers/temporaryunitmarker";
|
||||
import { ClickableMiniMap } from "./clickableminimap";
|
||||
import { SVGInjector } from '@tanem/svg-injector'
|
||||
import { mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, MOVE_UNIT, SHOW_UNIT_CONTACTS, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, SHOW_UNIT_LABELS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS, FILL_SELECTED_RING, MAP_MARKER_CONTROLS } from "../constants/constants";
|
||||
import { TargetMarker } from "./markers/targetmarker";
|
||||
import { CoalitionArea } from "./coalitionarea/coalitionarea";
|
||||
import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu";
|
||||
import { DrawingCursor } from "./coalitionarea/drawingcursor";
|
||||
@@ -27,9 +26,9 @@ var hasTouchScreen = false;
|
||||
//if ("maxTouchPoints" in navigator)
|
||||
// hasTouchScreen = navigator.maxTouchPoints > 0;
|
||||
|
||||
if (hasTouchScreen)
|
||||
if (hasTouchScreen)
|
||||
L.Map.addInitHook('addHandler', 'boxSelect', TouchBoxSelect);
|
||||
else
|
||||
else
|
||||
L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect);
|
||||
|
||||
L.Map.addInitHook("addHandler", "gestureHandling", GestureHandling);
|
||||
@@ -38,10 +37,10 @@ L.Map.addInitHook("addHandler", "gestureHandling", GestureHandling);
|
||||
require("../../public/javascripts/leaflet.nauticscale.js")
|
||||
require("../../public/javascripts/L.Path.Drag.js")
|
||||
|
||||
export type MapMarkerControl = {
|
||||
export type MapMarkerVisibilityControl = {
|
||||
"image": string;
|
||||
"isProtected"?: boolean,
|
||||
"name":string,
|
||||
"name": string,
|
||||
"protectable"?: boolean,
|
||||
"toggles": string[],
|
||||
"tooltip": string
|
||||
@@ -75,7 +74,6 @@ export class Map extends L.Map {
|
||||
#destinationRotationCenter: L.LatLng | null = null;
|
||||
#coalitionAreas: CoalitionArea[] = [];
|
||||
|
||||
#targetCursor: TargetMarker = new TargetMarker(new L.LatLng(0, 0), { interactive: false });
|
||||
#destinationPreviewCursors: DestinationPreviewMarker[] = [];
|
||||
#drawingCursor: DrawingCursor = new DrawingCursor();
|
||||
#destinationPreviewHandle: DestinationPreviewHandle = new DestinationPreviewHandle(new L.LatLng(0, 0));
|
||||
@@ -90,7 +88,7 @@ export class Map extends L.Map {
|
||||
#coalitionAreaContextMenu: CoalitionAreaContextMenu = new CoalitionAreaContextMenu("coalition-area-contextmenu");
|
||||
|
||||
#mapSourceDropdown: Dropdown;
|
||||
#mapMarkerControls:MapMarkerControl[] = MAP_MARKER_CONTROLS;
|
||||
#mapMarkerVisibilityControls: MapMarkerVisibilityControl[] = MAP_MARKER_CONTROLS;
|
||||
#mapVisibilityOptionsDropdown: Dropdown;
|
||||
#optionButtons: { [key: string]: HTMLButtonElement[] } = {}
|
||||
#visibilityOptions: { [key: string]: boolean } = {}
|
||||
@@ -100,21 +98,21 @@ export class Map extends L.Map {
|
||||
*
|
||||
* @param ID - the ID of the HTML element which will contain the context menu
|
||||
*/
|
||||
constructor(ID: string){
|
||||
constructor(ID: string) {
|
||||
/* Init the leaflet map */
|
||||
super(ID, {
|
||||
preferCanvas: true,
|
||||
doubleClickZoom: false,
|
||||
zoomControl: false,
|
||||
boxZoom: false,
|
||||
super(ID, {
|
||||
preferCanvas: true,
|
||||
doubleClickZoom: false,
|
||||
zoomControl: false,
|
||||
boxZoom: false,
|
||||
//@ts-ignore Needed because the boxSelect option is non-standard
|
||||
boxSelect: true,
|
||||
zoomAnimation: true,
|
||||
boxSelect: true,
|
||||
zoomAnimation: true,
|
||||
maxBoundsViscosity: 1.0,
|
||||
minZoom: 7,
|
||||
minZoom: 7,
|
||||
keyboard: true,
|
||||
keyboardPanDelta: 0,
|
||||
gestureHandling: hasTouchScreen
|
||||
gestureHandling: hasTouchScreen
|
||||
});
|
||||
this.setView([37.23, -115.8], 10);
|
||||
|
||||
@@ -198,15 +196,15 @@ export class Map extends L.Map {
|
||||
this.#panToUnit(this.#centerUnit);
|
||||
});
|
||||
|
||||
document.addEventListener("mapVisibilityOptionsChanged", () => {
|
||||
document.addEventListener("mapOptionsChanged", () => {
|
||||
this.getContainer().toggleAttribute("data-hide-labels", !this.getVisibilityOptions()[SHOW_UNIT_LABELS]);
|
||||
});
|
||||
|
||||
/* Pan interval */
|
||||
this.#panInterval = window.setInterval(() => {
|
||||
if (this.#panUp || this.#panDown || this.#panRight || this.#panLeft)
|
||||
this.panBy(new L.Point(((this.#panLeft ? -1 : 0) + (this.#panRight ? 1 : 0)) * this.#deafultPanDelta,
|
||||
((this.#panUp ? -1 : 0) + (this.#panDown ? 1 : 0)) * this.#deafultPanDelta));
|
||||
this.panBy(new L.Point(((this.#panLeft ? -1 : 0) + (this.#panRight ? 1 : 0)) * this.#deafultPanDelta * (this.#shiftKey ? 3 : 1),
|
||||
((this.#panUp ? -1 : 0) + (this.#panDown ? 1 : 0)) * this.#deafultPanDelta * (this.#shiftKey ? 3 : 1)));
|
||||
}, 20);
|
||||
|
||||
/* Option buttons */
|
||||
@@ -257,7 +255,7 @@ export class Map extends L.Map {
|
||||
|
||||
/* Operations to perform if you are NOT in a state */
|
||||
if (this.#state !== COALITIONAREA_DRAW_POLYGON) {
|
||||
this.#deselectCoalitionAreas();
|
||||
this.#deselectSelectedCoalitionArea();
|
||||
}
|
||||
|
||||
/* Operations to perform if you ARE in a state */
|
||||
@@ -291,7 +289,6 @@ export class Map extends L.Map {
|
||||
else {
|
||||
this.#hiddenTypes.push(key);
|
||||
}
|
||||
Object.values(getApp().getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility());
|
||||
}
|
||||
|
||||
getHiddenTypes() {
|
||||
@@ -377,11 +374,6 @@ export class Map extends L.Map {
|
||||
this.#coalitionAreaContextMenu.hide();
|
||||
}
|
||||
|
||||
isZooming() {
|
||||
return this.#isZooming;
|
||||
}
|
||||
|
||||
/* Mouse coordinates */
|
||||
getMousePosition() {
|
||||
return this.#lastMousePosition;
|
||||
}
|
||||
@@ -390,11 +382,6 @@ export class Map extends L.Map {
|
||||
return this.containerPointToLatLng(this.#lastMousePosition);
|
||||
}
|
||||
|
||||
/* Spawn from air base */
|
||||
spawnFromAirbase(e: any) {
|
||||
//this.#aircraftSpawnMenu(e);
|
||||
}
|
||||
|
||||
centerOnUnit(ID: number | null) {
|
||||
if (ID != null) {
|
||||
this.options.scrollWheelZoom = 'center';
|
||||
@@ -407,7 +394,7 @@ export class Map extends L.Map {
|
||||
this.#updateCursor();
|
||||
}
|
||||
|
||||
getCenterUnit() {
|
||||
getCenteredOnUnit() {
|
||||
return this.#centerUnit;
|
||||
}
|
||||
|
||||
@@ -420,7 +407,6 @@ export class Map extends L.Map {
|
||||
}
|
||||
|
||||
this.setView(bounds.getCenter(), 8);
|
||||
//this.setMaxBounds(bounds);
|
||||
|
||||
if (this.#miniMap)
|
||||
this.#miniMap.remove();
|
||||
@@ -502,10 +488,35 @@ export class Map extends L.Map {
|
||||
return this.#visibilityOptions;
|
||||
}
|
||||
|
||||
isZooming() {
|
||||
return this.#isZooming;
|
||||
}
|
||||
|
||||
getPreviousZoom() {
|
||||
return this.#previousZoom;
|
||||
}
|
||||
|
||||
getIsUnitProtected(unit: Unit) {
|
||||
const toggles = this.#mapMarkerVisibilityControls.reduce((list, control: MapMarkerVisibilityControl) => {
|
||||
if (control.isProtected) {
|
||||
list = list.concat(control.toggles);
|
||||
}
|
||||
return list;
|
||||
}, [] as string[]);
|
||||
|
||||
if (toggles.length === 0)
|
||||
return false;
|
||||
|
||||
return toggles.some((toggle: string) => {
|
||||
// Specific coding for robots - extend later if needed
|
||||
return (toggle === "dcs" && !unit.getControlled() && !unit.getHuman());
|
||||
});
|
||||
}
|
||||
|
||||
getMapMarkerVisibilityControls() {
|
||||
return this.#mapMarkerVisibilityControls;
|
||||
}
|
||||
|
||||
/* Event handlers */
|
||||
#onClick(e: any) {
|
||||
if (!this.#preventLeftClick) {
|
||||
@@ -560,19 +571,20 @@ export class Map extends L.Map {
|
||||
}
|
||||
}
|
||||
else if (this.#state === MOVE_UNIT) {
|
||||
if (!e.originalEvent.ctrlKey) {
|
||||
getApp().getUnitsManager().clearDestinations();
|
||||
if (!e.originalEvent.shiftKey) {
|
||||
if (!e.originalEvent.ctrlKey) {
|
||||
getApp().getUnitsManager().clearDestinations();
|
||||
}
|
||||
getApp().getUnitsManager().addDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation)
|
||||
|
||||
this.#destinationGroupRotation = 0;
|
||||
this.#destinationRotationCenter = null;
|
||||
this.#computeDestinationRotation = false;
|
||||
}
|
||||
getApp().getUnitsManager().addDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation)
|
||||
|
||||
this.#destinationGroupRotation = 0;
|
||||
this.#destinationRotationCenter = null;
|
||||
this.#computeDestinationRotation = false;
|
||||
}
|
||||
else {
|
||||
this.setState(IDLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#onSelectionStart(e: any) {
|
||||
@@ -616,7 +628,7 @@ export class Map extends L.Map {
|
||||
units.forEach((unit: Unit) => {
|
||||
unit.appendContextActions(contextActionSet, null, e.latlng);
|
||||
})
|
||||
|
||||
|
||||
if (Object.keys(contextActionSet.getContextActions()).length > 0) {
|
||||
getApp().getMap().showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng);
|
||||
getApp().getMap().getUnitContextMenu().setContextActions(contextActionSet);
|
||||
@@ -626,6 +638,16 @@ export class Map extends L.Map {
|
||||
}
|
||||
|
||||
#onMouseUp(e: any) {
|
||||
if (this.#state === MOVE_UNIT && e.originalEvent.button == 2 && e.originalEvent.shiftKey) {
|
||||
if (!e.originalEvent.ctrlKey) {
|
||||
getApp().getUnitsManager().clearDestinations();
|
||||
}
|
||||
getApp().getUnitsManager().addDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation)
|
||||
|
||||
this.#destinationGroupRotation = 0;
|
||||
this.#destinationRotationCenter = null;
|
||||
this.#computeDestinationRotation = false;
|
||||
}
|
||||
}
|
||||
|
||||
#onMouseMove(e: any) {
|
||||
@@ -677,6 +699,7 @@ export class Map extends L.Map {
|
||||
this.#isZooming = false;
|
||||
}
|
||||
|
||||
/* */
|
||||
#panToUnit(unit: Unit) {
|
||||
var unitPosition = new L.LatLng(unit.getPosition().lat, unit.getPosition().lng);
|
||||
this.setView(unitPosition, this.getZoom(), { animate: false });
|
||||
@@ -691,10 +714,10 @@ export class Map extends L.Map {
|
||||
|
||||
#createUnitMarkerControlButtons() {
|
||||
const unitVisibilityControls = <HTMLElement>document.getElementById("unit-visibility-control");
|
||||
const makeTitle = (isProtected:boolean) => {
|
||||
return ( isProtected ) ? "Unit type is protected and will ignore orders" : "Unit is NOT protected and will respond to orders";
|
||||
const makeTitle = (isProtected: boolean) => {
|
||||
return (isProtected) ? "Unit type is protected and will ignore orders" : "Unit is NOT protected and will respond to orders";
|
||||
}
|
||||
this.getMapMarkerControls().forEach( (control:MapMarkerControl) => {
|
||||
this.getMapMarkerVisibilityControls().forEach((control: MapMarkerVisibilityControl) => {
|
||||
const toggles = `["${control.toggles.join('","')}"]`;
|
||||
const div = document.createElement("div");
|
||||
div.className = control.protectable === true ? "protectable" : "";
|
||||
@@ -707,7 +730,7 @@ export class Map extends L.Map {
|
||||
`;
|
||||
unitVisibilityControls.appendChild(div);
|
||||
|
||||
if ( control.protectable ) {
|
||||
if (control.protectable) {
|
||||
div.innerHTML += `
|
||||
<button class="lock" ${control.isProtected ? "data-protected" : ""} title="${makeTitle(control.isProtected || false)}">
|
||||
<img src="/resources/theme/images/buttons/other/lock-solid.svg" class="locked" />
|
||||
@@ -715,10 +738,10 @@ export class Map extends L.Map {
|
||||
</button>`;
|
||||
|
||||
const btn = <HTMLButtonElement>div.querySelector("button.lock");
|
||||
btn.addEventListener("click", (ev:MouseEventInit) => {
|
||||
btn.addEventListener("click", (ev: MouseEventInit) => {
|
||||
control.isProtected = !control.isProtected;
|
||||
btn.toggleAttribute("data-protected", control.isProtected);
|
||||
btn.title = makeTitle( control.isProtected );
|
||||
btn.title = makeTitle(control.isProtected);
|
||||
document.dispatchEvent(new CustomEvent("toggleMarkerProtection", {
|
||||
detail: {
|
||||
"_element": btn,
|
||||
@@ -732,28 +755,32 @@ export class Map extends L.Map {
|
||||
unitVisibilityControls.querySelectorAll(`img[src$=".svg"]`).forEach(img => SVGInjector(img));
|
||||
}
|
||||
|
||||
unitIsProtected(unit:Unit) {
|
||||
const toggles = this.#mapMarkerControls.reduce((list, control:MapMarkerControl) => {
|
||||
if (control.isProtected) {
|
||||
list = list.concat(control.toggles);
|
||||
}
|
||||
return list;
|
||||
}, [] as string[]);
|
||||
|
||||
if (toggles.length === 0)
|
||||
return false;
|
||||
|
||||
return toggles.some((toggle:string) => {
|
||||
// Specific coding for robots - extend later if needed
|
||||
return (toggle === "dcs" && !unit.getControlled() && !unit.getHuman());
|
||||
});
|
||||
}
|
||||
|
||||
#deselectCoalitionAreas() {
|
||||
#deselectSelectedCoalitionArea() {
|
||||
this.getSelectedCoalitionArea()?.setSelected(false);
|
||||
}
|
||||
|
||||
/* Cursors */
|
||||
#updateCursor() {
|
||||
/* If the ctrl key is being pressed or we are performing an area selection, show the default cursor */
|
||||
if (this.#ctrlKey || this.#selecting) {
|
||||
/* Hide all non default cursors */
|
||||
this.#hideDestinationCursors();
|
||||
this.#hideDrawingCursor();
|
||||
|
||||
this.#showDefaultCursor();
|
||||
} else {
|
||||
/* Hide all the unnecessary cursors depending on the active state */
|
||||
if (this.#state !== IDLE) this.#hideDefaultCursor();
|
||||
if (this.#state !== MOVE_UNIT) this.#hideDestinationCursors();
|
||||
if (this.#state !== COALITIONAREA_DRAW_POLYGON) this.#hideDrawingCursor();
|
||||
|
||||
/* Show the active cursor depending on the active state */
|
||||
if (this.#state === IDLE) this.#showDefaultCursor();
|
||||
else if (this.#state === MOVE_UNIT) this.#showDestinationCursors();
|
||||
else if (this.#state === COALITIONAREA_DRAW_POLYGON) this.#showDrawingCursor();
|
||||
}
|
||||
}
|
||||
|
||||
#showDefaultCursor() {
|
||||
document.getElementById(this.#ID)?.classList.remove("hidden-cursor");
|
||||
}
|
||||
@@ -766,48 +793,47 @@ export class Map extends L.Map {
|
||||
const singleCursor = !this.#shiftKey;
|
||||
const selectedUnitsCount = getApp().getUnitsManager().getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: true }).length;
|
||||
if (singleCursor) {
|
||||
if ( this.#destinationPreviewCursors.length != 1) {
|
||||
this.#hideDestinationCursors();
|
||||
var marker = new DestinationPreviewMarker(this.getMouseCoordinates(), { interactive: false });
|
||||
marker.addTo(this);
|
||||
this.#destinationPreviewCursors = [marker];
|
||||
}
|
||||
|
||||
this.#destinationPreviewHandleLine.removeFrom(this);
|
||||
this.#destinationPreviewHandle.removeFrom(this);
|
||||
this.#hideDestinationCursors();
|
||||
}
|
||||
else if (!singleCursor) {
|
||||
while (this.#destinationPreviewCursors.length > selectedUnitsCount) {
|
||||
this.removeLayer(this.#destinationPreviewCursors[0]);
|
||||
this.#destinationPreviewCursors.splice(0, 1);
|
||||
if (selectedUnitsCount > 1) {
|
||||
while (this.#destinationPreviewCursors.length > selectedUnitsCount) {
|
||||
this.removeLayer(this.#destinationPreviewCursors[0]);
|
||||
this.#destinationPreviewCursors.splice(0, 1);
|
||||
}
|
||||
|
||||
this.#destinationPreviewHandleLine.addTo(this);
|
||||
this.#destinationPreviewHandle.addTo(this);
|
||||
|
||||
while (this.#destinationPreviewCursors.length < selectedUnitsCount) {
|
||||
var cursor = new DestinationPreviewMarker(this.getMouseCoordinates(), { interactive: false });
|
||||
cursor.addTo(this);
|
||||
this.#destinationPreviewCursors.push(cursor);
|
||||
}
|
||||
|
||||
this.#updateDestinationCursors();
|
||||
}
|
||||
|
||||
this.#destinationPreviewHandleLine.addTo(this);
|
||||
this.#destinationPreviewHandle.addTo(this);
|
||||
|
||||
while (this.#destinationPreviewCursors.length < selectedUnitsCount) {
|
||||
var cursor = new DestinationPreviewMarker(this.getMouseCoordinates(), { interactive: false });
|
||||
cursor.addTo(this);
|
||||
this.#destinationPreviewCursors.push(cursor);
|
||||
}
|
||||
|
||||
this.#updateDestinationCursors();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#updateDestinationCursors() {
|
||||
const groupLatLng = this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : this.getMouseCoordinates();
|
||||
if (this.#destinationPreviewCursors.length == 1)
|
||||
this.#destinationPreviewCursors[0].setLatLng(this.getMouseCoordinates());
|
||||
else {
|
||||
Object.values(getApp().getUnitsManager().computeGroupDestination(groupLatLng, this.#destinationGroupRotation)).forEach((latlng: L.LatLng, idx: number) => {
|
||||
if (idx < this.#destinationPreviewCursors.length)
|
||||
this.#destinationPreviewCursors[idx].setLatLng(this.#shiftKey ? latlng : this.getMouseCoordinates());
|
||||
})
|
||||
};
|
||||
const selectedUnitsCount = getApp().getUnitsManager().getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: true }).length;
|
||||
if (selectedUnitsCount > 1) {
|
||||
const groupLatLng = this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : this.getMouseCoordinates();
|
||||
if (this.#destinationPreviewCursors.length == 1)
|
||||
this.#destinationPreviewCursors[0].setLatLng(this.getMouseCoordinates());
|
||||
else {
|
||||
Object.values(getApp().getUnitsManager().computeGroupDestination(groupLatLng, this.#destinationGroupRotation)).forEach((latlng: L.LatLng, idx: number) => {
|
||||
if (idx < this.#destinationPreviewCursors.length)
|
||||
this.#destinationPreviewCursors[idx].setLatLng(this.#shiftKey ? latlng : this.getMouseCoordinates());
|
||||
})
|
||||
};
|
||||
|
||||
this.#destinationPreviewHandleLine.setLatLngs([groupLatLng, this.getMouseCoordinates()]);
|
||||
this.#destinationPreviewHandle.setLatLng(this.getMouseCoordinates());
|
||||
this.#destinationPreviewHandleLine.setLatLngs([groupLatLng, this.getMouseCoordinates()]);
|
||||
this.#destinationPreviewHandle.setLatLng(this.getMouseCoordinates());
|
||||
} else {
|
||||
this.#hideDestinationCursors();
|
||||
}
|
||||
}
|
||||
|
||||
#hideDestinationCursors() {
|
||||
@@ -838,34 +864,9 @@ export class Map extends L.Map {
|
||||
this.#drawingCursor.removeFrom(this);
|
||||
}
|
||||
|
||||
#updateCursor() {
|
||||
/* If the ctrl key is being pressed or we are performing an area selection, show the default cursor */
|
||||
if (this.#ctrlKey || this.#selecting) {
|
||||
/* Hide all non default cursors */
|
||||
this.#hideDestinationCursors();
|
||||
this.#hideDrawingCursor();
|
||||
|
||||
this.#showDefaultCursor();
|
||||
} else {
|
||||
/* Hide all the unnecessary cursors depending on the active state */
|
||||
if (this.#state !== IDLE) this.#hideDefaultCursor();
|
||||
if (this.#state !== MOVE_UNIT) this.#hideDestinationCursors();
|
||||
if (this.#state !== COALITIONAREA_DRAW_POLYGON) this.#hideDrawingCursor();
|
||||
|
||||
/* Show the active cursor depending on the active state */
|
||||
if (this.#state === IDLE) this.#showDefaultCursor();
|
||||
else if (this.#state === MOVE_UNIT) this.#showDestinationCursors();
|
||||
else if (this.#state === COALITIONAREA_DRAW_POLYGON) this.#showDrawingCursor();
|
||||
}
|
||||
}
|
||||
|
||||
#setVisibilityOption(option: string, ev: any) {
|
||||
this.#visibilityOptions[option] = ev.currentTarget.checked;
|
||||
document.dispatchEvent(new CustomEvent("mapVisibilityOptionsChanged"));
|
||||
}
|
||||
|
||||
getMapMarkerControls() {
|
||||
return this.#mapMarkerControls;
|
||||
document.dispatchEvent(new CustomEvent("mapOptionsChanged"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import { WeaponsManager } from "./weapon/weaponsmanager";
|
||||
import { Manager } from "./other/manager";
|
||||
import { SVGInjector } from "@tanem/svg-injector";
|
||||
import { ServerManager } from "./server/servermanager";
|
||||
import { sha256 } from 'js-sha256';
|
||||
|
||||
import { BLUE_COMMANDER, FILL_SELECTED_RING, GAME_MASTER, HIDE_UNITS_SHORT_RANGE_RINGS, RED_COMMANDER, SHOW_UNITS_ACQUISITION_RINGS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNIT_LABELS } from "./constants/constants";
|
||||
import { aircraftDatabase } from "./unit/databases/aircraftdatabase";
|
||||
@@ -231,11 +232,21 @@ export class OlympusApp {
|
||||
this.#setupEvents();
|
||||
|
||||
/* Set the splash background image to a random image */
|
||||
var splashScreen = document.getElementById("splash-screen");
|
||||
if (splashScreen) {
|
||||
let i = Math.round(Math.random() * 7 + 1);
|
||||
let splashScreen = document.getElementById("splash-screen") as HTMLElement;
|
||||
let i = Math.round(Math.random() * 7 + 1);
|
||||
|
||||
new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
image.addEventListener('load', resolve);
|
||||
image.addEventListener('error', resolve);
|
||||
image.src = `/resources/theme/images/splash/${i}.jpg`;
|
||||
}).then(() => {
|
||||
splashScreen.style.backgroundImage = `url('/resources/theme/images/splash/${i}.jpg')`;
|
||||
}
|
||||
let loadingScreen = document.getElementById("loading-screen") as HTMLElement;
|
||||
loadingScreen.classList.add("fade-out");
|
||||
window.setInterval(() => { loadingScreen.classList.add("hide"); }, 1000);
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
#setupEvents() {
|
||||
@@ -408,8 +419,9 @@ export class OlympusApp {
|
||||
loginForm.addEventListener("submit", (ev:SubmitEvent) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
var hash = sha256.create();
|
||||
const username = (loginForm.querySelector("#username") as HTMLInputElement).value;
|
||||
const password = (loginForm.querySelector("#password") as HTMLInputElement).value;
|
||||
const password = hash.update((loginForm.querySelector("#password") as HTMLInputElement).value).hex();
|
||||
|
||||
// Update the user credentials
|
||||
this.getServerManager().setCredentials(username, password);
|
||||
|
||||
@@ -33,36 +33,36 @@ export class UnitControlPanel extends Panel {
|
||||
*
|
||||
* @param ID - the ID of the HTML element which will contain the context menu
|
||||
*/
|
||||
constructor(ID: string){
|
||||
constructor(ID: string) {
|
||||
super(ID);
|
||||
|
||||
/* Unit control sliders */
|
||||
this.#altitudeSlider = new Slider("altitude-slider", 0, 100, "ft", (value: number) => { getApp().getUnitsManager().setAltitude(ftToM(value)); });
|
||||
this.#altitudeTypeSwitch = new Switch("altitude-type-switch", (value: boolean) => { getApp().getUnitsManager().setAltitudeType(value? "ASL": "AGL"); });
|
||||
this.#altitudeTypeSwitch = new Switch("altitude-type-switch", (value: boolean) => { getApp().getUnitsManager().setAltitudeType(value ? "ASL" : "AGL"); });
|
||||
|
||||
this.#speedSlider = new Slider("speed-slider", 0, 100, "kts", (value: number) => { getApp().getUnitsManager().setSpeed(knotsToMs(value)); });
|
||||
this.#speedTypeSwitch = new Switch("speed-type-switch", (value: boolean) => { getApp().getUnitsManager().setSpeedType(value? "CAS": "GS"); });
|
||||
this.#speedTypeSwitch = new Switch("speed-type-switch", (value: boolean) => { getApp().getUnitsManager().setSpeedType(value ? "CAS" : "GS"); });
|
||||
|
||||
/* Option buttons */
|
||||
// Reversing the ROEs so that the least "aggressive" option is always on the left
|
||||
this.#optionButtons["ROE"] = ROEs.slice(0).reverse().map((option: string, index: number) => {
|
||||
return this.#createOptionButton(option, `roe/${option.toLowerCase()}.svg`, ROEDescriptions.slice(0).reverse()[index], () => { getApp().getUnitsManager().setROE(option); });
|
||||
}).filter((button: HTMLButtonElement, index: number) => {return ROEs[index] !== "";});
|
||||
}).filter((button: HTMLButtonElement, index: number) => { return ROEs[index] !== ""; });
|
||||
|
||||
this.#optionButtons["reactionToThreat"] = reactionsToThreat.map((option: string, index: number) => {
|
||||
return this.#createOptionButton(option, `threat/${option.toLowerCase()}.svg`, reactionsToThreatDescriptions[index],() => { getApp().getUnitsManager().setReactionToThreat(option); });
|
||||
return this.#createOptionButton(option, `threat/${option.toLowerCase()}.svg`, reactionsToThreatDescriptions[index], () => { getApp().getUnitsManager().setReactionToThreat(option); });
|
||||
});
|
||||
|
||||
this.#optionButtons["emissionsCountermeasures"] = emissionsCountermeasures.map((option: string, index: number) => {
|
||||
return this.#createOptionButton(option, `emissions/${option.toLowerCase()}.svg`, emissionsCountermeasuresDescriptions[index],() => { getApp().getUnitsManager().setEmissionsCountermeasures(option); });
|
||||
return this.#createOptionButton(option, `emissions/${option.toLowerCase()}.svg`, emissionsCountermeasuresDescriptions[index], () => { getApp().getUnitsManager().setEmissionsCountermeasures(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().setShotsScatter(option); });
|
||||
return this.#createOptionButton(option.toString(), `scatter/${option.toString().toLowerCase()}.svg`, shotsScatterDescriptions[index], () => { getApp().getUnitsManager().setShotsScatter(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().setShotsIntensity(option); });
|
||||
return this.#createOptionButton(option.toString(), `intensity/${option.toString().toLowerCase()}.svg`, shotsIntensityDescriptions[index], () => { getApp().getUnitsManager().setShotsIntensity(option); });
|
||||
});
|
||||
|
||||
this.getElement().querySelector("#roe-buttons-container")?.append(...this.#optionButtons["ROE"]);
|
||||
@@ -107,48 +107,50 @@ export class UnitControlPanel extends Panel {
|
||||
/* Mouseover of (?) highlights activation buttons */
|
||||
const operateAsQuestionMark = <HTMLElement>this.getElement().querySelector("#operate-as h4 img");
|
||||
operateAsQuestionMark.addEventListener("mouseover", () => {
|
||||
document.querySelectorAll(`#rapid-controls button.scenic-action`).forEach((btn:Element) => {
|
||||
document.querySelectorAll(`#rapid-controls button.scenic-action`).forEach((btn: Element) => {
|
||||
btn.classList.add(`pulse`);
|
||||
});
|
||||
});
|
||||
operateAsQuestionMark.addEventListener("mouseout", () => {
|
||||
document.querySelectorAll(`#rapid-controls button.scenic-action.pulse`).forEach((btn:Element) => {
|
||||
document.querySelectorAll(`#rapid-controls button.scenic-action.pulse`).forEach((btn: Element) => {
|
||||
btn.classList.remove(`pulse`);
|
||||
});
|
||||
});
|
||||
|
||||
/* Advanced settings dialog */
|
||||
this.#advancedSettingsDialog = <HTMLElement> document.querySelector("#advanced-settings-dialog");
|
||||
this.#advancedSettingsDialog = <HTMLElement>document.querySelector("#advanced-settings-dialog");
|
||||
|
||||
/* Advanced settings dropdowns */
|
||||
this.#TACANXYDropdown = new Dropdown("TACAN-XY", () => {});
|
||||
this.#TACANXYDropdown = new Dropdown("TACAN-XY", () => { });
|
||||
this.#TACANXYDropdown.setOptions(["X", "Y"]);
|
||||
this.#radioDecimalsDropdown = new Dropdown("radio-decimals", () => {});
|
||||
this.#radioDecimalsDropdown = new Dropdown("radio-decimals", () => { });
|
||||
this.#radioDecimalsDropdown.setOptions([".000", ".250", ".500", ".750"]);
|
||||
this.#radioCallsignDropdown = new Dropdown("radio-callsign", () => {});
|
||||
this.#radioCallsignDropdown = new Dropdown("radio-callsign", () => { });
|
||||
this.#deleteDropdown = new Dropdown("delete-options", () => { });
|
||||
|
||||
/* Events and timer */
|
||||
window.setInterval(() => {this.update();}, 25);
|
||||
window.setInterval(() => { this.update(); }, 25);
|
||||
|
||||
document.addEventListener("unitsSelection", (e: CustomEvent<Unit[]>) => {
|
||||
this.show();
|
||||
document.addEventListener("unitsSelection", (e: CustomEvent<Unit[]>) => {
|
||||
this.show();
|
||||
this.addButtons();
|
||||
this.#updateRapidControls();
|
||||
this.#updateRapidControls();
|
||||
});
|
||||
document.addEventListener("clearSelection", () => {
|
||||
document.addEventListener("clearSelection", () => {
|
||||
this.hide();
|
||||
this.#updateRapidControls();
|
||||
this.#updateRapidControls();
|
||||
});
|
||||
document.addEventListener("applyAdvancedSettings", () => {this.#applyAdvancedSettings();})
|
||||
document.addEventListener("applyAdvancedSettings", () => { this.#applyAdvancedSettings(); })
|
||||
document.addEventListener("showAdvancedSettings", () => {
|
||||
this.#updateAdvancedSettingsDialog(getApp().getUnitsManager().getSelectedUnits());
|
||||
this.#advancedSettingsDialog.classList.remove("hide");
|
||||
});
|
||||
|
||||
/* This is for when a ctrl-click happens on the map for deselection and we need to remove the selected unit from the panel */
|
||||
document.addEventListener( "unitsDeselection", ( ev:CustomEventInit ) => {
|
||||
this.getElement().querySelector( `button[data-unit-id="${ev.detail.ID}"]` )?.remove();
|
||||
this.#updateRapidControls();
|
||||
document.addEventListener("unitsDeselection", (ev: CustomEventInit) => {
|
||||
this.show();
|
||||
this.addButtons();
|
||||
this.#updateRapidControls();
|
||||
});
|
||||
|
||||
window.addEventListener("resize", (e: any) => this.#calculateMaxHeight());
|
||||
@@ -156,16 +158,16 @@ export class UnitControlPanel extends Panel {
|
||||
const element = document.getElementById("toolbar-container");
|
||||
if (element)
|
||||
new ResizeObserver(() => this.#calculateTop()).observe(element);
|
||||
|
||||
|
||||
this.#calculateMaxHeight()
|
||||
this.hide();
|
||||
}
|
||||
|
||||
show() {
|
||||
const context = getApp().getCurrentContext();
|
||||
if ( !context.getUseUnitControlPanel() )
|
||||
if (!context.getUseUnitControlPanel())
|
||||
return;
|
||||
|
||||
|
||||
super.show();
|
||||
this.#speedTypeSwitch.resetExpectedValue();
|
||||
this.#altitudeTypeSwitch.resetExpectedValue();
|
||||
@@ -182,26 +184,26 @@ export class UnitControlPanel extends Panel {
|
||||
addButtons() {
|
||||
this.#units = getApp().getUnitsManager().getSelectedUnits();
|
||||
this.#selectedUnitsTypes = getApp().getUnitsManager().getSelectedUnitsCategories();
|
||||
|
||||
|
||||
if (this.#units.length < 20) {
|
||||
this.getElement().querySelector("#selected-units-container")?.replaceChildren(...this.#units.map((unit: Unit, index: number) => {
|
||||
var button = document.createElement("button");
|
||||
var callsign = unit.getUnitName() || "";
|
||||
var label = unit.getDatabase()?.getByName(unit.getName())?.label || unit.getName();
|
||||
|
||||
button.setAttribute("data-unit-id", "" + unit.ID );
|
||||
button.setAttribute("data-unit-id", "" + unit.ID);
|
||||
button.setAttribute("data-label", label);
|
||||
button.setAttribute("data-callsign", callsign);
|
||||
|
||||
button.setAttribute("data-coalition", unit.getCoalition());
|
||||
button.classList.add("pill", "highlight-coalition")
|
||||
|
||||
button.addEventListener("click", ( ev:MouseEventInit ) => {
|
||||
button.addEventListener("click", (ev: MouseEventInit) => {
|
||||
// Ctrl-click deselection
|
||||
if ( ev.ctrlKey === true && ev.shiftKey === false && ev.altKey === false ) {
|
||||
getApp().getUnitsManager().deselectUnit( unit.ID );
|
||||
if (ev.ctrlKey === true && ev.shiftKey === false && ev.altKey === false) {
|
||||
getApp().getUnitsManager().deselectUnit(unit.ID);
|
||||
button.remove();
|
||||
// Deselect all
|
||||
// Deselect all
|
||||
} else {
|
||||
getApp().getUnitsManager().deselectAllUnits();
|
||||
getApp().getUnitsManager().selectUnit(unit.ID, true);
|
||||
@@ -217,14 +219,14 @@ export class UnitControlPanel extends Panel {
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.getVisible()){
|
||||
if (this.getVisible()) {
|
||||
const element = this.getElement();
|
||||
if (element != null && this.#units.length > 0) {
|
||||
/* Toggle visibility of control elements */
|
||||
var isTanker = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.isTanker();});
|
||||
var isAWACS = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.isAWACS();});
|
||||
var isActiveTanker = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getIsActiveTanker()});
|
||||
var isActiveAWACAS = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getIsActiveAWACS()});
|
||||
var isTanker = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.isTanker(); });
|
||||
var isAWACS = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.isAWACS(); });
|
||||
var isActiveTanker = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getIsActiveTanker() });
|
||||
var isActiveAWACAS = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getIsActiveAWACS() });
|
||||
|
||||
element.toggleAttribute("data-show-categories-tooltip", this.#selectedUnitsTypes.length > 1);
|
||||
element.toggleAttribute("data-show-speed-slider", this.#selectedUnitsTypes.length == 1);
|
||||
@@ -234,35 +236,35 @@ export class UnitControlPanel extends Panel {
|
||||
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-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")));
|
||||
element.toggleAttribute("data-show-follow-roads", (this.#selectedUnitsTypes.length == 1 && this.#selectedUnitsTypes.includes("GroundUnit")));
|
||||
element.toggleAttribute("data-show-operate-as", getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getCoalition()}) === "neutral");
|
||||
element.toggleAttribute("data-show-operate-as", getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getCoalition() }) === "neutral");
|
||||
|
||||
if (this.#units.length == 1) {
|
||||
if (isAWACS)
|
||||
if (isAWACS)
|
||||
element.toggleAttribute("data-show-advanced-settings-button", isActiveAWACAS);
|
||||
else if (isTanker)
|
||||
else if (isTanker)
|
||||
element.toggleAttribute("data-show-advanced-settings-button", isActiveTanker);
|
||||
else
|
||||
else
|
||||
element.toggleAttribute("data-show-advanced-settings-button", true);
|
||||
}
|
||||
|
||||
|
||||
if (this.#selectedUnitsTypes.length == 1) {
|
||||
/* Flight controls */
|
||||
var desiredAltitude = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitude()});
|
||||
var desiredAltitudeType = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitudeType()});
|
||||
var desiredSpeed = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeed()});
|
||||
var desiredSpeedType = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeedType()});
|
||||
var isActiveTanker = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getIsActiveTanker()});
|
||||
var isActiveAWACAS = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getIsActiveAWACS()});
|
||||
var onOff = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getOnOff()});
|
||||
var followRoads = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getFollowRoads()});
|
||||
var operateAs = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getOperateAs()});
|
||||
|
||||
this.#altitudeTypeSwitch.setValue(desiredAltitudeType != undefined? desiredAltitudeType == "ASL": undefined, false);
|
||||
this.#speedTypeSwitch.setValue(desiredSpeedType != undefined? desiredSpeedType == "CAS": undefined, false);
|
||||
var desiredAltitude = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getDesiredAltitude() });
|
||||
var desiredAltitudeType = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getDesiredAltitudeType() });
|
||||
var desiredSpeed = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getDesiredSpeed() });
|
||||
var desiredSpeedType = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getDesiredSpeedType() });
|
||||
var isActiveTanker = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getIsActiveTanker() });
|
||||
var isActiveAWACAS = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getIsActiveAWACS() });
|
||||
var onOff = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getOnOff() });
|
||||
var followRoads = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getFollowRoads() });
|
||||
var operateAs = getApp().getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getOperateAs() });
|
||||
|
||||
this.#altitudeTypeSwitch.setValue(desiredAltitudeType != undefined ? desiredAltitudeType == "ASL" : undefined, false);
|
||||
this.#speedTypeSwitch.setValue(desiredSpeedType != undefined ? desiredSpeedType == "CAS" : undefined, false);
|
||||
|
||||
this.#speedSlider.setMinMax(minSpeedValues[this.#selectedUnitsTypes[0]], maxSpeedValues[this.#selectedUnitsTypes[0]]);
|
||||
this.#altitudeSlider.setMinMax(minAltitudeValues[this.#selectedUnitsTypes[0]], maxAltitudeValues[this.#selectedUnitsTypes[0]]);
|
||||
@@ -307,7 +309,7 @@ export class UnitControlPanel extends Panel {
|
||||
this.#AWACSSwitch.setValue(isActiveAWACAS, false);
|
||||
this.#onOffSwitch.setValue(onOff, false);
|
||||
this.#followRoadsSwitch.setValue(followRoads, false);
|
||||
this.#operateAsSwitch.setValue(operateAs? operateAs === "blue": undefined, false);
|
||||
this.#operateAsSwitch.setValue(operateAs ? operateAs === "blue" : undefined, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,8 +318,8 @@ export class UnitControlPanel extends Panel {
|
||||
var contextActionSet = new ContextActionSet();
|
||||
var units = getApp().getUnitsManager().getSelectedUnits();
|
||||
|
||||
var showAltitudeChange = units.some((unit: Unit) => {return ["Aircraft", "Helicopter"].includes(unit.getCategory());});
|
||||
this.getElement().querySelector("#climb")?.classList.toggle("hide", !showAltitudeChange);
|
||||
var showAltitudeChange = units.some((unit: Unit) => { return ["Aircraft", "Helicopter"].includes(unit.getCategory()); });
|
||||
this.getElement().querySelector("#climb")?.classList.toggle("hide", !showAltitudeChange);
|
||||
this.getElement().querySelector("#descend")?.classList.toggle("hide", !showAltitudeChange);
|
||||
|
||||
units.forEach((unit: Unit) => {
|
||||
@@ -345,10 +347,8 @@ export class UnitControlPanel extends Panel {
|
||||
}
|
||||
}
|
||||
|
||||
#updateAdvancedSettingsDialog(units: Unit[])
|
||||
{
|
||||
if (units.length == 1)
|
||||
{
|
||||
#updateAdvancedSettingsDialog(units: Unit[]) {
|
||||
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;
|
||||
@@ -361,7 +361,7 @@ export class UnitControlPanel extends Panel {
|
||||
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];
|
||||
const isTanker = unit.isTanker();
|
||||
const isAWACS = unit.isAWACS();
|
||||
@@ -398,7 +398,7 @@ export class UnitControlPanel extends Panel {
|
||||
radioMhzInput.value = String(radioMHz);
|
||||
radioCallsignNumberInput.value = String(unit.getRadio().callsignNumber);
|
||||
this.#radioDecimalsDropdown.setValue("." + radioDecimals);
|
||||
|
||||
|
||||
if (isTanker) /* Set tanker specific options */
|
||||
this.#radioCallsignDropdown.setOptions(["Texaco", "Arco", "Shell"]);
|
||||
else if (isAWACS) /* Set AWACS specific options */
|
||||
@@ -412,8 +412,7 @@ export class UnitControlPanel extends Panel {
|
||||
}
|
||||
}
|
||||
|
||||
#applyAdvancedSettings()
|
||||
{
|
||||
#applyAdvancedSettings() {
|
||||
/* 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;
|
||||
@@ -429,7 +428,7 @@ export class UnitControlPanel extends Panel {
|
||||
|
||||
/* TACAN */
|
||||
const TACAN: TACAN = {
|
||||
isOn: TACANCheckbox.checked? true: false,
|
||||
isOn: TACANCheckbox.checked ? true : false,
|
||||
channel: Number(TACANChannelInput.value),
|
||||
XY: this.#TACANXYDropdown.getValue(),
|
||||
callsign: TACANCallsignInput.value as string
|
||||
@@ -441,18 +440,18 @@ export class UnitControlPanel extends Panel {
|
||||
const radio: Radio = {
|
||||
frequency: (radioMHz * 1000 + Number(radioDecimals.substring(1))) * 1000,
|
||||
callsign: this.#radioCallsignDropdown.getIndex() + 1,
|
||||
callsignNumber: Number(radioCallsignNumberInput.value)
|
||||
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
|
||||
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 = getApp().getUnitsManager().getSelectedUnits();
|
||||
// TODO: split setAdvancedOptions into setIsTanker, setIsAWACS, setAdvancedOptions
|
||||
|
||||
@@ -339,12 +339,14 @@ export class ServerManager {
|
||||
this.PUT(data, callback);
|
||||
}
|
||||
|
||||
// TODO: Remove coalition
|
||||
scenicAAA(ID: number, coalition: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "coalition": coalition }
|
||||
var data = { "scenicAAA": command }
|
||||
this.PUT(data, callback);
|
||||
}
|
||||
|
||||
// TODO: Remove coalition
|
||||
missOnPurpose(ID: number, coalition: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "coalition": coalition }
|
||||
var data = { "missOnPurpose": command }
|
||||
|
||||
@@ -190,15 +190,17 @@ export abstract class Unit extends CustomMarker {
|
||||
|
||||
/* Deselect units if they are hidden */
|
||||
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
|
||||
window.setTimeout(() => { this.setSelected(this.getSelected() && !this.getHidden()) }, 300);
|
||||
this.#updateMarker();
|
||||
this.setSelected(this.getSelected() && !this.getHidden());
|
||||
});
|
||||
|
||||
document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => {
|
||||
window.setTimeout(() => { this.setSelected(this.getSelected() && !this.getHidden()) }, 300);
|
||||
document.addEventListener("toggleMarkerVisibility", (ev: CustomEventInit) => {
|
||||
this.#updateMarker();
|
||||
this.setSelected(this.getSelected() && !this.getHidden());
|
||||
});
|
||||
|
||||
/* Update the marker when the visibility options change */
|
||||
document.addEventListener("mapVisibilityOptionsChanged", (ev: CustomEventInit) => {
|
||||
/* Update the marker when the options change */
|
||||
document.addEventListener("mapOptionsChanged", (ev: CustomEventInit) => {
|
||||
this.#updateMarker();
|
||||
|
||||
/* Circles don't like to be updated when the map is zooming */
|
||||
@@ -323,7 +325,7 @@ export abstract class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
/* If the unit is selected or if the view is centered on this unit, sent the update signal so that other elements like the UnitControlPanel can be updated. */
|
||||
if (this.getSelected() || getApp().getMap().getCenterUnit() === this)
|
||||
if (this.getSelected() || getApp().getMap().getCenteredOnUnit() === this)
|
||||
document.dispatchEvent(new CustomEvent("unitUpdated", { detail: this }));
|
||||
}
|
||||
|
||||
@@ -415,7 +417,7 @@ export abstract class Unit extends CustomMarker {
|
||||
else {
|
||||
this.#clearContacts();
|
||||
this.#clearPath();
|
||||
this.#clearTarget();
|
||||
this.#clearTargetPosition();
|
||||
}
|
||||
|
||||
/* When the group leader is selected, if grouping is active, all the other group members are also selected */
|
||||
@@ -684,14 +686,11 @@ export abstract class Unit extends CustomMarker {
|
||||
/* Hide the unit if it does not belong to the commanded coalition and it is not detected by a method that can pinpoint its location (RWR does not count) */
|
||||
(!this.belongsToCommandedCoalition() && (this.#detectionMethods.length == 0 || (this.#detectionMethods.length == 1 && this.#detectionMethods[0] === RWR))) ||
|
||||
/* Hide the unit if grouping is activated, the unit is not the group leader, it is not selected, and the zoom is higher than the grouping threshold */
|
||||
(getApp().getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && this.getCategory() == "GroundUnit" && getApp().getMap().getZoom() < GROUPING_ZOOM_TRANSITION &&
|
||||
(getApp().getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && !this.getSelected() && this.getCategory() == "GroundUnit" && getApp().getMap().getZoom() < GROUPING_ZOOM_TRANSITION &&
|
||||
(this.belongsToCommandedCoalition() || (!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0))));
|
||||
|
||||
/* Force dead units to be hidden */
|
||||
this.setHidden(hidden || !this.getAlive());
|
||||
|
||||
/* Force hidden units to be unselected */
|
||||
this.setSelected(this.getSelected() && !this.getHidden());
|
||||
}
|
||||
|
||||
setHidden(hidden: boolean) {
|
||||
@@ -775,7 +774,7 @@ export abstract class Unit extends CustomMarker {
|
||||
return this.getDatabaseEntry()?.canAAA === true;
|
||||
}
|
||||
|
||||
indirectFire() {
|
||||
isIndirectFire() {
|
||||
return this.getDatabaseEntry()?.indirectFire === true;
|
||||
}
|
||||
|
||||
@@ -932,6 +931,7 @@ export abstract class Unit extends CustomMarker {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Remove coalition
|
||||
scenicAAA() {
|
||||
var coalition = "neutral";
|
||||
if (this.getCoalition() === "red")
|
||||
@@ -941,6 +941,7 @@ export abstract class Unit extends CustomMarker {
|
||||
getApp().getServerManager().scenicAAA(this.ID, coalition);
|
||||
}
|
||||
|
||||
// TODO: Remove coalition
|
||||
missOnPurpose() {
|
||||
var coalition = "neutral";
|
||||
if (this.getCoalition() === "red")
|
||||
@@ -1254,11 +1255,13 @@ export abstract class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
#clearPath() {
|
||||
for (let WP in this.#pathMarkers) {
|
||||
getApp().getMap().removeLayer(this.#pathMarkers[WP]);
|
||||
if (this.#pathPolyline.getLatLngs().length != 0) {
|
||||
for (let WP in this.#pathMarkers) {
|
||||
getApp().getMap().removeLayer(this.#pathMarkers[WP]);
|
||||
}
|
||||
this.#pathMarkers = [];
|
||||
this.#pathPolyline.setLatLngs([]);
|
||||
}
|
||||
this.#pathMarkers = [];
|
||||
this.#pathPolyline.setLatLngs([]);
|
||||
}
|
||||
|
||||
#drawContacts() {
|
||||
@@ -1412,7 +1415,7 @@ export abstract class Unit extends CustomMarker {
|
||||
}
|
||||
}
|
||||
else
|
||||
this.#clearTarget();
|
||||
this.#clearTargetPosition();
|
||||
}
|
||||
|
||||
#drawTargetPosition(targetPosition: LatLng) {
|
||||
@@ -1424,7 +1427,7 @@ export abstract class Unit extends CustomMarker {
|
||||
this.#targetPositionPolyline.setLatLngs([new LatLng(this.#position.lat, this.#position.lng), new LatLng(targetPosition.lat, targetPosition.lng)])
|
||||
}
|
||||
|
||||
#clearTarget() {
|
||||
#clearTargetPosition() {
|
||||
if (getApp().getMap().hasLayer(this.#targetPositionMarker))
|
||||
this.#targetPositionMarker.removeFrom(getApp().getMap());
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { CoalitionArea } from "../map/coalitionarea/coalitionarea";
|
||||
import { groundUnitDatabase } from "./databases/groundunitdatabase";
|
||||
import { DELETE_CYCLE_TIME, DELETE_SLOW_THRESHOLD, DataIndexes, GAME_MASTER, IADSDensities, IDLE, MOVE_UNIT } from "../constants/constants";
|
||||
import { DataExtractor } from "../server/dataextractor";
|
||||
import { citiesDatabase } from "./citiesDatabase";
|
||||
import { citiesDatabase } from "./databases/citiesdatabase";
|
||||
import { aircraftDatabase } from "./databases/aircraftdatabase";
|
||||
import { helicopterDatabase } from "./databases/helicopterdatabase";
|
||||
import { navyUnitDatabase } from "./databases/navyunitdatabase";
|
||||
@@ -321,11 +321,13 @@ export class UnitsManager {
|
||||
getUnitsVariable(variableGetter: CallableFunction, units: Unit[]) {
|
||||
if (units.length == 0)
|
||||
return undefined;
|
||||
return units.map((unit: Unit) => {
|
||||
return variableGetter(unit);
|
||||
})?.reduce((a: any, b: any) => {
|
||||
return a === b ? a : undefined
|
||||
|
||||
var value: any = variableGetter(units[0]);
|
||||
units.forEach((unit: Unit) => {
|
||||
if (variableGetter(unit) !== value)
|
||||
return undefined;
|
||||
});
|
||||
return value;
|
||||
};
|
||||
|
||||
/** For a given unit, it returns if and how it is being detected by other units. NOTE: this function will return how a unit is being detected, i.e. how other units are detecting it. It will not return
|
||||
@@ -353,6 +355,7 @@ export class UnitsManager {
|
||||
* @param latlng Position of the new destination
|
||||
* @param mantainRelativePosition If true, the selected units will mantain their relative positions when reaching the target. This is useful to maintain a formation for groun/navy units
|
||||
* @param rotation Rotation in radians by which the formation will be rigidly rotated. E.g. a ( V ) formation will look like this ( < ) if rotated pi/4 radians (90 degrees)
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
addDestination(latlng: L.LatLng, mantainRelativePosition: boolean, rotation: number, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -412,6 +415,7 @@ export class UnitsManager {
|
||||
/** Instruct all the selected units to land at a specific location
|
||||
*
|
||||
* @param latlng Location where to land at
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
landAt(latlng: LatLng, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -428,6 +432,7 @@ export class UnitsManager {
|
||||
/** Instruct all the selected units to change their speed
|
||||
*
|
||||
* @param speedChange Speed change, either "stop", "slow", or "fast". The specific value depends on the unit category
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
changeSpeed(speedChange: string, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -442,6 +447,7 @@ export class UnitsManager {
|
||||
/** Instruct all the selected units to change their altitude
|
||||
*
|
||||
* @param altitudeChange Altitude change, either "climb" or "descend". The specific value depends on the unit category
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
changeAltitude(altitudeChange: string, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -456,6 +462,7 @@ export class UnitsManager {
|
||||
/** Set a specific speed to all the selected units
|
||||
*
|
||||
* @param speed Value to set, in m/s
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setSpeed(speed: number, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -471,6 +478,7 @@ export class UnitsManager {
|
||||
/** Set a specific speed type to all the selected units
|
||||
*
|
||||
* @param speedType Value to set, either "CAS" or "GS". If "CAS" is selected, the unit will try to maintain the selected Calibrated Air Speed, but DCS will still only maintain a Ground Speed value so errors may arise depending on wind.
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setSpeedType(speedType: string, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -486,6 +494,7 @@ export class UnitsManager {
|
||||
/** Set a specific altitude to all the selected units
|
||||
*
|
||||
* @param altitude Value to set, in m
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setAltitude(altitude: number, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -501,6 +510,7 @@ export class UnitsManager {
|
||||
/** Set a specific altitude type to all the selected units
|
||||
*
|
||||
* @param altitudeType Value to set, either "ASL" or "AGL". If "AGL" is selected, the unit will try to maintain the selected Above Ground Level altitude. Due to a DCS bug, this will only be true at the final position.
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setAltitudeType(altitudeType: string, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -516,6 +526,7 @@ export class UnitsManager {
|
||||
/** Set a specific ROE to all the selected units
|
||||
*
|
||||
* @param ROE Value to set, see constants for acceptable values
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setROE(ROE: string, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -531,6 +542,7 @@ export class UnitsManager {
|
||||
/** Set a specific reaction to threat to all the selected units
|
||||
*
|
||||
* @param reactionToThreat Value to set, see constants for acceptable values
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setReactionToThreat(reactionToThreat: string, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -546,6 +558,7 @@ export class UnitsManager {
|
||||
/** Set a specific emissions & countermeasures to all the selected units
|
||||
*
|
||||
* @param emissionCountermeasure Value to set, see constants for acceptable values
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setEmissionsCountermeasures(emissionCountermeasure: string, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -561,6 +574,7 @@ export class UnitsManager {
|
||||
/** Turn selected units on or off, only works on ground and navy units
|
||||
*
|
||||
* @param onOff If true, the unit will be turned on
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setOnOff(onOff: boolean, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -576,6 +590,7 @@ export class UnitsManager {
|
||||
/** Instruct the selected units to follow roads, only works on ground units
|
||||
*
|
||||
* @param followRoads If true, units will follow roads
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setFollowRoads(followRoads: boolean, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -591,6 +606,7 @@ export class UnitsManager {
|
||||
/** Instruct selected units to operate as a certain coalition
|
||||
*
|
||||
* @param operateAsBool If true, units will operate as blue
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setOperateAs(operateAsBool: boolean, units: Unit[] | null = null) {
|
||||
var operateAs = operateAsBool ? "blue" : "red";
|
||||
@@ -607,6 +623,7 @@ export class UnitsManager {
|
||||
/** Instruct units to attack a specific unit
|
||||
*
|
||||
* @param ID ID of the unit to attack
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
attackUnit(ID: number, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -620,7 +637,7 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
/** Instruct units to refuel at the nearest tanker, if possible. Else units will RTB
|
||||
*
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
refuel(units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -638,6 +655,7 @@ export class UnitsManager {
|
||||
* @param ID ID of the unit to follow
|
||||
* @param offset Optional parameter, defines a static offset. X: front-rear, positive front, Y: top-bottom, positive top, Z: left-right, positive right
|
||||
* @param formation Optional parameter, defines a predefined formation type. Values are: "trail", "echelon-lh", "echelon-rh", "line-abreast-lh", "line-abreast-rh", "front", "diamond"
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
followUnit(ID: number, offset?: { "x": number, "y": number, "z": number }, formation?: string, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -690,6 +708,7 @@ export class UnitsManager {
|
||||
/** Instruct the selected units to perform precision bombing of specific coordinates
|
||||
*
|
||||
* @param latlng Location to bomb
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
bombPoint(latlng: LatLng, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -705,6 +724,7 @@ export class UnitsManager {
|
||||
/** Instruct the selected units to perform carpet bombing of specific coordinates
|
||||
*
|
||||
* @param latlng Location to bomb
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
carpetBomb(latlng: LatLng, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -720,6 +740,7 @@ export class UnitsManager {
|
||||
/** Instruct the selected units to fire at specific coordinates
|
||||
*
|
||||
* @param latlng Location to fire at
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
fireAtArea(latlng: LatLng, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -735,6 +756,7 @@ export class UnitsManager {
|
||||
/** Instruct the selected units to simulate a fire fight at specific coordinates
|
||||
*
|
||||
* @param latlng Location to fire at
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
simulateFireFight(latlng: LatLng, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -756,7 +778,7 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
/** Instruct units to enter into scenic AAA mode. Units will shoot in the air without aiming
|
||||
*
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
scenicAAA(units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -770,7 +792,7 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
/** Instruct units to enter into miss on purpose mode. Units will aim to the nearest enemy unit but not precisely.
|
||||
*
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
missOnPurpose(units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -786,6 +808,7 @@ export class UnitsManager {
|
||||
/** Instruct units to land at specific point
|
||||
*
|
||||
* @param latlng Point where to land
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
landAtPoint(latlng: LatLng, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -802,6 +825,7 @@ export class UnitsManager {
|
||||
/** Set a specific shots scatter to all the selected units
|
||||
*
|
||||
* @param shotsScatter Value to set
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setShotsScatter(shotsScatter: number, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -817,6 +841,7 @@ export class UnitsManager {
|
||||
/** Set a specific shots intensity to all the selected units
|
||||
*
|
||||
* @param shotsScatter Value to set
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setShotsIntensity(shotsIntensity: number, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -870,6 +895,7 @@ export class UnitsManager {
|
||||
/** Set the hotgroup for the selected units. It will be the only hotgroup of the unit
|
||||
*
|
||||
* @param hotgroup Hotgroup number
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
setHotgroup(hotgroup: number, units: Unit[] | null = null) {
|
||||
this.getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHotgroup(null));
|
||||
@@ -879,6 +905,7 @@ export class UnitsManager {
|
||||
/** Add the selected units to a hotgroup. Units can be in multiple hotgroups at the same type
|
||||
*
|
||||
* @param hotgroup Hotgroup number
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
*/
|
||||
addToHotgroup(hotgroup: number, units: Unit[] | null = null) {
|
||||
if (units === null)
|
||||
@@ -891,6 +918,7 @@ export class UnitsManager {
|
||||
/** Delete the selected units
|
||||
*
|
||||
* @param explosion If true, the unit will be deleted using an explosion
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
* @returns
|
||||
*/
|
||||
delete(explosion: boolean = false, explosionType: string = "", units: Unit[] | null = null) {
|
||||
@@ -929,6 +957,7 @@ export class UnitsManager {
|
||||
*
|
||||
* @param latlng Center of the group after the translation
|
||||
* @param rotation Rotation of the group, in radians
|
||||
* @param units (Optional) Array of units to apply the control to. If not provided, the operation will be completed on all selected units.
|
||||
* @returns Array of positions for each unit, in order
|
||||
*/
|
||||
computeGroupDestination(latlng: LatLng, rotation: number, units: Unit[] | null = null) {
|
||||
@@ -972,6 +1001,9 @@ export class UnitsManager {
|
||||
*
|
||||
*/
|
||||
copy(units: Unit[] | null = null) {
|
||||
if ( !getApp().getContextManager().getCurrentContext().getAllowUnitCopying() )
|
||||
return;
|
||||
|
||||
if (units === null)
|
||||
units = this.getSelectedUnits({ excludeHumans: true });
|
||||
|
||||
@@ -989,6 +1021,9 @@ export class UnitsManager {
|
||||
* @returns True if units were pasted successfully
|
||||
*/
|
||||
paste() {
|
||||
if ( !getApp().getContextManager().getCurrentContext().getAllowUnitPasting() )
|
||||
return;
|
||||
|
||||
let spawnPoints = 0;
|
||||
|
||||
/* If spawns are restricted, check that the user has the necessary spawn points */
|
||||
@@ -1290,7 +1325,7 @@ export class UnitsManager {
|
||||
const map = getApp().getMap();
|
||||
const units = this.getSelectedUnits();
|
||||
const numSelectedUnits = units.length;
|
||||
const numProtectedUnits = units.filter((unit: Unit) => map.unitIsProtected(unit)).length;
|
||||
const numProtectedUnits = units.filter((unit: Unit) => map.getIsUnitProtected(unit)).length;
|
||||
|
||||
if (numProtectedUnits === 1 && numSelectedUnits === numProtectedUnits)
|
||||
(getApp().getPopupsManager().get("infoPopup") as Popup).setText(`Notice: unit is protected`);
|
||||
@@ -1300,6 +1335,6 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
#unitIsProtected(unit: Unit) {
|
||||
return getApp().getMap().unitIsProtected(unit)
|
||||
return getApp().getMap().getIsUnitProtected(unit)
|
||||
}
|
||||
}
|
||||
@@ -36,17 +36,9 @@ export class Weapon extends CustomMarker {
|
||||
super(new LatLng(0, 0), { riseOnHover: true, keyboard: false });
|
||||
|
||||
this.ID = ID;
|
||||
|
||||
/* Deselect units if they are hidden */
|
||||
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
|
||||
window.setTimeout(() => { !this.getHidden() }, 300);
|
||||
});
|
||||
|
||||
document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => {
|
||||
window.setTimeout(() => { !this.getHidden() }, 300);
|
||||
});
|
||||
|
||||
document.addEventListener("mapVisibilityOptionsChanged", (ev: CustomEventInit) => {
|
||||
/* Update the marker when the options change */
|
||||
document.addEventListener("mapOptionsChanged", (ev: CustomEventInit) => {
|
||||
this.#updateMarker();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -50,6 +50,12 @@
|
||||
|
||||
<!-- Grayout effect of the background when login prompt is visible -->
|
||||
<div id="gray-out"></div>
|
||||
|
||||
<!-- Loading screen -->
|
||||
<div id="loading-screen">
|
||||
<img src="images/olympus-500x500.png">
|
||||
<div>Loading DCS Olympus...</div>
|
||||
</div>
|
||||
|
||||
<script src="javascripts/bundle.js"></script>
|
||||
</body>
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
</div>
|
||||
|
||||
<form id="authentication-form">
|
||||
<div><h5>Name</h5> <input type="text" id="username" name="username" required autocomplete="username" placeholder="Enter username..."></div>
|
||||
<div><h5>Server password</h5> <input type="password" id="password" name="password" minlength="8" required autocomplete="current-password" placeholder="Enter password..."></div>
|
||||
<div><h5>Name</h5> <input type="text" id="username" name="username" required autocomplete="username" placeholder="Enter name..."></div>
|
||||
<div><h5>Server password</h5> <input type="password" id="password" name="password" minlength="1" required autocomplete="current-password" placeholder="Enter server password..."></div>
|
||||
<button type="submit" id="connection-button" class="ol-button-apply">Connect</button>
|
||||
</form>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<div class="ol-group">
|
||||
<div id="map-type" class="ol-select">
|
||||
<div class="ol-select-value"><img src="resources/theme/images/icons/map-source.svg" inject-svg>ArcGIS Satellite</div>
|
||||
<div class="ol-select-value"><img src="resources/theme/images/icons/map-source.svg" inject-svg><span class="ol-select-value-text">ArcGIS Satellite</span></div>
|
||||
<div class="ol-select-options">
|
||||
<!-- Here the available map sources will be listed-->
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user