diff --git a/backend/core/include/datatypes.h b/backend/core/include/datatypes.h index fec3cb5b..471b288a 100644 --- a/backend/core/include/datatypes.h +++ b/backend/core/include/datatypes.h @@ -155,6 +155,7 @@ struct SpawnOptions { string loadout; string skill; string liveryID; + double heading; }; struct CloneOptions { diff --git a/backend/core/src/airunit.cpp b/backend/core/src/airunit.cpp index 459162f2..703ba7ad 100644 --- a/backend/core/src/airunit.cpp +++ b/backend/core/src/airunit.cpp @@ -170,7 +170,8 @@ void AirUnit::AIloop() if (isActiveTanker) { taskSS << "{ [1] = { id = 'Tanker' }, [2] = { id = 'Orbit', pattern = 'Race-Track', altitude = " << desiredAltitude << ", speed = " << desiredSpeed << ", altitudeType = '" << - (desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "' }}"; + (desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "', heading = " << + heading << ", length = " << (50000 * 1.852) << " }}"; } else if (isActiveAWACS) { taskSS << "{ [1] = { id = 'AWACS' }, [2] = { id = 'Orbit', pattern = 'Circle', altitude = " << @@ -178,9 +179,10 @@ void AirUnit::AIloop() (desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "' }}"; } else { - taskSS << "{ id = 'Orbit', pattern = 'Circle', altitude = " << + taskSS << "{ id = 'Orbit', pattern = 'Race-Track', altitude = " << desiredAltitude << ", speed = " << desiredSpeed << ", altitudeType = '" << - (desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "'}"; + (desiredAltitudeType ? "AGL" : "ASL") << "', speedType = '" << (desiredSpeedType ? "GS" : "CAS") << "', heading = " << + heading << ", length = " << desiredSpeed * 30 << " }"; } Command* command = dynamic_cast(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); })); scheduler->appendCommand(command); diff --git a/backend/core/src/commands.cpp b/backend/core/src/commands.cpp index 604580cb..dde084be 100644 --- a/backend/core/src/commands.cpp +++ b/backend/core/src/commands.cpp @@ -46,6 +46,7 @@ string SpawnGroundUnits::getString() << "unitType = " << "\"" << spawnOptions[i].unitType << "\"" << ", " << "lat = " << spawnOptions[i].location.lat << ", " << "lng = " << spawnOptions[i].location.lng << ", " + << "heading = " << spawnOptions[i].heading << ", " << "liveryID = " << "\"" << spawnOptions[i].liveryID << "\"" << ", " << "skill = \"" << spawnOptions[i].skill << "\"" << "}, "; @@ -72,6 +73,7 @@ string SpawnNavyUnits::getString() << "unitType = " << "\"" << spawnOptions[i].unitType << "\"" << ", " << "lat = " << spawnOptions[i].location.lat << ", " << "lng = " << spawnOptions[i].location.lng << ", " + << "heading = " << spawnOptions[i].heading << ", " << "liveryID = " << "\"" << spawnOptions[i].liveryID << "\"" << ", " << "skill = \"" << spawnOptions[i].skill << "\"" << "}, "; } @@ -97,6 +99,7 @@ string SpawnAircrafts::getString() << "lat = " << spawnOptions[i].location.lat << ", " << "lng = " << spawnOptions[i].location.lng << ", " << "alt = " << spawnOptions[i].location.alt << ", " + << "heading = " << spawnOptions[i].heading << ", " << "loadout = \"" << spawnOptions[i].loadout << "\"" << ", " << "liveryID = " << "\"" << spawnOptions[i].liveryID << "\"" << ", " << "skill = \"" << spawnOptions[i].skill << "\"" << "}, "; @@ -125,6 +128,7 @@ string SpawnHelicopters::getString() << "lat = " << spawnOptions[i].location.lat << ", " << "lng = " << spawnOptions[i].location.lng << ", " << "alt = " << spawnOptions[i].location.alt << ", " + << "heading = " << spawnOptions[i].heading << ", " << "loadout = \"" << spawnOptions[i].loadout << "\"" << ", " << "liveryID = " << "\"" << spawnOptions[i].liveryID << "\"" << ", " << "skill = \"" << spawnOptions[i].skill << "\"" << "}, "; diff --git a/backend/core/src/scheduler.cpp b/backend/core/src/scheduler.cpp index 23947274..f2c75fd4 100644 --- a/backend/core/src/scheduler.cpp +++ b/backend/core/src/scheduler.cpp @@ -202,12 +202,16 @@ void Scheduler::handleRequest(string key, json::value value, string username, js 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(); + double heading = 0; + if (unit.has_number_field(L"heading")) + heading = unit[L"heading"].as_double(); + Coords location; location.lat = lat; location.lng = lng; location.alt = alt; string loadout = to_string(unit[L"loadout"]); string liveryID = to_string(unit[L"liveryID"]); string skill = to_string(unit[L"skill"]); - spawnOptions.push_back({unitType, location, loadout, skill, liveryID}); + spawnOptions.push_back({unitType, location, loadout, skill, liveryID, heading}); log(username + " spawned a " + coalition + " " + unitType , true); } @@ -231,11 +235,15 @@ void Scheduler::handleRequest(string key, json::value value, string username, js 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 heading = 0; + if (unit.has_number_field(L"heading")) + heading = unit[L"heading"].as_double(); + Coords location; location.lat = lat; location.lng = lng; string liveryID = to_string(unit[L"liveryID"]); string skill = to_string(unit[L"skill"]); - spawnOptions.push_back({ unitType, location, "", skill, liveryID}); + spawnOptions.push_back({ unitType, location, "", skill, liveryID, heading}); log(username + " spawned a " + coalition + " " + unitType, true); } diff --git a/frontend/react/src/constants/constants.ts b/frontend/react/src/constants/constants.ts index 94847291..2aaca9c0 100644 --- a/frontend/react/src/constants/constants.ts +++ b/frontend/react/src/constants/constants.ts @@ -446,6 +446,7 @@ export enum DataIndexes { country, name, unitName, + callsign, groupName, state, task, diff --git a/frontend/react/src/interfaces.ts b/frontend/react/src/interfaces.ts index 8648c956..a70794c9 100644 --- a/frontend/react/src/interfaces.ts +++ b/frontend/react/src/interfaces.ts @@ -210,6 +210,7 @@ export interface UnitData { country: number; name: string; unitName: string; + callsign: string; groupName: string; state: string; task: string; diff --git a/frontend/react/src/unit/unit.ts b/frontend/react/src/unit/unit.ts index b808937f..669b9e56 100644 --- a/frontend/react/src/unit/unit.ts +++ b/frontend/react/src/unit/unit.ts @@ -88,6 +88,7 @@ export abstract class Unit extends CustomMarker { #country: number = 0; #name: string = ""; #unitName: string = ""; + #callsign: string = ""; #groupName: string = ""; #state: string = states[0]; #task: string = ""; @@ -197,6 +198,9 @@ export abstract class Unit extends CustomMarker { getUnitName() { return this.#unitName; } + getCallsign() { + return this.#callsign; + } getGroupName() { return this.#groupName; } @@ -459,6 +463,9 @@ export abstract class Unit extends CustomMarker { case DataIndexes.unitName: this.#unitName = dataExtractor.extractString(); break; + case DataIndexes.callsign: + this.#callsign = dataExtractor.extractString(); + break; case DataIndexes.groupName: this.#groupName = dataExtractor.extractString(); updateMarker = true; @@ -646,6 +653,7 @@ export abstract class Unit extends CustomMarker { country: this.#country, name: this.#name, unitName: this.#unitName, + callsign: this.#callsign, groupName: this.#groupName, state: this.#state, task: this.#task, diff --git a/scripts/lua/backend/OlympusCommand.lua b/scripts/lua/backend/OlympusCommand.lua index 4479dcfd..a8940fb8 100644 --- a/scripts/lua/backend/OlympusCommand.lua +++ b/scripts/lua/backend/OlympusCommand.lua @@ -181,6 +181,16 @@ function Olympus.buildTask(groupName, options) } } + if options['pattern'] == 'Race-Track' then + local heading = options['heading'] or 0 + local length = options['length'] or 20000 + if group ~= nil then + local groupPos = mist.getLeadPos(group) + task['params']['point'] = {x = groupPos.x, y = groupPos.z} + task['params']['point2'] = {x = groupPos.x + math.cos(heading) * length, y = groupPos.z + math.sin(heading) * length} + end + end + -- Compute the altitude depending on the altitude type if options['altitude'] then if options ['altitudeType'] then