mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge branch 'laser-fix' into release-candidate
This commit is contained in:
commit
8ffcbaa05b
@ -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<Command*>(new SetTask(groupName, taskSS.str(), [this]() { this->setHasTaskAssigned(true); }));
|
||||
scheduler->appendCommand(command);
|
||||
setHasTask(true);
|
||||
@ -437,9 +442,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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -89,7 +89,7 @@ export interface BullseyesData {
|
||||
|
||||
export interface SpotsData {
|
||||
spots: {
|
||||
[key: string]: { type: string; targetPosition: { lat: number; lng: number }; sourceUnitID: number; code?: number };
|
||||
[key: string]: { active: boolean; type: string; targetPosition: { lat: number; lng: number }; sourceUnitID: number; code?: number };
|
||||
};
|
||||
sessionHash: string;
|
||||
time: number;
|
||||
|
||||
@ -6,13 +6,20 @@ import { BLUE_COMMANDER, GAME_MASTER, NONE, RED_COMMANDER } from "../constants/c
|
||||
import { AirbasesData, BullseyesData, CommandModeOptions, DateAndTime, MissionData, SpotsData } from "../interfaces";
|
||||
import { Coalition } from "../types/types";
|
||||
import { Carrier } from "./carrier";
|
||||
import { AirbaseSelectedEvent, AppStateChangedEvent, BullseyesDataChangedEvent, CommandModeOptionsChangedEvent, EnabledCommandModesChangedEvent, MissionDataChangedEvent } from "../events";
|
||||
import {
|
||||
AirbaseSelectedEvent,
|
||||
AppStateChangedEvent,
|
||||
BullseyesDataChangedEvent,
|
||||
CommandModeOptionsChangedEvent,
|
||||
EnabledCommandModesChangedEvent,
|
||||
MissionDataChangedEvent,
|
||||
} from "../events";
|
||||
import { Spot } from "./spot";
|
||||
|
||||
/** The MissionManager */
|
||||
export class MissionManager {
|
||||
#bullseyes: { [name: string]: Bullseye } = {};
|
||||
#spots: {[key: string]: Spot} = {};
|
||||
#spots: { [key: string]: Spot } = {};
|
||||
#airbases: { [name: string]: Airbase | Carrier } = {};
|
||||
#theatre: string = "";
|
||||
#dateAndTime: DateAndTime = {
|
||||
@ -39,7 +46,7 @@ export class MissionManager {
|
||||
constructor() {
|
||||
AppStateChangedEvent.on((state, subState) => {
|
||||
if (this.getSelectedAirbase() !== null) AirbaseSelectedEvent.dispatch(null);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/** Update location of bullseyes
|
||||
@ -63,7 +70,7 @@ export class MissionManager {
|
||||
this.#bullseyes[idx].setCoalition(bullseye.coalition);
|
||||
}
|
||||
|
||||
BullseyesDataChangedEvent.dispatch(this.#bullseyes)
|
||||
BullseyesDataChangedEvent.dispatch(this.#bullseyes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,18 +79,18 @@ export class MissionManager {
|
||||
const spotID = Number(idx);
|
||||
const spot = data.spots[idx];
|
||||
if (this.#spots[spotID] === undefined) {
|
||||
this.#spots[spotID] = new Spot(spotID, spot.type, new LatLng(spot.targetPosition.lat, spot.targetPosition.lng), spot.sourceUnitID, spot.code);
|
||||
this.#spots[spotID] = new Spot(
|
||||
spotID,
|
||||
spot.type,
|
||||
new LatLng(spot.targetPosition.lat, spot.targetPosition.lng),
|
||||
spot.sourceUnitID,
|
||||
spot.active,
|
||||
spot.code
|
||||
);
|
||||
} else {
|
||||
if (spot.type === "laser")
|
||||
this.#spots[spotID].setCode(spot.code ?? 0)
|
||||
this.#spots[spotID].setTargetPosition( new LatLng(spot.targetPosition.lat, spot.targetPosition.lng));
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate the existing spots and remove all spots that where deleted */
|
||||
for (let idx in this.#spots) {
|
||||
if (data.spots[idx] === undefined) {
|
||||
delete this.#spots[idx];
|
||||
if (spot.type === "laser") this.#spots[spotID].setCode(spot.code ?? 0);
|
||||
this.#spots[spotID].setActive(spot.active);
|
||||
this.#spots[spotID].setTargetPosition(new LatLng(spot.targetPosition.lat, spot.targetPosition.lng));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -99,7 +106,7 @@ export class MissionManager {
|
||||
updateAirbases(data: AirbasesData) {
|
||||
for (let idx in data.airbases) {
|
||||
var airbase = data.airbases[idx];
|
||||
var airbaseCallsign = airbase.callsign !== ""? airbase.callsign: `carrier-${airbase.unitId}`
|
||||
var airbaseCallsign = airbase.callsign !== "" ? airbase.callsign : `carrier-${airbase.unitId}`;
|
||||
if (this.#airbases[airbaseCallsign] === undefined) {
|
||||
if (airbase.callsign != "") {
|
||||
this.#airbases[airbaseCallsign] = new Airbase({
|
||||
@ -161,7 +168,7 @@ export class MissionManager {
|
||||
return this.#airbases;
|
||||
}
|
||||
|
||||
getSpots() {
|
||||
getSpots() {
|
||||
return this.#spots;
|
||||
}
|
||||
|
||||
@ -279,7 +286,7 @@ export class MissionManager {
|
||||
commandModeOptions.spawnPoints.red !== this.getCommandModeOptions().spawnPoints.red ||
|
||||
commandModeOptions.spawnPoints.blue !== this.getCommandModeOptions().spawnPoints.blue ||
|
||||
commandModeOptions.restrictSpawns !== this.getCommandModeOptions().restrictSpawns ||
|
||||
commandModeOptions.restrictToCoalition !== this.getCommandModeOptions().restrictToCoalition ||
|
||||
commandModeOptions.restrictToCoalition !== this.getCommandModeOptions().restrictToCoalition ||
|
||||
commandModeOptions.setupTime !== this.getCommandModeOptions().setupTime;
|
||||
|
||||
this.#commandModeOptions = commandModeOptions;
|
||||
|
||||
@ -2,47 +2,57 @@ import { LatLng } from "leaflet";
|
||||
import { getApp } from "../olympusapp";
|
||||
|
||||
export class Spot {
|
||||
private ID: number;
|
||||
private type: string;
|
||||
private targetPosition: LatLng;
|
||||
private sourceUnitID: number;
|
||||
private code?: number;
|
||||
#ID: number;
|
||||
#type: string;
|
||||
#targetPosition: LatLng;
|
||||
#sourceUnitID: number;
|
||||
#active: boolean;
|
||||
#code?: number;
|
||||
|
||||
constructor(ID: number, type: string, targetPosition: LatLng, sourceUnitID: number, code?: number) {
|
||||
this.ID = ID;
|
||||
this.type = type;
|
||||
this.targetPosition = targetPosition;
|
||||
this.sourceUnitID = sourceUnitID;
|
||||
this.code = code;
|
||||
constructor(ID: number, type: string, targetPosition: LatLng, sourceUnitID: number, active: boolean, code?: number) {
|
||||
this.#ID = ID;
|
||||
this.#type = type;
|
||||
this.#targetPosition = targetPosition;
|
||||
this.#sourceUnitID = sourceUnitID;
|
||||
this.#code = code;
|
||||
this.#active = active;
|
||||
}
|
||||
|
||||
// Getter methods
|
||||
getID() {
|
||||
return this.ID;
|
||||
return this.#ID;
|
||||
}
|
||||
|
||||
getType() {
|
||||
return this.type;
|
||||
return this.#type;
|
||||
}
|
||||
|
||||
getTargetPosition() {
|
||||
return this.targetPosition;
|
||||
return this.#targetPosition;
|
||||
}
|
||||
|
||||
getSourceUnitID() {
|
||||
return this.sourceUnitID;
|
||||
return this.#sourceUnitID;
|
||||
}
|
||||
|
||||
getCode() {
|
||||
return this.code;
|
||||
return this.#code;
|
||||
}
|
||||
|
||||
getActive() {
|
||||
return this.#active;
|
||||
}
|
||||
|
||||
// Setter methods
|
||||
setTargetPosition(position: LatLng) {
|
||||
this.targetPosition = position;
|
||||
this.#targetPosition = position;
|
||||
}
|
||||
|
||||
setCode(code: number) {
|
||||
this.code = code;
|
||||
this.#code = code;
|
||||
}
|
||||
|
||||
setActive(active: boolean) {
|
||||
this.#active = active;
|
||||
}
|
||||
}
|
||||
@ -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() {
|
||||
/>
|
||||
</div>
|
||||
<div className={`h-8 w-0 border-l-[2px] border-gray-700`}></div>
|
||||
<OlRoundStateButton
|
||||
onClick={() => {
|
||||
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}
|
||||
/>
|
||||
<div className={`flex h-fit flex-row items-center justify-start gap-1`}>
|
||||
{Object.entries({
|
||||
human: olButtonsVisibilityHuman,
|
||||
|
||||
@ -1953,21 +1953,29 @@ export abstract class Unit extends CustomMarker {
|
||||
// Iterate over all spots and draw lines, edit markers, and markers
|
||||
Object.values(getApp().getMissionManager().getSpots()).forEach((spot: Spot) => {
|
||||
if (spot.getSourceUnitID() === this.ID) {
|
||||
const spotBearing = deg2rad(bearing(this.getPosition().lat, this.getPosition().lng, spot.getTargetPosition().lat, spot.getTargetPosition().lng, false));
|
||||
const spotDistance = this.getPosition().distanceTo(spot.getTargetPosition());
|
||||
const midPosition = bearingAndDistanceToLatLng(this.getPosition().lat, this.getPosition().lng, spotBearing, spotDistance / 2);
|
||||
if (spot.getActive()) {
|
||||
const spotBearing = deg2rad(
|
||||
bearing(this.getPosition().lat, this.getPosition().lng, spot.getTargetPosition().lat, spot.getTargetPosition().lng, false)
|
||||
);
|
||||
const spotDistance = this.getPosition().distanceTo(spot.getTargetPosition());
|
||||
const midPosition = bearingAndDistanceToLatLng(this.getPosition().lat, this.getPosition().lng, spotBearing, spotDistance / 2);
|
||||
|
||||
// Draw the spot line
|
||||
this.#drawSpotLine(spot, spotBearing);
|
||||
// Draw the spot line
|
||||
this.#drawSpotLine(spot, spotBearing);
|
||||
|
||||
// Draw the spot edit marker if the map is zoomed in enough
|
||||
if (getApp().getMap().getZoom() >= SPOTS_EDIT_ZOOM_TRANSITION) {
|
||||
// Draw the spot edit marker
|
||||
this.#drawSpotEditMarker(spot, midPosition, spotBearing);
|
||||
// Draw the spot edit marker if the map is zoomed in enough
|
||||
if (getApp().getMap().getZoom() >= SPOTS_EDIT_ZOOM_TRANSITION) {
|
||||
// Draw the spot edit marker
|
||||
this.#drawSpotEditMarker(spot, midPosition, spotBearing);
|
||||
}
|
||||
|
||||
// Draw the spot marker
|
||||
this.#drawSpotMarker(spot);
|
||||
} else {
|
||||
this.#spotLines[spot.getID()]?.removeFrom(getApp().getMap());
|
||||
this.#spotEditMarkers[spot.getID()]?.removeFrom(getApp().getMap());
|
||||
this.#spotMarkers[spot.getID()]?.removeFrom(getApp().getMap());
|
||||
}
|
||||
|
||||
// Draw the spot marker
|
||||
this.#drawSpotMarker(spot);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -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:
|
||||
@ -116,6 +119,9 @@ export abstract class Weapon extends CustomMarker {
|
||||
getApp().getMap().addFlakMarker(this.getLatLng());
|
||||
}
|
||||
this.#alive = newAlive;
|
||||
if (this.#speedVector.length > 0 && newAlive === false) {
|
||||
let asd = 1;
|
||||
}
|
||||
}
|
||||
|
||||
belongsToCommandedCoalition() {
|
||||
|
||||
@ -589,6 +589,7 @@ function Olympus.fireLaser(ID, code, lat, lng)
|
||||
lat = lat,
|
||||
lng = lng
|
||||
},
|
||||
active = true,
|
||||
code = code
|
||||
}
|
||||
end
|
||||
@ -611,13 +612,15 @@ function Olympus.fireInfrared(ID, lat, lng)
|
||||
targetPosition = {
|
||||
lat = lat,
|
||||
lng = lng
|
||||
}
|
||||
},
|
||||
active = true
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- Set new laser code
|
||||
function Olympus.setLaserCode(spotID, code)
|
||||
Olympus.debug("Olympus.setLaserCode " .. spotID .. " -> " .. code, 2)
|
||||
local spot = Olympus.spots[spotID]
|
||||
if spot ~= nil and spot.type == "laser" then
|
||||
spot.object:setCode(code)
|
||||
@ -627,19 +630,21 @@ end
|
||||
|
||||
-- Move spot to a new location
|
||||
function Olympus.moveSpot(spotID, lat, lng)
|
||||
Olympus.debug("Olympus.moveSpot " .. spotID .. " -> (" .. lat .. ", " .. lng .. ")", 2)
|
||||
local spot = Olympus.spots[spotID]
|
||||
if spot ~= nil then
|
||||
spot.object:setPoint(coord.LLtoLO(lat, lng, 0))
|
||||
spot.object:setPoint(mist.utils.makeVec3GL(coord.LLtoLO(lat, lng, 0)))
|
||||
spot.targetPosition = {lat = lat, lng = lng}
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove the spot
|
||||
function Olympus.deleteSpot(spotID)
|
||||
Olympus.debug("Olympus.deleteSpot " .. spotID, 2)
|
||||
local spot = Olympus.spots[spotID]
|
||||
if spot ~= nil then
|
||||
spot.object:destroy()
|
||||
Olympus.spots[spotID] = nil
|
||||
Olympus.spots[spotID]["active"] = false
|
||||
end
|
||||
end
|
||||
|
||||
@ -1415,8 +1420,8 @@ function Olympus.setWeaponsData(arg, time)
|
||||
table["category"] = "Missile"
|
||||
elseif weapon:getDesc().category == Weapon.Category.BOMB then
|
||||
table["category"] = "Bomb"
|
||||
elseif weapon:getDesc().category == Weapon.Category.SHELL then
|
||||
table["category"] = "Shell"
|
||||
--elseif weapon:getDesc().category == Weapon.Category.SHELL then
|
||||
-- table["category"] = "Shell" -- Useful for debugging but has no real use and has big impact on performance
|
||||
end
|
||||
else
|
||||
weapons[ID] = {isAlive = false}
|
||||
@ -1527,6 +1532,7 @@ function Olympus.setMissionData(arg, time)
|
||||
type = spot.type,
|
||||
sourceUnitID = spot.sourceUnitID,
|
||||
targetPosition = spot.targetPosition,
|
||||
active = spot.active,
|
||||
}
|
||||
|
||||
-- If the spot type is "laser", add the code to the spot entry
|
||||
@ -1542,7 +1548,7 @@ function Olympus.setMissionData(arg, time)
|
||||
Olympus.missionData["spots"] = spots
|
||||
|
||||
Olympus.OlympusDLL.setMissionData()
|
||||
return time + 1 -- For perfomance reasons weapons are updated once every second
|
||||
return time + 1 -- For perfomance reasons mission data is updated once every second
|
||||
end
|
||||
|
||||
-- Initializes the units table with all the existing ME units
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user