mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Front end tweaks
Added visibility options and server log panel
This commit is contained in:
parent
5613394a2c
commit
4ae72b7c0b
@ -393,7 +393,7 @@ class DemoDataGenerator {
|
||||
ret.mission.RTSOptions = {
|
||||
restrictSpawns: true,
|
||||
restrictToCoalition: true,
|
||||
setupTime: 300,
|
||||
setupTime: 0,
|
||||
spawnPoints: {
|
||||
red: 1000,
|
||||
blue: 400
|
||||
|
||||
@ -101,4 +101,17 @@
|
||||
left: 50%;
|
||||
translate: -50% 0%;
|
||||
z-index: 9999;
|
||||
}
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#log-panel {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 220px;
|
||||
width: 310px;
|
||||
height: fit-content;
|
||||
z-index: 9990;
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
@import url("panels/mouseinfo.css");
|
||||
@import url("panels/unitcontrol.css");
|
||||
@import url("panels/unitinfo.css");
|
||||
@import url("panels/logpanel.css");
|
||||
@import url("other/contextmenus.css");
|
||||
@import url("other/popup.css");
|
||||
@import url("markers/airbase.css");
|
||||
@ -1351,4 +1352,11 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
[data-coalition="neutral"].ol-contexmenu-button:hover,
|
||||
[data-coalition="neutral"].ol-contexmenu-button.is-open {
|
||||
background-color: var(--primary-neutral)
|
||||
}
|
||||
|
||||
#map-type svg,
|
||||
#map-visibility-options svg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
fill: lightgray;
|
||||
}
|
||||
28
client/public/stylesheets/panels/logpanel.css
Normal file
28
client/public/stylesheets/panels/logpanel.css
Normal file
@ -0,0 +1,28 @@
|
||||
#log-panel>div:first-child {
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#log-panel svg {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#log-panel>div:nth-child(2) {
|
||||
display: none;
|
||||
margin-top: 5px;
|
||||
width: 100%;
|
||||
height: calc(100% - 40px);
|
||||
background-color: #00000055;
|
||||
}
|
||||
|
||||
#log-panel.open {
|
||||
height: 505px;
|
||||
}
|
||||
|
||||
#log-panel.open>div:nth-child(2) {
|
||||
display: block;
|
||||
}
|
||||
1
client/public/themes/olympus/images/icons/eye-solid.svg
Normal file
1
client/public/themes/olympus/images/icons/eye-solid.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM144 256a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm144-64c0 35.3-28.7 64-64 64c-7.1 0-13.9-1.2-20.3-3.3c-5.5-1.8-11.9 1.6-11.7 7.4c.3 6.9 1.3 13.8 3.2 20.7c13.7 51.2 66.4 81.6 117.6 67.9s81.6-66.4 67.9-117.6c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 820 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
2
client/src/@types/dom.d.ts
vendored
2
client/src/@types/dom.d.ts
vendored
@ -18,7 +18,7 @@ interface CustomEventMap {
|
||||
"groupDeletion": CustomEvent<Unit[]>,
|
||||
"mapStateChanged": CustomEvent<string>,
|
||||
"mapContextMenu": CustomEvent<>,
|
||||
"visibilityModeChanged": CustomEvent<string>,
|
||||
"mapVisibilityOptionsChanged": CustomEvent<>,
|
||||
"RTSOptionsChanged": CustomEvent<>,
|
||||
"contactsUpdated": CustomEvent<Unit>,
|
||||
}
|
||||
|
||||
@ -145,6 +145,11 @@ export const visibilityControlsTootlips: string[] = ["Toggle human players visib
|
||||
export const IADSTypes = ["AAA", "MANPADS", "SAM Site", "Radar"];
|
||||
export const IADSDensities: {[key: string]: number}= {"AAA": 0.8, "MANPADS": 0.3, "SAM Site": 0.1, "Radar": 0.05};
|
||||
|
||||
export const SHOW_CONTACT_LINES = "Show unit contact lines";
|
||||
export const HIDE_GROUP_MEMBERS = "Hide group members when zoomed out";
|
||||
export const SHOW_UNIT_PATHS = "Show unit paths";
|
||||
export const SHOW_UNIT_TARGETS = "Show unit targets";
|
||||
|
||||
export enum DataIndexes {
|
||||
startOfData = 0,
|
||||
category,
|
||||
|
||||
@ -562,7 +562,7 @@ export class MapContextMenu extends ContextMenu {
|
||||
}
|
||||
|
||||
#computeSpawnPoints() {
|
||||
if (getMissionHandler()){
|
||||
if (getMissionHandler() && getUnitsManager().getCommandMode() !== GAME_MASTER){
|
||||
var aircraftCount = parseInt(this.#aircraftCountDropdown.getValue());
|
||||
var aircraftSpawnPoints = aircraftCount * aircraftDatabase.getSpawnPointsByLabel(this.#aircraftLabelDropdown.getValue());
|
||||
(<HTMLButtonElement>this.getContainer()?.querySelector("#aircraft-spawn-menu")?.querySelector(".deploy-unit-button")).dataset.points = `${aircraftSpawnPoints}`;
|
||||
|
||||
@ -58,8 +58,8 @@ function setup() {
|
||||
serverStatusPanel = new ServerStatusPanel("server-status-panel");
|
||||
mouseInfoPanel = new MouseInfoPanel("mouse-info-panel");
|
||||
hotgroupPanel = new HotgroupPanel("hotgroup-panel");
|
||||
logPanel = new LogPanel("log-panel");
|
||||
|
||||
|
||||
/* Popups */
|
||||
infoPopup = new Popup("info-popup");
|
||||
|
||||
|
||||
@ -7,18 +7,16 @@ import { AirbaseContextMenu } from "../controls/airbasecontextmenu";
|
||||
import { Dropdown } from "../controls/dropdown";
|
||||
import { Airbase } from "../missionhandler/airbase";
|
||||
import { Unit } from "../units/unit";
|
||||
import { bearing } from "../other/utils";
|
||||
import { bearing, createCheckboxOption } from "../other/utils";
|
||||
import { DestinationPreviewMarker } from "./destinationpreviewmarker";
|
||||
import { TemporaryUnitMarker } from "./temporaryunitmarker";
|
||||
import { ClickableMiniMap } from "./clickableminimap";
|
||||
import { SVGInjector } from '@tanem/svg-injector'
|
||||
import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTootlips, FIRE_AT_AREA, MOVE_UNIT, CARPET_BOMBING, BOMBING } from "../constants/constants";
|
||||
import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTootlips, FIRE_AT_AREA, MOVE_UNIT, CARPET_BOMBING, BOMBING, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS } from "../constants/constants";
|
||||
import { TargetMarker } from "./targetmarker";
|
||||
import { CoalitionArea } from "./coalitionarea";
|
||||
import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu";
|
||||
import { DrawingCursor } from "./drawingcursor";
|
||||
import { aircraftDatabase } from "../units/aircraftdatabase";
|
||||
import { groundUnitDatabase } from "../units/groundunitdatabase";
|
||||
|
||||
L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect);
|
||||
|
||||
@ -47,7 +45,7 @@ export class Map extends L.Map {
|
||||
#temporaryMarkers: TemporaryUnitMarker[] = [];
|
||||
#selecting: boolean = false;
|
||||
#isZooming: boolean = false;
|
||||
|
||||
|
||||
#destinationGroupRotation: number = 0;
|
||||
#computeDestinationRotation: boolean = false;
|
||||
#destinationRotationCenter: L.LatLng | null = null;
|
||||
@ -63,7 +61,9 @@ export class Map extends L.Map {
|
||||
#coalitionAreaContextMenu: CoalitionAreaContextMenu = new CoalitionAreaContextMenu("coalition-area-contextmenu");
|
||||
|
||||
#mapSourceDropdown: Dropdown;
|
||||
#mapVisibilityOptionsDropdown: Dropdown;
|
||||
#optionButtons: { [key: string]: HTMLButtonElement[] } = {}
|
||||
#visibiityOptions: { [key: string]: boolean } = {}
|
||||
|
||||
constructor(ID: string) {
|
||||
/* Init the leaflet map */
|
||||
@ -86,7 +86,10 @@ export class Map extends L.Map {
|
||||
L.control.scalenautic({ position: "topright", maxWidth: 300, nautic: true, metric: true, imperial: false }).addTo(this);
|
||||
|
||||
/* Map source dropdown */
|
||||
this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName), this.getLayers())
|
||||
this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName), this.getLayers());
|
||||
|
||||
/* Visibility options dropdown */
|
||||
this.#mapVisibilityOptionsDropdown = new Dropdown("map-visibility-options", () => {});
|
||||
|
||||
/* Init the state machine */
|
||||
this.#state = IDLE;
|
||||
@ -123,9 +126,7 @@ export class Map extends L.Map {
|
||||
|
||||
|
||||
document.addEventListener("toggleCoalitionAreaDraw", (ev: CustomEventInit) => {
|
||||
const el = ev.detail._element;
|
||||
/* Add listener to set the button to off if the state changes */
|
||||
document.addEventListener("mapStateChanged", () => el?.classList.toggle("off", !(this.getState() === COALITIONAREA_DRAW_POLYGON)));
|
||||
this.getMapContextMenu().hide();
|
||||
this.deselectAllCoalitionAreas();
|
||||
if (ev.detail?.type == "polygon") {
|
||||
if (this.getState() !== COALITIONAREA_DRAW_POLYGON)
|
||||
@ -152,6 +153,18 @@ export class Map extends L.Map {
|
||||
return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, visibilityControlsTootlips[index], "toggleUnitVisibility", `{"type": "${option}"}`);
|
||||
});
|
||||
document.querySelector("#unit-visibility-control")?.append(...this.#optionButtons["visibility"]);
|
||||
|
||||
/* Create the checkboxes to select the advanced visibility options */
|
||||
|
||||
this.#visibiityOptions[SHOW_CONTACT_LINES] = false;
|
||||
this.#visibiityOptions[HIDE_GROUP_MEMBERS] = true;
|
||||
this.#visibiityOptions[SHOW_UNIT_PATHS] = true;
|
||||
this.#visibiityOptions[SHOW_UNIT_TARGETS] = true;
|
||||
this.#mapVisibilityOptionsDropdown.setOptionsElements(Object.keys(this.#visibiityOptions).map((option: string) => {
|
||||
return createCheckboxOption(option, option, this.#visibiityOptions[option], (ev: any) => {
|
||||
this.#setVisibilityOption(option, ev);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
setLayer(layerName: string) {
|
||||
@ -410,6 +423,10 @@ export class Map extends L.Map {
|
||||
this.#coalitionAreas.unshift(coalitionArea);
|
||||
}
|
||||
|
||||
getVisibilityOptions() {
|
||||
return this.#visibiityOptions;
|
||||
}
|
||||
|
||||
/* Event handlers */
|
||||
#onClick(e: any) {
|
||||
if (!this.#preventLeftClick) {
|
||||
@ -694,5 +711,10 @@ export class Map extends L.Map {
|
||||
else if (this.#state === COALITIONAREA_DRAW_POLYGON) this.#showDrawingCursor();
|
||||
}
|
||||
}
|
||||
|
||||
#setVisibilityOption(option: string, ev: any) {
|
||||
this.#visibiityOptions[option] = ev.currentTarget.checked;
|
||||
document.dispatchEvent(new CustomEvent("mapVisibilityOptionsChanged"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -119,10 +119,7 @@ export class MissionHandler {
|
||||
return 0;
|
||||
}
|
||||
|
||||
refreshSpawnPoints() {
|
||||
if (getUnitsManager().getCommandMode() === GAME_MASTER)
|
||||
document.querySelector("#spawn-points-container")?.classList.add("hide");
|
||||
|
||||
refreshSpawnPoints() {
|
||||
var spawnPointsEl = document.querySelector("#spawn-points");
|
||||
if (spawnPointsEl) {
|
||||
spawnPointsEl.textContent = `${this.getAvailableSpawnPoints()}`;
|
||||
@ -193,6 +190,9 @@ export class MissionHandler {
|
||||
el.textContent = RTSOptions.commandMode.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector("#spawn-points-container")?.classList.toggle("hide", getUnitsManager().getCommandMode() === GAME_MASTER);
|
||||
document.querySelector("#rts-settings-button")?.classList.toggle("hide", getUnitsManager().getCommandMode() !== GAME_MASTER);
|
||||
}
|
||||
|
||||
#onAirbaseClick(e: any) {
|
||||
|
||||
@ -366,7 +366,7 @@ export function convertDateAndTimeToDate(dateAndTime: DateAndTime) {
|
||||
return new Date(year, month, date.Day, time.h, time.m, time.s);
|
||||
}
|
||||
|
||||
export function createCheckboxOption(value: string, text: string, checked: boolean = true) {
|
||||
export function createCheckboxOption(value: string, text: string, checked: boolean = true, callback: CallableFunction = (ev: any) => {}) {
|
||||
var div = document.createElement("div");
|
||||
div.classList.add("ol-checkbox");
|
||||
var label = document.createElement("label");
|
||||
@ -379,6 +379,7 @@ export function createCheckboxOption(value: string, text: string, checked: boole
|
||||
label.appendChild(input);
|
||||
label.appendChild(span);
|
||||
div.appendChild(label);
|
||||
input.onclick = (ev: any) => callback(ev);
|
||||
return div as HTMLElement;
|
||||
}
|
||||
|
||||
|
||||
@ -1,28 +1,65 @@
|
||||
import { Panel } from "./panel";
|
||||
|
||||
export class LogPanel extends Panel
|
||||
{
|
||||
#logs: String[];
|
||||
export class LogPanel extends Panel {
|
||||
#open: boolean = false;
|
||||
#queuedMessages: number = 0;
|
||||
#scrolledDown: boolean = true;
|
||||
|
||||
constructor(ID: string)
|
||||
{
|
||||
constructor(ID: string) {
|
||||
super(ID);
|
||||
this.#logs = [];
|
||||
|
||||
document.addEventListener("toggleLogPanel", () => {
|
||||
this.getElement().classList.toggle("open");
|
||||
this.#open = !this.#open;
|
||||
this.#queuedMessages = 0;
|
||||
this.#updateHeader();
|
||||
|
||||
if (this.#scrolledDown)
|
||||
this.#scrollDown();
|
||||
});
|
||||
|
||||
const scrollEl = this.getElement().querySelector(".ol-scrollable");
|
||||
if (scrollEl) {
|
||||
scrollEl.addEventListener("scroll", () => {
|
||||
this.#scrolledDown = Math.abs(scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight) < 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
update(data: any)
|
||||
{
|
||||
var logs = data["logs"];
|
||||
for (let idx in logs)
|
||||
{
|
||||
if (parseInt(idx) >= this.#logs.length) {
|
||||
this.#logs.push(logs[idx]);
|
||||
var el = document.createElement("div");
|
||||
el.innerText = logs[idx];
|
||||
el.classList.add("js-log-element", "ol-log-element");
|
||||
this.getElement().appendChild(el);
|
||||
this.getElement().scrollTop = this.getElement().scrollHeight;
|
||||
}
|
||||
appendLogs(logs: string[]) {
|
||||
logs.forEach((log: string) => this.appendLog(log));
|
||||
}
|
||||
|
||||
appendLog(log: string) {
|
||||
var el = document.createElement("div");
|
||||
el.classList.add("ol-log-entry");
|
||||
el.textContent = log;
|
||||
this.getElement().querySelector(".ol-scrollable")?.appendChild(el);
|
||||
console.log(log);
|
||||
|
||||
if (!this.#open)
|
||||
this.#queuedMessages++;
|
||||
|
||||
this.#updateHeader();
|
||||
|
||||
if (this.#scrolledDown)
|
||||
this.#scrollDown();
|
||||
}
|
||||
|
||||
#updateHeader() {
|
||||
const headerEl = this.getElement().querySelector("#log-panel-header") as HTMLElement;
|
||||
if (headerEl) {
|
||||
if (this.#queuedMessages)
|
||||
headerEl.innerText = `Server log (${this.#queuedMessages})`;
|
||||
else
|
||||
headerEl.innerText = `Server log`;
|
||||
}
|
||||
}
|
||||
|
||||
#scrollDown() {
|
||||
const scrollEl = this.getElement().querySelector(".ol-scrollable");
|
||||
if (scrollEl) {
|
||||
scrollEl.scrollTop = scrollEl.scrollHeight - scrollEl.clientHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { LatLng } from 'leaflet';
|
||||
import { getConnectionStatusPanel, getInfoPopup, getMissionHandler, getServerStatusPanel, getUnitDataTable, getUnitsManager, setLoginStatus } from '..';
|
||||
import { getConnectionStatusPanel, getInfoPopup, getLogPanel, getMissionHandler, getServerStatusPanel, getUnitDataTable, getUnitsManager, setLoginStatus } from '..';
|
||||
import { GeneralSettings, Radio, TACAN } from '../@types/unit';
|
||||
import { ROEs, emissionsCountermeasures, reactionsToThreat } from '../constants/constants';
|
||||
|
||||
@ -338,18 +338,20 @@ export function startUpdate() {
|
||||
getAirbases((data: AirbasesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateAirbases(data);
|
||||
return data.time;
|
||||
});
|
||||
getBullseye((data: BullseyesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateBullseyes(data);
|
||||
return data.time;
|
||||
});
|
||||
getMission((data: MissionData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateMission(data);
|
||||
return data.time;
|
||||
});
|
||||
getLogs((data: any) => {
|
||||
for (let key in data.logs)
|
||||
console.log(data.logs[key]);
|
||||
getLogPanel().appendLogs(Object.values(data.logs))
|
||||
return data.time;
|
||||
});
|
||||
getUnits((buffer: ArrayBuffer) => {return getUnitsManager()?.update(buffer), true /* Does a full refresh */});
|
||||
@ -374,18 +376,20 @@ export function requestRefresh() {
|
||||
getAirbases((data: AirbasesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateAirbases(data);
|
||||
return data.time;
|
||||
});
|
||||
getBullseye((data: BullseyesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateBullseyes(data);
|
||||
return data.time;
|
||||
});
|
||||
getMission((data: MissionData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateMission(data);
|
||||
return data.time;
|
||||
});
|
||||
getLogs((data: any) => {
|
||||
for (let key in data.logs)
|
||||
console.log(data.logs[key]);
|
||||
getLogPanel().appendLogs(Object.values(data.logs))
|
||||
return data.time;
|
||||
});
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import { CustomMarker } from '../map/custommarker';
|
||||
import { SVGInjector } from '@tanem/svg-injector';
|
||||
import { UnitDatabase } from './unitdatabase';
|
||||
import { TargetMarker } from '../map/targetmarker';
|
||||
import { BOMBING, CARPET_BOMBING, DLINK, DataIndexes, FIRE_AT_AREA, GAME_MASTER, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants';
|
||||
import { BOMBING, CARPET_BOMBING, DLINK, DataIndexes, FIRE_AT_AREA, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_CONTACT_LINES, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants';
|
||||
import { Ammo, Contact, GeneralSettings, Offset, Radio, TACAN, UnitIconOptions } from '../@types/unit';
|
||||
import { DataExtractor } from './dataextractor';
|
||||
import { groundUnitDatabase } from './groundunitdatabase';
|
||||
@ -166,7 +166,13 @@ export class Unit extends CustomMarker {
|
||||
|
||||
document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => {
|
||||
window.setTimeout(() => { this.setSelected(this.getSelected() && !this.getHidden()) }, 300);
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("mapVisibilityOptionsChanged", (ev: CustomEventInit) => {
|
||||
this.#updateMarker();
|
||||
if (this.getSelected())
|
||||
this.drawLines();
|
||||
});
|
||||
}
|
||||
|
||||
getCategory() {
|
||||
@ -495,7 +501,7 @@ export class Unit extends CustomMarker {
|
||||
(hiddenUnits.includes(this.getMarkerCategory())) ||
|
||||
(hiddenUnits.includes(this.#coalition)) ||
|
||||
(!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0) ||
|
||||
(!this.#isLeader && this.getCategory() == "GroundUnit" && getMap().getZoom() < 13)) &&
|
||||
(getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && this.getCategory() == "GroundUnit" && getMap().getZoom() < 13)) &&
|
||||
!(this.getSelected());
|
||||
|
||||
this.setHidden(hidden || !this.#alive);
|
||||
@ -925,7 +931,7 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
#drawPath() {
|
||||
if (this.#activePath != undefined) {
|
||||
if (this.#activePath != undefined && getMap().getVisibilityOptions()[SHOW_UNIT_PATHS]) {
|
||||
var points = [];
|
||||
points.push(new LatLng(this.#position.lat, this.#position.lng));
|
||||
|
||||
@ -952,6 +958,9 @@ export class Unit extends CustomMarker {
|
||||
if (points.length == 1)
|
||||
this.#clearPath();
|
||||
}
|
||||
else {
|
||||
this.#clearPath();
|
||||
}
|
||||
}
|
||||
|
||||
#clearPath() {
|
||||
@ -964,34 +973,36 @@ export class Unit extends CustomMarker {
|
||||
|
||||
#drawContacts() {
|
||||
this.#clearContacts();
|
||||
for (let index in this.#contacts) {
|
||||
var contactData = this.#contacts[index];
|
||||
var contact = getUnitsManager().getUnitByID(contactData.ID)
|
||||
if (contact != null && contact.getAlive()) {
|
||||
var startLatLng = new LatLng(this.#position.lat, this.#position.lng);
|
||||
var endLatLng: LatLng;
|
||||
if (contactData.detectionMethod === RWR) {
|
||||
var bearingToContact = bearing(this.#position.lat, this.#position.lng, contact.#position.lat, contact.#position.lng);
|
||||
var startXY = getMap().latLngToContainerPoint(startLatLng);
|
||||
var endX = startXY.x + 80 * Math.sin(deg2rad(bearingToContact));
|
||||
var endY = startXY.y - 80 * Math.cos(deg2rad(bearingToContact));
|
||||
endLatLng = getMap().containerPointToLatLng(new Point(endX, endY));
|
||||
}
|
||||
else
|
||||
endLatLng = new LatLng(contact.#position.lat, contact.#position.lng);
|
||||
if (getMap().getVisibilityOptions()[SHOW_CONTACT_LINES]) {
|
||||
for (let index in this.#contacts) {
|
||||
var contactData = this.#contacts[index];
|
||||
var contact = getUnitsManager().getUnitByID(contactData.ID)
|
||||
if (contact != null && contact.getAlive()) {
|
||||
var startLatLng = new LatLng(this.#position.lat, this.#position.lng);
|
||||
var endLatLng: LatLng;
|
||||
if (contactData.detectionMethod === RWR) {
|
||||
var bearingToContact = bearing(this.#position.lat, this.#position.lng, contact.#position.lat, contact.#position.lng);
|
||||
var startXY = getMap().latLngToContainerPoint(startLatLng);
|
||||
var endX = startXY.x + 80 * Math.sin(deg2rad(bearingToContact));
|
||||
var endY = startXY.y - 80 * Math.cos(deg2rad(bearingToContact));
|
||||
endLatLng = getMap().containerPointToLatLng(new Point(endX, endY));
|
||||
}
|
||||
else
|
||||
endLatLng = new LatLng(contact.#position.lat, contact.#position.lng);
|
||||
|
||||
var color;
|
||||
if (contactData.detectionMethod === VISUAL || contactData.detectionMethod === OPTIC)
|
||||
color = "#FF00FF";
|
||||
else if (contactData.detectionMethod === RADAR || contactData.detectionMethod === IRST)
|
||||
color = "#FFFF00";
|
||||
else if (contactData.detectionMethod === RWR)
|
||||
color = "#00FF00";
|
||||
else
|
||||
color = "#FFFFFF";
|
||||
var contactPolyline = new Polyline([startLatLng, endLatLng], { color: color, weight: 3, opacity: 1, smoothFactor: 1, dashArray: "4, 8" });
|
||||
contactPolyline.addTo(getMap());
|
||||
this.#contactsPolylines.push(contactPolyline)
|
||||
var color;
|
||||
if (contactData.detectionMethod === VISUAL || contactData.detectionMethod === OPTIC)
|
||||
color = "#FF00FF";
|
||||
else if (contactData.detectionMethod === RADAR || contactData.detectionMethod === IRST)
|
||||
color = "#FFFF00";
|
||||
else if (contactData.detectionMethod === RWR)
|
||||
color = "#00FF00";
|
||||
else
|
||||
color = "#FFFFFF";
|
||||
var contactPolyline = new Polyline([startLatLng, endLatLng], { color: color, weight: 3, opacity: 1, smoothFactor: 1, dashArray: "4, 8" });
|
||||
contactPolyline.addTo(getMap());
|
||||
this.#contactsPolylines.push(contactPolyline)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1003,20 +1014,20 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
#drawTarget() {
|
||||
if (this.#targetPosition.lat != 0 && this.#targetPosition.lng != 0) {
|
||||
this.#drawtargetPosition(this.#targetPosition);
|
||||
if (this.#targetPosition.lat != 0 && this.#targetPosition.lng != 0 && getMap().getVisibilityOptions()[SHOW_UNIT_PATHS]) {
|
||||
this.#drawTargetPosition(this.#targetPosition);
|
||||
}
|
||||
else if (this.#targetID != 0) {
|
||||
else if (this.#targetID != 0 && getMap().getVisibilityOptions()[SHOW_UNIT_TARGETS]) {
|
||||
const target = getUnitsManager().getUnitByID(this.#targetID);
|
||||
if (target && (getUnitsManager().getCommandMode() == GAME_MASTER || (this.belongsToCommandedCoalition() && getUnitsManager().getUnitDetectedMethods(target).some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))))) {
|
||||
this.#drawtargetPosition(target.getPosition());
|
||||
this.#drawTargetPosition(target.getPosition());
|
||||
}
|
||||
}
|
||||
else
|
||||
this.#clearTarget();
|
||||
}
|
||||
|
||||
#drawtargetPosition(targetPosition: LatLng) {
|
||||
#drawTargetPosition(targetPosition: LatLng) {
|
||||
if (!getMap().hasLayer(this.#targetPositionMarker))
|
||||
this.#targetPositionMarker.addTo(getMap());
|
||||
if (!getMap().hasLayer(this.#targetPositionPolyline))
|
||||
|
||||
@ -36,7 +36,6 @@ export class UnitDatabase {
|
||||
var filteredBlueprints: { [key: string]: UnitBlueprint } = {};
|
||||
for (let unit in this.blueprints) {
|
||||
const blueprint = this.blueprints[unit];
|
||||
console.log(blueprint.era)
|
||||
if (this.getSpawnPointsByName(blueprint.name) < getMissionHandler().getAvailableSpawnPoints() &&
|
||||
getMissionHandler().getRTSOptions().eras.includes(blueprint.era) &&
|
||||
(!getMissionHandler().getRTSOptions().restrictToCoalition || blueprint.coalition === getUnitsManager().getCommandedCoalition())) {
|
||||
|
||||
@ -701,21 +701,21 @@ export class UnitsManager {
|
||||
getInfoPopup().setText("Helicopters can be air spawned during the SETUP phase only");
|
||||
return false;
|
||||
}
|
||||
spawnPoints = units.reduce((unit: any, points: number) => {return points + helicopterDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnPoints = units.reduce((points: number, unit: any) => {return points + helicopterDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnHelicopters(units, coalition, airbase, immediate, spawnPoints);
|
||||
} else if (category === "GroundUnit") {
|
||||
if (getMissionHandler().getRemainingSetupTime() < 0 && this.getCommandMode() !== GAME_MASTER) {
|
||||
getInfoPopup().setText("Ground units can be spawned during the SETUP phase only");
|
||||
return false;
|
||||
}
|
||||
spawnPoints = units.reduce((unit: any, points: number) => {return points + groundUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnPoints = units.reduce((points: number, unit: any) => {return points + groundUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnGroundUnits(units, coalition, immediate, spawnPoints);
|
||||
} else if (category === "NavyUnit") {
|
||||
if (getMissionHandler().getRemainingSetupTime() < 0 && this.getCommandMode() !== GAME_MASTER) {
|
||||
getInfoPopup().setText("Navy units can be spawned during the SETUP phase only");
|
||||
return false;
|
||||
}
|
||||
spawnPoints = units.reduce((unit: any, points: number) => {return points + navyUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnPoints = units.reduce((points: number, unit: any) => {return points + navyUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnNavyUnits(units, coalition, immediate, spawnPoints);
|
||||
}
|
||||
if (spawnPoints <= getMissionHandler().getAvailableSpawnPoints()) {
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
<%- include('panels/connectionstatus.ejs') %>
|
||||
<%- include('panels/serverstatus.ejs') %>
|
||||
<%- include('panels/hotgroup.ejs') %>
|
||||
<%- include('panels/logpanel.ejs') %>
|
||||
|
||||
<div id="toolbar-container">
|
||||
<%- include('toolbars/primary.ejs') %>
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
<div id="log-panel" class="ol-panel">
|
||||
<!-- Log entries go here -->
|
||||
</div>
|
||||
@ -15,15 +15,15 @@
|
||||
</div>
|
||||
<div id="more-options-button-bar" class="upper-bar ol-panel hide">
|
||||
<div id="coalition-switch" class="ol-switch ol-coalition-switch"></div>
|
||||
|
||||
<button data-coalition="blue" id="navyunit-spawn-button" title="Spawn navy unit" data-on-click="mapContextMenuShow"
|
||||
data-on-click-params='{ "type": "navyunit" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/navyunit.svg" inject-svg></button>
|
||||
|
||||
<button data-coalition="blue" id="smoke-spawn-button" title="Spawn smoke" data-on-click="mapContextMenuShow"
|
||||
data-on-click-params='{ "type": "smoke" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/smoke.svg" inject-svg></button>
|
||||
<button data-coalition="blue" id="explosion-spawn-button" title="Explosion" data-on-click="mapContextMenuShow"
|
||||
data-on-click-params='{ "type": "explosion" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/explosion.svg" inject-svg></button>
|
||||
</div>
|
||||
<button data-coalition="blue" id="polygon-draw-button" title="Enter polygon draw mode" data-on-click="toggleCoalitionAreaDraw"
|
||||
data-on-click-params='{"type": "polygon"}' class="ol-contexmenu-button"><img src="resources/theme/images/buttons/tools/draw-polygon-solid.svg" inject-svg></button>
|
||||
</div>
|
||||
<div id="aircraft-spawn-menu" class="ol-contexmenu-panel ol-panel hide">
|
||||
<div class="ol-select-container">
|
||||
<div id="aircraft-role-options" class="ol-select">
|
||||
|
||||
5
client/views/panels/logpanel.ejs
Normal file
5
client/views/panels/logpanel.ejs
Normal file
@ -0,0 +1,5 @@
|
||||
<div id="log-panel" oncontextmenu="return false;">
|
||||
<div class="ol-panel" data-on-click="toggleLogPanel"><div id="log-panel-header">Server log</div><img src="/resources/theme/images/icons/chevron-down.svg" inject-svg></div>
|
||||
<div class="ol-panel ol-scrollable closed">
|
||||
</div>
|
||||
</div>
|
||||
@ -26,12 +26,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="map-type" class="ol-select">
|
||||
<div class="ol-select-value map-source-dropdown">
|
||||
<span>ArcGIS Satellite</span>
|
||||
<div class="ol-group">
|
||||
<div id="map-type" class="ol-select">
|
||||
<div class="ol-select-value">
|
||||
<img src="resources/theme/images/icons/map-source.svg" inject-svg> ArcGIS Satellite
|
||||
</div>
|
||||
<div class="ol-select-options">
|
||||
<!-- Here the available map sources will be listed-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ol-select-options">
|
||||
<!-- Here the available map sources will be listed-->
|
||||
|
||||
<div id="map-visibility-options" class="ol-select">
|
||||
<div class="ol-select-value"><img src="resources/theme/images/icons/eye-solid.svg" inject-svg>Options</div>
|
||||
<div class="ol-select-options">
|
||||
<!-- This is where the advanced visibility options will be listed -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -56,6 +65,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div id="atc-navbar-control" class="ol-group-container ol-navbar-buttons-group" data-feature-switch="atc">
|
||||
<div class="ol-group">
|
||||
<button data-on-click="toggleElements"
|
||||
@ -63,13 +73,5 @@
|
||||
<button data-on-click="toggleElements"
|
||||
data-on-click-params='{"selector": "#strip-board-tower"}' class="off"><img src="resources/theme/images/buttons/tools/tower.svg" inject-svg></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="map-tools" class="ol-group-container ol-navbar-buttons-group">
|
||||
<div class="ol-group">
|
||||
<button title="Draw Coalition Areas on the map" data-on-click="toggleCoalitionAreaDraw" data-on-click-params='{"type": "polygon"}' class="off">
|
||||
<img src="resources/theme/images/buttons/tools/draw-polygon-solid.svg" inject-svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</nav>
|
||||
@ -2,5 +2,5 @@
|
||||
<span id="command-mode"></span>
|
||||
<div id="spawn-points-container">Spawn points<span id="spawn-points"></span></div>
|
||||
<span id="rts-phase"></span>
|
||||
<button class="ol-button" data-on-click="showRTSSettingsDialog"><img src="/resources/theme/images/icons/gears-solid.svg" inject-svg>Settings</button>
|
||||
<button id="rts-settings-button" class="ol-button" data-on-click="showRTSSettingsDialog"><img src="/resources/theme/images/icons/gears-solid.svg" inject-svg>Settings</button>
|
||||
</nav>
|
||||
Loading…
x
Reference in New Issue
Block a user