diff --git a/client/public/stylesheets/other/contextmenus.css b/client/public/stylesheets/other/contextmenus.css index b6a39d96..f1f0df53 100644 --- a/client/public/stylesheets/other/contextmenus.css +++ b/client/public/stylesheets/other/contextmenus.css @@ -53,6 +53,7 @@ width: 100%; margin: 5px; column-gap: 5px; + cursor: pointer; } .contextmenu-advanced-options-toggle:after { @@ -69,10 +70,7 @@ width: 100%; } -#aircraft-spawn-menu, -#helicopter-spawn-menu, -#groundunit-spawn-menu, -#navyunit-spawn-menu { +.unit-spawn-menu { height: fit-content; } @@ -95,18 +93,15 @@ width: 50px; } -#aircraft-spawn-menu .ol-select.is-open .ol-select-options, -#helicopter-spawn-menu .ol-select.is-open .ol-select-options { +.unit-spawn-menu .ol-select.is-open .ol-select-options { max-height: 300px; } -#aircraft-loadout-list, -#helicopter-loadout-list { +.unit-loadout-list { min-width: 0; } -#aircraft-loadout-list div, -#helicopter-loadout-list div { +.unit-loadout-list div { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -114,8 +109,7 @@ padding: 2px 5px 2px 5px; } -#aircraft-loadout-list div:hover, -#helicopter-loadout-list div:hover { +.unit-loadout-list div:hover { overflow: visible; white-space: nowrap; background-color: var(--background-steel); @@ -197,6 +191,22 @@ content: "Create neutral unit"; } +.unit-label-count-container { + display: flex; + flex-direction: row; + align-items: center; + column-gap: 5px; +} + +.unit-label-count-container>div:nth-child(1) { + width: 100%; + min-width: 0; +} + +.unit-label-count-container>div:nth-child(2) { + font-size: large; +} + .unit-loadout-preview { align-content: space-between; align-items: center; diff --git a/client/public/stylesheets/style/style.css b/client/public/stylesheets/style/style.css index 16bbd7a6..9158683a 100644 --- a/client/public/stylesheets/style/style.css +++ b/client/public/stylesheets/style/style.css @@ -175,8 +175,8 @@ form>div { padding-left: 20px; padding-right: 30px; text-overflow: ellipsis; - - width: calc(100%); + max-width: initial; + width: 100%; } .ol-select.narrow:not(.ol-select-image)>.ol-select-value { diff --git a/client/src/@types/unitdatabase.d.ts b/client/src/@types/unitdatabase.d.ts index 7eb8328d..08c9efbd 100644 --- a/client/src/@types/unitdatabase.d.ts +++ b/client/src/@types/unitdatabase.d.ts @@ -1,3 +1,6 @@ +import { LatLng } from "leaflet"; +import { Airbase } from "../mission/airbase"; + interface LoadoutItemBlueprint { name: string; quantity: number; @@ -25,3 +28,16 @@ interface UnitBlueprint { liveries?: {[key: string]: {name: string, countries: string[]}}; cost?: number; } + +interface UnitSpawnOptions { + roleType: string; + name: string; + latlng: LatLng; + coalition: string; + count: number; + country: string; + loadout: LoadoutBlueprint | undefined; + airbase: Airbase | undefined; + liveryID: string | undefined; + altitude: number | undefined; +} diff --git a/client/src/controls/airbasecontextmenu.ts b/client/src/controls/airbasecontextmenu.ts index 0d00d17d..4a73e655 100644 --- a/client/src/controls/airbasecontextmenu.ts +++ b/client/src/controls/airbasecontextmenu.ts @@ -76,7 +76,7 @@ export class AirbaseContextMenu extends ContextMenu { getMap().getMapContextMenu().hideLowerBar(); getMap().getMapContextMenu().hideAltitudeSlider(); getMap().getMapContextMenu().showSubMenu("aircraft"); - getMap().getMapContextMenu().setAirbaseName(this.#airbase.getName()); + getMap().getMapContextMenu().setAirbase(this.#airbase); getMap().getMapContextMenu().setLatLng(this.#airbase.getLatLng()); } } diff --git a/client/src/controls/mapcontextmenu.ts b/client/src/controls/mapcontextmenu.ts index 92ec77ac..a8c46b03 100644 --- a/client/src/controls/mapcontextmenu.ts +++ b/client/src/controls/mapcontextmenu.ts @@ -13,10 +13,14 @@ import { GAME_MASTER } from "../constants/constants"; import { navyUnitDatabase } from "../unit/navyunitdatabase"; import { CoalitionArea } from "../map/coalitionarea"; import { UnitSpawnMenu } from "./unitspawnmenu"; +import { Airbase } from "../mission/airbase"; export class MapContextMenu extends ContextMenu { #coalitionSwitch: Switch; #aircraftSpawnMenu: UnitSpawnMenu; + #helicopterSpawnMenu: UnitSpawnMenu; + #groundUnitSpawnMenu: UnitSpawnMenu; + #navyUnitSpawnMenu: UnitSpawnMenu; #coalitionArea: CoalitionArea | null = null; @@ -28,6 +32,9 @@ export class MapContextMenu extends ContextMenu { this.#coalitionSwitch.getContainer()?.addEventListener("contextmenu", (e) => this.#onSwitchRightClick(e)); this.#aircraftSpawnMenu = new UnitSpawnMenu("aircraft-spawn-menu", aircraftDatabase); + this.#helicopterSpawnMenu = new UnitSpawnMenu("helicopter-spawn-menu", helicopterDatabase); + this.#groundUnitSpawnMenu = new UnitSpawnMenu("groundunit-spawn-menu", groundUnitDatabase, {orderByRole: false, maxUnitCount: 20, showLoadout: false, showAltitudeSlider: false}); + this.#navyUnitSpawnMenu = new UnitSpawnMenu("navyunit-spawn-menu", navyUnitDatabase, {orderByRole: false, maxUnitCount: 4, showLoadout: false, showAltitudeSlider: false}); document.addEventListener("mapContextMenuShow", (e: any) => { if (this.getVisibleSubMenu() !== e.detail.type) @@ -36,22 +43,6 @@ export class MapContextMenu extends ContextMenu { this.hideSubMenus(e.detail.type); }); - document.addEventListener("contextMenuDeployAircrafts", () => { - - }); - - document.addEventListener("contextMenuDeployHelicopters", () => { - - }); - - document.addEventListener("contextMenuDeployGroundUnits", () => { - - }); - - document.addEventListener("contextMenuDeployNavyUnits", () => { - - }); - document.addEventListener("contextMenuDeploySmoke", (e: any) => { this.hide(); spawnSmoke(e.detail.color, this.getLatLng()); @@ -82,7 +73,11 @@ export class MapContextMenu extends ContextMenu { this.clip(); }); - + this.#aircraftSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); + this.#helicopterSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); + this.#groundUnitSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); + this.#navyUnitSpawnMenu.getContainer().addEventListener("resize", () => this.clip()); + this.hide(); } @@ -92,8 +87,12 @@ export class MapContextMenu extends ContextMenu { this.showAltitudeSlider(); - //this.#spawnOptions.airbaseName = ""; - //this.#spawnOptions.latlng = latlng; + this.#aircraftSpawnMenu.setAirbase(undefined); + this.#aircraftSpawnMenu.setLatLng(latlng); + this.#helicopterSpawnMenu.setAirbase(undefined); + this.#helicopterSpawnMenu.setLatLng(latlng); + this.#groundUnitSpawnMenu.setLatLng(latlng); + this.#navyUnitSpawnMenu.setLatLng(latlng); this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) }); if (getActiveCoalition() == "blue") @@ -108,7 +107,10 @@ export class MapContextMenu extends ContextMenu { this.getContainer()?.querySelector("#coalition-area-button")?.classList.toggle("hide", true); - //this.#setCountries(); + this.#aircraftSpawnMenu.setCountries(); + this.#helicopterSpawnMenu.setCountries(); + this.#groundUnitSpawnMenu.setCountries(); + this.#navyUnitSpawnMenu.setCountries(); } showSubMenu(type: string) { @@ -132,20 +134,17 @@ export class MapContextMenu extends ContextMenu { (this.getContainer()?.querySelectorAll(".deploy-unit-button"))?.forEach((element: Node) => {(element as HTMLButtonElement).disabled = true;}) - this.#aircraftSpawnMenu.resetUnitRole(); - this.#aircraftSpawnMenu.resetUnitLabel(); + this.#aircraftSpawnMenu.reset(); this.#aircraftSpawnMenu.setCountries(); - - this.clip(); - - //if (type === "aircraft") { - // this.#spawnOptions.altitude = ftToM(this.#aircraftSpawnAltitudeSlider.getValue()); - //} - //else if (type === "helicopter") { - // this.#spawnOptions.altitude = ftToM(this.#helicopterSpawnAltitudeSlider.getValue()); - //} - + this.#helicopterSpawnMenu.reset(); + this.#helicopterSpawnMenu.setCountries(); + this.#groundUnitSpawnMenu.reset(); + this.#groundUnitSpawnMenu.setCountries(); + this.#navyUnitSpawnMenu.reset(); + this.#navyUnitSpawnMenu.setCountries(); + this.setVisibleSubMenu(type); + this.clip(); } hideSubMenus(type: string) { @@ -163,12 +162,13 @@ export class MapContextMenu extends ContextMenu { this.getContainer()?.querySelector("#explosion-menu")?.classList.toggle("hide", true); this.getContainer()?.querySelector("#explosion-spawn-button")?.classList.toggle("is-open", false); - this.#aircraftSpawnMenu.resetUnitRole(); - this.#aircraftSpawnMenu.resetUnitLabel(); - - this.clip(); + this.#aircraftSpawnMenu.reset(); + this.#helicopterSpawnMenu.reset(); + this.#groundUnitSpawnMenu.reset(); + this.#navyUnitSpawnMenu.reset(); this.setVisibleSubMenu(null); + this.clip(); } showUpperBar() { @@ -195,12 +195,16 @@ export class MapContextMenu extends ContextMenu { this.getContainer()?.querySelector("#aircraft-spawn-altitude-slider")?.classList.toggle("hide", true); } - setAirbaseName(airbaseName: string) { - //this.#spawnOptions.airbaseName = airbaseName; + setAirbase(airbase: Airbase) { + this.#aircraftSpawnMenu.setAirbase(airbase); + this.#helicopterSpawnMenu.setAirbase(airbase); } setLatLng(latlng: LatLng) { - //this.#spawnOptions.latlng = latlng; + this.#aircraftSpawnMenu.setLatLng(latlng); + this.#helicopterSpawnMenu.setLatLng(latlng); + this.#groundUnitSpawnMenu.setLatLng(latlng); + this.#navyUnitSpawnMenu.setLatLng(latlng); } setCoalitionArea(coalitionArea: CoalitionArea) { @@ -211,13 +215,19 @@ export class MapContextMenu extends ContextMenu { #onSwitchClick(value: boolean) { value? setActiveCoalition("red"): setActiveCoalition("blue"); this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) }); - //this.#setCountries(); + this.#aircraftSpawnMenu.setCountries(); + this.#helicopterSpawnMenu.setCountries(); + this.#groundUnitSpawnMenu.setCountries(); + this.#navyUnitSpawnMenu.setCountries(); } #onSwitchRightClick(e: any) { this.#coalitionSwitch.setValue(undefined); setActiveCoalition("neutral"); this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) }); - //this.#setCountries(); + this.#aircraftSpawnMenu.setCountries(); + this.#helicopterSpawnMenu.setCountries(); + this.#groundUnitSpawnMenu.setCountries(); + this.#navyUnitSpawnMenu.setCountries(); } } \ No newline at end of file diff --git a/client/src/controls/unitspawnmenu.ts b/client/src/controls/unitspawnmenu.ts index 07930ef2..47da87f3 100644 --- a/client/src/controls/unitspawnmenu.ts +++ b/client/src/controls/unitspawnmenu.ts @@ -4,63 +4,92 @@ import { Slider } from "./slider"; import { UnitDatabase } from "../unit/unitdatabase"; import { getActiveCoalition, getMap, getMissionHandler, getUnitsManager } from ".."; import { GAME_MASTER } from "../constants/constants"; +import { UnitSpawnOptions } from "../@types/unitdatabase"; +import { Airbase } from "../mission/airbase"; export class UnitSpawnMenu { - #unitRoleDropdown: Dropdown; + #unitRoleTypeDropdown: Dropdown; #unitLabelDropdown: Dropdown; #unitCountDropdown: Dropdown; - #unitLoadoutDropdown: Dropdown; + #unitLoadoutDropdown: Dropdown | null = null; #unitCountryDropdown: Dropdown; #unitLiveryDropdown: Dropdown; //#unitSpawnAltitudeSlider: Slider; - #unitRoleDropdownEl: HTMLDivElement; - #unitTypeDropdownEl: HTMLDivElement; - #unitLoadoutDropdownEl: HTMLDivElement; + #unitRoleTypeDropdownEl: HTMLDivElement; + #unitLabelDropdownEl: HTMLDivElement; + #unitLoadoutDropdownEl: HTMLDivElement | null = null; #unitCountDropdownEl: HTMLDivElement; #unitCountryDropdownEl: HTMLDivElement; #unitLiveryDropdownEl: HTMLDivElement; #deployUnitButtonEl: HTMLButtonElement; - #unitLoadoutPreview: HTMLDivElement; - #unitImage: HTMLImageElement; - #unitLoadoutList: HTMLDivElement; + #unitLoadoutPreviewEl: HTMLDivElement | null = null; + #unitImageEl: HTMLImageElement | null = null; + #unitLoadoutListEl: HTMLDivElement | null = null; #container: HTMLElement; - #spawnOptions = { role: "", name: "", latlng: new LatLng(0, 0), coalition: "blue", loadout: "", airbaseName: "", liveryID: "", altitude: 0, count: 1, country: "" }; + #options = {orderByRole: true, maxUnitCount: 4, showLoadout: true, showAltitudeSlider: true}; + #spawnOptions: UnitSpawnOptions = { roleType: "", name: "", latlng: new LatLng(0, 0), coalition: "blue", count: 1, country: "", loadout: undefined, airbase: undefined, liveryID: undefined, altitude: undefined }; #unitDatabase: UnitDatabase; #countryCodes: any; - constructor(id: string, unitDatabase: UnitDatabase, options?: {maxUnitCount: number, showLoadout: boolean}) { + constructor(id: string, unitDatabase: UnitDatabase, options?: {orderByRole: boolean, maxUnitCount: number, showLoadout: boolean, showAltitudeSlider: boolean}) { this.#container = document.getElementById(id) as HTMLElement; this.#unitDatabase = unitDatabase; - this.#unitRoleDropdownEl = this.#addDropdown("Unit role"); - this.#unitTypeDropdownEl = this.#addDropdown("Unit type"); - this.#unitLoadoutDropdownEl = this.#addDropdown("Unit loadout"); + if (options !== undefined) + this.#options = options; + + /* Create the HTML elements for the dropdowns */ + if (this.#options.orderByRole) + this.#unitRoleTypeDropdownEl = this.#addDropdown("Unit role"); + else + this.#unitRoleTypeDropdownEl = this.#addDropdown("Unit type"); + this.#unitLabelDropdownEl = this.#addDropdown("Unit label"); + if (this.#options.showLoadout) + this.#unitLoadoutDropdownEl = this.#addDropdown("Unit loadout"); this.#unitCountDropdownEl = this.#addDropdown("Unit count"); this.#unitCountryDropdownEl = this.#addDropdown("Unit country"); this.#unitLiveryDropdownEl = this.#addDropdown("Unit livery"); - this.#unitRoleDropdown = new Dropdown(this.#unitRoleDropdownEl, (role: string) => this.#setUnitRole(role)); - this.#unitLabelDropdown = new Dropdown(this.#unitTypeDropdownEl, (type: string) => this.#setUnitLabel(type)); - this.#unitLoadoutDropdown = new Dropdown(this.#unitLoadoutDropdownEl, (loadout: string) => this.#setUnitLoadout(loadout)); + var unitLabelCountContainerEl = document.createElement("div"); + unitLabelCountContainerEl.classList.add("unit-label-count-container"); + var divider = document.createElement("div"); + divider.innerText = "x"; + unitLabelCountContainerEl.append(this.#unitLabelDropdownEl, divider, this.#unitCountDropdownEl); + + /* Create the dropdowns and the altitude slider */ + this.#unitRoleTypeDropdown = new Dropdown(this.#unitRoleTypeDropdownEl, (roleType: string) => this.#setUnitRoleType(roleType)); + this.#unitLabelDropdown = new Dropdown(this.#unitLabelDropdownEl, (label: string) => this.#setUnitLabel(label)); + if (this.#unitLoadoutDropdownEl !== null) + this.#unitLoadoutDropdown = new Dropdown(this.#unitLoadoutDropdownEl, (loadout: string) => this.#setUnitLoadout(loadout)); this.#unitCountDropdown = new Dropdown(this.#unitCountDropdownEl, (count: string) => this.#setUnitCount(count)); - this.#unitCountDropdown.setOptions(["1", "2", "3", "4"]); this.#unitCountryDropdown = new Dropdown(this.#unitCountryDropdownEl, () => { /* Custom button implementation */ }); this.#unitLiveryDropdown = new Dropdown(this.#unitLiveryDropdownEl, (livery: string) => this.#setUnitLivery(livery)); //this.#unitSpawnAltitudeSlider = new Slider("unit-spawn-altitude-slider", 0, 50000, "ft", (value: number) => {this.#spawnOptions.altitude = ftToM(value);}); + + var countOptions: string[] = []; + for (let i = 1; i <= this.#options.maxUnitCount; i++) + countOptions.push(i.toString()); + this.#unitCountDropdown.setOptions(countOptions); + this.#unitCountDropdown.selectValue(0); + //this.#unitSpawnAltitudeSlider.setIncrement(500); //this.#unitSpawnAltitudeSlider.setValue(20000); //this.#unitSpawnAltitudeSlider.setActive(true); - this.#unitLoadoutPreview = document.createElement("div"); - this.#unitLoadoutPreview.classList.add("unit-loadout-preview"); - this.#unitImage = document.createElement("img"); - this.#unitImage.classList.add("unit-image", "hide"); - this.#unitLoadoutList = document.createElement("div"); - this.#unitLoadoutList.classList.add("unit-loadout-list"); - this.#unitLoadoutPreview.append(this.#unitImage, this.#unitLoadoutList); + /* Create the unit image and loadout elements */ + if (this.#options.showLoadout) { + this.#unitLoadoutPreviewEl = document.createElement("div"); + this.#unitLoadoutPreviewEl.classList.add("unit-loadout-preview"); + this.#unitImageEl = document.createElement("img"); + this.#unitImageEl.classList.add("unit-image", "hide"); + this.#unitLoadoutListEl = document.createElement("div"); + this.#unitLoadoutListEl.classList.add("unit-loadout-list"); + this.#unitLoadoutPreviewEl.append(this.#unitImageEl, this.#unitLoadoutListEl); + } + /* Create the divider and the advanced options collapsible div */ var advancedOptionsDiv = document.createElement("div"); advancedOptionsDiv.classList.add("contextmenu-advanced-options", "hide"); var advancedOptionsToggle = document.createElement("div"); @@ -70,8 +99,11 @@ export class UnitSpawnMenu { var advancedOptionsHr = document.createElement("hr"); advancedOptionsToggle.append(advancedOptionsText, advancedOptionsHr); advancedOptionsToggle.addEventListener("click", () => {advancedOptionsDiv.classList.toggle("hide")}); - advancedOptionsDiv.append(this.#unitCountryDropdownEl, this.#unitLiveryDropdownEl, this.#unitLoadoutPreview); + advancedOptionsDiv.append(this.#unitCountryDropdownEl, this.#unitLiveryDropdownEl); + if (this.#unitLoadoutPreviewEl !== null) + advancedOptionsDiv.append(this.#unitLoadoutPreviewEl) + /* Create the unit deploy button */ this.#deployUnitButtonEl = document.createElement("button"); this.#deployUnitButtonEl.classList.add("deploy-unit-button"); this.#deployUnitButtonEl.disabled = true; @@ -79,8 +111,11 @@ export class UnitSpawnMenu { this.#deployUnitButtonEl.setAttribute("data-coalition", "blue"); this.#deployUnitButtonEl.addEventListener("click", () => { this.#deployUnits(); }); - this.#container.append(this.#unitRoleDropdownEl, this.#unitTypeDropdownEl, this.#unitLoadoutDropdownEl, this.#unitCountDropdownEl, - advancedOptionsToggle, advancedOptionsDiv, this.#deployUnitButtonEl); + /* Assemble all components */ + this.#container.append(this.#unitRoleTypeDropdownEl, unitLabelCountContainerEl) + if (this.#unitLoadoutDropdownEl !== null) + this.#container.append(this.#unitLoadoutDropdownEl) + this.#container.append(advancedOptionsToggle, advancedOptionsDiv, this.#deployUnitButtonEl); /* Load the country codes from the public folder */ var xhr = new XMLHttpRequest(); @@ -95,6 +130,158 @@ export class UnitSpawnMenu { } }; xhr.send(); + + this.#container.addEventListener("unitRoleTypeChanged", () => { + this.#unitLabelDropdown.reset(); + if (this.#unitLoadoutListEl !== null) + this.#unitLoadoutListEl.replaceChildren(); + if (this.#unitLoadoutDropdown !== null) + this.#unitLoadoutDropdown.reset(); + if (this.#unitImageEl !== null) + this.#unitImageEl.classList.toggle("hide", true); + this.#unitLiveryDropdown.reset(); + + if (this.#options.orderByRole) + this.#unitLabelDropdown.setOptions(this.#unitDatabase.getByRole(this.#spawnOptions.roleType).map((blueprint) => { return blueprint.label })); + else + this.#unitLabelDropdown.setOptions(this.#unitDatabase.getByType(this.#spawnOptions.roleType).map((blueprint) => { return blueprint.label })); + this.#container.dispatchEvent(new Event("resize")); + this.#computeSpawnPoints(); + }) + + this.#container.addEventListener("unitLabelChanged", () => { + if (this.#unitLoadoutDropdown !== null) { + this.#unitLoadoutDropdown.setOptions(this.#unitDatabase.getLoadoutNamesByRole(this.#spawnOptions.name, this.#spawnOptions.roleType)); + this.#unitLoadoutDropdown.selectValue(0); + } + if (this.#unitImageEl !== null) { + this.#unitImageEl.src = `images/units/${this.#unitDatabase.getByName(this.#spawnOptions.name)?.filename}`; + this.#unitImageEl.classList.toggle("hide", false); + } + this.#setUnitLiveryOptions(); + + this.#container.dispatchEvent(new Event("resize")); + this.#computeSpawnPoints(); + }) + + this.#container.addEventListener("unitLoadoutChanged", () => { + this.#deployUnitButtonEl.disabled = false; + var items = this.#spawnOptions.loadout?.items.map((item: any) => { return `${item.quantity}x ${item.name}`; }); + if (items != undefined && this.#unitLoadoutListEl !== null) { + items.length == 0 ? items.push("Empty loadout") : ""; + this.#unitLoadoutListEl.replaceChildren( + ...items.map((item: any) => { + var div = document.createElement('div'); + div.innerText = item; + return div; + }) + ); + } + + this.#container.dispatchEvent(new Event("resize")); + }) + + this.#container.addEventListener("unitCountChanged", () => { + this.#computeSpawnPoints(); + }) + + this.#container.addEventListener("unitCountryChanged", () => { + this.#setUnitLiveryOptions(); + }) + + this.#container.addEventListener("unitLiveryChanged", () => { + + }) + } + + getContainer() { + return this.#container; + } + + reset() { + this.#deployUnitButtonEl.disabled = true; + this.#unitRoleTypeDropdown.reset(); + this.#unitLabelDropdown.reset(); + this.#unitLiveryDropdown.reset(); + if (this.#options.orderByRole) + this.#unitRoleTypeDropdown.setOptions(this.#unitDatabase.getRoles()); + else + this.#unitRoleTypeDropdown.setOptions(this.#unitDatabase.getTypes()); + + if (this.#unitLoadoutListEl !== null) + this.#unitLoadoutListEl.replaceChildren(); + if (this.#unitLoadoutDropdown !== null) + this.#unitLoadoutDropdown.reset(); + if (this.#unitImageEl !== null) + this.#unitImageEl.classList.toggle("hide", true); + + this.setCountries(); + this.#container.dispatchEvent(new Event("resize")); + } + + setCountries() { + var coalitions = getMissionHandler().getCoalitions(); + var countries = Object.values(coalitions[getActiveCoalition() as keyof typeof coalitions]); + this.#unitCountryDropdown.setOptionsElements(this.#createCountryButtons(this.#unitCountryDropdown, countries, (country: string) => {this.#setUnitCountry(country)})); + + if (countries.length > 0 && !countries.includes(this.#spawnOptions.country)) { + this.#unitCountryDropdown.forceValue(countries[0]); + this.#setUnitCountry(countries[0]); + } + } + + refreshOptions() { + //if (!this.#unitDatabase.getTypes().includes(this.#unitTypeDropdown.getValue())) + // this.reset(); + //if (!this.#unitDatabase.getByType(this.#unitTypeDropdown.getValue()).map((blueprint) => { return blueprint.label }).includes(this.#unitLabelDropdown.getValue())) + // this.resetUnitLabel(); + } + + setAirbase(airbase: Airbase | undefined) { + this.#spawnOptions.airbase = airbase; + } + + setLatLng(latlng: LatLng) { + this.#spawnOptions.latlng = latlng; + } + + #setUnitRoleType(roleType: string) { + this.#spawnOptions.roleType = roleType; + this.#container.dispatchEvent(new Event("unitRoleTypeChanged")); + } + + #setUnitLabel(label: string) { + var name = this.#unitDatabase.getByLabel(label)?.name || null; + if (name != null) + this.#spawnOptions.name = name; + this.#container.dispatchEvent(new Event("unitLabelChanged")); + } + + #setUnitLoadout(loadoutName: string) { + var loadout = this.#unitDatabase.getLoadoutByName(this.#spawnOptions.name, loadoutName); + if (loadout) + this.#spawnOptions.loadout = loadout; + this.#container.dispatchEvent(new Event("unitLoadoutChanged")); + } + + #setUnitCount(count: string) { + this.#spawnOptions.count = parseInt(count); + this.#container.dispatchEvent(new Event("unitCountChanged")); + } + + #setUnitCountry(country: string) { + this.#spawnOptions.country = country; + this.#container.dispatchEvent(new Event("unitCountryChanged")); + } + + #setUnitLivery(liveryName: string) { + var liveries = this.#unitDatabase.getByName(this.#spawnOptions.name)?.liveries; + if (liveries !== undefined) { + for (let liveryID in liveries) + if (liveries[liveryID].name === liveryName) + this.#spawnOptions.liveryID = liveryID; + } + this.#container.dispatchEvent(new Event("unitLiveryChanged")); } #addDropdown(defaultText: string) { @@ -112,89 +299,6 @@ export class UnitSpawnMenu { return div; } - ///********* Unit spawn menu *********/ - #setUnitRole(role: string) { - this.#spawnOptions.role = role; - this.resetUnitLabel(); - this.#unitLabelDropdown.setOptions(this.#unitDatabase.getByRole(role).map((blueprint) => { return blueprint.label })); - this.#unitLabelDropdown.selectValue(0); - this.#container.dispatchEvent(new Event("resize")); - this.#computeSpawnPoints(); - } - - resetUnitRole() { - this.#deployUnitButtonEl.disabled = true; - //(this.getContainer()?.querySelector("#unit-loadout-list")).replaceChildren(); - this.#unitRoleDropdown.reset(); - this.#unitLabelDropdown.reset(); - this.#unitRoleDropdown.setOptions(this.#unitDatabase.getRoles()); - this.#container.dispatchEvent(new Event("resize")); - } - - #setUnitLabel(label: string) { - this.resetUnitLabel(); - var name = this.#unitDatabase.getByLabel(label)?.name || null; - if (name != null) { - this.#spawnOptions.name = name; - this.#unitLoadoutDropdown.setOptions(this.#unitDatabase.getLoadoutNamesByRole(name, this.#spawnOptions.role)); - this.#unitLoadoutDropdown.selectValue(0); - //var image = (this.getContainer()?.querySelector("#unit-unit-image")); - //image.src = `images/units/${this.#unitDatabase.getByLabel(label)?.filename}`; - //image.classList.toggle("hide", false); - this.#setUnitLiveryOptions(); - } - this.#container.dispatchEvent(new Event("resize")); - this.#computeSpawnPoints(); - } - - resetUnitLabel() { - this.#deployUnitButtonEl.disabled = true; - // //(this.getContainer()?.querySelector("#unit-loadout-list")).replaceChildren(); - this.#unitLoadoutDropdown.reset(); - this.#unitLiveryDropdown.reset(); - //(this.getContainer()?.querySelector("#unit-unit-image")).classList.toggle("hide", true); - this.#container.dispatchEvent(new Event("resize")); - } - - #setUnitCount(count: string) { - this.#spawnOptions.count = parseInt(count); - this.#container.dispatchEvent(new Event("resize")); - this.#computeSpawnPoints(); - } - - #setUnitLoadout(loadoutName: string) { - var loadout = this.#unitDatabase.getLoadoutByName(this.#spawnOptions.name, loadoutName); - if (loadout) { - this.#spawnOptions.loadout = loadout.code; - this.#deployUnitButtonEl.disabled = false; - var items = loadout.items.map((item: any) => { return `${item.quantity}x ${item.name}`; }); - items.length == 0 ? items.push("Empty loadout") : ""; - //(this.getContainer()?.querySelector("#unit-loadout-list")).replaceChildren( - // ...items.map((item: any) => { - // var div = document.createElement('div'); - // div.innerText = item; - // return div; - // }) - //) - } - this.#container.dispatchEvent(new Event("resize")); - } - - #setUnitLivery(liveryName: string) { - var liveries = this.#unitDatabase.getByName(this.#spawnOptions.name)?.liveries; - if (liveries !== undefined) { - for (let liveryID in liveries) - if (liveries[liveryID].name === liveryName) - this.#spawnOptions.liveryID = liveryID; - } - this.#container.dispatchEvent(new Event("resize")); - } - - #setUnitCountry(country: string) { - this.#spawnOptions.country = country; - this.#setUnitLiveryOptions(); - } - #setUnitLiveryOptions() { if (this.#spawnOptions.name !== "" && this.#spawnOptions.country !== "") { var liveries = this.#unitDatabase.getLiveryNamesByName(this.#spawnOptions.name); @@ -223,24 +327,13 @@ export class UnitSpawnMenu { for (let i = 1; i < parseInt(this.#unitCountDropdown.getValue()) + 1; i++) { units.push(unitTable); } - if (getUnitsManager().spawnUnits("Unit", units, getActiveCoalition(), false, this.#spawnOptions.airbaseName, this.#spawnOptions.country)) { + if (getUnitsManager().spawnUnits("Unit", units, getActiveCoalition(), false, this.#spawnOptions.airbase? this.#spawnOptions.airbase.getName(): "", this.#spawnOptions.country)) { getMap().addTemporaryMarker(this.#spawnOptions.latlng, this.#spawnOptions.name, getActiveCoalition()); getMap().getMapContextMenu().hide(); } } } - setCountries() { - var coalitions = getMissionHandler().getCoalitions(); - var countries = Object.values(coalitions[getActiveCoalition() as keyof typeof coalitions]); - this.#unitCountryDropdown.setOptionsElements(this.#createCountryButtons(this.#unitCountryDropdown, countries, (country: string) => {this.#setUnitCountry(country)})); - - if (countries.length > 0 && !countries.includes(this.#spawnOptions.country)) { - this.#unitCountryDropdown.forceValue(countries[0]); - this.#setUnitCountry(countries[0]); - } - } - #createCountryButtons(parent: Dropdown, countries: string[], callback: CallableFunction) { return Object.values(countries).map((country: string) => { var el = document.createElement("div"); @@ -285,11 +378,4 @@ export class UnitSpawnMenu { this.#deployUnitButtonEl.disabled = unitSpawnPoints >= getMissionHandler().getAvailableSpawnPoints(); } } - - refreshOptions() { - if (!this.#unitDatabase.getRoles().includes(this.#unitRoleDropdown.getValue())) - this.resetUnitRole(); - if (!this.#unitDatabase.getByRole(this.#unitRoleDropdown.getValue()).map((blueprint) => { return blueprint.label }).includes(this.#unitLabelDropdown.getValue())) - this.resetUnitLabel(); - } } \ No newline at end of file diff --git a/client/src/other/utils.ts b/client/src/other/utils.ts index ac9b5e1d..58a2ee43 100644 --- a/client/src/other/utils.ts +++ b/client/src/other/utils.ts @@ -7,6 +7,7 @@ import { groundUnitDatabase } from "../unit/groundunitdatabase"; import { Buffer } from "buffer"; import { ROEs, emissionsCountermeasures, reactionsToThreat, states } from "../constants/constants"; import { Dropdown } from "../controls/dropdown"; +import { UnitBlueprint } from "../@types/unitdatabase"; export function bearing(lat1: number, lon1: number, lat2: number, lon2: number) { const φ1 = deg2rad(lat1); // φ, λ in radians diff --git a/client/src/unit/unit.ts b/client/src/unit/unit.ts index ef9b3e13..54dc21a0 100644 --- a/client/src/unit/unit.ts +++ b/client/src/unit/unit.ts @@ -12,6 +12,7 @@ import { DataExtractor } from '../server/dataextractor'; import { groundUnitDatabase } from './groundunitdatabase'; import { navyUnitDatabase } from './navyunitdatabase'; import { Weapon } from '../weapon/weapon'; +import { LoadoutBlueprint } from '../@types/unitdatabase'; var pathIcon = new Icon({ iconUrl: '/resources/theme/images/markers/marker-icon.png', diff --git a/client/src/unit/unitdatabase.ts b/client/src/unit/unitdatabase.ts index fc5f29b1..8e681559 100644 --- a/client/src/unit/unitdatabase.ts +++ b/client/src/unit/unitdatabase.ts @@ -1,6 +1,7 @@ import { LatLng } from "leaflet"; import { getMissionHandler, getUnitsManager } from ".."; import { GAME_MASTER } from "../constants/constants"; +import { UnitBlueprint } from "../@types/unitdatabase"; export class UnitDatabase { blueprints: { [key: string]: UnitBlueprint } = {};