mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Started event handling
This commit is contained in:
parent
abf5f40020
commit
93b1ac8f81
@ -1,102 +0,0 @@
|
||||
.ol-selection-wheel {
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
overflow: visible;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ol-wheel {
|
||||
width: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: var(--background-color-dark);
|
||||
-webkit-mask: radial-gradient(transparent 30%, #000 31%);
|
||||
mask: radial-gradient(transparent 30%, #000 31%);
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.ol-wheel:before {
|
||||
content: "";
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
|
||||
.selection-wheel-button {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
opacity: 0;
|
||||
/*transition: opacity var(--animation_duration), left var(--animation_duration), top var(--animation_duration);*/
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.selection-wheel-image {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
/*filter: invert(100%);*/
|
||||
transition: width var(--animation_duration), height var(--animation_duration);
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.selection-wheel-button:hover {
|
||||
|
||||
}
|
||||
|
||||
.selection-wheel-button:hover .selection-wheel-image {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/*filter: invert(21%) sepia(23%) saturate(775%) hue-rotate(170deg) brightness(92%) contrast(90%);*/
|
||||
}
|
||||
|
||||
.ol-selection-wheel label {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.ol-selection-wheel input {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.ol-selection-wheel-switch {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 34px;
|
||||
background-color: var(--active-coalition-color);
|
||||
border-radius: 17px;
|
||||
margin-left: -30px;
|
||||
margin-top: -17px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ol-selection-wheel-switch:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
-webkit-transition: 0.2s;
|
||||
transition: 0.2s;
|
||||
border-radius: 50%;
|
||||
|
||||
}
|
||||
|
||||
input:checked+.ol-selection-wheel-switch:before {
|
||||
-webkit-transform: translateX(26px);
|
||||
-ms-transform: translateX(26px);
|
||||
transform: translateX(26px);
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
@import url("dropdown.css");
|
||||
|
||||
@import url("selectionwheel.css");
|
||||
@import url("selectionscroll.css");
|
||||
@import url("contextmenu.css");
|
||||
|
||||
@import url("unitmarker.css");
|
||||
@import url("airbasemarker.css");
|
||||
|
||||
29
client/src/@types/dom.d.ts
vendored
Normal file
29
client/src/@types/dom.d.ts
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
interface CustomEventMap {
|
||||
"unitSelection": CustomEvent<Unit>,
|
||||
"unitsSelection": CustomEvent<Unit[]>,
|
||||
"clearSelection": CustomEvent<>,
|
||||
"unitCreation": CustomEvent<Unit>,
|
||||
"unitDeletion": CustomEvent<Unit>,
|
||||
"unitUpdated": CustomEvent<Unit>,
|
||||
"unitMoveCommand": CustomEvent<Unit>,
|
||||
"unitAttackCommand": CustomEvent<Unit>,
|
||||
"unitLandCommand": CustomEvent<Unit>,
|
||||
"unitSetAltitudeCommand": CustomEvent<Unit>,
|
||||
"unitSetSpeedCommand": CustomEvent<Unit>,
|
||||
"unitSetROECommand": CustomEvent<Unit>,
|
||||
"unitSetReactionToThreatCommand": CustomEvent<Unit>,
|
||||
"groupCreation": CustomEvent<Unit[]>,
|
||||
"groupDeletion": CustomEvent<Unit[]>,
|
||||
"mapStateChanged": CustomEvent<string>,
|
||||
"mapContextMenu": CustomEvent<>
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Document {
|
||||
addEventListener<K extends keyof CustomEventMap>(type: K,
|
||||
listener: (this: Document, ev: CustomEventMap[K]) => void): void;
|
||||
dispatchEvent<K extends keyof CustomEventMap>(ev: CustomEventMap[K]): void;
|
||||
}
|
||||
}
|
||||
|
||||
export { };
|
||||
@ -1,7 +1,7 @@
|
||||
import { LatLng } from "leaflet";
|
||||
import { getActiveCoalition, setActiveCoalition } from "..";
|
||||
|
||||
export class SelectionScroll {
|
||||
export class ContextMenu {
|
||||
#container: HTMLElement | null;
|
||||
#display: string;
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
import { getActiveCoalition, setActiveCoalition } from "..";
|
||||
import { deg2rad } from "../other/utils";
|
||||
|
||||
export class SelectionWheel {
|
||||
#container: HTMLElement | null;
|
||||
#display: string;
|
||||
|
||||
constructor(id: string) {
|
||||
this.#container = document.getElementById(id);
|
||||
this.#display = '';
|
||||
if (this.#container != null) {
|
||||
this.#container.querySelector("#coalition-switch")?.addEventListener('change', (e) => this.#onSwitch(e))
|
||||
this.#display = this.#container.style.display;
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
|
||||
show(x: number, y: number, options: any, showCoalition: boolean) {
|
||||
/* Hide to remove buttons, if present */
|
||||
this.hide();
|
||||
|
||||
if (this.#container != null) {
|
||||
this.#container.style.display = this.#display;
|
||||
this.#container.style.left = x - 110 + "px";
|
||||
this.#container.style.top = y - 110 + "px";
|
||||
|
||||
var angularSize = 360 / options.length;
|
||||
var r = 80;
|
||||
|
||||
/* Create the buttons */
|
||||
for (let id in options) {
|
||||
var button = document.createElement("div");
|
||||
button.classList.add("selection-wheel-button");
|
||||
button.style.left = x - 25 + "px";
|
||||
button.style.top = y - 25 + "px";
|
||||
button.addEventListener('click', (e) => options[id].callback(e));
|
||||
this.#container.appendChild(button);
|
||||
var angle = parseInt(id) * angularSize;
|
||||
button.style.opacity = "1";
|
||||
button.style.left = x + r * Math.sin(deg2rad(angle)) - 25 + "px";
|
||||
button.style.top = y - r * Math.cos(deg2rad(angle)) - 25 + "px";
|
||||
|
||||
var image = document.createElement("img");
|
||||
image.classList.add("selection-wheel-image");
|
||||
image.src = `images/buttons/${options[id].src}`
|
||||
image.title = options[id].tooltip;
|
||||
if ('tint' in options[id]) {
|
||||
button.style.setProperty('background-color', options[id].tint);
|
||||
image.style.opacity = "0";
|
||||
}
|
||||
button.appendChild(image);
|
||||
}
|
||||
|
||||
/* Hide the coalition switch if required */
|
||||
var switchContainer = <HTMLElement>this.#container.querySelector("#coalition-switch-container");
|
||||
if (showCoalition == false) {
|
||||
switchContainer.style.display = "none";
|
||||
document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--neutral-coalition-color"));
|
||||
}
|
||||
else {
|
||||
switchContainer.style.display = "block";
|
||||
if (getActiveCoalition() == "blue")
|
||||
document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--blue-coalition-color"));
|
||||
else
|
||||
document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--red-coalition-color"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hide() {
|
||||
if (this.#container != null) {
|
||||
this.#container.style.display = "none";
|
||||
var buttons = this.#container.querySelectorAll(".selection-wheel-button");
|
||||
for (let child of buttons) {
|
||||
this.#container.removeChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#onSwitch(e: any) {
|
||||
if (this.#container != null) {
|
||||
if (e.currentTarget.checked) {
|
||||
document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--red-coalition-color"));
|
||||
setActiveCoalition("red");
|
||||
}
|
||||
else {
|
||||
document.documentElement.style.setProperty('--active-coalition-color', getComputedStyle(this.#container).getPropertyValue("--blue-coalition-color"));
|
||||
setActiveCoalition("blue");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,8 @@
|
||||
import { Map } from "./map/map"
|
||||
import { getDataFromDCS } from "./dcs/dcs"
|
||||
import { SelectionWheel } from "./controls/selectionwheel";
|
||||
import { UnitsManager } from "./units/unitsmanager";
|
||||
import { UnitInfoPanel } from "./panels/unitinfopanel";
|
||||
import { SelectionScroll } from "./controls/selectionscroll";
|
||||
import { ContextMenu } from "./controls/contextmenu";
|
||||
import { Dropdown } from "./controls/dropdown";
|
||||
import { ConnectionStatusPanel } from "./panels/connectionstatuspanel";
|
||||
import { MissionData } from "./missiondata/missiondata";
|
||||
@ -14,8 +13,7 @@ import { LogPanel } from "./panels/logpanel";
|
||||
|
||||
/* TODO: should this be a class? */
|
||||
var map: Map;
|
||||
var selectionWheel: SelectionWheel;
|
||||
var selectionScroll: SelectionScroll;
|
||||
var contextMenu: ContextMenu;
|
||||
|
||||
var unitsManager: UnitsManager;
|
||||
var missionData: MissionData;
|
||||
@ -38,8 +36,7 @@ function setup() {
|
||||
unitsManager = new UnitsManager();
|
||||
missionData = new MissionData();
|
||||
|
||||
selectionWheel = new SelectionWheel("selection-wheel");
|
||||
selectionScroll = new SelectionScroll("selection-scroll");
|
||||
contextMenu = new ContextMenu("selection-scroll");
|
||||
|
||||
unitInfoPanel = new UnitInfoPanel("unit-info-panel");
|
||||
unitControlPanel = new UnitControlPanel("unit-control-panel");
|
||||
@ -78,12 +75,8 @@ export function getMissionData() {
|
||||
return missionData;
|
||||
}
|
||||
|
||||
export function getSelectionWheel() {
|
||||
return selectionWheel;
|
||||
}
|
||||
|
||||
export function getSelectionScroll() {
|
||||
return selectionScroll;
|
||||
export function getContextMenu() {
|
||||
return contextMenu;
|
||||
}
|
||||
|
||||
export function getUnitsManager() {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import * as L from "leaflet"
|
||||
import { getSelectionWheel, getSelectionScroll, getUnitsManager, getActiveCoalition, getMouseInfoPanel } from "..";
|
||||
import { getContextMenu, getUnitsManager, getActiveCoalition, getMouseInfoPanel } from "..";
|
||||
import { spawnAircraft, spawnGroundUnit, spawnSmoke } from "../dcs/dcs";
|
||||
import { bearing, distance, zeroAppend } from "../other/utils";
|
||||
import { aircraftDatabase, getAircraftLabelsByRole, getLoadoutsByName, getLoadoutNamesByRole, getAircraftNameByLabel } from "../units/aircraftDatabase";
|
||||
import { getAircraftLabelsByRole, getLoadoutsByName, getLoadoutNamesByRole, getAircraftNameByLabel } from "../units/aircraftDatabase";
|
||||
import { unitTypes } from "../units/unitTypes";
|
||||
import { BoxSelect } from "./boxselect";
|
||||
|
||||
@ -14,14 +14,14 @@ export interface ClickEvent {
|
||||
latlng: L.LatLng;
|
||||
}
|
||||
|
||||
export interface SpawnEvent extends ClickEvent{
|
||||
export interface SpawnEvent extends ClickEvent {
|
||||
airbaseName: string | null;
|
||||
coalitionID: number | null;
|
||||
}
|
||||
|
||||
export class Map extends L.Map {
|
||||
#state: string;
|
||||
#layer?: L.TileLayer;
|
||||
#layer: L.TileLayer | null = null;
|
||||
#preventLeftClick: boolean = false;
|
||||
#leftClickTimer: number = 0;
|
||||
#measurePoint: L.LatLng | null;
|
||||
@ -113,39 +113,30 @@ export class Map extends L.Map {
|
||||
/* State machine */
|
||||
setState(state: string) {
|
||||
this.#state = state;
|
||||
|
||||
if (this.#state === "IDLE") {
|
||||
L.DomUtil.removeClass(this.getContainer(),'crosshair-cursor-enabled');
|
||||
}
|
||||
else if (this.#state === "MOVE_UNIT") {
|
||||
L.DomUtil.addClass(this.getContainer(),'crosshair-cursor-enabled');
|
||||
}
|
||||
document.dispatchEvent(new CustomEvent("mapStateChanged"));
|
||||
}
|
||||
|
||||
getState() {
|
||||
return this.#state;
|
||||
}
|
||||
|
||||
/* Selection wheel */
|
||||
showSelectionWheel(e: ClickEvent | SpawnEvent, options: any, showCoalition: boolean) {
|
||||
var x = e.x;
|
||||
var y = e.y;
|
||||
getSelectionWheel().show(x, y, options, showCoalition);
|
||||
}
|
||||
|
||||
hideSelectionWheel() {
|
||||
getSelectionWheel().hide();
|
||||
}
|
||||
|
||||
/* Selection scroll */
|
||||
showSelectionScroll(e: ClickEvent | SpawnEvent, title: string, options: any, callback: CallableFunction, showCoalition: boolean = false) {
|
||||
showContextMenu(e: ClickEvent | SpawnEvent, title: string, options: any, callback: CallableFunction, showCoalition: boolean = false) {
|
||||
var x = e.x;
|
||||
var y = e.y;
|
||||
getSelectionScroll().show(x, y, title, options, callback, showCoalition);
|
||||
getContextMenu().show(x, y, title, options, callback, showCoalition);
|
||||
document.dispatchEvent(new CustomEvent("mapContextMenu"));
|
||||
}
|
||||
|
||||
hideSelectionScroll() {
|
||||
getSelectionScroll().hide();
|
||||
hideContextMenu() {
|
||||
getContextMenu().hide();
|
||||
document.dispatchEvent(new CustomEvent("mapContextMenu"));
|
||||
}
|
||||
|
||||
getMousePosition() {
|
||||
@ -156,11 +147,16 @@ export class Map extends L.Map {
|
||||
return this.containerPointToLatLng(this.#lastMousePosition);
|
||||
}
|
||||
|
||||
/* Spawn from air base */
|
||||
spawnFromAirbase(e: SpawnEvent)
|
||||
{
|
||||
this.#aircraftSpawnMenu(e);
|
||||
}
|
||||
|
||||
/* Event handlers */
|
||||
#onClick(e: any) {
|
||||
if (!this.#preventLeftClick) {
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.hideContextMenu();
|
||||
if (this.#state === "IDLE") {
|
||||
if (e.originalEvent.ctrlKey)
|
||||
if (!this.#measurePoint)
|
||||
@ -179,8 +175,7 @@ export class Map extends L.Map {
|
||||
else if (this.#state === "MOVE_UNIT") {
|
||||
this.setState("IDLE");
|
||||
getUnitsManager().deselectAllUnits();
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.hideContextMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,8 +185,7 @@ export class Map extends L.Map {
|
||||
}
|
||||
|
||||
#onContextMenu(e: any) {
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.hideContextMenu();
|
||||
if (this.#state === "IDLE") {
|
||||
var spawnEvent: SpawnEvent = {x: e.originalEvent.x, y: e.originalEvent.y, latlng: e.latlng, airbaseName: null, coalitionID: null};
|
||||
if (this.#state == "IDLE") {
|
||||
@ -201,7 +195,7 @@ export class Map extends L.Map {
|
||||
{ "tooltip": "Smoke", "src": "spawnSmoke.png", "callback": () => this.#smokeSpawnMenu(spawnEvent) },
|
||||
//{ "tooltip": "Explosion", "src": "spawnExplosion.png", "callback": () => this.#explosionSpawnMenu(e) }
|
||||
]
|
||||
this.showSelectionScroll(spawnEvent, "Action", options, () => {}, false);
|
||||
this.showContextMenu(spawnEvent, "Action", options, () => {}, false);
|
||||
}
|
||||
}
|
||||
else if (this.#state === "MOVE_UNIT") {
|
||||
@ -265,12 +259,6 @@ export class Map extends L.Map {
|
||||
this.#hideMeasureLine();
|
||||
}
|
||||
|
||||
/* Spawn from air base */
|
||||
spawnFromAirbase(e: SpawnEvent)
|
||||
{
|
||||
this.#aircraftSpawnMenu(e);
|
||||
}
|
||||
|
||||
/* Spawning menus */
|
||||
#aircraftSpawnMenu(e: SpawnEvent) {
|
||||
var options = [
|
||||
@ -284,9 +272,9 @@ export class Map extends L.Map {
|
||||
{ 'coalition': true, 'tooltip': 'Transport', 'src': 'spawnTransport.png', 'callback': () => this.#selectAircraft(e, "transport") },
|
||||
]
|
||||
if (e.airbaseName != null)
|
||||
this.showSelectionScroll(e, "Spawn at " + e.airbaseName, options, () => {}, true);
|
||||
this.showContextMenu(e, "Spawn at " + e.airbaseName, options, () => {}, true);
|
||||
else
|
||||
this.showSelectionScroll(e, "Spawn air unit", options, () => {}, true);
|
||||
this.showContextMenu(e, "Spawn air unit", options, () => {}, true);
|
||||
}
|
||||
|
||||
#groundUnitSpawnMenu(e: SpawnEvent) {
|
||||
@ -299,20 +287,19 @@ export class Map extends L.Map {
|
||||
{'coalition': true, 'tooltip': 'Radar', 'src': 'spawnRadar.png', 'callback': () => this.#selectGroundUnit(e, "Radar")},
|
||||
{'coalition': true, 'tooltip': 'Unarmed', 'src': 'spawnUnarmed.png', 'callback': () => this.#selectGroundUnit(e, "Unarmed")}
|
||||
]
|
||||
this.showSelectionScroll(e, "Spawn ground unit", options, () => {}, true);
|
||||
this.showContextMenu(e, "Spawn ground unit", options, () => {}, true);
|
||||
}
|
||||
|
||||
#smokeSpawnMenu(e: SpawnEvent) {
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.hideContextMenu();
|
||||
var options = [
|
||||
{'tooltip': 'Red smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideSelectionWheel(); this.hideSelectionScroll(); spawnSmoke('red', e.latlng)}, 'tint': 'red'},
|
||||
{'tooltip': 'White smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideSelectionWheel(); this.hideSelectionScroll(); spawnSmoke('white', e.latlng)}, 'tint': 'white'},
|
||||
{'tooltip': 'Blue smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideSelectionWheel(); this.hideSelectionScroll(); spawnSmoke('blue', e.latlng)}, 'tint': 'blue'},
|
||||
{'tooltip': 'Green smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideSelectionWheel(); this.hideSelectionScroll(); spawnSmoke('green', e.latlng)}, 'tint': 'green'},
|
||||
{'tooltip': 'Orange smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideSelectionWheel(); this.hideSelectionScroll(); spawnSmoke('orange', e.latlng)}, 'tint': 'orange'},
|
||||
{'tooltip': 'Red smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideContextMenu(); spawnSmoke('red', e.latlng)}, 'tint': 'red'},
|
||||
{'tooltip': 'White smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideContextMenu(); spawnSmoke('white', e.latlng)}, 'tint': 'white'},
|
||||
{'tooltip': 'Blue smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideContextMenu(); spawnSmoke('blue', e.latlng)}, 'tint': 'blue'},
|
||||
{'tooltip': 'Green smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideContextMenu(); spawnSmoke('green', e.latlng)}, 'tint': 'green'},
|
||||
{'tooltip': 'Orange smoke', 'src': 'spawnSmoke.png', 'callback': () => {this.hideContextMenu(); spawnSmoke('orange', e.latlng)}, 'tint': 'orange'},
|
||||
]
|
||||
this.showSelectionScroll(e, "Spawn smoke", options, () => {}, false);
|
||||
this.showContextMenu(e, "Spawn smoke", options, () => {}, false);
|
||||
}
|
||||
|
||||
#explosionSpawnMenu(e: SpawnEvent) {
|
||||
@ -321,12 +308,10 @@ export class Map extends L.Map {
|
||||
|
||||
/* Show unit selection for air units */
|
||||
#selectAircraft(e: SpawnEvent, role: string) {
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.hideContextMenu();
|
||||
var options = getAircraftLabelsByRole(role);
|
||||
this.showSelectionScroll(e, "Select aircraft", options, (label: string) => {
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.showContextMenu(e, "Select aircraft", options, (label: string) => {
|
||||
this.hideContextMenu();
|
||||
var name = getAircraftNameByLabel(label);
|
||||
if (name != null)
|
||||
this.#unitSelectPayload(e, name, role);
|
||||
@ -335,15 +320,13 @@ export class Map extends L.Map {
|
||||
|
||||
/* Show weapon selection for air units */
|
||||
#unitSelectPayload(e: SpawnEvent, unitType: string, role: string) {
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.hideContextMenu();
|
||||
var options = getLoadoutNamesByRole(unitType, role);
|
||||
//options = payloadNames[unitType]
|
||||
if (options != undefined && options.length > 0) {
|
||||
options.sort();
|
||||
this.showSelectionScroll({x: e.x, y: e.y, latlng: e.latlng}, "Select loadout", options, (loadoutName: string) => {
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.showContextMenu({x: e.x, y: e.y, latlng: e.latlng}, "Select loadout", options, (loadoutName: string) => {
|
||||
this.hideContextMenu();
|
||||
var loadout = getLoadoutsByName(unitType, loadoutName);
|
||||
spawnAircraft(unitType, e.latlng, getActiveCoalition(), loadout.code, e.airbaseName);
|
||||
}, true);
|
||||
@ -356,13 +339,11 @@ export class Map extends L.Map {
|
||||
/* Show unit selection for ground units */
|
||||
#selectGroundUnit(e: any, group: string)
|
||||
{
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.hideContextMenu();
|
||||
var options = unitTypes.vehicles[group];
|
||||
options.sort();
|
||||
this.showSelectionScroll(e, "Select ground unit", options, (unitType: string) => {
|
||||
this.hideSelectionWheel();
|
||||
this.hideSelectionScroll();
|
||||
this.showContextMenu(e, "Select ground unit", options, (unitType: string) => {
|
||||
this.hideContextMenu();
|
||||
spawnGroundUnit(unitType, e.latlng, getActiveCoalition());
|
||||
}, true);
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ export class MissionData
|
||||
options = ["Spawn unit", "Land here"];
|
||||
else
|
||||
options = ["Spawn unit"];
|
||||
getMap().showSelectionScroll(e.originalEvent, e.sourceTarget.getName(), options, (option: string) => this.#onAirbaseOptionSelection(e, option), false);
|
||||
getMap().showContextMenu(e.originalEvent, e.sourceTarget.getName(), options, (option: string) => this.#onAirbaseOptionSelection(e, option), false);
|
||||
|
||||
}
|
||||
|
||||
@ -90,8 +90,7 @@ export class MissionData
|
||||
}
|
||||
else if (option === "Land here")
|
||||
{
|
||||
getMap().hideSelectionWheel();
|
||||
getMap().hideSelectionScroll();
|
||||
getMap().hideContextMenu();
|
||||
getUnitsManager().selectedUnitsLandAt(e.latlng);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,8 +118,7 @@ export class Unit {
|
||||
if ((this.alive || !selected) && this.#selectable && this.#selected != selected) {
|
||||
this.#selected = selected;
|
||||
this.#marker.setSelected(selected);
|
||||
getUnitsManager().onUnitSelection();
|
||||
|
||||
document.dispatchEvent(new CustomEvent("unitSelection", {detail: this}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,11 +206,11 @@ export class Unit {
|
||||
'Follow'
|
||||
]
|
||||
|
||||
getMap().showSelectionScroll(e.originalEvent, "Action: " + this.unitName, options, (action: string) => this.#executeAction(action));
|
||||
getMap().showContextMenu(e.originalEvent, "Action: " + this.unitName, options, (action: string) => this.#executeAction(action));
|
||||
}
|
||||
|
||||
#executeAction(action: string) {
|
||||
getMap().hideSelectionScroll();
|
||||
getMap().hideContextMenu();
|
||||
if (action === "Attack")
|
||||
getUnitsManager().selectedUnitsAttackUnit(this.ID);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ export class UnitsManager {
|
||||
|
||||
document.addEventListener('copy', () => this.copyUnits());
|
||||
document.addEventListener('paste', () => this.pasteUnits());
|
||||
document.addEventListener('unitSelection', () => this.onUnitSelection());
|
||||
}
|
||||
|
||||
#updateUnitControlPanel() {
|
||||
@ -98,13 +99,12 @@ export class UnitsManager {
|
||||
onUnitSelection() {
|
||||
if (this.getSelectedUnits().length > 0) {
|
||||
getMap().setState("MOVE_UNIT");
|
||||
//unitControlPanel.setEnabled(true);
|
||||
document.dispatchEvent(new CustomEvent("unitsSelection", {detail: this.getSelectedUnits()}));
|
||||
}
|
||||
else {
|
||||
getMap().setState("IDLE");
|
||||
//unitControlPanel.setEnabled(false);
|
||||
document.dispatchEvent(new CustomEvent("clearSelection"));
|
||||
}
|
||||
|
||||
this.#updateUnitControlPanel();
|
||||
}
|
||||
|
||||
|
||||
@ -11,8 +11,7 @@
|
||||
|
||||
<body>
|
||||
<div id="map-container"></div>
|
||||
<%- include('selectionwheel.ejs') %>
|
||||
<%- include('selectionscroll.ejs') %>
|
||||
<%- include('contextmenu.ejs') %>
|
||||
<div class="ol-dropdown" id="map-source-dropdown"></div>
|
||||
<!-- <div class="ol-dropdown" id="scenario-dropdown"></div> -->
|
||||
<%- include('unitinfopanel.ejs') %>
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
<div class="ol-selection-wheel" id="selection-wheel">
|
||||
<div class="ol-wheel">
|
||||
</div>
|
||||
<label id="coalition-switch-container">
|
||||
<input type="checkbox" id="coalition-switch"> <span
|
||||
class="ol-selection-wheel-slider ol-selection-wheel-switch"></span>
|
||||
</label>
|
||||
</div>
|
||||
@ -12,10 +12,13 @@ class Server
|
||||
{
|
||||
public:
|
||||
Server(lua_State* L);
|
||||
~Server();
|
||||
|
||||
void start(lua_State* L);
|
||||
void stop(lua_State* L);
|
||||
|
||||
private:
|
||||
std::thread* serverThread;
|
||||
json::value answer;
|
||||
|
||||
void handle_options(http_request request);
|
||||
void handle_get(http_request request);
|
||||
|
||||
@ -24,6 +24,8 @@ extern "C" DllExport int coreDeinit(lua_State* L)
|
||||
|
||||
log("Olympus coreDeinit called successfully");
|
||||
|
||||
server->stop(L);
|
||||
|
||||
delete unitsManager;
|
||||
delete server;
|
||||
delete scheduler;
|
||||
@ -42,6 +44,8 @@ extern "C" DllExport int coreInit(lua_State* L)
|
||||
|
||||
registerLuaFunctions(L);
|
||||
|
||||
server->start(L);
|
||||
|
||||
initialized = true;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -26,15 +26,25 @@ void handle_eptr(std::exception_ptr eptr)
|
||||
}
|
||||
|
||||
Server::Server(lua_State* L):
|
||||
serverThread(nullptr),
|
||||
runListener(true)
|
||||
{
|
||||
LogInfo(L, "Starting RESTServer");
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Server::start(lua_State* L)
|
||||
{
|
||||
log("Starting RESTServer");
|
||||
serverThread = new thread(&Server::task, this);
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
void Server::stop(lua_State* L)
|
||||
{
|
||||
log("Stopping RESTServer");
|
||||
runListener = false;
|
||||
if (serverThread != nullptr)
|
||||
serverThread->join();
|
||||
}
|
||||
|
||||
void Server::handle_options(http_request request)
|
||||
@ -59,18 +69,18 @@ void Server::handle_get(http_request request)
|
||||
response.headers().add(U("Access-Control-Allow-Methods"), U("GET, POST, PUT, OPTIONS"));
|
||||
response.headers().add(U("Access-Control-Allow-Headers"), U("Content-Type"));
|
||||
|
||||
auto answer = json::value::object();
|
||||
std::exception_ptr eptr;
|
||||
try {
|
||||
unitsManager->updateAnswer(answer);
|
||||
|
||||
/* Get the logs from the logger */
|
||||
auto logs = json::value::object();
|
||||
logsToJSON(logs); // By reference, for thread safety
|
||||
|
||||
answer[L"airbases"] = airbasesData;
|
||||
answer[L"bullseye"] = bullseyeData;
|
||||
answer[L"logs"] = json::value::object();
|
||||
|
||||
int i = 0;
|
||||
for (auto log : getLogs())
|
||||
answer[L"logs"][to_wstring(i++)] = json::value::string(to_wstring(log));
|
||||
|
||||
answer[L"logs"] = logs;
|
||||
|
||||
response.set_body(answer);
|
||||
}
|
||||
catch (...) {
|
||||
@ -156,7 +166,10 @@ void Server::task()
|
||||
|
||||
while (runListener);
|
||||
|
||||
listener.close();
|
||||
listener.close()
|
||||
.then([&listener]() {log("RESTServer stopping connections"); })
|
||||
.wait();
|
||||
|
||||
log("RESTServer stopped listening");
|
||||
}
|
||||
catch (exception const& e)
|
||||
|
||||
@ -3,4 +3,4 @@
|
||||
|
||||
void DllExport log(const std::string& sMessage);
|
||||
void DllExport log(const std::wstring& sMessage);
|
||||
std::list<std::string> DllExport getLogs();
|
||||
void DllExport logsToJSON(json::value& json);
|
||||
|
||||
@ -5,11 +5,12 @@
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
void Log(const string& sMessage);
|
||||
void Log(const wstring& sMessage);
|
||||
std::list<std::string> getLogs() { return m_logs; };
|
||||
void log(const string& sMessage);
|
||||
void log(const wstring& sMessage);
|
||||
void toJSON(json::value& json);
|
||||
|
||||
static Logger* GetLogger();
|
||||
|
||||
private:
|
||||
Logger();
|
||||
Logger(const Logger&) {}; // copy constructor is private
|
||||
@ -20,6 +21,8 @@ private:
|
||||
static ofstream m_Logfile;
|
||||
static std::list<std::string> m_logs;
|
||||
|
||||
mutex mutexLock;
|
||||
|
||||
void Open();
|
||||
void Close();
|
||||
};
|
||||
|
||||
@ -6,15 +6,15 @@
|
||||
|
||||
void log(const string& message)
|
||||
{
|
||||
LOGGER->Log(message);
|
||||
LOGGER->log(message);
|
||||
}
|
||||
|
||||
void log(const wstring& message)
|
||||
{
|
||||
LOGGER->Log(message);
|
||||
LOGGER->log(message);
|
||||
}
|
||||
|
||||
std::list<std::string> getLogs()
|
||||
void logsToJSON(json::value& json)
|
||||
{
|
||||
return LOGGER->getLogs();
|
||||
LOGGER->toJSON(json);
|
||||
}
|
||||
@ -16,8 +16,7 @@ Logger* Logger::GetLogger()
|
||||
if (m_pThis == NULL) {
|
||||
m_pThis = new Logger();
|
||||
std::filesystem::path dirPath = std::filesystem::temp_directory_path();
|
||||
m_Logfile.open((dirPath.string() + m_sFileName).c_str(), ios::out | ios::app);
|
||||
m_pThis->Log("**************************************************");
|
||||
m_Logfile.open((dirPath.string() + m_sFileName).c_str(), ios::out);
|
||||
}
|
||||
return m_pThis;
|
||||
}
|
||||
@ -33,8 +32,17 @@ void Logger::Close()
|
||||
m_Logfile.close();
|
||||
}
|
||||
|
||||
void Logger::Log(const string& message)
|
||||
void Logger::toJSON(json::value& json)
|
||||
{
|
||||
lock_guard<mutex> guard(mutexLock);
|
||||
int i = 0;
|
||||
for (auto log : m_logs)
|
||||
json[to_wstring(i++)] = json::value::string(to_wstring(log));
|
||||
}
|
||||
|
||||
void Logger::log(const string& message)
|
||||
{
|
||||
lock_guard<mutex> guard(mutexLock);
|
||||
Open();
|
||||
m_Logfile << CurrentDateTime() << ":\t";
|
||||
m_Logfile << message << "\n";
|
||||
@ -42,8 +50,9 @@ void Logger::Log(const string& message)
|
||||
Close();
|
||||
}
|
||||
|
||||
void Logger::Log(const wstring& message)
|
||||
void Logger::log(const wstring& message)
|
||||
{
|
||||
lock_guard<mutex> guard(mutexLock);
|
||||
Open();
|
||||
m_Logfile << CurrentDateTime() << ":\t";
|
||||
m_Logfile << to_string(message) << "\n";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user