From ee08d9d48e03edff8f7091e6e35b8a8065ad84d0 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Fri, 28 Apr 2023 17:32:28 +0200 Subject: [PATCH] Started work on better follow functionality And other minor fixes --- client/demo.js | 7 +- client/public/images/airbase.png | Bin 8704 -> 0 bytes client/public/stylesheets/units.css | 12 +- .../olympus/images/icon_airbase_blue.svg | 91 +- .../olympus/images/icon_airbase_neutral.svg | 91 +- .../olympus/images/icon_airbase_red.svg | 91 +- .../themes/olympus/images/task_tanker.svg | 1256 +++++++++++++++++ client/src/units/unit.ts | 105 +- client/src/units/unitsmanager.ts | 26 +- 9 files changed, 1576 insertions(+), 103 deletions(-) delete mode 100644 client/public/images/airbase.png create mode 100644 client/public/themes/olympus/images/task_tanker.svg diff --git a/client/demo.js b/client/demo.js index c30f7f7b..2c113e9f 100644 --- a/client/demo.js +++ b/client/demo.js @@ -2,7 +2,7 @@ const DEMO_UNIT_DATA = { ["1"]:{ baseData: { - AI: true, + AI: false, name: "KC-135", unitName: "Olympus 1-1", groupName: "Group 1", @@ -18,7 +18,7 @@ const DEMO_UNIT_DATA = { }, missionData: { fuel: 50, - flags: {human: true}, + flags: {Human: false}, ammo: [ { count: 4, @@ -47,6 +47,7 @@ const DEMO_UNIT_DATA = { }, taskData: { currentTask: "Holding", + currentState: "Idle", activePath: undefined, targetSpeed: 400, targetAltitude: 3000, @@ -67,7 +68,7 @@ const DEMO_UNIT_DATA = { }, ["2"]:{ baseData: { - AI: false, + AI: true, name: "KC-135", unitName: "Olympus 1-2", groupName: "Group 1", diff --git a/client/public/images/airbase.png b/client/public/images/airbase.png deleted file mode 100644 index 874174d63b1993217ac45d2b6171e60966dc61b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8704 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 diff --git a/client/public/stylesheets/units.css b/client/public/stylesheets/units.css index 0685381f..ddd1bd77 100644 --- a/client/public/stylesheets/units.css +++ b/client/public/stylesheets/units.css @@ -392,8 +392,8 @@ padding: var( --unit-aircraft-ammo-radius ); } - [data-object|="unit"] .unit-summary { + pointer-events: none; column-gap: 6px; color:white; display:flex; @@ -438,14 +438,14 @@ -[data-object|="unit"][data-pilot|="ai"]:hover .unit-ammo, -[data-object|="unit"][data-pilot|="ai"]:hover .unit-fuel { +[data-object|="unit"]:hover .unit-ammo, +[data-object|="unit"]:hover .unit-fuel { display:flex; } [data-object|="unit"][data-is-in-hotgroup] .unit-hotgroup, -[data-object|="unit"][data-pilot|="ai"][data-is-selected] .unit-ammo, -[data-object|="unit"][data-pilot|="ai"][data-is-selected] .unit-fuel, +[data-object|="unit"][data-is-selected] .unit-ammo, +[data-object|="unit"][data-is-selected] .unit-fuel, [data-object|="unit"][data-is-selected] .unit-selected-spotlight { display:flex; } @@ -501,7 +501,7 @@ } } -[data-object|="unit"][data-pilot|="ai"][data-has-low-fuel] .unit-fuel { +[data-object|="unit"][data-has-low-fuel] .unit-fuel { animation: pulse 1.5s linear infinite; } diff --git a/client/public/themes/olympus/images/icon_airbase_blue.svg b/client/public/themes/olympus/images/icon_airbase_blue.svg index 0800974c..d1fcf84c 100644 --- a/client/public/themes/olympus/images/icon_airbase_blue.svg +++ b/client/public/themes/olympus/images/icon_airbase_blue.svg @@ -1,10 +1,83 @@ - - - - - - - - - + + + + + + image/svg+xml + + + + + + + + + + diff --git a/client/public/themes/olympus/images/icon_airbase_neutral.svg b/client/public/themes/olympus/images/icon_airbase_neutral.svg index 69713bd5..43222171 100644 --- a/client/public/themes/olympus/images/icon_airbase_neutral.svg +++ b/client/public/themes/olympus/images/icon_airbase_neutral.svg @@ -1,10 +1,83 @@ - - - - - - - - - + + + + + + image/svg+xml + + + + + + + + + + diff --git a/client/public/themes/olympus/images/icon_airbase_red.svg b/client/public/themes/olympus/images/icon_airbase_red.svg index 45d55abd..d95872f1 100644 --- a/client/public/themes/olympus/images/icon_airbase_red.svg +++ b/client/public/themes/olympus/images/icon_airbase_red.svg @@ -1,10 +1,83 @@ - - - - - - - - - + + + + + + image/svg+xml + + + + + + + + + + diff --git a/client/public/themes/olympus/images/task_tanker.svg b/client/public/themes/olympus/images/task_tanker.svg new file mode 100644 index 00000000..32ee5980 --- /dev/null +++ b/client/public/themes/olympus/images/task_tanker.svg @@ -0,0 +1,1256 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index b8ad84b2..fcb02761 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -71,6 +71,7 @@ export class Unit extends Marker { #selectable: boolean; #selected: boolean = false; + #hovered: boolean = false; #hidden: boolean = false; #preventClick: boolean = false; @@ -81,7 +82,6 @@ export class Unit extends Marker { #miniMapMarker: CircleMarker | null = null; #timer: number = 0; - #forceUpdate: boolean = false; static getConstructor(type: string) { if (type === "GroundUnit") return GroundUnit; @@ -102,6 +102,8 @@ export class Unit extends Marker { this.on('click', (e) => this.#onClick(e)); this.on('dblclick', (e) => this.#onDoubleClick(e)); this.on('contextmenu', (e) => this.#onContextMenu(e)); + this.on('mouseover', () => { this.#hovered = true;}) + this.on('mouseout', () => { this.#hovered = false;}) this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 }); this.#pathPolyline.addTo(getMap()); @@ -123,7 +125,8 @@ export class Unit extends Marker { var icon = new DivIcon({ html: this.getMarkerHTML(), className: 'leaflet-unit-marker', - iconAnchor: [0, 0] + iconAnchor: [25, 0], + iconSize: [50, 50], }); this.setIcon(icon); } @@ -143,13 +146,11 @@ export class Unit extends Marker { } setData(data: UpdateData) { - var updateMarker = false; - - if ((data.flightData.latitude != undefined && data.flightData.longitude != undefined && (this.getFlightData().latitude != data.flightData.latitude || this.getFlightData().longitude != data.flightData.longitude)) - || (data.flightData.heading != undefined && this.getFlightData().heading != data.flightData.heading) - || (data.baseData.alive != undefined && this.getBaseData().alive != data.baseData.alive) - || this.#forceUpdate || !getMap().hasLayer(this)) - updateMarker = true; + /* Check if data has changed comparing new values to old values */ + const positionChanged = (data.flightData.latitude != undefined && data.flightData.longitude != undefined && (this.getFlightData().latitude != data.flightData.latitude || this.getFlightData().longitude != data.flightData.longitude)); + const headingChanged = (data.flightData.heading != undefined && this.getFlightData().heading != data.flightData.heading); + const aliveChanged = (data.baseData.alive != undefined && this.getBaseData().alive != data.baseData.alive); + var updateMarker = (positionChanged || headingChanged || aliveChanged || !getMap().hasLayer(this)) if (data.baseData != undefined) { @@ -331,21 +332,17 @@ export class Unit extends Marker { } attackUnit(targetID: number) { + /* Units can't attack themselves */ if (this.ID != targetID) { attackUnit(this.ID, targetID); } - else { - // TODO: show a message - } } followUnit(targetID: number, offset: {"x": number, "y": number, "z": number}) { + /* Units can't follow themselves */ if (this.ID != targetID) { followUnit(this.ID, targetID, offset); } - else { - // TODO: show a message - } } landAt(latlng: LatLng) { @@ -399,7 +396,7 @@ export class Unit extends Marker { if (!e.originalEvent.ctrlKey) { getUnitsManager().deselectAllUnits(); } - this.setSelected(true); + this.setSelected(!this.getSelected()); } } this.#preventClick = false; @@ -416,12 +413,11 @@ export class Unit extends Marker { options["Center"] = `
Center map
`; - if (getUnitsManager().getSelectedUnits().length > 0 && !(getUnitsManager().getSelectedUnits().includes(this))) + if (getUnitsManager().getSelectedUnits().length > 0 && !(getUnitsManager().getSelectedUnits().length == 1 && (getUnitsManager().getSelectedUnits().includes(this)))) { - options = { - 'Attack': `
Attack
`, - 'Follow': `
Follow
`, - } + options['Attack'] = `
Attack
`; + if (getUnitsManager().getSelectedUnitsType() === "Aircraft") + options['Follow'] = `
Follow
`; } else if ((getUnitsManager().getSelectedUnits().length > 0 && (getUnitsManager().getSelectedUnits().includes(this))) || getUnitsManager().getSelectedUnits().length == 0) { @@ -487,30 +483,12 @@ export class Unit extends Marker { // Z: left-right, positive right var offset = {"x": 0, "y": 0, "z": 0}; - if (action == "Trail") - { - offset.x = -50; offset.y = -30; offset.z = 0; - } - else if (action == "Echelon (LH)") - { - offset.x = -50; offset.y = -10; offset.z = -50; - } - else if (action == "Echelon (RH)") - { - offset.x = -50; offset.y = -10; offset.z = 50; - } - else if (action == "Line abreast (RH)") - { - offset.x = 0; offset.y = 0; offset.z = 50; - } - else if (action == "Line abreast (LH)") - { - offset.x = 0; offset.y = 0; offset.z = -50; - } - else if (action == "Front") - { - offset.x = 100; offset.y = 0; offset.z = 0; - } + if (action == "Trail") { offset.x = -50; offset.y = -30; offset.z = 0; } + else if (action == "Echelon (LH)") { offset.x = -50; offset.y = -10; offset.z = -50; } + else if (action == "Echelon (RH)") { offset.x = -50; offset.y = -10; offset.z = 50; } + else if (action == "Line abreast (RH)") { offset.x = 0; offset.y = 0; offset.z = 50; } + else if (action == "Line abreast (LH)") { offset.x = 0; offset.y = 0; offset.z = -50; } + else if (action == "Front") { offset.x = 100; offset.y = 0; offset.z = 0; } getUnitsManager().selectedUnitsFollowUnit(this.ID, offset); } } @@ -518,6 +496,7 @@ export class Unit extends Marker { #updateMarker() { this.updateVisibility(); + /* Draw the minimap marker */ if (this.getBaseData().alive ) { if (this.#miniMapMarker == null) @@ -544,47 +523,47 @@ export class Unit extends Marker { } } + /* Draw the marker */ if (!this.getHidden()) { this.setLatLng(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude)); + var element = this.getElement(); if (element != null) { + /* Draw the velocity vector */ element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${15 + this.getFlightData().speed / 5}px;`); - element.querySelector(".unit")?.setAttribute("data-pilot", this.getMissionData().flags.human? "human": "ai"); + /* Set fuel data */ element.querySelector(".unit-fuel-level")?.setAttribute("style", `width: ${this.getMissionData().fuel}%`); element.querySelector(".unit")?.toggleAttribute("data-has-low-fuel", this.getMissionData().fuel < 20); + /* Set dead/alive flag */ element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.getBaseData().alive); - if (this.getMissionData().flags.Human) // Unit is human + /* Set current unit state */ + if (this.getMissionData().flags.Human) // Unit is human element.querySelector(".unit")?.setAttribute("data-state", "human"); - else if (!this.getBaseData().AI) // Unit is under DCS control (no Olympus) + else if (!this.getBaseData().AI) // Unit is under DCS control (not Olympus) element.querySelector(".unit")?.setAttribute("data-state", "dcs"); - else // Unit is under Olympus control + else // Unit is under Olympus control element.querySelector(".unit")?.setAttribute("data-state", this.getTaskData().currentState.toLowerCase()); - var unitAltitudeDiv = element.querySelector(".unit-altitude"); - if (unitAltitudeDiv != null) - unitAltitudeDiv.innerHTML = "FL" + String(Math.floor(this.getFlightData().altitude / 0.3048 / 1000)); - - var unitSpeedDiv = element.querySelector(".unit-speed"); - if (unitSpeedDiv != null) - unitSpeedDiv.innerHTML = String(Math.floor(this.getFlightData().speed * 1.94384 ) ); + /* Set altitude and speed */ + if (element.querySelector(".unit-altitude")) + ( element.querySelector(".unit-altitude")).innerText = "FL" + String(Math.floor(this.getFlightData().altitude / 0.3048 / 1000)); + if (element.querySelector(".unit-speed")) + ( element.querySelector(".unit-speed")).innerHTML = String(Math.floor(this.getFlightData().speed * 1.94384 ) ); + /* Rotate elements according to heading */ element.querySelectorAll( "[data-rotate-to-heading]" ).forEach( el => { const headingDeg = rad2deg( this.getFlightData().heading ); let currentStyle = el.getAttribute( "style" ) || ""; el.setAttribute( "style", currentStyle + `transform:rotate(${headingDeg}deg);` ); }); - - - } + /* Set vertical offset for altitude stacking */ var pos = getMap().latLngToLayerPoint(this.getLatLng()).round(); - this.setZIndexOffset(1000 + Math.floor(this.getFlightData().altitude) - pos.y); + this.setZIndexOffset(1000 + Math.floor(this.getFlightData().altitude) - pos.y + (this.#hovered || this.#selected? 5000: 0)); } - - this.#forceUpdate = false; } #drawPath() { @@ -643,7 +622,7 @@ export class Unit extends Marker { color = "#00FF00"; else color = "#FFFFFF"; - var targetPolyline = new Polyline([startLatLng, endLatLng], { color: color, weight: 3, opacity: 1, smoothFactor: 1 }); + var targetPolyline = new Polyline([startLatLng, endLatLng], { color: color, weight: 3, opacity: 0.4, smoothFactor: 1 }); targetPolyline.addTo(getMap()); this.#targetsPolylines.push(targetPolyline) } diff --git a/client/src/units/unitsmanager.ts b/client/src/units/unitsmanager.ts index 7c6086d5..c4b67c54 100644 --- a/client/src/units/unitsmanager.ts +++ b/client/src/units/unitsmanager.ts @@ -191,8 +191,17 @@ export class UnitsManager { selectedUnitsAddDestination(latlng: L.LatLng) { var selectedUnits = this.getSelectedUnits(); for (let idx in selectedUnits) { - var commandedUnit = selectedUnits[idx]; - commandedUnit.addDestination(latlng); + const unit = selectedUnits[idx]; + if (unit.getTaskData().currentState === "Follow") + { + const leader = this.getUnitByID(unit.getFormationData().leaderID) + if (leader && leader.getSelected()) + leader.addDestination(latlng); + else + unit.addDestination(latlng); + } + else + unit.addDestination(latlng); } this.#showActionMessage(selectedUnits, " new destination added"); } @@ -200,8 +209,17 @@ export class UnitsManager { selectedUnitsClearDestinations() { var selectedUnits = this.getSelectedUnits(); for (let idx in selectedUnits) { - var commandedUnit = selectedUnits[idx]; - commandedUnit.clearDestinations(); + const unit = selectedUnits[idx]; + if (unit.getTaskData().currentState === "Follow") + { + const leader = this.getUnitByID(unit.getFormationData().leaderID) + if (leader && leader.getSelected()) + leader.clearDestinations(); + else + unit.clearDestinations(); + } + else + unit.clearDestinations(); } }