From fd00cffa15558feac6ecdbad7a16e69c797f5d16 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Tue, 6 Jun 2023 17:27:11 +0200 Subject: [PATCH] Added backend for advanced commands --- client/src/panels/mouseinfopanel.ts | 6 +-- client/src/server/server.ts | 1 + scripts/OlympusCommand.lua | 41 +++++++++++++++++++- src/core/include/commands.h | 20 +++++++++- src/core/include/unit.h | 11 +++++- src/core/src/airunit.cpp | 59 ++++++++++++++++++++++++++++- src/core/src/commands.cpp | 12 ++++++ src/core/src/groundunit.cpp | 21 ++++++++++ src/core/src/scheduler.cpp | 45 ++++++++++++++++++++++ src/core/src/unit.cpp | 10 ++++- 10 files changed, 217 insertions(+), 9 deletions(-) diff --git a/client/src/panels/mouseinfopanel.ts b/client/src/panels/mouseinfopanel.ts index 0aace7fb..81ef04e6 100644 --- a/client/src/panels/mouseinfopanel.ts +++ b/client/src/panels/mouseinfopanel.ts @@ -97,7 +97,7 @@ export class MouseInfoPanel extends Panel { let bng = zeroAppend(Math.floor(bear), 3); - if (bng === "000") + if (bng === "000") bng = "360"; var [str, unit] = this.#computeDistanceString(dist) @@ -112,7 +112,7 @@ export class MouseInfoPanel extends Panel { } #onMouseMove(e: any) { - + this.#update(); this.#drawMeasureLine(); } @@ -171,7 +171,7 @@ export class MouseInfoPanel extends Panel { #computeDistanceString(dist: number) { var val = mToNm(dist); - var strVal = 0; + var strVal = 0; var decimal = false; var unit = "NM"; if (val > 10) diff --git a/client/src/server/server.ts b/client/src/server/server.ts index f4a0000f..f92a1204 100644 --- a/client/src/server/server.ts +++ b/client/src/server/server.ts @@ -280,6 +280,7 @@ export function fireAtArea(ID: number, latlng: LatLng) { var data = { "fireAtArea": command } POST(data, () => { }); } + export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings) { var command = { "ID": ID, diff --git a/scripts/OlympusCommand.lua b/scripts/OlympusCommand.lua index 8edf6214..bde0dc53 100644 --- a/scripts/OlympusCommand.lua +++ b/scripts/OlympusCommand.lua @@ -139,8 +139,41 @@ function Olympus.buildTask(options) pattern = options['pattern'] or "Circle" } } + elseif options['id'] == 'Bombing' and options['lat'] and options['lng'] then + task = { + id = 'Bombing', + params = { + point = coord.LLtoLO(options['lat'], options['lng'], 0), + attackQty = 1 + } + } + elseif options['id'] == 'CarpetBombing' and options['lat'] and options['lng'] then + task = { + id = 'CarpetBombing', + params = { + point = coord.LLtoLO(options['lat'], options['lng'], 0), + attackQty = 1, + carpetLength = 1000, + attackType = 'Carpet' + } + } + elseif options['id'] == 'AttackMapObject' and options['lat'] and options['lng'] then + task = { + id = 'AttackMapObject', + params = { + point = coord.LLtoLO(options['lat'], options['lng'], 0), + } + } + end + elseif options['id'] == 'FireAtPoint' and options['lat'] and options['lng'] and options['radius'] then + task = { + id = 'AttackMapObject', + params = { + point = coord.LLtoLO(options['lat'], options['lng'], 0), + radius = options['radius'] + } + } end - end return task end @@ -238,6 +271,12 @@ function Olympus.smoke(color, lat, lng) trigger.action.smoke(mist.utils.makeVec3GL(coord.LLtoLO(lat, lng, 0)), colorEnum) end +-- Creates an explosion on the ground +function Olympus.explosion(intensity, lat, lng) + Olympus.debug("Olympus.explosion " .. intensity .. " (" .. lat .. ", " .. lng ..")", 2) + trigger.action.explosion(mist.utils.makeVec3GL(coord.LLtoLO(lat, lng, 0)), intensity) +end + -- Spawns a single ground unit function Olympus.spawnGroundUnit(coalition, unitType, lat, lng) Olympus.debug("Olympus.spawnGroundUnit " .. coalition .. " " .. unitType .. " (" .. lat .. ", " .. lng ..")", 2) diff --git a/src/core/include/commands.h b/src/core/include/commands.h index 920256bb..b244bc58 100644 --- a/src/core/include/commands.h +++ b/src/core/include/commands.h @@ -305,7 +305,7 @@ private: const bool isBoolean; }; -/* Set on ooff */ +/* Set on off */ class SetOnOff : public Command { public: @@ -322,3 +322,21 @@ private: const int ID; const bool onOff; }; + +/* Make a ground explosion */ +class Explosion : public Command +{ +public: + Explosion(int intensity, Coords location) : + location(location), + intensity(intensity) + { + priority = CommandPriority::MEDIUM; + }; + virtual wstring getString(lua_State* L); + virtual int getLoad() { return 10; } + +private: + const Coords location; + const int intensity; +}; diff --git a/src/core/include/unit.h b/src/core/include/unit.h index a34e4345..13e47945 100644 --- a/src/core/include/unit.h +++ b/src/core/include/unit.h @@ -18,7 +18,11 @@ namespace State LAND, REFUEL, AWACS, - TANKER + TANKER, + BOMB_POINT, + CARPET_BOMB, + BOMB_BUILDING, + FIRE_AT_AREA }; }; @@ -124,6 +128,7 @@ public: void setActiveDestination(Coords newActiveDestination) { activeDestination = newActiveDestination; addMeasure(L"activeDestination", json::value("")); } // TODO fix void setActivePath(list newActivePath); void setTargetID(int newTargetID) { targetID = newTargetID; addMeasure(L"targetID", json::value(newTargetID));} + void setTargetLocation(Coords newTargetLocation); void setIsTanker(bool newIsTanker); void setIsAWACS(bool newIsAWACS); virtual void setOnOff(bool newOnOff) { onOff = newOnOff; addMeasure(L"onOff", json::value(newOnOff));}; @@ -137,6 +142,7 @@ public: Coords getActiveDestination() { return activeDestination; } list getActivePath() { return activePath; } int getTargetID() { return targetID; } + Coords getTargetLocation() { return targetLocation; } bool getIsTanker() { return isTanker; } bool getIsAWACS() { return isAWACS; } bool getOnOff() { return onOff; }; @@ -212,8 +218,9 @@ protected: wstring targetSpeedType = L"GS"; wstring targetAltitudeType = L"AGL"; list activePath; - Coords activeDestination = Coords(0); + Coords activeDestination = Coords(NULL); int targetID = NULL; + Coords targetLocation = Coords(NULL); bool isTanker = false; bool isAWACS = false; bool onOff = true; diff --git a/src/core/src/airunit.cpp b/src/core/src/airunit.cpp index c63b69c2..4cb7c798 100644 --- a/src/core/src/airunit.cpp +++ b/src/core/src/airunit.cpp @@ -43,6 +43,12 @@ void AirUnit::setState(int newState) case State::REFUEL: { break; } + case State::BOMB_POINT: + case State::CARPET_BOMB: + case State::BOMB_BUILDING: { + setTargetLocation(Coords(NULL)); + break; + } default: break; } @@ -90,6 +96,24 @@ void AirUnit::setState(int newState) addMeasure(L"currentState", json::value(L"Refuel")); break; } + case State::BOMB_POINT: { + addMeasure(L"currentState", json::value(L"Bombing point")); + clearActivePath(); + resetActiveDestination(); + break; + } + case State::CARPET_BOMB: { + addMeasure(L"currentState", json::value(L"Carpet bombing")); + clearActivePath(); + resetActiveDestination(); + break; + } + case State::BOMB_BUILDING: { + addMeasure(L"currentState", json::value(L"Bombing building")); + clearActivePath(); + resetActiveDestination(); + break; + } default: break; } @@ -249,9 +273,42 @@ void AirUnit::AIloop() } } } + case State::BOMB_POINT: { + currentTask = L"Bombing point"; + + if (!getHasTask()) { + std::wostringstream taskSS; + taskSS << "{id = 'Bombing', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}"; + Command* command = dynamic_cast(new SetTask(ID, taskSS.str())); + scheduler->appendCommand(command); + setHasTask(true); + } + } + case State::CARPET_BOMB: { + currentTask = L"Carpet bombing"; + + if (!getHasTask()) { + std::wostringstream taskSS; + taskSS << "{id = 'CarpetBombing', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}"; + Command* command = dynamic_cast(new SetTask(ID, taskSS.str())); + scheduler->appendCommand(command); + setHasTask(true); + } + } + case State::BOMB_BUILDING: { + currentTask = L"Bombing building"; + + if (!getHasTask()) { + std::wostringstream taskSS; + taskSS << "{id = 'AttackMapObject', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << "}"; + Command* command = dynamic_cast(new SetTask(ID, taskSS.str())); + scheduler->appendCommand(command); + setHasTask(true); + } + } default: break; } addMeasure(L"currentTask", json::value(currentTask)); -} +} \ No newline at end of file diff --git a/src/core/src/commands.cpp b/src/core/src/commands.cpp index a360f7c2..279a9700 100644 --- a/src/core/src/commands.cpp +++ b/src/core/src/commands.cpp @@ -177,4 +177,16 @@ wstring SetOnOff::getString(lua_State* L) << (onOff ? "true" : "false"); return commandSS.str(); +} + +/* Explosion command */ +wstring Explosion::getString(lua_State* L) +{ + std::wostringstream commandSS; + commandSS.precision(10); + commandSS << "Olympus.explosion, " + << intensity << ", " + << location.lat << ", " + << location.lng; + return commandSS.str(); } \ No newline at end of file diff --git a/src/core/src/groundunit.cpp b/src/core/src/groundunit.cpp index c5685d91..7de80307 100644 --- a/src/core/src/groundunit.cpp +++ b/src/core/src/groundunit.cpp @@ -33,6 +33,10 @@ void GroundUnit::setState(int newState) case State::REACH_DESTINATION: { break; } + case State::FIRE_AT_AREA: { + setTargetLocation(Coords(NULL)); + break; + } default: break; } @@ -51,6 +55,12 @@ void GroundUnit::setState(int newState) addMeasure(L"currentState", json::value(L"Reach destination")); break; } + case State::FIRE_AT_AREA: { + addMeasure(L"currentState", json::value(L"Firing at area")); + clearActivePath(); + resetActiveDestination(); + break; + } default: break; } @@ -96,6 +106,17 @@ void GroundUnit::AIloop() } break; } + case State::FIRE_AT_AREA: { + currentTask = L"Firing at area"; + + if (!getHasTask()) { + std::wostringstream taskSS; + taskSS << "{id = 'FireAtPoint', lat = " << targetLocation.lat << ", lng = " << targetLocation.lng << ", radius = 1000}"; + Command* command = dynamic_cast(new SetTask(ID, taskSS.str())); + scheduler->appendCommand(command); + setHasTask(true); + } + } default: break; } diff --git a/src/core/src/scheduler.cpp b/src/core/src/scheduler.cpp index a6b133c4..d15a1947 100644 --- a/src/core/src/scheduler.cpp +++ b/src/core/src/scheduler.cpp @@ -316,6 +316,51 @@ void Scheduler::handleRequest(wstring key, json::value value) Unit* unit = unitsManager->getUnit(ID); unit->setOnOff(onOff); } + else if (key.compare(L"explosion") == 0) + { + int intensity = value[L"intensity"].as_integer(); + double lat = value[L"location"][L"lat"].as_double(); + double lng = value[L"location"][L"lng"].as_double(); + log(L"Adding " + to_wstring(intensity) + L" explosion at (" + to_wstring(lat) + L", " + to_wstring(lng) + L")"); + Coords loc; loc.lat = lat; loc.lng = lng; + command = dynamic_cast(new Explosion(intensity, loc)); + } + else if (key.compare(L"bombPoint") == 0) + { + int ID = value[L"ID"].as_integer(); + 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->setState(State::BOMB_POINT); + } + else if (key.compare(L"carpetBomb") == 0) + { + int ID = value[L"ID"].as_integer(); + 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->setState(State::CARPET_BOMB); + } + else if (key.compare(L"bombBuilding") == 0) + { + int ID = value[L"ID"].as_integer(); + 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->setState(State::BOMB_BUILDING); + } + else if (key.compare(L"fireAtArea") == 0) + { + int ID = value[L"ID"].as_integer(); + 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->setState(State::FIRE_AT_AREA); + } else { log(L"Unknown command: " + key); diff --git a/src/core/src/unit.cpp b/src/core/src/unit.cpp index 2c70efc6..160a176e 100644 --- a/src/core/src/unit.cpp +++ b/src/core/src/unit.cpp @@ -179,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"targetSpeedType", L"targetAltitudeType", L"activePath", L"isTanker", L"isAWACS", L"onOff", L"followRoads"}) + 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(); @@ -660,4 +660,12 @@ bool Unit::updateActivePath(bool looping) else { return false; } +} + +void Unit::setTargetLocation(Coords newTargetLocation) { + targetLocation = newTargetLocation; + auto json = json::value(); + json[L"latitude"] = json::value(newTargetLocation.lat); + json[L"longitude"] = json::value(newTargetLocation.lng); + addMeasure(L"targetLocation", json::value(json)); } \ No newline at end of file