From e0a3fd179551ef390b8caf393cc85e2a335b748e Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Sat, 12 Aug 2023 16:46:37 +0100 Subject: [PATCH 1/6] Corrected some variable names. --- client/src/constants/constants.ts | 7 ++++--- client/src/map/map.ts | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/client/src/constants/constants.ts b/client/src/constants/constants.ts index 8d29bbb7..192825e1 100644 --- a/client/src/constants/constants.ts +++ b/client/src/constants/constants.ts @@ -141,15 +141,16 @@ export const FIRE_AT_AREA = "Fire at area"; export const COALITIONAREA_DRAW_POLYGON = "Draw Coalition Area"; export const visibilityControls: string[] = ["human", "dcs", "aircraft", "groundunit-sam", "groundunit-other", "navyunit", "airbase"]; export const visibilityControlsTypes: string[][] = [["human"], ["dcs"], ["aircraft"], ["groundunit-sam", "groundunit-sam-radar", "groundunit-sam-launcher"], ["groundunit-other", "groundunit-ewr"], ["navyunit"], ["airbase"]]; -export const visibilityControlsTootlips: string[] = ["Toggle human players visibility", "Toggle DCS controlled units visibility", "Toggle aircrafts visibility", "Toggle SAM units visibility", "Toggle ground units (not SAM) visibility", "Toggle navy units visibility", "Toggle airbases visibility"]; +export const visibilityControlsTooltips: string[] = ["Toggle human players visibility", "Toggle DCS controlled units visibility", "Toggle aircrafts visibility", "Toggle SAM units visibility", "Toggle ground units (not SAM) visibility", "Toggle navy units visibility", "Toggle airbases visibility"]; 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 const SHOW_UNIT_LABELS = "Show unit labels (L)"; +export const SHOW_UNIT_PATHS = "Show unit paths"; +export const SHOW_UNIT_TARGETS = "Show unit targets"; export enum DataIndexes { startOfData = 0, diff --git a/client/src/map/map.ts b/client/src/map/map.ts index f727ce93..8cb6e968 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -12,7 +12,7 @@ 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, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes } from "../constants/constants"; +import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, FIRE_AT_AREA, MOVE_UNIT, CARPET_BOMBING, BOMBING, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes } from "../constants/constants"; import { TargetMarker } from "./targetmarker"; import { CoalitionArea } from "./coalitionarea"; import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu"; @@ -63,7 +63,7 @@ export class Map extends L.Map { #mapSourceDropdown: Dropdown; #mapVisibilityOptionsDropdown: Dropdown; #optionButtons: { [key: string]: HTMLButtonElement[] } = {} - #visibiityOptions: { [key: string]: boolean } = {} + #visibilityOptions: { [key: string]: boolean } = {} constructor(ID: string) { /* Init the leaflet map */ @@ -89,7 +89,7 @@ export class Map extends L.Map { this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName), this.getLayers()); /* Visibility options dropdown */ - this.#mapVisibilityOptionsDropdown = new Dropdown("map-visibility-options", () => {}); + this.#mapVisibilityOptionsDropdown = new Dropdown("map-visibility-options", ( value:string ) => {}); /* Init the state machine */ this.#state = IDLE; @@ -161,18 +161,18 @@ export class Map extends L.Map { this.#optionButtons["visibility"] = visibilityControls.map((option: string, index: number) => { var typesArrayString = `"${visibilityControlsTypes[index][0]}"`; visibilityControlsTypes[index].forEach((type: string, idx: number) => {if (idx > 0) typesArrayString = `${typesArrayString}, "${type}"`}); - return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, visibilityControlsTootlips[index], "toggleMarkerVisibility", `{"types": [${typesArrayString}]}`); + return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, visibilityControlsTooltips[index], "toggleMarkerVisibility", `{"types": [${typesArrayString}]}`); }); 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.#visibilityOptions[SHOW_CONTACT_LINES] = false; + this.#visibilityOptions[HIDE_GROUP_MEMBERS] = true; + this.#visibilityOptions[SHOW_UNIT_PATHS] = true; + this.#visibilityOptions[SHOW_UNIT_TARGETS] = true; + this.#mapVisibilityOptionsDropdown.setOptionsElements(Object.keys(this.#visibilityOptions).map((option: string) => { + return createCheckboxOption(option, option, this.#visibilityOptions[option], (ev: any) => { this.#setVisibilityOption(option, ev); }); })); @@ -435,7 +435,7 @@ export class Map extends L.Map { } getVisibilityOptions() { - return this.#visibiityOptions; + return this.#visibilityOptions; } /* Event handlers */ @@ -724,7 +724,7 @@ export class Map extends L.Map { } #setVisibilityOption(option: string, ev: any) { - this.#visibiityOptions[option] = ev.currentTarget.checked; + this.#visibilityOptions[option] = ev.currentTarget.checked; document.dispatchEvent(new CustomEvent("mapVisibilityOptionsChanged")); } } From 07b69fe96f52500f8277f9b1f6959b7f621fca1a Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Sat, 12 Aug 2023 19:31:08 +0100 Subject: [PATCH 2/6] Added dbl-click select but it's buggy AF --- client/src/unit/unit.ts | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/client/src/unit/unit.ts b/client/src/unit/unit.ts index 3a3f2cd4..7d972ee1 100644 --- a/client/src/unit/unit.ts +++ b/client/src/unit/unit.ts @@ -567,6 +567,18 @@ export class Unit extends CustomMarker { return false; } + isInViewport() { + + const mapBounds = getMap().getBounds(); + const unitPos = this.getPosition(); + + return ( unitPos.lng > mapBounds.getWest() + && unitPos.lng < mapBounds.getEast() + && unitPos.lat > mapBounds.getSouth() + && unitPos.lat < mapBounds.getNorth() ); + + } + /********************** Unit commands *************************/ addDestination(latlng: L.LatLng) { if (!this.#human) { @@ -707,6 +719,7 @@ export class Unit extends CustomMarker { /***********************************************/ #onClick(e: any) { if (!this.#preventClick) { + console.log( getMap().getState() ); if (getMap().getState() === IDLE || getMap().getState() === MOVE_UNIT || e.originalEvent.ctrlKey) { if (!e.originalEvent.ctrlKey) { @@ -716,10 +729,10 @@ export class Unit extends CustomMarker { const unitIsSelected = !this.getSelected(); this.setSelected( unitIsSelected ); - - - // Tell everyone a unit (de-)selection has happened, usually a panel or something. + + // Tell everyone a unit (de-)selection has happened, usually a panel or something. + // const detail = { "detail": { "unit": this @@ -741,6 +754,18 @@ export class Unit extends CustomMarker { } #onDoubleClick(e: any) { + + const unitsManager = getUnitsManager(); + + Object.values( unitsManager.getUnits() ).forEach( ( unit:Unit ) => { + + if ( unit.getAlive() === true && unit.getControlled() && unit.getName() === this.getName() && unit.isInViewport() ) { + unitsManager.selectUnit( unit.ID, false ); + } + + }); + + clearTimeout(this.#timer); this.#preventClick = true; } From 9547559e000b7a00d310404ac112a5917070bf45 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Mon, 28 Aug 2023 17:14:03 +0200 Subject: [PATCH 3/6] Refactoring and merge --- client/src/unit/unit.ts | 180 ++++++++++++++++++---------------------- 1 file changed, 79 insertions(+), 101 deletions(-) diff --git a/client/src/unit/unit.ts b/client/src/unit/unit.ts index c2cdc075..8eccce12 100644 --- a/client/src/unit/unit.ts +++ b/client/src/unit/unit.ts @@ -76,7 +76,7 @@ export class Unit extends CustomMarker { }; #ammo: Ammo[] = []; #contacts: Contact[] = []; - #activePath: LatLng[] = []; + #activePath: LatLng[] = []; #isLeader: boolean = false; #selectable: boolean; @@ -94,43 +94,43 @@ export class Unit extends CustomMarker { #hotgroup: number | null = null; #detectionMethods: number[] = []; - getAlive() {return this.#alive}; - getHuman() {return this.#human}; - getControlled() {return this.#controlled}; - getCoalition() {return this.#coalition}; - getCountry() {return this.#country}; - getName() {return this.#name}; - getUnitName() {return this.#unitName}; - getGroupName() {return this.#groupName}; - getState() {return this.#state}; - getTask() {return this.#task}; - getHasTask() {return this.#hasTask}; - getPosition() {return this.#position}; - getSpeed() {return this.#speed}; - getHeading() {return this.#heading}; - getIsTanker() {return this.#isTanker}; - getIsAWACS() {return this.#isAWACS}; - getOnOff() {return this.#onOff}; - getFollowRoads() {return this.#followRoads}; - getFuel() {return this.#fuel}; - getDesiredSpeed() {return this.#desiredSpeed}; - getDesiredSpeedType() {return this.#desiredSpeedType}; - getDesiredAltitude() {return this.#desiredAltitude}; - getDesiredAltitudeType() {return this.#desiredAltitudeType}; - getLeaderID() {return this.#leaderID}; - getFormationOffset() {return this.#formationOffset}; - getTargetID() {return this.#targetID}; - getTargetPosition() {return this.#targetPosition}; - getROE() {return this.#ROE}; - getReactionToThreat() {return this.#reactionToThreat}; - getEmissionsCountermeasures() {return this.#emissionsCountermeasures}; - getTACAN() {return this.#TACAN}; - getRadio() {return this.#radio}; - getGeneralSettings() {return this.#generalSettings}; - getAmmo() {return this.#ammo}; - getContacts() {return this.#contacts}; - getActivePath() {return this.#activePath}; - getIsLeader() {return this.#isLeader}; + getAlive() { return this.#alive }; + getHuman() { return this.#human }; + getControlled() { return this.#controlled }; + getCoalition() { return this.#coalition }; + getCountry() { return this.#country }; + getName() { return this.#name }; + getUnitName() { return this.#unitName }; + getGroupName() { return this.#groupName }; + getState() { return this.#state }; + getTask() { return this.#task }; + getHasTask() { return this.#hasTask }; + getPosition() { return this.#position }; + getSpeed() { return this.#speed }; + getHeading() { return this.#heading }; + getIsTanker() { return this.#isTanker }; + getIsAWACS() { return this.#isAWACS }; + getOnOff() { return this.#onOff }; + getFollowRoads() { return this.#followRoads }; + getFuel() { return this.#fuel }; + getDesiredSpeed() { return this.#desiredSpeed }; + getDesiredSpeedType() { return this.#desiredSpeedType }; + getDesiredAltitude() { return this.#desiredAltitude }; + getDesiredAltitudeType() { return this.#desiredAltitudeType }; + getLeaderID() { return this.#leaderID }; + getFormationOffset() { return this.#formationOffset }; + getTargetID() { return this.#targetID }; + getTargetPosition() { return this.#targetPosition }; + getROE() { return this.#ROE }; + getReactionToThreat() { return this.#reactionToThreat }; + getEmissionsCountermeasures() { return this.#emissionsCountermeasures }; + getTACAN() { return this.#TACAN }; + getRadio() { return this.#radio }; + getGeneralSettings() { return this.#generalSettings }; + getAmmo() { return this.#ammo }; + getContacts() { return this.#contacts }; + getActivePath() { return this.#activePath }; + getIsLeader() { return this.#isLeader }; static getConstructor(type: string) { if (type === "GroundUnit") return GroundUnit; @@ -156,7 +156,7 @@ export class Unit extends CustomMarker { this.on('contextmenu', (e) => this.#onContextMenu(e)); this.on('mouseover', () => { if (this.belongsToCommandedCoalition()) this.setHighlighted(true); }) this.on('mouseout', () => { this.setHighlighted(false); }) - getMap().on("zoomend", () => {this.#onZoom();}) + getMap().on("zoomend", () => { this.#onZoom(); }) /* Deselect units if they are hidden */ document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => { @@ -165,13 +165,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() { @@ -222,12 +222,12 @@ export class Unit extends CustomMarker { case DataIndexes.radio: this.#radio = dataExtractor.extractRadio(); break; case DataIndexes.generalSettings: this.#generalSettings = dataExtractor.extractGeneralSettings(); break; case DataIndexes.ammo: this.#ammo = dataExtractor.extractAmmo(); break; - case DataIndexes.contacts: this.#contacts = dataExtractor.extractContacts(); document.dispatchEvent(new CustomEvent("contactsUpdated", {detail: this})); break; + case DataIndexes.contacts: this.#contacts = dataExtractor.extractContacts(); document.dispatchEvent(new CustomEvent("contactsUpdated", { detail: this })); break; case DataIndexes.activePath: this.#activePath = dataExtractor.extractActivePath(); break; case DataIndexes.isLeader: this.#isLeader = dataExtractor.extractBool(); break; } } - + /* Dead units can't be selected */ this.setSelected(this.getSelected() && this.#alive && !this.getHidden()) @@ -314,7 +314,7 @@ export class Unit extends CustomMarker { getLiveryID(): string { const liveryID = this.getDatabase()?.getByName(this.getName())?.liveryID; - return liveryID? liveryID: ""; + return liveryID ? liveryID : ""; } setAlive(newAlive: boolean) { @@ -327,7 +327,7 @@ export class Unit extends CustomMarker { /* Only alive units can be selected. Some units are not selectable (weapons) */ if ((this.#alive || !selected) && this.getSelectable() && this.getSelected() != selected && this.belongsToCommandedCoalition()) { this.#selected = selected; - + if (selected) { document.dispatchEvent(new CustomEvent("unitSelection", { detail: this })); this.#updateMarker(); @@ -346,7 +346,7 @@ export class Unit extends CustomMarker { else this.#updateMarker(); } - + } } @@ -390,7 +390,7 @@ export class Unit extends CustomMarker { belongsToCommandedCoalition() { if (getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER && getMissionHandler().getCommandedCoalition() !== this.#coalition) return false; - return true; + return true; } getType() { @@ -503,12 +503,12 @@ export class Unit extends CustomMarker { updateVisibility() { const hiddenUnits = getUnitsManager().getHiddenTypes(); var hidden = ((this.#human && hiddenUnits.includes("human")) || - (this.#controlled == false && hiddenUnits.includes("dcs")) || - (hiddenUnits.includes(this.getMarkerCategory())) || - (hiddenUnits.includes(this.#coalition)) || - (!this.belongsToCommandedCoalition() && (this.#detectionMethods.length == 0 || (this.#detectionMethods.length == 1 && this.#detectionMethods[0] === RWR))) || - (getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && this.getCategory() == "GroundUnit" && getMap().getZoom() < 13 && (this.belongsToCommandedCoalition() || (!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0)))) && - !(this.getSelected()); + (this.#controlled == false && hiddenUnits.includes("dcs")) || + (hiddenUnits.includes(this.getMarkerCategory())) || + (hiddenUnits.includes(this.#coalition)) || + (!this.belongsToCommandedCoalition() && (this.#detectionMethods.length == 0 || (this.#detectionMethods.length == 1 && this.#detectionMethods[0] === RWR))) || + (getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && this.getCategory() == "GroundUnit" && getMap().getZoom() < 13 && (this.belongsToCommandedCoalition() || (!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0)))) && + !(this.getSelected()); this.setHidden(hidden || !this.#alive); } @@ -518,9 +518,9 @@ export class Unit extends CustomMarker { /* Add the marker if not present */ if (!getMap().hasLayer(this) && !this.getHidden()) { - if (getMap().isZooming()) - this.once("zoomend", () => {this.addTo(getMap())}) - else + if (getMap().isZooming()) + this.once("zoomend", () => { this.addTo(getMap()) }) + else this.addTo(getMap()); } @@ -563,19 +563,19 @@ export class Unit extends CustomMarker { return loadouts.some((loadout: LoadoutBlueprint) => { return (roles as string[]).some((role: string) => { return loadout.roles.includes(role) }); }); - } else + } else return false; } isInViewport() { const mapBounds = getMap().getBounds(); - const unitPos = this.getPosition(); + const unitPos = this.getPosition(); - return ( unitPos.lng > mapBounds.getWest() - && unitPos.lng < mapBounds.getEast() - && unitPos.lat > mapBounds.getSouth() - && unitPos.lat < mapBounds.getNorth() ); + return (unitPos.lng > mapBounds.getWest() + && unitPos.lng < mapBounds.getEast() + && unitPos.lat > mapBounds.getSouth() + && unitPos.lat < mapBounds.getNorth()); } @@ -719,51 +719,29 @@ export class Unit extends CustomMarker { /***********************************************/ #onClick(e: any) { if (!this.#preventClick) { - console.log( getMap().getState() ); if (getMap().getState() === IDLE || getMap().getState() === MOVE_UNIT || e.originalEvent.ctrlKey) { - if (!e.originalEvent.ctrlKey) + if (!e.originalEvent.ctrlKey) getUnitsManager().deselectAllUnits(); - } - const unitIsSelected = !this.getSelected(); - - this.setSelected( unitIsSelected ); - - - // Tell everyone a unit (de-)selection has happened, usually a panel or something. - // - const detail = { - "detail": { - "unit": this - } - }; - - if ( unitIsSelected ) { - document.dispatchEvent( new CustomEvent( "unitSelected", detail ) ); - } else { - document.dispatchEvent( new CustomEvent( "unitDeselection", { "detail": this })); - } + this.setSelected(!this.getSelected()); + const detail = { "detail": { "unit": this } }; + if (this.getSelected()) + document.dispatchEvent(new CustomEvent("unitSelected", detail)); + else + document.dispatchEvent(new CustomEvent("unitDeselection", { "detail": this })); } } - this.#timer = window.setTimeout(() => { - this.#preventClick = false; - }, 200); + this.#timer = window.setTimeout(() => { this.#preventClick = false; }, 200); } #onDoubleClick(e: any) { - const unitsManager = getUnitsManager(); - - Object.values( unitsManager.getUnits() ).forEach( ( unit:Unit ) => { - - if ( unit.getAlive() === true && unit.getControlled() && unit.getName() === this.getName() && unit.isInViewport() ) { - unitsManager.selectUnit( unit.ID, false ); - } - + Object.values(unitsManager.getUnits()).forEach((unit: Unit) => { + if (unit.getAlive() === true && unit.getName() === this.getName() && unit.isInViewport()) + unitsManager.selectUnit(unit.ID, false); }); - clearTimeout(this.#timer); this.#preventClick = true; } @@ -803,7 +781,7 @@ export class Unit extends CustomMarker { options["fire-at-area"] = { text: "Fire at area", tooltip: "Fire at a large area" }; } - if (selectedUnitTypes.length === 1 && ["NavyUnit", "GroundUnit"].includes(selectedUnitTypes[0]) && getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getCoalition()}) !== undefined) + if (selectedUnitTypes.length === 1 && ["NavyUnit", "GroundUnit"].includes(selectedUnitTypes[0]) && getUnitsManager().getSelectedUnitsVariable((unit: Unit) => { return unit.getCoalition() }) !== undefined) options["group"] = { text: "Create group", tooltip: "Create a group from the selected units." }; if (Object.keys(options).length > 0) { @@ -832,7 +810,7 @@ export class Unit extends CustomMarker { getMap().setState(CARPET_BOMBING); else if (action === "fire-at-area") getMap().setState(FIRE_AT_AREA); - + } #showFollowOptions(e: any) { @@ -853,7 +831,7 @@ export class Unit extends CustomMarker { getMap().hideUnitContextMenu(); this.#applyFollowOptions(option); }); - + getMap().showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng); } @@ -1173,7 +1151,7 @@ export class GroundUnit extends Unit { getType() { var blueprint = groundUnitDatabase.getByName(this.getName()); - return blueprint?.type? blueprint.type: ""; + return blueprint?.type ? blueprint.type : ""; } } @@ -1207,6 +1185,6 @@ export class NavyUnit extends Unit { getType() { var blueprint = navyUnitDatabase.getByName(this.getName()); - return blueprint?.type? blueprint.type: ""; + return blueprint?.type ? blueprint.type : ""; } } From 8e7d64f0e4aec0a1543dd380cdc31a52f365c416 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Tue, 29 Aug 2023 09:39:07 +0200 Subject: [PATCH 4/6] Remove shortcut and added option in dropdown --- client/src/@types/dom.d.ts | 2 +- client/src/constants/constants.ts | 2 +- client/src/index.ts | 3 --- client/src/map/map.ts | 24 ++++++++++++++---------- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/client/src/@types/dom.d.ts b/client/src/@types/dom.d.ts index a3712343..dc70c183 100644 --- a/client/src/@types/dom.d.ts +++ b/client/src/@types/dom.d.ts @@ -19,7 +19,7 @@ interface CustomEventMap { "mapStateChanged": CustomEvent, "mapContextMenu": CustomEvent<>, "mapVisibilityOptionsChanged": CustomEvent<>, - "commandModeOptionsChanged": CustomEvent<>, + "commandModeOptionsChanged": CustomEvent<>, "contactsUpdated": CustomEvent, } diff --git a/client/src/constants/constants.ts b/client/src/constants/constants.ts index 192825e1..08f63b97 100644 --- a/client/src/constants/constants.ts +++ b/client/src/constants/constants.ts @@ -148,7 +148,7 @@ export const IADSDensities: {[key: string]: number}= {"AAA": 0.8, "MANPADS": 0.3 export const SHOW_CONTACT_LINES = "Show unit contact lines"; export const HIDE_GROUP_MEMBERS = "Hide group members when zoomed out"; -export const SHOW_UNIT_LABELS = "Show unit labels (L)"; +export const SHOW_UNIT_LABELS = "Show unit labels"; export const SHOW_UNIT_PATHS = "Show unit paths"; export const SHOW_UNIT_TARGETS = "Show unit targets"; diff --git a/client/src/index.ts b/client/src/index.ts index 8a86d75e..e16f8562 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -137,9 +137,6 @@ function setupEvents() { return; } switch (ev.code) { - case "KeyL": - document.body.toggleAttribute("data-hide-labels"); - break; case "KeyT": toggleDemoEnabled(); break; diff --git a/client/src/map/map.ts b/client/src/map/map.ts index 8cb6e968..b50886ff 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -12,7 +12,7 @@ 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, visibilityControlsTooltips, FIRE_AT_AREA, MOVE_UNIT, CARPET_BOMBING, BOMBING, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes } from "../constants/constants"; +import { layers as mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, FIRE_AT_AREA, MOVE_UNIT, CARPET_BOMBING, BOMBING, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants"; import { TargetMarker } from "./targetmarker"; import { CoalitionArea } from "./coalitionarea"; import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu"; @@ -45,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; @@ -89,7 +89,7 @@ export class Map extends L.Map { this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName), this.getLayers()); /* Visibility options dropdown */ - this.#mapVisibilityOptionsDropdown = new Dropdown("map-visibility-options", ( value:string ) => {}); + this.#mapVisibilityOptionsDropdown = new Dropdown("map-visibility-options", (value: string) => { }); /* Init the state machine */ this.#state = IDLE; @@ -132,7 +132,7 @@ export class Map extends L.Map { }) } }); - + document.addEventListener("toggleCoalitionAreaDraw", (ev: CustomEventInit) => { this.getMapContextMenu().hide(); @@ -150,6 +150,10 @@ export class Map extends L.Map { this.#panToUnit(this.#centerUnit); }); + document.addEventListener("mapVisibilityOptionsChanged", () => { + this.getContainer().toggleAttribute("data-hide-labels", !this.getVisibilityOptions()[SHOW_UNIT_LABELS]); + }); + /* Pan interval */ this.#panInterval = window.setInterval(() => { if (this.#panLeft || this.#panDown || this.#panRight || this.#panLeft) @@ -160,17 +164,17 @@ export class Map extends L.Map { /* Option buttons */ this.#optionButtons["visibility"] = visibilityControls.map((option: string, index: number) => { var typesArrayString = `"${visibilityControlsTypes[index][0]}"`; - visibilityControlsTypes[index].forEach((type: string, idx: number) => {if (idx > 0) typesArrayString = `${typesArrayString}, "${type}"`}); + visibilityControlsTypes[index].forEach((type: string, idx: number) => { if (idx > 0) typesArrayString = `${typesArrayString}, "${type}"` }); return this.#createOptionButton(option, `visibility/${option.toLowerCase()}.svg`, visibilityControlsTooltips[index], "toggleMarkerVisibility", `{"types": [${typesArrayString}]}`); }); document.querySelector("#unit-visibility-control")?.append(...this.#optionButtons["visibility"]); /* Create the checkboxes to select the advanced visibility options */ - this.#visibilityOptions[SHOW_CONTACT_LINES] = false; this.#visibilityOptions[HIDE_GROUP_MEMBERS] = true; - this.#visibilityOptions[SHOW_UNIT_PATHS] = true; - this.#visibilityOptions[SHOW_UNIT_TARGETS] = true; + this.#visibilityOptions[SHOW_UNIT_PATHS] = true; + this.#visibilityOptions[SHOW_UNIT_TARGETS] = true; + this.#visibilityOptions[SHOW_UNIT_LABELS] = true; this.#mapVisibilityOptionsDropdown.setOptionsElements(Object.keys(this.#visibilityOptions).map((option: string) => { return createCheckboxOption(option, option, this.#visibilityOptions[option], (ev: any) => { this.#setVisibilityOption(option, ev); @@ -473,7 +477,7 @@ export class Map extends L.Map { /* Coalition areas are ordered in the #coalitionAreas array according to their zindex. Select the upper one */ for (let coalitionArea of this.#coalitionAreas) { if (coalitionArea.getBounds().contains(e.latlng)) { - if (coalitionArea.getSelected()) + if (coalitionArea.getSelected()) clickedCoalitionArea = coalitionArea; else this.getMapContextMenu().setCoalitionArea(coalitionArea); @@ -659,7 +663,7 @@ export class Map extends L.Map { else { Object.values(getUnitsManager().selectedUnitsComputeGroupDestination(groupLatLng, this.#destinationGroupRotation)).forEach((latlng: L.LatLng, idx: number) => { if (idx < this.#destinationPreviewCursors.length) - this.#destinationPreviewCursors[idx].setLatLng(this.#shiftKey? latlng : this.getMouseCoordinates()); + this.#destinationPreviewCursors[idx].setLatLng(this.#shiftKey ? latlng : this.getMouseCoordinates()); }) }; } From cc386e86b9ebe0f45c50c1dbc144d39f51bf7b69 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Tue, 29 Aug 2023 10:02:18 +0200 Subject: [PATCH 5/6] Create colored smoke markers --- client/public/stylesheets/olympus.css | 30 +++- .../themes/olympus/images/markers/smoke.svg | 133 ++++++++++++++++++ .../olympus/images/markers/target - Copy.svg | 101 +++++++++++++ .../olympus/images/markers/temporary-icon.png | Bin 2538 -> 0 bytes client/src/controls/mapcontextmenu.ts | 3 + client/src/map/smokemarker.ts | 31 ++++ 6 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 client/public/themes/olympus/images/markers/smoke.svg create mode 100644 client/public/themes/olympus/images/markers/target - Copy.svg delete mode 100644 client/public/themes/olympus/images/markers/temporary-icon.png create mode 100644 client/src/map/smokemarker.ts diff --git a/client/public/stylesheets/olympus.css b/client/public/stylesheets/olympus.css index fabc3105..9c40b7f1 100644 --- a/client/public/stylesheets/olympus.css +++ b/client/public/stylesheets/olympus.css @@ -1031,13 +1031,41 @@ nav.ol-panel> :last-child { } .ol-target-icon { - background-image: url("/resources/theme/images/markers/target.svg"); height: 52px; pointer-events: none; width: 52px; z-index: 9999; } +.ol-smoke-icon { + background-image: url("/resources/theme/images/markers/smoke.svg"); + height: 52px; + pointer-events: none; + width: 52px; + z-index: 9999; + opacity: 0.8; +} + +.ol-smoke-icon[data-color="white"] { + fill: white; +} + +.ol-smoke-icon[data-color="blue"] { + fill: blue; +} + +.ol-smoke-icon[data-color="red"] { + fill: red; +} + +.ol-smoke-icon[data-color="green"] { + fill: green; +} + +.ol-smoke-icon[data-color="orange"] { + fill: orange; +} + .ol-draw-icon { background-image: url("/resources/theme/images/markers/draw.svg"); height: 24px; diff --git a/client/public/themes/olympus/images/markers/smoke.svg b/client/public/themes/olympus/images/markers/smoke.svg new file mode 100644 index 00000000..4c058371 --- /dev/null +++ b/client/public/themes/olympus/images/markers/smoke.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/public/themes/olympus/images/markers/target - Copy.svg b/client/public/themes/olympus/images/markers/target - Copy.svg new file mode 100644 index 00000000..7afbf612 --- /dev/null +++ b/client/public/themes/olympus/images/markers/target - Copy.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + diff --git a/client/public/themes/olympus/images/markers/temporary-icon.png b/client/public/themes/olympus/images/markers/temporary-icon.png deleted file mode 100644 index 712221a037440b8ec733699557345d0a48851823..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2538 zcmV%$WAf1p#$bTT!hGBHbX8|B!=xZUQ z8q%&thj$YhBu5?xu+Sbgde<5WxW*ot zK+w$&sK<{3Tw9B?lJOp5G9)1KP{zQ(zyXiP^Qt(Y_QM8w@BM1?^OD8+vS!sv87r{% zYgqdLbTQSEv4CWP!Qers*Z6U3n_9bRo64EDFie)MT4z2RM@tQ6*Jv=}5D}UOWcJ|g z{8k*WeDykMZTlqZv!|bWQfkhglCc7o`ia-;JwkT)YI;xP7*DJpb96^X$1FE)_TJfZ zG070EZU2*#6;(1;P#5ZCgb>yBq7tG>i;IhmDO0AD%g`<#6Sei1#Bt1r&SP9)s?X;; zE?V!9p~8_6?N_AV+uQqHe0)~M2~&I-QSToweOvs2F4^NI{B#r8&lHzfv$_z0|HYWknH08cdNJz#HLD7d-k%p=W~R6Wb-Q=(9`^(4A3KdB zZa5&Rr>Cb%jSx)D%T}$O$g~}X{{DVe>Io_$g%9R+oi)6bm6ciR*RTInMv0RZ?@Dva z4e3N&Gt!b7xgm)!YpmHr&Nm#*(r>v`UM_+qZ9T zi}z-(HMOX1-`=I>FIr)~{h$8)Rn_VDtMS0vjYAvrnX~5{$HVQuA)&-JXeBetS=NDg zGBPq&#Cj`D&DUk!=5G#u_Xh&zTW!96UCK(|8c`fXL#A)&_kMrCaeQiO>I<`H&#t_A z^JdVxXXSItLSAII`LQPW*(=3S?>9By7?+Ln^+N}x011LA+{xt#Y_u~$#x#U=&%O_t zge1;J+JxAM`K&qiGq+&Y`$y@YT#rvoO#G^7&w^0~=xHW1UB&XV2es0d<#Ph)&3*;- z9*iOT=44t3X7t6Hpa92#SXdJ0nOiU>i*|fpX5~I7>oygc@fi=AP?*cv33((=u}aX# zqivwy+wm<|KJNq;xplfOqTagI!ootMy1LpxhV!6A_s6mleVp0s zFW4)tVL@MJhIxP+4>Ck#0qgg7#T`#waq--`bt}9K0wEG(^*94X>Bnl4@IhUDSe0?C z^zFFgA3b_>4LWB-(lv*Wg#v+q6;vLSJx$0SPs=2LH60Iv+yeO7DK2sN^rxq%%Yz3G zL~}4$3(3lrE3L9Yb#-;M!S%!~*h8QKK5UBP(L)&qPy!kokJ)MNMZry4UvZrafo2sa&@WYHP;(&NZ z>UjNy@HrZWjXn8}yAtaD{rm5imzTFosLEC+PMk1ZjwJ*82mHbkJcy(aJbn7~n@$tP zD@1+1%wdY}eYsd(`_=1Vn`N{)+!nYE4GoplSLMZ7*xrbnVD%whqQZUdwcuwsZ*!M-3(ZNS(SEP?wl}}p?fV~{q?vsKsZ#WX=l0J47lAhxISB7Uw>GQ0Zid^#qnsG)Ya9o zeZ^kkGuqwKB}Q-2B1E@Kft&G=_Y`CvB>&2lD}PpF012G=*Eus*MvJRgufBznEFadf zk^yy05r-4PU~=Fli|Z^1PlbywU%q@yO%k{^bR`)0hsQgwWv^ z;_WP%3{slR637CC!B@}%rcTr?S;BiFajitZOhaS*3%GtsyB^Dor57$-DCz6#3#bVO z*QlwfDdCIMYtPfVP^UDBXkW#I(i^SidPtF368fKmT#MAMUAwk)c6R<(O%U$hy?c4* z&YeunOZA$$T8At*t`^NgqRp9G%6T#dgqGQc}`bTU*P` z+boVb48KDsptlEPP_{j?DgjEr9upIeeyE9gwBm`HM2ePV{hjwcnwVG5Yk-IW63V^~ z?uou<3f!t6BnNN};>z8>mx3434HvW%>6gf+{3r?881ou#UA3t-sQzOW+M-d^Nb}y5;5lh0fl=52zJxm;I;!G)8E?KYFRBPLvb>; z{~8$y)X<+`tTr-T%uE_+%`#!6W@l%!8qVNeCZP>6T}vv*i_@% diff --git a/client/src/controls/mapcontextmenu.ts b/client/src/controls/mapcontextmenu.ts index 1d51952c..1dd906ad 100644 --- a/client/src/controls/mapcontextmenu.ts +++ b/client/src/controls/mapcontextmenu.ts @@ -12,6 +12,7 @@ import { ftToM } from "../other/utils"; import { GAME_MASTER } from "../constants/constants"; import { navyUnitDatabase } from "../unit/navyunitdatabase"; import { CoalitionArea } from "../map/coalitionarea"; +import { SmokeMarker } from "../map/smokemarker"; export class MapContextMenu extends ContextMenu { #coalitionSwitch: Switch; @@ -158,6 +159,8 @@ export class MapContextMenu extends ContextMenu { document.addEventListener("contextMenuDeploySmoke", (e: any) => { this.hide(); spawnSmoke(e.detail.color, this.getLatLng()); + var marker = new SmokeMarker(this.getLatLng(), e.detail.color); + marker.addTo(getMap()); }); document.addEventListener("contextMenuExplosion", (e: any) => { diff --git a/client/src/map/smokemarker.ts b/client/src/map/smokemarker.ts new file mode 100644 index 00000000..678912c2 --- /dev/null +++ b/client/src/map/smokemarker.ts @@ -0,0 +1,31 @@ +import { DivIcon, LatLngExpression, MarkerOptions } from "leaflet"; +import { CustomMarker } from "./custommarker"; +import { SVGInjector } from "@tanem/svg-injector"; +import { getMap } from ".."; + +export class SmokeMarker extends CustomMarker { + #color: string; + + constructor(latlng: LatLngExpression, color: string, options?: MarkerOptions) { + super(latlng, options); + this.setZIndexOffset(9999); + this.#color = color; + window.setTimeout(() => { this.removeFrom(getMap()); }, 300000) /* Remove the smoke after 5 minutes */ + } + + createIcon() { + this.setIcon(new DivIcon({ + iconSize: [52, 52], + iconAnchor: [26, 52], + className: "leaflet-smoke-marker", + })); + var el = document.createElement("div"); + el.classList.add("ol-smoke-icon"); + el.setAttribute("data-color", this.#color); + var img = document.createElement("img"); + img.src = "/resources/theme/images/markers/smoke.svg"; + img.onload = () => SVGInjector(img); + el.appendChild(img); + this.getElement()?.appendChild(el); + } +} From 0ae694c1a8e3cc77ff698d17a88192cd3ddb0a0d Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Tue, 29 Aug 2023 14:59:23 +0200 Subject: [PATCH 6/6] Non visually detected units are now drawn with generic symbol --- client/demo.js | 2 +- client/src/unit/unit.ts | 45 +++++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/client/demo.js b/client/demo.js index d7f970df..6530f21b 100644 --- a/client/demo.js +++ b/client/demo.js @@ -15,7 +15,7 @@ const DEMO_UNIT_DATA = { radio: { frequency: 124000000, callsign: 1, callsignNumber: 1 }, generalSettings: { prohibitAA: false, prohibitAfterburner: false, prohibitAG: false, prohibitAirWpn: false, prohibitJettison: false }, ammo: [{ quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } ], - contacts: [{ID: 2, detectionMethod: 1}, {ID: 3, detectionMethod: 4}], + contacts: [{ID: 2, detectionMethod: 1}, {ID: 3, detectionMethod: 4}, {ID: 5, detectionMethod: 4}], activePath: [{lat: 38, lng: -115, alt: 0}, {lat: 38, lng: -114, alt: 0}] }, ["2"]:{ category: "Aircraft", alive: true, human: false, controlled: false, coalition: 1, country: 0, name: "FA-18C_hornet", unitName: "Cool guy 1-2", groupName: "Cool group 2", state: 1, task: "Being cool", diff --git a/client/src/unit/unit.ts b/client/src/unit/unit.ts index 8eccce12..badf719e 100644 --- a/client/src/unit/unit.ts +++ b/client/src/unit/unit.ts @@ -438,7 +438,15 @@ export class Unit extends CustomMarker { var unitIcon = document.createElement("div"); unitIcon.classList.add("unit-icon"); var img = document.createElement("img"); - img.src = `/resources/theme/images/units/${this.getMarkerCategory()}.svg`; + var imgSrc; + + /* If a unit does not belong to the commanded coalition or it is not visually detected, show it with the generic aircraft square */ + if (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC].includes(value))) + imgSrc = this.getMarkerCategory(); + else + imgSrc = "aircraft"; + + img.src = `/resources/theme/images/units/${imgSrc}.svg`; img.onload = () => SVGInjector(img); unitIcon.appendChild(img); unitIcon.toggleAttribute("data-rotate-to-heading", iconOptions.rotateToHeading); @@ -1090,16 +1098,17 @@ export class Unit extends CustomMarker { export class AirUnit extends Unit { getIconOptions() { + var belongsToCommandedCoalition = this.belongsToCommandedCoalition(); return { - showState: this.belongsToCommandedCoalition(), - showVvi: (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), - showHotgroup: this.belongsToCommandedCoalition(), - showUnitIcon: (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), - showShortLabel: (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC].includes(value))), - showFuel: this.belongsToCommandedCoalition(), - showAmmo: this.belongsToCommandedCoalition(), - showSummary: (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), - showCallsign: this.belongsToCommandedCoalition(), + showState: belongsToCommandedCoalition, + showVvi: (belongsToCommandedCoalition || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), + showHotgroup: belongsToCommandedCoalition, + showUnitIcon: (belongsToCommandedCoalition || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), + showShortLabel: (belongsToCommandedCoalition || this.getDetectionMethods().some(value => [VISUAL, OPTIC].includes(value))), + showFuel: belongsToCommandedCoalition, + showAmmo: belongsToCommandedCoalition, + showSummary: (belongsToCommandedCoalition || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), + showCallsign: belongsToCommandedCoalition, rotateToHeading: false }; } @@ -1131,16 +1140,17 @@ export class GroundUnit extends Unit { } getIconOptions() { + var belongsToCommandedCoalition = this.belongsToCommandedCoalition(); return { - showState: this.belongsToCommandedCoalition(), + showState: belongsToCommandedCoalition, showVvi: false, - showHotgroup: this.belongsToCommandedCoalition(), - showUnitIcon: (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), + showHotgroup: belongsToCommandedCoalition, + showUnitIcon: (belongsToCommandedCoalition || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), showShortLabel: false, showFuel: false, showAmmo: false, showSummary: false, - showCallsign: this.belongsToCommandedCoalition(), + showCallsign: belongsToCommandedCoalition, rotateToHeading: false }; } @@ -1161,16 +1171,17 @@ export class NavyUnit extends Unit { } getIconOptions() { + var belongsToCommandedCoalition = this.belongsToCommandedCoalition(); return { - showState: this.belongsToCommandedCoalition(), + showState: belongsToCommandedCoalition, showVvi: false, showHotgroup: true, - showUnitIcon: (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), + showUnitIcon: (belongsToCommandedCoalition || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))), showShortLabel: false, showFuel: false, showAmmo: false, showSummary: false, - showCallsign: this.belongsToCommandedCoalition(), + showCallsign: belongsToCommandedCoalition, rotateToHeading: false }; }