mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
fix: magvar used for BE calls
fix: unit summary labels
This commit is contained in:
parent
89abcb3330
commit
8006d639ae
@ -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",
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
});
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
} */
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -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>
|
||||
)}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 />
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user