diff --git a/backend/core/src/groundunit.cpp b/backend/core/src/groundunit.cpp index 3923ce03..806db620 100644 --- a/backend/core/src/groundunit.cpp +++ b/backend/core/src/groundunit.cpp @@ -242,7 +242,12 @@ void GroundUnit::AIloop() if (!getHasTask()) { std::ostringstream taskSS; taskSS.precision(10); - taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 100}"; + if (targetPosition.alt == NULL) { + taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", radius = 100}"; + } + else { + taskSS << "{id = 'FireAtPoint', lat = " << targetPosition.lat << ", lng = " << targetPosition.lng << ", alt = " << targetPosition.alt << ", radius = 100}"; + } Command* command = dynamic_cast(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); })); scheduler->appendCommand(command); setHasTask(true); @@ -429,9 +434,22 @@ void GroundUnit::AIloop() taskString += "Missing on purpose. Valid target at range: " + to_string((int) round(distance)) + "m"; double correctedAimTime = aimTime; + double dstep = 0; + double vstep = muzzleVelocity; + double dt = 0.1; + double k = 0.0086; + double gdelta = 9.81; + /* Approximate the flight time */ - if (muzzleVelocity != 0) - correctedAimTime += distance / muzzleVelocity; + unsigned int stepCount = 0; + if (muzzleVelocity != 0) { + while (dstep < distance && stepCount < 1000) { + dstep += vstep * dt; + vstep -= (k * vstep + gdelta) * dt; + stepCount++; + } + correctedAimTime += stepCount * dt; + } /* If the target is in targeting range and we are in highest precision mode, target it */ if (distance < targetingRange && shotsScatter == ShotsScatter::LOW) { diff --git a/backend/core/src/scheduler.cpp b/backend/core/src/scheduler.cpp index 30243911..663600d6 100644 --- a/backend/core/src/scheduler.cpp +++ b/backend/core/src/scheduler.cpp @@ -619,6 +619,11 @@ void Scheduler::handleRequest(string key, json::value value, string username, js 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; + + if (value[L"location"].has_number_field(L"alt")) { + loc.alt = value[L"location"][L"alt"].as_double(); + } + Unit* unit = unitsManager->getGroupLeader(ID); if (unit != nullptr) { unit->setTargetPosition(loc); diff --git a/frontend/react/src/ui/panels/header.tsx b/frontend/react/src/ui/panels/header.tsx index e3891a3a..9da74fcf 100644 --- a/frontend/react/src/ui/panels/header.tsx +++ b/frontend/react/src/ui/panels/header.tsx @@ -50,6 +50,8 @@ import { import { OlympusConfig } from "../../interfaces"; import { FaCheck, FaQuestionCircle, FaSave, FaSpinner } from "react-icons/fa"; import { OlExpandingTooltip } from "../components/olexpandingtooltip"; +import { ftToM } from "../../other/utils"; +import { LatLng } from "leaflet"; export function Header() { const [mapHiddenTypes, setMapHiddenTypes] = useState(MAP_HIDDEN_TYPES_DEFAULTS); @@ -219,6 +221,18 @@ export function Header() { />
+ { + getApp().getUnitsManager().getSelectedUnits().forEach((unit) => { + let position = new LatLng(unit.getPosition().lat, unit.getPosition().lng); + position.lat += 0.01; + position.alt = ftToM(15000); + unit.fireAtArea(position); + }) + }} + checked={false} + icon={faFlag} + />
{Object.entries({ human: olButtonsVisibilityHuman, diff --git a/frontend/react/src/weapon/weapon.ts b/frontend/react/src/weapon/weapon.ts index 0181c9e0..f692a84a 100644 --- a/frontend/react/src/weapon/weapon.ts +++ b/frontend/react/src/weapon/weapon.ts @@ -20,7 +20,9 @@ export abstract class Weapon extends CustomMarker { #hidden: boolean = false; #detectionMethods: number[] = []; - + #speedVector: number[] = []; + #altitude: number[] = []; + getAlive() { return this.#alive; } @@ -86,6 +88,7 @@ export abstract class Weapon extends CustomMarker { break; case DataIndexes.speed: this.#speed = dataExtractor.extractFloat64(); + this.#speedVector.push(this.#speed); updateMarker = true; break; case DataIndexes.heading: @@ -113,6 +116,9 @@ export abstract class Weapon extends CustomMarker { setAlive(newAlive: boolean) { this.#alive = newAlive; + if (this.#speedVector.length > 0 && newAlive === false) { + let asd = 1; + } } belongsToCommandedCoalition() {