Added advanced unit controls

Radio, ECM, countermeasures and prohibits
This commit is contained in:
Pax1601
2023-05-17 16:17:17 +02:00
parent 71ef292763
commit 03a8c93e9e
16 changed files with 721 additions and 383 deletions

View File

@@ -2,6 +2,7 @@
#include "framework.h"
#include "luatools.h"
#include "utils.h"
#include "logger.h"
namespace CommandPriority {
enum CommandPriorities { LOW, MEDIUM, HIGH };
@@ -24,6 +25,7 @@ namespace SetCommandType {
PROHIBIT_AG = 17,
MISSILE_ATTACK = 18,
PROHIBIT_WP_PASS_REPORT = 19,
ENGAGE_AIR_WEAPONS = 20,
OPTION_RADIO_USAGE_CONTACT = 21,
OPTION_RADIO_USAGE_ENGAGE = 22,
OPTION_RADIO_USAGE_KILL = 23,
@@ -43,7 +45,7 @@ namespace ROE {
}
namespace ReactionToThreat {
enum ReactionToThreats {
enum ReactionsToThreat {
NO_REACTION = 0,
PASSIVE_DEFENCE = 1,
EVADE_FIRE = 2,
@@ -52,6 +54,35 @@ namespace ReactionToThreat {
};
}
namespace RadarUse {
enum RadarUses {
NEVER = 0,
FOR_ATTACK_ONLY = 1,
FOR_SEARCH_IF_REQUIRED = 2,
FOR_CONTINUOUS_SEARCH = 3
};
}
namespace FlareUse {
enum FlareUses {
NEVER = 0,
AGAINST_FIRED_MISSILE = 1,
WHEN_FLYING_IN_SAM_WEZ = 2,
WHEN_FLYING_NEAR_ENEMIES = 3
};
}
namespace ECMUse {
enum ECMUses {
NEVER_USE = 0,
USE_IF_ONLY_LOCK_BY_RADAR = 1,
USE_IF_DETECTED_LOCK_BY_RADAR = 2,
ALWAYS_USE = 3
};
}
/* Base command class */
class Command
{
@@ -243,7 +274,19 @@ public:
SetOption(int ID, int optionID, int optionValue) :
ID(ID),
optionID(optionID),
optionValue(optionValue)
optionValue(optionValue),
optionBool(false),
isBoolean(false)
{
priority = CommandPriority::HIGH;
};
SetOption(int ID, int optionID, bool optionBool) :
ID(ID),
optionID(optionID),
optionValue(0),
optionBool(optionBool),
isBoolean(true)
{
priority = CommandPriority::HIGH;
};
@@ -254,4 +297,6 @@ private:
const int ID;
const int optionID;
const int optionValue;
const bool optionBool;
const bool isBoolean;
};

View File

@@ -9,20 +9,44 @@ namespace State
{
enum States
{
NONE = 0,
IDLE,
REACH_DESTINATION,
ATTACK,
WINGMAN,
FOLLOW,
LAND,
REFUEL,
AWACS,
EWR,
TANKER,
RUN_AWAY
TANKER
};
};
namespace Options {
struct TACAN
{
bool isOn = false;
int channel = 40;
wstring XY = L"X";
wstring callsign = L"TKR";
};
struct Radio
{
int frequency = 124000000; // MHz
int callsign = 1;
int callsignNumber = 1;
};
struct GeneralSettings
{
bool prohibitJettison = false;
bool prohibitAA = false;
bool prohibitAG = false;
bool prohibitAfterburner = false;
bool prohibitAirWpn = false;
};
}
class Unit
{
public:
@@ -30,6 +54,7 @@ public:
~Unit();
/********** Public methods **********/
void initialize(json::value json);
int getID() { return ID; }
void updateExportData(json::value json);
void updateMissionData(json::value json);
@@ -98,15 +123,7 @@ public:
void setTargetID(int newTargetID) { targetID = newTargetID; addMeasure(L"targetID", json::value(newTargetID));}
void setIsTanker(bool newIsTanker);
void setIsAWACS(bool newIsAWACS);
void setTACANChannel(int newTACANChannel);
void setTACANXY(wstring newTACANXY);
void setTACANCallsign(wstring newTACANCallsign);
void setTACAN();
void setEPLRS(bool state);
void setRadioFrequency(int newRadioFrequency);
void setRadioCallsign(int newRadioCallsign);
void setRadioCallsignNumber(int newRadioCallsignNumber);
void setRadio();
wstring getCurrentTask() { return currentTask; }
virtual double getTargetSpeed() { return targetSpeed; };
virtual double getTargetAltitude() { return targetAltitude; };
@@ -115,18 +132,22 @@ public:
int getTargetID() { return targetID; }
bool getIsTanker() { return isTanker; }
bool getIsAWACS() { return isAWACS; }
int getTACANChannel() { return TACANChannel; }
wstring getTACANXY() { return TACANXY; }
wstring getTACANCallsign() { return TACANCallsign; }
int getRadioFrequency() { return radioFrequency; }
int getRadioCallsign() { return radioCallsign; }
int getRadioCallsignNumber() { return radioCallsignNumber; }
/********** Options data **********/
void setROE(wstring newROE);
void setReactionToThreat(wstring newReactionToThreat);
void setEmissionsCountermeasures(wstring newEmissionsCountermeasures);
void setTACAN(Options::TACAN newTACAN);
void setRadio(Options::Radio newradio);
void setGeneralSettings(Options::GeneralSettings newGeneralSettings);
void setEPLRS(bool newEPLRS);
wstring getROE() { return ROE; }
wstring getReactionToThreat() {return reactionToThreat;}
wstring getReactionToThreat() { return reactionToThreat; }
wstring getEmissionsCountermeasures() { return emissionsCountermeasures; };
Options::TACAN getTACAN() { return TACAN; }
Options::Radio getRadio() { return radio; }
Options::GeneralSettings getGeneralSettings() { return generalSettings; }
bool getEPLRS() { return EPLRS; }
/********** Control functions **********/
void landAt(Coords loc);
@@ -179,19 +200,18 @@ protected:
int targetID = NULL;
bool isTanker = false;
bool isAWACS = false;
int TACANChannel = 40;
wstring TACANXY = L"X";
wstring TACANCallsign = L"TKR";
int radioFrequency = 260000000; // MHz
int radioCallsign = 1;
int radioCallsignNumber = 1;
/********** Options data **********/
wstring ROE = L"";
wstring reactionToThreat = L"";
wstring ROE = L"Designated";
wstring reactionToThreat = L"Evade";
wstring emissionsCountermeasures = L"Defend";
Options::TACAN TACAN;
Options::Radio radio;
Options::GeneralSettings generalSettings;
bool EPLRS = false;
/********** State machine **********/
int state = State::IDLE;
int state = State::NONE;
/********** Other **********/
Coords oldPosition = Coords(0); // Used to approximate speed

View File

@@ -185,7 +185,7 @@ void AirUnit::AIloop()
}
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
scheduler->appendCommand(command);
hasTask = true;
setHasTask(true);
}
break;
}
@@ -290,7 +290,7 @@ void AirUnit::AIloop()
<< "}";
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
scheduler->appendCommand(command);
hasTask = true;
setHasTask(true);
}
}
break;
@@ -306,7 +306,7 @@ void AirUnit::AIloop()
<< "}";
Command* command = dynamic_cast<Command*>(new SetTask(ID, taskSS.str()));
scheduler->appendCommand(command);
hasTask = true;
setHasTask(true);
}
else {
setState(State::IDLE);

View File

@@ -62,7 +62,7 @@ wstring SpawnAircraft::getString(lua_State* L)
optionsSS.precision(10);
optionsSS << "{"
<< "payloadName = \"" << payloadName << "\", "
<< "airbaseName = \"" << airbaseName << "\","
<< "airbaseName = \"" << airbaseName << "\", "
<< "}";
std::wostringstream commandSS;
@@ -71,7 +71,7 @@ wstring SpawnAircraft::getString(lua_State* L)
<< "\"" << coalition << "\"" << ", "
<< "\"" << unitType << "\"" << ", "
<< location.lat << ", "
<< location.lng << ","
<< location.lng << ", "
<< optionsSS.str();
return commandSS.str();
}
@@ -113,7 +113,7 @@ wstring SetTask::getString(lua_State* L)
std::wostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.setTask, "
<< ID << ","
<< ID << ", "
<< task;
return commandSS.str();
@@ -136,7 +136,7 @@ wstring SetCommand::getString(lua_State* L)
std::wostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.setCommand, "
<< ID << ","
<< ID << ", "
<< command;
return commandSS.str();
@@ -147,10 +147,17 @@ wstring SetOption::getString(lua_State* L)
{
std::wostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.setOption, "
<< ID << ","
<< optionID << ","
<< optionValue;
if (!isBoolean) {
commandSS << "Olympus.setOption, "
<< ID << ", "
<< optionID << ", "
<< optionValue;
} else {
commandSS << "Olympus.setOption, "
<< ID << ", "
<< optionID << ", "
<< (optionBool? "true": "false");
}
return commandSS.str();
}

View File

@@ -222,6 +222,13 @@ void Scheduler::handleRequest(wstring key, json::value value)
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);
wstring emissionsCountermeasures = value[L"emissionsCountermeasures"].as_string();
unit->setEmissionsCountermeasures(emissionsCountermeasures);
}
else if (key.compare(L"landAt") == 0)
{
int ID = value[L"ID"].as_integer();
@@ -248,18 +255,33 @@ void Scheduler::handleRequest(wstring key, json::value value)
Unit* unit = unitsManager->getUnit(ID);
if (unit != nullptr)
{
/* Advanced tasking */
unit->setIsTanker(value[L"isTanker"].as_bool());
unit->setIsAWACS(value[L"isAWACS"].as_bool());
unit->setTACANChannel(value[L"TACANChannel"].as_number().to_int32());
unit->setTACANXY(value[L"TACANXY"].as_string());
unit->setTACANCallsign(value[L"TACANCallsign"].as_string());
unit->setTACAN();
/* TACAN Options */
auto TACAN = value[L"TACAN"];
unit->setTACAN({ TACAN[L"isOn"].as_bool(),
TACAN[L"channel"].as_number().to_int32(),
TACAN[L"XY"].as_string(),
TACAN[L"callsign"].as_string()
});
unit->setRadioFrequency(value[L"radioFrequency"].as_number().to_int32());
unit->setRadioCallsign(value[L"radioCallsign"].as_number().to_int32());
unit->setRadioCallsignNumber(value[L"radioCallsignNumber"].as_number().to_int32());
unit->setRadio();
/* Radio Options */
auto radio = value[L"radio"];
unit->setRadio({ radio[L"frequency"].as_number().to_int32(),
radio[L"callsign"].as_number().to_int32(),
radio[L"callsignNumber"].as_number().to_int32()
});
/* General Settings */
auto generalSettings = value[L"generalSettings"];
unit->setGeneralSettings({ generalSettings[L"prohibitJettison"].as_bool(),
generalSettings[L"prohibitAA"].as_bool(),
generalSettings[L"prohibitAG"].as_bool(),
generalSettings[L"prohibitAfterburner"].as_bool(),
generalSettings[L"prohibitAirWpn"].as_bool(),
});
unit->resetActiveDestination();
}

View File

@@ -15,22 +15,27 @@ using namespace GeographicLib;
extern Scheduler* scheduler;
extern UnitsManager* unitsManager;
// TODO: Make dedicated file
bool operator==(const Options::TACAN& lhs, const Options::TACAN& rhs)
{
return lhs.isOn == rhs.isOn && lhs.channel == rhs.channel && lhs.XY == rhs.XY && lhs.callsign == rhs.callsign;
}
bool operator==(const Options::Radio& lhs, const Options::Radio& rhs)
{
return lhs.frequency == rhs.frequency && lhs.callsign == rhs.callsign && lhs.callsignNumber == rhs.callsignNumber;
}
bool operator==(const Options::GeneralSettings& lhs, const Options::GeneralSettings& rhs)
{
return lhs.prohibitAA == rhs.prohibitAA && lhs.prohibitAfterburner == rhs.prohibitAfterburner && lhs.prohibitAG == rhs.prohibitAG &&
lhs.prohibitAirWpn == rhs.prohibitAirWpn && lhs.prohibitJettison == rhs.prohibitJettison;
}
Unit::Unit(json::value json, int ID) :
ID(ID)
{
log("Creating unit with ID: " + to_string(ID));
addMeasure(L"currentState", json::value(L"Idle"));
addMeasure(L"TACANChannel", json::value(TACANChannel));
addMeasure(L"TACANXY", json::value(TACANXY));
addMeasure(L"TACANCallsign", json::value(TACANCallsign));
addMeasure(L"radioFrequency", json::value(radioFrequency));
addMeasure(L"radioCallsign", json::value(radioCallsign));
addMeasure(L"radioCallsignNumber", json::value(radioCallsignNumber));
addMeasure(L"ROE", json::value(L"Designated"));
addMeasure(L"reactionToThreat", json::value(L"Evade"));
}
Unit::~Unit()
@@ -38,6 +43,25 @@ Unit::~Unit()
}
void Unit::initialize(json::value json)
{
updateExportData(json);
if (getAI()) {
/* Set the default IDLE state */
setState(State::IDLE);
/* Set the default options (these are all defaults so will only affect the export data, no DCS command will be sent) */
setROE(L"Designated");
setReactionToThreat(L"Evade");
setEmissionsCountermeasures(L"Defend");
setTACAN(TACAN);
setRadio(radio);
setEPLRS(EPLRS);
setGeneralSettings(generalSettings);
}
}
void Unit::addMeasure(wstring key, json::value value)
{
milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
@@ -155,7 +179,7 @@ json::value Unit::getData(long long time)
/********** Task data **********/
json[L"taskData"] = json::value::object();
for (auto key : { L"currentState", L"currentTask", L"targetSpeed", L"targetAltitude", L"activePath", L"isTanker", L"isAWACS", L"TACANChannel", L"TACANXY", L"TACANCallsign", L"radioFrequency", L"radioCallsign", L"radioCallsignNumber" })
for (auto key : { L"currentState", L"currentTask", L"targetSpeed", L"targetAltitude", L"activePath", L"isTanker", L"isAWACS" })
{
if (measures.find(key) != measures.end() && measures[key]->getTime() > time)
json[L"taskData"][key] = measures[key]->getValue();
@@ -165,7 +189,7 @@ json::value Unit::getData(long long time)
/********** Options data **********/
json[L"optionsData"] = json::value::object();
for (auto key : { L"ROE", L"reactionToThreat" })
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();
@@ -309,43 +333,102 @@ void Unit::setFormationOffset(Offset newFormationOffset)
}
void Unit::setROE(wstring newROE) {
ROE = newROE;
int ROEEnum;
if (newROE.compare(L"Free") == 0)
ROEEnum = ROE::WEAPON_FREE;
else if (newROE.compare(L"Designated free") == 0)
ROEEnum = ROE::OPEN_FIRE_WEAPON_FREE;
else if (newROE.compare(L"Designated") == 0)
ROEEnum = ROE::OPEN_FIRE;
else if (newROE.compare(L"Return") == 0)
ROEEnum = ROE::RETURN_FIRE;
else if (newROE.compare(L"Hold") == 0)
ROEEnum = ROE::WEAPON_HOLD;
else
return;
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ROE, ROEEnum));
scheduler->appendCommand(command);
addMeasure(L"ROE", json::value(newROE));
if (ROE != newROE) {
ROE = newROE;
int ROEEnum;
if (ROE.compare(L"Free") == 0)
ROEEnum = ROE::WEAPON_FREE;
else if (ROE.compare(L"Designated free") == 0)
ROEEnum = ROE::OPEN_FIRE_WEAPON_FREE;
else if (ROE.compare(L"Designated") == 0)
ROEEnum = ROE::OPEN_FIRE;
else if (ROE.compare(L"Return") == 0)
ROEEnum = ROE::RETURN_FIRE;
else if (ROE.compare(L"Hold") == 0)
ROEEnum = ROE::WEAPON_HOLD;
else
return;
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ROE, ROEEnum));
scheduler->appendCommand(command);
}
}
void Unit::setReactionToThreat(wstring newReactionToThreat) {
reactionToThreat = newReactionToThreat;
int reactionToThreatEnum;
if (newReactionToThreat.compare(L"None") == 0)
reactionToThreatEnum = ReactionToThreat::NO_REACTION;
else if (newReactionToThreat.compare(L"Passive") == 0)
reactionToThreatEnum = ReactionToThreat::PASSIVE_DEFENCE;
else if (newReactionToThreat.compare(L"Evade") == 0)
reactionToThreatEnum = ReactionToThreat::EVADE_FIRE;
else if (newReactionToThreat.compare(L"Escape") == 0)
reactionToThreatEnum = ReactionToThreat::BYPASS_AND_ESCAPE;
else if (newReactionToThreat.compare(L"Abort") == 0)
reactionToThreatEnum = ReactionToThreat::ALLOW_ABORT_MISSION;
else
return;
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::REACTION_ON_THREAT, reactionToThreatEnum));
scheduler->appendCommand(command);
addMeasure(L"reactionToThreat", json::value(newReactionToThreat));
if (reactionToThreat != newReactionToThreat) {
reactionToThreat = newReactionToThreat;
int reactionToThreatEnum;
if (reactionToThreat.compare(L"None") == 0)
reactionToThreatEnum = ReactionToThreat::NO_REACTION;
else if (reactionToThreat.compare(L"Passive") == 0)
reactionToThreatEnum = ReactionToThreat::PASSIVE_DEFENCE;
else if (reactionToThreat.compare(L"Evade") == 0)
reactionToThreatEnum = ReactionToThreat::EVADE_FIRE;
else if (reactionToThreat.compare(L"Escape") == 0)
reactionToThreatEnum = ReactionToThreat::BYPASS_AND_ESCAPE;
else if (reactionToThreat.compare(L"Abort") == 0)
reactionToThreatEnum = ReactionToThreat::ALLOW_ABORT_MISSION;
else
return;
Command* command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::REACTION_ON_THREAT, reactionToThreatEnum));
scheduler->appendCommand(command);
}
}
void Unit::setEmissionsCountermeasures(wstring newEmissionsCountermeasures) {
addMeasure(L"emissionsCountermeasures", json::value(newEmissionsCountermeasures));
if (emissionsCountermeasures != newEmissionsCountermeasures) {
emissionsCountermeasures = newEmissionsCountermeasures;
int radarEnum;
int flareEnum;
int ECMEnum;
if (emissionsCountermeasures.compare(L"Silent") == 0)
{
radarEnum = RadarUse::NEVER;
flareEnum = FlareUse::NEVER;
ECMEnum = ECMUse::NEVER_USE;
}
else if (emissionsCountermeasures.compare(L"Attack") == 0)
{
radarEnum = RadarUse::FOR_ATTACK_ONLY;
flareEnum = FlareUse::AGAINST_FIRED_MISSILE;
ECMEnum = ECMUse::USE_IF_ONLY_LOCK_BY_RADAR;
}
else if (emissionsCountermeasures.compare(L"Defend") == 0)
{
radarEnum = RadarUse::FOR_SEARCH_IF_REQUIRED;
flareEnum = FlareUse::WHEN_FLYING_IN_SAM_WEZ;
ECMEnum = ECMUse::USE_IF_DETECTED_LOCK_BY_RADAR;
}
else if (emissionsCountermeasures.compare(L"Free") == 0)
{
radarEnum = RadarUse::FOR_CONTINUOUS_SEARCH;
flareEnum = FlareUse::WHEN_FLYING_NEAR_ENEMIES;
ECMEnum = ECMUse::ALWAYS_USE;
}
else
return;
Command* command;
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::RADAR_USING, radarEnum));
scheduler->appendCommand(command);
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::FLARE_USING, flareEnum));
scheduler->appendCommand(command);
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ECM_USING, ECMEnum));
scheduler->appendCommand(command);
}
}
void Unit::landAt(Coords loc) {
@@ -364,93 +447,131 @@ void Unit::setIsAWACS(bool newIsAWACS) {
isAWACS = newIsAWACS;
resetTask();
addMeasure(L"isAWACS", json::value(newIsAWACS));
setEPLRS(true);
setEPLRS(isAWACS);
}
void Unit::setTACANChannel(int newTACANChannel) {
TACANChannel = newTACANChannel;
addMeasure(L"TACANChannel", json::value(newTACANChannel));
}
void Unit::setTACAN(Options::TACAN newTACAN) {
auto json = json::value();
json[L"isOn"] = json::value(newTACAN.isOn);
json[L"channel"] = json::value(newTACAN.channel);
json[L"XY"] = json::value(newTACAN.XY);
json[L"callsign"] = json::value(newTACAN.callsign);
addMeasure(L"TACAN", json);
void Unit::setTACANXY(wstring newTACANXY) {
TACANXY = newTACANXY;
addMeasure(L"TACANXY", json::value(newTACANXY));
}
void Unit::setTACANCallsign(wstring newTACANCallsign) {
TACANCallsign = newTACANCallsign;
addMeasure(L"TACANCallsign", json::value(newTACANCallsign));
}
void Unit::setRadioFrequency(int newRadioFrequency) {
radioFrequency = newRadioFrequency;
addMeasure(L"radioFrequency", json::value(newRadioFrequency));
}
void Unit::setRadioCallsign(int newRadioCallsign) {
radioCallsign = newRadioCallsign;
addMeasure(L"radioCallsign", json::value(newRadioCallsign));
}
void Unit::setRadioCallsignNumber(int newRadioCallsignNumber) {
radioCallsignNumber = newRadioCallsignNumber;
addMeasure(L"radioCallsignNumber", json::value(newRadioCallsignNumber));
}
void Unit::setEPLRS(bool state)
{
std::wostringstream commandSS;
commandSS << "{"
<< "id = 'EPLRS',"
<< "params = {"
<< "value = " << (state? "true": "false") << ", "
<< "}"
<< "}";
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
scheduler->appendCommand(command);
}
void Unit::setTACAN()
{
std::wostringstream commandSS;
commandSS << "{"
<< "id = 'ActivateBeacon',"
<< "params = {"
<< "type = " << ((TACANXY.compare(L"X") == 0)? 4: 5) << ","
<< "system = 3,"
<< "name = \"Olympus_TACAN\","
<< "callsign = \"" << TACANCallsign << "\", "
<< "frequency = " << TACANChannelToFrequency(TACANChannel, TACANXY) << ","
<< "}"
<< "}";
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
scheduler->appendCommand(command);
}
void Unit::setRadio()
{
if (TACAN != newTACAN)
{
std::wostringstream commandSS;
commandSS << "{"
<< "id = 'SetFrequency',"
<< "params = {"
<< "modulation = 0," // TODO Allow selection
<< "frequency = " << radioFrequency << ","
<< "}"
<< "}";
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
scheduler->appendCommand(command);
TACAN = newTACAN;
if (TACAN.isOn) {
std::wostringstream commandSS;
commandSS << "{"
<< "id = 'ActivateBeacon',"
<< "params = {"
<< "type = " << ((TACAN.XY.compare(L"X") == 0) ? 4 : 5) << ","
<< "system = 3,"
<< "name = \"Olympus_TACAN\","
<< "callsign = \"" << TACAN.callsign << "\", "
<< "frequency = " << TACANChannelToFrequency(TACAN.channel, TACAN.XY) << ","
<< "}"
<< "}";
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
scheduler->appendCommand(command);
}
else {
std::wostringstream commandSS;
commandSS << "{"
<< "id = 'DeactivateBeacon',"
<< "params = {"
<< "}"
<< "}";
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
scheduler->appendCommand(command);
}
}
}
void Unit::setRadio(Options::Radio newRadio) {
auto json = json::value();
json[L"frequency"] = json::value(newRadio.frequency);
json[L"callsign"] = json::value(newRadio.callsign);
json[L"callsignNumber"] = json::value(newRadio.callsignNumber);
addMeasure(L"radio", json);
if (radio != newRadio)
{
radio = newRadio;
std::wostringstream commandSS;
Command* command;
commandSS << "{"
<< "id = 'SetCallsign',"
<< "params = {"
<< "callname = " << radioCallsign << ","
<< "number = " << radioCallsignNumber << ","
<< "}"
<< "}";
Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
<< "id = 'SetFrequency',"
<< "params = {"
<< "modulation = 0," // TODO Allow selection
<< "frequency = " << radio.frequency << ","
<< "}"
<< "}";
command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
scheduler->appendCommand(command);
// Clear the stringstream
commandSS.str(wstring());
commandSS << "{"
<< "id = 'SetCallsign',"
<< "params = {"
<< "callname = " << radio.callsign << ","
<< "number = " << radio.callsignNumber << ","
<< "}"
<< "}";
command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
scheduler->appendCommand(command);
}
}
void Unit::setEPLRS(bool newEPLRS)
{
//addMeasure(L"EPLRS", json::value(newEPLRS));
//
//if (EPLRS != newEPLRS) {
// EPLRS = newEPLRS;
//
// std::wostringstream commandSS;
// commandSS << "{"
// << "id = 'EPLRS',"
// << "params = {"
// << "value = " << (EPLRS ? "true" : "false") << ", "
// << "}"
// << "}";
// Command* command = dynamic_cast<Command*>(new SetCommand(ID, commandSS.str()));
// scheduler->appendCommand(command);
//}
}
void Unit::setGeneralSettings(Options::GeneralSettings newGeneralSettings) {
auto json = json::value();
json[L"prohibitJettison"] = json::value(newGeneralSettings.prohibitJettison);
json[L"prohibitAA"] = json::value(newGeneralSettings.prohibitAA);
json[L"prohibitAG"] = json::value(newGeneralSettings.prohibitAG);
json[L"prohibitAfterburner"] = json::value(newGeneralSettings.prohibitAfterburner);
json[L"prohibitAirWpn"] = json::value(newGeneralSettings.prohibitAirWpn);
addMeasure(L"generalSettings", json);
if (generalSettings != newGeneralSettings)
{
generalSettings = newGeneralSettings;
Command* command;
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AA, generalSettings.prohibitAA));
scheduler->appendCommand(command);
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AG, generalSettings.prohibitAG));
scheduler->appendCommand(command);
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_JETT, generalSettings.prohibitJettison));
scheduler->appendCommand(command);
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::PROHIBIT_AB, generalSettings.prohibitAfterburner));
scheduler->appendCommand(command);
command = dynamic_cast<Command*>(new SetOption(ID, SetCommandType::ENGAGE_AIR_WEAPONS, !generalSettings.prohibitAirWpn));
scheduler->appendCommand(command);
}
}

View File

@@ -64,11 +64,14 @@ void UnitsManager::updateExportData(lua_State* L)
units[ID] = dynamic_cast<Unit*>(new Bomb(p.second, ID));
}
}
/* Initialize the unit if creation was successfull */
if (units.count(ID) != 0)
units[ID]->initialize(p.second);
}
/* Update the unit if present*/
if (units.count(ID) != 0)
{
units[ID]->updateExportData(p.second);
else {
/* Update the unit if present*/
if (units.count(ID) != 0)
units[ID]->updateExportData(p.second);
}
}