Multiple bug fixes and optimizations

This commit is contained in:
Pax1601 2023-07-28 17:43:31 +02:00
parent bac2c430ef
commit fd7f4b9772
9 changed files with 240 additions and 172 deletions

View File

@ -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();

View File

@ -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) {

View File

@ -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);

View File

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

View File

@ -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);

View File

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

View File

@ -1,6 +1,6 @@
{
"server": {
"address": "localhost",
"address": "88.99.250.188",
"port": 30000
},
"authentication": {

View File

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

View File

@ -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;
}
}
}
}