diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index 971cff02..f1350faa 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -139,6 +139,8 @@ export class Unit extends Marker { return ""; } + /********************** Unit data *************************/ + setData(data: UpdateData) { /* Check if data has changed comparing new values to old values */ const positionChanged = (data.flightData != undefined && data.flightData.latitude != undefined && data.flightData.longitude != undefined && (this.getFlightData().latitude != data.flightData.latitude || this.getFlightData().longitude != data.flightData.longitude)); @@ -263,22 +265,7 @@ export class Unit extends Marker { return this.#selectable; } - addDestination(latlng: L.LatLng) { - var path: any = {}; - if (this.getTaskData().activePath != undefined) { - path = this.getTaskData().activePath; - path[(Object.keys(path).length + 1).toString()] = latlng; - } - else { - path = { "1": latlng }; - } - addDestination(this.ID, path); - } - - clearDestinations() { - this.getTaskData().activePath = undefined; - } - + /********************** Visibility *************************/ updateVisibility() { this.setHidden( document.body.getAttribute(`data-hide-${this.getMissionData().coalition}`) != null || @@ -309,64 +296,103 @@ export class Unit extends Marker { return getUnitsManager().getUnitByID(this.getFormationData().leaderID); } + /********************** Unit commands *************************/ + addDestination(latlng: L.LatLng) { + if (!this.getMissionData().flags.Human) { + var path: any = {}; + if (this.getTaskData().activePath != undefined) { + path = this.getTaskData().activePath; + path[(Object.keys(path).length + 1).toString()] = latlng; + } + else { + path = { "1": latlng }; + } + addDestination(this.ID, path); + } + } + + clearDestinations() { + if (!this.getMissionData().flags.Human) + this.getTaskData().activePath = undefined; + } + attackUnit(targetID: number) { /* Units can't attack themselves */ - if (this.ID != targetID) { - attackUnit(this.ID, targetID); - } + if (!this.getMissionData().flags.Human) + if (this.ID != targetID) + attackUnit(this.ID, targetID); } followUnit(targetID: number, offset: {"x": number, "y": number, "z": number}) { /* Units can't follow themselves */ - if (this.ID != targetID) { - followUnit(this.ID, targetID, offset); - } + if (!this.getMissionData().flags.Human) + if (this.ID != targetID) + followUnit(this.ID, targetID, offset); } landAt(latlng: LatLng) { - landAt(this.ID, latlng); + if (!this.getMissionData().flags.Human) + landAt(this.ID, latlng); } changeSpeed(speedChange: string) { - changeSpeed(this.ID, speedChange); + if (!this.getMissionData().flags.Human) + changeSpeed(this.ID, speedChange); } changeAltitude(altitudeChange: string) { - changeAltitude(this.ID, altitudeChange); + if (!this.getMissionData().flags.Human) + changeAltitude(this.ID, altitudeChange); } setSpeed(speed: number) { - setSpeed(this.ID, speed); + if (!this.getMissionData().flags.Human) + setSpeed(this.ID, speed); } setAltitude(altitude: number) { - setAltitude(this.ID, altitude); + if (!this.getMissionData().flags.Human) + setAltitude(this.ID, altitude); } setROE(ROE: string) { - setROE(this.ID, ROE); + if (!this.getMissionData().flags.Human) + setROE(this.ID, ROE); } setReactionToThreat(reactionToThreat: string) { - setReactionToThreat(this.ID, reactionToThreat); + if (!this.getMissionData().flags.Human) + setReactionToThreat(this.ID, reactionToThreat); } setLeader(isLeader: boolean, wingmenIDs: number[] = []) { - setLeader(this.ID, isLeader, wingmenIDs); + if (!this.getMissionData().flags.Human) + setLeader(this.ID, isLeader, wingmenIDs); } delete() { + // TODO: add confirmation popup deleteUnit(this.ID); } refuel() { - refuel(this.ID); + if (!this.getMissionData().flags.Human) + refuel(this.ID); } setAdvancedOptions(isTanker: boolean, isAWACS: boolean, TACANChannel: number, TACANXY: string, TACANcallsign: string, radioFrequency: number, radioCallsign: number, radioCallsignNumber: number) { - setAdvacedOptions(this.ID, isTanker, isAWACS, TACANChannel, TACANXY, TACANcallsign, radioFrequency, radioCallsign, radioCallsignNumber); + if (!this.getMissionData().flags.Human) + setAdvacedOptions(this.ID, isTanker, isAWACS, TACANChannel, TACANXY, TACANcallsign, radioFrequency, radioCallsign, radioCallsignNumber); } + /***********************************************/ + onAdd(map: Map): this { + super.onAdd(map); + getMap().removeTemporaryMarker(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude)); + return this; + } + + /***********************************************/ #onClick(e: any) { if (!this.#preventClick) { if (getMap().getState() === 'IDLE' || getMap().getState() === 'MOVE_UNIT' || e.originalEvent.ctrlKey) { @@ -382,12 +408,6 @@ export class Unit extends Marker { }, 200); } - onAdd(map: Map): this { - super.onAdd(map); - getMap().removeTemporaryMarker(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude)); - return this; - } - #onDoubleClick(e: any) { clearTimeout(this.#timer); this.#preventClick = true; diff --git a/client/src/units/unitsmanager.ts b/client/src/units/unitsmanager.ts index dbc024de..62ac5db6 100644 --- a/client/src/units/unitsmanager.ts +++ b/client/src/units/unitsmanager.ts @@ -92,13 +92,17 @@ export class UnitsManager { } } - getSelectedUnits() { + getSelectedUnits(options?: {excludeHumans?: boolean}) { var selectedUnits = []; for (let ID in this.#units) { if (this.#units[ID].getSelected()) { selectedUnits.push(this.#units[ID]); } } + if (options) { + if (options.excludeHumans) + selectedUnits = selectedUnits.filter((unit: Unit) => {return !unit.getMissionData().flags.Human}); + } return selectedUnits; } @@ -148,10 +152,12 @@ export class UnitsManager { }); }; + /*********************** Actions on selected units ************************/ selectedUnitsAddDestination(latlng: L.LatLng) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { const unit = selectedUnits[idx]; + /* If a unit is following another unit, and that unit is also selected, send the command to the followed unit */ if (unit.getTaskData().currentState === "Follow") { const leader = this.getUnitByID(unit.getFormationData().leaderID) if (leader && leader.getSelected()) @@ -166,7 +172,7 @@ export class UnitsManager { } selectedUnitsClearDestinations() { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { const unit = selectedUnits[idx]; if (unit.getTaskData().currentState === "Follow") { @@ -182,7 +188,7 @@ export class UnitsManager { } selectedUnitsLandAt(latlng: LatLng) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].landAt(latlng); } @@ -190,21 +196,21 @@ export class UnitsManager { } selectedUnitsChangeSpeed(speedChange: string) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].changeSpeed(speedChange); } } selectedUnitsChangeAltitude(altitudeChange: string) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].changeAltitude(altitudeChange); } } selectedUnitsSetSpeed(speed: number) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].setSpeed(speed); } @@ -213,7 +219,7 @@ export class UnitsManager { } selectedUnitsSetAltitude(altitude: number) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].setAltitude(altitude); } @@ -221,7 +227,7 @@ export class UnitsManager { } selectedUnitsSetROE(ROE: string) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].setROE(ROE); } @@ -229,7 +235,7 @@ export class UnitsManager { } selectedUnitsSetReactionToThreat(reactionToThreat: string) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].setReactionToThreat(reactionToThreat); } @@ -237,7 +243,7 @@ export class UnitsManager { } selectedUnitsAttackUnit(ID: number) { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].attackUnit(ID); } @@ -245,7 +251,7 @@ export class UnitsManager { } selectedUnitsDelete() { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits(); /* Can be applied to humans too */ for (let idx in selectedUnits) { selectedUnits[idx].delete(); } @@ -253,7 +259,7 @@ export class UnitsManager { } selectedUnitsRefuel() { - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); for (let idx in selectedUnits) { selectedUnits[idx].refuel(); } @@ -262,6 +268,7 @@ export class UnitsManager { selectedUnitsFollowUnit(ID: number, offset?: { "x": number, "y": number, "z": number }, formation?: string) { if (offset == undefined) { + /* Simple formations with fixed offsets */ // X: front-rear, positive front // Y: top-bottom, positive top // Z: left-right, positive right @@ -274,19 +281,21 @@ export class UnitsManager { else if (formation === "Front") { offset.x = 100; offset.y = 0; offset.z = 0; } else offset = undefined; } - var selectedUnits = this.getSelectedUnits(); + var selectedUnits = this.getSelectedUnits({excludeHumans: true}); var count = 1; var xr = 0; var yr = 1; var zr = -1; var layer = 1; for (let idx in selectedUnits) { - var commandedUnit = selectedUnits[idx]; + var unit = selectedUnits[idx]; if (offset != undefined) - commandedUnit.followUnit(ID, { "x": offset.x * count, "y": offset.y * count, "z": offset.z * count }); + /* Offset is set, apply it */ + unit.followUnit(ID, { "x": offset.x * count, "y": offset.y * count, "z": offset.z * count }); else { + /* More complex formations with variable offsets */ if (formation === "Diamond") { var xl = xr * Math.cos(Math.PI / 4) - yr * Math.sin(Math.PI / 4); var yl = xr * Math.sin(Math.PI / 4) + yr * Math.cos(Math.PI / 4); - commandedUnit.followUnit(ID, { "x": -yl * 50, "y": zr * 10, "z": xl * 50 }); + unit.followUnit(ID, { "x": -yl * 50, "y": zr * 10, "z": xl * 50 }); if (yr == 0) { layer++; xr = 0; yr = layer; zr = -layer; } else { @@ -300,8 +309,9 @@ export class UnitsManager { this.#showActionMessage(selectedUnits, `following unit ${this.getUnitByID(ID)?.getBaseData().unitName}`); } + /***********************************************/ copyUnits() { - this.#copiedUnits = this.getSelectedUnits(); + this.#copiedUnits = this.getSelectedUnits(); /* Can be applied to humans too */ this.#showActionMessage(this.#copiedUnits, `copied`); } @@ -318,6 +328,7 @@ export class UnitsManager { } } + /***********************************************/ #onKeyDown(event: KeyboardEvent) { if (!keyEventWasInInput(event) && event.key === "Delete") { this.selectedUnitsDelete(); @@ -354,7 +365,7 @@ export class UnitsManager { #showActionMessage(units: Unit[], message: string) { if (units.length == 1) getInfoPopup().setText(`${units[0].getBaseData().unitName} ${message}`); - else + else if (units.length > 1) getInfoPopup().setText(`${units[0].getBaseData().unitName} and ${units.length - 1} other units ${message}`); } } \ No newline at end of file