Tweaks and implemented workaround to MIST bug

This commit is contained in:
Pax1601
2023-07-12 17:01:03 +02:00
parent b78cd27e4e
commit a949a9bf22
27 changed files with 453 additions and 135 deletions

View File

@@ -1,12 +1,12 @@
{ {
"name": "DCSOlympus", "name": "DCSOlympus",
"version": "v0.3.0-alpha", "version": "v0.4.0-alpha",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "DCSOlympus", "name": "DCSOlympus",
"version": "v0.3.0-alpha", "version": "v0.4.0-alpha",
"dependencies": { "dependencies": {
"@turf/turf": "^6.5.0", "@turf/turf": "^6.5.0",
"@types/formatcoords": "^1.1.0", "@types/formatcoords": "^1.1.0",

View File

@@ -2,7 +2,7 @@
"name": "DCSOlympus", "name": "DCSOlympus",
"node-main": "./bin/www", "node-main": "./bin/www",
"main": "http://localhost:3000", "main": "http://localhost:3000",
"version": "v0.3.0-alpha", "version": "v0.4.0-alpha",
"private": true, "private": true,
"scripts": { "scripts": {
"copy": "copy.bat", "copy": "copy.bat",

View File

@@ -31,7 +31,7 @@ export class MapContextMenu extends ContextMenu {
#navyUnitTypeDropdown: Dropdown; #navyUnitTypeDropdown: Dropdown;
#navyUnitNameDropdown: Dropdown; #navyUnitNameDropdown: Dropdown;
#navyUnitCountDropdown: Dropdown; #navyUnitCountDropdown: Dropdown;
#spawnOptions = { role: "", name: "", latlng: new LatLng(0, 0), coalition: "blue", loadout: "", airbaseName: "", altitude: ftToM(20000), count: 1 }; #spawnOptions = { role: "", name: "", latlng: new LatLng(0, 0), coalition: "blue", loadout: "", airbaseName: "", altitude: 0, count: 1 };
#coalitionArea: CoalitionArea | null = null; #coalitionArea: CoalitionArea | null = null;
constructor(id: string) { constructor(id: string) {
@@ -89,7 +89,7 @@ export class MapContextMenu extends ContextMenu {
this.hideSubMenus(e.detail.type); this.hideSubMenus(e.detail.type);
}); });
document.addEventListener("contextMenuDeployAircraft", () => { document.addEventListener("contextMenuDeployAircrafts", () => {
this.hide(); this.hide();
this.#spawnOptions.coalition = getActiveCoalition(); this.#spawnOptions.coalition = getActiveCoalition();
if (this.#spawnOptions) { if (this.#spawnOptions) {
@@ -103,7 +103,7 @@ export class MapContextMenu extends ContextMenu {
} }
}); });
document.addEventListener("contextMenuDeployHelicopter", () => { document.addEventListener("contextMenuDeployHelicopters", () => {
this.hide(); this.hide();
this.#spawnOptions.coalition = getActiveCoalition(); this.#spawnOptions.coalition = getActiveCoalition();
if (this.#spawnOptions) { if (this.#spawnOptions) {
@@ -117,7 +117,7 @@ export class MapContextMenu extends ContextMenu {
} }
}); });
document.addEventListener("contextMenuDeployGroundUnit", () => { document.addEventListener("contextMenuDeployGroundUnits", () => {
this.hide(); this.hide();
this.#spawnOptions.coalition = getActiveCoalition(); this.#spawnOptions.coalition = getActiveCoalition();
if (this.#spawnOptions) { if (this.#spawnOptions) {
@@ -222,6 +222,13 @@ export class MapContextMenu extends ContextMenu {
this.#groundUnitCountDropdown.setValue("1"); this.#groundUnitCountDropdown.setValue("1");
this.clip(); this.clip();
if (type === "aircraft") {
this.#spawnOptions.altitude = ftToM(this.#aircraftSpawnAltitudeSlider.getValue());
}
else if (type === "helicopter") {
this.#spawnOptions.altitude = ftToM(this.#helicopterSpawnAltitudeSlider.getValue());
}
this.setVisibleSubMenu(type); this.setVisibleSubMenu(type);
} }

View File

@@ -17,6 +17,8 @@ import { TargetMarker } from "./targetmarker";
import { CoalitionArea } from "./coalitionarea"; import { CoalitionArea } from "./coalitionarea";
import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu"; import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu";
import { DrawingCursor } from "./drawingcursor"; import { DrawingCursor } from "./drawingcursor";
import { aircraftDatabase } from "../units/aircraftdatabase";
import { groundUnitDatabase } from "../units/groundunitdatabase";
L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect); L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect);
@@ -422,6 +424,9 @@ export class Map extends L.Map {
#onDoubleClick(e: any) { #onDoubleClick(e: any) {
this.deselectAllCoalitionAreas(); this.deselectAllCoalitionAreas();
var db = groundUnitDatabase;
db.generateTestGrid(this.getMouseCoordinates())
} }
#onContextMenu(e: any) { #onContextMenu(e: any) {

View File

@@ -153,7 +153,7 @@ export function spawnAircrafts(units: any, coalition: string, airbaseName: strin
export function spawnHelicopters(units: any, coalition: string, airbaseName: string, immediate: boolean) { export function spawnHelicopters(units: any, coalition: string, airbaseName: string, immediate: boolean) {
var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "immediate": immediate }; var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "immediate": immediate };
var data = { "spawnHelicopter": command } var data = { "spawnHelicopters": command }
POST(data, () => { }); POST(data, () => { });
} }
@@ -191,8 +191,8 @@ export function cloneUnit(ID: number, latlng: LatLng) {
POST(data, () => { }); POST(data, () => { });
} }
export function deleteUnit(ID: number, explosion: boolean) { export function deleteUnit(ID: number, explosion: boolean, immediate: boolean) {
var command = { "ID": ID, "explosion": explosion }; var command = { "ID": ID, "explosion": explosion, "immediate": immediate };
var data = { "deleteUnit": command } var data = { "deleteUnit": command }
POST(data, () => { }); POST(data, () => { });
} }

View File

@@ -3906,6 +3906,10 @@ export class AircraftDatabase extends UnitDatabase {
} }
} }
} }
getCategory() {
return "Aircraft";
}
} }
export var aircraftDatabase = new AircraftDatabase(); export var aircraftDatabase = new AircraftDatabase();

View File

@@ -1537,6 +1537,10 @@ export class GroundUnitDatabase extends UnitDatabase {
} }
} }
} }
getCategory() {
return "GroundUnit";
}
} }
export var groundUnitDatabase = new GroundUnitDatabase(); export var groundUnitDatabase = new GroundUnitDatabase();

View File

@@ -578,6 +578,10 @@ export class HelicopterDatabase extends UnitDatabase {
} }
} }
} }
getCategory() {
return "Helicopter";
}
} }
export var helicopterDatabase = new HelicopterDatabase(); export var helicopterDatabase = new HelicopterDatabase();

View File

@@ -631,8 +631,8 @@ export class NavyUnitDatabase extends UnitDatabase {
"range": "", "range": "",
"filename": "" "filename": ""
}, },
"Ticonderoga": { "TICONDEROG": {
"name": "Ticonderoga", "name": "TICONDEROG",
"type": "Cruiser", "type": "Cruiser",
"era": [ "era": [
"Late Cold War" "Late Cold War"
@@ -941,6 +941,10 @@ export class NavyUnitDatabase extends UnitDatabase {
} }
} }
} }
getCategory() {
return "NavyUnit";
}
} }
export var navyUnitDatabase = new NavyUnitDatabase(); export var navyUnitDatabase = new NavyUnitDatabase();

View File

@@ -646,8 +646,8 @@ export class Unit extends CustomMarker {
setFollowRoads(this.ID, followRoads); setFollowRoads(this.ID, followRoads);
} }
delete(explosion: boolean) { delete(explosion: boolean, immediate: boolean) {
deleteUnit(this.ID, explosion); deleteUnit(this.ID, explosion, immediate);
} }
refuel() { refuel() {

View File

@@ -1,3 +1,6 @@
import { LatLng } from "leaflet";
import { getUnitsManager } from "..";
export class UnitDatabase { export class UnitDatabase {
blueprints: { [key: string]: UnitBlueprint } = {}; blueprints: { [key: string]: UnitBlueprint } = {};
@@ -5,6 +8,10 @@ export class UnitDatabase {
} }
getCategory() {
return "";
}
getBlueprints() { getBlueprints() {
return this.blueprints; return this.blueprints;
} }
@@ -143,4 +150,16 @@ export class UnitDatabase {
} }
return null; return null;
} }
generateTestGrid(initialPosition: LatLng) {
const step = 0.01;
var nUnits = Object.values(this.blueprints).length;
var gridSize = Math.ceil(Math.sqrt(nUnits));
Object.values(this.blueprints).forEach((unitBlueprint: UnitBlueprint, idx: number) => {
var row = Math.floor(idx / gridSize);
var col = idx - row * gridSize;
var location = new LatLng(initialPosition.lat + col * step, initialPosition.lng + row * step)
getUnitsManager().spawnUnit(this.getCategory(), [{unitType: unitBlueprint.name, location: location, altitude: 1000, loadout: ""}]);
})
}
} }

View File

@@ -1,15 +1,14 @@
import { LatLng, LatLngBounds } from "leaflet"; import { LatLng, LatLngBounds } from "leaflet";
import { getHotgroupPanel, getInfoPopup, getMap, getMissionHandler } from ".."; import { getHotgroupPanel, getInfoPopup, getMap } from "..";
import { Unit } from "./unit"; import { Unit } from "./unit";
import { cloneUnit, setLastUpdateTime, spawnGroundUnits } from "../server/server"; import { cloneUnit, setLastUpdateTime, spawnAircrafts, spawnGroundUnits } from "../server/server";
import { bearingAndDistanceToLatLng, deg2rad, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polyContains, polygonArea, randomPointInPoly, randomUnitBlueprint } from "../other/utils"; import { bearingAndDistanceToLatLng, deg2rad, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polyContains, polygonArea, randomPointInPoly, randomUnitBlueprint } from "../other/utils";
import { CoalitionArea } from "../map/coalitionarea"; import { CoalitionArea } from "../map/coalitionarea";
import { Airbase } from "../missionhandler/airbase";
import { groundUnitDatabase } from "./groundunitdatabase"; import { groundUnitDatabase } from "./groundunitdatabase";
import { DataIndexes, HIDE_ALL, IADSDensities, IDLE, MOVE_UNIT } from "../constants/constants"; import { DataIndexes, HIDE_ALL, IADSDensities, IDLE, MOVE_UNIT } from "../constants/constants";
import { DataExtractor } from "./dataextractor"; import { DataExtractor } from "./dataextractor";
import { Contact } from "../@types/unit"; import { Contact } from "../@types/unit";
import { citiesDatabase } from "./citiesDatabase"; import { citiesDatabase } from "./citiesdatabase";
export class UnitsManager { export class UnitsManager {
#units: { [ID: number]: Unit }; #units: { [ID: number]: Unit };
@@ -378,8 +377,12 @@ export class UnitsManager {
return; return;
} }
var immediate = false;
if (selectedUnits.length > 20)
immediate = confirm(`You are trying to delete ${selectedUnits.length} units, do you want to delete them immediately? This may cause lag for players.`)
for (let idx in selectedUnits) { for (let idx in selectedUnits) {
selectedUnits[idx].delete(explosion); selectedUnits[idx].delete(explosion, immediate);
} }
this.#showActionMessage(selectedUnits, `deleted`); this.#showActionMessage(selectedUnits, `deleted`);
} }
@@ -518,7 +521,7 @@ export class UnitsManager {
if (this.#units[idx].getCoalition() !== "neutral" && this.#units[idx].getCoalition() != unit.getCoalition()) if (this.#units[idx].getCoalition() !== "neutral" && this.#units[idx].getCoalition() != unit.getCoalition())
{ {
this.#units[idx].getContacts().forEach((contact: Contact) => { this.#units[idx].getContacts().forEach((contact: Contact) => {
if (contact.ID == unit.ID && !detectionMethods.includes(contact.detectionMethod)) if (this.#units[idx].getAlive() && contact.ID == unit.ID && !detectionMethods.includes(contact.detectionMethod))
detectionMethods.push(contact.detectionMethod); detectionMethods.push(contact.detectionMethod);
}); });
} }
@@ -616,6 +619,14 @@ export class UnitsManager {
input.click(); input.click();
} }
spawnUnit(category: string, units: any, coalition: string = "blue", immediate: boolean = true) {
if (category === "Aircraft") {
spawnAircrafts(units, coalition, "", immediate);
} else if (category === "GroundUnit") {
spawnGroundUnits(units, coalition, immediate);
}
}
/***********************************************/ /***********************************************/
#onKeyUp(event: KeyboardEvent) { #onKeyUp(event: KeyboardEvent) {
if (!keyEventWasInInput(event) && event.key === "Delete" ) { if (!keyEventWasInInput(event) && event.key === "Delete" ) {

View File

@@ -4,8 +4,8 @@
<div id="coalition-switch" class="ol-switch ol-coalition-switch"></div> <div id="coalition-switch" class="ol-switch ol-coalition-switch"></div>
<button data-coalition="blue" id="aircraft-spawn-button" title="Spawn aircraft" data-on-click="mapContextMenuShow" <button data-coalition="blue" id="aircraft-spawn-button" title="Spawn aircraft" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "aircraft" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/aircraft.svg" inject-svg></button> data-on-click-params='{ "type": "aircraft" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/aircraft.svg" inject-svg></button>
<!--<button data-coalition="blue" id="helicopter-spawn-button" title="Spawn helicopter" data-on-click="mapContextMenuShow" <button data-coalition="blue" id="helicopter-spawn-button" title="Spawn helicopter" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "helicopter" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/helicopter.svg" inject-svg></button>--> data-on-click-params='{ "type": "helicopter" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/helicopter.svg" inject-svg></button>
<button data-coalition="blue" id="groundunit-spawn-button" title="Spawn ground unit" data-on-click="mapContextMenuShow" <button data-coalition="blue" id="groundunit-spawn-button" title="Spawn ground unit" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "groundunit" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/groundunit.svg" inject-svg></button> data-on-click-params='{ "type": "groundunit" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/groundunit.svg" inject-svg></button>
<button data-coalition="blue" id="coalition-area-button" title="Edit coalition area" data-on-click="editCoalitionArea" <button data-coalition="blue" id="coalition-area-button" title="Edit coalition area" data-on-click="editCoalitionArea"
@@ -15,9 +15,10 @@
</div> </div>
<div id="more-options-button-bar" class="upper-bar ol-panel hide"> <div id="more-options-button-bar" class="upper-bar ol-panel hide">
<div id="coalition-switch" class="ol-switch ol-coalition-switch"></div> <div id="coalition-switch" class="ol-switch ol-coalition-switch"></div>
<!--
<!-- <button data-coalition="blue" id="navyunit-spawn-button" title="Spawn navy unit" data-on-click="mapContextMenuShow" <button data-coalition="blue" id="navyunit-spawn-button" title="Spawn navy unit" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "navyunit" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/navyunit.svg" inject-svg></button> --> data-on-click-params='{ "type": "navyunit" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/navyunit.svg" inject-svg></button>
-->
<button data-coalition="blue" id="smoke-spawn-button" title="Spawn smoke" data-on-click="mapContextMenuShow" <button data-coalition="blue" id="smoke-spawn-button" title="Spawn smoke" data-on-click="mapContextMenuShow"
data-on-click-params='{ "type": "smoke" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/smoke.svg" inject-svg></button> data-on-click-params='{ "type": "smoke" }' class="ol-contexmenu-button"><img src="/resources/theme/images/buttons/spawn/smoke.svg" inject-svg></button>
<button data-coalition="blue" id="explosion-spawn-button" title="Explosion" data-on-click="mapContextMenuShow" <button data-coalition="blue" id="explosion-spawn-button" title="Explosion" data-on-click="mapContextMenuShow"
@@ -75,7 +76,7 @@
<div id="aircraft-loadout-list"> <div id="aircraft-loadout-list">
</div> </div>
</div> </div>
<button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployAircraft" disabled>Deploy unit</button> <button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployAircrafts" disabled>Deploy unit</button>
</div> </div>
<div id="helicopter-spawn-menu" class="ol-contexmenu-panel ol-panel hide"> <div id="helicopter-spawn-menu" class="ol-contexmenu-panel ol-panel hide">
<div class="ol-select-container"> <div class="ol-select-container">
@@ -129,7 +130,7 @@
<div id="helicopter-loadout-list"> <div id="helicopter-loadout-list">
</div> </div>
</div> </div>
<button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployAircraft" disabled>Deploy unit</button> <button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployHelicopters" disabled>Deploy unit</button>
</div> </div>
<div id="groundunit-spawn-menu" class="ol-panel ol-contexmenu-panel hide"> <div id="groundunit-spawn-menu" class="ol-panel ol-contexmenu-panel hide">
<div class="ol-select-container"> <div class="ol-select-container">
@@ -158,7 +159,7 @@
</div> </div>
</div> </div>
</div> </div>
<button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployGroundUnit" disabled>Deploy unit</button> <button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployGroundUnits" disabled>Deploy unit</button>
</div> </div>
<div id="navyunit-spawn-menu" class="ol-panel ol-contexmenu-panel hide"> <div id="navyunit-spawn-menu" class="ol-panel ol-contexmenu-panel hide">
<div class="ol-select-container"> <div class="ol-select-container">
@@ -187,7 +188,7 @@
</div> </div>
</div> </div>
</div> </div>
<button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployNavyUnit" disabled>Deploy unit</button> <button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployNavyUnits" disabled>Deploy unit</button>
</div> </div>
<div id="smoke-spawn-menu" class="ol-panel ol-contexmenu-panel hide"> <div id="smoke-spawn-menu" class="ol-panel ol-contexmenu-panel hide">
<button class="smoke-button" title="" data-smoke-color="white" data-on-click="contextMenuDeploySmoke" data-on-click-params='{ "color": "white" }'>White smoke</button> <button class="smoke-button" title="" data-smoke-color="white" data-on-click="contextMenuDeploySmoke" data-on-click-params='{ "color": "white" }'>White smoke</button>

View File

@@ -3,7 +3,7 @@
<div id="app-summary"> <div id="app-summary">
<h2>DCS Olympus</h2> <h2>DCS Olympus</h2>
<h4>Dynamic Unit Command</h4> <h4>Dynamic Unit Command</h4>
<div class="app-version">Version <span class="app-version-number">v0.3.0</span></div> <div class="app-version">Version <span class="app-version-number">v0.4.0-alpha</span></div>
</div> </div>
<div id="authentication-form"> <div id="authentication-form">

View File

@@ -6,7 +6,7 @@
<div class="ol-select-options"> <div class="ol-select-options">
<div id="toolbar-summary"> <div id="toolbar-summary">
<h3>DCS Olympus</h3> <h3>DCS Olympus</h3>
<div class="accent-green app-version-number">version v0.3.0</div> <div class="accent-green app-version-number">version v0.4.0-alpha</div>
</div> </div>
<div> <div>
<a href="https://www.discord.com" target="_blank">Discord</a> <a href="https://www.discord.com" target="_blank">Discord</a>

View File

@@ -1,5 +1,5 @@
#define nwjsFolder "C:\Users\dpass\Documents\nwjs\" #define nwjsFolder "C:\Users\dpass\Documents\nwjs\"
#define version "v0.3.0-alpha" #define version "v0.4.0-alpha"
[Setup] [Setup]
AppName=DCS Olympus AppName=DCS Olympus

View File

@@ -15,7 +15,7 @@ declare_plugin(self_ID,
shortName = "Olympus", shortName = "Olympus",
fileMenuName = "Olympus", fileMenuName = "Olympus",
version = "0.1.1-alpha", version = "v0.4.0-alpha",
state = "installed", state = "installed",
developerName= "DCS Refugees 767 squadron", developerName= "DCS Refugees 767 squadron",
info = _("DCS Olympus is a mod for DCS World. It allows users to spawn, control, task, group, and remove units from a DCS World server using a real-time map interface, similarly to Real Time Strategy games. The user interface also provides useful informations units, like loadouts, fuel, tasking, and so on. In the future, more features for DCS World GCI and JTAC will be available."), info = _("DCS Olympus is a mod for DCS World. It allows users to spawn, control, task, group, and remove units from a DCS World server using a real-time map interface, similarly to Real Time Strategy games. The user interface also provides useful informations units, like loadouts, fuel, tasking, and so on. In the future, more features for DCS World GCI and JTAC will be available."),

View File

@@ -1,6 +1,6 @@
local version = "v0.3.0-alpha" local version = "v0.4.0-alpha"
local debug = false local debug = true
Olympus.unitCounter = 1 Olympus.unitCounter = 1
Olympus.payloadRegistry = {} Olympus.payloadRegistry = {}
@@ -10,6 +10,7 @@ Olympus.groupStep = 40
Olympus.OlympusDLL = nil Olympus.OlympusDLL = nil
Olympus.DLLsloaded = false Olympus.DLLsloaded = false
Olympus.OlympusModPath = os.getenv('DCSOLYMPUS_PATH')..'\\bin\\' Olympus.OlympusModPath = os.getenv('DCSOLYMPUS_PATH')..'\\bin\\'
Olympus.log = mist.Logger:new("Olympus", 'info')
function Olympus.debug(message, displayFor) function Olympus.debug(message, displayFor)
if debug == true then if debug == true then
@@ -252,7 +253,51 @@ function Olympus.move(groupName, lat, lng, altitude, altitudeType, speed, speedT
if groupCon then if groupCon then
groupCon:setTask(missionTask) groupCon:setTask(missionTask)
end end
Olympus.debug("Olympus.move executed successfully on a Aircraft", 2) Olympus.debug("Olympus.move executed successfully on Aircraft", 2)
elseif category == "Helicopter" then
local startPoint = mist.getLeadPos(group)
local endPoint = coord.LLtoLO(lat, lng, 0)
if altitudeType == "AGL" then
altitude = land.getHeight({x = endPoint.x, y = endPoint.z}) + altitude
end
local path = {}
if taskOptions and taskOptions['id'] == 'Land' then
path = {
[1] = mist.heli.buildWP(startPoint, turningPoint, speed, altitude, 'BARO'),
[2] = mist.heli.buildWP(endPoint, landing, speed, 0, 'AGL')
}
else
path = {
[1] = mist.heli.buildWP(startPoint, turningPoint, speed, altitude, 'BARO'),
[2] = mist.heli.buildWP(endPoint, turningPoint, speed, altitude, 'BARO')
}
end
-- If a task exists assign it to the controller
if taskOptions then
local task = Olympus.buildEnrouteTask(taskOptions)
if task then
path[1].task = task
path[2].task = task
end
end
-- Assign the mission task to the controller
local missionTask = {
id = 'Mission',
params = {
route = {
points = mist.utils.deepCopy(path),
},
},
}
local groupCon = group:getController()
if groupCon then
groupCon:setTask(missionTask)
end
Olympus.debug("Olympus.move executed successfully on Helicopter", 2)
elseif category == "GroundUnit" then elseif category == "GroundUnit" then
vars = vars =
{ {
@@ -270,7 +315,17 @@ function Olympus.move(groupName, lat, lng, altitude, altitudeType, speed, speedT
end end
mist.groupToRandomPoint(vars) mist.groupToRandomPoint(vars)
Olympus.debug("Olympus.move executed succesfully on a ground unit", 2) Olympus.debug("Olympus.move executed succesfully on GroundUnit", 2)
elseif category == "NavyUnit" then
vars =
{
group = group,
point = coord.LLtoLO(lat, lng, 0),
heading = 0,
speed = speed
}
mist.groupToRandomPoint(vars)
Olympus.debug("Olympus.move executed succesfully on NavyUnit", 2)
else else
Olympus.debug("Olympus.move not implemented yet for " .. category, 2) Olympus.debug("Olympus.move not implemented yet for " .. category, 2)
end end
@@ -314,12 +369,21 @@ function Olympus.spawnUnits(spawnTable)
if spawnTable.category == 'Aircraft' then if spawnTable.category == 'Aircraft' then
unitTable = Olympus.generateAirUnitsTable(spawnTable.units) unitTable = Olympus.generateAirUnitsTable(spawnTable.units)
route = Olympus.generateAirUnitsRoute(spawnTable) route = Olympus.generateAirUnitsRoute(spawnTable)
category = 'airplane' category = 'plane'
elseif spawnTable.category == 'Helicopter' then
unitTable = Olympus.generateAirUnitsTable(spawnTable.units)
route = Olympus.generateAirUnitsRoute(spawnTable)
category = 'helicopter'
elseif spawnTable.category == 'GroundUnit' then elseif spawnTable.category == 'GroundUnit' then
unitTable = Olympus.generateGroundUnitsTable(spawnTable.units) unitTable = Olympus.generateGroundUnitsTable(spawnTable.units)
category = 'vehicle' category = 'vehicle'
elseif spawnTable.category == 'NavyUnit' then
unitTable = Olympus.generateNavyUnitsTable(spawnTable.units)
category = 'ship'
end end
Olympus.debug(Olympus.serializeTable(unitTable), 5)
local countryID = Olympus.getCountryIDByCoalition(spawnTable.coalition) local countryID = Olympus.getCountryIDByCoalition(spawnTable.coalition)
local vars = local vars =
{ {
@@ -336,37 +400,6 @@ function Olympus.spawnUnits(spawnTable)
Olympus.debug("Olympus.spawnUnits completed succesfully", 2) Olympus.debug("Olympus.spawnUnits completed succesfully", 2)
end end
-- Generates ground units table, either single or from template
function Olympus.generateGroundUnitsTable(units)
local unitTable = {}
for idx, unit in pairs(units) do
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(unit.lat, unit.lng, 0))
if Olympus.hasKey(templates, unit.unitType) then
for idx, value in pairs(templates[unit.unitType].units) do
unitTable[#unitTable + 1] =
{
["type"] = value.name,
["x"] = spawnLocation.x + value.dx,
["y"] = spawnLocation.z + value.dy,
["heading"] = 0,
["skill"] = "High"
}
end
else
unitTable[#unitTable + 1] =
{
["type"] = unit.unitType,
["x"] = spawnLocation.x,
["y"] = spawnLocation.z,
["heading"] = 0,
["skill"] = "High"
}
end
end
return unitTable
end
-- Generates unit table for a air unit. -- Generates unit table for a air unit.
function Olympus.generateAirUnitsTable(units) function Olympus.generateAirUnitsTable(units)
local unitTable = {} local unitTable = {}
@@ -456,6 +489,74 @@ function Olympus.generateAirUnitsRoute(spawnTable)
return route return route
end end
-- Generates ground units table, either single or from template
function Olympus.generateGroundUnitsTable(units)
local unitTable = {}
for idx, unit in pairs(units) do
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(unit.lat, unit.lng, 0))
if Olympus.hasKey(templates, unit.unitType) then
for idx, value in pairs(templates[unit.unitType].units) do
unitTable[#unitTable + 1] =
{
["type"] = value.name,
["x"] = spawnLocation.x + value.dx,
["y"] = spawnLocation.z + value.dy,
["heading"] = 0,
["skill"] = "High",
["name"] = "GroundUnit-" .. Olympus.unitCounter .. "-" .. #unitTable + 1
}
end
else
unitTable[#unitTable + 1] =
{
["type"] = unit.unitType,
["x"] = spawnLocation.x,
["y"] = spawnLocation.z,
["heading"] = 0,
["skill"] = "High",
["name"] = "GroundUnit-" .. Olympus.unitCounter .. "-" .. #unitTable + 1
}
end
end
return unitTable
end
-- Generates navy units table, either single or from template
function Olympus.generateNavyUnitsTable(units)
local unitTable = {}
for idx, unit in pairs(units) do
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(unit.lat, unit.lng, 0))
if Olympus.hasKey(templates, unit.unitType) then
for idx, value in pairs(templates[unit.unitType].units) do
unitTable[#unitTable + 1] =
{
["type"] = value.name,
["x"] = spawnLocation.x + value.dx,
["y"] = spawnLocation.z + value.dy,
["heading"] = 0,
["skill"] = "High",
["name"] = "NavyUnit-" .. Olympus.unitCounter .. "-" .. #unitTable + 1,
["transportable"] = { ["randomTransportable"] = false }
}
end
else
unitTable[#unitTable + 1] =
{
["type"] = unit.unitType,
["x"] = spawnLocation.x,
["y"] = spawnLocation.z,
["heading"] = 0,
["skill"] = "High",
["name"] = "NavyUnit-" .. Olympus.unitCounter .. "-" .. #unitTable + 1,
["transportable"] = { ["randomTransportable"] = false }
}
end
end
return unitTable
end
-- Clones a unit by ID. Will clone the unit with the same original payload as the source unit. TODO: only works on Olympus unit not ME units. -- Clones a unit by ID. Will clone the unit with the same original payload as the source unit. TODO: only works on Olympus unit not ME units.
function Olympus.clone(ID, lat, lng, category) function Olympus.clone(ID, lat, lng, category)
Olympus.debug("Olympus.clone " .. ID .. ", " .. category, 2) Olympus.debug("Olympus.clone " .. ID .. ", " .. category, 2)

View File

@@ -1,4 +1,4 @@
local version = 'v0.3.0-alpha' local version = 'v0.4.0-alpha'
Olympus = {} Olympus = {}
Olympus.OlympusDLL = nil Olympus.OlympusDLL = nil

View File

@@ -163,7 +163,7 @@ public:
priority = immediate? CommandPriority::IMMEDIATE: CommandPriority::LOW; priority = immediate? CommandPriority::IMMEDIATE: CommandPriority::LOW;
}; };
virtual string getString(lua_State* L); virtual string getString(lua_State* L);
virtual unsigned int getLoad() { return 100 * !immediate; } virtual unsigned int getLoad() { return immediate? 1: 100; }
private: private:
const string coalition; const string coalition;
@@ -172,7 +172,29 @@ private:
const bool immediate; const bool immediate;
}; };
/* Spawn air unit command */ /* Spawn navy unit command */
class SpawnNavyUnits : public Command
{
public:
SpawnNavyUnits(string coalition, vector<string> unitTypes, vector<Coords> locations, bool immediate) :
coalition(coalition),
unitTypes(unitTypes),
locations(locations),
immediate(immediate)
{
priority = immediate ? CommandPriority::IMMEDIATE : CommandPriority::LOW;
};
virtual string getString(lua_State* L);
virtual unsigned int getLoad() { return immediate ? 1 : 100; }
private:
const string coalition;
const vector<string> unitTypes;
const vector<Coords> locations;
const bool immediate;
};
/* Spawn aircraft command */
class SpawnAircrafts : public Command class SpawnAircrafts : public Command
{ {
public: public:
@@ -187,7 +209,34 @@ public:
priority = immediate ? CommandPriority::IMMEDIATE : CommandPriority::LOW; priority = immediate ? CommandPriority::IMMEDIATE : CommandPriority::LOW;
}; };
virtual string getString(lua_State* L); virtual string getString(lua_State* L);
virtual unsigned int getLoad() { return 100 * !immediate; } virtual unsigned int getLoad() { return immediate ? 1 : 100; }
private:
const string coalition;
const vector<string> unitTypes;
const vector<Coords> locations;
const vector<string> loadouts;
const string airbaseName;
const bool immediate;
};
/* Spawn helicopter command */
class SpawnHelicopters : public Command
{
public:
SpawnHelicopters(string coalition, vector<string> unitTypes, vector<Coords> locations, vector<string> loadouts, string airbaseName, bool immediate) :
coalition(coalition),
unitTypes(unitTypes),
locations(locations),
loadouts(loadouts),
airbaseName(airbaseName),
immediate(immediate)
{
priority = immediate ? CommandPriority::IMMEDIATE : CommandPriority::LOW;
};
virtual string getString(lua_State* L);
virtual unsigned int getLoad() { return immediate ? 1 : 100; }
private: private:
const string coalition; const string coalition;
@@ -220,18 +269,21 @@ private:
class Delete : public Command class Delete : public Command
{ {
public: public:
Delete(unsigned int ID, bool explosion) : Delete(unsigned int ID, bool explosion, bool immediate ) :
ID(ID), ID(ID),
explosion(explosion) explosion(explosion),
immediate(immediate)
{ {
priority = CommandPriority::HIGH; priority = CommandPriority::HIGH;
immediate = immediate;
}; };
virtual string getString(lua_State* L); virtual string getString(lua_State* L);
virtual unsigned int getLoad() { return 20; } virtual unsigned int getLoad() { return immediate? 1: 20; }
private: private:
const unsigned int ID; const unsigned int ID;
const bool explosion; const bool explosion;
const bool immediate;
}; };
/* SetTask command */ /* SetTask command */

View File

@@ -10,6 +10,7 @@ public:
~Scheduler(); ~Scheduler();
void appendCommand(Command* command); void appendCommand(Command* command);
int getCurrentLoad();
void execute(lua_State* L); void execute(lua_State* L);
void handleRequest(string key, json::value value); void handleRequest(string key, json::value value);

View File

@@ -21,7 +21,7 @@ public:
void updateMissionData(json::value missionData); void updateMissionData(json::value missionData);
void runAILoop(); void runAILoop();
string getUnitData(stringstream &ss, unsigned long long time); string getUnitData(stringstream &ss, unsigned long long time);
void deleteUnit(unsigned int ID, bool explosion); void deleteUnit(unsigned int ID, bool explosion, bool immediate);
void acquireControl(unsigned int ID); void acquireControl(unsigned int ID);
private: private:

View File

@@ -60,6 +60,30 @@ string SpawnGroundUnits::getString(lua_State* L)
return commandSS.str(); return commandSS.str();
} }
/* Spawn ground units command */
string SpawnNavyUnits::getString(lua_State* L)
{
if (unitTypes.size() != locations.size()) return "";
std::ostringstream unitsSS;
unitsSS.precision(10);
for (int i = 0; i < unitTypes.size(); i++) {
unitsSS << "[" << i + 1 << "] = {"
<< "unitType = " << "\"" << unitTypes[i] << "\"" << ", "
<< "lat = " << locations[i].lat << ", "
<< "lng = " << locations[i].lng << "},";
}
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.spawnUnits, {"
<< "category = " << "\"" << "NavyUnit" << "\"" << ", "
<< "coalition = " << "\"" << coalition << "\"" << ", "
<< "units = " << "{" << unitsSS.str() << "}" << "}";
return commandSS.str();
}
/* Spawn aircrafts command */ /* Spawn aircrafts command */
string SpawnAircrafts::getString(lua_State* L) string SpawnAircrafts::getString(lua_State* L)
{ {
@@ -86,6 +110,34 @@ string SpawnAircrafts::getString(lua_State* L)
return commandSS.str(); return commandSS.str();
} }
/* Spawn helicopters command */
string SpawnHelicopters::getString(lua_State* L)
{
if (unitTypes.size() != locations.size() || unitTypes.size() != loadouts.size()) return "";
std::ostringstream unitsSS;
unitsSS.precision(10);
for (int i = 0; i < unitTypes.size(); i++) {
unitsSS << "[" << i + 1 << "] = {"
<< "unitType = " << "\"" << unitTypes[i] << "\"" << ", "
<< "lat = " << locations[i].lat << ", "
<< "lng = " << locations[i].lng << ", "
<< "alt = " << locations[i].alt << ", "
<< "loadout = \"" << loadouts[i] << "\"" << "},";
}
std::ostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.spawnUnits, {"
<< "category = " << "\"" << "Helicopter" << "\"" << ", "
<< "coalition = " << "\"" << coalition << "\"" << ", "
<< "airbaseName = \"" << airbaseName << "\", "
<< "units = " << "{" << unitsSS.str() << "}" << "}";
return commandSS.str();
}
/* Clone unit command */ /* Clone unit command */
string Clone::getString(lua_State* L) string Clone::getString(lua_State* L)
{ {

View File

@@ -9,7 +9,8 @@
#include <chrono> #include <chrono>
using namespace std::chrono; using namespace std::chrono;
auto before = std::chrono::system_clock::now(); auto lastUpdate = std::chrono::system_clock::now();
auto lastExecution = std::chrono::system_clock::now();
/* Singleton objects */ /* Singleton objects */
UnitsManager* unitsManager = nullptr; UnitsManager* unitsManager = nullptr;
@@ -72,27 +73,33 @@ extern "C" DllExport int coreFrame(lua_State* L)
frameCounter++; frameCounter++;
/* Slow down the update rate if the frameRate is very low since it means DCS is struggling to keep up */ /* Slow down the update rate if the frameRate is very low since it means DCS is struggling to keep up */
const std::chrono::duration<double> duration = std::chrono::system_clock::now() - before; const std::chrono::duration<double> updateDuration = std::chrono::system_clock::now() - lastUpdate;
if (duration.count() > UPDATE_TIME_INTERVAL * (60.0 / frameRate)) double updateTimeInterval = max(UPDATE_TIME_INTERVAL, UPDATE_TIME_INTERVAL * (60.0 / frameRate));
if (updateDuration.count() > updateTimeInterval)
{ {
/* Lock for thread safety */ /* Lock for thread safety */
lock_guard<mutex> guard(mutexLock); lock_guard<mutex> guard(mutexLock);
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch()); milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
if (duration.count() > 0) if (updateDuration.count() > 0)
frameRate = frameCounter / duration.count(); frameRate = frameCounter / updateDuration.count();
frameCounter = 0; frameCounter = 0;
if (unitsManager != nullptr) { if (unitsManager != nullptr) {
unitsManager->updateExportData(L, duration.count()); unitsManager->updateExportData(L, updateDuration.count());
unitsManager->runAILoop(); unitsManager->runAILoop();
} }
before = std::chrono::system_clock::now(); lastUpdate = std::chrono::system_clock::now();
} }
if (scheduler != nullptr) const std::chrono::duration<double> executionDuration = std::chrono::system_clock::now() - lastExecution;
scheduler->execute(L); double executionTimeInterval = max(EXECUTION_TIME_INTERVAL, EXECUTION_TIME_INTERVAL * (60.0 / frameRate));
if (executionDuration.count() > executionTimeInterval) {
if (scheduler != nullptr)
scheduler->execute(L);
lastExecution = std::chrono::system_clock::now();
}
return(0); return(0);
} }
@@ -104,28 +111,19 @@ extern "C" DllExport int coreMissionData(lua_State * L)
/* Lock for thread safety */ /* Lock for thread safety */
lock_guard<mutex> guard(mutexLock); lock_guard<mutex> guard(mutexLock);
lua_getglobal(L, "Olympus");
lua_getfield(L, -1, "missionData");
json::value missionData = luaTableToJSON(L, -1);
try if (missionData.has_object_field(L"unitsData")) {
{ unitsManager->updateMissionData(missionData[L"unitsData"]);
lua_getglobal(L, "Olympus");
lua_getfield(L, -1, "missionData");
json::value missionData = luaTableToJSON(L, -1);
if (missionData.has_object_field(L"unitsData"))
unitsManager->updateMissionData(missionData[L"unitsData"]);
if (missionData.has_object_field(L"airbases"))
airbases = missionData[L"airbases"];
if (missionData.has_object_field(L"bullseyes"))
bullseyes = missionData[L"bullseyes"];
if (missionData.has_object_field(L"mission"))
mission = missionData[L"mission"];
} }
catch (exception const& e) if (missionData.has_object_field(L"airbases"))
{ airbases = missionData[L"airbases"];
log(e.what()); if (missionData.has_object_field(L"bullseyes"))
} bullseyes = missionData[L"bullseyes"];
if (missionData.has_object_field(L"mission"))
mission = missionData[L"mission"];
return(0); return(0);
} }

View File

@@ -23,6 +23,15 @@ void Scheduler::appendCommand(Command* command)
commands.push_back(command); commands.push_back(command);
} }
int Scheduler::getCurrentLoad()
{
int currentLoad = 0;
for (auto command : commands) {
currentLoad += command->getLoad();
}
return currentLoad;
}
void Scheduler::execute(lua_State* L) void Scheduler::execute(lua_State* L)
{ {
/* Decrease the active computation load. New commands can be sent only if the load has reached 0. /* Decrease the active computation load. New commands can be sent only if the load has reached 0.
@@ -42,7 +51,7 @@ void Scheduler::execute(lua_State* L)
if (dostring_in(L, "server", (commandString))) if (dostring_in(L, "server", (commandString)))
log("Error executing command " + commandString); log("Error executing command " + commandString);
else else
log("Command '" + commandString + "' executed correctly, current load " + to_string(load)); log("Command '" + commandString + "' executed correctly, current load " + to_string(getCurrentLoad()));
load = command->getLoad(); load = command->getLoad();
commands.remove(command); commands.remove(command);
return; return;
@@ -92,25 +101,6 @@ void Scheduler::handleRequest(string key, json::value value)
Coords loc; loc.lat = lat; loc.lng = lng; Coords loc; loc.lat = lat; loc.lng = lng;
command = dynamic_cast<Command*>(new Smoke(color, loc)); command = dynamic_cast<Command*>(new Smoke(color, loc));
} }
else if (key.compare("spawnGroundUnits") == 0)
{
bool immediate = value[L"immediate"].as_bool();
string coalition = to_string(value[L"coalition"]);
vector<string> unitTypes;
vector<Coords> locations;
for (auto unit : value[L"units"].as_array()) {
string unitType = to_string(unit[L"unitType"]);
double lat = unit[L"location"][L"lat"].as_double();
double lng = unit[L"location"][L"lng"].as_double();
Coords location; location.lat = lat; location.lng = lng;
log("Spawning " + coalition + " ground unit of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
unitTypes.push_back(unitType);
locations.push_back(location);
}
command = dynamic_cast<Command*>(new SpawnGroundUnits(coalition, unitTypes, locations, immediate));
}
else if (key.compare("spawnAircrafts") == 0) else if (key.compare("spawnAircrafts") == 0)
{ {
bool immediate = value[L"immediate"].as_bool(); bool immediate = value[L"immediate"].as_bool();
@@ -127,15 +117,78 @@ void Scheduler::handleRequest(string key, json::value value)
double alt = unit[L"altitude"].as_double(); double alt = unit[L"altitude"].as_double();
Coords location; location.lat = lat; location.lng = lng; location.alt = alt; Coords location; location.lat = lat; location.lng = lng; location.alt = alt;
string loadout = to_string(unit[L"loadout"]); string loadout = to_string(unit[L"loadout"]);
log("Spawning " + coalition + " air unit unit of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")"); log("Spawning " + coalition + " aircraft of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
unitTypes.push_back(unitType); unitTypes.push_back(unitType);
locations.push_back(location); locations.push_back(location);
loadouts.push_back(loadout); loadouts.push_back(loadout);
} }
command = dynamic_cast<Command*>(new SpawnAircrafts(coalition, unitTypes, locations, loadouts, airbaseName, immediate)); command = dynamic_cast<Command*>(new SpawnAircrafts(coalition, unitTypes, locations, loadouts, airbaseName, immediate));
} }
else if (key.compare("spawnHelicopters") == 0)
{
bool immediate = value[L"immediate"].as_bool();
string coalition = to_string(value[L"coalition"]);
string airbaseName = to_string(value[L"airbaseName"]);
vector<string> unitTypes;
vector<Coords> locations;
vector<string> loadouts;
for (auto unit : value[L"units"].as_array()) {
string unitType = to_string(unit[L"unitType"]);
double lat = unit[L"location"][L"lat"].as_double();
double lng = unit[L"location"][L"lng"].as_double();
double alt = unit[L"altitude"].as_double();
Coords location; location.lat = lat; location.lng = lng; location.alt = alt;
string loadout = to_string(unit[L"loadout"]);
log("Spawning " + coalition + " helicopter of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
unitTypes.push_back(unitType);
locations.push_back(location);
loadouts.push_back(loadout);
}
command = dynamic_cast<Command*>(new SpawnHelicopters(coalition, unitTypes, locations, loadouts, airbaseName, immediate));
}
else if (key.compare("spawnGroundUnits") == 0)
{
bool immediate = value[L"immediate"].as_bool();
string coalition = to_string(value[L"coalition"]);
vector<string> unitTypes;
vector<Coords> locations;
for (auto unit : value[L"units"].as_array()) {
string unitType = to_string(unit[L"unitType"]);
double lat = unit[L"location"][L"lat"].as_double();
double lng = unit[L"location"][L"lng"].as_double();
Coords location; location.lat = lat; location.lng = lng;
log("Spawning " + coalition + " GroundUnit of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
unitTypes.push_back(unitType);
locations.push_back(location);
}
command = dynamic_cast<Command*>(new SpawnGroundUnits(coalition, unitTypes, locations, immediate));
}
else if (key.compare("spawnNavyUnits") == 0)
{
bool immediate = value[L"immediate"].as_bool();
string coalition = to_string(value[L"coalition"]);
vector<string> unitTypes;
vector<Coords> locations;
for (auto unit : value[L"units"].as_array()) {
string unitType = to_string(unit[L"unitType"]);
double lat = unit[L"location"][L"lat"].as_double();
double lng = unit[L"location"][L"lng"].as_double();
Coords location; location.lat = lat; location.lng = lng;
log("Spawning " + coalition + " NavyUnit of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
unitTypes.push_back(unitType);
locations.push_back(location);
}
command = dynamic_cast<Command*>(new SpawnNavyUnits(coalition, unitTypes, locations, immediate));
}
else if (key.compare("attackUnit") == 0) else if (key.compare("attackUnit") == 0)
{ {
unsigned int ID = value[L"ID"].as_integer(); unsigned int ID = value[L"ID"].as_integer();
@@ -287,7 +340,8 @@ void Scheduler::handleRequest(string key, json::value value)
{ {
unsigned int ID = value[L"ID"].as_integer(); unsigned int ID = value[L"ID"].as_integer();
bool explosion = value[L"explosion"].as_bool(); bool explosion = value[L"explosion"].as_bool();
unitsManager->deleteUnit(ID, explosion); bool immediate = value[L"immediate"].as_bool();
unitsManager->deleteUnit(ID, explosion, immediate);
} }
else if (key.compare("refuel") == 0) else if (key.compare("refuel") == 0)
{ {
@@ -414,7 +468,7 @@ void Scheduler::handleRequest(string key, json::value value)
if (command != nullptr) if (command != nullptr)
{ {
appendCommand(command); appendCommand(command);
log("New command appended correctly to stack. Current server load: " + to_string(load)); log("New command appended correctly to stack. Current server load: " + to_string(getCurrentLoad()));
} }
} }

View File

@@ -164,11 +164,11 @@ string UnitsManager::getUnitData(stringstream &ss, unsigned long long time)
return to_base64(ss.str()); return to_base64(ss.str());
} }
void UnitsManager::deleteUnit(unsigned int ID, bool explosion) void UnitsManager::deleteUnit(unsigned int ID, bool explosion, bool immediate)
{ {
if (getUnit(ID) != nullptr) if (getUnit(ID) != nullptr)
{ {
Command* command = dynamic_cast<Command*>(new Delete(ID, explosion)); Command* command = dynamic_cast<Command*>(new Delete(ID, explosion, immediate));
scheduler->appendCommand(command); scheduler->appendCommand(command);
} }
} }

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#define VERSION "v0.2.1" #define VERSION "v0.4.0-alpha"
#define LOG_NAME "Olympus_log.txt" #define LOG_NAME "Olympus_log.txt"
#define REST_ADDRESS "http://localhost:30000" #define REST_ADDRESS "http://localhost:30000"
#define REST_URI "olympus" #define REST_URI "olympus"
@@ -10,4 +10,5 @@
#define BULLSEYE_URI "bullseyes" #define BULLSEYE_URI "bullseyes"
#define MISSION_URI "mission" #define MISSION_URI "mission"
#define UPDATE_TIME_INTERVAL 0.25 #define UPDATE_TIME_INTERVAL 0.25
#define EXECUTION_TIME_INTERVAL 0.05