diff --git a/client/package-lock.json b/client/package-lock.json index f773cef7..2e496915 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "DCSOlympus", - "version": "v0.3.0-alpha", + "version": "v0.4.0-alpha", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "DCSOlympus", - "version": "v0.3.0-alpha", + "version": "v0.4.0-alpha", "dependencies": { "@turf/turf": "^6.5.0", "@types/formatcoords": "^1.1.0", diff --git a/client/package.json b/client/package.json index 9c451789..7c591b58 100644 --- a/client/package.json +++ b/client/package.json @@ -2,7 +2,7 @@ "name": "DCSOlympus", "node-main": "./bin/www", "main": "http://localhost:3000", - "version": "v0.3.0-alpha", + "version": "v0.4.0-alpha", "private": true, "scripts": { "copy": "copy.bat", diff --git a/client/src/controls/mapcontextmenu.ts b/client/src/controls/mapcontextmenu.ts index c90445e0..b2cf335c 100644 --- a/client/src/controls/mapcontextmenu.ts +++ b/client/src/controls/mapcontextmenu.ts @@ -31,7 +31,7 @@ export class MapContextMenu extends ContextMenu { #navyUnitTypeDropdown: Dropdown; #navyUnitNameDropdown: Dropdown; #navyUnitCountDropdown: Dropdown; - #spawnOptions = { role: "", name: "", latlng: new LatLng(0, 0), coalition: "blue", loadout: "", airbaseName: "", altitude: ftToM(20000), count: 1 }; + #spawnOptions = { role: "", name: "", latlng: new LatLng(0, 0), coalition: "blue", loadout: "", airbaseName: "", altitude: 0, count: 1 }; #coalitionArea: CoalitionArea | null = null; constructor(id: string) { @@ -89,7 +89,7 @@ export class MapContextMenu extends ContextMenu { this.hideSubMenus(e.detail.type); }); - document.addEventListener("contextMenuDeployAircraft", () => { + document.addEventListener("contextMenuDeployAircrafts", () => { this.hide(); this.#spawnOptions.coalition = getActiveCoalition(); if (this.#spawnOptions) { @@ -103,7 +103,7 @@ export class MapContextMenu extends ContextMenu { } }); - document.addEventListener("contextMenuDeployHelicopter", () => { + document.addEventListener("contextMenuDeployHelicopters", () => { this.hide(); this.#spawnOptions.coalition = getActiveCoalition(); if (this.#spawnOptions) { @@ -117,7 +117,7 @@ export class MapContextMenu extends ContextMenu { } }); - document.addEventListener("contextMenuDeployGroundUnit", () => { + document.addEventListener("contextMenuDeployGroundUnits", () => { this.hide(); this.#spawnOptions.coalition = getActiveCoalition(); if (this.#spawnOptions) { @@ -222,6 +222,13 @@ export class MapContextMenu extends ContextMenu { this.#groundUnitCountDropdown.setValue("1"); this.clip(); + if (type === "aircraft") { + this.#spawnOptions.altitude = ftToM(this.#aircraftSpawnAltitudeSlider.getValue()); + } + else if (type === "helicopter") { + this.#spawnOptions.altitude = ftToM(this.#helicopterSpawnAltitudeSlider.getValue()); + } + this.setVisibleSubMenu(type); } diff --git a/client/src/map/map.ts b/client/src/map/map.ts index 6c50858a..1d3053e5 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -17,6 +17,8 @@ import { TargetMarker } from "./targetmarker"; import { CoalitionArea } from "./coalitionarea"; import { CoalitionAreaContextMenu } from "../controls/coalitionareacontextmenu"; import { DrawingCursor } from "./drawingcursor"; +import { aircraftDatabase } from "../units/aircraftdatabase"; +import { groundUnitDatabase } from "../units/groundunitdatabase"; L.Map.addInitHook('addHandler', 'boxSelect', BoxSelect); @@ -422,6 +424,9 @@ export class Map extends L.Map { #onDoubleClick(e: any) { this.deselectAllCoalitionAreas(); + + var db = groundUnitDatabase; + db.generateTestGrid(this.getMouseCoordinates()) } #onContextMenu(e: any) { diff --git a/client/src/server/server.ts b/client/src/server/server.ts index 52f64b87..26841dfb 100644 --- a/client/src/server/server.ts +++ b/client/src/server/server.ts @@ -153,7 +153,7 @@ export function spawnAircrafts(units: any, coalition: string, airbaseName: strin export function spawnHelicopters(units: any, coalition: string, airbaseName: string, immediate: boolean) { var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "immediate": immediate }; - var data = { "spawnHelicopter": command } + var data = { "spawnHelicopters": command } POST(data, () => { }); } @@ -191,8 +191,8 @@ export function cloneUnit(ID: number, latlng: LatLng) { POST(data, () => { }); } -export function deleteUnit(ID: number, explosion: boolean) { - var command = { "ID": ID, "explosion": explosion }; +export function deleteUnit(ID: number, explosion: boolean, immediate: boolean) { + var command = { "ID": ID, "explosion": explosion, "immediate": immediate }; var data = { "deleteUnit": command } POST(data, () => { }); } diff --git a/client/src/units/aircraftdatabase.ts b/client/src/units/aircraftdatabase.ts index a798d841..b7044f8f 100644 --- a/client/src/units/aircraftdatabase.ts +++ b/client/src/units/aircraftdatabase.ts @@ -3906,6 +3906,10 @@ export class AircraftDatabase extends UnitDatabase { } } } + + getCategory() { + return "Aircraft"; + } } export var aircraftDatabase = new AircraftDatabase(); diff --git a/client/src/units/groundunitdatabase.ts b/client/src/units/groundunitdatabase.ts index b6e94fe6..dd100eee 100644 --- a/client/src/units/groundunitdatabase.ts +++ b/client/src/units/groundunitdatabase.ts @@ -1537,6 +1537,10 @@ export class GroundUnitDatabase extends UnitDatabase { } } } + + getCategory() { + return "GroundUnit"; + } } export var groundUnitDatabase = new GroundUnitDatabase(); diff --git a/client/src/units/helicopterdatabase.ts b/client/src/units/helicopterdatabase.ts index 04b4dda9..e00ac1f5 100644 --- a/client/src/units/helicopterdatabase.ts +++ b/client/src/units/helicopterdatabase.ts @@ -578,6 +578,10 @@ export class HelicopterDatabase extends UnitDatabase { } } } + + getCategory() { + return "Helicopter"; + } } export var helicopterDatabase = new HelicopterDatabase(); diff --git a/client/src/units/navyunitdatabase.ts b/client/src/units/navyunitdatabase.ts index b157f5d2..57d3cb1c 100644 --- a/client/src/units/navyunitdatabase.ts +++ b/client/src/units/navyunitdatabase.ts @@ -631,8 +631,8 @@ export class NavyUnitDatabase extends UnitDatabase { "range": "", "filename": "" }, - "Ticonderoga": { - "name": "Ticonderoga", + "TICONDEROG": { + "name": "TICONDEROG", "type": "Cruiser", "era": [ "Late Cold War" @@ -941,6 +941,10 @@ export class NavyUnitDatabase extends UnitDatabase { } } } + + getCategory() { + return "NavyUnit"; + } } export var navyUnitDatabase = new NavyUnitDatabase(); diff --git a/client/src/units/unit.ts b/client/src/units/unit.ts index ca4d66a9..fc5f13a8 100644 --- a/client/src/units/unit.ts +++ b/client/src/units/unit.ts @@ -646,8 +646,8 @@ export class Unit extends CustomMarker { setFollowRoads(this.ID, followRoads); } - delete(explosion: boolean) { - deleteUnit(this.ID, explosion); + delete(explosion: boolean, immediate: boolean) { + deleteUnit(this.ID, explosion, immediate); } refuel() { diff --git a/client/src/units/unitdatabase.ts b/client/src/units/unitdatabase.ts index 68fc7120..cb00b912 100644 --- a/client/src/units/unitdatabase.ts +++ b/client/src/units/unitdatabase.ts @@ -1,3 +1,6 @@ +import { LatLng } from "leaflet"; +import { getUnitsManager } from ".."; + export class UnitDatabase { blueprints: { [key: string]: UnitBlueprint } = {}; @@ -5,6 +8,10 @@ export class UnitDatabase { } + getCategory() { + return ""; + } + getBlueprints() { return this.blueprints; } @@ -143,4 +150,16 @@ export class UnitDatabase { } return null; } + + generateTestGrid(initialPosition: LatLng) { + const step = 0.01; + var nUnits = Object.values(this.blueprints).length; + var gridSize = Math.ceil(Math.sqrt(nUnits)); + Object.values(this.blueprints).forEach((unitBlueprint: UnitBlueprint, idx: number) => { + var row = Math.floor(idx / gridSize); + var col = idx - row * gridSize; + var location = new LatLng(initialPosition.lat + col * step, initialPosition.lng + row * step) + getUnitsManager().spawnUnit(this.getCategory(), [{unitType: unitBlueprint.name, location: location, altitude: 1000, loadout: ""}]); + }) + } } \ No newline at end of file diff --git a/client/src/units/unitsmanager.ts b/client/src/units/unitsmanager.ts index bd35acbf..0041aa0d 100644 --- a/client/src/units/unitsmanager.ts +++ b/client/src/units/unitsmanager.ts @@ -1,15 +1,14 @@ import { LatLng, LatLngBounds } from "leaflet"; -import { getHotgroupPanel, getInfoPopup, getMap, getMissionHandler } from ".."; +import { getHotgroupPanel, getInfoPopup, getMap } from ".."; import { Unit } from "./unit"; -import { cloneUnit, setLastUpdateTime, spawnGroundUnits } from "../server/server"; +import { cloneUnit, setLastUpdateTime, spawnAircrafts, spawnGroundUnits } from "../server/server"; import { bearingAndDistanceToLatLng, deg2rad, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polyContains, polygonArea, randomPointInPoly, randomUnitBlueprint } from "../other/utils"; import { CoalitionArea } from "../map/coalitionarea"; -import { Airbase } from "../missionhandler/airbase"; import { groundUnitDatabase } from "./groundunitdatabase"; import { DataIndexes, HIDE_ALL, IADSDensities, IDLE, MOVE_UNIT } from "../constants/constants"; import { DataExtractor } from "./dataextractor"; import { Contact } from "../@types/unit"; -import { citiesDatabase } from "./citiesDatabase"; +import { citiesDatabase } from "./citiesdatabase"; export class UnitsManager { #units: { [ID: number]: Unit }; @@ -378,8 +377,12 @@ export class UnitsManager { return; } + var immediate = false; + if (selectedUnits.length > 20) + immediate = confirm(`You are trying to delete ${selectedUnits.length} units, do you want to delete them immediately? This may cause lag for players.`) + for (let idx in selectedUnits) { - selectedUnits[idx].delete(explosion); + selectedUnits[idx].delete(explosion, immediate); } this.#showActionMessage(selectedUnits, `deleted`); } @@ -518,7 +521,7 @@ export class UnitsManager { if (this.#units[idx].getCoalition() !== "neutral" && this.#units[idx].getCoalition() != unit.getCoalition()) { this.#units[idx].getContacts().forEach((contact: Contact) => { - if (contact.ID == unit.ID && !detectionMethods.includes(contact.detectionMethod)) + if (this.#units[idx].getAlive() && contact.ID == unit.ID && !detectionMethods.includes(contact.detectionMethod)) detectionMethods.push(contact.detectionMethod); }); } @@ -616,6 +619,14 @@ export class UnitsManager { input.click(); } + spawnUnit(category: string, units: any, coalition: string = "blue", immediate: boolean = true) { + if (category === "Aircraft") { + spawnAircrafts(units, coalition, "", immediate); + } else if (category === "GroundUnit") { + spawnGroundUnits(units, coalition, immediate); + } + } + /***********************************************/ #onKeyUp(event: KeyboardEvent) { if (!keyEventWasInInput(event) && event.key === "Delete" ) { diff --git a/client/views/other/contextmenus.ejs b/client/views/other/contextmenus.ejs index 197cbb63..9bb8e91b 100644 --- a/client/views/other/contextmenus.ejs +++ b/client/views/other/contextmenus.ejs @@ -4,8 +4,8 @@
- +