mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'main' into 329-add-basic-automatic-firefight
This commit is contained in:
@@ -6,6 +6,7 @@ var fs = require('fs');
|
||||
|
||||
var atcRouter = require('./routes/api/atc');
|
||||
var airbasesRouter = require('./routes/api/airbases');
|
||||
var elevationRouter = require('./routes/api/elevation');
|
||||
var indexRouter = require('./routes/index');
|
||||
var uikitRouter = require('./routes/uikit');
|
||||
var usersRouter = require('./routes/users');
|
||||
@@ -23,6 +24,7 @@ app.use(express.static(path.join(__dirname, 'public')));
|
||||
app.use('/', indexRouter);
|
||||
app.use('/api/atc', atcRouter);
|
||||
app.use('/api/airbases', airbasesRouter);
|
||||
app.use('/api/elevation', elevationRouter);
|
||||
app.use('/plugins', pluginsRouter)
|
||||
app.use('/users', usersRouter);
|
||||
app.use('/uikit', uikitRouter);
|
||||
|
||||
8387
client/package-lock.json
generated
8387
client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,7 @@
|
||||
"scripts": {
|
||||
"copy": "copy.bat",
|
||||
"start": "npm run copy & concurrently --kill-others \"npm run watch\" \"nodemon ./bin/www\"",
|
||||
"watch": "watchify .\\src\\index.ts --debug -o .\\public\\javascripts\\bundle.js -t [ babelify --global true --presets [ @babel/preset-env ] --extensions '.js'] -p [ tsify --noImplicitAny ]",
|
||||
"document": "typedoc --out ../docs src/index.ts src/contextmenus/*.ts src/controls/*.ts src/map/*.ts src/mission/*.ts src/other/*.ts src/panels/*.ts src/popups/*.ts src/server/*.ts src/unit/*.ts src/weapon/*.ts"
|
||||
"watch": "watchify .\\src\\index.ts --debug -o .\\public\\javascripts\\bundle.js -t [ babelify --global true --presets [ @babel/preset-env ] --extensions '.js'] -p [ tsify --noImplicitAny ]"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie-parser": "~1.4.4",
|
||||
@@ -17,7 +16,8 @@
|
||||
"express": "~4.16.1",
|
||||
"express-basic-auth": "^1.2.1",
|
||||
"morgan": "~1.9.1",
|
||||
"save": "^2.9.0"
|
||||
"save": "^2.9.0",
|
||||
"srtm-elevation": "^2.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.21.4",
|
||||
|
||||
@@ -11,7 +11,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
||||
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_updateTips;
|
||||
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";
|
||||
@@ -23,6 +23,7 @@ class ControlTipsPlugin {
|
||||
_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"));
|
||||
@@ -64,6 +65,15 @@ class ControlTipsPlugin {
|
||||
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;
|
||||
@@ -76,7 +86,7 @@ class ControlTipsPlugin {
|
||||
}
|
||||
}
|
||||
exports.ControlTipsPlugin = ControlTipsPlugin;
|
||||
_ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap(), _ControlTipsPlugin_shortcutManager = new WeakMap(), _ControlTipsPlugin_cursorIsHoveringOverUnit = new WeakMap(), _ControlTipsPlugin_cursorIsHoveringOverAirbase = new WeakMap(), _ControlTipsPlugin_instances = new WeakSet(), _ControlTipsPlugin_updateTips = function _ControlTipsPlugin_updateTips() {
|
||||
_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": [],
|
||||
@@ -128,21 +138,27 @@ _ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap
|
||||
"showIfUnitSelected": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": "CTRL+Mouse2",
|
||||
"action": "Add waypoint",
|
||||
"showIfUnitSelected": true,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2 (hold)`,
|
||||
"action": `Point operations`,
|
||||
"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",
|
||||
@@ -159,10 +175,14 @@ _ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Delete`,
|
||||
"action": `Delete unit`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfUnitSelected": true
|
||||
"key": `Mouse1`,
|
||||
"action": "Toggle Blue/Red",
|
||||
"mouseoverSelector": "#coalition-switch .ol-switch-fill"
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": "Set Neutral",
|
||||
"mouseoverSelector": "#coalition-switch .ol-switch-fill"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -187,15 +207,35 @@ _ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap
|
||||
"key": `Mouse2`,
|
||||
"action": `Add waypoint`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false,
|
||||
"showIfUnitSelected": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Airbase menu`,
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -203,8 +243,35 @@ _ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap
|
||||
"keys": ["ShiftLeft"],
|
||||
"tips": [
|
||||
{
|
||||
"key": `mouse1+drag`,
|
||||
"action": "Box select"
|
||||
"key": `Mouse1+drag`,
|
||||
"action": "Box select",
|
||||
"showIfUnitSelected": false
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": "Set first formation waypoint",
|
||||
"showIfUnitSelected": true,
|
||||
"minSelectedUnits": 2
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -213,34 +280,57 @@ _ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap
|
||||
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;
|
||||
unitSelectionContainsControlled = selectedUnits.some((unit) => unit.getControlled());
|
||||
numSelectedControlledUnits = selectedUnits.filter((unit) => unit.getControlled()).length;
|
||||
unitSelectionContainsControlled = numSelectedControlledUnits > 0;
|
||||
}
|
||||
currentCombo.tips.forEach((tip) => {
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
if (tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (typeof tip.minSelectedUnits === "number" && numSelectedControlledUnits < tip.minSelectedUnits) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (numSelectedUnits === 0 && tip.showIfUnitSelected === true) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (typeof tip.showIfHoveringOverAirbase === "boolean") {
|
||||
if (tip.showIfHoveringOverAirbase !== __classPrivateFieldGet(this, _ControlTipsPlugin_cursorIsHoveringOverAirbase, "f")) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (typeof tip.showIfHoveringOverUnit === "boolean") {
|
||||
if (tip.showIfHoveringOverUnit !== __classPrivateFieldGet(this, _ControlTipsPlugin_cursorIsHoveringOverUnit, "f")) {
|
||||
return;
|
||||
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;
|
||||
}
|
||||
element.innerHTML += `<div><span class="key">${tip.key}</span><span class="action">${tip.action}</span></div>`;
|
||||
});
|
||||
};
|
||||
@@ -248,9 +338,9 @@ _ControlTipsPlugin_element = new WeakMap(), _ControlTipsPlugin_app = new WeakMap
|
||||
},{}],2:[function(require,module,exports){
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const controltips_1 = require("./controltips");
|
||||
const controltipsplugin_1 = require("./controltipsplugin");
|
||||
globalThis.getOlympusPlugin = () => {
|
||||
return new controltips_1.ControlTipsPlugin();
|
||||
return new controltipsplugin_1.ControlTipsPlugin();
|
||||
};
|
||||
|
||||
},{"./controltips":1}]},{},[2]);
|
||||
},{"./controltipsplugin":1}]},{},[2]);
|
||||
|
||||
@@ -6,6 +6,7 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
#shortcutManager: any;
|
||||
#cursorIsHoveringOverUnit: boolean = false;
|
||||
#cursorIsHoveringOverAirbase: boolean = false;
|
||||
#mouseoverElement!: HTMLElement;
|
||||
|
||||
constructor() {
|
||||
this.#element = document.createElement("div");
|
||||
@@ -55,13 +56,24 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
});
|
||||
|
||||
document.addEventListener("unitSelection", (ev: CustomEvent) => {
|
||||
this.#updateTips()
|
||||
this.#updateTips();
|
||||
});
|
||||
|
||||
document.addEventListener("mapVisibilityOptionsChanged", () => {
|
||||
this.toggle( !this.#app.getMap().getVisibilityOptions()[SHOW_CONTROL_TIPS] );
|
||||
});
|
||||
|
||||
document.addEventListener( "mouseover", ( ev: MouseEvent ) => {
|
||||
if ( ev.target instanceof HTMLElement ) {
|
||||
this.#mouseoverElement = <HTMLElement>ev.target;
|
||||
}
|
||||
this.#updateTips();
|
||||
});
|
||||
|
||||
document.addEventListener( "mouseup", ( ev: MouseEvent ) => {
|
||||
this.#updateTips();
|
||||
});
|
||||
|
||||
this.#updateTips();
|
||||
|
||||
this.#app.getMap().addVisibilityOption(SHOW_CONTROL_TIPS, true);
|
||||
@@ -129,21 +141,27 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
"showIfUnitSelected": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": "CTRL+Mouse2",
|
||||
"action": "Add waypoint",
|
||||
"showIfUnitSelected": true,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2 (hold)`,
|
||||
"action": `Point operations`,
|
||||
"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",
|
||||
@@ -160,10 +178,14 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Delete`,
|
||||
"action": `Delete unit`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfUnitSelected": true
|
||||
"key": `Mouse1`,
|
||||
"action": "Toggle Blue/Red",
|
||||
"mouseoverSelector": "#coalition-switch .ol-switch-fill"
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": "Set Neutral",
|
||||
"mouseoverSelector": "#coalition-switch .ol-switch-fill"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -188,15 +210,35 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
"key": `Mouse2`,
|
||||
"action": `Add waypoint`,
|
||||
"showIfHoveringOverAirbase": false,
|
||||
"showIfHoveringOverUnit": false,
|
||||
"showIfUnitSelected": true,
|
||||
"unitsMustBeControlled": true
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": `Airbase menu`,
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -204,8 +246,35 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
"keys": ["ShiftLeft"],
|
||||
"tips": [
|
||||
{
|
||||
"key": `mouse1+drag`,
|
||||
"action": "Box select"
|
||||
"key": `Mouse1+drag`,
|
||||
"action": "Box select",
|
||||
"showIfUnitSelected": false
|
||||
},
|
||||
{
|
||||
"key": `Mouse2`,
|
||||
"action": "Set first formation waypoint",
|
||||
"showIfUnitSelected": true,
|
||||
"minSelectedUnits": 2
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -218,42 +287,73 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
element.innerHTML = "";
|
||||
|
||||
let numSelectedUnits = 0;
|
||||
let numSelectedControlledUnits = 0;
|
||||
let unitSelectionContainsControlled = false;
|
||||
|
||||
if (this.#app.getUnitsManager()) {
|
||||
let selectedUnits = Object.values(this.#app.getUnitsManager().getSelectedUnits());
|
||||
numSelectedUnits = selectedUnits.length;
|
||||
unitSelectionContainsControlled = selectedUnits.some((unit: any) => unit.getControlled());
|
||||
numSelectedUnits = selectedUnits.length;
|
||||
numSelectedControlledUnits = selectedUnits.filter((unit: any) => unit.getControlled()).length;
|
||||
unitSelectionContainsControlled = numSelectedControlledUnits > 0;
|
||||
}
|
||||
|
||||
currentCombo.tips.forEach((tip: any) => {
|
||||
const tipsIncludesActiveMouseover = ( currentCombo.tips.some( ( tip:any ) => {
|
||||
if ( !tip.mouseoverSelector ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( this.#mouseoverElement instanceof HTMLElement === false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !this.#mouseoverElement.matches( tip.mouseoverSelector ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}));
|
||||
|
||||
currentCombo.tips.filter((tip: any) => {
|
||||
if (numSelectedUnits > 0) {
|
||||
if (tip.showIfUnitSelected === false) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tip.unitsMustBeControlled === true && unitSelectionContainsControlled === false) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( typeof tip.minSelectedUnits === "number" && numSelectedControlledUnits < tip.minSelectedUnits ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (numSelectedUnits === 0 && tip.showIfUnitSelected === true) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof tip.showIfHoveringOverAirbase === "boolean") {
|
||||
if (tip.showIfHoveringOverAirbase !== this.#cursorIsHoveringOverAirbase) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof tip.showIfHoveringOverUnit === "boolean") {
|
||||
if (tip.showIfHoveringOverUnit !== this.#cursorIsHoveringOverUnit) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
element.innerHTML += `<div><span class="key">${tip.key}</span><span class="action">${tip.action}</span></div>`
|
||||
if ( tipsIncludesActiveMouseover && typeof tip.mouseoverSelector !== "string" && !this.#mouseoverElement.matches( tip.mouseoverSelector ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !tipsIncludesActiveMouseover && typeof tip.mouseoverSelector === "string" ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
element.innerHTML += `<div><span class="key">${tip.key}</span><span class="action">${tip.action}</span></div>`;
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,11 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.leaflet-container img.leaflet-tile {
|
||||
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
|
||||
mix-blend-mode: plus-lighter;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
@@ -646,7 +651,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
|
||||
}
|
||||
|
||||
/* Printing */
|
||||
|
||||
|
||||
@media print {
|
||||
/* Prevent printers from removing background-images of controls. */
|
||||
.leaflet-control {
|
||||
|
||||
@@ -106,4 +106,14 @@
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: var(--background-offwhite);
|
||||
}
|
||||
|
||||
.elevation::after {
|
||||
content: attr(data-value);
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: var(--background-offwhite);
|
||||
}
|
||||
28
client/routes/api/elevation.js
Normal file
28
client/routes/api/elevation.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const express = require('express');
|
||||
var fs = require('fs');
|
||||
const router = express.Router();
|
||||
const TileSet = require('srtm-elevation').TileSet;
|
||||
const SRTMElevationDownloader = require('srtm-elevation').SRTMElevationDownloader;
|
||||
|
||||
let rawdata = fs.readFileSync('../olympus.json');
|
||||
let config = JSON.parse(rawdata);
|
||||
var tileset = null;
|
||||
|
||||
if (config["client"] === undefined || config["client"]["elevationProvider"] === undefined)
|
||||
tileset = new TileSet('./hgt');
|
||||
else
|
||||
tileset = new TileSet('./hgt', {downloader: new SRTMElevationDownloader('./hgt', config["client"]["elevationProvider"])});
|
||||
|
||||
router.get( "/:lat/:lng", ( req, res ) => {
|
||||
tileset.getElevation([req.params.lat, req.params.lng], function(err, elevation) {
|
||||
if (err) {
|
||||
console.log('getElevation failed: ' + err.message);
|
||||
res.send("n/a");
|
||||
} else {
|
||||
res.send(String(elevation));
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -16,7 +16,6 @@ function listDirectories(source) {
|
||||
|
||||
router.get('/list', function (req, res) {
|
||||
var directories = listDirectories(pluginsDirectory);
|
||||
console.log(directories)
|
||||
res.send(directories.filter(directory => fs.existsSync(path.join(pluginsDirectory, directory))));
|
||||
});
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ export const mapBounds = {
|
||||
// TODO "Falklands"
|
||||
}
|
||||
|
||||
export const layers = {
|
||||
export const mapLayers = {
|
||||
"ArcGIS Satellite": {
|
||||
urlTemplate: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
||||
maxZoom: 20,
|
||||
|
||||
@@ -12,7 +12,7 @@ import { DestinationPreviewMarker } from "./markers/destinationpreviewmarker";
|
||||
import { TemporaryUnitMarker } from "./markers/temporaryunitmarker";
|
||||
import { ClickableMiniMap } from "./clickableminimap";
|
||||
import { SVGInjector } from '@tanem/svg-injector'
|
||||
import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants";
|
||||
import { mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants";
|
||||
import { TargetMarker } from "./markers/targetmarker";
|
||||
import { CoalitionArea } from "./coalitionarea/coalitionarea";
|
||||
import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Icon, LatLng, Marker, Polyline } from "leaflet";
|
||||
import { getApp } from "..";
|
||||
import { distance, bearing, zeroAppend, mToNm, nmToFt } from "../other/utils";
|
||||
import { distance, bearing, zeroAppend, mToNm, nmToFt, mToFt } from "../other/utils";
|
||||
import { Unit } from "../unit/unit";
|
||||
import { Panel } from "./panel";
|
||||
import formatcoords from "formatcoords";
|
||||
@@ -11,6 +11,7 @@ export class MouseInfoPanel extends Panel {
|
||||
#measureIcon: Icon;
|
||||
#measureLine: Polyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1, interactive: false });
|
||||
#measureBox: HTMLElement;
|
||||
#elevationRequest: XMLHttpRequest | null = null;
|
||||
|
||||
constructor(ID: string) {
|
||||
super( ID );
|
||||
@@ -53,6 +54,30 @@ export class MouseInfoPanel extends Panel {
|
||||
var coordString = coords.format('XDDMMss', {decimalPlaces: 4});
|
||||
this.#drawCoordinates("ref-mouse-position-latitude", "mouse-position-latitude", coordString.split(" ")[0]);
|
||||
this.#drawCoordinates("ref-mouse-position-longitude", "mouse-position-longitude", coordString.split(" ")[1]);
|
||||
|
||||
/* Get the ground elevation from the server endpoint */
|
||||
if (this.#elevationRequest == null) {
|
||||
this.#elevationRequest = new XMLHttpRequest();
|
||||
this.#elevationRequest.open('GET', `api/elevation/${mousePosition.lat}/${mousePosition.lng}`, true);
|
||||
this.#elevationRequest.timeout = 500; // ms
|
||||
this.#elevationRequest.responseType = 'json';
|
||||
this.#elevationRequest.onload = () => {
|
||||
var status = this.#elevationRequest?.status;
|
||||
if (status === 200) {
|
||||
const el = this.getElement().querySelector(`#mouse-position-elevation`) as HTMLElement;
|
||||
try {
|
||||
el.dataset.value = `${Math.floor(mToFt(parseFloat(this.#elevationRequest?.response)))} ft`;
|
||||
} catch {
|
||||
el.dataset.value = `N/A`;
|
||||
}
|
||||
}
|
||||
this.#elevationRequest = null;
|
||||
};
|
||||
this.#elevationRequest.ontimeout = () => {this.#elevationRequest = null;}
|
||||
this.#elevationRequest.onerror = () => {this.#elevationRequest = null;}
|
||||
this.#elevationRequest.onabort = () => {this.#elevationRequest = null;}
|
||||
this.#elevationRequest.send();
|
||||
}
|
||||
}
|
||||
|
||||
#onMapClick(e: any) {
|
||||
@@ -115,7 +140,6 @@ export class MouseInfoPanel extends Panel {
|
||||
}
|
||||
|
||||
#onMouseMove(e: any) {
|
||||
|
||||
this.#update();
|
||||
this.#drawMeasureLine();
|
||||
}
|
||||
|
||||
@@ -81,14 +81,14 @@ export class Unit extends CustomMarker {
|
||||
#selected: boolean = false;
|
||||
#hidden: boolean = false;
|
||||
#highlighted: boolean = false;
|
||||
#preventClick: boolean = false;
|
||||
#waitingForDoubleClick: boolean = false;
|
||||
#pathMarkers: Marker[] = [];
|
||||
#pathPolyline: Polyline;
|
||||
#contactsPolylines: Polyline[];
|
||||
#miniMapMarker: CircleMarker | null = null;
|
||||
#targetPositionMarker: TargetMarker;
|
||||
#targetPositionPolyline: Polyline;
|
||||
#timer: number = 0;
|
||||
#doubleClickTimer: number = 0;
|
||||
#hotgroup: number | null = null;
|
||||
#detectionMethods: number[] = [];
|
||||
|
||||
@@ -734,32 +734,49 @@ export class Unit extends CustomMarker {
|
||||
|
||||
/***********************************************/
|
||||
#onClick(e: any) {
|
||||
if (!this.#preventClick) {
|
||||
if (getApp().getMap().getState() === IDLE || getApp().getMap().getState() === MOVE_UNIT || e.originalEvent.ctrlKey) {
|
||||
if (!e.originalEvent.ctrlKey)
|
||||
getApp().getUnitsManager().deselectAllUnits();
|
||||
|
||||
this.setSelected(!this.getSelected());
|
||||
const detail = { "detail": { "unit": this } };
|
||||
if (this.getSelected())
|
||||
document.dispatchEvent(new CustomEvent("unitSelected", detail));
|
||||
else
|
||||
document.dispatchEvent(new CustomEvent("unitDeselection", { "detail": this }));
|
||||
}
|
||||
// Exit if we were waiting for a doubleclick
|
||||
if (this.#waitingForDoubleClick) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We'll wait for a doubleclick
|
||||
this.#waitingForDoubleClick = true;
|
||||
|
||||
this.#timer = window.setTimeout(() => { this.#preventClick = false; }, 200);
|
||||
this.#doubleClickTimer = window.setTimeout(() => {
|
||||
|
||||
// Still waiting so no doubleclick; do the click action
|
||||
if (this.#waitingForDoubleClick) {
|
||||
if (getApp().getMap().getState() === IDLE || getApp().getMap().getState() === MOVE_UNIT || e.originalEvent.ctrlKey) {
|
||||
if (!e.originalEvent.ctrlKey)
|
||||
getApp().getUnitsManager().deselectAllUnits();
|
||||
|
||||
this.setSelected(!this.getSelected());
|
||||
const detail = { "detail": { "unit": this } };
|
||||
if (this.getSelected())
|
||||
document.dispatchEvent(new CustomEvent("unitSelected", detail));
|
||||
else
|
||||
document.dispatchEvent(new CustomEvent("unitDeselection", { "detail": this }));
|
||||
}
|
||||
}
|
||||
|
||||
// No longer waiting for a doubleclick
|
||||
this.#waitingForDoubleClick = false;
|
||||
}, 200);
|
||||
}
|
||||
|
||||
#onDoubleClick(e: any) {
|
||||
|
||||
// Let single clicks work again
|
||||
this.#waitingForDoubleClick = false;
|
||||
clearTimeout(this.#doubleClickTimer);
|
||||
|
||||
// Select all matching units in the viewport
|
||||
const unitsManager = getApp().getUnitsManager();
|
||||
Object.values(unitsManager.getUnits()).forEach((unit: Unit) => {
|
||||
if (unit.getAlive() === true && unit.getName() === this.getName() && unit.isInViewport())
|
||||
unitsManager.selectUnit(unit.ID, false);
|
||||
});
|
||||
|
||||
clearTimeout(this.#timer);
|
||||
this.#preventClick = true;
|
||||
}
|
||||
|
||||
#onContextMenu(e: any) {
|
||||
|
||||
@@ -36,9 +36,7 @@
|
||||
"leaflet",
|
||||
"geojson",
|
||||
"node",
|
||||
"formatcoords",
|
||||
"olympus",
|
||||
"dom"
|
||||
"formatcoords"
|
||||
], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
|
||||
@@ -25,9 +25,11 @@
|
||||
<div id="coordinates-tool">
|
||||
<dl class="ol-data-grid">
|
||||
<dt id="ref-mouse-position-latitude" data-label="?"></dt>
|
||||
<dd id="mouse-position-latitude" class="coordinates" data-dd="---" data-mm="---" data-ss="--" data-sss="--"></dd>
|
||||
<dd id="mouse-position-latitude" class="coordinates"></dd>
|
||||
<dt id="ref-mouse-position-longitude" data-label="?"></dt>
|
||||
<dd id="mouse-position-longitude" class="coordinates" data-dd="---" data-mm="---" data-ss="--" data-sss="--"></dd>
|
||||
<dd id="mouse-position-longitude" class="coordinates"></dd>
|
||||
<dt id="ref-mouse-position-elevation" data-label="H"></dt>
|
||||
<dd id="mouse-position-elevation" class="elevation" data-value="---"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user