Merge branch 'react-transition-test' of https://github.com/Pax1601/DCSOlympus into react-transition-test

This commit is contained in:
Dogma
2024-04-14 20:40:24 +10:00
8 changed files with 116 additions and 65 deletions

View File

@@ -183,6 +183,7 @@ export const defaultMapLayers = {
/* Map constants */ /* Map constants */
export const IDLE = "Idle"; export const IDLE = "Idle";
export const MOVE_UNIT = "Move unit"; export const MOVE_UNIT = "Move unit";
export const SPAWN_UNIT = "Spawn unit";
export const COALITIONAREA_DRAW_POLYGON = "Draw Coalition Area"; export const COALITIONAREA_DRAW_POLYGON = "Draw Coalition Area";
export const IADSTypes = ["AAA", "SAM Site", "Radar (EWR)"]; export const IADSTypes = ["AAA", "SAM Site", "Radar (EWR)"];

View File

@@ -12,7 +12,7 @@ import { DestinationPreviewMarker } from "./markers/destinationpreviewmarker";
import { TemporaryUnitMarker } from "./markers/temporaryunitmarker"; import { TemporaryUnitMarker } from "./markers/temporaryunitmarker";
import { ClickableMiniMap } from "./clickableminimap"; import { ClickableMiniMap } from "./clickableminimap";
import { SVGInjector } from '@tanem/svg-injector' import { SVGInjector } from '@tanem/svg-injector'
import { defaultMapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, MOVE_UNIT, SHOW_UNIT_CONTACTS, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, SHOW_UNIT_LABELS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS, FILL_SELECTED_RING, /*MAP_MARKER_CONTROLS,*/ DCS_LINK_PORT, DCSMapsZoomLevelsByTheatre, DCS_LINK_RATIO, MAP_OPTIONS_DEFAULTS, MAP_HIDDEN_TYPES_DEFAULTS } from "../constants/constants"; import { defaultMapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, MOVE_UNIT, SHOW_UNIT_CONTACTS, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, SHOW_UNIT_LABELS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS, FILL_SELECTED_RING, /*MAP_MARKER_CONTROLS,*/ DCS_LINK_PORT, DCSMapsZoomLevelsByTheatre, DCS_LINK_RATIO, MAP_OPTIONS_DEFAULTS, MAP_HIDDEN_TYPES_DEFAULTS, SPAWN_UNIT } from "../constants/constants";
import { CoalitionArea } from "./coalitionarea/coalitionarea"; import { CoalitionArea } from "./coalitionarea/coalitionarea";
//import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu"; //import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu";
import { DrawingCursor } from "./coalitionarea/drawingcursor"; import { DrawingCursor } from "./coalitionarea/drawingcursor";
@@ -29,7 +29,8 @@ import './markers/stylesheets/units.css'
// Temporary // Temporary
import './theme.css' import './theme.css'
import { MapHiddenTypes, MapOptions } from "../types/types"; import { Coalition, MapHiddenTypes, MapOptions } from "../types/types";
import { UnitBlueprint } from "../interfaces";
var hasTouchScreen = false; var hasTouchScreen = false;
//if ("maxTouchPoints" in navigator) //if ("maxTouchPoints" in navigator)
@@ -45,7 +46,7 @@ else
// TODO would be nice to convert to ts - yes // TODO would be nice to convert to ts - yes
//require("../../node_modules/leaflet.nauticscale/dist/leaflet.nauticscale.js") //require("../../node_modules/leaflet.nauticscale/dist/leaflet.nauticscale.js")
//require("../../node_modules/leaflet-path-drag/dist/index.js") //require("../../node_modules/leaflet-path-drag/dist/index.js")
export class Map extends L.Map { export class Map extends L.Map {
/* Options */ /* Options */
#options: MapOptions = MAP_OPTIONS_DEFAULTS; #options: MapOptions = MAP_OPTIONS_DEFAULTS;
@@ -54,6 +55,9 @@ export class Map extends L.Map {
#ID: string; #ID: string;
#state: string; #state: string;
#layer: L.TileLayer | L.LayerGroup | null = null; #layer: L.TileLayer | L.LayerGroup | null = null;
#spawningBlueprint: UnitBlueprint | null = null;
#preventLeftClick: boolean = false; #preventLeftClick: boolean = false;
#leftClickTimer: number = 0; #leftClickTimer: number = 0;
#deafultPanDelta: number = 100; #deafultPanDelta: number = 100;
@@ -62,17 +66,23 @@ export class Map extends L.Map {
#panRight: boolean = false; #panRight: boolean = false;
#panUp: boolean = false; #panUp: boolean = false;
#panDown: boolean = false; #panDown: boolean = false;
#lastMousePosition: L.Point = new L.Point(0, 0); #lastMousePosition: L.Point = new L.Point(0, 0);
#shiftKey: boolean = false; #shiftKey: boolean = false;
#ctrlKey: boolean = false; #ctrlKey: boolean = false;
#centerUnit: Unit | null = null; #centerUnit: Unit | null = null;
#miniMap: ClickableMiniMap | null = null; #miniMap: ClickableMiniMap | null = null;
#miniMapLayerGroup: L.LayerGroup; #miniMapLayerGroup: L.LayerGroup;
#miniMapPolyline: L.Polyline; #miniMapPolyline: L.Polyline;
#temporaryMarkers: TemporaryUnitMarker[] = []; #temporaryMarkers: TemporaryUnitMarker[] = [];
#selecting: boolean = false; #selecting: boolean = false;
#isZooming: boolean = false; #isZooming: boolean = false;
#previousZoom: number = 0; #previousZoom: number = 0;
#slaveDCSCamera: boolean = false; #slaveDCSCamera: boolean = false;
#slaveDCSCameraAvailable: boolean = false; #slaveDCSCameraAvailable: boolean = false;
#cameraControlTimer: number = 0; #cameraControlTimer: number = 0;
@@ -88,6 +98,8 @@ export class Map extends L.Map {
#drawingCursor: DrawingCursor = new DrawingCursor(); #drawingCursor: DrawingCursor = new DrawingCursor();
#destinationPreviewHandle: DestinationPreviewHandle = new DestinationPreviewHandle(new L.LatLng(0, 0)); #destinationPreviewHandle: DestinationPreviewHandle = new DestinationPreviewHandle(new L.LatLng(0, 0));
#destinationPreviewHandleLine: L.Polyline = new L.Polyline([], { color: "#000000", weight: 3, opacity: 0.5, smoothFactor: 1, dashArray: "4, 8" }); #destinationPreviewHandleLine: L.Polyline = new L.Polyline([], { color: "#000000", weight: 3, opacity: 0.5, smoothFactor: 1, dashArray: "4, 8" });
#spawnCursor: TemporaryUnitMarker | null = null;
#longPressHandled: boolean = false; #longPressHandled: boolean = false;
#longPressTimer: number = 0; #longPressTimer: number = 0;
@@ -128,7 +140,7 @@ export class Map extends L.Map {
this.#miniMapLayerGroup = new L.LayerGroup([minimapLayer]); this.#miniMapLayerGroup = new L.LayerGroup([minimapLayer]);
this.#miniMapPolyline = new L.Polyline([], { color: '#202831' }); this.#miniMapPolyline = new L.Polyline([], { color: '#202831' });
this.#miniMapPolyline.addTo(this.#miniMapLayerGroup); this.#miniMapPolyline.addTo(this.#miniMapLayerGroup);
/* Scale */ /* Scale */
//@ts-ignore TODO more hacking because the module is provided as a pure javascript module only //@ts-ignore TODO more hacking because the module is provided as a pure javascript module only
@@ -137,7 +149,7 @@ export class Map extends L.Map {
/* Map source dropdown */ /* Map source dropdown */
//this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName)); //this.#mapSourceDropdown = new Dropdown("map-type", (layerName: string) => this.setLayer(layerName));
//this.#mapSourceDropdown.setOptions(this.getLayers(), null); //this.#mapSourceDropdown.setOptions(this.getLayers(), null);
// //
///* Visibility options dropdown */ ///* Visibility options dropdown */
//this.#mapVisibilityOptionsDropdown = new Dropdown("map-visibility-options", (value: string) => { }); //this.#mapVisibilityOptionsDropdown = new Dropdown("map-visibility-options", (value: string) => { });
@@ -216,13 +228,13 @@ export class Map extends L.Map {
document.addEventListener("toggleCameraLinkStatus", () => { document.addEventListener("toggleCameraLinkStatus", () => {
// if (this.#slaveDCSCameraAvailable) { // Commented to experiment with usability // if (this.#slaveDCSCameraAvailable) { // Commented to experiment with usability
this.setSlaveDCSCamera(!this.#slaveDCSCamera); this.setSlaveDCSCamera(!this.#slaveDCSCamera);
// } // }
}) })
document.addEventListener("slewCameraToPosition", () => { document.addEventListener("slewCameraToPosition", () => {
// if (this.#slaveDCSCameraAvailable) { // Commented to experiment with usability // if (this.#slaveDCSCameraAvailable) { // Commented to experiment with usability
this.#broadcastPosition(); this.#broadcastPosition();
// } // }
}) })
@@ -256,14 +268,14 @@ export class Map extends L.Map {
} else { } else {
this.#layer = new L.TileLayer(layerData.urlTemplate, layerData); this.#layer = new L.TileLayer(layerData.urlTemplate, layerData);
} }
/* DCS core layers are handled here */ /* DCS core layers are handled here */
} else if (["DCS Map", "DCS Satellite"].includes(layerName) ) { } else if (["DCS Map", "DCS Satellite"].includes(layerName)) {
let layerData = this.#mapLayers["ArcGIS Satellite"]; let layerData = this.#mapLayers["ArcGIS Satellite"];
let layers = [new L.TileLayer(layerData.urlTemplate, layerData)]; let layers = [new L.TileLayer(layerData.urlTemplate, layerData)];
let template = `https://maps.dcsolympus.com/maps/${layerName === "DCS Map"? "alt": "sat"}-{theatre}-modern/{z}/{x}/{y}.png`; let template = `https://maps.dcsolympus.com/maps/${layerName === "DCS Map" ? "alt" : "sat"}-{theatre}-modern/{z}/{x}/{y}.png`;
layers.push(...DCSMapsZoomLevelsByTheatre[theatre].map((nativeZoomLevels: any) => { layers.push(...DCSMapsZoomLevelsByTheatre[theatre].map((nativeZoomLevels: any) => {
return new L.TileLayer(template.replace("{theatre}", theatre.toLowerCase()), {...nativeZoomLevels, maxZoom: 20, crossOrigin: ""}); return new L.TileLayer(template.replace("{theatre}", theatre.toLowerCase()), { ...nativeZoomLevels, maxZoom: 20, crossOrigin: "" });
})); }));
this.#layer = new L.LayerGroup(layers); this.#layer = new L.LayerGroup(layers);
@@ -280,9 +292,8 @@ export class Map extends L.Map {
} }
/* State machine */ /* State machine */
setState(state: string) { setState(state: string, options?: { blueprint: UnitBlueprint, coalition: Coalition }) {
this.#state = state; this.#state = state;
this.#updateCursor();
/* Operations to perform if you are NOT in a state */ /* Operations to perform if you are NOT in a state */
if (this.#state !== COALITIONAREA_DRAW_POLYGON) { if (this.#state !== COALITIONAREA_DRAW_POLYGON) {
@@ -290,10 +301,18 @@ export class Map extends L.Map {
} }
/* Operations to perform if you ARE in a state */ /* Operations to perform if you ARE in a state */
if (this.#state === COALITIONAREA_DRAW_POLYGON) { if (this.#state === SPAWN_UNIT) {
this.#spawningBlueprint = options?.blueprint ?? null;
this.#spawnCursor?.removeFrom(this);
this.#spawnCursor = new TemporaryUnitMarker(new L.LatLng(0, 0), this.#spawningBlueprint?.name ?? "unknown", options?.coalition ?? 'blue');
}
else if (this.#state === COALITIONAREA_DRAW_POLYGON) {
this.#coalitionAreas.push(new CoalitionArea([])); this.#coalitionAreas.push(new CoalitionArea([]));
this.#coalitionAreas[this.#coalitionAreas.length - 1].addTo(this); this.#coalitionAreas[this.#coalitionAreas.length - 1].addTo(this);
} }
this.#updateCursor();
document.dispatchEvent(new CustomEvent("mapStateChanged")); document.dispatchEvent(new CustomEvent("mapStateChanged"));
} }
@@ -447,7 +466,7 @@ export class Map extends L.Map {
const boundaries = this.#getMinimapBoundaries(); const boundaries = this.#getMinimapBoundaries();
this.#miniMapPolyline.setLatLngs(boundaries[theatre as keyof typeof boundaries]); this.#miniMapPolyline.setLatLngs(boundaries[theatre as keyof typeof boundaries]);
this.setLayer(this.#layerName); this.setLayer(this.#layerName);
} }
@@ -539,10 +558,10 @@ export class Map extends L.Map {
// } // }
// return list; // return list;
//}, [] as string[]); //}, [] as string[]);
// //
//if (toggles.length === 0) //if (toggles.length === 0)
// return false; // return false;
// //
//return toggles.some((toggle: string) => { //return toggles.some((toggle: string) => {
// // Specific coding for robots - extend later if needed // // Specific coding for robots - extend later if needed
// return (toggle === "dcs" && !unit.getControlled() && !unit.getHuman()); // return (toggle === "dcs" && !unit.getControlled() && !unit.getHuman());
@@ -601,6 +620,14 @@ export class Map extends L.Map {
if (this.#state === IDLE) { if (this.#state === IDLE) {
this.deselectAllCoalitionAreas(); this.deselectAllCoalitionAreas();
} }
else if (this.#state === SPAWN_UNIT) {
//getApp().getUnitsManager().spawnUnits(
// "asd",
// [
// {}
// ]
//)
}
else if (this.#state === COALITIONAREA_DRAW_POLYGON) { else if (this.#state === COALITIONAREA_DRAW_POLYGON) {
if (this.getSelectedCoalitionArea()?.getEditing()) { if (this.getSelectedCoalitionArea()?.getEditing()) {
this.getSelectedCoalitionArea()?.addTemporaryLatLng(e.latlng); this.getSelectedCoalitionArea()?.addTemporaryLatLng(e.latlng);
@@ -693,25 +720,25 @@ export class Map extends L.Map {
} }
} }
this.#longPressTimer = window.setTimeout(() => { //this.#longPressTimer = window.setTimeout(() => {
this.hideMapContextMenu(); // this.hideMapContextMenu();
this.#longPressHandled = true; // this.#longPressHandled = true;
//
if (e.originalEvent.button != 2 || e.originalEvent.ctrlKey || e.originalEvent.shiftKey) // if (e.originalEvent.button != 2 || e.originalEvent.ctrlKey || e.originalEvent.shiftKey)
return; // return;
//
var contextActionSet = new ContextActionSet(); // var contextActionSet = new ContextActionSet();
var units = getApp().getUnitsManager().getSelectedUnits(); // var units = getApp().getUnitsManager().getSelectedUnits();
units.forEach((unit: Unit) => { // units.forEach((unit: Unit) => {
unit.appendContextActions(contextActionSet, null, e.latlng); // unit.appendContextActions(contextActionSet, null, e.latlng);
}) // })
//
if (Object.keys(contextActionSet.getContextActions()).length > 0) { // if (Object.keys(contextActionSet.getContextActions()).length > 0) {
getApp().getMap().showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng); // getApp().getMap().showUnitContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng);
//getApp().getMap().getUnitContextMenu().setContextActions(contextActionSet); // //getApp().getMap().getUnitContextMenu().setContextActions(contextActionSet);
} // }
}, 150); //}, 150);
this.#longPressHandled = false; //this.#longPressHandled = false;
} }
#onMouseUp(e: any) { #onMouseUp(e: any) {
@@ -739,6 +766,9 @@ export class Map extends L.Map {
this.#destinationGroupRotation = -bearing(this.#destinationRotationCenter.lat, this.#destinationRotationCenter.lng, this.getMouseCoordinates().lat, this.getMouseCoordinates().lng); this.#destinationGroupRotation = -bearing(this.#destinationRotationCenter.lat, this.#destinationRotationCenter.lng, this.getMouseCoordinates().lat, this.getMouseCoordinates().lng);
this.#updateDestinationCursors(); this.#updateDestinationCursors();
} }
else if (this.#state === SPAWN_UNIT) {
this.#updateSpawnCursor();
}
else if (this.#state === COALITIONAREA_DRAW_POLYGON && e.latlng !== undefined) { else if (this.#state === COALITIONAREA_DRAW_POLYGON && e.latlng !== undefined) {
this.#drawingCursor.setLatLng(e.latlng); this.#drawingCursor.setLatLng(e.latlng);
/* Update the polygon being drawn with the current position of the mouse cursor */ /* Update the polygon being drawn with the current position of the mouse cursor */
@@ -825,17 +855,20 @@ export class Map extends L.Map {
/* Hide all non default cursors */ /* Hide all non default cursors */
this.#hideDestinationCursors(); this.#hideDestinationCursors();
this.#hideDrawingCursor(); this.#hideDrawingCursor();
this.#hideSpawnCursor();
this.#showDefaultCursor(); this.#showDefaultCursor();
} else { } else {
/* Hide all the unnecessary cursors depending on the active state */ /* Hide all the unnecessary cursors depending on the active state */
if (this.#state !== IDLE) this.#hideDefaultCursor(); if (this.#state !== IDLE) this.#hideDefaultCursor();
if (this.#state !== MOVE_UNIT) this.#hideDestinationCursors(); if (this.#state !== MOVE_UNIT) this.#hideDestinationCursors();
if (this.#state !== SPAWN_UNIT) this.#hideSpawnCursor();
if (this.#state !== COALITIONAREA_DRAW_POLYGON) this.#hideDrawingCursor(); if (this.#state !== COALITIONAREA_DRAW_POLYGON) this.#hideDrawingCursor();
/* Show the active cursor depending on the active state */ /* Show the active cursor depending on the active state */
if (this.#state === IDLE) this.#showDefaultCursor(); if (this.#state === IDLE) this.#showDefaultCursor();
else if (this.#state === MOVE_UNIT) this.#showDestinationCursors(); else if (this.#state === MOVE_UNIT) this.#showDestinationCursors();
else if (this.#state === SPAWN_UNIT) this.#showSpawnCursor();
else if (this.#state === COALITIONAREA_DRAW_POLYGON) this.#showDrawingCursor(); else if (this.#state === COALITIONAREA_DRAW_POLYGON) this.#showDrawingCursor();
} }
} }
@@ -923,6 +956,18 @@ export class Map extends L.Map {
this.#drawingCursor.removeFrom(this); this.#drawingCursor.removeFrom(this);
} }
#showSpawnCursor() {
this.#spawnCursor?.addTo(this);
}
#updateSpawnCursor() {
this.#spawnCursor?.setLatLng(this.getMouseCoordinates());
}
#hideSpawnCursor() {
this.#spawnCursor?.removeFrom(this);
}
#setSlaveDCSCameraAvailable(newSlaveDCSCameraAvailable: boolean) { #setSlaveDCSCameraAvailable(newSlaveDCSCameraAvailable: boolean) {
this.#slaveDCSCameraAvailable = newSlaveDCSCameraAvailable; this.#slaveDCSCameraAvailable = newSlaveDCSCameraAvailable;
let linkButton = document.getElementById("camera-link-control"); let linkButton = document.getElementById("camera-link-control");
@@ -939,12 +984,12 @@ export class Map extends L.Map {
} }
/* Check if the camera control plugin is available. Right now this will only change the color of the button, no changes in functionality */ /* Check if the camera control plugin is available. Right now this will only change the color of the button, no changes in functionality */
#checkCameraPort(){ #checkCameraPort() {
if (this.#cameraOptionsXmlHttp?.readyState !== 4) if (this.#cameraOptionsXmlHttp?.readyState !== 4)
this.#cameraOptionsXmlHttp?.abort() this.#cameraOptionsXmlHttp?.abort()
this.#cameraOptionsXmlHttp = new XMLHttpRequest(); this.#cameraOptionsXmlHttp = new XMLHttpRequest();
/* Using 127.0.0.1 instead of localhost because the LuaSocket version used in DCS only listens to IPv4. This avoids the lag caused by the /* Using 127.0.0.1 instead of localhost because the LuaSocket version used in DCS only listens to IPv4. This avoids the lag caused by the
browser if it first tries to send the request on the IPv6 address for localhost */ browser if it first tries to send the request on the IPv6 address for localhost */
this.#cameraOptionsXmlHttp.open("OPTIONS", `http://127.0.0.1:${this.#cameraControlPort}`); this.#cameraOptionsXmlHttp.open("OPTIONS", `http://127.0.0.1:${this.#cameraControlPort}`);

View File

@@ -35,7 +35,6 @@ import { aircraftDatabase } from "./unit/databases/aircraftdatabase";
import { helicopterDatabase } from "./unit/databases/helicopterdatabase"; import { helicopterDatabase } from "./unit/databases/helicopterdatabase";
import { groundUnitDatabase } from "./unit/databases/groundunitdatabase"; import { groundUnitDatabase } from "./unit/databases/groundunitdatabase";
import { navyUnitDatabase } from "./unit/databases/navyunitdatabase"; import { navyUnitDatabase } from "./unit/databases/navyunitdatabase";
import { initFlowbite } from "flowbite";
//import { UnitListPanel } from "./panels/unitlistpanel"; //import { UnitListPanel } from "./panels/unitlistpanel";
//import { ContextManager } from "./context/contextmanager"; //import { ContextManager } from "./context/contextmanager";
//import { Context } from "./context/context"; //import { Context } from "./context/context";
@@ -478,7 +477,7 @@ export class OlympusApp {
} }
/* Temporary */ /* Temporary */
this.getServerManager().setCredentials("admin", "4b8823ed9e5c2392ab4a791913bb8ce41956ea32e308b760eefb97536746dd33"); this.getServerManager().setCredentials("admin", "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b");
this.getServerManager().startUpdate(); this.getServerManager().startUpdate();
/* Reload the page, used to mimic a restart of the app */ /* Reload the page, used to mimic a restart of the app */

View File

@@ -13,7 +13,7 @@ export function Header() {
{(appState) => {(appState) =>
<EventsConsumer> <EventsConsumer>
{(events) => {(events) =>
<nav className="flex w-screen h-[66px] bg-gray-300 border-gray-200 dark:bg-[#171C26] dark:border-gray-700 px-3"> <nav className="flex w-screen h-[66px] bg-gray-300 border-gray-200 dark:bg-[#171C26] dark:border-gray-700 px-3 z-ui-1">
<div className="w-full max-w-full flex flex-nowrap items-center justify-between gap-3 my-auto"> <div className="w-full max-w-full flex flex-nowrap items-center justify-between gap-3 my-auto">
<div className="flex flex-row items-center justify-center gap-1 flex-none"> <div className="flex flex-row items-center justify-center gap-1 flex-none">
<img src="images/icon.png" className='h-10 w-10 p-0 rounded-md mr-2 cursor-pointer'></img> <img src="images/icon.png" className='h-10 w-10 p-0 rounded-md mr-2 cursor-pointer'></img>

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import { Menu } from "./components/menu"; import { Menu } from "./components/menu";
import { faHelicopter, faJetFighter, faPlus, faShieldAlt, faShip, faTruck } from '@fortawesome/free-solid-svg-icons'; import { faHelicopter, faJetFighter, faPlus, faShieldAlt, faShip, faTruck } from '@fortawesome/free-solid-svg-icons';
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
@@ -9,6 +9,7 @@ import { OlUnitEntryList } from "../components/olunitlistentry";
import { UnitSpawnMenu } from "./unitspawnmenu"; import { UnitSpawnMenu } from "./unitspawnmenu";
import { UnitBlueprint } from "../../interfaces"; import { UnitBlueprint } from "../../interfaces";
import { olButtonsVisibilityAircraft, olButtonsVisibilityGroundunit, olButtonsVisibilityGroundunitSam, olButtonsVisibilityHelicopter, olButtonsVisibilityNavyunit } from "../components/olicons"; import { olButtonsVisibilityAircraft, olButtonsVisibilityGroundunit, olButtonsVisibilityGroundunitSam, olButtonsVisibilityHelicopter, olButtonsVisibilityNavyunit } from "../components/olicons";
import { SPAWN_UNIT } from "../../constants/constants";
library.add(faPlus); library.add(faPlus);
@@ -31,6 +32,12 @@ export function SpawnMenu(props: {
var [blueprint, setBlueprint] = useState(null as (null | UnitBlueprint)); var [blueprint, setBlueprint] = useState(null as (null | UnitBlueprint));
var [filterString, setFilterString] = useState(""); var [filterString, setFilterString] = useState("");
useEffect(() => {
if (!props.open || blueprint !== null) {
//getApp()?.getMap()?.setState(SPAWN_UNIT, {name: blueprint?.name ?? '', coalition: 'blue'});
}
} )
/* Filter aircrafts, helicopters, and navyunits */ /* Filter aircrafts, helicopters, and navyunits */
const filteredAircraft = filterUnits(getApp()?.getAircraftDatabase()?.blueprints, filterString); const filteredAircraft = filterUnits(getApp()?.getAircraftDatabase()?.blueprints, filterString);
const filteredHelicopters = filterUnits(getApp()?.getHelicopterDatabase()?.blueprints, filterString); const filteredHelicopters = filterUnits(getApp()?.getHelicopterDatabase()?.blueprints, filterString);
@@ -59,7 +66,7 @@ export function SpawnMenu(props: {
<> <>
{(blueprint === null) && <div className="p-5"> {(blueprint === null) && <div className="p-5">
<OlSearchBar onChange={(ev) => setFilterString(ev.target.value)}/> <OlSearchBar onChange={(ev) => setFilterString(ev.target.value)}/>
<OlAccordion title={`Aircrafts (${Object.keys(filteredAircraft).length})`}> <OlAccordion title={`Aircrafts`}>
<div className="flex flex-col gap-1 max-h-80 overflow-y-scroll"> <div className="flex flex-col gap-1 max-h-80 overflow-y-scroll">
{Object.keys(filteredAircraft).map((key) => { {Object.keys(filteredAircraft).map((key) => {
const blueprint = getApp().getAircraftDatabase().blueprints[key]; const blueprint = getApp().getAircraftDatabase().blueprints[key];
@@ -67,7 +74,7 @@ export function SpawnMenu(props: {
})} })}
</div> </div>
</OlAccordion> </OlAccordion>
<OlAccordion title={`Helicopters (${Object.keys(filteredHelicopters).length})`}> <OlAccordion title={`Helicopters`}>
<div className="flex flex-col gap-1 max-h-80 overflow-y-scroll"> <div className="flex flex-col gap-1 max-h-80 overflow-y-scroll">
{Object.keys(filteredHelicopters).map((key) => { {Object.keys(filteredHelicopters).map((key) => {
const blueprint = getApp().getHelicopterDatabase().blueprints[key]; const blueprint = getApp().getHelicopterDatabase().blueprints[key];
@@ -75,7 +82,7 @@ export function SpawnMenu(props: {
})} })}
</div> </div>
</OlAccordion> </OlAccordion>
<OlAccordion title={`SAM & AAA (${Object.keys(filteredAirDefense).length})`}> <OlAccordion title={`SAM & AAA`}>
<div className="flex flex-col gap-1 max-h-80 overflow-y-scroll"> <div className="flex flex-col gap-1 max-h-80 overflow-y-scroll">
{Object.keys(filteredAirDefense).map((key) => { {Object.keys(filteredAirDefense).map((key) => {
const blueprint = getApp().getGroundUnitDatabase().blueprints[key]; const blueprint = getApp().getGroundUnitDatabase().blueprints[key];
@@ -83,7 +90,7 @@ export function SpawnMenu(props: {
})} })}
</div> </div>
</OlAccordion> </OlAccordion>
<OlAccordion title={`Ground Units (${Object.keys(filteredGroundUnits).length})`}> <OlAccordion title={`Ground Units`}>
<div className="flex flex-col gap-1 max-h-80 overflow-y-scroll"> <div className="flex flex-col gap-1 max-h-80 overflow-y-scroll">
{Object.keys(filteredGroundUnits).map((key) => { {Object.keys(filteredGroundUnits).map((key) => {
const blueprint = getApp().getGroundUnitDatabase().blueprints[key]; const blueprint = getApp().getGroundUnitDatabase().blueprints[key];
@@ -91,7 +98,7 @@ export function SpawnMenu(props: {
})} })}
</div> </div>
</OlAccordion> </OlAccordion>
<OlAccordion title={`Ships and submarines (${Object.keys(filteredNavyUnits).length})`}> <OlAccordion title={`Ships and submarines`}>
<div className="flex flex-col gap-1 max-h-80 overflow-y-scroll"> <div className="flex flex-col gap-1 max-h-80 overflow-y-scroll">
{Object.keys(filteredNavyUnits).map((key) => { {Object.keys(filteredNavyUnits).map((key) => {
const blueprint = getApp().getNavyUnitDatabase().blueprints[key]; const blueprint = getApp().getNavyUnitDatabase().blueprints[key];

View File

@@ -10,6 +10,7 @@ import { OlToggle } from "../components/oltoggle";
import { OlCoalitionToggle } from "../components/olcoalitiontoggle"; import { OlCoalitionToggle } from "../components/olcoalitiontoggle";
import { olButtonsEmissionsAttack, olButtonsEmissionsDefend, olButtonsEmissionsFree, olButtonsEmissionsSilent, olButtonsIntensity1, olButtonsIntensity2, olButtonsIntensity3, olButtonsRoeDesignated, olButtonsRoeFree, olButtonsRoeHold, olButtonsRoeReturn, olButtonsScatter1, olButtonsScatter2, olButtonsScatter3, olButtonsThreatEvade, olButtonsThreatManoeuvre, olButtonsThreatNone, olButtonsThreatPassive } from "../components/olicons"; import { olButtonsEmissionsAttack, olButtonsEmissionsDefend, olButtonsEmissionsFree, olButtonsEmissionsSilent, olButtonsIntensity1, olButtonsIntensity2, olButtonsIntensity3, olButtonsRoeDesignated, olButtonsRoeFree, olButtonsRoeHold, olButtonsRoeReturn, olButtonsScatter1, olButtonsScatter2, olButtonsScatter3, olButtonsThreatEvade, olButtonsThreatManoeuvre, olButtonsThreatNone, olButtonsThreatPassive } from "../components/olicons";
import { Coalition } from "../../types/types"; import { Coalition } from "../../types/types";
import { ftToM, knotsToMs, mToFt, msToKnots } from "../../other/utils";
export function UnitControlMenu() { export function UnitControlMenu() {
var [open, setOpen] = useState(false); var [open, setOpen] = useState(false);
@@ -63,13 +64,13 @@ export function UnitControlMenu() {
/* Update the current values of the shown data */ /* Update the current values of the shown data */
function updateData() { function updateData() {
const getters = { const getters = {
desiredAltitude: (unit: Unit) => { return unit.getDesiredAltitude(); }, desiredAltitude: (unit: Unit) => { return Math.round(mToFt(unit.getDesiredAltitude())); },
desiredAltitudeType: (unit: Unit) => { return unit.getDesiredAltitudeType(); }, desiredAltitudeType: (unit: Unit) => { return unit.getDesiredAltitudeType(); },
desiredSpeed: (unit: Unit) => { return unit.getDesiredSpeed(); }, desiredSpeed: (unit: Unit) => { return Math.round(msToKnots(unit.getDesiredSpeed())); },
desiredSpeedType: (unit: Unit) => { return unit.getDesiredSpeedType(); }, desiredSpeedType: (unit: Unit) => { return unit.getDesiredSpeedType(); },
ROE: (unit: Unit) => { return unit.getROE(); }, ROE: (unit: Unit) => { return unit.getROE(); },
reactionToThreat: (unit: Unit) => { return unit.getReactionToThreat(); }, reactionToThreat: (unit: Unit) => { return unit.getReactionToThreat(); },
emissionsCountermeasures: (unit: Unit) => { return unit.getROE(); }, emissionsCountermeasures: (unit: Unit) => { return unit.getEmissionsCountermeasures(); },
shotsScatter: (unit: Unit) => { return unit.getShotsScatter(); }, shotsScatter: (unit: Unit) => { return unit.getShotsScatter(); },
shotsIntensity: (unit: Unit) => { return unit.getShotsIntensity(); }, shotsIntensity: (unit: Unit) => { return unit.getShotsIntensity(); },
operateAs: (unit: Unit) => { return unit.getOperateAs(); }, operateAs: (unit: Unit) => { return unit.getOperateAs(); },
@@ -158,7 +159,7 @@ export function UnitControlMenu() {
<OlRangeSlider <OlRangeSlider
onChange={(ev) => { onChange={(ev) => {
selectedUnits.forEach((unit) => { selectedUnits.forEach((unit) => {
unit.setAltitude(Number(ev.target.value)); unit.setAltitude(ftToM(Number(ev.target.value)));
setSelectedUnitsData({ setSelectedUnitsData({
...selectedUnitsData, ...selectedUnitsData,
desiredAltitude: Number(ev.target.value) desiredAltitude: Number(ev.target.value)
@@ -200,7 +201,7 @@ export function UnitControlMenu() {
<OlRangeSlider <OlRangeSlider
onChange={(ev) => { onChange={(ev) => {
selectedUnits.forEach((unit) => { selectedUnits.forEach((unit) => {
unit.setSpeed(Number(ev.target.value)); unit.setSpeed(knotsToMs(Number(ev.target.value)));
setSelectedUnitsData({ setSelectedUnitsData({
...selectedUnitsData, ...selectedUnitsData,
desiredSpeed: Number(ev.target.value) desiredSpeed: Number(ev.target.value)
@@ -318,14 +319,14 @@ export function UnitControlMenu() {
return <OlButtonGroupItem return <OlButtonGroupItem
onClick={() => { onClick={() => {
selectedUnits.forEach((unit) => { selectedUnits.forEach((unit) => {
unit.setShotsScatter(idx); unit.setShotsScatter((idx + 1));
setSelectedUnitsData({ setSelectedUnitsData({
...selectedUnitsData, ...selectedUnitsData,
shotsScatter: idx shotsScatter: (idx + 1)
}) })
}) })
}} }}
active={selectedUnitsData.shotsScatter === idx} active={selectedUnitsData.shotsScatter === (idx + 1)}
icon={icon} /> icon={icon} />
}) })
} }
@@ -339,14 +340,14 @@ export function UnitControlMenu() {
return <OlButtonGroupItem return <OlButtonGroupItem
onClick={() => { onClick={() => {
selectedUnits.forEach((unit) => { selectedUnits.forEach((unit) => {
unit.setShotsIntensity(idx); unit.setShotsIntensity((idx + 1));
setSelectedUnitsData({ setSelectedUnitsData({
...selectedUnitsData, ...selectedUnitsData,
shotsIntensity: idx shotsIntensity: (idx + 1)
}) })
}) })
}} }}
active={selectedUnitsData.shotsIntensity === idx} active={selectedUnitsData.shotsIntensity === (idx + 1)}
icon={icon} /> icon={icon} />
}) })
} }

View File

@@ -77,12 +77,12 @@ export function UI() {
<Header /> <Header />
<div className='flex h-full'> <div className='flex h-full'>
<SideBar /> <SideBar />
<div id='map-container' className='relative h-full w-screen top-0 left-0' />
<MainMenu open={mainMenuVisible} onClose={() => setMainMenuVisible(false)} /> <MainMenu open={mainMenuVisible} onClose={() => setMainMenuVisible(false)} />
<SpawnMenu open={spawnMenuVisible} onClose={() => setSpawnMenuVisible(false)} /> <SpawnMenu open={spawnMenuVisible} onClose={() => setSpawnMenuVisible(false)} />
<UnitControlMenu /> <UnitControlMenu />
</div> </div>
</div> </div>
<div id='map-container' className='fixed h-full w-screen top-0 left-0' />
</EventsProvider> </EventsProvider>
</StateProvider> </StateProvider>
</div> </div>

View File

@@ -67,7 +67,7 @@ module.exports = function (configLocation) {
} }
/*
// UNCOMMENT TO TEST ALL UNITS **************** // UNCOMMENT TO TEST ALL UNITS ****************
var databases = Object.assign({}, aircraftDatabase, helicopterDatabase, groundUnitDatabase, navyUnitDatabase); var databases = Object.assign({}, aircraftDatabase, helicopterDatabase, groundUnitDatabase, navyUnitDatabase);
@@ -105,8 +105,8 @@ module.exports = function (configLocation) {
} }
} }
*/
/*
let idx = 1; let idx = 1;
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData)); DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
DEMO_UNIT_DATA[idx].name = "S_75M_Volhov"; DEMO_UNIT_DATA[idx].name = "S_75M_Volhov";
@@ -142,7 +142,6 @@ module.exports = function (configLocation) {
DEMO_UNIT_DATA[idx].coalition = 1; DEMO_UNIT_DATA[idx].coalition = 1;
DEMO_UNIT_DATA[idx].desiredAltitude = 10000; DEMO_UNIT_DATA[idx].desiredAltitude = 10000;
DEMO_UNIT_DATA[idx].desiredAltitudeType = 0; DEMO_UNIT_DATA[idx].desiredAltitudeType = 0;
idx += 1; idx += 1;
DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData)); DEMO_UNIT_DATA[idx] = JSON.parse(JSON.stringify(baseData));
@@ -171,8 +170,7 @@ module.exports = function (configLocation) {
DEMO_UNIT_DATA[idx].position.lat += idx / 100; DEMO_UNIT_DATA[idx].position.lat += idx / 100;
DEMO_UNIT_DATA[idx].category = "Aircraft"; DEMO_UNIT_DATA[idx].category = "Aircraft";
DEMO_UNIT_DATA[idx].isLeader = true; DEMO_UNIT_DATA[idx].isLeader = true;
*/
this.startTime = Date.now(); this.startTime = Date.now();
} }