diff --git a/client/@types/olympus/index.d.ts b/client/@types/olympus/index.d.ts index f1215d76..95f77f6b 100644 --- a/client/@types/olympus/index.d.ts +++ b/client/@types/olympus/index.d.ts @@ -894,7 +894,7 @@ declare module "contextmenus/mapcontextmenu" { * @param y Y screen coordinate of the top left corner of the context menu * @param latlng Leaflet latlng object of the mouse click */ - show(x: number, y: number, latlng: LatLng): void; + show(x: number, y: number, latlng: LatLng): false | undefined; /** If the user rightclicked on a CoalitionArea, it will be given the ability to edit it. * * @param coalitionArea The CoalitionArea the user can edit diff --git a/client/plugins/databasemanager/index.js b/client/plugins/databasemanager/index.js index 432c8142..db4029ad 100644 --- a/client/plugins/databasemanager/index.js +++ b/client/plugins/databasemanager/index.js @@ -1043,8 +1043,7 @@ function arrayToString(array) { } exports.arrayToString = arrayToString; function stringToArray(input) { - var _a; - return (_a = input.match(/(\w)+/g)) !== null && _a !== void 0 ? _a : []; + return input.match(/(\w)+/g) || []; } exports.stringToArray = stringToArray; diff --git a/client/src/contextmenus/mapcontextmenu.ts b/client/src/contextmenus/mapcontextmenu.ts index 0f75a596..209a4cfb 100644 --- a/client/src/contextmenus/mapcontextmenu.ts +++ b/client/src/contextmenus/mapcontextmenu.ts @@ -4,7 +4,7 @@ import { ContextMenu } from "./contextmenu"; import { Switch } from "../controls/switch"; import { GAME_MASTER } from "../constants/constants"; import { CoalitionArea } from "../map/coalitionarea/coalitionarea"; -import { AircraftSpawnMenu, GroundUnitSpawnMenu, HelicopterSpawnMenu, NavyUnitSpawnMenu } from "../controls/unitspawnmenu"; +import { AirDefenceUnitSpawnMenu, AircraftSpawnMenu, GroundUnitSpawnMenu, HelicopterSpawnMenu, NavyUnitSpawnMenu } from "../controls/unitspawnmenu"; import { Airbase } from "../mission/airbase"; import { SmokeMarker } from "../map/markers/smokemarker"; @@ -15,6 +15,7 @@ export class MapContextMenu extends ContextMenu { #coalitionSwitch: Switch; #aircraftSpawnMenu: AircraftSpawnMenu; #helicopterSpawnMenu: HelicopterSpawnMenu; + #airDefenceUnitSpawnMenu: AirDefenceUnitSpawnMenu; #groundUnitSpawnMenu: GroundUnitSpawnMenu; #navyUnitSpawnMenu: NavyUnitSpawnMenu; #coalitionArea: CoalitionArea | null = null; @@ -35,6 +36,7 @@ export class MapContextMenu extends ContextMenu { /* Create the spawn menus for the different unit types */ this.#aircraftSpawnMenu = new AircraftSpawnMenu("aircraft-spawn-menu"); this.#helicopterSpawnMenu = new HelicopterSpawnMenu("helicopter-spawn-menu"); + this.#airDefenceUnitSpawnMenu = new AirDefenceUnitSpawnMenu("air-defence-spawn-menu"); this.#groundUnitSpawnMenu = new GroundUnitSpawnMenu("groundunit-spawn-menu"); this.#navyUnitSpawnMenu = new NavyUnitSpawnMenu("navyunit-spawn-menu"); @@ -73,21 +75,25 @@ export class MapContextMenu extends ContextMenu { this.#aircraftSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); this.#helicopterSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); + this.#airDefenceUnitSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); this.#groundUnitSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); this.#navyUnitSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); this.#aircraftSpawnMenu.getContainer().addEventListener("hide", () => this.hide()); this.#helicopterSpawnMenu.getContainer().addEventListener("hide", () => this.hide()); + this.#airDefenceUnitSpawnMenu.getContainer().addEventListener("hide", () => this.hide()); this.#groundUnitSpawnMenu.getContainer().addEventListener("hide", () => this.hide()); this.#navyUnitSpawnMenu.getContainer().addEventListener("hide", () => this.hide()); this.getContainer()?.addEventListener("show", () => this.#aircraftSpawnMenu.showCirclesPreviews()); this.getContainer()?.addEventListener("show", () => this.#helicopterSpawnMenu.showCirclesPreviews()); + this.getContainer()?.addEventListener("show", () => this.#airDefenceUnitSpawnMenu.showCirclesPreviews()); this.getContainer()?.addEventListener("show", () => this.#groundUnitSpawnMenu.showCirclesPreviews()); this.getContainer()?.addEventListener("show", () => this.#navyUnitSpawnMenu.showCirclesPreviews()); this.getContainer()?.addEventListener("hide", () => this.#aircraftSpawnMenu.clearCirclesPreviews()); this.getContainer()?.addEventListener("hide", () => this.#helicopterSpawnMenu.clearCirclesPreviews()); + this.getContainer()?.addEventListener("hide", () => this.#airDefenceUnitSpawnMenu.clearCirclesPreviews()); this.getContainer()?.addEventListener("hide", () => this.#groundUnitSpawnMenu.clearCirclesPreviews()); this.getContainer()?.addEventListener("hide", () => this.#navyUnitSpawnMenu.clearCirclesPreviews()); } @@ -106,11 +112,13 @@ export class MapContextMenu extends ContextMenu { this.#aircraftSpawnMenu.setLatLng(latlng); this.#helicopterSpawnMenu.setLatLng(latlng); + this.#airDefenceUnitSpawnMenu.setLatLng(latlng); this.#groundUnitSpawnMenu.setLatLng(latlng); this.#navyUnitSpawnMenu.setLatLng(latlng); this.#aircraftSpawnMenu.setCountries(); this.#helicopterSpawnMenu.setCountries(); + this.#airDefenceUnitSpawnMenu.setCountries(); this.#groundUnitSpawnMenu.setCountries(); this.#navyUnitSpawnMenu.setCountries(); @@ -146,7 +154,7 @@ export class MapContextMenu extends ContextMenu { #showSubMenu(type: string) { if (type === "more") this.getContainer()?.querySelector("#more-options-button-bar")?.classList.toggle("hide"); - else if (["aircraft", "helicopter", "groundunit"].includes(type)) + else if (["aircraft", "helicopter", "air-defence", "groundunit"].includes(type)) this.getContainer()?.querySelector("#more-options-button-bar")?.classList.toggle("hide", true); this.getContainer()?.querySelector("#aircraft-spawn-menu")?.classList.toggle("hide", type !== "aircraft"); @@ -155,6 +163,8 @@ export class MapContextMenu extends ContextMenu { this.getContainer()?.querySelector("#helicopter-spawn-button")?.classList.toggle("is-open", type === "helicopter"); this.getContainer()?.querySelector("#groundunit-spawn-menu")?.classList.toggle("hide", type !== "groundunit"); this.getContainer()?.querySelector("#groundunit-spawn-button")?.classList.toggle("is-open", type === "groundunit"); + this.getContainer()?.querySelector("#air-defence-spawn-menu")?.classList.toggle("hide", type !== "air-defence"); + this.getContainer()?.querySelector("#air-defence-spawn-button")?.classList.toggle("is-open", type === "air-defence"); this.getContainer()?.querySelector("#navyunit-spawn-menu")?.classList.toggle("hide", type !== "navyunit"); this.getContainer()?.querySelector("#navyunit-spawn-button")?.classList.toggle("is-open", type === "navyunit"); this.getContainer()?.querySelector("#smoke-spawn-menu")?.classList.toggle("hide", type !== "smoke"); @@ -170,6 +180,9 @@ export class MapContextMenu extends ContextMenu { this.#helicopterSpawnMenu.reset(); this.#helicopterSpawnMenu.setCountries(); this.#helicopterSpawnMenu.clearCirclesPreviews(); + this.#airDefenceUnitSpawnMenu.reset(); + this.#airDefenceUnitSpawnMenu.setCountries(); + this.#airDefenceUnitSpawnMenu.clearCirclesPreviews(); this.#groundUnitSpawnMenu.reset(); this.#groundUnitSpawnMenu.setCountries(); this.#groundUnitSpawnMenu.clearCirclesPreviews(); @@ -203,11 +216,13 @@ export class MapContextMenu extends ContextMenu { this.#aircraftSpawnMenu.reset(); this.#helicopterSpawnMenu.reset(); + this.#airDefenceUnitSpawnMenu.reset(); this.#groundUnitSpawnMenu.reset(); this.#navyUnitSpawnMenu.reset(); this.#aircraftSpawnMenu.clearCirclesPreviews(); this.#helicopterSpawnMenu.clearCirclesPreviews(); + this.#airDefenceUnitSpawnMenu.clearCirclesPreviews(); this.#groundUnitSpawnMenu.clearCirclesPreviews(); this.#navyUnitSpawnMenu.clearCirclesPreviews(); @@ -224,6 +239,7 @@ export class MapContextMenu extends ContextMenu { this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getApp().getActiveCoalition()) }); this.#aircraftSpawnMenu.setCountries(); this.#helicopterSpawnMenu.setCountries(); + this.#airDefenceUnitSpawnMenu.setCountries(); this.#groundUnitSpawnMenu.setCountries(); this.#navyUnitSpawnMenu.setCountries(); } @@ -237,6 +253,7 @@ export class MapContextMenu extends ContextMenu { this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getApp().getActiveCoalition()) }); this.#aircraftSpawnMenu.setCountries(); this.#helicopterSpawnMenu.setCountries(); + this.#airDefenceUnitSpawnMenu.setCountries(); this.#groundUnitSpawnMenu.setCountries(); this.#navyUnitSpawnMenu.setCountries(); } diff --git a/client/src/controls/unitspawnmenu.ts b/client/src/controls/unitspawnmenu.ts index 0ed023d1..b0ee3fd4 100644 --- a/client/src/controls/unitspawnmenu.ts +++ b/client/src/controls/unitspawnmenu.ts @@ -31,6 +31,7 @@ export class UnitSpawnMenu { #unitDatabase: UnitDatabase; #countryCodes: any; #orderByRole: boolean; + protected unitTypeFilter = (unit:any) => { return true; }; /* Controls */ #unitRoleTypeDropdown: Dropdown; @@ -258,7 +259,7 @@ export class UnitSpawnMenu { if (this.#orderByRole) this.#unitRoleTypeDropdown.setOptions(this.#unitDatabase.getRoles()); else - this.#unitRoleTypeDropdown.setOptions(this.#unitDatabase.getTypes()); + this.#unitRoleTypeDropdown.setOptions(this.#unitDatabase.getTypes(this.unitTypeFilter)); this.#unitLoadoutListEl.replaceChildren(); this.#unitLoadoutDropdown.reset(); @@ -585,6 +586,7 @@ export class HelicopterSpawnMenu extends UnitSpawnMenu { export class GroundUnitSpawnMenu extends UnitSpawnMenu { protected showRangeCircles: boolean = true; + protected unitTypeFilter = (unit:any) => {return !(/\bAAA|SAM\b/.test(unit.type) || /\bmanpad|stinger\b/i.test(unit.type))}; /** * @@ -623,6 +625,20 @@ export class GroundUnitSpawnMenu extends UnitSpawnMenu { } } +export class AirDefenceUnitSpawnMenu extends GroundUnitSpawnMenu { + + protected unitTypeFilter = (unit:any) => {return /\bAAA|SAM\b/.test(unit.type) || /\bmanpad|stinger\b/i.test(unit.type)}; + + /** + * + * @param ID - the ID of the HTML element which will contain the context menu + */ + constructor(ID: string){ + super(ID); + this.setMaxUnitCount(4); + } +} + export class NavyUnitSpawnMenu extends UnitSpawnMenu { /** * diff --git a/client/src/unit/databases/unitdatabase.ts b/client/src/unit/databases/unitdatabase.ts index ba7c41cc..94c8acca 100644 --- a/client/src/unit/databases/unitdatabase.ts +++ b/client/src/unit/databases/unitdatabase.ts @@ -94,10 +94,12 @@ export class UnitDatabase { } /* Returns a list of all possible types in a database */ - getTypes() { + getTypes(unitFilter?:CallableFunction) { var filteredBlueprints = this.getBlueprints(); var types: string[] = []; for (let unit in filteredBlueprints) { + if ( typeof unitFilter === "function" && !unitFilter(filteredBlueprints[unit])) + continue; var type = filteredBlueprints[unit].type; if (type && type !== "" && !types.includes(type)) types.push(type); diff --git a/client/views/contextmenus/map.ejs b/client/views/contextmenus/map.ejs index 75533346..ae4de75d 100644 --- a/client/views/contextmenus/map.ejs +++ b/client/views/contextmenus/map.ejs @@ -6,6 +6,8 @@ data-on-click-params='{ "type": "aircraft" }' class="ol-contexmenu-button"> +