Completed transition to injected svgs

This commit is contained in:
Pax1601
2023-05-24 11:07:41 +02:00
parent e7ce9ac76d
commit 3009a73a66
26 changed files with 333 additions and 303 deletions

View File

@@ -6,6 +6,7 @@ import { aircraftDatabase } from './aircraftdatabase';
import { groundUnitsDatabase } from './groundunitsdatabase';
import { CustomMarker } from '../map/custommarker';
import { SVGInjector } from '@tanem/svg-injector';
import { UnitDatabase } from './unitdatabase';
var pathIcon = new Icon({
iconUrl: '/resources/theme/images/markers/marker-icon.png',
@@ -124,17 +125,23 @@ export class Unit extends CustomMarker {
return "";
}
getActiveMarkerElements() {
// Default values
getDatabase(): UnitDatabase | null {
// Overloaded by child classes
return null;
}
getIconOptions(): UnitIconOptions {
// Default values, overloaded by child classes if needed
return {
state: false,
vvi: false,
hotgroup: false,
unitIcon: true,
shortLabel: false,
fuel: false,
ammo: false,
summary: false
showState: false,
showVvi: false,
showHotgroup: false,
showUnitIcon: true,
showShortLabel: false,
showFuel: false,
showAmmo: false,
showSummary: false,
rotateToHeading: false
}
}
@@ -165,6 +172,7 @@ export class Unit extends CustomMarker {
setHotgroup(hotgroup: number | null) {
this.#hotgroup = hotgroup;
this.#updateMarker();
}
getHotgroup() {
@@ -172,7 +180,7 @@ export class Unit extends CustomMarker {
}
setHighlighted(highlighted: boolean) {
if (this.#highlighted != highlighted) {
if (this.getSelectable() && this.#highlighted != highlighted) {
this.getElement()?.querySelector(`[data-object|="unit"]`)?.toggleAttribute("data-is-highlighted", highlighted);
this.#highlighted = highlighted;
this.getGroupMembers().forEach((unit: Unit) => unit.setHighlighted(highlighted));
@@ -297,19 +305,13 @@ export class Unit extends CustomMarker {
this.setIcon(icon);
var el = document.createElement("div");
el.classList.add("unit");
el.setAttribute("data-object", `unit-${this.getMarkerCategory()}`);
el.setAttribute("data-coalition", this.getMissionData().coalition);
// Generate and append elements depending on active options
// State icon
if (this.getActiveMarkerElements().state){
var state = document.createElement("div");
state.classList.add("unit-state");
el.appendChild(state);
}
// Generate and append elements depending on active options
// Velocity vector
if (this.getActiveMarkerElements().vvi) {
if (this.getIconOptions().showVvi) {
var vvi = document.createElement("div");
vvi.classList.add("unit-vvi");
vvi.toggleAttribute("data-rotate-to-heading");
@@ -317,7 +319,7 @@ export class Unit extends CustomMarker {
}
// Hotgroup indicator
if (this.getActiveMarkerElements().hotgroup) {
if (this.getIconOptions().showHotgroup) {
var hotgroup = document.createElement("div");
hotgroup.classList.add("unit-hotgroup");
var hotgroupId = document.createElement("div");
@@ -327,26 +329,34 @@ export class Unit extends CustomMarker {
}
// Main icon
if (this.getActiveMarkerElements().unitIcon) {
if (this.getIconOptions().showUnitIcon) {
var unitIcon = document.createElement("div");
unitIcon.classList.add("unit-icon");
var img = document.createElement("img");
img.src = `/resources/theme/images/units/${this.getMarkerCategory()}.svg`;
img.onload = () => SVGInjector(img);
unitIcon.appendChild(img);
unitIcon.toggleAttribute("data-rotate-to-heading", this.getIconOptions().rotateToHeading);
el.append(unitIcon);
}
// State icon
if (this.getIconOptions().showState){
var state = document.createElement("div");
state.classList.add("unit-state");
el.appendChild(state);
}
// Short label
if (this.getActiveMarkerElements().shortLabel) {
if (this.getIconOptions().showShortLabel) {
var shortLabel = document.createElement("div");
shortLabel.classList.add("unit-short-label");
shortLabel.innerText = aircraftDatabase.getByName(this.getBaseData().name)?.shortLabel || ""; //TODO: fix, use correct database
shortLabel.innerText = this.getDatabase()?.getByName(this.getBaseData().name)?.shortLabel || "";
el.append(shortLabel);
}
// Fuel indicator
if (this.getActiveMarkerElements().fuel) {
if (this.getIconOptions().showFuel) {
var fuelIndicator = document.createElement("div");
fuelIndicator.classList.add("unit-fuel");
var fuelLevel = document.createElement("div");
@@ -356,7 +366,7 @@ export class Unit extends CustomMarker {
}
// Ammo indicator
if (this.getActiveMarkerElements().ammo){
if (this.getIconOptions().showAmmo){
var ammoIndicator = document.createElement("div");
ammoIndicator.classList.add("unit-ammo");
for (let i = 0; i <= 3; i++)
@@ -365,7 +375,7 @@ export class Unit extends CustomMarker {
}
// Unit summary
if (this.getActiveMarkerElements().summary) {
if (this.getIconOptions().showSummary) {
var summary = document.createElement("div");
summary.classList.add("unit-summary");
var callsign = document.createElement("div");
@@ -544,18 +554,18 @@ export class Unit extends CustomMarker {
}
#onContextMenu(e: any) {
var options: { [key: string]: string } = {};
var options: {[key: string]: {text: string, tooltip: string}} = {};
options["Center"] = `<div id="center-map">Center map</div>`;
options["center-map"] = {text: "Center map", tooltip: "Center the map on the unit and follow it"};
if (getUnitsManager().getSelectedUnits().length > 0 && !(getUnitsManager().getSelectedUnits().length == 1 && (getUnitsManager().getSelectedUnits().includes(this)))) {
options['Attack'] = `<div id="attack">Attack</div>`;
options["attack"] = {text: "Attack", tooltip: "Attack the unit using A/A or A/G weapons"};
if (getUnitsManager().getSelectedUnitsType() === "Aircraft")
options['Follow'] = `<div id="follow">Follow</div>`;
options["follow"] = {text: "Follow", tooltip: "Follow the unit at a user defined distance and position"};;
}
else if ((getUnitsManager().getSelectedUnits().length > 0 && (getUnitsManager().getSelectedUnits().includes(this))) || getUnitsManager().getSelectedUnits().length == 0) {
if (this.getBaseData().category == "Aircraft") {
options["Refuel"] = `<div id="refuel">Refuel</div>`; // TODO Add some way of knowing which aircraft can AAR
options["refuel"] = {text: "AAR Refuel", tooltip: "Refuel unit at the nearest AAR Tanker. If no tanker is available the unit will RTB."}; // TODO Add some way of knowing which aircraft can AAR
}
}
@@ -569,28 +579,28 @@ export class Unit extends CustomMarker {
}
#executeAction(e: any, action: string) {
if (action === "Center")
if (action === "center-map")
getMap().centerOnUnit(this.ID);
if (action === "Attack")
if (action === "attack")
getUnitsManager().selectedUnitsAttackUnit(this.ID);
else if (action === "Refuel")
else if (action === "refuel")
getUnitsManager().selectedUnitsRefuel();
else if (action === "Follow")
else if (action === "follow")
this.#showFollowOptions(e);
}
#showFollowOptions(e: any) {
var options: { [key: string]: string } = {};
var options: {[key: string]: {text: string, tooltip: string}} = {};
options = {
'Trail': `<div id="trail">Trail</div>`,
'Echelon (LH)': `<div id="echelon-lh">Echelon (left)</div>`,
'Echelon (RH)': `<div id="echelon-rh">Echelon (right)</div>`,
'Line abreast (LH)': `<div id="line-abreast">Line abreast (left)</div>`,
'Line abreast (RH)': `<div id="line-abreast">Line abreast (right)</div>`,
'Front': `<div id="front">In front</div>`,
'Diamond': `<div id="diamond">Diamond</div>`,
'Custom': `<div id="custom">Custom</div>`
'trail': {text: "Trail", tooltip: "Follow unit in trail formation"},
'echelon-lh': {text: "Echelon (LH)", tooltip: "Follow unit in echelon left formation"},
'echelon-rh': {text: "Echelon (RH)", tooltip: "Follow unit in echelon right formation"},
'line-abreast-lh': {text: "Line abreast (LH)", tooltip: "Follow unit in line abreast left formation"},
'line-abreast-rh': {text: "Line abreast (RH)", tooltip: "Follow unit in line abreast right formation"},
'front': {text: "Front", tooltip: "Fly in front of unit"},
'diamond': {text: "Diamond", tooltip: "Follow unit in diamond formation"},
'custom': {text: "Custom", tooltip: "Set a custom formation position"},
}
getMap().getUnitContextMenu().setOptions(options, (option: string) => {
@@ -601,7 +611,7 @@ export class Unit extends CustomMarker {
}
#applyFollowOptions(action: string) {
if (action === "Custom") {
if (action === "custom") {
document.getElementById("custom-formation-dialog")?.classList.remove("hide");
getMap().getUnitContextMenu().setCustomFormationCallback((offset: { x: number, y: number, z: number }) => {
getUnitsManager().selectedUnitsFollowUnit(this.ID, offset);
@@ -657,18 +667,18 @@ export class Unit extends CustomMarker {
element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.getBaseData().alive);
/* Set current unit state */
if (this.getMissionData().flags.Human) // Unit is human
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 (not 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());
/* Set altitude and speed */
if (element.querySelector(".unit-altitude"))
(<HTMLElement>element.querySelector(".unit-altitude")).innerText = "FL" + String(Math.floor(this.getFlightData().altitude / 0.3048 / 100));
if (element.querySelector(".unit-speed"))
(<HTMLElement>element.querySelector(".unit-speed")).innerHTML = String(Math.floor(this.getFlightData().speed * 1.94384));
(<HTMLElement>element.querySelector(".unit-speed")).innerText = String(Math.floor(this.getFlightData().speed * 1.94384));
/* Rotate elements according to heading */
element.querySelectorAll("[data-rotate-to-heading]").forEach(el => {
@@ -791,16 +801,17 @@ export class Unit extends CustomMarker {
}
export class AirUnit extends Unit {
getActiveMarkerElements() {
getIconOptions() {
return {
state: true,
vvi: true,
hotgroup: true,
unitIcon: true,
shortLabel: true,
fuel: true,
ammo: true,
summary: true
showState: true,
showVvi: true,
showHotgroup: true,
showUnitIcon: true,
showShortLabel: true,
showFuel: true,
showAmmo: true,
showSummary: true,
rotateToHeading: false
};
}
}
@@ -813,6 +824,10 @@ export class Aircraft extends AirUnit {
getMarkerCategory() {
return "aircraft";
}
getDatabase(): UnitDatabase | null {
return aircraftDatabase;
}
}
export class Helicopter extends AirUnit {
@@ -830,16 +845,17 @@ export class GroundUnit extends Unit {
super(ID, data);
}
getActiveMarkerElements() {
getIconOptions() {
return {
state: true,
vvi: false,
hotgroup: true,
unitIcon: true,
shortLabel: true,
fuel: false,
ammo: false,
summary: false
showState: true,
showVvi: false,
showHotgroup: true,
showUnitIcon: true,
showShortLabel: true,
showFuel: false,
showAmmo: false,
showSummary: false,
rotateToHeading: false
};
}
@@ -849,6 +865,10 @@ export class GroundUnit extends Unit {
var markerCategory = (role === "SAM") ? "groundunit-sam" : "groundunit-other";
return markerCategory;
}
getDatabase(): UnitDatabase | null {
return groundUnitsDatabase;
}
}
export class NavyUnit extends Unit {
@@ -856,16 +876,17 @@ export class NavyUnit extends Unit {
super(ID, data);
}
getActiveMarkerElements() {
getIconOptions() {
return {
state: true,
vvi: false,
hotgroup: true,
unitIcon: true,
shortLabel: true,
fuel: false,
ammo: false,
summary: false
showState: true,
showVvi: false,
showHotgroup: true,
showUnitIcon: true,
showShortLabel: true,
showFuel: false,
showAmmo: false,
showSummary: false,
rotateToHeading: false
};
}
@@ -879,6 +900,20 @@ export class Weapon extends Unit {
super(ID, data);
this.setSelectable(false);
}
getIconOptions() {
return {
showState: false,
showVvi: false,
showHotgroup: false,
showUnitIcon: true,
showShortLabel: false,
showFuel: false,
showAmmo: false,
showSummary: false,
rotateToHeading: true
};
}
}
export class Missile extends Weapon {

View File

@@ -1,21 +1,16 @@
export class UnitDatabase {
blueprints: {[key: string]: UnitBlueprint} = {};
blueprints: { [key: string]: UnitBlueprint } = {};
constructor()
{
constructor() {
}
/* Returns a list of all possible roles in a database */
getRoles()
{
getRoles() {
var roles: string[] = [];
for (let unit in this.blueprints)
{
for (let loadout of this.blueprints[unit].loadouts)
{
for (let role of loadout.roles)
{
for (let unit in this.blueprints) {
for (let loadout of this.blueprints[unit].loadouts) {
for (let role of loadout.roles) {
if (role !== "" && !roles.includes(role))
roles.push(role);
}
@@ -25,18 +20,15 @@ export class UnitDatabase {
}
/* Gets a specific blueprint by name */
getByName(name: string)
{
getByName(name: string) {
if (name in this.blueprints)
return this.blueprints[name];
return null;
}
/* Gets a specific blueprint by label */
getByLabel(label: string)
{
for (let unit in this.blueprints)
{
getByLabel(label: string) {
for (let unit in this.blueprints) {
if (this.blueprints[unit].label === label)
return this.blueprints[unit];
}
@@ -44,15 +36,11 @@ export class UnitDatabase {
}
/* Get all blueprints by role */
getByRole(role: string)
{
getByRole(role: string) {
var units = [];
for (let unit in this.blueprints)
{
for (let loadout of this.blueprints[unit].loadouts)
{
if (loadout.roles.includes(role) || loadout.roles.includes(role.toLowerCase()))
{
for (let unit in this.blueprints) {
for (let loadout of this.blueprints[unit].loadouts) {
if (loadout.roles.includes(role) || loadout.roles.includes(role.toLowerCase())) {
units.push(this.blueprints[unit])
break;
}
@@ -62,13 +50,10 @@ export class UnitDatabase {
}
/* Get the names of all the loadouts for a specific unit and for a specific role */
getLoadoutNamesByRole(name: string, role: string)
{
getLoadoutNamesByRole(name: string, role: string) {
var loadouts = [];
for (let loadout of this.blueprints[name].loadouts)
{
if (loadout.roles.includes(role) || loadout.roles.includes(""))
{
for (let loadout of this.blueprints[name].loadouts) {
if (loadout.roles.includes(role) || loadout.roles.includes("")) {
loadouts.push(loadout.name)
}
}
@@ -76,10 +61,8 @@ export class UnitDatabase {
}
/* Get the loadout content from the unit name and loadout name */
getLoadoutByName(name: string, loadoutName: string)
{
for (let loadout of this.blueprints[name].loadouts)
{
getLoadoutByName(name: string, loadoutName: string) {
for (let loadout of this.blueprints[name].loadouts) {
if (loadout.name === loadoutName)
return loadout;
}

View File

@@ -47,7 +47,7 @@ export class UnitsManager {
}
getUnitsByHotgroup(hotgroup: number) {
return Object.values(this.#units).filter((unit: Unit) => {return unit.getBaseData().alive && unit.getHotgroup() == hotgroup});
return Object.values(this.#units).filter((unit: Unit) => { return unit.getBaseData().alive && unit.getHotgroup() == hotgroup });
}
addUnit(ID: number, data: UnitData) {
@@ -88,10 +88,8 @@ export class UnitsManager {
});
}
setHiddenType(key: string, value: boolean)
{
if (value)
{
setHiddenType(key: string, value: boolean) {
if (value) {
if (this.#hiddenTypes.includes(key))
delete this.#hiddenTypes[this.#hiddenTypes.indexOf(key)];
}
@@ -100,8 +98,7 @@ export class UnitsManager {
Object.values(this.getUnits()).forEach((unit: Unit) => unit.updateVisibility());
}
getHiddenTypes()
{
getHiddenTypes() {
return this.#hiddenTypes;
}
@@ -123,7 +120,7 @@ export class UnitsManager {
}
}
getSelectedUnits(options?: {excludeHumans?: boolean}) {
getSelectedUnits(options?: { excludeHumans?: boolean }) {
var selectedUnits = [];
for (let ID in this.#units) {
if (this.#units[ID].getSelected()) {
@@ -132,7 +129,7 @@ export class UnitsManager {
}
if (options) {
if (options.excludeHumans)
selectedUnits = selectedUnits.filter((unit: Unit) => {return !unit.getMissionData().flags.Human});
selectedUnits = selectedUnits.filter((unit: Unit) => { return !unit.getMissionData().flags.Human });
}
return selectedUnits;
}
@@ -190,14 +187,14 @@ export class UnitsManager {
/*********************** Actions on selected units ************************/
selectedUnitsAddDestination(latlng: L.LatLng, mantainRelativePosition: boolean, rotation: number) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
/* Compute the destination for each unit. If mantainRelativePosition is true, compute the destination so to hold the relative distances */
var unitDestinations: {[key: number]: LatLng} = {};
var unitDestinations: { [key: number]: LatLng } = {};
if (mantainRelativePosition)
unitDestinations = this.selectedUnitsComputeGroupDestination(latlng, rotation);
else
selectedUnits.forEach((unit: Unit) => {unitDestinations[unit.ID] = latlng});
selectedUnits.forEach((unit: Unit) => { unitDestinations[unit.ID] = latlng });
for (let idx in selectedUnits) {
const unit = selectedUnits[idx];
@@ -206,7 +203,7 @@ export class UnitsManager {
const leader = this.getUnitByID(unit.getFormationData().leaderID)
if (leader && leader.getSelected())
leader.addDestination(latlng);
else
else
unit.addDestination(latlng);
}
else {
@@ -219,7 +216,7 @@ export class UnitsManager {
}
selectedUnitsClearDestinations() {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
const unit = selectedUnits[idx];
if (unit.getTaskData().currentState === "Follow") {
@@ -235,7 +232,7 @@ export class UnitsManager {
}
selectedUnitsLandAt(latlng: LatLng) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].landAt(latlng);
}
@@ -243,21 +240,21 @@ export class UnitsManager {
}
selectedUnitsChangeSpeed(speedChange: string) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].changeSpeed(speedChange);
}
}
selectedUnitsChangeAltitude(altitudeChange: string) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].changeAltitude(altitudeChange);
}
}
selectedUnitsSetSpeed(speed: number) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].setSpeed(speed);
}
@@ -265,7 +262,7 @@ export class UnitsManager {
}
selectedUnitsSetAltitude(altitude: number) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].setAltitude(altitude);
}
@@ -273,7 +270,7 @@ export class UnitsManager {
}
selectedUnitsSetROE(ROE: string) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].setROE(ROE);
}
@@ -281,7 +278,7 @@ export class UnitsManager {
}
selectedUnitsSetReactionToThreat(reactionToThreat: string) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].setReactionToThreat(reactionToThreat);
}
@@ -289,7 +286,7 @@ export class UnitsManager {
}
selectedUnitsSetEmissionsCountermeasures(emissionCountermeasure: string) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].setEmissionsCountermeasures(emissionCountermeasure);
}
@@ -298,7 +295,7 @@ export class UnitsManager {
selectedUnitsAttackUnit(ID: number) {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].attackUnit(ID);
}
@@ -314,7 +311,7 @@ export class UnitsManager {
}
selectedUnitsRefuel() {
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].refuel();
}
@@ -328,15 +325,15 @@ export class UnitsManager {
// Y: top-bottom, positive top
// Z: left-right, positive right
offset = { "x": 0, "y": 0, "z": 0 };
if (formation === "Trail") { offset.x = -50; offset.y = -30; offset.z = 0; }
else if (formation === "Echelon (LH)") { offset.x = -50; offset.y = -10; offset.z = -50; }
else if (formation === "Echelon (RH)") { offset.x = -50; offset.y = -10; offset.z = 50; }
else if (formation === "Line abreast (RH)") { offset.x = 0; offset.y = 0; offset.z = 50; }
else if (formation === "Line abreast (LH)") { offset.x = 0; offset.y = 0; offset.z = -50; }
else if (formation === "Front") { offset.x = 100; offset.y = 0; offset.z = 0; }
if (formation === "trail") { offset.x = -50; offset.y = -30; offset.z = 0; }
else if (formation === "echelon-lh") { offset.x = -50; offset.y = -10; offset.z = -50; }
else if (formation === "echelon-rh") { offset.x = -50; offset.y = -10; offset.z = 50; }
else if (formation === "line-abreast-rh") { offset.x = 0; offset.y = 0; offset.z = 50; }
else if (formation === "line-abreast-lh") { offset.x = 0; offset.y = 0; offset.z = -50; }
else if (formation === "front") { offset.x = 100; offset.y = 0; offset.z = 0; }
else offset = undefined;
}
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
var count = 1;
var xr = 0; var yr = 1; var zr = -1;
var layer = 1;
@@ -347,7 +344,7 @@ export class UnitsManager {
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") {
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);
unit.followUnit(ID, { "x": -yl * 50, "y": zr * 10, "z": xl * 50 });
@@ -364,14 +361,12 @@ export class UnitsManager {
this.#showActionMessage(selectedUnits, `following unit ${this.getUnitByID(ID)?.getBaseData().unitName}`);
}
selectedUnitsSetHotgroup(hotgroup: number)
{
selectedUnitsSetHotgroup(hotgroup: number) {
this.getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setHotgroup(null));
this.selectedUnitsAddToHotgroup(hotgroup);
}
selectedUnitsAddToHotgroup(hotgroup: number)
{
selectedUnitsAddToHotgroup(hotgroup: number) {
var selectedUnits = this.getSelectedUnits();
for (let idx in selectedUnits) {
selectedUnits[idx].setHotgroup(hotgroup);
@@ -380,11 +375,10 @@ export class UnitsManager {
getHotgroupPanel().refreshHotgroups();
}
selectedUnitsComputeGroupDestination(latlng: LatLng, rotation: number)
{
var selectedUnits = this.getSelectedUnits({excludeHumans: true});
selectedUnitsComputeGroupDestination(latlng: LatLng, rotation: number) {
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
/* Compute the center of the group */
var center = {x: 0, y: 0};
var center = { x: 0, y: 0 };
selectedUnits.forEach((unit: Unit) => {
var mercator = latLngToMercator(unit.getFlightData().latitude, unit.getFlightData().longitude);
center.x += mercator.x / selectedUnits.length;
@@ -392,20 +386,19 @@ export class UnitsManager {
});
/* Compute the distances from the center of the group */
var unitDestinations: {[key: number]: LatLng} = {};
var unitDestinations: { [key: number]: LatLng } = {};
selectedUnits.forEach((unit: Unit) => {
var mercator = latLngToMercator(unit.getFlightData().latitude, unit.getFlightData().longitude);
var distancesFromCenter = {dx: mercator.x - center.x, dy: mercator.y - center.y};
var distancesFromCenter = { dx: mercator.x - center.x, dy: mercator.y - center.y };
/* Rotate the distance according to the group rotation */
var rotatedDistancesFromCenter: {dx: number, dy: number} = {dx: 0, dy: 0};
var rotatedDistancesFromCenter: { dx: number, dy: number } = { dx: 0, dy: 0 };
rotatedDistancesFromCenter.dx = distancesFromCenter.dx * Math.cos(deg2rad(rotation)) - distancesFromCenter.dy * Math.sin(deg2rad(rotation));
rotatedDistancesFromCenter.dy = distancesFromCenter.dx * Math.sin(deg2rad(rotation)) + distancesFromCenter.dy * Math.cos(deg2rad(rotation));
/* Compute the final position of the unit */
var destMercator = latLngToMercator(latlng.lat, latlng.lng); // Convert destination point to mercator
var unitMercator = {x: destMercator.x + rotatedDistancesFromCenter.dx, y: destMercator.y + rotatedDistancesFromCenter.dy}; // Compute final position of this unit in mercator coordinates
var unitMercator = { x: destMercator.x + rotatedDistancesFromCenter.dx, y: destMercator.y + rotatedDistancesFromCenter.dy }; // Compute final position of this unit in mercator coordinates
var unitLatLng = mercatorToLatLng(unitMercator.x, unitMercator.y);
unitDestinations[unit.ID] = new LatLng(unitLatLng.lat, unitLatLng.lng);
});