mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Multiple bug fixes and optimizations
This commit is contained in:
parent
bac2c430ef
commit
fd7f4b9772
@ -616,7 +616,7 @@ export class Map extends L.Map {
|
||||
|
||||
#showDestinationCursors() {
|
||||
const singleCursor = !this.#shiftKey;
|
||||
const selectedUnitsCount = getUnitsManager().getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: true }).length;
|
||||
const selectedUnitsCount = getUnitsManager().getSelectedUnits({ excludeHumans: false, onlyOnePerGroup: true }).length;
|
||||
if (selectedUnitsCount > 0) {
|
||||
if (singleCursor && this.#destinationPreviewCursors.length != 1) {
|
||||
this.#hideDestinationCursors();
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { LatLng } from "leaflet";
|
||||
import { getInfoPopup, getMap, getUnitsManager } from "..";
|
||||
import { getInfoPopup, getMap } from "..";
|
||||
import { Airbase } from "./airbase";
|
||||
import { Bullseye } from "./bullseye";
|
||||
import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "../constants/constants";
|
||||
import { setCommandModeOptions } from "../server/server";
|
||||
import { BLUE_COMMANDER, GAME_MASTER, NONE, RED_COMMANDER } from "../constants/constants";
|
||||
import { refreshAll, setCommandModeOptions } from "../server/server";
|
||||
import { Dropdown } from "../controls/dropdown";
|
||||
import { groundUnitDatabase } from "../unit/groundunitdatabase";
|
||||
import { createCheckboxOption, getCheckboxOptions } from "../other/utils";
|
||||
@ -16,7 +16,7 @@ export class MissionHandler {
|
||||
#airbases: { [name: string]: Airbase } = {};
|
||||
#theatre: string = "";
|
||||
#dateAndTime: DateAndTime = {date: {Year: 0, Month: 0, Day: 0}, time: {h: 0, m: 0, s: 0}, startTime: 0, elapsedTime: 0};
|
||||
#commandModeOptions: CommandModeOptions = {commandMode: "Hide all", restrictSpawns: false, restrictToCoalition: false, setupTime: Infinity, spawnPoints: {red: Infinity, blue: Infinity}, eras: []};
|
||||
#commandModeOptions: CommandModeOptions = {commandMode: NONE, restrictSpawns: false, restrictToCoalition: false, setupTime: Infinity, spawnPoints: {red: Infinity, blue: Infinity}, eras: []};
|
||||
#remainingSetupTime: number = 0;
|
||||
#spentSpawnPoint: number = 0;
|
||||
#commandModeDialog: HTMLElement;
|
||||
@ -183,6 +183,15 @@ export class MissionHandler {
|
||||
}
|
||||
|
||||
#setcommandModeOptions(commandModeOptions: CommandModeOptions) {
|
||||
/* Refresh all the data if we have exited the NONE state */
|
||||
if (this.#commandModeOptions.commandMode === NONE && commandModeOptions.commandMode !== NONE)
|
||||
refreshAll();
|
||||
|
||||
/* Refresh the page if we have lost Game Master priviledges */
|
||||
if (this.#commandModeOptions.commandMode === GAME_MASTER && commandModeOptions.commandMode !== GAME_MASTER)
|
||||
location.reload();
|
||||
|
||||
/* Check if any option has changed */
|
||||
var commandModeOptionsChanged = (!commandModeOptions.eras.every((value: string, idx: number) => {return value === this.getCommandModeOptions().eras[idx]}) ||
|
||||
commandModeOptions.spawnPoints.red !== this.getCommandModeOptions().spawnPoints.red ||
|
||||
commandModeOptions.spawnPoints.blue !== this.getCommandModeOptions().spawnPoints.blue ||
|
||||
@ -195,7 +204,6 @@ export class MissionHandler {
|
||||
|
||||
if (commandModeOptionsChanged) {
|
||||
document.dispatchEvent(new CustomEvent("commandModeOptionsChanged", { detail: this }));
|
||||
|
||||
document.getElementById("command-mode-toolbar")?.classList.remove("hide");
|
||||
const el = document.getElementById("command-mode");
|
||||
if (el) {
|
||||
|
||||
@ -22,6 +22,8 @@ export class UnitControlPanel extends Panel {
|
||||
#radioCallsignDropdown: Dropdown;
|
||||
#optionButtons: { [key: string]: HTMLButtonElement[] } = {}
|
||||
#advancedSettingsDialog: HTMLElement;
|
||||
#units: Unit[] = [];
|
||||
#selectedUnitsTypes: string[] = [];
|
||||
|
||||
constructor(ID: string) {
|
||||
super(ID);
|
||||
@ -96,9 +98,11 @@ export class UnitControlPanel extends Panel {
|
||||
}
|
||||
|
||||
addButtons() {
|
||||
var units = getUnitsManager().getSelectedUnits();
|
||||
if (units.length < 20) {
|
||||
this.getElement().querySelector("#selected-units-container")?.replaceChildren(...units.map((unit: Unit, index: number) => {
|
||||
this.#units = getUnitsManager().getSelectedUnits();
|
||||
this.#selectedUnitsTypes = getUnitsManager().getSelectedUnitsTypes();
|
||||
|
||||
if (this.#units.length < 20) {
|
||||
this.getElement().querySelector("#selected-units-container")?.replaceChildren(...this.#units.map((unit: Unit, index: number) => {
|
||||
var button = document.createElement("button");
|
||||
var callsign = unit.getUnitName() || "";
|
||||
var label = unit.getDatabase()?.getByName(unit.getName())?.label || unit.getName();
|
||||
@ -125,37 +129,34 @@ export class UnitControlPanel extends Panel {
|
||||
update() {
|
||||
if (this.getVisible()){
|
||||
const element = this.getElement();
|
||||
const units = getUnitsManager().getSelectedUnits();
|
||||
const selectedUnitsTypes = getUnitsManager().getSelectedUnitsTypes();
|
||||
|
||||
if (element != null && units.length > 0) {
|
||||
if (element != null && this.#units.length > 0) {
|
||||
/* Toggle visibility of control elements */
|
||||
element.toggleAttribute("data-show-categories-tooltip", selectedUnitsTypes.length > 1);
|
||||
element.toggleAttribute("data-show-speed-slider", selectedUnitsTypes.length == 1);
|
||||
element.toggleAttribute("data-show-altitude-slider", selectedUnitsTypes.length == 1 && (selectedUnitsTypes.includes("Aircraft") || selectedUnitsTypes.includes("Helicopter")));
|
||||
element.toggleAttribute("data-show-categories-tooltip", this.#selectedUnitsTypes.length > 1);
|
||||
element.toggleAttribute("data-show-speed-slider", this.#selectedUnitsTypes.length == 1);
|
||||
element.toggleAttribute("data-show-altitude-slider", this.#selectedUnitsTypes.length == 1 && (this.#selectedUnitsTypes.includes("Aircraft") || this.#selectedUnitsTypes.includes("Helicopter")));
|
||||
element.toggleAttribute("data-show-roe", true);
|
||||
element.toggleAttribute("data-show-threat", (selectedUnitsTypes.includes("Aircraft") || selectedUnitsTypes.includes("Helicopter")) && !(selectedUnitsTypes.includes("GroundUnit") || selectedUnitsTypes.includes("NavyUnit")));
|
||||
element.toggleAttribute("data-show-emissions-countermeasures", (selectedUnitsTypes.includes("Aircraft") || selectedUnitsTypes.includes("Helicopter")) && !(selectedUnitsTypes.includes("GroundUnit") || selectedUnitsTypes.includes("NavyUnit")));
|
||||
element.toggleAttribute("data-show-on-off", (selectedUnitsTypes.includes("GroundUnit") || selectedUnitsTypes.includes("NavyUnit")) && !(selectedUnitsTypes.includes("Aircraft") || selectedUnitsTypes.includes("Helicopter")));
|
||||
element.toggleAttribute("data-show-follow-roads", (selectedUnitsTypes.length == 1 && selectedUnitsTypes.includes("GroundUnit")));
|
||||
element.toggleAttribute("data-show-advanced-settings-button", units.length == 1);
|
||||
element.toggleAttribute("data-show-threat", (this.#selectedUnitsTypes.includes("Aircraft") || this.#selectedUnitsTypes.includes("Helicopter")) && !(this.#selectedUnitsTypes.includes("GroundUnit") || this.#selectedUnitsTypes.includes("NavyUnit")));
|
||||
element.toggleAttribute("data-show-emissions-countermeasures", (this.#selectedUnitsTypes.includes("Aircraft") || this.#selectedUnitsTypes.includes("Helicopter")) && !(this.#selectedUnitsTypes.includes("GroundUnit") || this.#selectedUnitsTypes.includes("NavyUnit")));
|
||||
element.toggleAttribute("data-show-on-off", (this.#selectedUnitsTypes.includes("GroundUnit") || this.#selectedUnitsTypes.includes("NavyUnit")) && !(this.#selectedUnitsTypes.includes("Aircraft") || this.#selectedUnitsTypes.includes("Helicopter")));
|
||||
element.toggleAttribute("data-show-follow-roads", (this.#selectedUnitsTypes.length == 1 && this.#selectedUnitsTypes.includes("GroundUnit")));
|
||||
element.toggleAttribute("data-show-advanced-settings-button", this.#units.length == 1);
|
||||
|
||||
/* Flight controls */
|
||||
var desiredAltitude = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitude()});
|
||||
var desiredAltitudeType = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitudeType()});
|
||||
var desiredSpeed = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeed()});
|
||||
var desiredSpeedType = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeedType()});
|
||||
var onOff = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getOnOff()});
|
||||
var followRoads = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getFollowRoads()});
|
||||
|
||||
if (selectedUnitsTypes.length == 1) {
|
||||
if (this.#selectedUnitsTypes.length == 1) {
|
||||
/* Flight controls */
|
||||
var desiredAltitude = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitude()});
|
||||
var desiredAltitudeType = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredAltitudeType()});
|
||||
var desiredSpeed = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeed()});
|
||||
var desiredSpeedType = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getDesiredSpeedType()});
|
||||
var onOff = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getOnOff()});
|
||||
var followRoads = getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getFollowRoads()});
|
||||
|
||||
this.#altitudeTypeSwitch.setValue(desiredAltitudeType != undefined? desiredAltitudeType == "AGL": undefined, false);
|
||||
this.#speedTypeSwitch.setValue(desiredSpeedType != undefined? desiredSpeedType == "GS": undefined, false);
|
||||
|
||||
this.#speedSlider.setMinMax(minSpeedValues[selectedUnitsTypes[0]], maxSpeedValues[selectedUnitsTypes[0]]);
|
||||
this.#altitudeSlider.setMinMax(minAltitudeValues[selectedUnitsTypes[0]], maxAltitudeValues[selectedUnitsTypes[0]]);
|
||||
this.#speedSlider.setIncrement(speedIncrements[selectedUnitsTypes[0]]);
|
||||
this.#altitudeSlider.setIncrement(altitudeIncrements[selectedUnitsTypes[0]]);
|
||||
this.#speedSlider.setMinMax(minSpeedValues[this.#selectedUnitsTypes[0]], maxSpeedValues[this.#selectedUnitsTypes[0]]);
|
||||
this.#altitudeSlider.setMinMax(minAltitudeValues[this.#selectedUnitsTypes[0]], maxAltitudeValues[this.#selectedUnitsTypes[0]]);
|
||||
this.#speedSlider.setIncrement(speedIncrements[this.#selectedUnitsTypes[0]]);
|
||||
this.#altitudeSlider.setIncrement(altitudeIncrements[this.#selectedUnitsTypes[0]]);
|
||||
|
||||
this.#speedSlider.setActive(desiredSpeed != undefined);
|
||||
if (desiredSpeed != undefined)
|
||||
@ -172,15 +173,15 @@ export class UnitControlPanel extends Panel {
|
||||
|
||||
/* Option buttons */
|
||||
this.#optionButtons["ROE"].forEach((button: HTMLButtonElement) => {
|
||||
button.classList.toggle("selected", units.every((unit: Unit) => unit.getROE() === button.value))
|
||||
button.classList.toggle("selected", this.#units.every((unit: Unit) => unit.getROE() === button.value))
|
||||
});
|
||||
|
||||
this.#optionButtons["reactionToThreat"].forEach((button: HTMLButtonElement) => {
|
||||
button.classList.toggle("selected", units.every((unit: Unit) => unit.getReactionToThreat() === button.value))
|
||||
button.classList.toggle("selected", this.#units.every((unit: Unit) => unit.getReactionToThreat() === button.value))
|
||||
});
|
||||
|
||||
this.#optionButtons["emissionsCountermeasures"].forEach((button: HTMLButtonElement) => {
|
||||
button.classList.toggle("selected", units.every((unit: Unit) => unit.getEmissionsCountermeasures() === button.value))
|
||||
button.classList.toggle("selected", this.#units.every((unit: Unit) => unit.getEmissionsCountermeasures() === button.value))
|
||||
});
|
||||
|
||||
this.#onOffSwitch.setValue(onOff, false);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { LatLng } from 'leaflet';
|
||||
import { getConnectionStatusPanel, getInfoPopup, getLogPanel, getMissionHandler, getServerStatusPanel, getUnitsManager, getWeaponsManager, setLoginStatus } from '..';
|
||||
import { GeneralSettings, Radio, TACAN } from '../@types/unit';
|
||||
import { ROEs, emissionsCountermeasures, reactionsToThreat } from '../constants/constants';
|
||||
import { NONE, ROEs, emissionsCountermeasures, reactionsToThreat } from '../constants/constants';
|
||||
|
||||
var connected: boolean = false;
|
||||
var paused: boolean = false;
|
||||
@ -20,6 +20,13 @@ var password = "";
|
||||
|
||||
var sessionHash: string | null = null;
|
||||
var lastUpdateTimes: {[key: string]: number} = {}
|
||||
lastUpdateTimes[UNITS_URI] = Date.now();
|
||||
lastUpdateTimes[WEAPONS_URI] = Date.now();
|
||||
lastUpdateTimes[LOGS_URI] = Date.now();
|
||||
lastUpdateTimes[AIRBASES_URI] = Date.now();
|
||||
lastUpdateTimes[BULLSEYE_URI] = Date.now();
|
||||
lastUpdateTimes[MISSION_URI] = Date.now();
|
||||
|
||||
var demoEnabled = false;
|
||||
|
||||
export function toggleDemoEnabled() {
|
||||
@ -339,26 +346,6 @@ export function setCommandModeOptions(restrictSpawns: boolean, restrictToCoaliti
|
||||
}
|
||||
|
||||
export function startUpdate() {
|
||||
window.setInterval(() => {
|
||||
if (!getPaused()) {
|
||||
getAirbases((data: AirbasesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateAirbases(data);
|
||||
return data.time;
|
||||
});
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
window.setInterval(() => {
|
||||
if (!getPaused()){
|
||||
getBullseye((data: BullseyesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateBullseyes(data);
|
||||
return data.time;
|
||||
});
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
window.setInterval(() => {
|
||||
if (!getPaused()) {
|
||||
getMission((data: MissionData) => {
|
||||
@ -370,7 +357,27 @@ export function startUpdate() {
|
||||
}, 1000);
|
||||
|
||||
window.setInterval(() => {
|
||||
if (!getPaused()) {
|
||||
if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) {
|
||||
getAirbases((data: AirbasesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateAirbases(data);
|
||||
return data.time;
|
||||
});
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
window.setInterval(() => {
|
||||
if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE){
|
||||
getBullseye((data: BullseyesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateBullseyes(data);
|
||||
return data.time;
|
||||
});
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
window.setInterval(() => {
|
||||
if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) {
|
||||
getLogs((data: any) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getLogPanel().appendLogs(data.logs)
|
||||
@ -380,7 +387,7 @@ export function startUpdate() {
|
||||
}, 1000);
|
||||
|
||||
window.setInterval(() => {
|
||||
if (!getPaused()) {
|
||||
if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) {
|
||||
getUnits((buffer: ArrayBuffer) => {
|
||||
var time = getUnitsManager()?.update(buffer);
|
||||
return time;
|
||||
@ -389,7 +396,7 @@ export function startUpdate() {
|
||||
}, 250);
|
||||
|
||||
window.setInterval(() => {
|
||||
if (!getPaused()) {
|
||||
if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) {
|
||||
getWeapons((buffer: ArrayBuffer) => {
|
||||
var time = getWeaponsManager()?.update(buffer);
|
||||
return time;
|
||||
@ -398,7 +405,7 @@ export function startUpdate() {
|
||||
}, 250);
|
||||
|
||||
window.setInterval(() => {
|
||||
if (!getPaused()) {
|
||||
if (!getPaused() && getMissionHandler().getCommandModeOptions().commandMode != NONE) {
|
||||
getUnits((buffer: ArrayBuffer) => {
|
||||
var time = getUnitsManager()?.update(buffer);
|
||||
return time;
|
||||
@ -408,9 +415,39 @@ export function startUpdate() {
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
export function refreshAll() {
|
||||
getAirbases((data: AirbasesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateAirbases(data);
|
||||
return data.time;
|
||||
});
|
||||
|
||||
getBullseye((data: BullseyesData) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getMissionHandler()?.updateBullseyes(data);
|
||||
return data.time;
|
||||
});
|
||||
|
||||
getLogs((data: any) => {
|
||||
checkSessionHash(data.sessionHash);
|
||||
getLogPanel().appendLogs(data.logs)
|
||||
return data.time;
|
||||
});
|
||||
|
||||
getWeapons((buffer: ArrayBuffer) => {
|
||||
var time = getWeaponsManager()?.update(buffer);
|
||||
return time;
|
||||
}, false);
|
||||
|
||||
getUnits((buffer: ArrayBuffer) => {
|
||||
var time = getUnitsManager()?.update(buffer);
|
||||
return time;
|
||||
}, true);
|
||||
}
|
||||
|
||||
export function checkSessionHash(newSessionHash: string) {
|
||||
if (sessionHash != null) {
|
||||
if (newSessionHash != sessionHash)
|
||||
if (newSessionHash !== sessionHash)
|
||||
location.reload();
|
||||
}
|
||||
else
|
||||
|
||||
@ -406,9 +406,11 @@ export class Unit extends CustomMarker {
|
||||
el.setAttribute("data-object", `unit-${this.getMarkerCategory()}`);
|
||||
el.setAttribute("data-coalition", this.#coalition);
|
||||
|
||||
var iconOptions = this.getIconOptions();
|
||||
|
||||
// Generate and append elements depending on active options
|
||||
// Velocity vector
|
||||
if (this.getIconOptions().showVvi) {
|
||||
if (iconOptions.showVvi) {
|
||||
var vvi = document.createElement("div");
|
||||
vvi.classList.add("unit-vvi");
|
||||
vvi.toggleAttribute("data-rotate-to-heading");
|
||||
@ -416,7 +418,7 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
// Hotgroup indicator
|
||||
if (this.getIconOptions().showHotgroup) {
|
||||
if (iconOptions.showHotgroup) {
|
||||
var hotgroup = document.createElement("div");
|
||||
hotgroup.classList.add("unit-hotgroup");
|
||||
var hotgroupId = document.createElement("div");
|
||||
@ -426,26 +428,26 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
// Main icon
|
||||
if (this.getIconOptions().showUnitIcon) {
|
||||
if (iconOptions.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);
|
||||
unitIcon.toggleAttribute("data-rotate-to-heading", iconOptions.rotateToHeading);
|
||||
el.append(unitIcon);
|
||||
}
|
||||
|
||||
// State icon
|
||||
if (this.getIconOptions().showState) {
|
||||
if (iconOptions.showState) {
|
||||
var state = document.createElement("div");
|
||||
state.classList.add("unit-state");
|
||||
el.appendChild(state);
|
||||
}
|
||||
|
||||
// Short label
|
||||
if (this.getIconOptions().showShortLabel) {
|
||||
if (iconOptions.showShortLabel) {
|
||||
var shortLabel = document.createElement("div");
|
||||
shortLabel.classList.add("unit-short-label");
|
||||
shortLabel.innerText = getUnitDatabaseByCategory(this.getMarkerCategory())?.getByName(this.#name)?.shortLabel || "";
|
||||
@ -453,7 +455,7 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
// Fuel indicator
|
||||
if (this.getIconOptions().showFuel) {
|
||||
if (iconOptions.showFuel) {
|
||||
var fuelIndicator = document.createElement("div");
|
||||
fuelIndicator.classList.add("unit-fuel");
|
||||
var fuelLevel = document.createElement("div");
|
||||
@ -463,7 +465,7 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
// Ammo indicator
|
||||
if (this.getIconOptions().showAmmo) {
|
||||
if (iconOptions.showAmmo) {
|
||||
var ammoIndicator = document.createElement("div");
|
||||
ammoIndicator.classList.add("unit-ammo");
|
||||
for (let i = 0; i <= 3; i++)
|
||||
@ -472,7 +474,7 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
// Unit summary
|
||||
if (this.getIconOptions().showSummary) {
|
||||
if (iconOptions.showSummary) {
|
||||
var summary = document.createElement("div");
|
||||
summary.classList.add("unit-summary");
|
||||
var callsign = document.createElement("div");
|
||||
@ -482,7 +484,7 @@ export class Unit extends CustomMarker {
|
||||
altitude.classList.add("unit-altitude");
|
||||
var speed = document.createElement("div");
|
||||
speed.classList.add("unit-speed");
|
||||
if (this.getIconOptions().showCallsign) summary.appendChild(callsign);
|
||||
if (iconOptions.showCallsign) summary.appendChild(callsign);
|
||||
summary.appendChild(altitude);
|
||||
summary.appendChild(speed);
|
||||
el.appendChild(summary);
|
||||
@ -499,7 +501,7 @@ export class Unit extends CustomMarker {
|
||||
(hiddenUnits.includes(this.getMarkerCategory())) ||
|
||||
(hiddenUnits.includes(this.#coalition)) ||
|
||||
(!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0) ||
|
||||
(getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && this.getCategory() == "GroundUnit" && getMap().getZoom() < 13)) &&
|
||||
(getMap().getVisibilityOptions()[HIDE_GROUP_MEMBERS] && !this.#isLeader && this.getCategory() == "GroundUnit" && getMap().getZoom() < 13 && (this.belongsToCommandedCoalition() || (!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0)))) &&
|
||||
!(this.getSelected());
|
||||
|
||||
this.setHidden(hidden || !this.#alive);
|
||||
|
||||
@ -95,7 +95,7 @@ export class UnitsManager {
|
||||
if (this.#requestDetectionUpdate && getMissionHandler().getCommandModeOptions().commandMode != GAME_MASTER) {
|
||||
for (let ID in this.#units) {
|
||||
var unit = this.#units[ID];
|
||||
if (!unit.belongsToCommandedCoalition())
|
||||
if (unit.getAlive() && !unit.belongsToCommandedCoalition())
|
||||
unit.setDetectionMethods(this.getUnitDetectedMethods(unit));
|
||||
}
|
||||
this.#requestDetectionUpdate = false;
|
||||
@ -651,7 +651,8 @@ export class UnitsManager {
|
||||
var groups = JSON.parse(contents);
|
||||
for (let groupName in groups) {
|
||||
if (groupName !== "" && groups[groupName].length > 0 && groups[groupName].every((unit: any) => {return unit.category == "GroundUnit";})) {
|
||||
var units = groups[groupName].map((unit: any) => {return {unitType: unit.name, location: unit.position}});
|
||||
var aliveUnits = groups[groupName].filter((unit: any) => {return unit.alive});
|
||||
var units = aliveUnits.map((unit: any) => {return {unitType: unit.name, location: unit.position}});
|
||||
getUnitsManager().spawnUnits("GroundUnit", units, groups[groupName][0].coalition, true);
|
||||
}
|
||||
}
|
||||
@ -714,9 +715,9 @@ export class UnitsManager {
|
||||
|
||||
#onUnitSelection(unit: Unit) {
|
||||
if (this.getSelectedUnits().length > 0) {
|
||||
getMap().setState(MOVE_UNIT);
|
||||
/* Disable the firing of the selection event for a certain amount of time. This avoids firing many events if many units are selected */
|
||||
if (!this.#selectionEventDisabled) {
|
||||
getMap().setState(MOVE_UNIT);
|
||||
window.setTimeout(() => {
|
||||
document.dispatchEvent(new CustomEvent("unitsSelection", { detail: this.getSelectedUnits() }));
|
||||
this.#selectionEventDisabled = false;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"server": {
|
||||
"address": "localhost",
|
||||
"address": "88.99.250.188",
|
||||
"port": 30000
|
||||
},
|
||||
"authentication": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
local version = "v0.4.1-alpha"
|
||||
|
||||
local debug = true
|
||||
local debug = false
|
||||
|
||||
|
||||
Olympus.OlympusDLL = nil
|
||||
@ -53,26 +53,33 @@ function Olympus.getUnitByID(ID)
|
||||
return Olympus.units[ID];
|
||||
end
|
||||
|
||||
function Olympus.getCountryIDByCoalition(coalition)
|
||||
local countryID = 0
|
||||
if coalition == 'red' then
|
||||
countryID = country.id.CJTF_RED
|
||||
elseif coalition == 'blue' then
|
||||
countryID = country.id.CJTF_BLUE
|
||||
else
|
||||
countryID = country.id.UN_PEACEKEEPERS
|
||||
function Olympus.getCountryIDByCoalition(coalitionString)
|
||||
for countryName, countryId in pairs(country.id) do
|
||||
if coalition.getCountryCoalition(countryId) == Olympus.getCoalitionIDByCoalition(coalitionString) then
|
||||
return countryId
|
||||
end
|
||||
end
|
||||
return countryID
|
||||
return 0
|
||||
end
|
||||
|
||||
function Olympus.getCoalitionIDByCoalition(coalitionString)
|
||||
local coalitionID = 0
|
||||
if coalitionString == "red" then
|
||||
coalitionID = 1
|
||||
elseif coalitionString == "blue" then
|
||||
coalitionID = 2
|
||||
end
|
||||
return coalitionID
|
||||
end
|
||||
|
||||
function Olympus.getCoalitionByCoalitionID(coalitionID)
|
||||
local coalition = "neutral"
|
||||
local coalitionString = "neutral"
|
||||
if coalitionID == 1 then
|
||||
coalition = "red"
|
||||
coalitionString = "red"
|
||||
elseif coalitionID == 2 then
|
||||
coalition = "blue"
|
||||
coalitionString = "blue"
|
||||
end
|
||||
return coalition
|
||||
return coalitionString
|
||||
end
|
||||
|
||||
-- Builds a valid task depending on the provided options
|
||||
@ -569,10 +576,9 @@ function Olympus.clone(ID, lat, lng, category)
|
||||
Olympus.debug("Olympus.clone " .. ID .. ", " .. category, 2)
|
||||
local unit = Olympus.getUnitByID(ID)
|
||||
if unit then
|
||||
local coalition = Olympus.getCoalitionByCoalitionID(unit:getCoalition())
|
||||
-- TODO: understand category in this script
|
||||
local spawnTable = {
|
||||
coalition = coalition,
|
||||
coalition = Olympus.getCoalitionByCoalitionID(unit:getCoalition()),
|
||||
category = category,
|
||||
units = {
|
||||
[1] = {
|
||||
@ -663,9 +669,7 @@ function Olympus.setUnitsData(arg, time)
|
||||
index = index + 1
|
||||
if index > startIndex then
|
||||
if unit ~= nil then
|
||||
local table = {}
|
||||
table["category"] = "None"
|
||||
|
||||
local table = {}
|
||||
-- Get the object category in Olympus name
|
||||
local objectCategory = unit:getCategory()
|
||||
if objectCategory == Object.Category.UNIT then
|
||||
@ -684,7 +688,7 @@ function Olympus.setUnitsData(arg, time)
|
||||
end
|
||||
|
||||
-- If the category is handled by Olympus, get the data
|
||||
if table["category"] ~= "None" then
|
||||
if table["category"] ~= nil then
|
||||
-- Compute unit position and heading
|
||||
local lat, lng, alt = coord.LOtoLL(unit:getPoint())
|
||||
local position = unit:getPosition()
|
||||
@ -699,34 +703,40 @@ function Olympus.setUnitsData(arg, time)
|
||||
table["position"]["alt"] = alt
|
||||
table["speed"] = mist.vec.mag(unit:getVelocity())
|
||||
table["heading"] = heading
|
||||
table["isAlive"] = unit:isExist()
|
||||
table["isAlive"] = unit:isExist() and unit:isActive() and unit:getLife() >= 1
|
||||
|
||||
-- Get the targets detected by the group controller
|
||||
local group = unit:getGroup()
|
||||
local controller = group:getController()
|
||||
|
||||
local contacts = {}
|
||||
for det, enum in pairs(Controller.Detection) do
|
||||
local controllerTargets = unit:getController():getDetectedTargets(enum)
|
||||
for i, target in ipairs(controllerTargets) do
|
||||
if target.object ~= nil and target.visible then
|
||||
target["detectionMethod"] = det
|
||||
contacts[#contacts + 1] = target
|
||||
if group ~= nil then
|
||||
local controller = group:getController()
|
||||
if controller ~= nil then
|
||||
-- Get the targets detected by the unit controller
|
||||
local contacts = {}
|
||||
local unitController = unit:getController()
|
||||
if unitController ~= nil then
|
||||
for det, enum in pairs(Controller.Detection) do
|
||||
local controllerTargets = unitController:getDetectedTargets(enum)
|
||||
for i, target in ipairs(controllerTargets) do
|
||||
if target ~= nil and target.object ~= nil and target.visible then
|
||||
target["detectionMethod"] = det
|
||||
contacts[#contacts + 1] = target
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table["country"] = unit:getCountry()
|
||||
table["unitName"] = unit:getName()
|
||||
table["groupName"] = group:getName()
|
||||
table["isHuman"] = (unit:getPlayerName() ~= nil)
|
||||
table["hasTask"] = controller:hasTask()
|
||||
table["ammo"] = unit:getAmmo() --TODO remove a lot of stuff we don't really need
|
||||
table["fuel"] = unit:getFuel()
|
||||
table["life"] = unit:getLife() / unit:getLife0()
|
||||
table["contacts"] = contacts
|
||||
|
||||
units[ID] = table
|
||||
end
|
||||
end
|
||||
|
||||
table["country"] = unit:getCountry()
|
||||
table["unitName"] = unit:getName()
|
||||
table["groupName"] = group:getName()
|
||||
table["isHuman"] = (unit:getPlayerName() ~= nil)
|
||||
table["hasTask"] = controller:hasTask()
|
||||
table["ammo"] = unit:getAmmo() --TODO remove a lot of stuff we don't really need
|
||||
table["fuel"] = unit:getFuel()
|
||||
table["life"] = unit:getLife() / unit:getLife0()
|
||||
table["contacts"] = contacts
|
||||
|
||||
units[ID] = table
|
||||
end
|
||||
else
|
||||
units[ID] = {isAlive = false}
|
||||
@ -762,8 +772,7 @@ function Olympus.setWeaponsData(arg, time)
|
||||
if index > startIndex then
|
||||
if weapon ~= nil then
|
||||
local table = {}
|
||||
table["category"] = "None"
|
||||
|
||||
|
||||
-- Get the object category in Olympus name
|
||||
local objectCategory = weapon:getCategory()
|
||||
if objectCategory == Object.Category.WEAPON then
|
||||
@ -780,7 +789,7 @@ function Olympus.setWeaponsData(arg, time)
|
||||
end
|
||||
|
||||
-- If the category is handled by Olympus, get the data
|
||||
if table["category"] ~= "None" then
|
||||
if table["category"] ~= nil then
|
||||
-- Compute weapon position and heading
|
||||
local lat, lng, alt = coord.LOtoLL(weapon:getPoint())
|
||||
local position = weapon:getPosition()
|
||||
@ -964,12 +973,16 @@ handler = {}
|
||||
function handler:onEvent(event)
|
||||
if event.id == 1 then
|
||||
local weapon = event.weapon
|
||||
Olympus.weapons[weapon["id_"]] = weapon
|
||||
Olympus.debug("New weapon created " .. weapon["id_"], 2)
|
||||
if Olympus ~= nil and Olympus.weapons ~= nil then
|
||||
Olympus.weapons[weapon["id_"]] = weapon
|
||||
Olympus.debug("New weapon created " .. weapon["id_"], 2)
|
||||
end
|
||||
elseif event.id == 15 then
|
||||
local unit = event.initiator
|
||||
Olympus.units[unit["id_"]] = unit
|
||||
Olympus.debug("New unit created " .. unit["id_"], 2)
|
||||
if Olympus ~= nil and Olympus.units ~= nil then
|
||||
Olympus.units[unit["id_"]] = unit
|
||||
Olympus.debug("New unit created " .. unit["id_"], 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
world.addEventHandler(handler)
|
||||
|
||||
@ -85,8 +85,9 @@ void Unit::update(json::value json, double dt)
|
||||
DataTypes::Ammo ammoItem;
|
||||
auto ammoJson = el.second;
|
||||
ammoItem.quantity = ammoJson[L"count"].as_number().to_uint32();
|
||||
string name = to_string(ammoJson[L"desc"][L"displayName"].as_string()).substr(0, sizeof(ammoItem.name) - 1);
|
||||
strcpy_s(ammoItem.name, sizeof(ammoItem.name), name.c_str());
|
||||
string name = to_string(ammoJson[L"desc"][L"displayName"].as_string());
|
||||
name = name.substr(min(name.length(), sizeof(ammoItem.name) - 1));
|
||||
strcpy_s(ammoItem.name, sizeof(ammoItem.name) - 1, name.c_str());
|
||||
|
||||
if (ammoJson[L"desc"].has_number_field(L"guidance"))
|
||||
ammoItem.guidance = ammoJson[L"desc"][L"guidance"].as_number().to_uint32();
|
||||
@ -211,48 +212,53 @@ void Unit::getData(stringstream& ss, unsigned long long time)
|
||||
|
||||
const unsigned char endOfData = DataIndex::endOfData;
|
||||
ss.write((const char*)&ID, sizeof(ID));
|
||||
for (unsigned char datumIndex = DataIndex::startOfData + 1; datumIndex < DataIndex::lastIndex; datumIndex++)
|
||||
{
|
||||
if (checkFreshness(datumIndex, time)) {
|
||||
switch (datumIndex) {
|
||||
case DataIndex::category: appendString(ss, datumIndex, category); break;
|
||||
case DataIndex::alive: appendNumeric(ss, datumIndex, alive); break;
|
||||
case DataIndex::human: appendNumeric(ss, datumIndex, human); break;
|
||||
case DataIndex::controlled: appendNumeric(ss, datumIndex, controlled); break;
|
||||
case DataIndex::coalition: appendNumeric(ss, datumIndex, coalition); break;
|
||||
case DataIndex::country: appendNumeric(ss, datumIndex, country); break;
|
||||
case DataIndex::name: appendString(ss, datumIndex, name); break;
|
||||
case DataIndex::unitName: appendString(ss, datumIndex, unitName); break;
|
||||
case DataIndex::groupName: appendString(ss, datumIndex, groupName); break;
|
||||
case DataIndex::state: appendNumeric(ss, datumIndex, state); break;
|
||||
case DataIndex::task: appendString(ss, datumIndex, task); break;
|
||||
case DataIndex::hasTask: appendNumeric(ss, datumIndex, hasTask); break;
|
||||
case DataIndex::position: appendNumeric(ss, datumIndex, position); break;
|
||||
case DataIndex::speed: appendNumeric(ss, datumIndex, speed); break;
|
||||
case DataIndex::heading: appendNumeric(ss, datumIndex, heading); break;
|
||||
case DataIndex::isTanker: appendNumeric(ss, datumIndex, isTanker); break;
|
||||
case DataIndex::isAWACS: appendNumeric(ss, datumIndex, isAWACS); break;
|
||||
case DataIndex::onOff: appendNumeric(ss, datumIndex, onOff); break;
|
||||
case DataIndex::followRoads: appendNumeric(ss, datumIndex, followRoads); break;
|
||||
case DataIndex::fuel: appendNumeric(ss, datumIndex, fuel); break;
|
||||
case DataIndex::desiredSpeed: appendNumeric(ss, datumIndex, desiredSpeed); break;
|
||||
case DataIndex::desiredSpeedType: appendNumeric(ss, datumIndex, desiredSpeedType); break;
|
||||
case DataIndex::desiredAltitude: appendNumeric(ss, datumIndex, desiredAltitude); break;
|
||||
case DataIndex::desiredAltitudeType: appendNumeric(ss, datumIndex, desiredAltitudeType); break;
|
||||
case DataIndex::leaderID: appendNumeric(ss, datumIndex, leaderID); break;
|
||||
case DataIndex::formationOffset: appendNumeric(ss, datumIndex, formationOffset); break;
|
||||
case DataIndex::targetID: appendNumeric(ss, datumIndex, targetID); break;
|
||||
case DataIndex::targetPosition: appendNumeric(ss, datumIndex, targetPosition); break;
|
||||
case DataIndex::ROE: appendNumeric(ss, datumIndex, ROE); break;
|
||||
case DataIndex::reactionToThreat: appendNumeric(ss, datumIndex, reactionToThreat); break;
|
||||
case DataIndex::emissionsCountermeasures: appendNumeric(ss, datumIndex, emissionsCountermeasures); break;
|
||||
case DataIndex::TACAN: appendNumeric(ss, datumIndex, TACAN); break;
|
||||
case DataIndex::radio: appendNumeric(ss, datumIndex, radio); break;
|
||||
case DataIndex::generalSettings: appendNumeric(ss, datumIndex, generalSettings); break;
|
||||
case DataIndex::ammo: appendVector(ss, datumIndex, ammo); break;
|
||||
case DataIndex::contacts: appendVector(ss, datumIndex, contacts); break;
|
||||
case DataIndex::activePath: appendList(ss, datumIndex, activePath); break;
|
||||
case DataIndex::isLeader: appendNumeric(ss, datumIndex, isLeader); break;
|
||||
if (!alive) {
|
||||
appendNumeric(ss, DataIndex::alive, alive);
|
||||
}
|
||||
else {
|
||||
for (unsigned char datumIndex = DataIndex::startOfData + 1; datumIndex < DataIndex::lastIndex; datumIndex++)
|
||||
{
|
||||
if (checkFreshness(datumIndex, time)) {
|
||||
switch (datumIndex) {
|
||||
case DataIndex::category: appendString(ss, datumIndex, category); break;
|
||||
case DataIndex::alive: appendNumeric(ss, datumIndex, alive); break;
|
||||
case DataIndex::human: appendNumeric(ss, datumIndex, human); break;
|
||||
case DataIndex::controlled: appendNumeric(ss, datumIndex, controlled); break;
|
||||
case DataIndex::coalition: appendNumeric(ss, datumIndex, coalition); break;
|
||||
case DataIndex::country: appendNumeric(ss, datumIndex, country); break;
|
||||
case DataIndex::name: appendString(ss, datumIndex, name); break;
|
||||
case DataIndex::unitName: appendString(ss, datumIndex, unitName); break;
|
||||
case DataIndex::groupName: appendString(ss, datumIndex, groupName); break;
|
||||
case DataIndex::state: appendNumeric(ss, datumIndex, state); break;
|
||||
case DataIndex::task: appendString(ss, datumIndex, task); break;
|
||||
case DataIndex::hasTask: appendNumeric(ss, datumIndex, hasTask); break;
|
||||
case DataIndex::position: appendNumeric(ss, datumIndex, position); break;
|
||||
case DataIndex::speed: appendNumeric(ss, datumIndex, speed); break;
|
||||
case DataIndex::heading: appendNumeric(ss, datumIndex, heading); break;
|
||||
case DataIndex::isTanker: appendNumeric(ss, datumIndex, isTanker); break;
|
||||
case DataIndex::isAWACS: appendNumeric(ss, datumIndex, isAWACS); break;
|
||||
case DataIndex::onOff: appendNumeric(ss, datumIndex, onOff); break;
|
||||
case DataIndex::followRoads: appendNumeric(ss, datumIndex, followRoads); break;
|
||||
case DataIndex::fuel: appendNumeric(ss, datumIndex, fuel); break;
|
||||
case DataIndex::desiredSpeed: appendNumeric(ss, datumIndex, desiredSpeed); break;
|
||||
case DataIndex::desiredSpeedType: appendNumeric(ss, datumIndex, desiredSpeedType); break;
|
||||
case DataIndex::desiredAltitude: appendNumeric(ss, datumIndex, desiredAltitude); break;
|
||||
case DataIndex::desiredAltitudeType: appendNumeric(ss, datumIndex, desiredAltitudeType); break;
|
||||
case DataIndex::leaderID: appendNumeric(ss, datumIndex, leaderID); break;
|
||||
case DataIndex::formationOffset: appendNumeric(ss, datumIndex, formationOffset); break;
|
||||
case DataIndex::targetID: appendNumeric(ss, datumIndex, targetID); break;
|
||||
case DataIndex::targetPosition: appendNumeric(ss, datumIndex, targetPosition); break;
|
||||
case DataIndex::ROE: appendNumeric(ss, datumIndex, ROE); break;
|
||||
case DataIndex::reactionToThreat: appendNumeric(ss, datumIndex, reactionToThreat); break;
|
||||
case DataIndex::emissionsCountermeasures: appendNumeric(ss, datumIndex, emissionsCountermeasures); break;
|
||||
case DataIndex::TACAN: appendNumeric(ss, datumIndex, TACAN); break;
|
||||
case DataIndex::radio: appendNumeric(ss, datumIndex, radio); break;
|
||||
case DataIndex::generalSettings: appendNumeric(ss, datumIndex, generalSettings); break;
|
||||
case DataIndex::ammo: appendVector(ss, datumIndex, ammo); break;
|
||||
case DataIndex::contacts: appendVector(ss, datumIndex, contacts); break;
|
||||
case DataIndex::activePath: appendList(ss, datumIndex, activePath); break;
|
||||
case DataIndex::isLeader: appendNumeric(ss, datumIndex, isLeader); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user