mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'v0.1.0' of https://github.com/Pax1601/DCSOlympus into v0.1.0
This commit is contained in:
21
client/src/@types/unit.d.ts
vendored
21
client/src/@types/unit.d.ts
vendored
@@ -1,3 +1,16 @@
|
||||
interface UpdateData {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
interface BaseData {
|
||||
AI: boolean;
|
||||
name: string;
|
||||
unitName: string;
|
||||
groupName: string;
|
||||
alive: boolean;
|
||||
category: string;
|
||||
}
|
||||
|
||||
interface FlightData {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
@@ -36,13 +49,7 @@ interface OptionsData {
|
||||
}
|
||||
|
||||
interface UnitData {
|
||||
AI: boolean;
|
||||
name: string;
|
||||
unitName: string;
|
||||
groupName: string;
|
||||
alive: boolean;
|
||||
category: string;
|
||||
|
||||
baseData: BaseData;
|
||||
flightData: FlightData;
|
||||
missionData: MissionData;
|
||||
formationData: FormationData;
|
||||
|
||||
@@ -51,7 +51,7 @@ function setup() {
|
||||
mouseInfoPanel = new MouseInfoPanel("mouse-info-panel");
|
||||
//logPanel = new LogPanel("log-panel");
|
||||
|
||||
missionHandler = new MissionHandler();
|
||||
missionHandler = new MissionHandler();
|
||||
|
||||
/* AIC */
|
||||
let aicFeatureSwitch = featureSwitches.getSwitch( "aic" );
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getUnitsManager } from "..";
|
||||
import { Slider } from "../controls/slider";
|
||||
import { Aircraft, AirUnit, GroundUnit, Helicopter, NavyUnit, Unit } from "../units/unit";
|
||||
import { Unit } from "../units/unit";
|
||||
import { Panel } from "./panel";
|
||||
|
||||
const ROEs: string[] = ["Free", "Designated free", "Designated", "Return", "Hold"];
|
||||
@@ -62,13 +62,13 @@ export class UnitControlPanel extends Panel {
|
||||
}
|
||||
|
||||
update(units: Unit[]) {
|
||||
if (this.getElement() != null)
|
||||
if (this.getElement() != null && units.length > 0)
|
||||
{
|
||||
this.#showFlightControlSliders(units);
|
||||
this.getElement().querySelector("#selected-units-container")?.replaceChildren(...units.map((unit: Unit) =>
|
||||
{
|
||||
var button = document.createElement("button");
|
||||
button.innerText = unit.getData().unitName;
|
||||
button.innerText = unit.getBaseData().unitName;
|
||||
button.addEventListener("click", () => getUnitsManager().selectUnit(unit.ID, true));
|
||||
return (button);
|
||||
}));
|
||||
|
||||
@@ -40,9 +40,9 @@ export class UnitInfoPanel extends Panel {
|
||||
#onUnitUpdate(unit: Unit) {
|
||||
if (this.getElement() != null && this.getVisible()) {
|
||||
/* Set the unit info */
|
||||
this.#unitName.innerText = unit.getData().unitName;
|
||||
this.#groupName.innerText = unit.getData().groupName;
|
||||
this.#name.innerText = unit.getData().name;
|
||||
this.#unitName.innerText = unit.getBaseData().unitName;
|
||||
this.#groupName.innerText = unit.getBaseData().groupName;
|
||||
this.#name.innerText = unit.getBaseData().name;
|
||||
this.#heading.innerText = String(Math.floor(rad2deg(unit.getFlightData().heading)) + " °");
|
||||
this.#altitude.innerText = String(Math.floor(unit.getFlightData().altitude / 0.3048) + " ft");
|
||||
this.#groundSpeed.innerText = String(Math.floor(unit.getFlightData().speed * 1.94384) + " kts");
|
||||
|
||||
@@ -3,20 +3,21 @@ import { setConnected } from '..';
|
||||
import { SpawnOptions } from '../controls/contextmenu';
|
||||
|
||||
/* Edit here to change server address */
|
||||
const REST_ADDRESS = "http://localhost:3000/demo";
|
||||
const REST_ADDRESS = "http://localhost:30000/olympus";
|
||||
const UNITS_URI = "units";
|
||||
const REFRESH_URI = "refresh";
|
||||
const UPDATE_URI = "update";
|
||||
const LOGS_URI = "logs";
|
||||
const AIRBASES_URI = "airbases";
|
||||
const BULLSEYE_URI = "bullseyes";
|
||||
|
||||
var lastUpdateTime = 0;
|
||||
|
||||
export function GET(callback: CallableFunction, uri: string){
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.open("GET", `${REST_ADDRESS}/${uri}`, true);
|
||||
xmlHttp.onload = function (e) {
|
||||
var data = JSON.parse(xmlHttp.responseText);
|
||||
callback(data);
|
||||
lastUpdateTime = parseInt(data.time);
|
||||
setConnected(true);
|
||||
};
|
||||
xmlHttp.onerror = function () {
|
||||
@@ -49,7 +50,7 @@ export function getLogs(callback: CallableFunction) {
|
||||
}
|
||||
|
||||
export function getUnits(callback: CallableFunction, refresh: boolean = false) {
|
||||
GET(callback, `${UNITS_URI}/${refresh? REFRESH_URI: UPDATE_URI}`);
|
||||
GET(callback, `${UNITS_URI}?time=${refresh? 0: lastUpdateTime}`);
|
||||
}
|
||||
|
||||
export function addDestination(ID: number, path: any) {
|
||||
|
||||
@@ -14,7 +14,48 @@ var pathIcon = new Icon({
|
||||
export class Unit extends Marker {
|
||||
ID: number;
|
||||
|
||||
#data: UnitData;
|
||||
#data: UnitData = {
|
||||
baseData: {
|
||||
AI: false,
|
||||
name: "",
|
||||
unitName: "",
|
||||
groupName: "",
|
||||
alive: true,
|
||||
category: "",
|
||||
},
|
||||
flightData: {
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
altitude: 0,
|
||||
heading: 0,
|
||||
speed: 0,
|
||||
},
|
||||
missionData: {
|
||||
fuel: 0,
|
||||
flags: {},
|
||||
ammo: {},
|
||||
targets: {},
|
||||
hasTask: false,
|
||||
coalition: "",
|
||||
},
|
||||
formationData: {
|
||||
formation: "",
|
||||
isLeader: false,
|
||||
isWingman: false,
|
||||
leaderID: 0,
|
||||
wingmenIDs: [],
|
||||
},
|
||||
taskData: {
|
||||
currentTask: "",
|
||||
activePath: {},
|
||||
targetSpeed: 0,
|
||||
targetAltitude: 0,
|
||||
},
|
||||
optionsData: {
|
||||
ROE: "",
|
||||
reactionToThreat: "",
|
||||
}
|
||||
};
|
||||
|
||||
#selectable: boolean;
|
||||
#selected: boolean = false;
|
||||
@@ -37,14 +78,13 @@ export class Unit extends Marker {
|
||||
if (type === "NavyUnit") return NavyUnit;
|
||||
}
|
||||
|
||||
constructor(ID: number, data: UnitData, html: string) {
|
||||
constructor(ID: number, data: UpdateData, html: string) {
|
||||
super(new LatLng(0, 0), { riseOnHover: true });
|
||||
|
||||
this.ID = ID;
|
||||
|
||||
this.#selectable = true;
|
||||
this.#data = data;
|
||||
|
||||
|
||||
this.on('click', (e) => this.#onClick(e));
|
||||
this.on('dblclick', (e) => this.#onDoubleClick(e));
|
||||
this.on('contextmenu', (e) => this.#onContextMenu(e));
|
||||
@@ -59,37 +99,69 @@ export class Unit extends Marker {
|
||||
this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 });
|
||||
this.#pathPolyline.addTo(getMap());
|
||||
this.#targetsPolylines = [];
|
||||
|
||||
this.setData(data);
|
||||
}
|
||||
|
||||
setData(data: UnitData) {
|
||||
setData(data: UpdateData) {
|
||||
document.dispatchEvent(new CustomEvent("unitUpdated", { detail: this }));
|
||||
var updateMarker = false;
|
||||
if (this.getFlightData().latitude != data.flightData.latitude ||
|
||||
this.getFlightData().longitude != data.flightData.longitude ||
|
||||
this.getData().alive != data.alive || this.#forceUpdate || !getMap().hasLayer(this))
|
||||
this.getBaseData().alive != data.baseData.alive || this.#forceUpdate || !getMap().hasLayer(this))
|
||||
updateMarker = true;
|
||||
|
||||
|
||||
if (data.baseData != undefined)
|
||||
{
|
||||
for (let key in this.#data.baseData)
|
||||
if (key in data.baseData)
|
||||
//@ts-ignore
|
||||
this.#data.baseData[key] = data.baseData[key];
|
||||
}
|
||||
|
||||
this.#data.AI = data.AI;
|
||||
this.#data.name = data.name;
|
||||
this.#data.unitName = data.unitName;
|
||||
this.#data.groupName = data.groupName;
|
||||
this.#data.alive = data.alive;
|
||||
this.#data.category = data.category;
|
||||
|
||||
if (data.flightData != undefined)
|
||||
this.#data.flightData = data.flightData;
|
||||
if (data.missionData != undefined)
|
||||
this.#data.missionData = data.missionData;
|
||||
if (data.formationData != undefined)
|
||||
this.#data.formationData = data.formationData;
|
||||
if (data.taskData != undefined)
|
||||
this.#data.taskData = data.taskData;
|
||||
if (data.optionsData != undefined)
|
||||
this.#data.optionsData = data.optionsData;
|
||||
{
|
||||
for (let key in this.#data.flightData)
|
||||
if (key in data.flightData)
|
||||
//@ts-ignore
|
||||
this.#data.flightData[key] = data.flightData[key];
|
||||
}
|
||||
|
||||
if (data.missionData != undefined)
|
||||
{
|
||||
for (let key in this.#data.missionData)
|
||||
if (key in data.missionData)
|
||||
//@ts-ignore
|
||||
this.#data.missionData[key] = data.missionData[key];
|
||||
}
|
||||
|
||||
if (data.formationData != undefined)
|
||||
{
|
||||
for (let key in this.#data.formationData)
|
||||
if (key in data.formationData)
|
||||
//@ts-ignore
|
||||
this.#data.formationData[key] = data.formationData[key];
|
||||
}
|
||||
|
||||
if (data.taskData != undefined)
|
||||
{
|
||||
for (let key in this.#data.taskData)
|
||||
if (key in data.taskData)
|
||||
//@ts-ignore
|
||||
this.#data.taskData[key] = data.taskData[key];
|
||||
}
|
||||
|
||||
if (data.optionsData != undefined)
|
||||
{
|
||||
for (let key in this.#data.optionsData)
|
||||
if (key in data.optionsData)
|
||||
//@ts-ignore
|
||||
this.#data.optionsData[key] = data.optionsData[key];
|
||||
}
|
||||
|
||||
/* Dead units can't be selected */
|
||||
this.setSelected(this.getSelected() && this.getData().alive)
|
||||
this.setSelected(this.getSelected() && this.getBaseData().alive)
|
||||
|
||||
if (updateMarker)
|
||||
this.#updateMarker();
|
||||
@@ -107,6 +179,10 @@ export class Unit extends Marker {
|
||||
return this.#data;
|
||||
}
|
||||
|
||||
getBaseData() {
|
||||
return this.getData().baseData;
|
||||
}
|
||||
|
||||
getFlightData() {
|
||||
return this.getData().flightData;
|
||||
}
|
||||
@@ -129,7 +205,7 @@ export class Unit extends Marker {
|
||||
|
||||
setSelected(selected: boolean) {
|
||||
/* Only alive units can be selected. Some units are not selectable (weapons) */
|
||||
if ((this.getData().alive || !selected) && this.#selectable && this.#selected != selected) {
|
||||
if ((this.getBaseData().alive || !selected) && this.#selectable && this.#selected != selected) {
|
||||
this.#selected = selected;
|
||||
this.getElement()?.querySelector( `[data-object|="unit"]` )?.toggleAttribute( "data-is-selected" );
|
||||
if (selected)
|
||||
@@ -288,9 +364,7 @@ export class Unit extends Marker {
|
||||
this.setLatLng(new LatLng(this.getFlightData().latitude, this.getFlightData().longitude));
|
||||
var element = this.getElement();
|
||||
if (element != null) {
|
||||
element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${this.getFlightData().speed / 5}px; transform:rotate(${rad2deg(this.getFlightData().heading)}deg);`);
|
||||
element.querySelector(".unit")?.setAttribute("data-fuel-level", "20");
|
||||
element.querySelector(".unit")?.toggleAttribute("data-has-fox-1", true );
|
||||
element.querySelector(".unit-vvi")?.setAttribute("style", `height: ${15 + this.getFlightData().speed / 5}px; transform:rotate(${rad2deg(this.getFlightData().heading)}deg);`);
|
||||
|
||||
var unitHeadingDiv = element.querySelector(".unit-heading");
|
||||
if (unitHeadingDiv != null)
|
||||
@@ -390,10 +464,10 @@ export class Aircraft extends AirUnit {
|
||||
<div class="unit-status"></div>
|
||||
<div class="unit-vvi"></div>
|
||||
<div class="unit-hotgroup">
|
||||
<div class="unit-hotgroup-id">4</div>
|
||||
<div class="unit-hotgroup-id"></div>
|
||||
</div>
|
||||
<div class="unit-marker"></div>
|
||||
<div class="unit-short-label">${aircraftDatabase.getShortLabelByName(data.name)}</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>
|
||||
@@ -404,7 +478,7 @@ export class Aircraft extends AirUnit {
|
||||
<div class="unit-ammo-other"></div>
|
||||
</div>
|
||||
<div class="unit-summary">
|
||||
<div class="unit-callsign">${data.unitName}</div>
|
||||
<div class="unit-callsign">${data.baseData.unitName}</div>
|
||||
<div class="unit-heading"></div>
|
||||
<div class="unit-altitude"></div>
|
||||
</div>
|
||||
@@ -421,7 +495,7 @@ export class Helicopter extends AirUnit {
|
||||
|
||||
export class GroundUnit extends Unit {
|
||||
constructor(ID: number, data: UnitData) {
|
||||
var role = groundUnitsDatabase.getByName(data.name)?.loadouts[0].roles[0];
|
||||
var role = groundUnitsDatabase.getByName(data.baseData.name)?.loadouts[0].roles[0];
|
||||
var roleType = (role === "SAM") ? "sam" : "mi";
|
||||
|
||||
super(ID, data, `
|
||||
|
||||
@@ -33,7 +33,7 @@ export class UnitsManager {
|
||||
|
||||
addUnit(ID: number, data: UnitData) {
|
||||
/* The name of the unit category is exactly the same as the constructor name */
|
||||
var constructor = Unit.getConstructor(data.category);
|
||||
var constructor = Unit.getConstructor(data.baseData.category);
|
||||
if (constructor != undefined) {
|
||||
this.#units[ID] = new constructor(ID, data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user