mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
commit
2805323cfa
@ -15,7 +15,7 @@ const DEMO_UNIT_DATA = {
|
||||
radio: { frequency: 124000000, callsign: 1, callsignNumber: 1 },
|
||||
generalSettings: { prohibitAA: false, prohibitAfterburner: false, prohibitAG: false, prohibitAirWpn: false, prohibitJettison: false },
|
||||
ammo: [{ quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 }, { quantity: 2, name: "A cool missile with a longer name\0Ciao", guidance: 0, category: 0, missileCategory: 0 }, { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } , { quantity: 2, name: "A cool missile\0Ciao", guidance: 0, category: 0, missileCategory: 0 } ],
|
||||
contacts: [{ID: 2, detectionMethod: 1}, {ID: 3, detectionMethod: 4}, {ID: 5, detectionMethod: 4}],
|
||||
contacts: [{ID: 2, detectionMethod: 1}, {ID: 3, detectionMethod: 4}, {ID: 4, detectionMethod: 1}],
|
||||
activePath: [{lat: 38, lng: -115, alt: 0}, {lat: 38, lng: -114, alt: 0}]
|
||||
},
|
||||
["2"]:{ category: "Aircraft", alive: true, human: false, controlled: false, coalition: 1, country: 0, name: "B-52H", unitName: "Cool guy 1-2", groupName: "Cool group 2", state: 1, task: "Being cool",
|
||||
@ -31,7 +31,7 @@ const DEMO_UNIT_DATA = {
|
||||
radio: { frequency: 124000000, callsign: 1, callsignNumber: 1 },
|
||||
generalSettings: { prohibitAA: false, prohibitAfterburner: false, prohibitAG: false, prohibitAirWpn: false, prohibitJettison: false },
|
||||
ammo: [{ quantity: 2, name: "A cool missile", guidance: 0, category: 0, missileCategory: 0 } ],
|
||||
contacts: [{ID: 1, detectionMethod: 16}],
|
||||
contacts: [{ID: 4, detectionMethod: 1}],
|
||||
activePath: [ ]
|
||||
}, ["3"]:{ category: "Helicopter", alive: true, human: false, controlled: false, coalition: 1, country: 0, name: "AH-64D_BLK_II", unitName: "Cool guy 1-4", groupName: "Cool group 3", state: 1, task: "Being cool",
|
||||
hasTask: false, position: { lat: 37.1, lng: -116.1, alt: 1000 }, speed: 200, heading: 315 * Math.PI / 180, isTanker: false, isAWACS: false, onOff: true, followRoads: false, fuel: 50,
|
||||
@ -48,7 +48,7 @@ const DEMO_UNIT_DATA = {
|
||||
ammo: [{ quantity: 2, name: "A cool missile", guidance: 0, category: 0, missileCategory: 0 } ],
|
||||
contacts: [{ID: 1, detectionMethod: 16}],
|
||||
activePath: [ ]
|
||||
}, ["4"]:{ category: "GroundUnit", alive: true, human: false, controlled: true, coalition: 0, country: 0, name: "Gepard", unitName: "Cool guy 2-1", groupName: "Cool group 4", state: 1, task: "Being cool",
|
||||
}, ["4"]:{ category: "GroundUnit", alive: true, human: false, controlled: true, coalition: 2, country: 0, name: "Tor 9A331", unitName: "Cool guy 2-1", groupName: "Cool group 4", state: 1, task: "Being cool",
|
||||
hasTask: false, position: { lat: 37.2, lng: -116.1, alt: 1000 }, speed: 200, heading: 315 * Math.PI / 180, isTanker: false, isAWACS: false, onOff: true, followRoads: false, fuel: 50,
|
||||
desiredSpeed: 300, desiredSpeedType: 1, desiredAltitude: 1000, desiredAltitudeType: 1, leaderID: 0,
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
@ -65,7 +65,7 @@ const DEMO_UNIT_DATA = {
|
||||
activePath: [ ],
|
||||
isLeader: true,
|
||||
operateAs: 2
|
||||
}, ["5"]:{ category: "GroundUnit", alive: true, human: false, controlled: true, coalition: 0, country: 0, name: "Gepard", unitName: "Cool guy 2-2", groupName: "Cool group 4", state: 1, task: "Being cool",
|
||||
}, ["5"]:{ category: "GroundUnit", alive: true, human: false, controlled: true, coalition: 2, country: 0, name: "Gepard", unitName: "Cool guy 2-2", groupName: "Cool group 4", state: 1, task: "Being cool",
|
||||
hasTask: false, position: { lat: 37.21, lng: -116.1, alt: 1000 }, speed: 200, heading: 315 * Math.PI / 180, isTanker: false, isAWACS: false, onOff: true, followRoads: false, fuel: 50,
|
||||
desiredSpeed: 300, desiredSpeedType: 1, desiredAltitude: 1000, desiredAltitudeType: 1, leaderID: 0,
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
@ -98,7 +98,7 @@ const DEMO_UNIT_DATA = {
|
||||
ammo: [{ quantity: 2, name: "A cool missile", guidance: 0, category: 0, missileCategory: 0 } ],
|
||||
contacts: [{ID: 1, detectionMethod: 16}],
|
||||
activePath: [ ]
|
||||
}, ["7"]:{ category: "GroundUnit", alive: true, human: false, controlled: true, coalition: 1, country: 0, name: "T-55", unitName: "Cool guy 2-1", groupName: "Cool group 10", state: 1, task: "Being cool",
|
||||
}, ["7"]:{ category: "GroundUnit", alive: true, human: false, controlled: true, coalition: 1, country: 0, name: "Tor 9A331", unitName: "Cool guy 2-1", groupName: "Cool group 10", state: 1, task: "Being cool",
|
||||
hasTask: false, position: { lat: 37.2, lng: -116.2, alt: 1000 }, speed: 200, heading: 315 * Math.PI / 180, isTanker: false, isAWACS: false, onOff: true, followRoads: false, fuel: 50,
|
||||
desiredSpeed: 300, desiredSpeedType: 1, desiredAltitude: 1000, desiredAltitudeType: 1, leaderID: 0,
|
||||
formationOffset: { x: 0, y: 0, z: 0 },
|
||||
|
||||
@ -58,7 +58,7 @@ export class ControlTipsPlugin implements OlympusPlugin {
|
||||
this.#updateTips();
|
||||
});
|
||||
|
||||
document.addEventListener("unitSelection", (ev: CustomEventInit ) => {
|
||||
document.addEventListener("unitsSelection", (ev: CustomEventInit ) => {
|
||||
this.#updateTips();
|
||||
});
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -34,8 +34,8 @@ export class GroundUnitEditor extends UnitEditor {
|
||||
addDropdownInput(this.contentDiv2, "Era", blueprint.era, ["WW2", "Early Cold War", "Mid Cold War", "Late Cold War", "Modern"]);
|
||||
//addStringInput(this.contentDiv2, "Filename", blueprint.filename?? "", "text", (value: string) => {blueprint.filename = value; });
|
||||
addStringInput(this.contentDiv2, "Cost", String(blueprint.cost)?? "", "number", (value: string) => {blueprint.cost = parseFloat(value); });
|
||||
addStringInput(this.contentDiv2, "Acquisition range [NM]", String(blueprint.acquisitionRange)?? "", "number", (value: string) => {blueprint.acquisitionRange = parseFloat(value); });
|
||||
addStringInput(this.contentDiv2, "Engagement range [NM]", String(blueprint.engagementRange)?? "", "number", (value: string) => {blueprint.engagementRange = parseFloat(value); });
|
||||
addStringInput(this.contentDiv2, "Acquisition range [m]", String(blueprint.acquisitionRange)?? "", "number", (value: string) => {blueprint.acquisitionRange = parseFloat(value); });
|
||||
addStringInput(this.contentDiv2, "Engagement range [m]", String(blueprint.engagementRange)?? "", "number", (value: string) => {blueprint.engagementRange = parseFloat(value); });
|
||||
addStringInput(this.contentDiv2, "Barrel height [m]", String(blueprint.barrelHeight)?? "", "number", (value: string) => {blueprint.barrelHeight = parseFloat(value); });
|
||||
addStringInput(this.contentDiv2, "Muzzle velocity [m/s]", String(blueprint.muzzleVelocity)?? "", "number", (value: string) => {blueprint.muzzleVelocity = parseFloat(value); });
|
||||
addStringInput(this.contentDiv2, "Aim time [s]", String(blueprint.aimTime)?? "", "number", (value: string) => {blueprint.aimTime = parseFloat(value); });
|
||||
|
||||
@ -68,6 +68,7 @@ export function addLoadoutItemsEditor(div: HTMLElement, loadout: LoadoutBlueprin
|
||||
itemsEl.classList.add("dm-scroll-container", "dm-items-container");
|
||||
|
||||
/* Create a row for each loadout item to allow and change the name and quantity of the item itself */
|
||||
loadout.items.sort((a: LoadoutItemBlueprint, b: LoadoutItemBlueprint) => a.name.localeCompare(b.name, undefined, {sensitivity: 'base'}));
|
||||
loadout.items.forEach((item: LoadoutItemBlueprint, index: number) => {
|
||||
var rowDiv = document.createElement("div");
|
||||
|
||||
@ -154,7 +155,7 @@ export function addBlueprintsScroll(div: HTMLElement, database: {blueprints: {[k
|
||||
if (database !== null) {
|
||||
var blueprints: {[key: string]: UnitBlueprint} = database.blueprints;
|
||||
|
||||
for (let key in blueprints) {
|
||||
for (let key of Object.keys(blueprints).sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))) {
|
||||
var rowDiv = document.createElement("div");
|
||||
scrollDiv.appendChild(rowDiv);
|
||||
|
||||
@ -186,6 +187,7 @@ export function addLoadoutsScroll(div: HTMLElement, loadouts: LoadoutBlueprint[]
|
||||
var loadoutsEl = document.createElement("div");
|
||||
loadoutsEl.classList.add("dm-scroll-container", "dm-loadout-container")
|
||||
|
||||
loadouts.sort((a: LoadoutBlueprint, b: LoadoutBlueprint) => a.name.localeCompare(b.name, undefined, {sensitivity: 'base'}));
|
||||
loadouts.forEach((loadout: LoadoutBlueprint, index: number) => {
|
||||
var rowDiv = document.createElement("div");
|
||||
loadoutsEl.appendChild(rowDiv);
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
}
|
||||
|
||||
.dm-content-container:nth-of-type(1) {
|
||||
width: 200px;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.dm-content-container:nth-of-type(2) {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"name": "A-10C_2",
|
||||
"coalition": "blue",
|
||||
"era": "Late Cold War",
|
||||
"label": "A-10C Warthog test",
|
||||
"label": "A-10C Warthog",
|
||||
"shortLabel": "10",
|
||||
"loadouts": [
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -144,18 +144,21 @@ export const mapLayers = {
|
||||
export const IDLE = "Idle";
|
||||
export const MOVE_UNIT = "Move unit";
|
||||
export const COALITIONAREA_DRAW_POLYGON = "Draw Coalition Area";
|
||||
export const visibilityControls: string[] = ["human", "dcs", "aircraft", "groundunit-sam", "groundunit-other", "navyunit", "airbase"];
|
||||
export const visibilityControlsTypes: string[][] = [["human"], ["dcs"], ["aircraft"], ["groundunit-sam", "groundunit-sam-radar", "groundunit-sam-launcher"], ["groundunit-other", "groundunit-ewr"], ["navyunit"], ["airbase"]];
|
||||
export const visibilityControlsTooltips: string[] = ["Toggle human players visibility", "Toggle DCS controlled units visibility", "Toggle aircrafts visibility", "Toggle SAM units visibility", "Toggle ground units (not SAM) visibility", "Toggle navy units visibility", "Toggle airbases visibility"];
|
||||
export const visibilityControls: string[] = ["human", "dcs", "aircraft", "helicopter", "groundunit-sam", "groundunit-other", "navyunit", "airbase"];
|
||||
export const visibilityControlsTypes: string[][] = [["human"], ["dcs"], ["aircraft"], ["helicopter"], ["groundunit-sam", "groundunit-sam-radar", "groundunit-sam-launcher"], ["groundunit-other", "groundunit-ewr"], ["navyunit"], ["airbase"]];
|
||||
export const visibilityControlsTooltips: string[] = ["Toggle human players visibility", "Toggle DCS controlled units visibility", "Toggle aircrafts visibility", "Toggle helicopter visibility", "Toggle SAM units visibility", "Toggle ground units (not SAM) visibility", "Toggle navy units visibility", "Toggle airbases visibility"];
|
||||
|
||||
export const IADSTypes = ["AAA", "MANPADS", "SAM Site", "Radar"];
|
||||
export const IADSDensities: {[key: string]: number}= {"AAA": 0.8, "MANPADS": 0.3, "SAM Site": 0.1, "Radar": 0.05};
|
||||
|
||||
export const SHOW_CONTACT_LINES = "Show unit contact lines";
|
||||
export const HIDE_GROUP_MEMBERS = "Hide group members when zoomed out";
|
||||
export const SHOW_UNIT_LABELS = "Show unit labels";
|
||||
export const SHOW_UNIT_PATHS = "Show unit paths";
|
||||
export const SHOW_UNIT_TARGETS = "Show unit targets";
|
||||
export const HIDE_GROUP_MEMBERS = "Hide group members when zoomed out";
|
||||
export const SHOW_UNIT_LABELS = "Show unit labels (L)";
|
||||
export const SHOW_UNITS_ENGAGEMENT_RINGS = "Show units threat range rings (Q)";
|
||||
export const HIDE_UNITS_SHORT_RANGE_RINGS = "Hide short range units threat range rings (R)";
|
||||
export const SHOW_UNITS_ACQUISITION_RINGS = "Show units detection range rings (E)";
|
||||
export const SHOW_UNIT_CONTACTS = "Show selected units contact lines";
|
||||
export const SHOW_UNIT_PATHS = "Show selected unit paths";
|
||||
export const SHOW_UNIT_TARGETS = "Show selected unit targets";
|
||||
|
||||
export enum DataIndexes {
|
||||
startOfData = 0,
|
||||
|
||||
@ -29,6 +29,7 @@ export class ContextMenu {
|
||||
this.#x = x;
|
||||
this.#y = y;
|
||||
this.clip();
|
||||
this.getContainer()?.dispatchEvent(new Event("show"));
|
||||
}
|
||||
|
||||
/** Hide the contextmenu
|
||||
@ -36,6 +37,7 @@ export class ContextMenu {
|
||||
*/
|
||||
hide() {
|
||||
this.#container?.classList.toggle("hide", true);
|
||||
this.getContainer()?.dispatchEvent(new Event("hide"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -79,7 +79,15 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.#groundUnitSpawnMenu.getContainer().addEventListener("hide", () => this.hide());
|
||||
this.#navyUnitSpawnMenu.getContainer().addEventListener("hide", () => this.hide());
|
||||
|
||||
this.hide();
|
||||
this.getContainer()?.addEventListener("show", () => this.#aircraftSpawnMenu.showCirclesPreviews());
|
||||
this.getContainer()?.addEventListener("show", () => this.#helicopterSpawnMenu.showCirclesPreviews());
|
||||
this.getContainer()?.addEventListener("show", () => this.#groundUnitSpawnMenu.showCirclesPreviews());
|
||||
this.getContainer()?.addEventListener("show", () => this.#navyUnitSpawnMenu.showCirclesPreviews());
|
||||
|
||||
this.getContainer()?.addEventListener("hide", () => this.#aircraftSpawnMenu.clearCirclesPreviews());
|
||||
this.getContainer()?.addEventListener("hide", () => this.#helicopterSpawnMenu.clearCirclesPreviews());
|
||||
this.getContainer()?.addEventListener("hide", () => this.#groundUnitSpawnMenu.clearCirclesPreviews());
|
||||
this.getContainer()?.addEventListener("hide", () => this.#navyUnitSpawnMenu.clearCirclesPreviews());
|
||||
}
|
||||
|
||||
/** Show the contextmenu on top of the map, usually at the location where the user has clicked on it.
|
||||
@ -189,6 +197,11 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.#groundUnitSpawnMenu.reset();
|
||||
this.#navyUnitSpawnMenu.reset();
|
||||
|
||||
this.#aircraftSpawnMenu.clearCirclesPreviews();
|
||||
this.#helicopterSpawnMenu.clearCirclesPreviews();
|
||||
this.#groundUnitSpawnMenu.clearCirclesPreviews();
|
||||
this.#navyUnitSpawnMenu.clearCirclesPreviews();
|
||||
|
||||
this.setVisibleSubMenu(null);
|
||||
this.clip();
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { LatLng } from "leaflet";
|
||||
import { Circle, LatLng } from "leaflet";
|
||||
import { Dropdown } from "./dropdown";
|
||||
import { Slider } from "./slider";
|
||||
import { UnitDatabase } from "../unit/databases/unitdatabase";
|
||||
@ -45,6 +45,10 @@ export class UnitSpawnMenu {
|
||||
#unitImageEl: HTMLImageElement;
|
||||
#unitLoadoutListEl: HTMLDivElement;
|
||||
|
||||
/* Range circle previews */
|
||||
#engagementCircle: Circle;
|
||||
#acquisitionCircle: Circle;
|
||||
|
||||
constructor(ID: string, unitDatabase: UnitDatabase, orderByRole: boolean) {
|
||||
this.#container = document.getElementById(ID) as HTMLElement;
|
||||
this.#unitDatabase = unitDatabase;
|
||||
@ -154,6 +158,8 @@ export class UnitSpawnMenu {
|
||||
|
||||
this.#container.dispatchEvent(new Event("resize"));
|
||||
this.#computeSpawnPoints();
|
||||
|
||||
this.showCirclesPreviews();
|
||||
})
|
||||
|
||||
this.#container.addEventListener("unitLoadoutChanged", () => {
|
||||
@ -183,6 +189,13 @@ export class UnitSpawnMenu {
|
||||
this.#container.addEventListener("unitLiveryChanged", () => {
|
||||
|
||||
})
|
||||
|
||||
document.addEventListener('activeCoalitionChanged', () => {
|
||||
this.showCirclesPreviews();
|
||||
});
|
||||
|
||||
this.#engagementCircle = new Circle(this.spawnOptions.latlng, { radius: 0, weight: 4, opacity: 0.8, fillOpacity: 0, dashArray: "4 8" });
|
||||
this.#acquisitionCircle = new Circle(this.spawnOptions.latlng, { radius: 0, weight: 2, opacity: 0.8, fillOpacity: 0, dashArray: "8 12" });
|
||||
}
|
||||
|
||||
getContainer() {
|
||||
@ -205,6 +218,8 @@ export class UnitSpawnMenu {
|
||||
|
||||
this.setCountries();
|
||||
this.#container.dispatchEvent(new Event("resize"));
|
||||
|
||||
this.clearCirclesPreviews();
|
||||
}
|
||||
|
||||
setCountries() {
|
||||
@ -225,12 +240,61 @@ export class UnitSpawnMenu {
|
||||
// this.resetUnitLabel();
|
||||
}
|
||||
|
||||
showCirclesPreviews() {
|
||||
this.clearCirclesPreviews();
|
||||
|
||||
var acquisitionRange = this.#unitDatabase.getByName(this.spawnOptions.name)?.acquisitionRange ?? 0;
|
||||
var engagementRange = this.#unitDatabase.getByName(this.spawnOptions.name)?.engagementRange ?? 0;
|
||||
|
||||
this.#acquisitionCircle.setRadius(acquisitionRange);
|
||||
this.#engagementCircle.setRadius(engagementRange);
|
||||
this.#acquisitionCircle.setLatLng(this.spawnOptions.latlng);
|
||||
this.#engagementCircle.setLatLng(this.spawnOptions.latlng);
|
||||
|
||||
switch (getApp().getActiveCoalition()) {
|
||||
case "red":
|
||||
this.#acquisitionCircle.options.color = "#D42121";
|
||||
break;
|
||||
case "blue":
|
||||
this.#acquisitionCircle.options.color = "#017DC1";
|
||||
break;
|
||||
default:
|
||||
this.#acquisitionCircle.options.color = "#111111"
|
||||
break;
|
||||
}
|
||||
|
||||
switch (getApp().getActiveCoalition()) {
|
||||
case "red":
|
||||
this.#engagementCircle.options.color = "#FF5858";
|
||||
break;
|
||||
case "blue":
|
||||
this.#engagementCircle.options.color = "#3BB9FF";
|
||||
break;
|
||||
default:
|
||||
this.#engagementCircle.options.color = "#CFD9E8"
|
||||
break;
|
||||
}
|
||||
|
||||
if (engagementRange > 0)
|
||||
this.#engagementCircle.addTo(getApp().getMap());
|
||||
|
||||
if (acquisitionRange > 0)
|
||||
this.#acquisitionCircle.addTo(getApp().getMap());
|
||||
}
|
||||
|
||||
clearCirclesPreviews() {
|
||||
this.#engagementCircle.removeFrom(getApp().getMap());
|
||||
this.#acquisitionCircle.removeFrom(getApp().getMap());
|
||||
}
|
||||
|
||||
setAirbase(airbase: Airbase | undefined) {
|
||||
this.spawnOptions.airbase = airbase;
|
||||
}
|
||||
|
||||
setLatLng(latlng: LatLng) {
|
||||
this.spawnOptions.latlng = latlng;
|
||||
|
||||
this.showCirclesPreviews();
|
||||
}
|
||||
|
||||
setMaxUnitCount(maxUnitCount: number) {
|
||||
|
||||
1
client/src/dom.d.ts
vendored
1
client/src/dom.d.ts
vendored
@ -21,6 +21,7 @@ interface CustomEventMap {
|
||||
"mapVisibilityOptionsChanged": CustomEvent<>,
|
||||
"commandModeOptionsChanged": CustomEvent<>,
|
||||
"contactsUpdated": CustomEvent<Unit>,
|
||||
"activeCoalitionChanged": CustomEvent<>
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@ -12,7 +12,7 @@ import { DestinationPreviewMarker } from "./markers/destinationpreviewmarker";
|
||||
import { TemporaryUnitMarker } from "./markers/temporaryunitmarker";
|
||||
import { ClickableMiniMap } from "./clickableminimap";
|
||||
import { SVGInjector } from '@tanem/svg-injector'
|
||||
import { mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants";
|
||||
import { mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_UNIT_CONTACTS, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS } from "../constants/constants";
|
||||
import { TargetMarker } from "./markers/targetmarker";
|
||||
import { CoalitionArea } from "./coalitionarea/coalitionarea";
|
||||
import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu";
|
||||
@ -209,11 +209,14 @@ export class Map extends L.Map {
|
||||
document.querySelector("#unit-visibility-control")?.append(...this.#optionButtons["visibility"]);
|
||||
|
||||
/* Create the checkboxes to select the advanced visibility options */
|
||||
this.addVisibilityOption(SHOW_CONTACT_LINES, false);
|
||||
this.addVisibilityOption(SHOW_UNIT_CONTACTS, false);
|
||||
this.addVisibilityOption(HIDE_GROUP_MEMBERS, true);
|
||||
this.addVisibilityOption(SHOW_UNIT_PATHS, true);
|
||||
this.addVisibilityOption(SHOW_UNIT_TARGETS, true);
|
||||
this.addVisibilityOption(SHOW_UNIT_LABELS, true);
|
||||
this.addVisibilityOption(SHOW_UNITS_ENGAGEMENT_RINGS, true);
|
||||
this.addVisibilityOption(SHOW_UNITS_ACQUISITION_RINGS, true);
|
||||
this.addVisibilityOption(HIDE_UNITS_SHORT_RANGE_RINGS, true);
|
||||
}
|
||||
|
||||
addVisibilityOption(option: string, defaultValue: boolean) {
|
||||
@ -528,39 +531,38 @@ export class Map extends L.Map {
|
||||
}
|
||||
|
||||
this.hideMapContextMenu();
|
||||
if (!this.#shiftKey) {
|
||||
if (this.#state === IDLE) {
|
||||
if (this.#state == IDLE) {
|
||||
this.showMapContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng);
|
||||
var clickedCoalitionArea = null;
|
||||
if (this.#state === IDLE) {
|
||||
if (this.#state == IDLE) {
|
||||
this.showMapContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng);
|
||||
var clickedCoalitionArea = null;
|
||||
|
||||
/* Coalition areas are ordered in the #coalitionAreas array according to their zindex. Select the upper one */
|
||||
for (let coalitionArea of this.#coalitionAreas) {
|
||||
if (coalitionArea.getBounds().contains(e.latlng)) {
|
||||
if (coalitionArea.getSelected())
|
||||
clickedCoalitionArea = coalitionArea;
|
||||
else
|
||||
this.getMapContextMenu().setCoalitionArea(coalitionArea);
|
||||
}
|
||||
/* Coalition areas are ordered in the #coalitionAreas array according to their zindex. Select the upper one */
|
||||
for (let coalitionArea of this.#coalitionAreas) {
|
||||
if (coalitionArea.getBounds().contains(e.latlng)) {
|
||||
if (coalitionArea.getSelected())
|
||||
clickedCoalitionArea = coalitionArea;
|
||||
else
|
||||
this.getMapContextMenu().setCoalitionArea(coalitionArea);
|
||||
}
|
||||
if (clickedCoalitionArea)
|
||||
this.showCoalitionAreaContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng, clickedCoalitionArea);
|
||||
}
|
||||
}
|
||||
else if (this.#state === MOVE_UNIT) {
|
||||
if (!e.originalEvent.ctrlKey) {
|
||||
getApp().getUnitsManager().selectedUnitsClearDestinations();
|
||||
}
|
||||
getApp().getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation)
|
||||
|
||||
this.#destinationGroupRotation = 0;
|
||||
this.#destinationRotationCenter = null;
|
||||
this.#computeDestinationRotation = false;
|
||||
}
|
||||
else {
|
||||
this.setState(IDLE);
|
||||
if (clickedCoalitionArea)
|
||||
this.showCoalitionAreaContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng, clickedCoalitionArea);
|
||||
}
|
||||
}
|
||||
else if (this.#state === MOVE_UNIT) {
|
||||
if (!e.originalEvent.ctrlKey) {
|
||||
getApp().getUnitsManager().selectedUnitsClearDestinations();
|
||||
}
|
||||
getApp().getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation)
|
||||
|
||||
this.#destinationGroupRotation = 0;
|
||||
this.#destinationRotationCenter = null;
|
||||
this.#computeDestinationRotation = false;
|
||||
}
|
||||
else {
|
||||
this.setState(IDLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#onSelectionStart(e: any) {
|
||||
@ -593,12 +595,12 @@ export class Map extends L.Map {
|
||||
}
|
||||
|
||||
this.#longPressTimer = window.setTimeout(() => {
|
||||
if (e.originalEvent.button != 2 || e.originalEvent.ctrlKey || e.originalEvent.shiftKey)
|
||||
return;
|
||||
|
||||
this.hideMapContextMenu();
|
||||
this.#longPressHandled = true;
|
||||
|
||||
if (e.originalEvent.button != 2 || e.originalEvent.ctrlKey || e.originalEvent.shiftKey)
|
||||
return;
|
||||
|
||||
var options: { [key: string]: { text: string, tooltip: string } } = {};
|
||||
const selectedUnits = getApp().getUnitsManager().getSelectedUnits();
|
||||
const selectedUnitTypes = getApp().getUnitsManager().getSelectedUnitsCategories();
|
||||
|
||||
@ -18,7 +18,7 @@ import { Manager } from "./other/manager";
|
||||
import { SVGInjector } from "@tanem/svg-injector";
|
||||
import { ServerManager } from "./server/servermanager";
|
||||
|
||||
import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constants";
|
||||
import { BLUE_COMMANDER, GAME_MASTER, HIDE_UNITS_SHORT_RANGE_RINGS, RED_COMMANDER, SHOW_UNITS_ACQUISITION_RINGS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNIT_LABELS } from "./constants/constants";
|
||||
import { aircraftDatabase } from "./unit/databases/aircraftdatabase";
|
||||
import { helicopterDatabase } from "./unit/databases/helicopterdatabase";
|
||||
import { groundUnitDatabase } from "./unit/databases/groundunitdatabase";
|
||||
@ -94,8 +94,10 @@ export class OlympusApp {
|
||||
* @param newActiveCoalition
|
||||
*/
|
||||
setActiveCoalition(newActiveCoalition: string) {
|
||||
if (this.getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER)
|
||||
if (this.getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER) {
|
||||
this.#activeCoalition = newActiveCoalition;
|
||||
document.dispatchEvent(new CustomEvent("activeCoalitionChanged"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,7 +259,7 @@ export class OlympusApp {
|
||||
}).addKeyboardShortcut("toggleUnitLabels", {
|
||||
"altKey": false,
|
||||
"callback": () => {
|
||||
const chk = document.querySelector(`label[title="Show unit labels"] input[type="checkbox"]`);
|
||||
const chk = document.querySelector(`label[title="${SHOW_UNIT_LABELS}"] input[type="checkbox"]`);
|
||||
if (chk instanceof HTMLElement) {
|
||||
chk.click();
|
||||
}
|
||||
@ -265,6 +267,39 @@ export class OlympusApp {
|
||||
"code": "KeyL",
|
||||
"ctrlKey": false,
|
||||
"shiftKey": false
|
||||
}).addKeyboardShortcut("toggleAcquisitionRings", {
|
||||
"altKey": false,
|
||||
"callback": () => {
|
||||
const chk = document.querySelector(`label[title="${SHOW_UNITS_ACQUISITION_RINGS}"] input[type="checkbox"]`);
|
||||
if (chk instanceof HTMLElement) {
|
||||
chk.click();
|
||||
}
|
||||
},
|
||||
"code": "KeyE",
|
||||
"ctrlKey": false,
|
||||
"shiftKey": false
|
||||
}).addKeyboardShortcut("toggleEngagementRings", {
|
||||
"altKey": false,
|
||||
"callback": () => {
|
||||
const chk = document.querySelector(`label[title="${SHOW_UNITS_ENGAGEMENT_RINGS}"] input[type="checkbox"]`);
|
||||
if (chk instanceof HTMLElement) {
|
||||
chk.click();
|
||||
}
|
||||
},
|
||||
"code": "KeyQ",
|
||||
"ctrlKey": false,
|
||||
"shiftKey": false
|
||||
}).addKeyboardShortcut("toggleHideShortEngagementRings", {
|
||||
"altKey": false,
|
||||
"callback": () => {
|
||||
const chk = document.querySelector(`label[title="${HIDE_UNITS_SHORT_RANGE_RINGS}"] input[type="checkbox"]`);
|
||||
if (chk instanceof HTMLElement) {
|
||||
chk.click();
|
||||
}
|
||||
},
|
||||
"code": "KeyR",
|
||||
"ctrlKey": false,
|
||||
"shiftKey": false
|
||||
});
|
||||
|
||||
["KeyW", "KeyA", "KeyS", "KeyD", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].forEach(code => {
|
||||
|
||||
@ -204,6 +204,10 @@ export function mToNm(m: number) {
|
||||
return m * 0.000539957;
|
||||
}
|
||||
|
||||
export function nmToM(nm: number) {
|
||||
return nm / 0.000539957;
|
||||
}
|
||||
|
||||
export function nmToFt(nm: number) {
|
||||
return nm * 6076.12;
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ export class UnitControlPanel extends Panel {
|
||||
this.#advancedSettingsDialog.classList.remove("hide");
|
||||
});
|
||||
/* This is for when a ctrl-click happens on the map for deselection and we need to remove the selected unit from the panel */
|
||||
document.addEventListener( "unitDeselection", ( ev:CustomEventInit ) => {
|
||||
document.addEventListener( "unitsDeselection", ( ev:CustomEventInit ) => {
|
||||
this.getElement().querySelector( `button[data-unit-id="${ev.detail.ID}"]` )?.remove();
|
||||
this.#updateRapidControls();
|
||||
});
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map, Point } from 'leaflet';
|
||||
import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map, Point, Circle } from 'leaflet';
|
||||
import { getApp } from '..';
|
||||
import { enumToCoalition, enumToEmissioNCountermeasure, getMarkerCategoryByName, enumToROE, enumToReactionToThreat, enumToState, getUnitDatabaseByCategory, mToFt, msToKnots, rad2deg, bearing, deg2rad, ftToM, getGroundElevation, coalitionToEnum } from '../other/utils';
|
||||
import { enumToCoalition, enumToEmissioNCountermeasure, getMarkerCategoryByName, enumToROE, enumToReactionToThreat, enumToState, getUnitDatabaseByCategory, mToFt, msToKnots, rad2deg, bearing, deg2rad, ftToM, getGroundElevation, coalitionToEnum, nmToFt, nmToM } from '../other/utils';
|
||||
import { CustomMarker } from '../map/markers/custommarker';
|
||||
import { SVGInjector } from '@tanem/svg-injector';
|
||||
import { UnitDatabase } from './databases/unitdatabase';
|
||||
import { TargetMarker } from '../map/markers/targetmarker';
|
||||
import { DLINK, DataIndexes, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_CONTACT_LINES, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants';
|
||||
import { DLINK, DataIndexes, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_UNIT_CONTACTS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS } from '../constants/constants';
|
||||
import { DataExtractor } from '../server/dataextractor';
|
||||
import { groundUnitDatabase } from './databases/groundunitdatabase';
|
||||
import { navyUnitDatabase } from './databases/navyunitdatabase';
|
||||
@ -86,7 +86,9 @@ export class Unit extends CustomMarker {
|
||||
#waitingForDoubleClick: boolean = false;
|
||||
#pathMarkers: Marker[] = [];
|
||||
#pathPolyline: Polyline;
|
||||
#contactsPolylines: Polyline[];
|
||||
#contactsPolylines: Polyline[] = [];
|
||||
#engagementCircle: Circle;
|
||||
#acquisitionCircle: Circle;
|
||||
#miniMapMarker: CircleMarker | null = null;
|
||||
#targetPositionMarker: TargetMarker;
|
||||
#targetPositionPolyline: Polyline;
|
||||
@ -148,9 +150,10 @@ export class Unit extends CustomMarker {
|
||||
|
||||
this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 });
|
||||
this.#pathPolyline.addTo(getApp().getMap());
|
||||
this.#contactsPolylines = [];
|
||||
this.#targetPositionMarker = new TargetMarker(new LatLng(0, 0));
|
||||
this.#targetPositionPolyline = new Polyline([], { color: '#FF0000', weight: 3, opacity: 0.5, smoothFactor: 1 });
|
||||
this.#engagementCircle = new Circle(this.getPosition(), { radius: 0, weight: 4, opacity: 1, fillOpacity: 0, dashArray: "4 8" });
|
||||
this.#acquisitionCircle = new Circle(this.getPosition(), { radius: 0, weight: 2, opacity: 1, fillOpacity: 0, dashArray: "8 12" });
|
||||
|
||||
this.on('click', (e) => this.#onClick(e));
|
||||
this.on('dblclick', (e) => this.#onDoubleClick(e));
|
||||
@ -178,6 +181,8 @@ export class Unit extends CustomMarker {
|
||||
|
||||
document.addEventListener("mapVisibilityOptionsChanged", (ev: CustomEventInit) => {
|
||||
this.#updateMarker();
|
||||
this.#drawRanges();
|
||||
|
||||
if (this.getSelected())
|
||||
this.drawLines();
|
||||
});
|
||||
@ -204,7 +209,7 @@ export class Unit extends CustomMarker {
|
||||
case DataIndexes.country: this.#country = dataExtractor.extractUInt8(); break;
|
||||
case DataIndexes.name: this.#name = dataExtractor.extractString(); break;
|
||||
case DataIndexes.unitName: this.#unitName = dataExtractor.extractString(); break;
|
||||
case DataIndexes.groupName: this.#groupName = dataExtractor.extractString(); break;
|
||||
case DataIndexes.groupName: this.#groupName = dataExtractor.extractString(); updateMarker = true; break;
|
||||
case DataIndexes.state: this.#state = enumToState(dataExtractor.extractUInt8()); updateMarker = true; break;
|
||||
case DataIndexes.task: this.#task = dataExtractor.extractString(); break;
|
||||
case DataIndexes.hasTask: this.#hasTask = dataExtractor.extractBool(); break;
|
||||
@ -233,7 +238,7 @@ export class Unit extends CustomMarker {
|
||||
case DataIndexes.ammo: this.#ammo = dataExtractor.extractAmmo(); break;
|
||||
case DataIndexes.contacts: this.#contacts = dataExtractor.extractContacts(); document.dispatchEvent(new CustomEvent("contactsUpdated", { detail: this })); break;
|
||||
case DataIndexes.activePath: this.#activePath = dataExtractor.extractActivePath(); break;
|
||||
case DataIndexes.isLeader: this.#isLeader = dataExtractor.extractBool(); break;
|
||||
case DataIndexes.isLeader: this.#isLeader = dataExtractor.extractBool(); updateMarker = true; break;
|
||||
case DataIndexes.operateAs: this.#operateAs = enumToCoalition(dataExtractor.extractUInt8()); break;
|
||||
}
|
||||
}
|
||||
@ -249,9 +254,12 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
drawLines() {
|
||||
this.#drawPath();
|
||||
this.#drawContacts();
|
||||
this.#drawTarget();
|
||||
/* Leaflet does not like it when you change coordinates when the map is zooming */
|
||||
if (!getApp().getMap().isZooming()) {
|
||||
this.#drawPath();
|
||||
this.#drawContacts();
|
||||
this.#drawTarget();
|
||||
}
|
||||
}
|
||||
|
||||
getData(): UnitData {
|
||||
@ -395,7 +403,7 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
getGroupMembers() {
|
||||
return Object.values(getApp().getUnitsManager().getUnits()).filter((unit: Unit) => { return unit != this && unit.#groupName === this.#groupName; });
|
||||
return Object.values(getApp().getUnitsManager().getUnits()).filter((unit: Unit) => { return unit != this && unit.getGroupName() === this.getGroupName(); });
|
||||
}
|
||||
|
||||
belongsToCommandedCoalition() {
|
||||
@ -521,6 +529,8 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
this.getElement()?.appendChild(el);
|
||||
|
||||
this.#drawRanges();
|
||||
}
|
||||
|
||||
/********************** Visibility *************************/
|
||||
@ -552,6 +562,12 @@ export class Unit extends CustomMarker {
|
||||
if (getApp().getMap().hasLayer(this) && this.getHidden()) {
|
||||
getApp().getMap().removeLayer(this);
|
||||
}
|
||||
|
||||
if (!this.getHidden()) {
|
||||
this.#drawRanges();
|
||||
} else {
|
||||
this.#clearRanges();
|
||||
}
|
||||
}
|
||||
|
||||
getHidden() {
|
||||
@ -746,7 +762,6 @@ export class Unit extends CustomMarker {
|
||||
coalition = "blue";
|
||||
else if (this.getCoalition() == "blue")
|
||||
coalition = "red";
|
||||
//TODO
|
||||
getApp().getServerManager().scenicAAA(this.ID, coalition);
|
||||
}
|
||||
|
||||
@ -756,7 +771,6 @@ export class Unit extends CustomMarker {
|
||||
coalition = "blue";
|
||||
else if (this.getCoalition() == "blue")
|
||||
coalition = "red";
|
||||
//TODO
|
||||
getApp().getServerManager().missOnPurpose(this.ID, coalition);
|
||||
}
|
||||
|
||||
@ -809,11 +823,6 @@ export class Unit extends CustomMarker {
|
||||
getApp().getUnitsManager().deselectAllUnits();
|
||||
|
||||
this.setSelected(!this.getSelected());
|
||||
const detail = { "detail": { "unit": this } };
|
||||
if (this.getSelected())
|
||||
document.dispatchEvent(new CustomEvent("unitSelected", detail));
|
||||
else
|
||||
document.dispatchEvent(new CustomEvent("unitDeselection", { "detail": this }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -882,14 +891,14 @@ export class Unit extends CustomMarker {
|
||||
var options: { [key: string]: { text: string, tooltip: string } } = {};
|
||||
|
||||
options = {
|
||||
'trail': { text: "Trail", tooltip: "Follow unit in trail formation" },
|
||||
'echelon-lh': { text: "Echelon (LH)", tooltip: "Follow unit in echelon left formation" },
|
||||
'echelon-rh': { text: "Echelon (RH)", tooltip: "Follow unit in echelon right formation" },
|
||||
'line-abreast-lh': { text: "Line abreast (LH)", tooltip: "Follow unit in line abreast left formation" },
|
||||
'line-abreast-rh': { text: "Line abreast (RH)", tooltip: "Follow unit in line abreast right formation" },
|
||||
'front': { text: "Front", tooltip: "Fly in front of unit" },
|
||||
'diamond': { text: "Diamond", tooltip: "Follow unit in diamond formation" },
|
||||
'custom': { text: "Custom", tooltip: "Set a custom formation position" },
|
||||
'trail': { text: "Trail", tooltip: "Follow unit in trail formation" },
|
||||
'echelon-lh': { text: "Echelon (LH)", tooltip: "Follow unit in echelon left formation" },
|
||||
'echelon-rh': { text: "Echelon (RH)", tooltip: "Follow unit in echelon right formation" },
|
||||
'line-abreast-lh': { text: "Line abreast (LH)", tooltip: "Follow unit in line abreast left formation" },
|
||||
'line-abreast-rh': { text: "Line abreast (RH)", tooltip: "Follow unit in line abreast right formation" },
|
||||
'front': { text: "Front", tooltip: "Fly in front of unit" },
|
||||
'diamond': { text: "Diamond", tooltip: "Follow unit in diamond formation" },
|
||||
'custom': { text: "Custom", tooltip: "Set a custom formation position" },
|
||||
}
|
||||
|
||||
getApp().getMap().getUnitContextMenu().setOptions(options, (option: string) => {
|
||||
@ -984,9 +993,9 @@ export class Unit extends CustomMarker {
|
||||
element.querySelector(".unit")?.toggleAttribute("data-is-dead", !this.#alive);
|
||||
|
||||
/* Set current unit state */
|
||||
if (this.#human) // Unit is human
|
||||
if (this.#human) // Unit is human
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "human");
|
||||
else if (!this.#controlled) // Unit is under DCS control (not Olympus)
|
||||
else if (!this.#controlled) // Unit is under DCS control (not Olympus)
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "dcs");
|
||||
else if ((this.getCategory() == "Aircraft" || this.getCategory() == "Helicopter") && !this.#hasTask)
|
||||
element.querySelector(".unit")?.setAttribute("data-state", "no-task");
|
||||
@ -1041,12 +1050,16 @@ export class Unit extends CustomMarker {
|
||||
if (hotgroupEl)
|
||||
hotgroupEl.innerText = String(this.#hotgroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Set vertical offset for altitude stacking */
|
||||
var pos = getApp().getMap().latLngToLayerPoint(this.getLatLng()).round();
|
||||
this.setZIndexOffset(1000 + Math.floor(this.#position.alt as number) - pos.y + (this.#highlighted || this.#selected ? 5000 : 0));
|
||||
|
||||
/* Circles don't like to be updated when the map is zooming */
|
||||
if (!getApp().getMap().isZooming()) {
|
||||
this.#drawRanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1093,7 +1106,7 @@ export class Unit extends CustomMarker {
|
||||
|
||||
#drawContacts() {
|
||||
this.#clearContacts();
|
||||
if (getApp().getMap().getVisibilityOptions()[SHOW_CONTACT_LINES]) {
|
||||
if (getApp().getMap().getVisibilityOptions()[SHOW_UNIT_CONTACTS]) {
|
||||
for (let index in this.#contacts) {
|
||||
var contactData = this.#contacts[index];
|
||||
var contact: Unit | Weapon | null;
|
||||
@ -1139,6 +1152,95 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
}
|
||||
|
||||
#drawRanges() {
|
||||
var engagementRange = 0;
|
||||
var acquisitionRange = 0;
|
||||
|
||||
/* Get the acquisition and engagement ranges of the entire group, not for each unit */
|
||||
if (this.getIsLeader()) {
|
||||
var engagementRange = this.getDatabase()?.getByName(this.getName())?.engagementRange?? 0;
|
||||
var acquisitionRange = this.getDatabase()?.getByName(this.getName())?.acquisitionRange?? 0;
|
||||
|
||||
this.getGroupMembers().forEach((unit: Unit) => {
|
||||
if (unit.getAlive()) {
|
||||
let unitEngagementRange = unit.getDatabase()?.getByName(unit.getName())?.engagementRange?? 0;
|
||||
let unitAcquisitionRange = unit.getDatabase()?.getByName(unit.getName())?.acquisitionRange?? 0;
|
||||
|
||||
if (unitEngagementRange > engagementRange)
|
||||
engagementRange = unitEngagementRange;
|
||||
|
||||
if (unitAcquisitionRange > acquisitionRange)
|
||||
acquisitionRange = unitAcquisitionRange;
|
||||
}
|
||||
})
|
||||
|
||||
if (acquisitionRange !== this.#acquisitionCircle.getRadius())
|
||||
this.#acquisitionCircle.setRadius(acquisitionRange);
|
||||
|
||||
if (engagementRange !== this.#engagementCircle.getRadius())
|
||||
this.#engagementCircle.setRadius(engagementRange);
|
||||
|
||||
this.#engagementCircle.options.fillOpacity = this.getSelected()? 0.3: 0;
|
||||
|
||||
/* Acquisition circles */
|
||||
var shortRangeCheck = (engagementRange > nmToM(3) && acquisitionRange > nmToM(3) || !getApp().getMap().getVisibilityOptions()[HIDE_UNITS_SHORT_RANGE_RINGS]);
|
||||
|
||||
if (getApp().getMap().getVisibilityOptions()[SHOW_UNITS_ACQUISITION_RINGS] && shortRangeCheck && (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC, IRST, RWR].includes(value)))) {
|
||||
if (!getApp().getMap().hasLayer(this.#acquisitionCircle)) {
|
||||
this.#acquisitionCircle.addTo(getApp().getMap());
|
||||
switch (this.getCoalition()) {
|
||||
case "red":
|
||||
this.#acquisitionCircle.options.color = "#D42121";
|
||||
break;
|
||||
case "blue":
|
||||
this.#acquisitionCircle.options.color = "#017DC1";
|
||||
break;
|
||||
default:
|
||||
this.#acquisitionCircle.options.color = "#111111"
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.#acquisitionCircle.setLatLng(this.getPosition());
|
||||
}
|
||||
else {
|
||||
if (getApp().getMap().hasLayer(this.#acquisitionCircle))
|
||||
this.#acquisitionCircle.removeFrom(getApp().getMap());
|
||||
}
|
||||
|
||||
/* Engagement circles */
|
||||
if (getApp().getMap().getVisibilityOptions()[SHOW_UNITS_ENGAGEMENT_RINGS] && shortRangeCheck && (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC, IRST, RWR].includes(value)))) {
|
||||
if (!getApp().getMap().hasLayer(this.#engagementCircle)) {
|
||||
this.#engagementCircle.addTo(getApp().getMap());
|
||||
switch (this.getCoalition()) {
|
||||
case "red":
|
||||
this.#engagementCircle.options.color = "#FF5858";
|
||||
break;
|
||||
case "blue":
|
||||
this.#engagementCircle.options.color = "#3BB9FF";
|
||||
break;
|
||||
default:
|
||||
this.#engagementCircle.options.color = "#CFD9E8"
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.#engagementCircle.setLatLng(this.getPosition());
|
||||
}
|
||||
else {
|
||||
if (getApp().getMap().hasLayer(this.#engagementCircle))
|
||||
this.#engagementCircle.removeFrom(getApp().getMap());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#clearRanges() {
|
||||
if (getApp().getMap().hasLayer(this.#acquisitionCircle))
|
||||
this.#acquisitionCircle.removeFrom(getApp().getMap());
|
||||
|
||||
if (getApp().getMap().hasLayer(this.#engagementCircle))
|
||||
this.#engagementCircle.removeFrom(getApp().getMap());
|
||||
}
|
||||
|
||||
#drawTarget() {
|
||||
if (this.#targetPosition.lat != 0 && this.#targetPosition.lng != 0 && getApp().getMap().getVisibilityOptions()[SHOW_UNIT_PATHS]) {
|
||||
this.#drawTargetPosition(this.#targetPosition);
|
||||
|
||||
@ -23,6 +23,7 @@ export class UnitsManager {
|
||||
#units: { [ID: number]: Unit };
|
||||
#copiedUnits: UnitData[];
|
||||
#selectionEventDisabled: boolean = false;
|
||||
#deselectionEventDisabled: boolean = false;
|
||||
#requestDetectionUpdate: boolean = false;
|
||||
|
||||
constructor() {
|
||||
@ -1048,8 +1049,16 @@ export class UnitsManager {
|
||||
getApp().getMap().setState(IDLE);
|
||||
document.dispatchEvent(new CustomEvent("clearSelection"));
|
||||
}
|
||||
else
|
||||
document.dispatchEvent(new CustomEvent("unitsDeselection", { detail: this.getSelectedUnits() }));
|
||||
else {
|
||||
/* Disable the firing of the selection event for a certain amount of time. This avoids firing many events if many units are selected */
|
||||
if (!this.#deselectionEventDisabled) {
|
||||
window.setTimeout(() => {
|
||||
document.dispatchEvent(new CustomEvent("unitsDeselection", { detail: this.getSelectedUnits() }));
|
||||
this.#deselectionEventDisabled = false;
|
||||
}, 100);
|
||||
this.#deselectionEventDisabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#showActionMessage(units: Unit[], message: string) {
|
||||
|
||||
2
scripts/python/.vscode/launch.json
vendored
2
scripts/python/.vscode/launch.json
vendored
@ -11,7 +11,7 @@
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true,
|
||||
"args": ["groundunit"]
|
||||
"args": ["navyunit"]
|
||||
}
|
||||
]
|
||||
}
|
||||
65
scripts/python/addRanges.py
Normal file
65
scripts/python/addRanges.py
Normal file
@ -0,0 +1,65 @@
|
||||
import sys
|
||||
import json
|
||||
import inspect
|
||||
import difflib
|
||||
from slpp import slpp as lua
|
||||
|
||||
SEARCH_FOLDER = "D:\\Eagle Dynamics\\DCS World OpenBeta"
|
||||
|
||||
sys.path.append("..\..\..\dcs-master\dcs-master")
|
||||
|
||||
from dcs.vehicles import *
|
||||
from dcs.ships import *
|
||||
from dcs.planes import *
|
||||
from dcs.helicopters import *
|
||||
|
||||
# The database file on which to operate is the first standard argument of the call
|
||||
if len(sys.argv) > 1:
|
||||
if (sys.argv[1] == "aircraft"):
|
||||
filename = '..\\..\\client\\public\\databases\\units\\aircraftdatabase.json'
|
||||
elif (sys.argv[1] == "helicopter"):
|
||||
filename = '..\\..\\client\\public\\databases\\units\\helicopterdatabase.json'
|
||||
elif (sys.argv[1] == "groundunit"):
|
||||
filename = '..\\..\\client\\public\\databases\\units\\groundunitdatabase.json'
|
||||
elif (sys.argv[1] == "navyunit"):
|
||||
filename = '..\\..\\client\\public\\databases\\units\\navyunitdatabase.json'
|
||||
|
||||
# Loads the database
|
||||
with open(filename) as f:
|
||||
database = json.load(f)
|
||||
|
||||
# Loop on all the units in the database
|
||||
for unit_name in database:
|
||||
try:
|
||||
# Get the pydcs Python class for the unit
|
||||
if (sys.argv[1] == "aircraft"):
|
||||
unitmap = plane_map
|
||||
elif (sys.argv[1] == "helicopter"):
|
||||
unitmap = helicopter_map
|
||||
elif (sys.argv[1] == "groundunit"):
|
||||
unitmap = vehicle_map
|
||||
elif (sys.argv[1] == "navyunit"):
|
||||
unitmap = ship_map
|
||||
lowercase_keys = [key.lower() for key in unitmap.keys()]
|
||||
res = difflib.get_close_matches(unit_name.lower(), lowercase_keys)
|
||||
if len(res) > 0:
|
||||
found_name = list(unitmap.keys())[lowercase_keys.index(res[0])]
|
||||
cls = unitmap[found_name]
|
||||
else:
|
||||
print(f"Warning, could not find {unit_name} in classes list. Skipping...")
|
||||
continue
|
||||
|
||||
database[unit_name]["acquisitionRange"] = unitmap[found_name].detection_range
|
||||
database[unit_name]["engagementRange"] = unitmap[found_name].threat_range
|
||||
|
||||
except Exception as e:
|
||||
print(f"Could not find data for aircraft of type {unit_name}: {e}, skipping...")
|
||||
|
||||
# Dump everything in the database
|
||||
with open(filename, "w") as f:
|
||||
json.dump(database, f, indent=2)
|
||||
|
||||
# Done!
|
||||
print("Done!")
|
||||
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
import json
|
||||
import difflib
|
||||
|
||||
countries = ['USA', 'GRG', 'GER', 'DZA', 'FRA', 'CAN', 'AUS', 'UKR', 'ITA', 'GRC', 'SPN', 'RUS', 'NETH', 'DEN', 'TUR', 'UK', 'BEL', 'ISR', 'NOR', 'JPN', 'ARE', 'QAT', 'IND', 'SAU', 'EGY', 'KOR', 'HND', 'CHL', 'BLUE', 'AUSAF', 'RED', 'VNM', 'SVK', 'SDN', 'GDR', 'JOR', 'PER', 'CHN', 'IDN', 'PHL', 'BOL', 'MAR', 'YEM', 'KWT', 'SUI', 'GHA', 'CYP', 'BHR', 'YUG', 'CZE', 'KAZ', 'AUT', 'HUN', 'MYS', 'ROU', 'THA', 'LBN', 'FIN', 'PRT', 'OMN', 'MEX', 'IRQ', 'BRA', 'SWE', 'NZG', 'CUB', 'INS', 'RSO', 'RSA', 'HRV', 'ABH', 'ARG', 'LBY', 'PRK', 'VEN', 'TUN', 'IRN', 'ETH', 'BLR', 'SUN', 'BGR', 'PAK', 'NGA', 'POL', 'SVN', 'SYR', 'SRB', 'UN', 'RSI', 'SPA', 'ECU', '', 'USAF', 'hide', 'EGP', 'LIB']
|
||||
|
||||
with open('C:\\Users\\dpass\\Documents\\DCSOlympus\\client\\public\\images\\nations\\codes.json', "r") as f:
|
||||
codes = json.load(f)
|
||||
|
||||
for country in countries:
|
||||
keys = difflib.get_close_matches(country, codes.keys(), cutoff=.35)
|
||||
if len(keys) > 0:
|
||||
codes[keys[0]]["liveryCodes"].append(country)
|
||||
|
||||
with open('C:\\Users\\dpass\\Documents\\DCSOlympus\\client\\public\\images\\nations\\codes.json', "w") as f:
|
||||
json.dump(codes, f)
|
||||
@ -74,9 +74,11 @@ void GroundUnit::setState(unsigned char newState)
|
||||
break;
|
||||
}
|
||||
case State::SCENIC_AAA: {
|
||||
setTargetPosition(Coords(NULL));
|
||||
break;
|
||||
}
|
||||
case State::MISS_ON_PURPOSE: {
|
||||
setTargetPosition(Coords(NULL));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user