Added speed and altitude controls

Fixed Clone
Added "Land here" command
Added ROE and reaction to threat buttons
This commit is contained in:
Pax1601
2023-02-08 18:26:45 +01:00
parent 3cf133a10e
commit 30a9d4e730
27 changed files with 852 additions and 102 deletions

View File

@@ -11,6 +11,54 @@ namespace CommandType {
enum CommandTypes { NO_TYPE, MOVE, SMOKE, SPAWN_AIR, SPAWN_GROUND, CLONE, FOLLOW, RESET_TASK, SET_OPTION, SET_COMMAND, SET_TASK };
};
namespace SetCommandType {
enum SetCommandTypes {
ROE = 0,
REACTION_ON_THREAT = 1,
RADAR_USING = 3,
FLARE_USING = 4,
Formation = 5,
RTB_ON_BINGO = 6,
SILENCE = 7,
RTB_ON_OUT_OF_AMMO = 10,
ECM_USING = 13,
PROHIBIT_AA = 14,
PROHIBIT_JETT = 15,
PROHIBIT_AB = 16,
PROHIBIT_AG = 17,
MISSILE_ATTACK = 18,
PROHIBIT_WP_PASS_REPORT = 19,
OPTION_RADIO_USAGE_CONTACT = 21,
OPTION_RADIO_USAGE_ENGAGE = 22,
OPTION_RADIO_USAGE_KILL = 23,
JETT_TANKS_IF_EMPTY = 25,
FORCED_ATTACK = 26
};
}
namespace ROE {
enum ROEs {
WEAPON_FREE = 0,
OPEN_FIRE_WEAPON_FREE = 1,
OPEN_FIRE = 2,
RETURN_FIRE = 3,
WEAPON_HOLD = 4,
};
}
namespace ReactionToThreat {
enum ReactionToThreats {
NO_REACTION = 0,
PASSIVE_DEFENCE = 1,
EVADE_FIRE = 2,
BYPASS_AND_ESCAPE = 3,
ALLOW_ABORT_MISSION = 4
};
}
/* Base command class */
class Command
{
@@ -117,14 +165,32 @@ private:
class Clone : public Command
{
public:
Clone(int ID) :
ID(ID)
Clone(int ID, Coords location) :
ID(ID),
location(location)
{
priority = CommandPriority::LOW;
type = CommandType::CLONE;
};
virtual wstring getString(lua_State* L);
private:
const int ID;
const Coords location;
};
/* Delete unit command */
class Delete : public Command
{
public:
Delete(int ID) :
ID(ID)
{
priority = CommandPriority::HIGH;
type = CommandType::CLONE;
};
virtual wstring getString(lua_State* L);
private:
const int ID;
};

View File

@@ -5,7 +5,7 @@
#include "luatools.h"
namespace State {
enum States { IDLE, REACH_DESTINATION, ATTACK, WINGMAN, FOLLOW, RTB, REFUEL, AWACS, EWR, TANKER, RUN_AWAY };
enum States { IDLE, REACH_DESTINATION, ATTACK, WINGMAN, FOLLOW, LAND, REFUEL, AWACS, EWR, TANKER, RUN_AWAY };
};
class Unit
@@ -31,6 +31,9 @@ public:
void setWingmen(vector<Unit*> newWingmen) { wingmen = newWingmen; }
void setFormation(wstring newFormation) { formation = newFormation; }
void setFormationOffset(Offset formationOffset);
void setROE(wstring newROE);
void setReactionToThreat(wstring newReactionToThreat);
void landAt(Coords loc);
int getID() { return ID; }
wstring getName() { return name; }
@@ -65,33 +68,35 @@ public:
protected:
int ID;
int state = State::IDLE;
bool hasTask = false;
bool AI = false;
bool alive = true;
wstring name = L"undefined";
wstring unitName = L"undefined";
wstring groupName = L"undefined";
json::value type = json::value::null();
int country = NULL;
int coalitionID = NULL;
double latitude = NULL;
double longitude = NULL;
double altitude = NULL;
double heading = NULL;
double speed = NULL;
json::value flags = json::value::null();
int targetID = NULL;
wstring currentTask = L"";
bool isLeader = false;
bool isWingman = false;
Offset formationOffset = Offset(NULL);
wstring formation = L"";
Unit* leader = nullptr;
int state = State::IDLE;
bool hasTask = false;
bool AI = false;
bool alive = true;
wstring name = L"undefined";
wstring unitName = L"undefined";
wstring groupName = L"undefined";
json::value type = json::value::null();
int country = NULL;
int coalitionID = NULL;
double latitude = NULL;
double longitude = NULL;
double altitude = NULL;
double heading = NULL;
double speed = NULL;
json::value flags = json::value::null();
int targetID = NULL;
wstring currentTask = L"";
bool isLeader = false;
bool isWingman = false;
Offset formationOffset = Offset(NULL);
wstring formation = L"";
Unit* leader = nullptr;
wstring ROE = L"";
wstring reactionToThreat = L"";
vector<Unit*> wingmen;
double targetSpeed = 0;
double targetAltitude = 0;
double fuel = 0;
double targetSpeed = 0;
double targetAltitude = 0;
double fuel = 0;
json::value ammo;
json::value targets;

View File

@@ -12,8 +12,10 @@ public:
virtual void changeAltitude(wstring change);
virtual double getTargetSpeed() { return targetSpeed; };
virtual double getTargetAltitude() { return targetAltitude; };
virtual void setTargetSpeed(double newTargetSpeed);
virtual void setTargetAltitude(double newTargetAltitude);
protected:
double targetSpeed = 150;
double targetAltitude = 5000;
double targetSpeed = 300 / 1.94384;
double targetAltitude = 20000 * 0.3048;
};

View File

@@ -15,8 +15,8 @@ public:
virtual wstring getCategory() = 0;
virtual void changeSpeed(wstring change) {};
virtual void changeAltitude(wstring change) {};
virtual void setTargetSpeed(double newTargetSpeed);
virtual void setTargetAltitude(double newTargetAltitude);
virtual void setTargetSpeed(double newTargetSpeed) {};
virtual void setTargetAltitude(double newTargetAltitude) {};
protected:
virtual void AIloop();

View File

@@ -12,8 +12,10 @@ public:
virtual void changeAltitude(wstring change);
virtual double getTargetSpeed() { return targetSpeed; };
virtual double getTargetAltitude() { return targetAltitude; };
virtual void setTargetSpeed(double newTargetSpeed);
virtual void setTargetAltitude(double newTargetAltitude);
protected:
double targetSpeed = 50;
double targetAltitude = 1000;
double targetSpeed = 100 / 1.94384;
double targetAltitude = 5000 * 0.3048;
};

View File

@@ -14,6 +14,7 @@ public:
void updateExportData(lua_State* L);
void updateMissionData(json::value missionData);
void updateAnswer(json::value& answer);
void deleteUnit(int ID);
private:
map<int, Unit*> units;

View File

@@ -69,7 +69,19 @@ wstring Clone::getString(lua_State* L)
{
std::wostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.clone, "
commandSS << "Olympus.clone, "
<< ID << ", "
<< location.lat << ", "
<< location.lng;
return commandSS.str();
}
/* Delete unit command */
wstring Delete::getString(lua_State* L)
{
std::wostringstream commandSS;
commandSS.precision(10);
commandSS << "Olympus.delete, "
<< ID;
return commandSS.str();
}

View File

@@ -182,7 +182,10 @@ void Scheduler::handleRequest(wstring key, json::value value)
else if (key.compare(L"cloneUnit") == 0)
{
int ID = value[L"ID"].as_integer();
command = dynamic_cast<Command*>(new Clone(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;
command = dynamic_cast<Command*>(new Clone(ID, loc));
log(L"Cloning unit " + to_wstring(ID));
}
else if (key.compare(L"setLeader") == 0)
@@ -219,6 +222,34 @@ void Scheduler::handleRequest(wstring key, json::value value)
wstring formation = value[L"formation"].as_string();
unit->setFormation(formation);
}
else if (key.compare(L"setROE") == 0)
{
int ID = value[L"ID"].as_integer();
Unit* unit = unitsFactory->getUnit(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 = unitsFactory->getUnit(ID);
wstring reactionToThreat = value[L"reactionToThreat"].as_string();
unit->setReactionToThreat(reactionToThreat);
}
else if (key.compare(L"landAt") == 0)
{
int ID = value[L"ID"].as_integer();
Unit* unit = unitsFactory->getUnit(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;
unit->landAt(loc);
}
else if (key.compare(L"deleteUnit") == 0)
{
int ID = value[L"ID"].as_integer();
unitsFactory->deleteUnit(ID);
}
else
{
log(L"Unknown command: " + key);

View File

@@ -118,9 +118,11 @@ json::value Unit::json()
json[L"fuel"] = fuel;
json[L"ammo"] = ammo;
json[L"targets"] = targets;
json[L"targetSpeed"] = targetSpeed;
json[L"targetAltitude"] = targetAltitude;
json[L"targetSpeed"] = getTargetSpeed();
json[L"targetAltitude"] = getTargetAltitude();
json[L"hasTask"] = hasTask;
json[L"ROE"] = json::value::string(ROE);
json[L"reactionToThreat"] = json::value::string(reactionToThreat);
int i = 0;
for (auto itr = wingmen.begin(); itr != wingmen.end(); itr++)
@@ -221,4 +223,48 @@ void Unit::setFormationOffset(Offset newFormationOffset)
{
formationOffset = newFormationOffset;
resetTask();
}
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);
}
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);
}
void Unit::landAt(Coords loc) {
activePath.clear();
activePath.push_back(loc);
setState(State::LAND);
}

View File

@@ -48,11 +48,21 @@ void Aircraft::changeAltitude(wstring change)
{
if (targetAltitude > 5000)
targetAltitude += 2500 / 3.28084;
else if (targetAltitude > 0)
else if (targetAltitude >= 0)
targetAltitude += 500 / 3.28084;
}
if (targetAltitude < 0)
targetAltitude = 0;
goToDestination(); /* Send the command to reach the destination */
}
void Aircraft::setTargetSpeed(double newTargetSpeed) {
targetSpeed = newTargetSpeed;
goToDestination();
}
void Aircraft::setTargetAltitude(double newTargetAltitude) {
targetAltitude = newTargetAltitude;
goToDestination();
}

View File

@@ -41,6 +41,9 @@ void AirUnit::setState(int newState)
return;
break;
}
case State::LAND: {
break;
}
default:
break;
}
@@ -72,6 +75,10 @@ void AirUnit::setState(int newState)
resetActiveDestination();
break;
}
case State::LAND: {
resetActiveDestination();
break;
}
default:
break;
}
@@ -242,6 +249,22 @@ void AirUnit::AIloop()
break;
}
case State::LAND: {
wstring enrouteTask = L"{" "id = 'land' }";
currentTask = L"Landing";
if (activeDestination == NULL)
{
setActiveDestination();
goToDestination(enrouteTask);
}
if (isLeader)
taskWingmen();
break;
}
case State::ATTACK: {
/* If the target is not alive (either not set or was succesfully destroyed) go back to REACH_DESTINATION */
if (!isTargetAlive()) {
@@ -319,13 +342,3 @@ void AirUnit::AIloop()
break;
}
}
void AirUnit::setTargetSpeed(double newTargetSpeed) {
targetSpeed = newTargetSpeed;
goToDestination();
}
void AirUnit::setTargetAltitude(double newTargetAltitude) {
targetAltitude = newTargetAltitude;
goToDestination();
}

View File

@@ -48,7 +48,7 @@ void Helicopter::changeAltitude(wstring change)
{
if (targetAltitude > 100)
targetAltitude += 100 / 3.28084;
else if (targetAltitude > 0)
else if (targetAltitude >= 0)
targetAltitude += 10 / 3.28084;
}
if (targetAltitude < 0)
@@ -56,3 +56,14 @@ void Helicopter::changeAltitude(wstring change)
goToDestination(); /* Send the command to reach the destination */
}
void Helicopter::setTargetSpeed(double newTargetSpeed) {
targetSpeed = newTargetSpeed;
goToDestination();
}
void Helicopter::setTargetAltitude(double newTargetAltitude) {
targetAltitude = newTargetAltitude;
goToDestination();
}

View File

@@ -7,6 +7,10 @@
#include "groundunit.h"
#include "navyunit.h"
#include "weapon.h"
#include "commands.h"
#include "scheduler.h"
extern Scheduler* scheduler;
UnitsFactory::UnitsFactory(lua_State* L)
{
@@ -116,3 +120,12 @@ void UnitsFactory::updateAnswer(json::value& answer)
answer[L"units"] = unitsJson;
}
void UnitsFactory::deleteUnit(int ID)
{
if (getUnit(ID) != nullptr)
{
Command* command = dynamic_cast<Command*>(new Delete(ID));
scheduler->appendCommand(command);
}
}