mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Completed advanced controls also for units
This commit is contained in:
@@ -97,14 +97,15 @@ protected:
|
||||
class Move : public Command
|
||||
{
|
||||
public:
|
||||
Move(int ID, Coords destination, double speed, wstring speedType, double altitude, wstring altitudeType, wstring taskOptions):
|
||||
ID(ID),
|
||||
Move(wstring groupName, Coords destination, double speed, wstring speedType, double altitude, wstring altitudeType, wstring taskOptions, wstring category):
|
||||
groupName(groupName),
|
||||
destination(destination),
|
||||
speed(speed),
|
||||
speedType(speedType),
|
||||
altitude(altitude),
|
||||
altitudeType(altitudeType),
|
||||
taskOptions(taskOptions)
|
||||
taskOptions(taskOptions),
|
||||
category(category)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
@@ -112,13 +113,14 @@ public:
|
||||
virtual int getLoad() { return 5; }
|
||||
|
||||
private:
|
||||
const int ID;
|
||||
const wstring groupName;
|
||||
const Coords destination;
|
||||
const double speed;
|
||||
const wstring speedType;
|
||||
const double altitude;
|
||||
const wstring altitudeType;
|
||||
const wstring taskOptions;
|
||||
const wstring category;
|
||||
};
|
||||
|
||||
/* Smoke command */
|
||||
@@ -223,8 +225,8 @@ private:
|
||||
class SetTask : public Command
|
||||
{
|
||||
public:
|
||||
SetTask(int ID, wstring task) :
|
||||
ID(ID),
|
||||
SetTask(wstring groupName, wstring task) :
|
||||
groupName(groupName),
|
||||
task(task)
|
||||
{
|
||||
priority = CommandPriority::MEDIUM;
|
||||
@@ -233,7 +235,7 @@ public:
|
||||
virtual int getLoad() { return 10; }
|
||||
|
||||
private:
|
||||
const int ID;
|
||||
const wstring groupName;
|
||||
const wstring task;
|
||||
};
|
||||
|
||||
@@ -241,8 +243,8 @@ private:
|
||||
class ResetTask : public Command
|
||||
{
|
||||
public:
|
||||
ResetTask(int ID) :
|
||||
ID(ID)
|
||||
ResetTask(wstring groupName) :
|
||||
groupName(groupName)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
@@ -250,15 +252,15 @@ public:
|
||||
virtual int getLoad() { return 10; }
|
||||
|
||||
private:
|
||||
const int ID;
|
||||
const wstring groupName;
|
||||
};
|
||||
|
||||
/* Set command */
|
||||
class SetCommand : public Command
|
||||
{
|
||||
public:
|
||||
SetCommand(int ID, wstring command) :
|
||||
ID(ID),
|
||||
SetCommand(wstring groupName, wstring command) :
|
||||
groupName(groupName),
|
||||
command(command)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
@@ -267,7 +269,7 @@ public:
|
||||
virtual int getLoad() { return 10; }
|
||||
|
||||
private:
|
||||
const int ID;
|
||||
const wstring groupName;
|
||||
const wstring command;
|
||||
};
|
||||
|
||||
@@ -275,8 +277,8 @@ private:
|
||||
class SetOption : public Command
|
||||
{
|
||||
public:
|
||||
SetOption(int ID, int optionID, int optionValue) :
|
||||
ID(ID),
|
||||
SetOption(wstring groupName, int optionID, int optionValue) :
|
||||
groupName(groupName),
|
||||
optionID(optionID),
|
||||
optionValue(optionValue),
|
||||
optionBool(false),
|
||||
@@ -285,8 +287,8 @@ public:
|
||||
priority = CommandPriority::HIGH;
|
||||
};
|
||||
|
||||
SetOption(int ID, int optionID, bool optionBool) :
|
||||
ID(ID),
|
||||
SetOption(wstring groupName, int optionID, bool optionBool) :
|
||||
groupName(groupName),
|
||||
optionID(optionID),
|
||||
optionValue(0),
|
||||
optionBool(optionBool),
|
||||
@@ -298,7 +300,7 @@ public:
|
||||
virtual int getLoad() { return 10; }
|
||||
|
||||
private:
|
||||
const int ID;
|
||||
const wstring groupName;
|
||||
const int optionID;
|
||||
const int optionValue;
|
||||
const bool optionBool;
|
||||
@@ -309,8 +311,8 @@ private:
|
||||
class SetOnOff : public Command
|
||||
{
|
||||
public:
|
||||
SetOnOff(int ID, bool onOff) :
|
||||
ID(ID),
|
||||
SetOnOff(wstring groupName, bool onOff) :
|
||||
groupName(groupName),
|
||||
onOff(onOff)
|
||||
{
|
||||
priority = CommandPriority::HIGH;
|
||||
@@ -319,7 +321,7 @@ public:
|
||||
virtual int getLoad() { return 10; }
|
||||
|
||||
private:
|
||||
const int ID;
|
||||
const wstring groupName;
|
||||
const bool onOff;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "measure.h"
|
||||
#include "logger.h"
|
||||
|
||||
#define TASK_CHECK_INIT_VALUE 10
|
||||
|
||||
namespace State
|
||||
{
|
||||
enum States
|
||||
@@ -63,7 +65,7 @@ public:
|
||||
int getID() { return ID; }
|
||||
void updateExportData(json::value json);
|
||||
void updateMissionData(json::value json);
|
||||
json::value getData(long long time);
|
||||
json::value getData(long long time, bool getAll = false);
|
||||
virtual wstring getCategory() { return L"No category"; };
|
||||
|
||||
/********** Base data **********/
|
||||
@@ -100,7 +102,7 @@ public:
|
||||
void setFuel(double newFuel) { fuel = newFuel; addMeasure(L"fuel", json::value(newFuel));}
|
||||
void setAmmo(json::value newAmmo) { ammo = newAmmo; addMeasure(L"ammo", json::value(newAmmo));}
|
||||
void setTargets(json::value newTargets) {targets = newTargets; addMeasure(L"targets", json::value(newTargets));}
|
||||
void setHasTask(bool newHasTask) { hasTask = newHasTask; addMeasure(L"hasTask", json::value(newHasTask)); }
|
||||
void setHasTask(bool newHasTask);
|
||||
void setCoalitionID(int newCoalitionID);
|
||||
void setFlags(json::value newFlags) { flags = newFlags; addMeasure(L"flags", json::value(newFlags));}
|
||||
|
||||
@@ -181,6 +183,7 @@ protected:
|
||||
int ID;
|
||||
|
||||
map<wstring, Measure*> measures;
|
||||
int taskCheckCounter = 0;
|
||||
|
||||
/********** Base data **********/
|
||||
bool AI = false;
|
||||
@@ -252,4 +255,6 @@ protected:
|
||||
bool setActiveDestination();
|
||||
bool updateActivePath(bool looping);
|
||||
void goToDestination(wstring enrouteTask = L"nil");
|
||||
bool checkTaskFailed();
|
||||
void resetTaskFailedCounter();
|
||||
};
|
||||
|
||||
@@ -11,6 +11,11 @@ public:
|
||||
~UnitsManager();
|
||||
|
||||
Unit* getUnit(int ID);
|
||||
bool isUnitInGroup(Unit* unit);
|
||||
bool isUnitGroupLeader(Unit* unit);
|
||||
Unit* getGroupLeader(int ID);
|
||||
Unit* getGroupLeader(Unit* unit);
|
||||
vector<Unit*> getGroupMembers(wstring groupName);
|
||||
void updateExportData(lua_State* L);
|
||||
void updateMissionData(json::value missionData);
|
||||
void getData(json::value& answer, long long time);
|
||||
|
||||
@@ -143,7 +143,7 @@ void AirUnit::AIloop()
|
||||
else {
|
||||
taskSS << "{ id = 'Orbit', pattern = 'Circle' }";
|
||||
}
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
@@ -248,7 +248,7 @@ void AirUnit::AIloop()
|
||||
<< "z = " << formationOffset.z
|
||||
<< "},"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
@@ -264,7 +264,7 @@ void AirUnit::AIloop()
|
||||
taskSS << "{"
|
||||
<< "id = 'Refuel'"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
@@ -279,7 +279,7 @@ void AirUnit::AIloop()
|
||||
if (!getHasTask()) {
|
||||
std::wostringstream taskSS;
|
||||
taskSS << "{id = 'Bombing', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
@@ -290,10 +290,11 @@ void AirUnit::AIloop()
|
||||
if (!getHasTask()) {
|
||||
std::wostringstream taskSS;
|
||||
taskSS << "{id = 'CarpetBombing', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case State::BOMB_BUILDING: {
|
||||
currentTask = L"Bombing building";
|
||||
@@ -301,14 +302,16 @@ void AirUnit::AIloop()
|
||||
if (!getHasTask()) {
|
||||
std::wostringstream taskSS;
|
||||
taskSS << "{id = 'AttackMapObject', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
addMeasure(L"currentTask", json::value(currentTask));
|
||||
|
||||
}
|
||||
@@ -9,27 +9,20 @@ extern UnitsManager* unitsManager;
|
||||
/* Move command */
|
||||
wstring Move::getString(lua_State* L)
|
||||
{
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
if (unit != nullptr)
|
||||
{
|
||||
std::wostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.move, "
|
||||
<< ID << ", "
|
||||
<< destination.lat << ", "
|
||||
<< destination.lng << ", "
|
||||
<< altitude << ", "
|
||||
<< "\"" << altitudeType << "\"" << ", "
|
||||
<< speed << ", "
|
||||
<< "\"" << speedType << "\"" << ", "
|
||||
<< "\"" << unit->getCategory() << "\"" << ", "
|
||||
<< taskOptions;
|
||||
return commandSS.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::wostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.move, "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
<< destination.lat << ", "
|
||||
<< destination.lng << ", "
|
||||
<< altitude << ", "
|
||||
<< "\"" << altitudeType << "\"" << ", "
|
||||
<< speed << ", "
|
||||
<< "\"" << speedType << "\"" << ", "
|
||||
<< "\"" << category << "\"" << ", "
|
||||
<< taskOptions;
|
||||
return commandSS.str();
|
||||
}
|
||||
|
||||
/* Smoke command */
|
||||
@@ -117,7 +110,7 @@ wstring SetTask::getString(lua_State* L)
|
||||
std::wostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.setTask, "
|
||||
<< ID << ", "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
<< task;
|
||||
|
||||
return commandSS.str();
|
||||
@@ -129,7 +122,7 @@ wstring ResetTask::getString(lua_State* L)
|
||||
std::wostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.resetTask, "
|
||||
<< ID;
|
||||
<< "\"" << groupName << "\"";
|
||||
|
||||
return commandSS.str();
|
||||
}
|
||||
@@ -140,7 +133,7 @@ wstring SetCommand::getString(lua_State* L)
|
||||
std::wostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.setCommand, "
|
||||
<< ID << ", "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
<< command;
|
||||
|
||||
return commandSS.str();
|
||||
@@ -154,12 +147,12 @@ wstring SetOption::getString(lua_State* L)
|
||||
|
||||
if (!isBoolean) {
|
||||
commandSS << "Olympus.setOption, "
|
||||
<< ID << ", "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
<< optionID << ", "
|
||||
<< optionValue;
|
||||
} else {
|
||||
commandSS << "Olympus.setOption, "
|
||||
<< ID << ", "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
<< optionID << ", "
|
||||
<< (optionBool? "true": "false");
|
||||
}
|
||||
@@ -173,7 +166,7 @@ wstring SetOnOff::getString(lua_State* L)
|
||||
commandSS.precision(10);
|
||||
|
||||
commandSS << "Olympus.setOnOff, "
|
||||
<< ID << ", "
|
||||
<< "\"" << groupName << "\"" << ", "
|
||||
<< (onOff ? "true" : "false");
|
||||
|
||||
return commandSS.str();
|
||||
|
||||
@@ -73,7 +73,6 @@ void GroundUnit::setState(int newState)
|
||||
|
||||
void GroundUnit::AIloop()
|
||||
{
|
||||
|
||||
switch (state) {
|
||||
case State::IDLE: {
|
||||
currentTask = L"Idle";
|
||||
@@ -112,7 +111,7 @@ void GroundUnit::AIloop()
|
||||
if (!getHasTask()) {
|
||||
std::wostringstream taskSS;
|
||||
taskSS << "{id = 'FireAtPoint', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << ", radius = 1000}";
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetTask(groupName, taskSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
@@ -140,7 +139,7 @@ void GroundUnit::changeSpeed(wstring change)
|
||||
void GroundUnit::setOnOff(bool newOnOff)
|
||||
{
|
||||
Unit::setOnOff(newOnOff);
|
||||
Command* command = dynamic_cast<Command*>(new SetOnOff(ID, onOff));
|
||||
Command* command = dynamic_cast<Command*>(new SetOnOff(groupName, onOff));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
if (key.compare(L"setPath") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
|
||||
if (unit != nullptr)
|
||||
{
|
||||
wstring unitName = unit->getUnitName();
|
||||
@@ -75,15 +76,9 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
newPath.push_back(dest);
|
||||
}
|
||||
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
if (unit != nullptr)
|
||||
{
|
||||
unit->setActivePath(newPath);
|
||||
unit->setState(State::REACH_DESTINATION);
|
||||
log(unitName + L" new path set successfully");
|
||||
}
|
||||
else
|
||||
log(unitName + L" not found, request will be discarded");
|
||||
unit->setActivePath(newPath);
|
||||
unit->setState(State::REACH_DESTINATION);
|
||||
log(unitName + L" new path set successfully");
|
||||
}
|
||||
}
|
||||
else if (key.compare(L"smoke") == 0)
|
||||
@@ -123,7 +118,7 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
int ID = value[L"ID"].as_integer();
|
||||
int targetID = value[L"targetID"].as_integer();
|
||||
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
Unit* target = unitsManager->getUnit(targetID);
|
||||
|
||||
wstring unitName;
|
||||
@@ -151,7 +146,7 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
int offsetY = value[L"offsetY"].as_integer();
|
||||
int offsetZ = value[L"offsetZ"].as_integer();
|
||||
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
Unit* leader = unitsManager->getUnit(leaderID);
|
||||
|
||||
wstring unitName;
|
||||
@@ -175,42 +170,42 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
else if (key.compare(L"changeSpeed") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->changeSpeed(value[L"change"].as_string());
|
||||
}
|
||||
else if (key.compare(L"changeAltitude") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->changeAltitude(value[L"change"].as_string());
|
||||
}
|
||||
else if (key.compare(L"setSpeed") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->setTargetSpeed(value[L"speed"].as_double());
|
||||
}
|
||||
else if (key.compare(L"setSpeedType") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->setTargetSpeedType(value[L"speedType"].as_string());
|
||||
}
|
||||
else if (key.compare(L"setAltitude") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->setTargetAltitude(value[L"altitude"].as_double());
|
||||
}
|
||||
else if (key.compare(L"setAltitudeType") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
unit->setTargetAltitudeType(value[L"altitudeType"].as_string());
|
||||
}
|
||||
@@ -226,28 +221,28 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
else if (key.compare(L"setROE") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
wstring ROE = value[L"ROE"].as_string();
|
||||
unit->setROE(ROE);
|
||||
}
|
||||
else if (key.compare(L"setReactionToThreat") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
wstring reactionToThreat = value[L"reactionToThreat"].as_string();
|
||||
unit->setReactionToThreat(reactionToThreat);
|
||||
}
|
||||
else if (key.compare(L"setEmissionsCountermeasures") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
wstring emissionsCountermeasures = value[L"emissionsCountermeasures"].as_string();
|
||||
unit->setEmissionsCountermeasures(emissionsCountermeasures);
|
||||
}
|
||||
else if (key.compare(L"landAt") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
double lat = value[L"location"][L"lat"].as_double();
|
||||
double lng = value[L"location"][L"lng"].as_double();
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
@@ -262,13 +257,13 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
else if (key.compare(L"refuel") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setState(State::REFUEL);
|
||||
}
|
||||
else if (key.compare(L"setAdvancedOptions") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
if (unit != nullptr)
|
||||
{
|
||||
/* Advanced tasking */
|
||||
@@ -306,14 +301,14 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
bool followRoads = value[L"followRoads"].as_bool();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setFollowRoads(followRoads);
|
||||
}
|
||||
else if (key.compare(L"setOnOff") == 0)
|
||||
{
|
||||
int ID = value[L"ID"].as_integer();
|
||||
bool onOff = value[L"onOff"].as_bool();
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setOnOff(onOff);
|
||||
}
|
||||
else if (key.compare(L"explosion") == 0)
|
||||
@@ -331,8 +326,9 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
double lat = value[L"location"][L"lat"].as_double();
|
||||
double lng = value[L"location"][L"lng"].as_double();
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setState(State::BOMB_POINT);
|
||||
unit->setTargetLocation(loc);
|
||||
}
|
||||
else if (key.compare(L"carpetBomb") == 0)
|
||||
{
|
||||
@@ -340,8 +336,9 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
double lat = value[L"location"][L"lat"].as_double();
|
||||
double lng = value[L"location"][L"lng"].as_double();
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setState(State::CARPET_BOMB);
|
||||
unit->setTargetLocation(loc);
|
||||
}
|
||||
else if (key.compare(L"bombBuilding") == 0)
|
||||
{
|
||||
@@ -349,8 +346,9 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
double lat = value[L"location"][L"lat"].as_double();
|
||||
double lng = value[L"location"][L"lng"].as_double();
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setState(State::BOMB_BUILDING);
|
||||
unit->setTargetLocation(loc);
|
||||
}
|
||||
else if (key.compare(L"fireAtArea") == 0)
|
||||
{
|
||||
@@ -358,8 +356,9 @@ void Scheduler::handleRequest(wstring key, json::value value)
|
||||
double lat = value[L"location"][L"lat"].as_double();
|
||||
double lng = value[L"location"][L"lng"].as_double();
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
Unit* unit = unitsManager->getGroupLeader(ID);
|
||||
unit->setState(State::FIRE_AT_AREA);
|
||||
unit->setTargetLocation(loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -116,8 +116,21 @@ void Unit::updateExportData(json::value json)
|
||||
setAI(getUnitName().find(L"Olympus") != wstring::npos);
|
||||
|
||||
/* If the unit is alive and it is not a human, run the AI Loop that performs the requested commands and instructions (moving, attacking, etc) */
|
||||
if (getAI() && getAlive() && getFlags()[L"Human"].as_bool() == false)
|
||||
// TODO at the moment groups will stop moving correctly if the leader dies
|
||||
const bool isUnitControlledByOlympus = getAI();
|
||||
const bool isUnitAlive = getAlive();
|
||||
const bool isUnitLeader = unitsManager->isUnitGroupLeader(this);
|
||||
const bool isUnitLeaderOfAGroupWithOtherUnits = unitsManager->isUnitInGroup(this) && unitsManager->isUnitGroupLeader(this);
|
||||
const bool isUnitHuman = getFlags()[L"Human"].as_bool();
|
||||
|
||||
// Keep running the AI loop even if the unit is dead if it is the leader of a group which has other members in it
|
||||
if (isUnitControlledByOlympus && (isUnitAlive || isUnitLeaderOfAGroupWithOtherUnits) && isUnitLeader && !isUnitHuman)
|
||||
{
|
||||
if (checkTaskFailed() && state != State::IDLE && State::LAND)
|
||||
setState(State::IDLE);
|
||||
|
||||
AIloop();
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::updateMissionData(json::value json)
|
||||
@@ -132,10 +145,14 @@ void Unit::updateMissionData(json::value json)
|
||||
setHasTask(json[L"hasTask"].as_bool());
|
||||
}
|
||||
|
||||
json::value Unit::getData(long long time)
|
||||
json::value Unit::getData(long long time, bool sendAll)
|
||||
{
|
||||
auto json = json::value::object();
|
||||
|
||||
/* If the unit is in a group, task & option data is given by the group leader */
|
||||
if (unitsManager->isUnitInGroup(this) && !unitsManager->isUnitGroupLeader(this))
|
||||
json = unitsManager->getGroupLeader(this)->getData(time, true);
|
||||
|
||||
/********** Base data **********/
|
||||
json[L"baseData"] = json::value::object();
|
||||
for (auto key : { L"AI", L"name", L"unitName", L"groupName", L"alive", L"category"})
|
||||
@@ -146,7 +163,7 @@ json::value Unit::getData(long long time)
|
||||
if (json[L"baseData"].size() == 0)
|
||||
json.erase(L"baseData");
|
||||
|
||||
if (alive) {
|
||||
if (alive || sendAll) {
|
||||
/********** Flight data **********/
|
||||
json[L"flightData"] = json::value::object();
|
||||
for (auto key : { L"latitude", L"longitude", L"altitude", L"speed", L"heading" })
|
||||
@@ -177,25 +194,28 @@ json::value Unit::getData(long long time)
|
||||
if (json[L"formationData"].size() == 0)
|
||||
json.erase(L"formationData");
|
||||
|
||||
/********** Task data **********/
|
||||
json[L"taskData"] = json::value::object();
|
||||
for (auto key : { L"currentState", L"currentTask", L"targetSpeed", L"targetAltitude", L"targetSpeedType", L"targetAltitudeType", L"activePath", L"isTanker", L"isAWACS", L"onOff", L"followRoads", L"targetID", L"targetLocation"})
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"taskData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"taskData"].size() == 0)
|
||||
json.erase(L"taskData");
|
||||
/* If the unit is in a group, task & option data is given by the group leader */
|
||||
if (unitsManager->isUnitGroupLeader(this)) {
|
||||
/********** Task data **********/
|
||||
json[L"taskData"] = json::value::object();
|
||||
for (auto key : { L"currentState", L"currentTask", L"targetSpeed", L"targetAltitude", L"targetSpeedType", L"targetAltitudeType", L"activePath", L"isTanker", L"isAWACS", L"onOff", L"followRoads", L"targetID", L"targetLocation" })
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"taskData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"taskData"].size() == 0)
|
||||
json.erase(L"taskData");
|
||||
|
||||
/********** Options data **********/
|
||||
json[L"optionsData"] = json::value::object();
|
||||
for (auto key : { L"ROE", L"reactionToThreat", L"emissionsCountermeasures", L"TACAN", L"radio", L"generalSettings"})
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"optionsData"][key] = measures[key]->getValue();
|
||||
/********** Options data **********/
|
||||
json[L"optionsData"] = json::value::object();
|
||||
for (auto key : { L"ROE", L"reactionToThreat", L"emissionsCountermeasures", L"TACAN", L"radio", L"generalSettings" })
|
||||
{
|
||||
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
|
||||
json[L"optionsData"][key] = measures[key]->getValue();
|
||||
}
|
||||
if (json[L"optionsData"].size() == 0)
|
||||
json.erase(L"optionsData");
|
||||
}
|
||||
if (json[L"optionsData"].size() == 0)
|
||||
json.erase(L"optionsData");
|
||||
}
|
||||
|
||||
return json;
|
||||
@@ -322,9 +342,10 @@ void Unit::resetActiveDestination()
|
||||
|
||||
void Unit::resetTask()
|
||||
{
|
||||
Command* command = dynamic_cast<Command*>(new ResetTask(ID));
|
||||
Command* command = dynamic_cast<Command*>(new ResetTask(groupName));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(false);
|
||||
resetTaskFailedCounter();
|
||||
}
|
||||
|
||||
void Unit::setFormationOffset(Offset newFormationOffset)
|
||||
@@ -353,7 +374,7 @@ void Unit::setROE(wstring newROE) {
|
||||
else
|
||||
return;
|
||||
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ROE, ROEEnum));
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ROE, ROEEnum));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -378,7 +399,7 @@ void Unit::setReactionToThreat(wstring newReactionToThreat) {
|
||||
else
|
||||
return;
|
||||
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::REACTION_ON_THREAT, reactionToThreatEnum));
|
||||
Command* command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::REACTION_ON_THREAT, reactionToThreatEnum));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -421,13 +442,13 @@ void Unit::setEmissionsCountermeasures(wstring newEmissionsCountermeasures) {
|
||||
|
||||
Command* command;
|
||||
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::RADAR_USING, radarEnum));
|
||||
command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::RADAR_USING, radarEnum));
|
||||
scheduler->appendCommand(command);
|
||||
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::FLARE_USING, flareEnum));
|
||||
command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::FLARE_USING, flareEnum));
|
||||
scheduler->appendCommand(command);
|
||||
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ECM_USING, ECMEnum));
|
||||
command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ECM_USING, ECMEnum));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -474,7 +495,7 @@ void Unit::setTACAN(Options::TACAN newTACAN) {
|
||||
<< "frequency = " << TACANChannelToFrequency(TACAN.channel, TACAN.XY) << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(groupName, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
else {
|
||||
@@ -484,7 +505,7 @@ void Unit::setTACAN(Options::TACAN newTACAN) {
|
||||
<< "params = {"
|
||||
<< "}"
|
||||
<< "}";
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
Command* command = dynamic_cast<Command*>(new SetCommand(groupName, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -512,7 +533,7 @@ void Unit::setRadio(Options::Radio newRadio) {
|
||||
<< "frequency = " << radio.frequency << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
command = dynamic_cast<Command*>(new SetCommand(groupName, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
|
||||
// Clear the stringstream
|
||||
@@ -525,7 +546,7 @@ void Unit::setRadio(Options::Radio newRadio) {
|
||||
<< "number = " << radio.callsignNumber << ","
|
||||
<< "}"
|
||||
<< "}";
|
||||
command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
|
||||
command = dynamic_cast<Command*>(new SetCommand(groupName, commandSS.str()));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -564,15 +585,15 @@ void Unit::setGeneralSettings(Options::GeneralSettings newGeneralSettings) {
|
||||
generalSettings = newGeneralSettings;
|
||||
|
||||
Command* command;
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AA, generalSettings.prohibitAA));
|
||||
command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::PROHIBIT_AA, generalSettings.prohibitAA));
|
||||
scheduler->appendCommand(command);
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AG, generalSettings.prohibitAG));
|
||||
command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::PROHIBIT_AG, generalSettings.prohibitAG));
|
||||
scheduler->appendCommand(command);
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_JETT, generalSettings.prohibitJettison));
|
||||
command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::PROHIBIT_JETT, generalSettings.prohibitJettison));
|
||||
scheduler->appendCommand(command);
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AB, generalSettings.prohibitAfterburner));
|
||||
command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::PROHIBIT_AB, generalSettings.prohibitAfterburner));
|
||||
scheduler->appendCommand(command);
|
||||
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ENGAGE_AIR_WEAPONS, !generalSettings.prohibitAirWpn));
|
||||
command = dynamic_cast<Command*>(new SetOption(groupName, SetCommandType::ENGAGE_AIR_WEAPONS, !generalSettings.prohibitAirWpn));
|
||||
scheduler->appendCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -605,7 +626,7 @@ void Unit::goToDestination(wstring enrouteTask)
|
||||
{
|
||||
if (activeDestination != NULL)
|
||||
{
|
||||
Command* command = dynamic_cast<Command*>(new Move(ID, activeDestination, getTargetSpeed(), getTargetSpeedType(), getTargetAltitude(), getTargetAltitudeType(), enrouteTask));
|
||||
Command* command = dynamic_cast<Command*>(new Move(groupName, activeDestination, getTargetSpeed(), getTargetSpeedType(), getTargetAltitude(), getTargetAltitudeType(), enrouteTask, getCategory()));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
}
|
||||
@@ -615,16 +636,20 @@ bool Unit::isDestinationReached(double threshold)
|
||||
{
|
||||
if (activeDestination != NULL)
|
||||
{
|
||||
double dist = 0;
|
||||
Geodesic::WGS84().Inverse(latitude, longitude, activeDestination.lat, activeDestination.lng, dist);
|
||||
if (dist < threshold)
|
||||
/* Check if any unit in the group has reached the point */
|
||||
for (auto const& p: unitsManager->getGroupMembers(groupName))
|
||||
{
|
||||
log(unitName + L" destination reached");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
double dist = 0;
|
||||
Geodesic::WGS84().Inverse(p->getLatitude(), p->getLongitude(), activeDestination.lat, activeDestination.lng, dist);
|
||||
if (dist < threshold)
|
||||
{
|
||||
log(unitName + L" destination reached");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return true;
|
||||
@@ -668,4 +693,23 @@ void Unit::setTargetLocation(Coords newTargetLocation) {
|
||||
json[L"latitude"] = json::value(newTargetLocation.lat);
|
||||
json[L"longitude"] = json::value(newTargetLocation.lng);
|
||||
addMeasure(L"targetLocation", json::value(json));
|
||||
}
|
||||
|
||||
bool Unit::checkTaskFailed() {
|
||||
if (getHasTask())
|
||||
return false;
|
||||
else {
|
||||
if (taskCheckCounter > 0)
|
||||
taskCheckCounter--;
|
||||
return taskCheckCounter == 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::resetTaskFailedCounter() {
|
||||
taskCheckCounter = TASK_CHECK_INIT_VALUE;
|
||||
}
|
||||
|
||||
void Unit::setHasTask(bool newHasTask) {
|
||||
hasTask = newHasTask;
|
||||
addMeasure(L"hasTask", json::value(newHasTask));
|
||||
}
|
||||
@@ -32,6 +32,67 @@ Unit* UnitsManager::getUnit(int ID)
|
||||
}
|
||||
}
|
||||
|
||||
bool UnitsManager::isUnitInGroup(Unit* unit)
|
||||
{
|
||||
if (unit != nullptr) {
|
||||
wstring groupName = unit->getGroupName();
|
||||
for (auto const& p : units)
|
||||
{
|
||||
if (p.second->getGroupName().compare(groupName) == 0 && p.second != unit)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnitsManager::isUnitGroupLeader(Unit* unit)
|
||||
{
|
||||
if (unit != nullptr)
|
||||
return unit == getGroupLeader(unit);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// The group leader is the unit with the lowest ID that is part of the group. This is different from DCS's concept of leader, which will change if the leader is destroyed
|
||||
Unit* UnitsManager::getGroupLeader(Unit* unit)
|
||||
{
|
||||
if (unit != nullptr) {
|
||||
wstring groupName = unit->getGroupName();
|
||||
|
||||
/* Get the unit IDs in order */
|
||||
std::vector<int> keys;
|
||||
for (auto const& p : units)
|
||||
keys.push_back(p.first);
|
||||
sort(keys.begin(), keys.end());
|
||||
|
||||
/* Find the first unit that has the same groupName */
|
||||
for (auto const& tempID : keys)
|
||||
{
|
||||
Unit* tempUnit = getUnit(tempID);
|
||||
if (tempUnit != nullptr && tempUnit->getGroupName().compare(groupName) == 0)
|
||||
return tempUnit;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
vector<Unit*> UnitsManager::getGroupMembers(wstring groupName)
|
||||
{
|
||||
vector<Unit*> members;
|
||||
for (auto const& p : units)
|
||||
{
|
||||
if (p.second->getGroupName().compare(groupName) == 0)
|
||||
members.push_back(p.second);
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
Unit* UnitsManager::getGroupLeader(int ID)
|
||||
{
|
||||
Unit* unit = getUnit(ID);
|
||||
return getGroupLeader(unit);
|
||||
}
|
||||
|
||||
void UnitsManager::updateExportData(lua_State* L)
|
||||
{
|
||||
map<int, json::value> unitJSONs = getAllUnits(L);
|
||||
|
||||
Reference in New Issue
Block a user