mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Multiple fixes
Refactored classes Fixed visibility of dead units Changed visibility handling Refactored unitDatabase class
This commit is contained in:
@@ -112,8 +112,8 @@ export class MapContextMenu extends ContextMenu {
|
||||
#setAircraftRole(role: string)
|
||||
{
|
||||
this.#spawnOptions.role = role;
|
||||
this.#resetAircraftRole();
|
||||
this.#aircraftTypeDropdown.setOptions(aircraftDatabase.getLabelsByRole(role));
|
||||
this.#resetAircraftType();
|
||||
this.#aircraftTypeDropdown.setOptions(aircraftDatabase.getByRole(role).map((blueprint) => {return blueprint.label}));
|
||||
this.#aircraftTypeDropdown.selectValue(0);
|
||||
this.clip();
|
||||
}
|
||||
@@ -130,7 +130,7 @@ export class MapContextMenu extends ContextMenu {
|
||||
#setAircraftType(label: string)
|
||||
{
|
||||
this.#resetAircraftType();
|
||||
var type = aircraftDatabase.getNameByLabel(label);
|
||||
var type = aircraftDatabase.getByLabel(label)?.name || null;
|
||||
if (type != null)
|
||||
{
|
||||
this.#spawnOptions.type = type;
|
||||
@@ -154,7 +154,7 @@ export class MapContextMenu extends ContextMenu {
|
||||
|
||||
#setAircraftLoadout(loadoutName: string)
|
||||
{
|
||||
var loadout = aircraftDatabase.getLoadoutsByName(this.#spawnOptions.type, loadoutName);
|
||||
var loadout = aircraftDatabase.getLoadoutByName(this.#spawnOptions.type, loadoutName);
|
||||
if (loadout)
|
||||
{
|
||||
this.#spawnOptions.loadout = loadout.code;
|
||||
@@ -177,7 +177,7 @@ export class MapContextMenu extends ContextMenu {
|
||||
{
|
||||
this.#spawnOptions.role = role;
|
||||
this.#resetGroundUnitRole();
|
||||
this.#groundUnitTypeDropdown.setOptions(groundUnitsDatabase.getLabelsByRole(role));
|
||||
this.#groundUnitTypeDropdown.setOptions(groundUnitsDatabase.getByRole(role).map((blueprint) => {return blueprint.label}));
|
||||
this.#groundUnitTypeDropdown.selectValue(0);
|
||||
this.clip();
|
||||
}
|
||||
@@ -194,7 +194,7 @@ export class MapContextMenu extends ContextMenu {
|
||||
#setGroundUnitType(label: string)
|
||||
{
|
||||
this.#resetGroundUnitType();
|
||||
var type = groundUnitsDatabase.getNameByLabel(label);
|
||||
var type = groundUnitsDatabase.getByLabel(label)?.name || null;
|
||||
if (type != null)
|
||||
{
|
||||
this.#spawnOptions.type = type;
|
||||
|
||||
@@ -184,15 +184,6 @@ function setupEvents() {
|
||||
}
|
||||
//*/
|
||||
|
||||
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
|
||||
ev.detail._element.classList.toggle("off");
|
||||
document.body.toggleAttribute("data-hide-" + ev.detail.coalition);
|
||||
});
|
||||
|
||||
document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => {
|
||||
document.body.toggleAttribute("data-hide-" + ev.detail.category);
|
||||
});
|
||||
|
||||
document.addEventListener( "closeDialog", (ev: CustomEventInit) => {
|
||||
ev.detail._element.closest( ".ol-dialog" ).classList.add( "hide" );
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import { UnitContextMenu } from "../controls/unitcontextmenu";
|
||||
import { AirbaseContextMenu } from "../controls/airbasecontextmenu";
|
||||
import { Dropdown } from "../controls/dropdown";
|
||||
import { Airbase } from "../missionhandler/airbase";
|
||||
import { Unit } from "../units/unit";
|
||||
|
||||
export const IDLE = "IDLE";
|
||||
export const MOVE_UNIT = "MOVE_UNIT";
|
||||
@@ -45,6 +46,17 @@ export class Map extends L.Map {
|
||||
this.on('mouseup', (e: any) => this.#onMouseUp(e));
|
||||
this.on('mousemove', (e: any) => this.#onMouseMove(e));
|
||||
|
||||
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
|
||||
ev.detail._element.classList.toggle("off");
|
||||
document.body.toggleAttribute("data-hide-" + ev.detail.coalition);
|
||||
Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility());
|
||||
});
|
||||
|
||||
document.addEventListener("toggleUnitVisibility", (ev: CustomEventInit) => {
|
||||
document.body.toggleAttribute("data-hide-" + ev.detail.category);
|
||||
Object.values(getUnitsManager().getUnits()).forEach((unit: Unit) => unit.updateVisibility());
|
||||
});
|
||||
|
||||
this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName), this.getLayers())
|
||||
}
|
||||
|
||||
|
||||
@@ -3,23 +3,24 @@ import { Slider } from "../controls/slider";
|
||||
import { aircraftDatabase } from "../units/aircraftdatabase";
|
||||
import { groundUnitsDatabase } from "../units/groundunitsdatabase";
|
||||
import { Aircraft, GroundUnit, Unit } from "../units/unit";
|
||||
import { UnitDatabase } from "../units/unitdatabase";
|
||||
import { UnitsManager } from "../units/unitsmanager";
|
||||
import { Panel } from "./panel";
|
||||
|
||||
const ROEs: string[] = ["Free", "Designated free", "Designated", "Return", "Hold"];
|
||||
const reactionsToThreat: string[] = [ "None", "Passive", "Evade", "Escape", "Abort"];
|
||||
const minSpeedValues: {[key: string]: number} = {Aircraft: 100, Helicopter: 0, NavyUnit: 0, GroundUnit: 0};
|
||||
const maxSpeedValues: {[key: string]: number} = {Aircraft: 800, Helicopter: 300, NavyUnit: 60, GroundUnit: 60};
|
||||
const speedIncrements: {[key: string]: number} = {Aircraft: 25, Helicopter: 10, NavyUnit: 5, GroundUnit: 5};
|
||||
const minAltitudeValues: {[key: string]: number} = {Aircraft: 0, Helicopter: 0};
|
||||
const maxAltitudeValues: {[key: string]: number} = {Aircraft: 50000, Helicopter: 10000};
|
||||
const altitudeIncrements: {[key: string]: number} = {Aircraft: 2500, Helicopter: 1000};
|
||||
const reactionsToThreat: string[] = ["None", "Passive", "Evade", "Escape", "Abort"];
|
||||
const minSpeedValues: { [key: string]: number } = { Aircraft: 100, Helicopter: 0, NavyUnit: 0, GroundUnit: 0 };
|
||||
const maxSpeedValues: { [key: string]: number } = { Aircraft: 800, Helicopter: 300, NavyUnit: 60, GroundUnit: 60 };
|
||||
const speedIncrements: { [key: string]: number } = { Aircraft: 25, Helicopter: 10, NavyUnit: 5, GroundUnit: 5 };
|
||||
const minAltitudeValues: { [key: string]: number } = { Aircraft: 0, Helicopter: 0 };
|
||||
const maxAltitudeValues: { [key: string]: number } = { Aircraft: 50000, Helicopter: 10000 };
|
||||
const altitudeIncrements: { [key: string]: number } = { Aircraft: 2500, Helicopter: 1000 };
|
||||
|
||||
export class UnitControlPanel extends Panel {
|
||||
#altitudeSlider: Slider;
|
||||
#airspeedSlider: Slider;
|
||||
#optionButtons: {[key: string]: HTMLButtonElement[]} = {}
|
||||
|
||||
#optionButtons: { [key: string]: HTMLButtonElement[] } = {}
|
||||
|
||||
constructor(ID: string) {
|
||||
super(ID);
|
||||
|
||||
@@ -28,87 +29,66 @@ export class UnitControlPanel extends Panel {
|
||||
this.#airspeedSlider = new Slider("airspeed-slider", 0, 100, "kts", (value: number) => getUnitsManager().selectedUnitsSetSpeed(value / 1.94384));
|
||||
|
||||
/* Option buttons */
|
||||
this.#optionButtons["ROE"] = ROEs.map((option: string, index:number) => {
|
||||
this.#optionButtons["ROE"] = ROEs.map((option: string, index: number) => {
|
||||
var button = document.createElement("button");
|
||||
button.title = option;
|
||||
button.value = option;
|
||||
button.addEventListener("click", () => {getUnitsManager().selectedUnitsSetROE(button.title);});
|
||||
button.addEventListener("click", () => { getUnitsManager().selectedUnitsSetROE(button.title); });
|
||||
return button;
|
||||
});
|
||||
|
||||
this.#optionButtons["reactionToThreat"] = reactionsToThreat.map((option: string, index:number) => {
|
||||
this.#optionButtons["reactionToThreat"] = reactionsToThreat.map((option: string, index: number) => {
|
||||
var button = document.createElement("button");
|
||||
button.title = option;
|
||||
button.value = option;
|
||||
button.addEventListener("click", () => {getUnitsManager().selectedUnitsSetReactionToThreat(button.title);});
|
||||
button.addEventListener("click", () => { getUnitsManager().selectedUnitsSetReactionToThreat(button.title); });
|
||||
return button;
|
||||
});
|
||||
|
||||
this.getElement().querySelector("#roe-buttons-container")?.append(...this.#optionButtons["ROE"]);
|
||||
this.getElement().querySelector("#reaction-to-threat-buttons-container")?.append(...this.#optionButtons["reactionToThreat"]);
|
||||
|
||||
document.addEventListener("unitUpdated", (e: CustomEvent<Unit>) => {if (e.detail.getSelected()) this.update()});
|
||||
document.addEventListener("unitsSelection", (e: CustomEvent<Unit[]>) => {this.show(); this.update()});
|
||||
document.addEventListener("clearSelection", () => {this.hide()});
|
||||
document.addEventListener("unitUpdated", (e: CustomEvent<Unit>) => { if (e.detail.getSelected()) this.update() });
|
||||
document.addEventListener("unitsSelection", (e: CustomEvent<Unit[]>) => { this.show(); this.update() });
|
||||
document.addEventListener("clearSelection", () => { this.hide() });
|
||||
|
||||
this.hide();
|
||||
}
|
||||
|
||||
update() {
|
||||
var units = getUnitsManager().getSelectedUnits();
|
||||
if (this.getElement() != null && units.length > 0)
|
||||
{
|
||||
if (this.getElement() != null && units.length > 0) {
|
||||
this.#showFlightControlSliders(units);
|
||||
|
||||
this.getElement().querySelector("#selected-units-container")?.replaceChildren(...units.map((unit: Unit, index:number) =>
|
||||
{
|
||||
|
||||
const baseData = unit.getBaseData();
|
||||
this.getElement().querySelector("#selected-units-container")?.replaceChildren(...units.map((unit: Unit, index: number) => {
|
||||
let database: UnitDatabase | null;
|
||||
if (unit instanceof Aircraft)
|
||||
database = aircraftDatabase;
|
||||
else if (unit instanceof GroundUnit)
|
||||
database = groundUnitsDatabase;
|
||||
else
|
||||
database = null; // TODO add databases for other unit types
|
||||
|
||||
if ( index === 0 ) {
|
||||
|
||||
this.getElement().querySelectorAll(`[data-object|="unit"]`).forEach( marker => {
|
||||
marker.setAttribute( "data-coalition", unit.getMissionData().coalition );
|
||||
const shortLabel = <HTMLElement>marker.querySelector( ".unit-short-label" );
|
||||
if ( shortLabel ) {
|
||||
shortLabel.innerText = aircraftDatabase.getShortLabelByName( baseData.name );
|
||||
}
|
||||
if (index === 0) {
|
||||
this.getElement().querySelectorAll(`[data-object|="unit"]`).forEach(marker => {
|
||||
marker.setAttribute("data-coalition", unit.getMissionData().coalition);
|
||||
const shortLabel = <HTMLElement>marker.querySelector(".unit-short-label");
|
||||
if (shortLabel)
|
||||
shortLabel.innerText = database?.getByName(unit.getBaseData().name)?.shortLabel || "";
|
||||
});
|
||||
}
|
||||
|
||||
var button = document.createElement("button");
|
||||
const unitName = <HTMLInputElement>this.getElement().querySelector("#unit-name");
|
||||
var callsign = aircraftDatabase.getByName(unit.getBaseData().unitName)?.label || "";
|
||||
|
||||
let callsign;
|
||||
button.innerText = "";
|
||||
button.setAttribute("data-short-label", database?.getByName(unit.getBaseData().name)?.shortLabel || "");
|
||||
button.setAttribute("data-callsign", callsign);
|
||||
unitName.value = callsign;
|
||||
|
||||
const unitName = <HTMLInputElement>this.getElement().querySelector( "#unit-name" );
|
||||
|
||||
if (unit instanceof Aircraft) {
|
||||
button.innerText = "";
|
||||
button.setAttribute( "data-short-label", aircraftDatabase.getLabelByName( baseData.name ) );
|
||||
|
||||
callsign = aircraftDatabase.getLabelByName( baseData.unitName );
|
||||
|
||||
button.setAttribute( "data-callsign", callsign );
|
||||
unitName.value = callsign;
|
||||
|
||||
} else if (unit instanceof GroundUnit) {
|
||||
|
||||
button.setAttribute( "data-short-label", groundUnitsDatabase.getShortLabelByName(baseData.name));
|
||||
|
||||
callsign = aircraftDatabase.getLabelByName( baseData.unitName ) || "";
|
||||
|
||||
button.setAttribute( "data-callsign", groundUnitsDatabase.getLabelByName( baseData.unitName ) );
|
||||
unitName.value = callsign;
|
||||
|
||||
} else {
|
||||
|
||||
button.setAttribute( "data-short-label", "");
|
||||
button.setAttribute( "data-callsign", "" );
|
||||
|
||||
}
|
||||
|
||||
button.setAttribute( "data-coalition", unit.getMissionData().coalition );
|
||||
button.classList.add( "pill", "highlight-coalition" )
|
||||
button.setAttribute("data-coalition", unit.getMissionData().coalition);
|
||||
button.classList.add("pill", "highlight-coalition")
|
||||
|
||||
button.addEventListener("click", () => getUnitsManager().selectUnit(unit.ID, true));
|
||||
return (button);
|
||||
@@ -116,16 +96,15 @@ export class UnitControlPanel extends Panel {
|
||||
|
||||
this.#optionButtons["ROE"].forEach((button: HTMLButtonElement) => {
|
||||
button.classList.toggle("selected", units.every((unit: Unit) => unit.getOptionsData().ROE === button.value))
|
||||
});
|
||||
});
|
||||
|
||||
this.#optionButtons["reactionToThreat"].forEach((button: HTMLButtonElement) => {
|
||||
button.classList.toggle("selected", units.every((unit: Unit) => unit.getOptionsData().reactionToThreat === button.value))
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#showFlightControlSliders(units: Unit[])
|
||||
{
|
||||
#showFlightControlSliders(units: Unit[]) {
|
||||
this.#airspeedSlider.show();
|
||||
this.#altitudeSlider.show();
|
||||
|
||||
@@ -133,8 +112,7 @@ export class UnitControlPanel extends Panel {
|
||||
var targetAltitude = getUnitsManager().getSelectedUnitsTargetAltitude();
|
||||
var targetSpeed = getUnitsManager().getSelectedUnitsTargetSpeed();
|
||||
|
||||
if (unitsType != undefined)
|
||||
{
|
||||
if (unitsType != undefined) {
|
||||
if (["GroundUnit", "NavyUnit"].includes(unitsType))
|
||||
this.#altitudeSlider.hide()
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export class UnitInfoPanel extends Panel {
|
||||
const baseData = unit.getBaseData();
|
||||
|
||||
/* Set the unit info */
|
||||
this.#unitLabel.innerText = aircraftDatabase.getLabelByName( baseData.name );
|
||||
this.#unitLabel.innerText = aircraftDatabase.getByName(baseData.name)?.label || "";
|
||||
this.#unitName.innerText = baseData.unitName;
|
||||
this.#unitControl.innerText = ( ( baseData.AI ) ? "AI" : "Human" ) + " controlled";
|
||||
// this.#groupName.innerText = baseData.groupName;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { UnitDatabase } from "./unitdatabase"
|
||||
export class AircraftDatabase extends UnitDatabase {
|
||||
constructor() {
|
||||
super();
|
||||
this.units = {
|
||||
this.blueprints = {
|
||||
|
||||
"A-10C": {
|
||||
"name": "A-10C",
|
||||
|
||||
@@ -3,7 +3,7 @@ import { UnitDatabase } from "./unitdatabase"
|
||||
export class GroundUnitsDatabase extends UnitDatabase {
|
||||
constructor() {
|
||||
super();
|
||||
this.units = {
|
||||
this.blueprints = {
|
||||
"2B11 mortar": {
|
||||
"name": "2B11 mortar",
|
||||
"label": "2B11 mortar",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Marker, LatLng, Polyline, Icon, DivIcon } from 'leaflet';
|
||||
import { getMap, getUnitsManager } from '..';
|
||||
import { rad2deg } from '../other/utils';
|
||||
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, landAt, setAltitude, setReactionToThreat, setROE, setSpeed } from '../server/server';
|
||||
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, getUnits, landAt, setAltitude, setReactionToThreat, setROE, setSpeed } from '../server/server';
|
||||
import { aircraftDatabase } from './aircraftdatabase';
|
||||
import { groundUnitsDatabase } from './groundunitsdatabase';
|
||||
|
||||
@@ -79,7 +79,7 @@ export class Unit extends Marker {
|
||||
if (type === "NavyUnit") return NavyUnit;
|
||||
}
|
||||
|
||||
constructor(ID: number, data: UpdateData, html: string) {
|
||||
constructor(ID: number, data: UpdateData) {
|
||||
super(new LatLng(0, 0), { riseOnHover: true });
|
||||
|
||||
this.ID = ID;
|
||||
@@ -89,19 +89,12 @@ 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));
|
||||
|
||||
var icon = new DivIcon({
|
||||
html: html,
|
||||
className: 'leaflet-unit-marker',
|
||||
iconAnchor: [0, 0]
|
||||
});
|
||||
this.setIcon(icon);
|
||||
|
||||
|
||||
this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 });
|
||||
this.#pathPolyline.addTo(getMap());
|
||||
this.#targetsPolylines = [];
|
||||
|
||||
// Deselect units if they are hidden
|
||||
/* Deselect units if they are hidden */
|
||||
document.addEventListener("toggleCoalitionVisibility", (ev: CustomEventInit) => {
|
||||
setTimeout(() => {this.setSelected(this.getSelected() && !this.getHidden())}, 300);
|
||||
});
|
||||
@@ -110,7 +103,31 @@ export class Unit extends Marker {
|
||||
setTimeout(() => {this.setSelected(this.getSelected() && !this.getHidden())}, 300);
|
||||
});
|
||||
|
||||
/* Set the unit data */
|
||||
this.setData(data);
|
||||
|
||||
/* Set the icon */
|
||||
var icon = new DivIcon({
|
||||
html: this.getMarkerHTML(),
|
||||
className: 'leaflet-unit-marker',
|
||||
iconAnchor: [0, 0]
|
||||
});
|
||||
this.setIcon(icon);
|
||||
|
||||
}
|
||||
|
||||
getMarkerHTML() {
|
||||
return `<div class="unit" data-object="unit-${this.getMarkerCategory()}" data-coalition="${this.getMissionData().coalition}">
|
||||
<div class="unit-selected-spotlight"></div>
|
||||
<div class="unit-marker"></div>
|
||||
<div class="unit-short-label"></div>
|
||||
</div>`
|
||||
}
|
||||
|
||||
getMarkerCategory()
|
||||
{
|
||||
// Overloaded by child classes
|
||||
return "";
|
||||
}
|
||||
|
||||
setData(data: UpdateData) {
|
||||
@@ -118,6 +135,7 @@ export class Unit extends Marker {
|
||||
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;
|
||||
@@ -253,13 +271,30 @@ export class Unit extends Marker {
|
||||
this.getTaskData().activePath = undefined;
|
||||
}
|
||||
|
||||
updateVisibility()
|
||||
{
|
||||
this.setHidden( document.body.getAttribute(`data-hide-${this.getMissionData().coalition}`) != null ||
|
||||
document.body.getAttribute(`data-hide-${this.getMarkerCategory()}`) != null ||
|
||||
!this.getBaseData().alive)
|
||||
}
|
||||
|
||||
setHidden(hidden: boolean)
|
||||
{
|
||||
this.#hidden = hidden;
|
||||
this.#hidden = hidden;
|
||||
|
||||
/* Add the marker if not present */
|
||||
if (!getMap().hasLayer(this) && !this.getHidden()) {
|
||||
this.addTo(getMap());
|
||||
}
|
||||
|
||||
/* Hide the marker if necessary*/
|
||||
if (getMap().hasLayer(this) && this.getHidden()) {
|
||||
getMap().removeLayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
getHidden() {
|
||||
return (<HTMLElement>this.getElement()?.querySelector(`.unit`))?.offsetParent === null;
|
||||
return this.#hidden;
|
||||
}
|
||||
|
||||
getLeader() {
|
||||
@@ -282,10 +317,6 @@ export class Unit extends Marker {
|
||||
return wingmen;
|
||||
}
|
||||
|
||||
forceUpdate() {
|
||||
this.#forceUpdate = true;
|
||||
}
|
||||
|
||||
attackUnit(targetID: number) {
|
||||
/* Call DCS attackUnit function */
|
||||
if (this.ID != targetID) {
|
||||
@@ -355,11 +386,14 @@ export class Unit extends Marker {
|
||||
var options = [
|
||||
'Attack'
|
||||
]
|
||||
getMap().showUnitContextMenu(e);
|
||||
getMap().getUnitContextMenu().setOptions(options, (option: string) => {
|
||||
getMap().hideUnitContextMenu();
|
||||
this.#executeAction(option);
|
||||
});
|
||||
if (getUnitsManager().getSelectedUnits().length > 0 && !(getUnitsManager().getSelectedUnits().includes(this)))
|
||||
{
|
||||
getMap().showUnitContextMenu(e);
|
||||
getMap().getUnitContextMenu().setOptions(options, (option: string) => {
|
||||
getMap().hideUnitContextMenu();
|
||||
this.#executeAction(option);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#executeAction(action: string) {
|
||||
@@ -368,21 +402,13 @@ export class Unit extends Marker {
|
||||
}
|
||||
|
||||
#updateMarker() {
|
||||
/* Add the marker if not present */
|
||||
if (!getMap().hasLayer(this) && !this.getHidden()) {
|
||||
this.addTo(getMap());
|
||||
}
|
||||
this.updateVisibility();
|
||||
|
||||
/* Hide the marker if necessary*/
|
||||
if (getMap().hasLayer(this) && this.getHidden()) {
|
||||
getMap().removeLayer(this);
|
||||
}
|
||||
else {
|
||||
if (!this.getHidden()) {
|
||||
|
||||
this.setLatLng(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude));
|
||||
var element = this.getElement();
|
||||
if (element != null) {
|
||||
|
||||
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");
|
||||
|
||||
@@ -401,9 +427,8 @@ export class Unit extends Marker {
|
||||
|
||||
}
|
||||
|
||||
const headingDeg = rad2deg( this.getFlightData().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);` );
|
||||
});
|
||||
@@ -494,93 +519,111 @@ export class AirUnit extends Unit {
|
||||
|
||||
export class Aircraft extends AirUnit {
|
||||
constructor(ID: number, data: UnitData) {
|
||||
super(ID, data,
|
||||
`<div class="unit" data-object="unit-air-aircraft" data-status="" data-coalition="${data.missionData.coalition}">
|
||||
<div class="unit-selected-spotlight"></div>
|
||||
<div class="unit-marker-border"></div>
|
||||
<div class="unit-status"></div>
|
||||
<div class="unit-vvi" data-rotate-to-heading></div>
|
||||
<div class="unit-hotgroup">
|
||||
<div class="unit-hotgroup-id"></div>
|
||||
</div>
|
||||
<div class="unit-marker"></div>
|
||||
<div class="unit-short-label">${aircraftDatabase.getShortLabelByName(data.baseData.name)}</div>
|
||||
<div class="unit-fuel">
|
||||
<div class="unit-fuel-level" style="width:100%;"></div>
|
||||
</div>
|
||||
<div class="unit-ammo">
|
||||
<div class="unit-ammo-fox-1"></div>
|
||||
<div class="unit-ammo-fox-2"></div>
|
||||
<div class="unit-ammo-fox-3"></div>
|
||||
<div class="unit-ammo-other"></div>
|
||||
</div>
|
||||
<div class="unit-summary">
|
||||
<div class="unit-callsign">${data.baseData.unitName}</div>
|
||||
<div class="unit-altitude"></div>
|
||||
<div class="unit-speed"></div>
|
||||
</div>
|
||||
</div>`);
|
||||
super(ID, data);
|
||||
}
|
||||
|
||||
getMarkerHTML()
|
||||
{
|
||||
return `<div class="unit" data-object="unit-aircraft" data-status="" data-coalition="${this.getMissionData().coalition}">
|
||||
<div class="unit-selected-spotlight"></div>
|
||||
<div class="unit-marker-border"></div>
|
||||
<div class="unit-status"></div>
|
||||
<div class="unit-vvi" data-rotate-to-heading></div>
|
||||
<div class="unit-hotgroup">
|
||||
<div class="unit-hotgroup-id"></div>
|
||||
</div>
|
||||
<div class="unit-marker"></div>
|
||||
<div class="unit-short-label">${aircraftDatabase.getByName(this.getBaseData().name)?.shortLabel || ""}</div>
|
||||
<div class="unit-fuel">
|
||||
<div class="unit-fuel-level" style="width:100%;"></div>
|
||||
</div>
|
||||
<div class="unit-ammo">
|
||||
<div class="unit-ammo-fox-1"></div>
|
||||
<div class="unit-ammo-fox-2"></div>
|
||||
<div class="unit-ammo-fox-3"></div>
|
||||
<div class="unit-ammo-other"></div>
|
||||
</div>
|
||||
<div class="unit-summary">
|
||||
<div class="unit-callsign">${this.getBaseData().unitName}</div>
|
||||
<div class="unit-altitude"></div>
|
||||
<div class="unit-speed"></div>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
|
||||
getMarkerCategory()
|
||||
{
|
||||
return "aircraft";
|
||||
}
|
||||
}
|
||||
|
||||
export class Helicopter extends AirUnit {
|
||||
constructor(ID: number, data: UnitData) {
|
||||
super(ID, data,
|
||||
``);
|
||||
super(ID, data);
|
||||
}
|
||||
|
||||
getVisibilityCategory()
|
||||
{
|
||||
return "helicopter";
|
||||
}
|
||||
}
|
||||
|
||||
export class GroundUnit extends Unit {
|
||||
constructor(ID: number, data: UnitData) {
|
||||
// TODO this is very messy
|
||||
var role = groundUnitsDatabase.getByName(data.baseData.name)?.loadouts[0].roles[0];
|
||||
if (role == undefined)
|
||||
role = "U";
|
||||
var roleType = (role === "SAM") ? "sam" : "mi";
|
||||
super(ID, data);
|
||||
}
|
||||
|
||||
super(ID, data, `
|
||||
<div class="unit" data-object="unit-ground-${roleType}" data-coalition="${data.missionData.coalition}">
|
||||
<div class="unit-selected-spotlight"></div>
|
||||
<div class="unit-marker"></div>
|
||||
<div class="unit-short-label">${role?.substring(0, 1).toUpperCase()}</div>
|
||||
</div>
|
||||
`);
|
||||
getMarkerCategory()
|
||||
{
|
||||
// TODO this is very messy
|
||||
var role = groundUnitsDatabase.getByName(this.getBaseData().name)?.loadouts[0].roles[0];
|
||||
var markerCategory = (role === "SAM") ? "sam" : "groundunit";
|
||||
return markerCategory;
|
||||
}
|
||||
}
|
||||
|
||||
export class NavyUnit extends Unit {
|
||||
constructor(ID: number, data: UnitData) {
|
||||
super(ID, data, `
|
||||
<div class="unit" data-object="unit-naval" data-coalition="${data.missionData.coalition}">
|
||||
<div class="unit-selected-spotlight"></div>
|
||||
<div class="unit-marker"></div>
|
||||
<div class="unit-short-label">N</div>
|
||||
</div>
|
||||
`);
|
||||
super(ID, data);
|
||||
}
|
||||
|
||||
getMarkerCategory() {
|
||||
return "navyunit";
|
||||
}
|
||||
}
|
||||
|
||||
export class Weapon extends Unit {
|
||||
constructor(ID: number, data: UnitData, html: string) {
|
||||
super(ID, data, html);
|
||||
constructor(ID: number, data: UnitData) {
|
||||
super(ID, data);
|
||||
this.setSelectable(false);
|
||||
}
|
||||
|
||||
getMarkerHTML(): string {
|
||||
return `<div class="unit" data-object="unit-${this.getMarkerCategory()}" data-coalition="${this.getMissionData().coalition}">
|
||||
<div class="unit-selected-spotlight"></div>
|
||||
<div class="unit-marker" data-rotate-to-heading></div>
|
||||
<div class="unit-short-label"></div>
|
||||
</div>`
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class Missile extends Weapon {
|
||||
constructor(ID: number, data: UnitData) {
|
||||
super(ID, data, `
|
||||
<div class="unit" data-object="unit-weapon-missile" data-coalition="${data.missionData.coalition}">
|
||||
<div class="unit-selected-spotlight"></div>
|
||||
<div class="unit-marker" data-rotate-to-heading></div>
|
||||
<div class="unit-short-label"></div>
|
||||
</div>
|
||||
`);
|
||||
super(ID, data);
|
||||
}
|
||||
|
||||
getMarkerCategory() {
|
||||
return "missile";
|
||||
}
|
||||
}
|
||||
|
||||
export class Bomb extends Weapon {
|
||||
constructor(ID: number, data: UnitData) {
|
||||
super(ID, data, "");
|
||||
super(ID, data);
|
||||
}
|
||||
|
||||
getMarkerCategory() {
|
||||
return "bomb";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
export class UnitDatabase {
|
||||
units: {[key: string]: UnitBlueprint} = {};
|
||||
blueprints: {[key: string]: UnitBlueprint} = {};
|
||||
|
||||
constructor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
getByName(name: string)
|
||||
{
|
||||
if (name in this.units)
|
||||
return this.units[name];
|
||||
return null;
|
||||
}
|
||||
|
||||
getByLabel(label: string)
|
||||
{
|
||||
for (let unit in this.units)
|
||||
{
|
||||
if (this.units[unit].label === label)
|
||||
return this.units[unit];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Returns a list of all possible roles in a database */
|
||||
getRoles()
|
||||
{
|
||||
var roles: string[] = [];
|
||||
for (let unit in this.units)
|
||||
for (let unit in this.blueprints)
|
||||
{
|
||||
for (let loadout of this.units[unit].loadouts)
|
||||
for (let loadout of this.blueprints[unit].loadouts)
|
||||
{
|
||||
for (let role of loadout.roles)
|
||||
{
|
||||
@@ -40,16 +24,36 @@ export class UnitDatabase {
|
||||
return roles;
|
||||
}
|
||||
|
||||
getLabelsByRole(role: string)
|
||||
/* Gets a specific blueprint by name */
|
||||
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)
|
||||
{
|
||||
if (this.blueprints[unit].label === label)
|
||||
return this.blueprints[unit];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Get all blueprints by role */
|
||||
getByRole(role: string)
|
||||
{
|
||||
var units = [];
|
||||
for (let unit in this.units)
|
||||
for (let unit in this.blueprints)
|
||||
{
|
||||
for (let loadout of this.units[unit].loadouts)
|
||||
for (let loadout of this.blueprints[unit].loadouts)
|
||||
{
|
||||
if (loadout.roles.includes(role) || loadout.roles.includes(role.toLowerCase()))
|
||||
{
|
||||
units.push(this.units[unit].label)
|
||||
units.push(this.blueprints[unit])
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -57,10 +61,11 @@ export class UnitDatabase {
|
||||
return units;
|
||||
}
|
||||
|
||||
getLoadoutNamesByRole(unit: string, role: string)
|
||||
/* Get the names of all the loadouts for a specific unit and for a specific role */
|
||||
getLoadoutNamesByRole(name: string, role: string)
|
||||
{
|
||||
var loadouts = [];
|
||||
for (let loadout of this.units[unit].loadouts)
|
||||
for (let loadout of this.blueprints[name].loadouts)
|
||||
{
|
||||
if (loadout.roles.includes(role) || loadout.roles.includes(""))
|
||||
{
|
||||
@@ -70,37 +75,14 @@ export class UnitDatabase {
|
||||
return loadouts;
|
||||
}
|
||||
|
||||
getLoadoutsByName(unit: string, loadoutName: string)
|
||||
/* Get the loadout content from the unit name and loadout name */
|
||||
getLoadoutByName(name: string, loadoutName: string)
|
||||
{
|
||||
for (let loadout of this.units[unit].loadouts)
|
||||
for (let loadout of this.blueprints[name].loadouts)
|
||||
{
|
||||
if (loadout.name === loadoutName)
|
||||
{
|
||||
return loadout;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getNameByLabel(label: string)
|
||||
{
|
||||
for (let name in this.units)
|
||||
{
|
||||
if (this.units[name].label === label)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getLabelByName(name: string)
|
||||
{
|
||||
return this.units[name] === undefined? name: this.units[name].label;
|
||||
}
|
||||
|
||||
getShortLabelByName(name: string)
|
||||
{
|
||||
return this.units[name] === undefined? "U": this.units[name].shortLabel;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user