From 22121622390f3098b8a6fd4c635d7f284d04a436 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Tue, 21 Mar 2023 21:22:29 +0100 Subject: [PATCH] Added spawn from airbase code The spawn from airbase code has been added. A couple of fixes to the UnitDataTable. --- client/public/stylesheets/unitdatatable.css | 10 +- client/src/controls/airbasecontextmenu.ts | 2 + client/src/controls/mapcontextmenu.ts | 97 +++++++++--------- client/src/index.ts | 12 ++- client/src/panels/panel.ts | 8 ++ client/src/panels/unitcontrolpanel.ts | 2 +- client/src/panels/unitinfopanel.ts | 2 +- client/src/units/unitdatatable.ts | 104 ++++++-------------- client/src/units/unitsmanager.ts | 2 +- client/views/unitdatatable.ejs | 6 +- 10 files changed, 107 insertions(+), 138 deletions(-) diff --git a/client/public/stylesheets/unitdatatable.css b/client/public/stylesheets/unitdatatable.css index f666ab25..e16e1bdd 100644 --- a/client/public/stylesheets/unitdatatable.css +++ b/client/public/stylesheets/unitdatatable.css @@ -1,4 +1,4 @@ -#unit-data-table { +#unit-list { display:flex; flex-direction: column; font-size:13px; @@ -6,22 +6,22 @@ width:fit-content; } -#unit-data-table > div { +#unit-list > div { display:flex; flex-direction: row; flex-wrap: nowrap; } -#unit-data-table > div > div { +#unit-list > div > div { text-overflow: ellipsis; white-space: nowrap; width:100px; } -#unit-data-table > div:first-of-type { +#unit-list > div:first-of-type { text-align: center; } -#unit-data-table > div > div:nth-of-type( 4 ) { +#unit-list > div > div:nth-of-type( 4 ) { text-align: center; } \ No newline at end of file diff --git a/client/src/controls/airbasecontextmenu.ts b/client/src/controls/airbasecontextmenu.ts index 2e94d0e3..6fccd626 100644 --- a/client/src/controls/airbasecontextmenu.ts +++ b/client/src/controls/airbasecontextmenu.ts @@ -66,6 +66,8 @@ export class AirbaseContextMenu extends ContextMenu { getMap().showMapContextMenu({originalEvent: {x: this.getX(), y: this.getY(), latlng: this.getLatLng()}}); getMap().getMapContextMenu().hideUpperBar(); getMap().getMapContextMenu().showSubMenu("aircraft"); + getMap().getMapContextMenu().setAirbaseName(this.#airbase.getName()); + getMap().getMapContextMenu().setLatLng(this.#airbase.getLatLng()); } } } \ No newline at end of file diff --git a/client/src/controls/mapcontextmenu.ts b/client/src/controls/mapcontextmenu.ts index 1723dc22..fafc82ef 100644 --- a/client/src/controls/mapcontextmenu.ts +++ b/client/src/controls/mapcontextmenu.ts @@ -55,6 +55,7 @@ export class MapContextMenu extends ContextMenu { } show(x: number, y: number, latlng: LatLng) { + this.#spawnOptions = {role: "", type: "", latlng: new LatLng(0, 0), loadout: null, coalition: "blue", airbaseName: null}; super.show(x, y, latlng); this.#spawnOptions.latlng = latlng; this.showUpperBar(); @@ -83,6 +84,16 @@ export class MapContextMenu extends ContextMenu { this.getContainer()?.querySelector("#upper-bar")?.classList.toggle("hide", true); } + setAirbaseName(airbaseName: string) + { + this.#spawnOptions.airbaseName = airbaseName; + } + + setLatLng(latlng: LatLng) + { + this.#spawnOptions.latlng = latlng; + } + #onSwitch(e: any) { if (this.getContainer() != null) { if (e.srcElement.checked) @@ -95,13 +106,10 @@ export class MapContextMenu extends ContextMenu { /********* Aircraft spawn menu *********/ #setAircraftRole(role: string) { - if (this.#spawnOptions != null) - { - this.#spawnOptions.role = role; - this.#resetAircraftRole(); - this.#aircraftTypeDropdown.setOptions(aircraftDatabase.getLabelsByRole(role)); - this.#aircraftTypeDropdown.selectValue(0); - } + this.#spawnOptions.role = role; + this.#resetAircraftRole(); + this.#aircraftTypeDropdown.setOptions(aircraftDatabase.getLabelsByRole(role)); + this.#aircraftTypeDropdown.selectValue(0); this.clip(); } @@ -116,20 +124,18 @@ export class MapContextMenu extends ContextMenu { #setAircraftType(label: string) { - if (this.#spawnOptions != null) + this.#resetAircraftType(); + var type = aircraftDatabase.getNameByLabel(label); + if (type != null) { - this.#resetAircraftType(); - var type = aircraftDatabase.getNameByLabel(label); - if (type != null) - { - this.#spawnOptions.type = type; - this.#aircraftLoadoutDropdown.setOptions(aircraftDatabase.getLoadoutNamesByRole(type, this.#spawnOptions.role)); - this.#aircraftLoadoutDropdown.selectValue(0); - var image = (this.getContainer()?.querySelector("#unit-image")); - image.src = `images/units/${aircraftDatabase.getByLabel(label)?.filename}`; - image.classList.toggle("hide", false); - } + this.#spawnOptions.type = type; + this.#aircraftLoadoutDropdown.setOptions(aircraftDatabase.getLoadoutNamesByRole(type, this.#spawnOptions.role)); + this.#aircraftLoadoutDropdown.selectValue(0); + var image = (this.getContainer()?.querySelector("#unit-image")); + image.src = `images/units/${aircraftDatabase.getByLabel(label)?.filename}`; + image.classList.toggle("hide", false); } + this.clip(); } @@ -143,23 +149,20 @@ export class MapContextMenu extends ContextMenu { #setAircraftLoadout(loadoutName: string) { - if (this.#spawnOptions != null) + var loadout = aircraftDatabase.getLoadoutsByName(this.#spawnOptions.type, loadoutName); + if (loadout) { - var loadout = aircraftDatabase.getLoadoutsByName(this.#spawnOptions.type, loadoutName); - if (loadout) - { - this.#spawnOptions.loadout = loadout.code; - (this.getContainer()?.querySelector("#aircraft-spawn-menu")?.querySelector(".deploy-unit-button")).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("#loadout-list")).replaceChildren( - ...items.map((item: any) => { - var div = document.createElement('div'); - div.innerText = item; - return div; - }) - ) - } + this.#spawnOptions.loadout = loadout.code; + (this.getContainer()?.querySelector("#aircraft-spawn-menu")?.querySelector(".deploy-unit-button")).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("#loadout-list")).replaceChildren( + ...items.map((item: any) => { + var div = document.createElement('div'); + div.innerText = item; + return div; + }) + ) } this.clip(); } @@ -167,13 +170,10 @@ export class MapContextMenu extends ContextMenu { /********* Ground unit spawn menu *********/ #setGroundUnitRole(role: string) { - if (this.#spawnOptions != null) - { - this.#spawnOptions.role = role; - this.#resetGroundUnitRole(); - this.#groundUnitTypeDropdown.setOptions(groundUnitsDatabase.getLabelsByRole(role)); - this.#groundUnitTypeDropdown.selectValue(0); - } + this.#spawnOptions.role = role; + this.#resetGroundUnitRole(); + this.#groundUnitTypeDropdown.setOptions(groundUnitsDatabase.getLabelsByRole(role)); + this.#groundUnitTypeDropdown.selectValue(0); this.clip(); } @@ -188,15 +188,12 @@ export class MapContextMenu extends ContextMenu { #setGroundUnitType(label: string) { - if (this.#spawnOptions != null) + this.#resetGroundUnitType(); + var type = groundUnitsDatabase.getNameByLabel(label); + if (type != null) { - this.#resetGroundUnitType(); - var type = groundUnitsDatabase.getNameByLabel(label); - if (type != null) - { - this.#spawnOptions.type = type; - (this.getContainer()?.querySelector("#ground-unit-spawn-menu")?.querySelector(".deploy-unit-button")).disabled = false; - } + this.#spawnOptions.type = type; + (this.getContainer()?.querySelector("#ground-unit-spawn-menu")?.querySelector(".deploy-unit-button")).disabled = false; } this.clip(); } diff --git a/client/src/index.ts b/client/src/index.ts index d4c83c8f..e2e404d2 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -30,7 +30,7 @@ var connected: boolean = false; var activeCoalition: string = "blue"; var sessionHash: string | null = null; -var unitDataTable = new UnitDataTable(); +var unitDataTable: UnitDataTable; var featureSwitches; @@ -50,6 +50,8 @@ function setup() { mouseInfoPanel = new MouseInfoPanel("mouse-info-panel"); //logPanel = new LogPanel("log-panel"); + unitDataTable = new UnitDataTable("unit-data-table"); + /* AIC */ let aicFeatureSwitch = featureSwitches.getSwitch("aic"); if (aicFeatureSwitch?.isEnabled()) { @@ -87,7 +89,6 @@ function requestUpdate() { /* Main update rate = 250ms is minimum time, equal to server update time. */ getUnits((data: UnitsData) => { getUnitsManager()?.update(data); - getUnitDataTable().update( data.units ) checkSessionHash(data.sessionHash); }, false); setTimeout(() => requestUpdate(), getConnected() ? 250 : 1000); @@ -98,9 +99,14 @@ function requestUpdate() { function requestRefresh() { /* Main refresh rate = 5000ms. */ getUnits((data: UnitsData) => { + getUnitsManager()?.update(data); getAirbases((data: AirbasesData) => getMissionData()?.update(data)); getBulllseyes((data: BullseyesData) => getMissionData()?.update(data)); getMission((data: any) => {getMissionData()?.update(data)}); + + // Update the list of existing units + getUnitDataTable()?.update(); + checkSessionHash(data.sessionHash); }, true); setTimeout(() => requestRefresh(), 5000); @@ -152,8 +158,10 @@ function setupEvents() { toggleDemoEnabled(); break; + case "Minus": // For Veltro's italian layout keyboard, which lacks a quote case "Quote": unitDataTable.toggle(); + break } }); diff --git a/client/src/panels/panel.ts b/client/src/panels/panel.ts index 1b803870..df0a2f48 100644 --- a/client/src/panels/panel.ts +++ b/client/src/panels/panel.ts @@ -16,6 +16,14 @@ export class Panel { this.#visible = false; } + toggle() { + // Simple way to track if currently visible + if (this.#visible) + this.hide(); + else + this.show(); + } + getElement() { return this.#element; } diff --git a/client/src/panels/unitcontrolpanel.ts b/client/src/panels/unitcontrolpanel.ts index 4e5bc7e2..374da4ee 100644 --- a/client/src/panels/unitcontrolpanel.ts +++ b/client/src/panels/unitcontrolpanel.ts @@ -38,7 +38,7 @@ export class UnitControlPanel extends Panel { var button = document.createElement("button"); button.title = option; button.value = option; - button.addEventListener("click", () => {getUnitsManager().selectedUnitsSetROE(button.title);}); + button.addEventListener("click", () => {getUnitsManager().selectedUnitsSetReactionToThreat(button.title);}); return button; }); diff --git a/client/src/panels/unitinfopanel.ts b/client/src/panels/unitinfopanel.ts index 3080edca..0910c0a7 100644 --- a/client/src/panels/unitinfopanel.ts +++ b/client/src/panels/unitinfopanel.ts @@ -58,7 +58,7 @@ export class UnitInfoPanel extends Panel { this.#task.classList.toggle("neutral", unit.getMissionData().coalition === "neutral"); /* Add the loadout elements */ - this.#loadoutContainer.replaceChildren(...unit.getMissionData().ammo.map( + this.#loadoutContainer.replaceChildren(...Object.values(unit.getMissionData().ammo).map( (ammo: any) => { var el = document.createElement("div"); el.classList.add("pill", "loadout-item"); diff --git a/client/src/units/unitdatatable.ts b/client/src/units/unitdatatable.ts index 4149cebb..e54b541c 100644 --- a/client/src/units/unitdatatable.ts +++ b/client/src/units/unitdatatable.ts @@ -1,103 +1,57 @@ -export class UnitDataTable { - - #element; - #tableId = "unit-data-table"; - - - constructor() { - - const table = document.getElementById( this.#tableId ); - - if ( table instanceof HTMLElement ) { - - this.#element = table; - - } else { - - return; - - } - +import { getUnitsManager } from ".."; +import { Panel } from "../panels/panel"; +import { Unit } from "./unit"; +export class UnitDataTable extends Panel { + constructor(id: string) { + super(id); + this.hide(); } + update() { + var units = getUnitsManager().getUnits(); - getElement() { - return this.#element; - } + const unitsArray = Object.values(units).sort((a: Unit, b: Unit) => { + const aVal = a.getBaseData().unitName?.toLowerCase(); + const bVal = b.getBaseData().unitName?.toLowerCase(); - - hide() { - this.getElement()?.closest( ".ol-dialog" )?.classList.add( "hide" ); - } - - - show() { - this.getElement()?.closest( ".ol-dialog" )?.classList.remove( "hide" ); - } - - - toggle() { - this.getElement()?.closest( ".ol-dialog" )?.classList.toggle( "hide" ); - } - - - update( units:object ) { - - const unitsArray = Object.values( units ).sort( ( a, b ) => { - - const aVal = a.baseData.unitName.toLowerCase(); - const bVal = b.baseData.unitName.toLowerCase(); - - if ( aVal > bVal ) { + if (aVal > bVal) { return 1; - } else if ( bVal > aVal ) { + } else if (bVal > aVal) { return -1; } else { return 0; } - }); + + function addRow(parentEl: HTMLElement, columns: string[]) { + const rowDiv = document.createElement("div"); - function addRow( parentEl:HTMLElement, columns:string[] ) { + for (const item of columns) { - const rowDiv = document.createElement( "div" ); - - for ( const item of columns ) { - - const div = document.createElement( "div" ); + const div = document.createElement("div"); div.innerText = item; - rowDiv.appendChild( div ); + rowDiv.appendChild(div); } - - parentEl.appendChild( rowDiv ); - + parentEl.appendChild(rowDiv); } + const el = this.getElement().querySelector("#unit-list"); - const el = this.getElement(); - - if ( el ) { + if (el) { el.innerHTML = ""; - addRow( el, [ "Callsign", "Name", "Category", "AI/Human" ] ) + addRow(el, ["Callsign", "Name", "Category", "AI/Human"]) - for ( const unit of unitsArray ) { - - const dataset = [ unit.baseData.unitName, unit.baseData.name, unit.baseData.category, ( unit.baseData.AI ) ? "AI" : "Human" ]; - - if ( this.getElement() ) { - - } - addRow( el, dataset ); - + for (const unit of unitsArray) { + + const dataset = [unit.getBaseData().unitName, unit.getBaseData().name, unit.getBaseData().category, (unit.getBaseData().AI) ? "AI" : "Human"]; + + addRow(el, dataset); } - } - } - } \ No newline at end of file diff --git a/client/src/units/unitsmanager.ts b/client/src/units/unitsmanager.ts index ca7ab99c..e06dd39f 100644 --- a/client/src/units/unitsmanager.ts +++ b/client/src/units/unitsmanager.ts @@ -1,5 +1,5 @@ import { LatLng, LatLngBounds } from "leaflet"; -import { getMap } from ".."; +import { getMap, getUnitDataTable } from ".."; import { Unit } from "./unit"; import { cloneUnit } from "../server/server"; import { IDLE, MOVE_UNIT } from "../map/map"; diff --git a/client/views/unitdatatable.ejs b/client/views/unitdatatable.ejs index fb89a424..d25613b2 100644 --- a/client/views/unitdatatable.ejs +++ b/client/views/unitdatatable.ejs @@ -1,4 +1,4 @@ -
+
@@ -6,8 +6,8 @@

Unit list

-
- +
+
\ No newline at end of file