From 31405119f01a077e95d7a6bebed95c0a049e7b42 Mon Sep 17 00:00:00 2001 From: PeekabooSteam Date: Fri, 3 Nov 2023 18:17:40 +0000 Subject: [PATCH] Enabled mixed-group actions, fixed some helicopter messages. --- client/src/map/map.ts | 2 +- client/src/unit/unitsmanager.ts | 79 ++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/client/src/map/map.ts b/client/src/map/map.ts index dc8f216a..d350327d 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -620,7 +620,7 @@ export class Map extends L.Map { if (selectedUnits.every((unit: Unit) => { return unit.canTargetPoint()})) { options["bomb"] = { text: "Precision bombing", tooltip: "Precision bombing of a specific point" }; options["carpet-bomb"] = { text: "Carpet bombing", tooltip: "Carpet bombing close to a point" }; - } else { + } else if (selectedUnitTypes[0] !== "Helicopter") { (getApp().getPopupsManager().get("infoPopup") as Popup).setText(`Selected units can not perform point actions.`); } } diff --git a/client/src/unit/unitsmanager.ts b/client/src/unit/unitsmanager.ts index 47dbbc86..28b8639f 100644 --- a/client/src/unit/unitsmanager.ts +++ b/client/src/unit/unitsmanager.ts @@ -223,18 +223,29 @@ export class UnitsManager { * @param options Selection options * @returns Array of selected units */ - getSelectedUnits(options?: { excludeHumans?: boolean, excludeProtected?:boolean, onlyOnePerGroup?: boolean }) { - var selectedUnits:Unit[] = []; + getSelectedUnits(options?: { excludeHumans?: boolean, excludeProtected?:boolean, onlyOnePerGroup?: boolean, showProtectionReminder?:boolean }) { + let selectedUnits:Unit[] = []; + let numProtectedUnits = 0; for (const [ID, unit] of Object.entries(this.#units)) { if (unit.getSelected()) { if (options) { - if ((options.excludeHumans && unit.getHuman()) || (options.excludeProtected === true && this.#unitIsProtected(unit))) + if (options.excludeHumans && unit.getHuman()) continue + + if (options.excludeProtected === true && this.#unitIsProtected(unit)) { + numProtectedUnits++; + continue; + } } selectedUnits.push(unit); } } if (options) { + if (options.showProtectionReminder === true && numProtectedUnits > selectedUnits.length && selectedUnits.length === 0) { + const messageText = (numProtectedUnits === 1) ? `Unit is protected` : `All selected units are protected`; + (getApp().getPopupsManager().get("infoPopup") as Popup).setText(messageText); + } + if (options.onlyOnePerGroup) { var temp: Unit[] = []; for (let unit of selectedUnits) { @@ -324,7 +335,10 @@ export class UnitsManager { * @param rotation Rotation in radians by which the formation will be rigidly rotated. E.g. a ( V ) formation will look like this ( < ) if rotated pi/4 radians (90 degrees) */ selectedUnitsAddDestination(latlng: L.LatLng, mantainRelativePosition: boolean, rotation: number) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); + + if (selectedUnits.length === 0) + return; /* Compute the destination for each unit. If mantainRelativePosition is true, compute the destination so to hold the relative positions */ var unitDestinations: { [key: number]: LatLng } = {}; @@ -357,7 +371,7 @@ export class UnitsManager { * */ selectedUnitsClearDestinations() { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: false }); for (let idx in selectedUnits) { const unit = selectedUnits[idx]; if (unit.getState() === "follow") { @@ -377,7 +391,7 @@ export class UnitsManager { * @param latlng Location where to land at */ selectedUnitsLandAt(latlng: LatLng) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].landAt(latlng); } @@ -389,7 +403,7 @@ export class UnitsManager { * @param speedChange Speed change, either "stop", "slow", or "fast". The specific value depends on the unit category */ selectedUnitsChangeSpeed(speedChange: string) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].changeSpeed(speedChange); } @@ -400,7 +414,7 @@ export class UnitsManager { * @param altitudeChange Altitude change, either "climb" or "descend". The specific value depends on the unit category */ selectedUnitsChangeAltitude(altitudeChange: string) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].changeAltitude(altitudeChange); } @@ -411,7 +425,7 @@ export class UnitsManager { * @param speed Value to set, in m/s */ selectedUnitsSetSpeed(speed: number) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setSpeed(speed); } @@ -423,7 +437,7 @@ export class UnitsManager { * @param speedType Value to set, either "CAS" or "GS". If "CAS" is selected, the unit will try to maintain the selected Calibrated Air Speed, but DCS will still only maintain a Ground Speed value so errors may arise depending on wind. */ selectedUnitsSetSpeedType(speedType: string) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setSpeedType(speedType); } @@ -435,7 +449,7 @@ export class UnitsManager { * @param altitude Value to set, in m */ selectedUnitsSetAltitude(altitude: number) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setAltitude(altitude); } @@ -447,7 +461,7 @@ export class UnitsManager { * @param altitudeType Value to set, either "ASL" or "AGL". If "AGL" is selected, the unit will try to maintain the selected Above Ground Level altitude. Due to a DCS bug, this will only be true at the final position. */ selectedUnitsSetAltitudeType(altitudeType: string) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setAltitudeType(altitudeType); } @@ -459,7 +473,7 @@ export class UnitsManager { * @param ROE Value to set, see constants for acceptable values */ selectedUnitsSetROE(ROE: string) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setROE(ROE); } @@ -471,7 +485,7 @@ export class UnitsManager { * @param reactionToThreat Value to set, see constants for acceptable values */ selectedUnitsSetReactionToThreat(reactionToThreat: string) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setReactionToThreat(reactionToThreat); } @@ -483,7 +497,7 @@ export class UnitsManager { * @param emissionCountermeasure Value to set, see constants for acceptable values */ selectedUnitsSetEmissionsCountermeasures(emissionCountermeasure: string) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setEmissionsCountermeasures(emissionCountermeasure); } @@ -495,7 +509,7 @@ export class UnitsManager { * @param onOff If true, the unit will be turned on */ selectedUnitsSetOnOff(onOff: boolean) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setOnOff(onOff); } @@ -507,7 +521,7 @@ export class UnitsManager { * @param followRoads If true, units will follow roads */ selectedUnitsSetFollowRoads(followRoads: boolean) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setFollowRoads(followRoads); } @@ -520,7 +534,7 @@ export class UnitsManager { */ selectedUnitsSetOperateAs(operateAsBool: boolean) { var operateAs = operateAsBool? "blue": "red"; - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].setOperateAs(operateAs); } @@ -532,7 +546,7 @@ export class UnitsManager { * @param ID ID of the unit to attack */ selectedUnitsAttackUnit(ID: number) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].attackUnit(ID); } @@ -543,7 +557,7 @@ export class UnitsManager { * */ selectedUnitsRefuel() { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].refuel(); } @@ -569,7 +583,10 @@ export class UnitsManager { else offset = undefined; } - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); + + if ( selectedUnits.length === 0) + return; var count = 1; var xr = 0; var yr = 1; var zr = -1; @@ -605,7 +622,7 @@ export class UnitsManager { * @param latlng Location to bomb */ selectedUnitsBombPoint(latlng: LatLng) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].bombPoint(latlng); } @@ -617,7 +634,7 @@ export class UnitsManager { * @param latlng Location to bomb */ selectedUnitsCarpetBomb(latlng: LatLng) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].carpetBomb(latlng); } @@ -629,7 +646,7 @@ export class UnitsManager { * @param latlng Location to fire at */ selectedUnitsFireAtArea(latlng: LatLng) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].fireAtArea(latlng); } @@ -641,7 +658,7 @@ export class UnitsManager { * @param latlng Location to fire at */ selectedUnitsSimulateFireFight(latlng: LatLng) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); getGroundElevation(latlng, (response: string) => { var groundElevation: number | null = null; try { @@ -660,7 +677,7 @@ export class UnitsManager { * */ selectedUnitsScenicAAA() { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].scenicAAA(); } @@ -671,11 +688,11 @@ export class UnitsManager { * */ selectedUnitsMissOnPurpose() { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].missOnPurpose(); } - this.#showActionMessage(selectedUnits, `unit set to perform miss on purpose AAA`); + this.#showActionMessage(selectedUnits, `unit set to perform miss-on-purpose AAA`); } /** Instruct units to land at specific point @@ -683,12 +700,12 @@ export class UnitsManager { * @param latlng Point where to land */ selectedUnitsLandAtPoint(latlng: LatLng) { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: true, showProtectionReminder: true }); for (let idx in selectedUnits) { selectedUnits[idx].landAtPoint(latlng); } - this.#showActionMessage(selectedUnits, `unit simulating fire fight`); + this.#showActionMessage(selectedUnits, `unit landing at point`); } /*********************** Control operations on selected units ************************/ @@ -713,7 +730,7 @@ export class UnitsManager { * */ selectedUnitsCreateGroup() { - var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: false }); + var selectedUnits = this.getSelectedUnits({ excludeHumans: true, excludeProtected: true, onlyOnePerGroup: false, showProtectionReminder: true }); if (this.getUnitsCategories(selectedUnits).length == 1) { var units: { ID: number, location: LatLng }[] = []; for (let idx in selectedUnits) {