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:
@@ -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