fix: magvar used for BE calls

fix: unit summary labels
This commit is contained in:
Davide Passoni 2024-12-12 16:43:24 +01:00
parent 89abcb3330
commit 8006d639ae
19 changed files with 159 additions and 146 deletions

View File

@ -26,6 +26,7 @@
"leaflet": "^1.9.4",
"leaflet-control-mini-map": "^0.4.0",
"leaflet-path-drag": "^1.9.5",
"magvar": "^1.1.5",
"opus-decoder": "^0.7.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@ -473,7 +473,7 @@ export namespace ContextActions {
export const STOP = new ContextAction(
"stop",
"Stop unit",
"Stops the unit",
"Stops the unit, removing any currently assigned task. Air units will orbin in place, while ground unit will halt.",
faHand,
ContextActionTarget.NONE,
(units: Unit[], _1, _2) => {
@ -488,7 +488,7 @@ export namespace ContextActions {
export const MOVE = new ContextAction(
"move",
"Set destination",
"Click on the map to move the units there",
"Click on the map to directly move the units there, overriding any existing command.",
faLocationDot,
ContextActionTarget.POINT,
(units: Unit[], _, targetPosition, originalEvent) => {
@ -504,7 +504,7 @@ export namespace ContextActions {
export const PATH = new ContextAction(
"path",
"Create route",
"Click on the map to add a destination to the path",
"Click on the map to add a destination add the end of the path. This allows to create a more complex route.",
faRoute,
ContextActionTarget.POINT,
(units: Unit[], _, targetPosition) => {
@ -519,7 +519,7 @@ export namespace ContextActions {
export const DELETE = new ContextAction(
"delete",
"Delete unit",
"Deletes the unit",
"Deletes the unit immediately with no effect.",
faTrash,
ContextActionTarget.NONE,
(units: Unit[], _1, _2) => {
@ -537,7 +537,7 @@ export namespace ContextActions {
export const EXPLODE = new ContextAction(
"explode",
"Explode unit",
"Explodes the unit",
"Explodes the unit using different explosions effects. WARNING: may affect surrounding units too!",
faExplosion,
ContextActionTarget.NONE,
(units: Unit[], _1, _2) => {
@ -556,7 +556,7 @@ export namespace ContextActions {
export const CENTER_MAP = new ContextAction(
"center-map",
"Center map",
"Center the map on the unit and follow it",
"Center the map on the unit and follow it.",
faMapLocation,
ContextActionTarget.NONE,
(units: Unit[]) => {
@ -568,7 +568,7 @@ export namespace ContextActions {
export const REFUEL = new ContextAction(
"refuel",
"Refuel at tanker",
"Refuel units at the nearest AAR Tanker. If no tanker is available the unit will RTB",
"Refuel units at the nearest Air-to-Air refuelling tanker of the appropriate type. If no tanker is available the unit will return to the nearest base.",
olButtonsContextRefuel,
ContextActionTarget.NONE,
(units: Unit[]) => {
@ -580,7 +580,7 @@ export namespace ContextActions {
export const FOLLOW = new ContextAction(
"follow",
"Follow unit",
"Right-click on a unit to follow it in formation",
"Click on a unit to follow it in formation. A menu allows to choose the formation type.",
olButtonsContextFollow,
ContextActionTarget.UNIT,
(units: Unit[], targetUnit: Unit | null, _) => {
@ -598,7 +598,7 @@ export namespace ContextActions {
export const BOMB = new ContextAction(
"bomb",
"Precision bomb location",
"Right-click on a point to execute a precision bombing attack",
"Click on a point to execute a precision bombing attack with the available A/G weapons.",
faLocationCrosshairs,
ContextActionTarget.POINT,
(units: Unit[], _, targetPosition: LatLng | null) => {
@ -611,7 +611,7 @@ export namespace ContextActions {
export const CARPET_BOMB = new ContextAction(
"carpet-bomb",
"Carpet bomb location",
"Right-click on a point to execute a carpet bombing attack",
"Click on a point to execute a carpet bombing attack with the available A/G weapons.",
faXmarksLines,
ContextActionTarget.POINT,
(units: Unit[], _, targetPosition: LatLng | null) => {
@ -624,7 +624,7 @@ export namespace ContextActions {
export const LAND = new ContextAction(
"land",
"Land",
"Right-click on a point to land at the nearest airbase",
"Click on a point to land at the nearest airbase.",
faPlaneArrival,
ContextActionTarget.POINT,
(units: Unit[], _, targetPosition: LatLng | null) => {
@ -636,7 +636,7 @@ export namespace ContextActions {
export const LAND_AT_POINT = new ContextAction(
"land-at-point",
"Land at location",
"Right-click on a point to land there",
"Click on a point to land there. WARNING: if multiple units are selected make sure to choose a different point for each or the units will crash!",
olButtonsContextLandAtPoint,
ContextActionTarget.POINT,
(units: Unit[], _, targetPosition: LatLng | null) => {
@ -649,7 +649,7 @@ export namespace ContextActions {
export const GROUP = new ContextAction(
"group-ground",
"Group ground units",
"Create a group of ground units",
"Create a DCS group of ground units. This is different from hotgroups or formations and is used primarily to create functioning SAM sites. When a group is created, units will no longer be individually controllable.",
faPeopleGroup,
ContextActionTarget.NONE,
(units: Unit[], _1, _2) => {
@ -661,7 +661,7 @@ export namespace ContextActions {
export const ATTACK = new ContextAction(
"attack",
"Attack unit",
"Right-click on a unit to attack it",
"Click on a unit to attack it using A/A or A/G weapons, depending on the target.",
olButtonsContextAttack,
ContextActionTarget.UNIT,
(units: Unit[], targetUnit: Unit | null, _) => {
@ -673,7 +673,7 @@ export namespace ContextActions {
export const FIRE_AT_AREA = new ContextAction(
"fire-at-area",
"Fire at area",
"Right-click on a point to precisely fire at it (if possible)",
"Click on a point to precisely fire at it, if possible. WARNING: this requires the unit to be able to reach the target and not be obstructed by obstacles.",
faLocationCrosshairs,
ContextActionTarget.POINT,
(units: Unit[], _, targetPosition: LatLng | null) => {
@ -686,7 +686,7 @@ export namespace ContextActions {
export const SIMULATE_FIRE_FIGHT = new ContextAction(
"simulate-fire-fight",
"Simulate fire fight",
"Simulate a fire fight by shooting randomly in a certain large area. WARNING: works correctly only on neutral units, blue or red units will aim",
"Click on a point to simulate a fire fight by shooting randomly in that general direction. WARNING: works correctly only on neutral units, blue or red units will aim",
olButtonsContextSimulateFireFight,
ContextActionTarget.POINT,
(units: Unit[], _, targetPosition: LatLng | null) => {
@ -701,7 +701,7 @@ export namespace ContextActions {
export const SET_AWACS_REFERENCE = new ContextAction(
"set-awacs-reference",
"Set AWACS reference",
"Set unit as AWACS reference",
"Set unit as AWACS reference. BRAA indicators will be shown next to Air unit markers.",
faWifi,
ContextActionTarget.NONE,
(units: Unit[], _1, _2) => {
@ -713,7 +713,7 @@ export namespace ContextActions {
export const CLONE = new ContextAction(
"clone",
"Clone unit",
"Clone the unit at the given location",
"Click on a point to clone the units there.",
faClone,
ContextActionTarget.POINT,
(units: Unit[], _1, targetPosition) => {

View File

@ -2,7 +2,6 @@ import { getApp } from "../olympusapp";
import { Coalition } from "../types/types";
import { Unit } from "../unit/unit";
import { bearing, coalitionToEnum, computeBearingRangeString, mToFt, rad2deg } from "../other/utils";
import { TextToSpeechSource } from "../audio/texttospeechsource";
const trackStrings = ["North", "North-East", "East", "South-East", "South", "South-West", "West", "North-West", "North"];
const relTrackStrings = ["hot", "flank right", "beam right", "cold", "cold", "cold", "beam left", "flank left", "hot"];
@ -49,7 +48,7 @@ export class AWACSController {
else if (idx == 2) order = "rd";
let trackDegs =
bearing(group[0].getPosition().lat, group[0].getPosition().lng, referenceUnit.getPosition().lat, referenceUnit.getPosition().lng) -
bearing(group[0].getPosition().lat, group[0].getPosition().lng, referenceUnit.getPosition().lat, referenceUnit.getPosition().lng, true) -
rad2deg(group[0].getTrack());
if (trackDegs < 0) trackDegs += 360;
if (trackDegs > 360) trackDegs -= 360;

View File

@ -243,7 +243,7 @@ export class Map extends L.Map {
}, 500); // DCS does not always apply the altitude correctly at the first set when changing map type
}
if (options.AWACSMode && this.#layerName !== "AWACS") this.setLayerName("AWACS");
//TODO if (options.AWACSMode && this.#layerName !== "AWACS") this.setLayerName("AWACS");
this.updateMinimap();
});

View File

@ -29,7 +29,7 @@
filter: drop-shadow(0px 2px 0px white) drop-shadow(0px -2px 0px white) drop-shadow(2px 0px 0px white) drop-shadow(-2px 0px 0px white);
}
[data-awacs-mode] .airbase-icon svg * {
[todo-todo-data-awacs-mode] .airbase-icon svg * {
fill: transparent !important;
}

View File

@ -21,6 +21,6 @@
stroke: var(--unit-background-neutral);
}
[data-awacs-mode] .bullseye-icon svg * {
[todo-todo-data-awacs-mode] .bullseye-icon svg * {
fill: transparent !important;
}

View File

@ -34,11 +34,11 @@
cursor: url("/images/cursors/simulate-fire-fight.svg"), auto !important;
}
[data-awacs-mode] .unit-short-label {
[todo-data-awacs-mode] .unit-short-label {
color: transparent !important;
}
[data-awacs-mode] [data-object|="unit"] svg {
[todo-data-awacs-mode] [data-object|="unit"] svg {
scale: 0.5;
}
@ -54,19 +54,19 @@
width: var(--unit-vvi-width);
}
[data-awacs-mode] .unit-vvi {
[todo-data-awacs-mode] .unit-vvi {
width: var(--unit-vvi-width-awacs);
}
[data-awacs-mode] [data-coalition="blue"] .unit-vvi {
[todo-data-awacs-mode] [data-coalition="blue"] .unit-vvi {
background: var(--unit-background-blue) !important;
}
[data-awacs-mode] [data-coalition="red"] .unit-vvi {
[todo-data-awacs-mode] [data-coalition="red"] .unit-vvi {
background: var(--unit-background-red) !important;
}
[data-awacs-mode] [data-coalition="neutral"] .unit-vvi {
[todo-data-awacs-mode] [data-coalition="neutral"] .unit-vvi {
background: var(--unit-background-neutral) !important;
}
@ -114,7 +114,7 @@
z-index: -1;
}
[data-awacs-mode] [data-is-selected] .unit-icon::before {
[todo-data-awacs-mode] [data-is-selected] .unit-icon::before {
display: none;
}
@ -139,34 +139,34 @@
stroke: white;
}
[data-awacs-mode] [data-coalition="blue"] .unit-icon svg {
[todo-data-awacs-mode] [data-coalition="blue"] .unit-icon svg {
fill: transparent !important;
stroke: var(--unit-background-blue) !important;
}
[data-awacs-mode] [data-coalition="red"] .unit-icon svg {
[todo-data-awacs-mode] [data-coalition="red"] .unit-icon svg {
fill: transparent !important;
stroke: var(--unit-background-red) !important;
}
[data-awacs-mode] [data-coalition="neutral"] .unit-icon svg {
[todo-data-awacs-mode] [data-coalition="neutral"] .unit-icon svg {
fill: transparent !important;
stroke: var(--unit-background-neutral) !important;
}
[data-awacs-mode] [data-is-selected] .unit-icon svg {
[todo-data-awacs-mode] [data-is-selected] .unit-icon svg {
stroke: #ff0 !important;
}
[data-awacs-mode] [data-is-selected] .unit-vvi {
[todo-data-awacs-mode] [data-is-selected] .unit-vvi {
background-color: #ff0 !important;
}
[data-awacs-mode] [data-is-selected] .unit-summary {
[todo-data-awacs-mode] [data-is-selected] .unit-summary {
color: #ff0 !important;
}
[data-awacs-mode] [data-is-selected] .unit-summary::after {
[todo-data-awacs-mode] [data-is-selected] .unit-summary::after {
background-color: #ff0 !important;
}
@ -244,12 +244,11 @@
/*** Unit summary ***/
[data-object|="unit"] .unit-summary {
color: white;
column-gap: 6px;
display: flex;
flex-wrap: wrap;
font-size: 11px;
font-weight: bold;
justify-content: start;
align-content: center;
line-height: 12px;
pointer-events: none;
position: absolute;
@ -259,43 +258,44 @@
1px -1px 0 #000,
-1px 1px 0 #000,
1px 1px 0 #000;
width: 100px;
translate: 80px 10px;
width: 80px;
height: 45px;
translate: 60px 2px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north {
translate: 50px -45px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north-east {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north-east {
translate: 76px -32px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-east {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-east {
translate: 95px 7px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south-east {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south-east {
translate: 79px 50px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south {
translate: 50px 63px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south-west {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south-west {
translate: -68px 50px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-west {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-west {
translate: -80px 7px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north-west {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north-west {
translate: -69px -35px;
}
[data-awacs-mode] .unit-summary::after {
[todo-data-awacs-mode] .unit-summary::after {
content: " ";
background-color: white;
width: 40px;
@ -306,40 +306,40 @@
top: 30px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north::after {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north::after {
transform: rotate(90deg);
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north-east::after {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north-east::after {
transform: rotate(135deg);
translate: 2px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-east::after {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-east::after {
transform: rotate(180deg);
translate: -5px -12px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south-east::after {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south-east::after {
transform: rotate(225deg);
translate: -2px -28px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south::after {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south::after {
transform: rotate(270deg);
translate: -0px -28px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south-west::after {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-south-west::after {
transform: rotate(315deg);
translate: 90px -28px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-west::after {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-west::after {
translate: 90px -12px;
}
[data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north-west::after {
[todo-data-awacs-mode] [data-object|="unit"] .unit-summary.cluster-north-west::after {
transform: rotate(45deg);
translate: 90px;
}
@ -355,10 +355,10 @@
[data-object|="unit"] .unit-summary .unit-callsign {
color: white;
overflow: hidden;
text-align: right;
text-align: left;
transform-origin: right;
white-space: nowrap;
width: 80px;
width: 100%;
text-overflow: ellipsis;
}
@ -367,6 +367,14 @@
overflow: visible;
}
[data-object|="unit"] .unit-summary .unit-altitude {
width: 50%;
}
[data-object|="unit"] .unit-summary .unit-speed {
width: 50%;
}
/*** Common ***/
[data-object|="unit"]:hover .unit-ammo,
[data-object|="unit"]:hover .unit-health,
@ -552,21 +560,17 @@
.unit-bullseye,
.unit-braa {
display: none;
}
[data-awacs-mode] .unit-bullseye,
[data-awacs-mode] .unit-braa {
width: 50%;
display: inline;
}
[data-awacs-mode] [data-object|="unit"] .unit-selected-spotlight,
[data-awacs-mode] [data-object|="unit"] .unit-short-label,
[data-awacs-mode] [data-object|="unit"] .unit-state,
[data-awacs-mode] [data-object|="unit"] .unit-fuel,
[data-awacs-mode] [data-object|="unit"] .unit-health,
[data-awacs-mode] [data-object|="unit"] .unit-ammo,
[data-awacs-mode] [data-object|="unit"]:hover .unit-fuel,
[data-awacs-mode] [data-object|="unit"]:hover .unit-ammo {
[todo-data-awacs-mode] [data-object|="unit"] .unit-selected-spotlight,
[todo-data-awacs-mode] [data-object|="unit"] .unit-short-label,
[todo-data-awacs-mode] [data-object|="unit"] .unit-state,
[todo-data-awacs-mode] [data-object|="unit"] .unit-fuel,
[todo-data-awacs-mode] [data-object|="unit"] .unit-health,
[todo-data-awacs-mode] [data-object|="unit"] .unit-ammo,
[todo-data-awacs-mode] [data-object|="unit"]:hover .unit-fuel,
[todo-data-awacs-mode] [data-object|="unit"]:hover .unit-ammo {
display: none;
}

View File

@ -56,7 +56,7 @@ export class TemporaryUnitMarker extends CustomMarker {
var unitIcon = document.createElement("div");
unitIcon.classList.add("unit-icon");
var img = document.createElement("img");
img.src = `./images/units/map/${getApp().getMap().getOptions().AWACSMode ? "awacs" : "normal"}/${this.#coalition}/${blueprint.markerFile ?? blueprint.category}.svg`;
img.src = `./images/units/map/${/*TODO getApp().getMap().getOptions().AWACSMode ? "awacs" :*/ "normal"}/${this.#coalition}/${blueprint.markerFile ?? blueprint.category}.svg`;
img.onload = () => SVGInjector(img);
unitIcon.appendChild(img);
unitIcon.toggleAttribute("data-rotate-to-heading", false);

View File

@ -1,14 +1,13 @@
import { Circle, LatLng, Polygon } from "leaflet";
import * as turf from "@turf/turf";
import { UnitDatabase } from "../unit/databases/unitdatabase";
import { ROEs, emissionsCountermeasures, reactionsToThreat, states } from "../constants/constants";
import { DateAndTime, UnitBlueprint } from "../interfaces";
import { DateAndTime } from "../interfaces";
import { Converter } from "usng";
import { MGRS } from "../types/types";
import { featureCollection } from "turf";
import { getApp } from "../olympusapp";
import MagVar from "magvar";
export function bearing(lat1: number, lon1: number, lat2: number, lon2: number) {
export function bearing(lat1: number, lon1: number, lat2: number, lon2: number, magnetic = true) {
const φ1 = deg2rad(lat1); // φ, λ in radians
const φ2 = deg2rad(lat2);
const λ1 = deg2rad(lon1); // φ, λ in radians
@ -16,7 +15,8 @@ export function bearing(lat1: number, lon1: number, lat2: number, lon2: number)
const y = Math.sin(λ2 - λ1) * Math.cos(φ2);
const x = Math.cos(φ1) * Math.sin(φ2) - Math.sin(φ1) * Math.cos(φ2) * Math.cos(λ2 - λ1);
const θ = Math.atan2(y, x);
const brng = (rad2deg(θ) + 360) % 360; // in degrees
const magvar = MagVar.get(lat1, lon1);
const brng = (rad2deg(θ) - (magnetic ? magvar : 0) + 360) % 360; // in degrees
return brng;
}
@ -406,24 +406,19 @@ export function blobToBase64(blob) {
});
}
export function mode(array)
{
if(array.length == 0)
return null;
var modeMap = {};
var maxEl = array[0], maxCount = 1;
for(var i = 0; i < array.length; i++)
{
var el = array[i];
if(modeMap[el] == null)
modeMap[el] = 1;
else
modeMap[el]++;
if(modeMap[el] > maxCount)
{
maxEl = el;
maxCount = modeMap[el];
}
export function mode(array) {
if (array.length == 0) return null;
var modeMap = {};
var maxEl = array[0],
maxCount = 1;
for (var i = 0; i < array.length; i++) {
var el = array[i];
if (modeMap[el] == null) modeMap[el] = 1;
else modeMap[el]++;
if (modeMap[el] > maxCount) {
maxEl = el;
maxCount = modeMap[el];
}
return maxEl;
}
}
return maxEl;
}

View File

@ -48,13 +48,13 @@ export class ServerManager {
})
MapOptionsChangedEvent.on((mapOptions) => {
if (this.#updateMode === "normal" && mapOptions.AWACSMode) {
/* TODO if (this.#updateMode === "normal" && mapOptions.AWACSMode) {
this.#updateMode = "awacs";
this.startUpdate();
} else if (this.#updateMode === "awacs" && !mapOptions.AWACSMode) {
this.#updateMode = "normal";
this.startUpdate();
}
} */
})
}

View File

@ -3,7 +3,7 @@ import { OlLocation } from "../components/ollocation";
import { LatLng } from "leaflet";
import { FaBullseye, FaChevronDown, FaChevronUp, FaJetFighter, FaMountain } from "react-icons/fa6";
import { BullseyesDataChanged, MouseMovedEvent, SelectedUnitsChangedEvent } from "../../events";
import { bearing, mToFt } from "../../other/utils";
import { bearing, computeBearingRangeString, mToFt } from "../../other/utils";
import { Bullseye } from "../../mission/bullseye";
import { Unit } from "../../unit/unit";
@ -52,8 +52,7 @@ export function CoordinatesPanel(props: {}) {
>
<FaBullseye />
</span>{" "}
{bearing(bullseyes[2].getLatLng().lat, bullseyes[2].getLatLng().lng, latlng.lat, latlng.lng).toFixed()}° /{" "}
{(bullseyes[2].getLatLng().distanceTo(latlng) / 1852).toFixed(0)}
{computeBearingRangeString(bullseyes[2].getLatLng(), latlng)}
</div>
<div className="flex w-[50%] justify-start gap-2">
<span
@ -64,8 +63,7 @@ export function CoordinatesPanel(props: {}) {
>
<FaBullseye />
</span>
{bearing(bullseyes[1].getLatLng().lat, bullseyes[1].getLatLng().lng, latlng.lat, latlng.lng).toFixed()}° /{" "}
{(bullseyes[1].getLatLng().distanceTo(latlng) / 1852).toFixed(0)}
{computeBearingRangeString(bullseyes[1].getLatLng(), latlng)}
</div>
</div>
{selectedUnits.length == 1 && (
@ -80,8 +78,7 @@ export function CoordinatesPanel(props: {}) {
</span>
<div>
{" "}
{bearing(selectedUnits[0].getLatLng().lat, selectedUnits[0].getLatLng().lng, latlng.lat, latlng.lng).toFixed()}° /
{(selectedUnits[0].getLatLng().distanceTo(latlng) / 1852).toFixed(0)}
{computeBearingRangeString(selectedUnits[0].getPosition(), latlng)}
</div>
</div>
)}

View File

@ -39,7 +39,7 @@ export function JTACMenu(props: { open: boolean; onClose: () => void; children?:
let IPPosition = "";
if (IP && ECHO) {
let dist = Math.round(IP.distanceTo(ECHO) / 1852);
let bear = bearing(point([ECHO.lng, ECHO.lat]), point([IP.lng, IP.lat]));
let bear = bearing(point([ECHO.lng, ECHO.lat]), point([IP.lng, IP.lat])); // TODO switch to mag
IPPosition = ["A", "AB", "B", "BC", "C", "CD", "D", "DA"][Math.round((bear > 0 ? bear : bear + 360) / 45)] + String(dist);
}
@ -50,7 +50,7 @@ export function JTACMenu(props: { open: boolean; onClose: () => void; children?:
let location = targetUnit ? targetUnit.getPosition() : targetLocation;
if (location) {
IPtoTargetDist = Math.round(IP.distanceTo(location) / 1852);
IPtoTargetBear = bearing(point([IP.lng, IP.lat]), point([location.lng, location.lat]));
IPtoTargetBear = bearing(point([IP.lng, IP.lat]), point([location.lng, location.lat])); // TODO switch to mag
if (IPtoTargetBear < 0) IPtoTargetBear += 360;
IPtoTargetBear = Math.round(IPtoTargetBear);
}

View File

@ -10,6 +10,7 @@ import { OlAccordion } from "../components/olaccordion";
import { Shortcut } from "../../shortcut/shortcut";
import { OlSearchBar } from "../components/olsearchbar";
import { FaTrash, FaXmark } from "react-icons/fa6";
import { OlCoalitionToggle } from "../components/olcoalitiontoggle";
const enum Accordion {
NONE,
@ -84,81 +85,96 @@ export function OptionsMenu(props: { open: boolean; onClose: () => void; childre
>
<div
className={`
group flex flex-row rounded-md justify-content cursor-pointer
gap-4 p-2
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => getApp().getMap().setOption("showUnitLabels", !mapOptions.showUnitLabels)}
>
<OlCheckbox checked={mapOptions.showUnitLabels} onChange={() => {}}></OlCheckbox>
<span>Show Unit Labels</span>
<span className="my-auto">Show Unit Labels</span>
</div>
<div
className={`
group flex flex-row rounded-md justify-content cursor-pointer
gap-4 p-2
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => getApp().getMap().setOption("showUnitsEngagementRings", !mapOptions.showUnitsEngagementRings)}
>
<OlCheckbox checked={mapOptions.showUnitsEngagementRings} onChange={() => {}}></OlCheckbox>
<span>Show Threat Rings</span>
<span className="my-auto">Show Threat Rings</span>
</div>
<div
className={`
group flex flex-row rounded-md justify-content cursor-pointer
gap-4 p-2
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => getApp().getMap().setOption("showUnitsAcquisitionRings", !mapOptions.showUnitsAcquisitionRings)}
>
<OlCheckbox checked={mapOptions.showUnitsAcquisitionRings} onChange={() => {}}></OlCheckbox>
<span>Show Detection rings</span>
<span className="my-auto">Show Detection rings</span>
</div>
<div
className={`
group flex flex-row rounded-md justify-content cursor-pointer
gap-4 p-2
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => getApp().getMap().setOption("showUnitTargets", !mapOptions.showUnitTargets)}
>
<OlCheckbox checked={mapOptions.showUnitTargets} onChange={() => {}}></OlCheckbox>
<span>Show Detection lines</span>
<span className="my-auto">Show Detection lines</span>
</div>
<div
className={`
group flex flex-row gap-4 rounded-md justify-content
cursor-pointer p-2
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => getApp().getMap().setOption("hideUnitsShortRangeRings", !mapOptions.hideUnitsShortRangeRings)}
>
<OlCheckbox checked={mapOptions.hideUnitsShortRangeRings} onChange={() => {}}></OlCheckbox>
<span>Hide Short range Rings</span>
<span className="my-auto">Hide Short range Rings</span>
</div>
<div
className={`
group flex flex-row gap-4 rounded-md justify-content
cursor-pointer p-2
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => getApp().getMap().setOption("hideGroupMembers", !mapOptions.hideGroupMembers)}
>
<OlCheckbox checked={mapOptions.hideGroupMembers} onChange={() => {}}></OlCheckbox>
<span>Hide Group members</span>
<span className="my-auto">Hide Group members</span>
</div>
<div
className={`
group flex flex-row gap-4 rounded-md justify-content
cursor-pointer p-2
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => getApp().getMap().setOption("showMinimap", !mapOptions.showMinimap)}
>
<OlCheckbox checked={mapOptions.showMinimap} onChange={() => {}}></OlCheckbox>
<span>Show minimap</span>
<span className="my-auto">Show minimap</span>
</div>
<div
className={`
group flex cursor-pointer flex-row content-center justify-start
gap-4 rounded-md p-2
dark:hover:bg-olympus-400
`}
onClick={() => {
mapOptions.AWACSCoalition === "blue" && getApp().getMap().setOption("AWACSCoalition", "neutral");
mapOptions.AWACSCoalition === "neutral" && getApp().getMap().setOption("AWACSCoalition", "red");
mapOptions.AWACSCoalition === "red" && getApp().getMap().setOption("AWACSCoalition", "blue");
}}
>
<OlCoalitionToggle onClick={() => {}} coalition={mapOptions.AWACSCoalition} />
<span className="my-auto">Coalition of unit bullseye info</span>
</div>
</OlAccordion>

View File

@ -77,7 +77,7 @@ export function SideBar() {
checked={appState === OlympusState.JTAC}
icon={faJ}
tooltip="Hide/show JTAC menu"
></OlStateButton>{*/}
></OlStateButton>
<OlStateButton
onClick={() => {
getApp().setState(appState !== OlympusState.AWACS ? OlympusState.AWACS : OlympusState.IDLE);
@ -86,7 +86,7 @@ export function SideBar() {
icon={faA}
tooltip="Hide/show AWACS menu"
tooltipPosition="side"
></OlStateButton>
></OlStateButton>{*/}
<OlStateButton
onClick={() => {
getApp().setState(appState !== OlympusState.GAME_MASTER ? OlympusState.GAME_MASTER : OlympusState.IDLE);

View File

@ -97,8 +97,8 @@ export function UI() {
open={appState === OlympusState.UNIT_CONTROL && appSubState === UnitControlSubState.UNIT_EXPLOSION_MENU}
onClose={() => getApp().setState(OlympusState.IDLE)}
/>
{/*}<JTACMenu open={appState === OlympusState.JTAC} onClose={() => getApp().setState(OlympusState.IDLE)} />{*/}
<AWACSMenu open={appState === OlympusState.AWACS} onClose={() => getApp().setState(OlympusState.IDLE)} />
{/*}<JTACMenu open={appState === OlympusState.JTAC} onClose={() => getApp().setState(OlympusState.IDLE)} />
<AWACSMenu open={appState === OlympusState.AWACS} onClose={() => getApp().setState(OlympusState.IDLE)} />{*/}
<MiniMapPanel />
<ControlsPanel />

View File

@ -912,7 +912,7 @@ export abstract class Unit extends CustomMarker {
if (this.belongsToCommandedCoalition() || this.getDetectionMethods().some((value) => [VISUAL, OPTIC].includes(value)))
marker = this.getBlueprint()?.markerFile ?? this.getDefaultMarker();
else marker = "aircraft";
img.src = `./images/units/map/${getApp().getMap().getOptions().AWACSMode ? "awacs" : "normal"}/${this.getCoalition()}/${marker}.svg`;
img.src = `./images/units/map/${/*TODO getApp().getMap().getOptions().AWACSMode ? "awacs" : */"normal"}/${this.getCoalition()}/${marker}.svg`;
img.onload = () => SVGInjector(img);
unitIcon.appendChild(img);
@ -1567,7 +1567,8 @@ export abstract class Unit extends CustomMarker {
clusterMean.geometry.coordinates[1],
clusterMean.geometry.coordinates[0],
this.getPosition().lat,
this.getPosition().lng
this.getPosition().lng,
false
);
if (bearingFromCluster < 0) bearingFromCluster += 360;
@ -1581,7 +1582,7 @@ export abstract class Unit extends CustomMarker {
}
/* Draw the contact trail */
if (getApp().getMap().getOptions().AWACSMode) {
if (/*TODO getApp().getMap().getOptions().AWACSMode*/ false) {
this.#trailPolylines = this.#trailPositions.map(
(latlng, idx) => new Polyline([latlng, latlng], { color: "#FFFFFF", opacity: 1 - (idx + 1) / TRAIL_LENGTH })
);
@ -1668,7 +1669,7 @@ export abstract class Unit extends CustomMarker {
var startLatLng = new LatLng(this.#position.lat, this.#position.lng);
var endLatLng: LatLng;
if (contactData.detectionMethod === RWR) {
var bearingToContact = bearing(this.#position.lat, this.#position.lng, contact.getPosition().lat, contact.getPosition().lng);
var bearingToContact = bearing(this.#position.lat, this.#position.lng, contact.getPosition().lat, contact.getPosition().lng, false);
var startXY = getApp().getMap().latLngToContainerPoint(startLatLng);
var endX = startXY.x + 80 * Math.sin(deg2rad(bearingToContact));
var endY = startXY.y - 80 * Math.cos(deg2rad(bearingToContact));
@ -1860,7 +1861,7 @@ export abstract class AirUnit extends Unit {
showFuel: belongsToCommandedCoalition,
showAmmo: belongsToCommandedCoalition,
showSummary: belongsToCommandedCoalition || this.getDetectionMethods().some((value) => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value)),
showCallsign: belongsToCommandedCoalition && (!getApp().getMap().getOptions().AWACSMode || this.getHuman()),
showCallsign: belongsToCommandedCoalition && (/*TODO !getApp().getMap().getOptions().AWACSMode || */ this.getHuman()),
rotateToHeading: false,
} as ObjectIconOptions;
}
@ -1947,7 +1948,7 @@ export class GroundUnit extends Unit {
showFuel: false,
showAmmo: false,
showSummary: false,
showCallsign: belongsToCommandedCoalition && (!getApp().getMap().getOptions().AWACSMode || this.getHuman()),
showCallsign: belongsToCommandedCoalition && (/*TODO !getApp().getMap().getOptions().AWACSMode || */ this.getHuman()),
rotateToHeading: false,
} as ObjectIconOptions;
}
@ -2012,7 +2013,7 @@ export class NavyUnit extends Unit {
showFuel: false,
showAmmo: false,
showSummary: false,
showCallsign: belongsToCommandedCoalition && (!getApp().getMap().getOptions().AWACSMode || this.getHuman()),
showCallsign: belongsToCommandedCoalition && (/*TODO !getApp().getMap().getOptions().AWACSMode || */ this.getHuman()),
rotateToHeading: false,
} as ObjectIconOptions;
}

View File

@ -178,7 +178,7 @@ export class Weapon extends CustomMarker {
var unitIcon = document.createElement("div");
unitIcon.classList.add("unit-icon");
var img = document.createElement("img");
img.src = `./images/units/map/${getApp().getMap().getOptions().AWACSMode ? "awacs" : "normal"}/${this.getCoalition()}/${this.getMarkerCategory()}.svg`;
img.src = `./images/units/map/${/*TODO getApp().getMap().getOptions().AWACSMode ? "awacs" :*/ "normal"}/${this.getCoalition()}/${this.getMarkerCategory()}.svg`;
img.onload = () => SVGInjector(img);
unitIcon.appendChild(img);
unitIcon.toggleAttribute("data-rotate-to-heading", this.getIconOptions().rotateToHeading);

View File

@ -22,7 +22,7 @@ module.exports = function () {
res.send(response[0].audioContent);
res.end()
}
).catch((error) => res.sendStatus(400));
).catch((error) => res.sendStatus(404));
});
router.put("/recognize", (req, res, next) => {
@ -46,7 +46,7 @@ module.exports = function () {
.map((result) => result.alternatives[0].transcript)
.join("\n");
res.send(transcription)
}).catch((error) => res.sendStatus(400));
}).catch((error) => res.sendStatus(404));
});
return router;

View File

@ -138,7 +138,7 @@ module.exports = function (configLocation) {
sessionData = {};
res.sendStatus(404);
} else {
res.send(sessionData[req.params.profileName]);
res.send(sessionData[req.params.profileName] ?? {});
res.end();
}
});