mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'v0.1.0' of https://github.com/Pax1601/DCSOlympus into v0.1.0
This commit is contained in:
commit
8741585294
@ -29,18 +29,6 @@ body {
|
||||
min-width: 820px;
|
||||
}
|
||||
|
||||
#unit-info-panel {
|
||||
position: fixed;
|
||||
left: 10px;
|
||||
bottom: 10px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.content #unit-info-panel {
|
||||
position: static;
|
||||
margin: 50px;
|
||||
}
|
||||
|
||||
#primary-toolbar {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
@ -54,10 +42,10 @@ body {
|
||||
|
||||
#unit-control-panel {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
top: 80px;
|
||||
height: fit-content;
|
||||
width: 250px;
|
||||
right: 10px;
|
||||
left: 10px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
|
||||
@ -236,6 +236,14 @@ button[disabled="disabled"] {
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
nav.ol-panel {
|
||||
column-gap: 20px;
|
||||
@ -306,7 +314,7 @@ nav.ol-panel > :last-child {
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.icon-small {
|
||||
@ -392,4 +400,26 @@ nav.ol-panel > :last-child {
|
||||
.main-logo {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.ol-measure-box {
|
||||
position: absolute;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
background-color: var(--background-steel);
|
||||
border-radius: 999px;
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
text-align: center;
|
||||
color: var(--primary-grey);
|
||||
font-size: 12px;
|
||||
z-index: 2000;
|
||||
font-weight: var(--font-weight-bolder);
|
||||
}
|
||||
|
||||
#unit-info-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
5
client/src/@types/dom.d.ts
vendored
5
client/src/@types/dom.d.ts
vendored
@ -1,6 +1,8 @@
|
||||
interface CustomEventMap {
|
||||
"unitSelection": CustomEvent<Unit>,
|
||||
"unitDeselection": CustomEvent<Unit>,
|
||||
"unitsSelection": CustomEvent<Unit[]>,
|
||||
"unitsDeselection": CustomEvent<Unit[]>,
|
||||
"clearSelection": CustomEvent<>,
|
||||
"unitCreation": CustomEvent<Unit>,
|
||||
"unitDeletion": CustomEvent<Unit>,
|
||||
@ -10,8 +12,7 @@ interface CustomEventMap {
|
||||
"unitLandCommand": CustomEvent<Unit>,
|
||||
"unitSetAltitudeCommand": CustomEvent<Unit>,
|
||||
"unitSetSpeedCommand": CustomEvent<Unit>,
|
||||
"unitSetROECommand": CustomEvent<Unit>,
|
||||
"unitSetReactionToThreatCommand": CustomEvent<Unit>,
|
||||
"unitSetOption": CustomEvent<Unit>,
|
||||
"groupCreation": CustomEvent<Unit[]>,
|
||||
"groupDeletion": CustomEvent<Unit[]>,
|
||||
"mapStateChanged": CustomEvent<string>,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import * as L from "leaflet"
|
||||
import { getContextMenu, getUnitsManager, getActiveCoalition, getMouseInfoPanel } from "..";
|
||||
import { getContextMenu, getUnitsManager, getActiveCoalition } from "..";
|
||||
import { spawnAircraft, spawnGroundUnit, spawnSmoke } from "../server/server";
|
||||
import { bearing, distance, zeroAppend } from "../other/utils";
|
||||
import { aircraftDatabase } from "../units/aircraftdatabase";
|
||||
import { unitTypes } from "../units/unittypes";
|
||||
import { BoxSelect } from "./boxselect";
|
||||
@ -28,11 +27,6 @@ export class Map extends L.Map {
|
||||
#layer: L.TileLayer | null = null;
|
||||
#preventLeftClick: boolean = false;
|
||||
#leftClickTimer: number = 0;
|
||||
#measurePoint: L.LatLng | null;
|
||||
#measureIcon: L.Icon;
|
||||
#measureMarker: L.Marker;
|
||||
#measureLine: L.Polyline = new L.Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1, interactive: false });
|
||||
#measureLineDiv: HTMLElement;
|
||||
#lastMousePosition: L.Point = new L.Point(0, 0);
|
||||
|
||||
constructor(ID: string) {
|
||||
@ -45,15 +39,7 @@ export class Map extends L.Map {
|
||||
|
||||
/* Init the state machine */
|
||||
this.#state = IDLE;
|
||||
this.#measurePoint = null;
|
||||
|
||||
this.#measureIcon = new L.Icon({ iconUrl: 'images/pin.png', iconAnchor: [16, 32]});
|
||||
this.#measureMarker = new L.Marker([0, 0], {icon: this.#measureIcon, interactive: false});
|
||||
this.#measureLineDiv = document.createElement("div");
|
||||
this.#measureLineDiv.classList.add("ol-measure-box");
|
||||
this.#measureLineDiv.style.display = 'none';
|
||||
|
||||
document.body.appendChild(this.#measureLineDiv);
|
||||
|
||||
|
||||
/* Register event handles */
|
||||
this.on("click", (e: any) => this.#onClick(e));
|
||||
@ -63,7 +49,6 @@ export class Map extends L.Map {
|
||||
this.on('mousedown', (e: any) => this.#onMouseDown(e));
|
||||
this.on('mouseup', (e: any) => this.#onMouseUp(e));
|
||||
this.on('mousemove', (e: any) => this.#onMouseMove(e));
|
||||
this.on('zoom', (e: any) => this.#onZoom(e));
|
||||
}
|
||||
|
||||
setLayer(layerName: string) {
|
||||
@ -162,19 +147,7 @@ export class Map extends L.Map {
|
||||
if (!this.#preventLeftClick) {
|
||||
this.hideContextMenu();
|
||||
if (this.#state === IDLE) {
|
||||
if (e.originalEvent.ctrlKey)
|
||||
if (!this.#measurePoint)
|
||||
{
|
||||
this.#measurePoint = e.latlng;
|
||||
this.#measureMarker.setLatLng(e.latlng);
|
||||
this.#measureMarker.addTo(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.#measurePoint = null;
|
||||
if (this.hasLayer(this.#measureMarker))
|
||||
this.removeLayer(this.#measureMarker);
|
||||
}
|
||||
|
||||
}
|
||||
else if (this.#state === MOVE_UNIT) {
|
||||
this.setState(IDLE);
|
||||
@ -223,17 +196,13 @@ export class Map extends L.Map {
|
||||
#onMouseDown(e: any)
|
||||
{
|
||||
if ((e.originalEvent.which == 1) && (e.originalEvent.button == 0))
|
||||
{
|
||||
this.dragging.disable();
|
||||
}
|
||||
}
|
||||
|
||||
#onMouseUp(e: any)
|
||||
{
|
||||
if ((e.originalEvent.which == 1) && (e.originalEvent.button == 0))
|
||||
{
|
||||
this.dragging.enable();
|
||||
}
|
||||
}
|
||||
|
||||
#onMouseMove(e: any)
|
||||
@ -241,26 +210,10 @@ export class Map extends L.Map {
|
||||
var selectedUnitPosition = null;
|
||||
var selectedUnits = getUnitsManager().getSelectedUnits();
|
||||
if (selectedUnits && selectedUnits.length == 1)
|
||||
{
|
||||
selectedUnitPosition = new L.LatLng(selectedUnits[0].getFlightData().latitude, selectedUnits[0].getFlightData().longitude);
|
||||
}
|
||||
getMouseInfoPanel()?.update(<L.LatLng>e.latlng, this.#measurePoint, selectedUnitPosition);
|
||||
|
||||
this.#lastMousePosition.x = e.originalEvent.x;
|
||||
this.#lastMousePosition.y = e.originalEvent.y;
|
||||
|
||||
if ( this.#measurePoint)
|
||||
this.#drawMeasureLine();
|
||||
else
|
||||
this.#hideMeasureLine();
|
||||
}
|
||||
|
||||
#onZoom(e: any)
|
||||
{
|
||||
if (this.#measurePoint)
|
||||
this.#drawMeasureLine();
|
||||
else
|
||||
this.#hideMeasureLine();
|
||||
}
|
||||
|
||||
/* Spawning menus */
|
||||
@ -357,43 +310,4 @@ export class Map extends L.Map {
|
||||
spawnGroundUnit(unitType, e.latlng, getActiveCoalition());
|
||||
}}}), true);
|
||||
}
|
||||
|
||||
#drawMeasureLine()
|
||||
{
|
||||
var mouseLatLng = this.containerPointToLatLng(this.#lastMousePosition);
|
||||
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 = this.latLngToContainerPoint(this.#measurePoint);
|
||||
var dx = (this.#lastMousePosition.x - startXY.x);
|
||||
var dy = (this.#lastMousePosition.y - startXY.y);
|
||||
|
||||
var angle = Math.atan2(dy, dx);
|
||||
if (angle > Math.PI / 2)
|
||||
angle = angle - Math.PI;
|
||||
|
||||
if (angle < -Math.PI / 2)
|
||||
angle = angle + Math.PI;
|
||||
|
||||
this.#measureLineDiv.innerHTML = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM`
|
||||
this.#measureLineDiv.style.left = (this.#lastMousePosition.x + startXY.x) / 2 - this.#measureLineDiv.offsetWidth / 2 + "px";
|
||||
this.#measureLineDiv.style.top = (this.#lastMousePosition.y + startXY.y) / 2 - this.#measureLineDiv.offsetHeight / 2 + "px";
|
||||
this.#measureLineDiv.style.rotate = angle + "rad";
|
||||
this.#measureLineDiv.style.display = "";
|
||||
}
|
||||
|
||||
if (!this.hasLayer(this.#measureLine))
|
||||
this.#measureLine.addTo(this);
|
||||
}
|
||||
|
||||
#hideMeasureLine()
|
||||
{
|
||||
this.#measureLineDiv.style.display = "none";
|
||||
|
||||
if (this.hasLayer(this.#measureLine))
|
||||
this.removeLayer(this.#measureLine)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,35 @@
|
||||
import { LatLng } from "leaflet";
|
||||
import { getMissionData } from "..";
|
||||
import { Icon, LatLng, Marker, Polyline } from "leaflet";
|
||||
import { getMap, getMissionData, getUnitsManager } from "..";
|
||||
import { distance, bearing, zeroPad, zeroAppend } from "../other/utils";
|
||||
import { Unit } from "../units/unit";
|
||||
import { Panel } from "./panel";
|
||||
|
||||
export class MouseInfoPanel extends Panel {
|
||||
#measureMarker: Marker;
|
||||
#measurePoint: LatLng | null = null;
|
||||
#measureIcon: Icon;
|
||||
#measureLine: Polyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1, interactive: false });
|
||||
#measureBox: HTMLElement;
|
||||
|
||||
constructor(ID: string) {
|
||||
super(ID);
|
||||
|
||||
this.#measureIcon = new Icon({ iconUrl: 'images/pin.png', iconAnchor: [16, 32]});
|
||||
this.#measureMarker = new Marker([0, 0], {icon: this.#measureIcon, interactive: false});
|
||||
|
||||
this.#measureBox = document.createElement("div");
|
||||
this.#measureBox.classList.add("ol-measure-box");
|
||||
document.body.appendChild(this.#measureBox);
|
||||
|
||||
getMap()?.on("click", (e: any) => this.#onMapClick(e));
|
||||
getMap()?.on('zoom', (e: any) => this.#onZoom(e));
|
||||
getMap()?.on('mousemove', (e: any) => this.#onMouseMove(e));
|
||||
|
||||
document.addEventListener('unitsSelection', (e: CustomEvent<Unit[]>) => this.#onUnitsSelection(e.detail));
|
||||
document.addEventListener('clearSelection', () => this.#onClearSelection());
|
||||
}
|
||||
|
||||
update(mousePosition: LatLng, measurePosition: LatLng | null, unitPosition: LatLng | null) {
|
||||
#update(mousePosition: LatLng, measurePosition: LatLng | null, unitPosition: LatLng | null) {
|
||||
var bullseyes = getMissionData().getBullseyes();
|
||||
for (let idx in bullseyes)
|
||||
{
|
||||
@ -16,7 +37,7 @@ export class MouseInfoPanel extends Panel {
|
||||
var bear = bearing(bullseyes[idx].lat, bullseyes[idx].lng, mousePosition.lat, mousePosition.lng);
|
||||
var el = <HTMLElement>this.getElement().querySelector(`#bullseye-${idx}`);
|
||||
if (el != null)
|
||||
el.innerHTML = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM`
|
||||
el.innerText = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM`
|
||||
}
|
||||
|
||||
if (measurePosition) {
|
||||
@ -24,33 +45,100 @@ export class MouseInfoPanel extends Panel {
|
||||
var bear = bearing(measurePosition.lat, measurePosition.lng, mousePosition.lat, mousePosition.lng);
|
||||
var el = <HTMLElement>this.getElement().querySelector(`#measure-position`);
|
||||
if (el != null)
|
||||
{
|
||||
el.innerHTML = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM`
|
||||
if (el.parentElement != null)
|
||||
el.parentElement.style.display = 'flex'; //TODO: don't like that it's hardcoded
|
||||
}
|
||||
}
|
||||
else {
|
||||
var el = <HTMLElement>this.getElement().querySelector(`#measure-position`);
|
||||
if (el != null && el.parentElement != null)
|
||||
el.parentElement.style.display = 'none';
|
||||
el.innerText = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM`
|
||||
}
|
||||
|
||||
|
||||
if (unitPosition) {
|
||||
var dist = distance(unitPosition.lat, unitPosition.lng, mousePosition.lat, mousePosition.lng);
|
||||
var bear = bearing(unitPosition.lat, unitPosition.lng, mousePosition.lat, mousePosition.lng);
|
||||
var el = <HTMLElement>this.getElement().querySelector(`#unit-position`);
|
||||
if (el != null)
|
||||
{
|
||||
el.innerHTML = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM`
|
||||
if (el.parentElement != null)
|
||||
el.parentElement.style.display = 'flex'; //TODO: don't like that its hardcoded
|
||||
}
|
||||
}
|
||||
else {
|
||||
var el = <HTMLElement>this.getElement().querySelector(`#unit-position`);
|
||||
if (el != null && el.parentElement != null)
|
||||
el.parentElement.style.display = 'none';
|
||||
el.innerText = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM`
|
||||
}
|
||||
}
|
||||
|
||||
#onMapClick(e: any)
|
||||
{
|
||||
if (e.originalEvent.ctrlKey)
|
||||
{
|
||||
if (!this.#measurePoint)
|
||||
{
|
||||
this.#measureBox.classList.toggle("hide", false);
|
||||
this.getElement().querySelector(`#measure-position`)?.classList.toggle("hide", false);
|
||||
this.#measurePoint = e.latlng;
|
||||
this.#measureMarker.setLatLng(e.latlng);
|
||||
this.#measureMarker.addTo(getMap());
|
||||
if (!getMap().hasLayer(this.#measureLine))
|
||||
this.#measureLine.addTo(getMap());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.#measureBox.classList.toggle("hide", true);
|
||||
this.getElement().querySelector(`#measure-position`)?.classList.toggle("hide", true);
|
||||
this.#measurePoint = null;
|
||||
if (getMap().hasLayer(this.#measureMarker))
|
||||
getMap().removeLayer(this.#measureMarker);
|
||||
|
||||
this.#measureLine.setLatLngs([]);
|
||||
if (getMap().hasLayer(this.#measureLine))
|
||||
getMap().removeLayer(this.#measureLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#drawMeasureLine()
|
||||
{
|
||||
var mouseLatLng = getMap().containerPointToLatLng(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 = getMap().latLngToContainerPoint(this.#measurePoint);
|
||||
var dx = (getMap().getMousePosition().x - startXY.x);
|
||||
var dy = (getMap().getMousePosition().y - startXY.y);
|
||||
|
||||
var angle = Math.atan2(dy, dx);
|
||||
if (angle > Math.PI / 2)
|
||||
angle = angle - Math.PI;
|
||||
|
||||
if (angle < -Math.PI / 2)
|
||||
angle = angle + Math.PI;
|
||||
|
||||
this.#measureBox.innerText = `${zeroAppend(Math.floor(bear), 3)}° / ${zeroAppend(Math.floor(dist*0.000539957), 3)} NM`
|
||||
this.#measureBox.style.left = (getMap().getMousePosition().x + startXY.x) / 2 - this.#measureBox.offsetWidth / 2 + "px";
|
||||
this.#measureBox.style.top = (getMap().getMousePosition().y + startXY.y) / 2 - this.#measureBox.offsetHeight / 2 + "px";
|
||||
this.#measureBox.style.rotate = angle + "rad";
|
||||
}
|
||||
}
|
||||
|
||||
#onMouseMove(e: any)
|
||||
{
|
||||
var selectedUnitPosition = null;
|
||||
var selectedUnits = getUnitsManager().getSelectedUnits();
|
||||
if (selectedUnits && selectedUnits.length == 1)
|
||||
selectedUnitPosition = new LatLng(selectedUnits[0].getFlightData().latitude, selectedUnits[0].getFlightData().longitude);
|
||||
|
||||
this.#update(<LatLng>e.latlng, this.#measurePoint, selectedUnitPosition);
|
||||
this.#drawMeasureLine();
|
||||
}
|
||||
|
||||
#onZoom(e: any)
|
||||
{
|
||||
this.#drawMeasureLine();
|
||||
}
|
||||
|
||||
#onUnitsSelection(units: Unit[])
|
||||
{
|
||||
if (units.length == 1)
|
||||
this.getElement().querySelector(`#unit-position`)?.classList.toggle("hide", false);
|
||||
}
|
||||
|
||||
#onClearSelection()
|
||||
{
|
||||
this.#measureBox.classList.toggle("hide", true);
|
||||
this.getElement().querySelector(`#unit-position`)?.classList.toggle("hide", true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
export class Panel {
|
||||
#element: HTMLElement
|
||||
#visible: boolean = true;
|
||||
|
||||
constructor(ID: string) {
|
||||
this.#element = <HTMLElement>document.getElementById(ID);
|
||||
@ -7,13 +8,19 @@ export class Panel {
|
||||
|
||||
show() {
|
||||
this.#element.classList.toggle("hide", false);
|
||||
this.#visible = true;
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.#element.classList.toggle("hide", true);
|
||||
this.#visible = false;
|
||||
}
|
||||
|
||||
getElement() {
|
||||
return this.#element;
|
||||
}
|
||||
|
||||
getVisible(){
|
||||
return this.#visible;
|
||||
}
|
||||
}
|
||||
@ -30,11 +30,15 @@ export class UnitInfoPanel extends Panel {
|
||||
this.#task = <HTMLElement>(this.getElement().querySelector("#task"));
|
||||
this.#loadoutContainer = <HTMLElement>(this.getElement().querySelector("#loadout-container"));
|
||||
|
||||
document.addEventListener("unitsSelection", (e: CustomEvent<Unit[]>) => this.#onUnitsSelection(e.detail));
|
||||
document.addEventListener("unitsDeselection", (e: CustomEvent<Unit[]>) => this.#onUnitsDeselection(e.detail));
|
||||
document.addEventListener("unitUpdated", (e: CustomEvent<Unit>) => this.#onUnitUpdate(e.detail));
|
||||
|
||||
this.hide();
|
||||
}
|
||||
|
||||
update(unit: Unit) {
|
||||
if (this.getElement() != null) {
|
||||
#onUnitUpdate(unit: Unit) {
|
||||
if (this.getElement() != null && this.getVisible()) {
|
||||
/* Set the unit info */
|
||||
this.#unitName.innerText = unit.getData().unitName;
|
||||
this.#groupName.innerText = unit.getData().groupName;
|
||||
@ -72,4 +76,18 @@ export class UnitInfoPanel extends Panel {
|
||||
el.innerText = amount + "x" + displayName;
|
||||
this.#loadoutContainer.appendChild(el);
|
||||
}
|
||||
|
||||
#onUnitsSelection(units: Unit[]){
|
||||
if (units.length == 1)
|
||||
this.show();
|
||||
else
|
||||
this.hide();
|
||||
}
|
||||
|
||||
#onUnitsDeselection(units: Unit[]){
|
||||
if (units.length == 1)
|
||||
this.show();
|
||||
else
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
@ -49,7 +49,7 @@ export function getUnits(callback: CallableFunction, refresh: boolean = false) {
|
||||
if (!DEMO)
|
||||
GET(callback, `${UNITS_URI}/${refresh? REFRESH_URI: UPDATE_URI}}`);
|
||||
else
|
||||
callback(refresh? generateRandomUnitsDemoData(1000): {units:{}});
|
||||
callback(refresh? generateRandomUnitsDemoData(100): {units:{}});
|
||||
}
|
||||
|
||||
export function addDestination(ID: number, path: any) {
|
||||
@ -149,8 +149,8 @@ function generateRandomUnitsDemoData(unitsNumber: number)
|
||||
for (let i = 0; i < unitsNumber; i++)
|
||||
{
|
||||
units[String(i)] = structuredClone(DEMO_UNIT_DATA);
|
||||
units[String(i)].flightData.latitude += (Math.random() - 0.5) * 0.1;
|
||||
units[String(i)].flightData.longitude += (Math.random() - 0.5) * 0.1;
|
||||
units[String(i)].flightData.latitude += (Math.random() - 0.5) * 0.3;
|
||||
units[String(i)].flightData.longitude += (Math.random() - 0.5) * 0.3;
|
||||
}
|
||||
return {"units": units};
|
||||
}
|
||||
@ -163,8 +163,8 @@ const DEMO_UNIT_DATA = {
|
||||
alive: true,
|
||||
category: "Aircraft",
|
||||
flightData: {
|
||||
latitude: 37.3,
|
||||
longitude: -116,
|
||||
latitude: 37.2,
|
||||
longitude: -115.8,
|
||||
altitude: 2000,
|
||||
heading: 0.5,
|
||||
speed: 300
|
||||
|
||||
@ -87,6 +87,7 @@ export class Unit extends Marker {
|
||||
}
|
||||
|
||||
setData(data: UnitData) {
|
||||
document.dispatchEvent(new CustomEvent("unitUpdated", { detail: this }));
|
||||
var updateMarker = true;
|
||||
//if (this.getFlightData().latitude != response.flightData.latitude ||
|
||||
// this.getFlightData().longitude != response.flightData.longitude ||
|
||||
@ -141,7 +142,10 @@ export class Unit extends Marker {
|
||||
if ((this.getData().alive || !selected) && this.#selectable && this.#selected != selected) {
|
||||
this.#selected = selected;
|
||||
this.getElement()?.querySelector(".unit")?.setAttribute("data-is-selected", String(this.getSelected()));
|
||||
document.dispatchEvent(new CustomEvent("unitSelection", { detail: this }));
|
||||
if (selected)
|
||||
document.dispatchEvent(new CustomEvent("unitSelection", { detail: this }));
|
||||
else
|
||||
document.dispatchEvent(new CustomEvent("unitDeselection", { detail: this }));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { LatLng, LatLngBounds } from "leaflet";
|
||||
import { getMap, getUnitControlPanel, getUnitInfoPanel } from "..";
|
||||
import { Unit, GroundUnit } from "./unit";
|
||||
import { getMap } from "..";
|
||||
import { Unit } from "./unit";
|
||||
import { cloneUnit } from "../server/server";
|
||||
import { IDLE, MOVE_UNIT } from "../map/map";
|
||||
|
||||
@ -15,7 +15,8 @@ export class UnitsManager {
|
||||
|
||||
document.addEventListener('copy', () => this.copyUnits());
|
||||
document.addEventListener('paste', () => this.pasteUnits());
|
||||
document.addEventListener('unitSelection', (e: CustomEvent) => this.onUnitSelection(e.detail));
|
||||
document.addEventListener('unitSelection', (e: CustomEvent) => this.#onUnitSelection(e.detail));
|
||||
document.addEventListener('unitDeselection', (e: CustomEvent) => this.#onUnitDeselection(e.detail));
|
||||
document.addEventListener('keydown', (event) => this.#onKeyDown(event));
|
||||
}
|
||||
|
||||
@ -56,15 +57,6 @@ export class UnitsManager {
|
||||
Object.keys(data.units)
|
||||
.filter((ID: string) => ID in this.#units)
|
||||
.forEach((ID: string) => this.#units[parseInt(ID)].setData(data.units[ID]));
|
||||
|
||||
/* Update the unit info panel */
|
||||
if (this.getSelectedUnits().length == 1) {
|
||||
getUnitInfoPanel()?.show();
|
||||
getUnitInfoPanel()?.update(this.getSelectedUnits()[0]);
|
||||
}
|
||||
else {
|
||||
getUnitInfoPanel()?.hide();
|
||||
}
|
||||
}
|
||||
|
||||
forceUpdate() {
|
||||
@ -80,25 +72,6 @@ export class UnitsManager {
|
||||
this.#units[ID]?.setSelected(true);
|
||||
}
|
||||
|
||||
onUnitSelection(unit: Unit) {
|
||||
if (this.getSelectedUnits().length > 0) {
|
||||
getMap().setState(MOVE_UNIT);
|
||||
/* Disable the firing of the selection event for a certain amount of time. This avoids firing many events if many units are selected */
|
||||
if (!this.#selectionEventDisabled)
|
||||
{
|
||||
setTimeout(() => {
|
||||
document.dispatchEvent(new CustomEvent("unitsSelection", {detail: this.getSelectedUnits()}));
|
||||
this.#selectionEventDisabled = false;
|
||||
}, 300);
|
||||
this.#selectionEventDisabled = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
getMap().setState(IDLE);
|
||||
document.dispatchEvent(new CustomEvent("clearSelection"));
|
||||
}
|
||||
}
|
||||
|
||||
selectFromBounds(bounds: LatLngBounds)
|
||||
{
|
||||
this.deselectAllUnits();
|
||||
@ -359,4 +332,32 @@ export class UnitsManager {
|
||||
this.selectedUnitsDelete();
|
||||
}
|
||||
}
|
||||
|
||||
#onUnitSelection(unit: Unit) {
|
||||
if (this.getSelectedUnits().length > 0) {
|
||||
getMap().setState(MOVE_UNIT);
|
||||
/* Disable the firing of the selection event for a certain amount of time. This avoids firing many events if many units are selected */
|
||||
if (!this.#selectionEventDisabled)
|
||||
{
|
||||
setTimeout(() => {
|
||||
document.dispatchEvent(new CustomEvent("unitsSelection", {detail: this.getSelectedUnits()}));
|
||||
this.#selectionEventDisabled = false;
|
||||
}, 300);
|
||||
this.#selectionEventDisabled = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
getMap().setState(IDLE);
|
||||
document.dispatchEvent(new CustomEvent("clearSelection"));
|
||||
}
|
||||
}
|
||||
|
||||
#onUnitDeselection(unit: Unit) {
|
||||
if (this.getSelectedUnits().length == 0) {
|
||||
getMap().setState(IDLE);
|
||||
document.dispatchEvent(new CustomEvent("clearSelection"));
|
||||
}
|
||||
else
|
||||
document.dispatchEvent(new CustomEvent("unitsDeselection", {detail: this.getSelectedUnits()}));
|
||||
}
|
||||
}
|
||||
@ -27,7 +27,6 @@
|
||||
|
||||
<%- include('contextmenu.ejs') %>
|
||||
<%- include('unitcontrolpanel.ejs') %>
|
||||
<%- include('unitinfopanel.ejs') %>
|
||||
<%- include('mouseinfopanel.ejs') %>
|
||||
<%- include('navbar.ejs') %>
|
||||
<%- include('connectionstatuspanel.ejs') %>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<div id="mouse-info-panel" class="ol-panel">
|
||||
<div class="list-item"><div id="measure-position">---° / --- NM</div></div>
|
||||
<div class="list-item"><div id="unit-position">---° / --- NM</div></div>
|
||||
<div class="list-item"><div id="measure-position" class="hide">---° / --- NM</div></div>
|
||||
<div class="list-item"><div id="unit-position" class="hide">---° / --- NM</div></div>
|
||||
<div class="list-item"><div id="bullseye-2">---° / --- NM</div></div>
|
||||
<div class="list-item"><div id="bullseye-1">---° / --- NM</div></div>
|
||||
</div>
|
||||
@ -1,9 +1,36 @@
|
||||
<div class="ol-panel" id="unit-control-panel">
|
||||
<div id="unit-control-panel" class="ol-panel">
|
||||
<h2>Selected units</h2>
|
||||
<div id="selected-units-container" class="ol-scroll">
|
||||
<!-- This is where all the unit selection buttons will be shown-->
|
||||
</div>
|
||||
|
||||
<div id="unit-info-panel">
|
||||
<div id="general" class="panel-section">
|
||||
<h3 id="unit-name">Olympus 1-1</h3>
|
||||
<div id="name" class="pill highlight-primary">Name</div>
|
||||
<div id="group-name" class="pill highlight-primary">Group</div>
|
||||
<div id="task" class="pill highlight-primary">Task</div>
|
||||
</div>
|
||||
<div id="flight-data" class="panel-section">
|
||||
<h3 id="flight-data-label">Flight data</h3>
|
||||
<div id="latitude"></div>
|
||||
<div id="longitude"></div>
|
||||
<div class="data-grid">
|
||||
<div class="data-row"><img class="icon-small" src="images/icons/speed.svg"><h5>Ground Speed</h5><h4 id="ground-speed">12</h4></div>
|
||||
<div class="data-row"><img class="icon-small" src="images/icons/altitude.svg"><h5>Altitude</h5><h4 id="altitude"></h4></div>
|
||||
<div class="data-row"><img class="icon-small" src="images/icons/heading.svg"><h5>Heading</h5><h4 id="heading"></h4></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loadout-data" class="panel-section">
|
||||
<h3 id="loadout-label">Loadout</h3>
|
||||
<div class="data-grid">
|
||||
<div class="data-row"><img class="icon-small" src="images/icons/fuel.svg"><h5>Fuel</h5><h4 id="fuel"></h4></div>
|
||||
</div>
|
||||
<div id="loadout-container" class="ol-scroll">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Controls</h3>
|
||||
<div id="flight-controls-buttons-container">
|
||||
<div class="slider-container flight-control-slider" id="altitude-slider">
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
<div id="unit-info-panel" class="ol-panel" >
|
||||
<div class="ol-panel-board">
|
||||
<div id="general" class="panel-section">
|
||||
<h1 id="unit-name">Olympus 1-1</h1>
|
||||
<div id="name" class="pill highlight-primary">Name</div>
|
||||
<div id="group-name" class="pill highlight-primary">Group</div>
|
||||
<div id="task" class="pill highlight-primary">Task</div>
|
||||
</div>
|
||||
<div id="flight-data" class="panel-section">
|
||||
<h1 id="flight-data-label">Flight data</h1>
|
||||
<div id="latitude"></div>
|
||||
<div id="longitude"></div>
|
||||
<div class="data-grid">
|
||||
<div class="data-row"><img class="icon-small" src="images/icons/speed.svg"><h5>Ground Speed</h5><h4 id="ground-speed">12</h4></div>
|
||||
<div class="data-row"><img class="icon-small" src="images/icons/altitude.svg"><h5>Altitude</h5><h4 id="altitude"></h4></div>
|
||||
<div class="data-row"><img class="icon-small" src="images/icons/heading.svg"><h5>Heading</h5><h4 id="heading"></h4></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loadout-data" class="panel-section">
|
||||
<h1 id="loadout-label">Loadout</h1>
|
||||
<div class="data-grid">
|
||||
<div class="data-row"><img class="icon-small" src="images/icons/fuel.svg"><h5>Fuel</h5><h4 id="fuel"></h4></div>
|
||||
</div>
|
||||
<div id="loadout-container" class="ol-scroll">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user