diff --git a/client/src/@types/unit.d.ts b/client/src/@types/unit.d.ts index 9e621fde..6a114825 100644 --- a/client/src/@types/unit.d.ts +++ b/client/src/@types/unit.d.ts @@ -29,11 +29,7 @@ interface MissionData { } interface FormationData { - formation: string; - isLeader: boolean; - isWingman: boolean; leaderID: number; - wingmenIDs: number[]; } interface TaskData { diff --git a/client/src/units/helicopterdatabase.ts b/client/src/units/helicopterdatabase.ts index 32312440..d7fc9996 100644 --- a/client/src/units/helicopterdatabase.ts +++ b/client/src/units/helicopterdatabase.ts @@ -381,57 +381,6 @@ export class HelicopterDatabase extends UnitDatabase { ], "filename": "ah-1.png" }, - "AH-1W": { - "name": "AH-1W", - "label": "AH-1W Cobra", - "shortLabel": "AH1", - "loadouts": [ - { - "fuel": 1, - "items": [ - { - "name": "BGM-71 TOW", - "quantity": 8 - }, - { - "name": "Hydra-70 WP", - "quantity": 38 - } - ], - "roles": [ - "CAS" - ], - "code": "8xBGM-71, 38xHYDRA-70 WP", - "name": "TOW / Hydra" - }, - { - "fuel": 1, - "items": [ - { - "name": "Hydra-70", - "quantity": 76 - } - ], - "roles": [ - "CAS" - ], - "code": "76xHYDRA-70", - "name": "Hydra" - }, - { - "fuel": 1, - "items": [ - - ], - "roles": [ - "" - ], - "code": "", - "name": "Empty Loadout" - } - ], - "filename": "ah-1.png" - }, "Mi-26": { "name": "Mi-26", "label": "Mi-26 Halo", diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index fcb02761..07c0c0e6 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -40,11 +40,7 @@ export class Unit extends Marker { coalition: "", }, formationData: { - formation: "", - isLeader: false, - isWingman: false, - leaderID: 0, - wingmenIDs: [], + leaderID: 0 }, taskData: { currentState: "IDLE", @@ -315,22 +311,6 @@ export class Unit extends Marker { return getUnitsManager().getUnitByID(this.getFormationData().leaderID); } - getFormation() { - return [this].concat(this.getWingmen()) - } - - getWingmen() { - var wingmen: Unit[] = []; - if (this.getFormationData().wingmenIDs != undefined) { - for (let ID of this.getFormationData().wingmenIDs) { - var unit = getUnitsManager().getUnitByID(ID) - if (unit) - wingmen.push(unit); - } - } - return wingmen; - } - attackUnit(targetID: number) { /* Units can't attack themselves */ if (this.ID != targetID) { diff --git a/client/src/units/unitsmanager.ts b/client/src/units/unitsmanager.ts index c4b67c54..dc1e4069 100644 --- a/client/src/units/unitsmanager.ts +++ b/client/src/units/unitsmanager.ts @@ -119,35 +119,7 @@ export class UnitsManager { this.#units[ID].setSelected(false); } } - - getSelectedLeaders() { - var leaders: Unit[] = []; - for (let idx in this.getSelectedUnits()) - { - var unit = this.getSelectedUnits()[idx]; - if (unit.getFormationData().isLeader) - leaders.push(unit); - else if (unit.getFormationData().isWingman) - { - var leader = unit.getLeader(); - if (leader && !leaders.includes(leader)) - leaders.push(leader); - } - } - return leaders; - } - - getSelectedSingletons() { - var singletons: Unit[] = []; - for (let idx in this.getSelectedUnits()) - { - var unit = this.getSelectedUnits()[idx]; - if (!unit.getFormationData().isLeader && !unit.getFormationData().isWingman) - singletons.push(unit); - } - return singletons; - } - + getSelectedUnitsType () { if (this.getSelectedUnits().length == 0) return undefined; diff --git a/src/core/include/airunit.h b/src/core/include/airunit.h index a2aeb7a6..a46e9909 100644 --- a/src/core/include/airunit.h +++ b/src/core/include/airunit.h @@ -23,7 +23,6 @@ protected: virtual void setState(int newState); bool isDestinationReached(); bool setActiveDestination(); - void createHoldingPattern(); bool updateActivePath(bool looping); void goToDestination(wstring enrouteTask = L"nil"); }; \ No newline at end of file diff --git a/src/core/include/unit.h b/src/core/include/unit.h index 441c3e75..b9fde024 100644 --- a/src/core/include/unit.h +++ b/src/core/include/unit.h @@ -79,17 +79,9 @@ public: json::value getFlags() { return flags; } /********** Formation data **********/ - void setIsLeader(bool newIsLeader); - void setIsWingman(bool newIsWingman); - void setLeader(Unit* newLeader); - void setWingmen(vector newWingmen); - void setFormation(wstring newFormation) { formation = newFormation; addMeasure(L"formation", json::value(formation));} + void setLeaderID(int newLeaderID) { leaderID = newLeaderID; addMeasure(L"leaderID", json::value(newLeaderID)); } void setFormationOffset(Offset formationOffset); - bool getIsLeader() { return isLeader; } - bool getIsWingman() { return isWingman; } - Unit* getLeader() { return leader; } - vector getWingmen() { return wingmen; } - wstring getFormation() { return formation; } + int getLeaderID() { return leaderID; } Offset getFormationoffset() { return formationOffset; } /********** Task data **********/ @@ -177,11 +169,7 @@ protected: json::value flags = json::value::null(); /********** Formation data **********/ - bool isLeader = false; - bool isWingman = false; - wstring formation = L""; - Unit *leader = nullptr; - vector wingmen; + int leaderID = NULL; Offset formationOffset = Offset(NULL); /********** Task data **********/ @@ -215,7 +203,9 @@ protected: /********** Functions **********/ virtual wstring getCategory() { return L"No category"; }; wstring getTargetName(); + wstring getLeaderName(); bool isTargetAlive(); + bool isLeaderAlive(); virtual void AIloop() = 0; void addMeasure(wstring key, json::value value); }; diff --git a/src/core/src/airunit.cpp b/src/core/src/airunit.cpp index cf3d2369..1faf5118 100644 --- a/src/core/src/airunit.cpp +++ b/src/core/src/airunit.cpp @@ -22,7 +22,7 @@ void AirUnit::setState(int newState) { if (state != newState) { - /* Perform any action required when LEAVING a certain state */ + /************ Perform any action required when LEAVING a certain state ************/ switch (state) { case State::IDLE: { break; @@ -35,6 +35,7 @@ void AirUnit::setState(int newState) break; } case State::FOLLOW: { + setLeaderID(NULL); break; } case State::LAND: { @@ -47,7 +48,7 @@ void AirUnit::setState(int newState) break; } - /* Perform any action required when ENTERING a certain state */ + /************ Perform any action required when ENTERING a certain state ************/ switch (newState) { case State::IDLE: { clearActivePath(); @@ -135,23 +136,6 @@ bool AirUnit::setActiveDestination() } } -void AirUnit::createHoldingPattern() -{ - /* Air units must ALWAYS have a destination or they will RTB and become uncontrollable */ - clearActivePath(); - Coords point1; - Coords point2; - Coords point3; - Geodesic::WGS84().Direct(latitude, longitude, 45, 10000, point1.lat, point1.lng); - Geodesic::WGS84().Direct(point1.lat, point1.lng, 135, 10000, point2.lat, point2.lng); - Geodesic::WGS84().Direct(point2.lat, point2.lng, 225, 10000, point3.lat, point3.lng); - pushActivePathBack(point1); - pushActivePathBack(point2); - pushActivePathBack(point3); - pushActivePathBack(Coords(latitude, longitude)); - log(unitName + L" holding pattern created"); -} - bool AirUnit::updateActivePath(bool looping) { if (activePath.size() > 0) @@ -282,22 +266,22 @@ void AirUnit::AIloop() clearActivePath(); activeDestination = Coords(NULL); - /* If the target is not alive (either not set or was destroyed) go back to IDLE */ - if (!isTargetAlive()) { + /* If the leader is not alive (either not set or was destroyed) go back to IDLE */ + if (!isLeaderAlive()) { setState(State::IDLE); break; } currentTask = L"Following " + getTargetName(); - Unit* target = unitsManager->getUnit(targetID); + Unit* leader = unitsManager->getUnit(leaderID); if (!hasTask) { - if (target != nullptr && target->getAlive() && formationOffset != NULL) + if (leader != nullptr && leader->getAlive() && formationOffset != NULL) { std::wostringstream taskSS; taskSS << "{" << "id = 'FollowUnit'" << ", " - << "leaderID = " << target->getID() << "," + << "leaderID = " << leader->getID() << "," << "offset = {" << "x = " << formationOffset.x << "," << "y = " << formationOffset.y << "," @@ -332,5 +316,6 @@ void AirUnit::AIloop() default: break; } + addMeasure(L"currentTask", json::value(currentTask)); } diff --git a/src/core/src/scheduler.cpp b/src/core/src/scheduler.cpp index 318945f4..2bd4c98c 100644 --- a/src/core/src/scheduler.cpp +++ b/src/core/src/scheduler.cpp @@ -145,30 +145,30 @@ void Scheduler::handleRequest(wstring key, json::value value) else if (key.compare(L"followUnit") == 0) { int ID = value[L"ID"].as_integer(); - int targetID = value[L"targetID"].as_integer(); + int leaderID = value[L"targetID"].as_integer(); int offsetX = value[L"offsetX"].as_integer(); int offsetY = value[L"offsetY"].as_integer(); int offsetZ = value[L"offsetZ"].as_integer(); Unit* unit = unitsManager->getUnit(ID); - Unit* target = unitsManager->getUnit(targetID); + Unit* leader = unitsManager->getUnit(leaderID); wstring unitName; - wstring targetName; + wstring leaderName; if (unit != nullptr) unitName = unit->getUnitName(); else return; - if (target != nullptr) - targetName = target->getUnitName(); + if (leader != nullptr) + leaderName = leader->getUnitName(); else return; - log(L"Unit " + unitName + L" following unit " + targetName); + log(L"Unit " + unitName + L" following unit " + leaderName); unit->setFormationOffset(Offset(offsetX, offsetY, offsetZ)); - unit->setTargetID(targetID); + unit->setLeaderID(leaderID); unit->setState(State::FOLLOW); } else if (key.compare(L"changeSpeed") == 0) @@ -208,40 +208,6 @@ void Scheduler::handleRequest(wstring key, json::value value) command = dynamic_cast(new Clone(ID, loc)); log(L"Cloning unit " + to_wstring(ID)); } - else if (key.compare(L"setLeader") == 0) - { - int ID = value[L"ID"].as_integer(); - Unit* unit = unitsManager->getUnit(ID); - bool isLeader = value[L"isLeader"].as_bool(); - if (isLeader) - { - json::value wingmenIDs = value[L"wingmenIDs"]; - vector wingmen; - if (unit != nullptr) - { - for (auto itr = wingmenIDs.as_array().begin(); itr != wingmenIDs.as_array().end(); itr++) - { - Unit* wingman = unitsManager->getUnit(itr->as_integer()); - if (wingman != nullptr) - wingmen.push_back(wingman); - } - unit->setFormation(L"Line abreast"); - unit->setIsLeader(true); - unit->setWingmen(wingmen); - log(L"Setting " + unit->getName() + L" as formation leader"); - } - } - else { - unit->setIsLeader(false); - } - } - else if (key.compare(L"setFormation") == 0) - { - int ID = value[L"ID"].as_integer(); - Unit* unit = unitsManager->getUnit(ID); - wstring formation = value[L"formation"].as_string(); - unit->setFormation(formation); - } else if (key.compare(L"setROE") == 0) { int ID = value[L"ID"].as_integer(); diff --git a/src/core/src/unit.cpp b/src/core/src/unit.cpp index bf848269..f442e044 100644 --- a/src/core/src/unit.cpp +++ b/src/core/src/unit.cpp @@ -20,6 +20,14 @@ Unit::Unit(json::value json, int 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)); } Unit::~Unit() @@ -127,10 +135,10 @@ json::value Unit::getData(long long time) /********** Formation data **********/ json[L"formationData"] = json::value::object(); - for (auto key : { L"isLeader", L"isWingman", L"formation", L"wingmenIDs", L"leaderID" }) + for (auto key : { L"leaderID" }) { if (measures.find(key) != measures.end() && measures[key]->getTime() > time) - json[L"missionData"][key] = measures[key]->getValue(); + json[L"formationData"][key] = measures[key]->getValue(); } /********** Task data **********/ @@ -154,12 +162,9 @@ json::value Unit::getData(long long time) void Unit::setActivePath(list newPath) { - if (state != State::WINGMAN && state != State::FOLLOW) - { - activePath = newPath; - resetActiveDestination(); - } - + activePath = newPath; + resetActiveDestination(); + auto path = json::value::object(); if (activePath.size() > 0) { int count = 1; @@ -223,22 +228,6 @@ int Unit::getCoalitionID() return 2; } -void Unit::setLeader(Unit* newLeader) -{ - leader = newLeader; - if (leader != nullptr) - addMeasure(L"leaderID", json::value(leader->getID())); -} - -void Unit::setWingmen(vector newWingmen) { - wingmen = newWingmen; - auto wingmenIDs = json::value::object(); - int i = 0; - for (auto itr = wingmen.begin(); itr != wingmen.end(); itr++) - wingmenIDs[i++] = (*itr)->getID(); - addMeasure(L"wingmen", wingmenIDs); -} - wstring Unit::getTargetName() { if (isTargetAlive()) @@ -262,6 +251,29 @@ bool Unit::isTargetAlive() return false; } +wstring Unit::getLeaderName() +{ + if (isLeaderAlive()) + { + Unit* leader = unitsManager->getUnit(leaderID); + if (leader != nullptr) + return leader->getUnitName(); + } + return L""; +} + +bool Unit::isLeaderAlive() +{ + if (leaderID == NULL) + return false; + + Unit* leader = unitsManager->getUnit(leaderID); + if (leader != nullptr) + return leader->alive; + else + return false; +} + void Unit::resetActiveDestination() { activeDestination = Coords(NULL); @@ -273,30 +285,6 @@ void Unit::resetTask() scheduler->appendCommand(command); } -void Unit::setIsLeader(bool newIsLeader) { - isLeader = newIsLeader; - if (!isLeader) { - for (auto wingman : wingmen) - { - wingman->setFormation(L""); - wingman->setIsWingman(false); - wingman->setLeader(nullptr); - } - } - addMeasure(L"isLeader", json::value(newIsLeader)); -} - -void Unit::setIsWingman(bool newIsWingman) -{ - isWingman = newIsWingman; - if (isWingman) - setState(State::WINGMAN); - else - setState(State::IDLE); - - addMeasure(L"isWingman", json::value(isWingman)); -} - void Unit::setFormationOffset(Offset newFormationOffset) { formationOffset = newFormationOffset;