Completed hotgroups

Single hotgroup per unit
This commit is contained in:
Pax1601
2023-05-17 11:43:14 +02:00
parent 493c75b6e7
commit 25d411b1be
8 changed files with 146 additions and 121 deletions

View File

@@ -99,7 +99,7 @@
width: var(--unit-aircraft-marker-width); width: var(--unit-aircraft-marker-width);
} }
[data-object|="unit-aircraft"]:hover .unit-marker { [data-object|="unit-aircraft"][data-is-highlighted] .unit-marker {
background-image: var(--unit-aircraft-marker-neutral-hover-url); background-image: var(--unit-aircraft-marker-neutral-hover-url);
} }
@@ -111,7 +111,7 @@
background-image: var(--unit-aircraft-marker-blue-url); background-image: var(--unit-aircraft-marker-blue-url);
} }
[data-object|="unit-aircraft"][data-coalition="blue"]:hover .unit-marker { [data-object|="unit-aircraft"][data-coalition="blue"][data-is-highlighted] .unit-marker {
background-image: var(--unit-aircraft-marker-blue-hover-url); background-image: var(--unit-aircraft-marker-blue-hover-url);
} }
@@ -124,7 +124,7 @@
background-image: var(--unit-aircraft-marker-red-url); background-image: var(--unit-aircraft-marker-red-url);
} }
[data-object|="unit-aircraft"][data-coalition="red"]:hover .unit-marker { [data-object|="unit-aircraft"][data-coalition="red"][data-is-highlighted] .unit-marker {
background-image: var(--unit-aircraft-marker-red-hover-url); background-image: var(--unit-aircraft-marker-red-hover-url);
} }
@@ -140,7 +140,7 @@
width: var(--unit-groundunit-marker-width); width: var(--unit-groundunit-marker-width);
} }
[data-object|="unit-groundunit"]:hover .unit-marker { [data-object|="unit-groundunit"][data-is-highlighted] .unit-marker {
background-image: var(--unit-groundunit-marker-neutral-hover-url); background-image: var(--unit-groundunit-marker-neutral-hover-url);
} }
@@ -153,7 +153,7 @@
background-image: var(--unit-groundunit-marker-blue-url); background-image: var(--unit-groundunit-marker-blue-url);
} }
[data-object|="unit-groundunit"][data-coalition="blue"]:hover .unit-marker { [data-object|="unit-groundunit"][data-coalition="blue"][data-is-highlighted] .unit-marker {
background-image: var(--unit-groundunit-marker-blue-hover-url); background-image: var(--unit-groundunit-marker-blue-hover-url);
} }
@@ -166,7 +166,7 @@
background-image: var(--unit-groundunit-marker-red-url); background-image: var(--unit-groundunit-marker-red-url);
} }
[data-object|="unit-groundunit"][data-coalition="red"]:hover .unit-marker { [data-object|="unit-groundunit"][data-coalition="red"][data-is-highlighted] .unit-marker {
background-image: var(--unit-groundunit-marker-red-hover-url); background-image: var(--unit-groundunit-marker-red-hover-url);
} }
@@ -188,7 +188,7 @@
} }
[data-object|="unit-sam"]:hover .unit-marker { [data-object|="unit-sam"][data-is-highlighted] .unit-marker {
background-image: var(--unit-sam-marker-neutral-hover-url); background-image: var(--unit-sam-marker-neutral-hover-url);
} }
@@ -201,7 +201,7 @@
background-image: var(--unit-sam-marker-blue-url); background-image: var(--unit-sam-marker-blue-url);
} }
[data-object|="unit-sam"][data-coalition="blue"]:hover .unit-marker { [data-object|="unit-sam"][data-coalition="blue"][data-is-highlighted] .unit-marker {
background-image: var(--unit-sam-marker-blue-hover-url); background-image: var(--unit-sam-marker-blue-hover-url);
} }
@@ -214,7 +214,7 @@
background-image: var(--unit-sam-marker-red-url); background-image: var(--unit-sam-marker-red-url);
} }
[data-object|="unit-sam"][data-coalition="red"]:hover .unit-marker { [data-object|="unit-sam"][data-coalition="red"][data-is-highlighted] .unit-marker {
background-image: var(--unit-sam-marker-red-hover-url); background-image: var(--unit-sam-marker-red-hover-url);
} }
@@ -236,7 +236,7 @@
} }
[data-object|="unit-navyunit"]:hover .unit-marker { [data-object|="unit-navyunit"][data-is-highlighted] .unit-marker {
background-image: var(--unit-navyunit-marker-neutral-hover-url); background-image: var(--unit-navyunit-marker-neutral-hover-url);
} }
@@ -249,7 +249,7 @@
background-image: var(--unit-navyunit-marker-blue-url); background-image: var(--unit-navyunit-marker-blue-url);
} }
[data-object|="unit-navyunit"][data-coalition="blue"]:hover .unit-marker { [data-object|="unit-navyunit"][data-coalition="blue"][data-is-highlighted] .unit-marker {
background-image: var(--unit-navyunit-marker-blue-hover-url); background-image: var(--unit-navyunit-marker-blue-hover-url);
} }
@@ -262,7 +262,7 @@
background-image: var(--unit-navyunit-marker-red-url); background-image: var(--unit-navyunit-marker-red-url);
} }
[data-object|="unit-navyunit"][data-coalition="red"]:hover .unit-marker { [data-object|="unit-navyunit"][data-coalition="red"][data-is-highlighted] .unit-marker {
background-image: var(--unit-navyunit-marker-red-hover-url); background-image: var(--unit-navyunit-marker-red-hover-url);
} }

View File

@@ -5,7 +5,8 @@ interface CustomEventMap {
"unitsDeselection": CustomEvent<Unit[]>, "unitsDeselection": CustomEvent<Unit[]>,
"clearSelection": CustomEvent<>, "clearSelection": CustomEvent<>,
"unitCreation": CustomEvent<Unit>, "unitCreation": CustomEvent<Unit>,
"unitDeletion": CustomEvent<Unit>, "unitDeletion": CustomEvent<Unit>,
"unitDeath": CustomEvent<Unit>,
"unitUpdated": CustomEvent<Unit>, "unitUpdated": CustomEvent<Unit>,
"unitMoveCommand": CustomEvent<Unit>, "unitMoveCommand": CustomEvent<Unit>,
"unitAttackCommand": CustomEvent<Unit>, "unitAttackCommand": CustomEvent<Unit>,

View File

@@ -9,7 +9,7 @@ import { AIC } from "./aic/aic";
import { ATC } from "./atc/atc"; import { ATC } from "./atc/atc";
import { FeatureSwitches } from "./featureswitches"; import { FeatureSwitches } from "./featureswitches";
import { LogPanel } from "./panels/logpanel"; import { LogPanel } from "./panels/logpanel";
import { getConfig, getFreezed, setAddress, setCredentials, setFreezed, startUpdate, toggleDemoEnabled } from "./server/server"; import { getConfig, getPaused, setAddress, setCredentials, setPaused, startUpdate, toggleDemoEnabled } from "./server/server";
import { UnitDataTable } from "./units/unitdatatable"; import { UnitDataTable } from "./units/unitdatatable";
import { keyEventWasInInput } from "./other/utils"; import { keyEventWasInInput } from "./other/utils";
import { Popup } from "./popups/popup"; import { Popup } from "./popups/popup";
@@ -138,7 +138,7 @@ function setupEvents() {
unitDataTable.toggle(); unitDataTable.toggle();
break break
case "Space": case "Space":
setFreezed(!getFreezed()); setPaused(!getPaused());
break; break;
case "KeyW": case "KeyW":
case "KeyA": case "KeyA":
@@ -159,10 +159,13 @@ function setupEvents() {
case "Digit7": case "Digit7":
case "Digit8": case "Digit8":
case "Digit9": case "Digit9":
if (ev.ctrlKey) // Using the substring because the key will be invalid when pressing the Shift key
getUnitsManager().selectedUnitsAddToHotgroup(parseInt(ev.key)); if (ev.ctrlKey && ev.shiftKey)
getUnitsManager().selectedUnitsAddToHotgroup(parseInt(ev.code.substring(5)));
else if (ev.ctrlKey && !ev.shiftKey)
getUnitsManager().selectedUnitsSetHotgroup(parseInt(ev.code.substring(5)));
else else
getUnitsManager().selectUnitsByHotgroup(parseInt(ev.key)); getUnitsManager().selectUnitsByHotgroup(parseInt(ev.code.substring(5)));
break; break;
} }
}); });

View File

@@ -1,9 +1,23 @@
import { getUnitsManager } from ".."; import { getUnitsManager } from "..";
import { Unit } from "../units/unit";
import { Panel } from "./panel"; import { Panel } from "./panel";
export class HotgroupPanel extends Panel { export class HotgroupPanel extends Panel {
constructor(ID: string) {
super(ID);
document.addEventListener("unitDeath", () => this.refreshHotgroups());
}
refreshHotgroups() {
for (let hotgroup = 1; hotgroup <= 9; hotgroup++){
this.removeHotgroup(hotgroup);
if (getUnitsManager().getUnitsByHotgroup(hotgroup).length > 0)
this.addHotgroup(hotgroup);
}
}
addHotgroup(hotgroup: number) { addHotgroup(hotgroup: number) {
this.removeHotgroup(hotgroup);
const hotgroupHtml = `<div class="unit-hotgroup"> const hotgroupHtml = `<div class="unit-hotgroup">
<div class="unit-hotgroup-id">${hotgroup}</div> <div class="unit-hotgroup-id">${hotgroup}</div>
</div> </div>
@@ -13,9 +27,18 @@ export class HotgroupPanel extends Panel {
el.innerHTML = hotgroupHtml; el.innerHTML = hotgroupHtml;
el.toggleAttribute(`data-hotgroup-${hotgroup}`, true) el.toggleAttribute(`data-hotgroup-${hotgroup}`, true)
this.getElement().appendChild(el); this.getElement().appendChild(el);
el.addEventListener("click", () => { el.addEventListener("click", () => {
getUnitsManager().selectUnitsByHotgroup(hotgroup); getUnitsManager().selectUnitsByHotgroup(hotgroup);
}); });
el.addEventListener("mouseover", () => {
getUnitsManager().getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHighlighted(true));
});
el.addEventListener("mouseout", () => {
getUnitsManager().getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHighlighted(false));
});
} }
removeHotgroup(hotgroup: number) { removeHotgroup(hotgroup: number) {

View File

@@ -3,7 +3,7 @@ import { getConnectionStatusPanel, getInfoPopup, getMissionData, getUnitDataTabl
import { SpawnOptions } from '../controls/mapcontextmenu'; import { SpawnOptions } from '../controls/mapcontextmenu';
var connected: boolean = false; var connected: boolean = false;
var freezed: boolean = false; var paused: boolean = false;
var REST_ADDRESS = "http://localhost:30000/olympus"; var REST_ADDRESS = "http://localhost:30000/olympus";
var DEMO_ADDRESS = window.location.href + "demo"; var DEMO_ADDRESS = window.location.href + "demo";
@@ -246,7 +246,7 @@ export function startUpdate() {
export function requestUpdate() { export function requestUpdate() {
/* Main update rate = 250ms is minimum time, equal to server update time. */ /* Main update rate = 250ms is minimum time, equal to server update time. */
getUnits((data: UnitsData) => { getUnits((data: UnitsData) => {
if (!getFreezed()) { if (!getPaused()) {
getUnitsManager()?.update(data); getUnitsManager()?.update(data);
checkSessionHash(data.sessionHash); checkSessionHash(data.sessionHash);
} }
@@ -259,7 +259,7 @@ export function requestUpdate() {
export function requestRefresh() { export function requestRefresh() {
/* Main refresh rate = 5000ms. */ /* Main refresh rate = 5000ms. */
getUnits((data: UnitsData) => { getUnits((data: UnitsData) => {
if (!getFreezed()) { if (!getPaused()) {
getUnitsManager()?.update(data); getUnitsManager()?.update(data);
getAirbases((data: AirbasesData) => getMissionData()?.update(data)); getAirbases((data: AirbasesData) => getMissionData()?.update(data));
getBullseye((data: BullseyesData) => getMissionData()?.update(data)); getBullseye((data: BullseyesData) => getMissionData()?.update(data));
@@ -300,11 +300,11 @@ export function getConnected() {
return connected; return connected;
} }
export function setFreezed(newFreezed: boolean) { export function setPaused(newPaused: boolean) {
freezed = newFreezed; paused = newPaused;
freezed ? getInfoPopup().setText("Freezed") : getInfoPopup().setText("Unfreezed"); paused ? getInfoPopup().setText("View paused") : getInfoPopup().setText("View unpaused");
} }
export function getFreezed() { export function getPaused() {
return freezed; return paused;
} }

View File

@@ -65,8 +65,8 @@ export class Unit extends Marker {
#selectable: boolean; #selectable: boolean;
#selected: boolean = false; #selected: boolean = false;
#hovered: boolean = false;
#hidden: boolean = false; #hidden: boolean = false;
#highlighted: boolean = false;
#preventClick: boolean = false; #preventClick: boolean = false;
@@ -94,24 +94,24 @@ export class Unit extends Marker {
this.ID = ID; this.ID = ID;
this.#selectable = true; this.#selectable = true;
this.on('click', (e) => this.#onClick(e)); this.on('click', (e) => this.#onClick(e));
this.on('dblclick', (e) => this.#onDoubleClick(e)); this.on('dblclick', (e) => this.#onDoubleClick(e));
this.on('contextmenu', (e) => this.#onContextMenu(e)); this.on('contextmenu', (e) => this.#onContextMenu(e));
this.on('mouseover', () => { this.#hovered = true;}) this.on('mouseover', () => { this.setHighlighted(true); })
this.on('mouseout', () => { this.#hovered = false;}) this.on('mouseout', () => { this.setHighlighted(false); })
this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 }); this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 });
this.#pathPolyline.addTo(getMap()); this.#pathPolyline.addTo(getMap());
this.#targetsPolylines = []; this.#targetsPolylines = [];
/* Deselect units if they are hidden */ /* Deselect units if they are hidden */
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => { document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
window.setTimeout(() => {this.setSelected(this.getSelected() && !this.getHidden())}, 300); window.setTimeout(() => { this.setSelected(this.getSelected() && !this.getHidden()) }, 300);
}); });
document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => { document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => {
window.setTimeout(() => {this.setSelected(this.getSelected() && !this.getHidden())}, 300); window.setTimeout(() => { this.setSelected(this.getSelected() && !this.getHidden()) }, 300);
}); });
/* Set the unit data */ /* Set the unit data */
@@ -128,15 +128,14 @@ export class Unit extends Marker {
} }
getMarkerHTML() { getMarkerHTML() {
return `<div class="unit" data-object="unit-${this.getMarkerCategory()}" data-coalition="${this.getMissionData().coalition}"> return `<div class="unit" data-object="unit-${this.getMarkerCategory()}" data-coalition="${this.getMissionData().coalition}">
<div class="unit-selected-spotlight"></div> <div class="unit-selected-spotlight"></div>
<div class="unit-marker"></div> <div class="unit-marker"></div>
<div class="unit-short-label"></div> <div class="unit-short-label"></div>
</div>` </div>`
} }
getMarkerCategory() getMarkerCategory() {
{
// Overloaded by child classes // Overloaded by child classes
return ""; return "";
} }
@@ -146,58 +145,56 @@ export class Unit extends Marker {
setData(data: UpdateData) { setData(data: UpdateData) {
/* Check if data has changed comparing new values to old values */ /* Check if data has changed comparing new values to old values */
const positionChanged = (data.flightData != undefined && data.flightData.latitude != undefined && data.flightData.longitude != undefined && (this.getFlightData().latitude != data.flightData.latitude || this.getFlightData().longitude != data.flightData.longitude)); const positionChanged = (data.flightData != undefined && data.flightData.latitude != undefined && data.flightData.longitude != undefined && (this.getFlightData().latitude != data.flightData.latitude || this.getFlightData().longitude != data.flightData.longitude));
const headingChanged = (data.flightData != undefined && data.flightData.heading != undefined && this.getFlightData().heading != data.flightData.heading); const headingChanged = (data.flightData != undefined && data.flightData.heading != undefined && this.getFlightData().heading != data.flightData.heading);
const aliveChanged = (data.baseData != undefined && data.baseData.alive != undefined && this.getBaseData().alive != data.baseData.alive); const aliveChanged = (data.baseData != undefined && data.baseData.alive != undefined && this.getBaseData().alive != data.baseData.alive);
var updateMarker = (positionChanged || headingChanged || aliveChanged || !getMap().hasLayer(this)) var updateMarker = (positionChanged || headingChanged || aliveChanged || !getMap().hasLayer(this));
if (data.baseData != undefined) if (data.baseData != undefined) {
{
for (let key in this.#data.baseData) for (let key in this.#data.baseData)
if (key in data.baseData) if (key in data.baseData)
//@ts-ignore //@ts-ignore
this.#data.baseData[key] = data.baseData[key]; this.#data.baseData[key] = data.baseData[key];
} }
if (data.flightData != undefined) if (data.flightData != undefined) {
{
for (let key in this.#data.flightData) for (let key in this.#data.flightData)
if (key in data.flightData) if (key in data.flightData)
//@ts-ignore //@ts-ignore
this.#data.flightData[key] = data.flightData[key]; this.#data.flightData[key] = data.flightData[key];
} }
if (data.missionData != undefined) if (data.missionData != undefined) {
{
for (let key in this.#data.missionData) for (let key in this.#data.missionData)
if (key in data.missionData) if (key in data.missionData)
//@ts-ignore //@ts-ignore
this.#data.missionData[key] = data.missionData[key]; this.#data.missionData[key] = data.missionData[key];
} }
if (data.formationData != undefined) if (data.formationData != undefined) {
{
for (let key in this.#data.formationData) for (let key in this.#data.formationData)
if (key in data.formationData) if (key in data.formationData)
//@ts-ignore //@ts-ignore
this.#data.formationData[key] = data.formationData[key]; this.#data.formationData[key] = data.formationData[key];
} }
if (data.taskData != undefined) if (data.taskData != undefined) {
{
for (let key in this.#data.taskData) for (let key in this.#data.taskData)
if (key in data.taskData) if (key in data.taskData)
//@ts-ignore //@ts-ignore
this.#data.taskData[key] = data.taskData[key]; this.#data.taskData[key] = data.taskData[key];
} }
if (data.optionsData != undefined) if (data.optionsData != undefined) {
{
for (let key in this.#data.optionsData) for (let key in this.#data.optionsData)
if (key in data.optionsData) if (key in data.optionsData)
//@ts-ignore //@ts-ignore
this.#data.optionsData[key] = data.optionsData[key]; this.#data.optionsData[key] = data.optionsData[key];
} }
/* Fire an event when a unit dies */
if (aliveChanged && this.getBaseData().alive == false)
document.dispatchEvent(new CustomEvent("unitDeath", { detail: this }));
/* Dead units can't be selected */ /* Dead units can't be selected */
this.setSelected(this.getSelected() && this.getBaseData().alive && !this.getHidden()) this.setSelected(this.getSelected() && this.getBaseData().alive && !this.getHidden())
@@ -275,17 +272,24 @@ export class Unit extends Marker {
return this.#hotgroup; return this.#hotgroup;
} }
/********************** Visibility *************************/ setHighlighted(highlighted: boolean) {
updateVisibility() this.getElement()?.querySelector(`[data-object|="unit"]`)?.toggleAttribute("data-is-highlighted", highlighted);
{ this.#highlighted = highlighted;
this.setHidden( document.body.getAttribute(`data-hide-${this.getMissionData().coalition}`) != null ||
document.body.getAttribute(`data-hide-${this.getMarkerCategory()}`) != null ||
!this.getBaseData().alive)
} }
setHidden(hidden: boolean) getHighlighted() {
{ return this.#highlighted;
this.#hidden = hidden; }
/********************** Visibility *************************/
updateVisibility() {
this.setHidden(document.body.getAttribute(`data-hide-${this.getMissionData().coalition}`) != null ||
document.body.getAttribute(`data-hide-${this.getMarkerCategory()}`) != null ||
!this.getBaseData().alive)
}
setHidden(hidden: boolean) {
this.#hidden = hidden;
/* Add the marker if not present */ /* Add the marker if not present */
if (!getMap().hasLayer(this) && !this.getHidden()) { if (!getMap().hasLayer(this) && !this.getHidden()) {
@@ -295,7 +299,7 @@ export class Unit extends Marker {
/* Hide the marker if necessary*/ /* Hide the marker if necessary*/
if (getMap().hasLayer(this) && this.getHidden()) { if (getMap().hasLayer(this) && this.getHidden()) {
getMap().removeLayer(this); getMap().removeLayer(this);
} }
} }
getHidden() { getHidden() {
@@ -329,15 +333,15 @@ export class Unit extends Marker {
attackUnit(targetID: number) { attackUnit(targetID: number) {
/* Units can't attack themselves */ /* Units can't attack themselves */
if (!this.getMissionData().flags.Human) if (!this.getMissionData().flags.Human)
if (this.ID != targetID) if (this.ID != targetID)
attackUnit(this.ID, targetID); attackUnit(this.ID, targetID);
} }
followUnit(targetID: number, offset: {"x": number, "y": number, "z": number}) { followUnit(targetID: number, offset: { "x": number, "y": number, "z": number }) {
/* Units can't follow themselves */ /* Units can't follow themselves */
if (!this.getMissionData().flags.Human) if (!this.getMissionData().flags.Human)
if (this.ID != targetID) if (this.ID != targetID)
followUnit(this.ID, targetID, offset); followUnit(this.ID, targetID, offset);
} }
landAt(latlng: LatLng) { landAt(latlng: LatLng) {
@@ -424,26 +428,22 @@ export class Unit extends Marker {
} }
#onContextMenu(e: any) { #onContextMenu(e: any) {
var options: {[key: string]: string} = {}; var options: { [key: string]: string } = {};
options["Center"] = `<div id="center-map">Center map</div>`; options["Center"] = `<div id="center-map">Center map</div>`;
if (getUnitsManager().getSelectedUnits().length > 0 && !(getUnitsManager().getSelectedUnits().length == 1 && (getUnitsManager().getSelectedUnits().includes(this)))) if (getUnitsManager().getSelectedUnits().length > 0 && !(getUnitsManager().getSelectedUnits().length == 1 && (getUnitsManager().getSelectedUnits().includes(this)))) {
{
options['Attack'] = `<div id="attack">Attack</div>`; options['Attack'] = `<div id="attack">Attack</div>`;
if (getUnitsManager().getSelectedUnitsType() === "Aircraft") if (getUnitsManager().getSelectedUnitsType() === "Aircraft")
options['Follow'] = `<div id="follow">Follow</div>`; options['Follow'] = `<div id="follow">Follow</div>`;
} }
else if ((getUnitsManager().getSelectedUnits().length > 0 && (getUnitsManager().getSelectedUnits().includes(this))) || getUnitsManager().getSelectedUnits().length == 0) else if ((getUnitsManager().getSelectedUnits().length > 0 && (getUnitsManager().getSelectedUnits().includes(this))) || getUnitsManager().getSelectedUnits().length == 0) {
{ if (this.getBaseData().category == "Aircraft") {
if (this.getBaseData().category == "Aircraft")
{
options["Refuel"] = `<div id="refuel">Refuel</div>`; // TODO Add some way of knowing which aircraft can AAR options["Refuel"] = `<div id="refuel">Refuel</div>`; // TODO Add some way of knowing which aircraft can AAR
} }
} }
if (Object.keys(options).length > 0) if (Object.keys(options).length > 0) {
{
getMap().showUnitContextMenu(e); getMap().showUnitContextMenu(e);
getMap().getUnitContextMenu().setOptions(options, (option: string) => { getMap().getUnitContextMenu().setOptions(options, (option: string) => {
getMap().hideUnitContextMenu(); getMap().hideUnitContextMenu();
@@ -464,7 +464,7 @@ export class Unit extends Marker {
} }
#showFollowOptions(e: any) { #showFollowOptions(e: any) {
var options: {[key: string]: string} = {}; var options: { [key: string]: string } = {};
options = { options = {
'Trail': `<div id="trail">Trail</div>`, 'Trail': `<div id="trail">Trail</div>`,
@@ -484,12 +484,10 @@ export class Unit extends Marker {
getMap().showUnitContextMenu(e); getMap().showUnitContextMenu(e);
} }
#applyFollowOptions(action: string) #applyFollowOptions(action: string) {
{ if (action === "Custom") {
if (action === "Custom")
{
document.getElementById("custom-formation-dialog")?.classList.remove("hide"); document.getElementById("custom-formation-dialog")?.classList.remove("hide");
getMap().getUnitContextMenu().setCustomFormationCallback((offset: {x: number, y: number, z: number}) => { getMap().getUnitContextMenu().setCustomFormationCallback((offset: { x: number, y: number, z: number }) => {
getUnitsManager().selectedUnitsFollowUnit(this.ID, offset); getUnitsManager().selectedUnitsFollowUnit(this.ID, offset);
}) })
} }
@@ -502,17 +500,15 @@ export class Unit extends Marker {
this.updateVisibility(); this.updateVisibility();
/* Draw the minimap marker */ /* Draw the minimap marker */
if (this.getBaseData().alive ) if (this.getBaseData().alive) {
{ if (this.#miniMapMarker == null) {
if (this.#miniMapMarker == null) this.#miniMapMarker = new CircleMarker(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude), { radius: 0.5 });
{
this.#miniMapMarker = new CircleMarker(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude), {radius: 0.5});
if (this.getMissionData().coalition == "neutral") if (this.getMissionData().coalition == "neutral")
this.#miniMapMarker.setStyle({color: "#CFD9E8"}); this.#miniMapMarker.setStyle({ color: "#CFD9E8" });
else if (this.getMissionData().coalition == "red") else if (this.getMissionData().coalition == "red")
this.#miniMapMarker.setStyle({color: "#ff5858"}); this.#miniMapMarker.setStyle({ color: "#ff5858" });
else else
this.#miniMapMarker.setStyle({color: "#247be2"}); this.#miniMapMarker.setStyle({ color: "#247be2" });
this.#miniMapMarker.addTo(getMap().getMiniMapLayerGroup()); this.#miniMapMarker.addTo(getMap().getMiniMapLayerGroup());
this.#miniMapMarker.bringToBack(); this.#miniMapMarker.bringToBack();
} }
@@ -554,15 +550,15 @@ export class Unit extends Marker {
/* Set altitude and speed */ /* Set altitude and speed */
if (element.querySelector(".unit-altitude")) if (element.querySelector(".unit-altitude"))
(<HTMLElement> element.querySelector(".unit-altitude")).innerText = "FL" + String(Math.floor(this.getFlightData().altitude / 0.3048 / 100)); (<HTMLElement>element.querySelector(".unit-altitude")).innerText = "FL" + String(Math.floor(this.getFlightData().altitude / 0.3048 / 100));
if (element.querySelector(".unit-speed")) if (element.querySelector(".unit-speed"))
(<HTMLElement> element.querySelector(".unit-speed")).innerHTML = String(Math.floor(this.getFlightData().speed * 1.94384 ) ); (<HTMLElement>element.querySelector(".unit-speed")).innerHTML = String(Math.floor(this.getFlightData().speed * 1.94384));
/* Rotate elements according to heading */ /* Rotate elements according to heading */
element.querySelectorAll( "[data-rotate-to-heading]" ).forEach( el => { element.querySelectorAll("[data-rotate-to-heading]").forEach(el => {
const headingDeg = rad2deg( this.getFlightData().heading ); const headingDeg = rad2deg(this.getFlightData().heading);
let currentStyle = el.getAttribute( "style" ) || ""; let currentStyle = el.getAttribute("style") || "";
el.setAttribute( "style", currentStyle + `transform:rotate(${headingDeg}deg);` ); el.setAttribute("style", currentStyle + `transform:rotate(${headingDeg}deg);`);
}); });
/* Turn on ordnance indicators */ /* Turn on ordnance indicators */
@@ -577,14 +573,14 @@ export class Unit extends Marker {
var newHasOtherAmmo = false; var newHasOtherAmmo = false;
Object.values(this.getMissionData().ammo).forEach((ammo: any) => { Object.values(this.getMissionData().ammo).forEach((ammo: any) => {
if (ammo.desc.category == 1 && ammo.desc.missileCategory == 1) { if (ammo.desc.category == 1 && ammo.desc.missileCategory == 1) {
if (ammo.desc.guidance == 4 || ammo.desc.guidance == 5) if (ammo.desc.guidance == 4 || ammo.desc.guidance == 5)
newHasFox1 = true; newHasFox1 = true;
else if (ammo.desc.guidance == 2) else if (ammo.desc.guidance == 2)
newHasFox2 = true; newHasFox2 = true;
else if (ammo.desc.guidance == 3) else if (ammo.desc.guidance == 3)
newHasFox3 = true; newHasFox3 = true;
} }
else else
newHasOtherAmmo = true; newHasOtherAmmo = true;
}); });
@@ -594,18 +590,18 @@ export class Unit extends Marker {
if (hasOtherAmmo != newHasOtherAmmo) element.querySelector(".unit")?.toggleAttribute("data-has-other-ammo", newHasOtherAmmo); if (hasOtherAmmo != newHasOtherAmmo) element.querySelector(".unit")?.toggleAttribute("data-has-other-ammo", newHasOtherAmmo);
/* Draw the hotgroup element */ /* Draw the hotgroup element */
element.querySelector(".unit")?.toggleAttribute("data-is-in-hotgroup", this.#hotgroup != null);
if (this.#hotgroup) { if (this.#hotgroup) {
element.querySelector(".unit")?.toggleAttribute("data-is-in-hotgroup", this.#hotgroup != null);
const hotgroupEl = element.querySelector(".unit-hotgroup-id") as HTMLElement; const hotgroupEl = element.querySelector(".unit-hotgroup-id") as HTMLElement;
if (hotgroupEl) if (hotgroupEl)
hotgroupEl.innerText = String(this.#hotgroup); hotgroupEl.innerText = String(this.#hotgroup);
} }
} }
/* Set vertical offset for altitude stacking */ /* Set vertical offset for altitude stacking */
var pos = getMap().latLngToLayerPoint(this.getLatLng()).round(); var pos = getMap().latLngToLayerPoint(this.getLatLng()).round();
this.setZIndexOffset(1000 + Math.floor(this.getFlightData().altitude) - pos.y + (this.#hovered || this.#selected? 5000: 0)); this.setZIndexOffset(1000 + Math.floor(this.getFlightData().altitude) - pos.y + (this.#highlighted || this.#selected ? 5000 : 0));
} }
} }
@@ -689,8 +685,7 @@ export class Aircraft extends AirUnit {
super(ID, data); super(ID, data);
} }
getMarkerHTML() getMarkerHTML() {
{
return `<div class="unit" data-object="unit-aircraft" data-coalition="${this.getMissionData().coalition}"> return `<div class="unit" data-object="unit-aircraft" data-coalition="${this.getMissionData().coalition}">
<div class="unit-selected-spotlight"></div> <div class="unit-selected-spotlight"></div>
<div class="unit-marker-border"></div> <div class="unit-marker-border"></div>
@@ -718,8 +713,7 @@ export class Aircraft extends AirUnit {
</div>` </div>`
} }
getMarkerCategory() getMarkerCategory() {
{
return "aircraft"; return "aircraft";
} }
} }
@@ -729,8 +723,7 @@ export class Helicopter extends AirUnit {
super(ID, data); super(ID, data);
} }
getVisibilityCategory() getVisibilityCategory() {
{
return "helicopter"; return "helicopter";
} }
} }
@@ -742,7 +735,7 @@ export class GroundUnit extends Unit {
getMarkerHTML() { getMarkerHTML() {
var role = groundUnitsDatabase.getByName(this.getBaseData().name)?.loadouts[0].roles[0]; var role = groundUnitsDatabase.getByName(this.getBaseData().name)?.loadouts[0].roles[0];
return `<div class="unit" data-object="unit-${this.getMarkerCategory()}" data-coalition="${this.getMissionData().coalition}"> return `<div class="unit" data-object="unit-${this.getMarkerCategory()}" data-coalition="${this.getMissionData().coalition}">
<div class="unit-selected-spotlight"></div> <div class="unit-selected-spotlight"></div>
<div class="unit-marker"></div> <div class="unit-marker"></div>
<div class="unit-short-label">${role?.substring(0, 1)?.toUpperCase() || ""}</div> <div class="unit-short-label">${role?.substring(0, 1)?.toUpperCase() || ""}</div>
@@ -752,8 +745,7 @@ export class GroundUnit extends Unit {
</div>` </div>`
} }
getMarkerCategory() getMarkerCategory() {
{
// TODO this is very messy // TODO this is very messy
var role = groundUnitsDatabase.getByName(this.getBaseData().name)?.loadouts[0].roles[0]; var role = groundUnitsDatabase.getByName(this.getBaseData().name)?.loadouts[0].roles[0];
var markerCategory = (role === "SAM") ? "sam" : "groundunit"; var markerCategory = (role === "SAM") ? "sam" : "groundunit";
@@ -765,7 +757,7 @@ export class NavyUnit extends Unit {
constructor(ID: number, data: UnitData) { constructor(ID: number, data: UnitData) {
super(ID, data); super(ID, data);
} }
getMarkerCategory() { getMarkerCategory() {
return "navyunit"; return "navyunit";
} }

View File

@@ -46,7 +46,7 @@ export class UnitsManager {
} }
getUnitsByHotgroup(hotgroup: number) { getUnitsByHotgroup(hotgroup: number) {
return Object.values(this.#units).filter((unit: Unit) => {return unit.getHotgroup() == hotgroup}); return Object.values(this.#units).filter((unit: Unit) => {return unit.getBaseData().alive && unit.getHotgroup() == hotgroup});
} }
addUnit(ID: number, data: UnitData) { addUnit(ID: number, data: UnitData) {
@@ -117,6 +117,7 @@ export class UnitsManager {
} }
selectUnitsByHotgroup(hotgroup: number) { selectUnitsByHotgroup(hotgroup: number) {
this.deselectAllUnits();
this.getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setSelected(true)) this.getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setSelected(true))
} }
@@ -222,7 +223,6 @@ export class UnitsManager {
for (let idx in selectedUnits) { for (let idx in selectedUnits) {
selectedUnits[idx].setSpeed(speed); selectedUnits[idx].setSpeed(speed);
} }
this.#showActionMessage(selectedUnits, `setting speed to ${speed * 1.94384} kts`); this.#showActionMessage(selectedUnits, `setting speed to ${speed * 1.94384} kts`);
} }
@@ -317,6 +317,12 @@ export class UnitsManager {
this.#showActionMessage(selectedUnits, `following unit ${this.getUnitByID(ID)?.getBaseData().unitName}`); this.#showActionMessage(selectedUnits, `following unit ${this.getUnitByID(ID)?.getBaseData().unitName}`);
} }
selectedUnitsSetHotgroup(hotgroup: number)
{
this.getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHotgroup(null));
this.selectedUnitsAddToHotgroup(hotgroup);
}
selectedUnitsAddToHotgroup(hotgroup: number) selectedUnitsAddToHotgroup(hotgroup: number)
{ {
var selectedUnits = this.getSelectedUnits(); var selectedUnits = this.getSelectedUnits();
@@ -324,7 +330,7 @@ export class UnitsManager {
selectedUnits[idx].setHotgroup(hotgroup); selectedUnits[idx].setHotgroup(hotgroup);
} }
this.#showActionMessage(selectedUnits, `added to hotgroup ${hotgroup}`); this.#showActionMessage(selectedUnits, `added to hotgroup ${hotgroup}`);
getHotgroupPanel().addHotgroup(hotgroup); getHotgroupPanel().refreshHotgroups();
} }
/***********************************************/ /***********************************************/

View File

@@ -1,3 +1,3 @@
<div id="hotgroup-panel"> <div id="hotgroup-panel">
<!-- Here is where the various hotgroup buttons will show up -->
</div> </div>