mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'main' into 328-add-simple-miss-on-purpose-mode-for-aaa
This commit is contained in:
@@ -1,12 +1,27 @@
|
||||
import { Panel } from "./panel";
|
||||
|
||||
export class ConnectionStatusPanel extends Panel {
|
||||
|
||||
constructor(ID: string) {
|
||||
super( ID );
|
||||
}
|
||||
|
||||
|
||||
update(connected: boolean) {
|
||||
this.getElement().toggleAttribute( "data-is-connected", connected );
|
||||
|
||||
showDisconnected() {
|
||||
this.getElement().toggleAttribute( "data-is-connected", false );
|
||||
this.getElement().toggleAttribute( "data-is-paused", false );
|
||||
}
|
||||
|
||||
|
||||
showConnected() {
|
||||
this.getElement().toggleAttribute( "data-is-connected", true );
|
||||
this.getElement().toggleAttribute( "data-is-paused", false );
|
||||
}
|
||||
|
||||
|
||||
showServerPaused() {
|
||||
this.getElement().toggleAttribute( "data-is-connected", false );
|
||||
this.getElement().toggleAttribute( "data-is-paused", true );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ export class MouseInfoPanel extends Panel {
|
||||
getApp().getMap()?.on("click", (e: any) => this.#onMapClick(e));
|
||||
getApp().getMap()?.on('zoom', (e: any) => this.#onZoom(e));
|
||||
getApp().getMap()?.on('mousemove', (e: any) => this.#onMouseMove(e));
|
||||
getApp().getMap()?.on('drag', (e: any) => this.#onMouseMove(e));
|
||||
|
||||
document.addEventListener('unitsSelection', (e: CustomEvent<Unit[]>) => this.#update());
|
||||
document.addEventListener('clearSelection', () => this.#update());
|
||||
@@ -107,14 +108,15 @@ export class MouseInfoPanel extends Panel {
|
||||
|
||||
#drawMeasureLine() {
|
||||
var mouseLatLng = getApp().getMap().containerPointToLatLng(getApp().getMap().getMousePosition());
|
||||
const mousePosition = getApp().getMap().getMousePosition();
|
||||
if (this.#measurePoint != null) {
|
||||
var points = [this.#measurePoint, mouseLatLng];
|
||||
this.#measureLine.setLatLngs(points);
|
||||
var dist = distance(this.#measurePoint.lat, this.#measurePoint.lng, mouseLatLng.lat, mouseLatLng.lng);
|
||||
var bear = bearing(this.#measurePoint.lat, this.#measurePoint.lng, mouseLatLng.lat, mouseLatLng.lng);
|
||||
var startXY = getApp().getMap().latLngToContainerPoint(this.#measurePoint);
|
||||
var dx = (getApp().getMap().getMousePosition().x - startXY.x);
|
||||
var dy = (getApp().getMap().getMousePosition().y - startXY.y);
|
||||
var dx = mousePosition.x - startXY.x;
|
||||
var dy = mousePosition.y - startXY.y;
|
||||
|
||||
var angle = Math.atan2(dy, dx);
|
||||
if (angle > Math.PI / 2)
|
||||
@@ -133,8 +135,8 @@ export class MouseInfoPanel extends Panel {
|
||||
let data = [`${bng}°`, `${str} ${unit}`];
|
||||
|
||||
this.#measureBox.innerText = data.join(" / ");
|
||||
this.#measureBox.style.left = (getApp().getMap().getMousePosition().x + startXY.x) / 2 - this.#measureBox.offsetWidth / 2 + "px";
|
||||
this.#measureBox.style.top = (getApp().getMap().getMousePosition().y + startXY.y) / 2 - this.#measureBox.offsetHeight / 2 + "px";
|
||||
this.#measureBox.style.left = (mousePosition.x + startXY.x) / 2 - this.#measureBox.offsetWidth / 2 + "px";
|
||||
this.#measureBox.style.top = (mousePosition.y + startXY.y) / 2 - this.#measureBox.offsetHeight / 2 + "px";
|
||||
this.#measureBox.style.rotate = angle + "rad";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +295,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 roles = aircraftDatabase.getByName(unit.getName())?.loadouts?.map((loadout) => {return loadout.roles})
|
||||
const tanker = roles != undefined && Array.prototype.concat.apply([], roles)?.includes("Refueling");
|
||||
@@ -305,6 +305,7 @@ export class UnitControlPanel extends Panel {
|
||||
|
||||
/* Activate the correct options depending on unit type */
|
||||
this.#advancedSettingsDialog.toggleAttribute("data-show-settings", !tanker && !AWACS);
|
||||
this.#advancedSettingsDialog.toggleAttribute("data-show-air-unit-checkboxes", ["Aircraft", "Helicopter"].includes(units[0].getCategory()));
|
||||
this.#advancedSettingsDialog.toggleAttribute("data-show-tasking", tanker || AWACS);
|
||||
this.#advancedSettingsDialog.toggleAttribute("data-show-tanker", tanker);
|
||||
this.#advancedSettingsDialog.toggleAttribute("data-show-AWACS", AWACS);
|
||||
|
||||
191
client/src/panels/unitlistpanel.ts
Normal file
191
client/src/panels/unitlistpanel.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
import { getApp } from "..";
|
||||
import { ShortcutKeyboard } from "../shortcut/shortcut";
|
||||
import { Unit } from "../unit/unit";
|
||||
import { Panel } from "./panel";
|
||||
|
||||
export class UnitListPanel extends Panel {
|
||||
#contentElement: HTMLElement;
|
||||
#currentSortAlgorithm: string = "unitName";
|
||||
#currentSortDirection: string = "ASC";
|
||||
#units: Unit[] = [];
|
||||
#unitNameCache: {[key:string]: string} = {};
|
||||
#updatesInterval!: ReturnType<typeof setInterval>;
|
||||
|
||||
constructor(panelElement: string, contentElement: string) {
|
||||
super(panelElement);
|
||||
const getElement = document.getElementById(contentElement);
|
||||
|
||||
if (getElement instanceof HTMLElement)
|
||||
this.#contentElement = getElement;
|
||||
else
|
||||
throw new Error(`UnitList: unable to find element "${contentElement}".`);
|
||||
|
||||
// Add the header click listener and sorting
|
||||
[].slice.call(this.getElement().querySelectorAll(".headers > *")).forEach((header: HTMLElement) => {
|
||||
header.addEventListener("click", (ev: MouseEvent) => {
|
||||
const el = ev.target;
|
||||
if (el instanceof HTMLElement) {
|
||||
const newSort = el.getAttribute("data-sort-field") || "unitName";
|
||||
|
||||
if (this.#currentSortAlgorithm === newSort)
|
||||
this.#currentSortDirection = (this.#currentSortDirection === "ASC") ? "DESC" : "ASC";
|
||||
else
|
||||
this.#currentSortDirection = "ASC";
|
||||
|
||||
this.#currentSortAlgorithm = newSort;
|
||||
|
||||
this.doUpdate();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Dynamically listen for clicks in order to do stuff with units
|
||||
this.getElement().addEventListener("click", (ev: MouseEvent) => {
|
||||
const t = ev.target;
|
||||
|
||||
if (t instanceof HTMLElement) {
|
||||
const el = t.closest( "[data-unit-id]");
|
||||
|
||||
if (el instanceof HTMLElement) {
|
||||
let id: number = Number(el.getAttribute("data-unit-id") || 0);
|
||||
getApp().getUnitsManager().selectUnit(id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new ShortcutKeyboard({
|
||||
"callback": () => { this.toggle() },
|
||||
"code": "KeyU"
|
||||
});
|
||||
|
||||
this.startUpdates();
|
||||
}
|
||||
|
||||
doUpdate() {
|
||||
if (!this.getVisible())
|
||||
return;
|
||||
|
||||
this.#contentElement.innerHTML = "";
|
||||
|
||||
this.#units = Object.values(getApp().getUnitsManager().getUnits());
|
||||
|
||||
if (this.#currentSortAlgorithm === "coalition")
|
||||
this.#sortUnitsByCoalition();
|
||||
|
||||
if (this.#currentSortAlgorithm === "name")
|
||||
this.#sortUnitsByName();
|
||||
|
||||
if (this.#currentSortAlgorithm === "unitName")
|
||||
this.#sortUnitsByUnitName();
|
||||
|
||||
Object.values(this.#units).forEach((unit: Unit) => {
|
||||
// Exclude dead units
|
||||
if (!unit.getAlive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const name = unit.getName();
|
||||
|
||||
if ( this.#unitNameCache.hasOwnProperty( name ) === false ) {
|
||||
this.#unitNameCache[name] = unit.getDatabase()?.getByName(unit.getName())?.label || unit.getName();
|
||||
}
|
||||
|
||||
this.#contentElement.innerHTML += `
|
||||
<div class="unit-list-unit" data-unit-id="${unit.ID}" data-value-unitName="${unit.getUnitName()}" data-value-name="${unit.getName()}" data-value-coalition="${unit.getCoalition()}" data-value-human="${unit.getHuman() ? "Human" : "AI"}">
|
||||
<div><span>${unit.getUnitName()}</span></div>
|
||||
<div>${this.#unitNameCache[name]}</div>
|
||||
<div>${unit.getCategory()}</div>
|
||||
<div>${unit.getCoalition()}</div>
|
||||
<div>${unit.getHuman() ? "Human" : "AI"}</div>
|
||||
</div>`;
|
||||
});
|
||||
}
|
||||
|
||||
getContentElement() {
|
||||
return this.#contentElement;
|
||||
}
|
||||
|
||||
#sortStringsCompare(str1: string, str2: string) {
|
||||
if (str1 > str2) {
|
||||
return (this.#currentSortDirection === "ASC") ? 1 : -1;
|
||||
} else if (str1 < str2) {
|
||||
return (this.#currentSortDirection === "ASC") ? -1 : 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#sortUnitsByUnitName() {
|
||||
this.#units.sort((unit1: Unit, unit2: Unit) => {
|
||||
|
||||
const str1 = unit1.getUnitName().toLowerCase();
|
||||
const str2 = unit2.getUnitName().toLowerCase();
|
||||
|
||||
return this.#sortStringsCompare(str1, str2);
|
||||
});
|
||||
}
|
||||
|
||||
#sortUnitsByCategory() {
|
||||
this.#units.sort((unit1: Unit, unit2: Unit) => {
|
||||
let str1 = unit1.getCategory();
|
||||
let str2 = unit2.getCategory();
|
||||
|
||||
let cmp = this.#sortStringsCompare(str1, str2);
|
||||
|
||||
if (cmp !== 0)
|
||||
return cmp;
|
||||
|
||||
str1 = unit1.getUnitName().toLowerCase();
|
||||
str2 = unit2.getUnitName().toLowerCase();
|
||||
|
||||
return this.#sortStringsCompare(str1, str2);
|
||||
});
|
||||
}
|
||||
|
||||
#sortUnitsByCoalition() {
|
||||
this.#units.sort((unit1: Unit, unit2: Unit) => {
|
||||
let str1 = unit1.getCoalition();
|
||||
let str2 = unit2.getCoalition();
|
||||
|
||||
let cmp = this.#sortStringsCompare(str1, str2);
|
||||
|
||||
if (cmp !== 0)
|
||||
return cmp;
|
||||
|
||||
str1 = unit1.getUnitName().toLowerCase();
|
||||
str2 = unit2.getUnitName().toLowerCase();
|
||||
|
||||
return this.#sortStringsCompare(str1, str2);
|
||||
});
|
||||
}
|
||||
|
||||
#sortUnitsByName() {
|
||||
this.#units.sort((unit1: Unit, unit2: Unit) => {
|
||||
const str1 = unit1.getName().toLowerCase();
|
||||
const str2 = unit2.getName().toLowerCase();
|
||||
return this.#sortStringsCompare(str1, str2);
|
||||
});
|
||||
}
|
||||
|
||||
startUpdates() {
|
||||
this.doUpdate();
|
||||
|
||||
this.#updatesInterval = setInterval(() => {
|
||||
this.doUpdate();
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
stopUpdates() {
|
||||
clearInterval(this.#updatesInterval);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
if (this.getVisible())
|
||||
this.stopUpdates();
|
||||
else
|
||||
this.startUpdates();
|
||||
|
||||
super.toggle();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user