mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Merge pull request #377 from Pax1601/370-write-better-method-of-determining-if-a-command-has-been-completed
370 write better method of determining if a command has been completed
This commit is contained in:
@@ -112,6 +112,8 @@ class DemoDataGenerator {
|
||||
app.get('/demo/bullseyes', (req, res) => this.bullseyes(req, res));
|
||||
app.get('/demo/airbases', (req, res) => this.airbases(req, res));
|
||||
app.get('/demo/mission', (req, res) => this.mission(req, res));
|
||||
app.get('/demo/commands', (req, res) => this.command(req, res));
|
||||
app.put('/demo', (req, res) => this.put(req, res));
|
||||
|
||||
app.use('/demo', basicAuth({
|
||||
users: {
|
||||
@@ -457,7 +459,17 @@ class DemoDataGenerator {
|
||||
}
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
command(req, res) {
|
||||
var ret = {commandExecuted: Math.random() > 0.5};
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
put(req, res) {
|
||||
var ret = {commandHash: Math.random().toString(36).slice(2, 19)}
|
||||
res.send(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = DemoDataGenerator;
|
||||
5
client/src/@types/server.d.ts
vendored
5
client/src/@types/server.d.ts
vendored
@@ -44,4 +44,9 @@ interface LogData {
|
||||
logs: {[key: string]: string},
|
||||
sessionHash: string;
|
||||
time: number;
|
||||
}
|
||||
|
||||
interface ServerRequestOptions {
|
||||
time?: number;
|
||||
commandHash?: string;
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
import { LatLng, LatLngBounds } from "leaflet";
|
||||
|
||||
export const UNITS_URI = "units";
|
||||
export const WEAPONS_URI = "weapons";
|
||||
export const LOGS_URI = "logs";
|
||||
export const AIRBASES_URI = "airbases";
|
||||
export const BULLSEYE_URI = "bullseyes";
|
||||
export const MISSION_URI = "mission";
|
||||
export const COMMANDS_URI = "commands";
|
||||
|
||||
export const NONE = "None";
|
||||
export const GAME_MASTER = "Game master";
|
||||
export const BLUE_COMMANDER = "Blue commander";
|
||||
|
||||
@@ -2,6 +2,7 @@ import { getMap, getMissionHandler, getUnitsManager, setActiveCoalition } from "
|
||||
import { GAME_MASTER } from "../constants/constants";
|
||||
import { Airbase } from "../mission/airbase";
|
||||
import { dataPointMap } from "../other/utils";
|
||||
import { Unit } from "../unit/unit";
|
||||
import { ContextMenu } from "./contextmenu";
|
||||
|
||||
/** This context menu is shown to the user when the airbase marker is right clicked on the map.
|
||||
@@ -38,7 +39,7 @@ export class AirbaseContextMenu extends ContextMenu {
|
||||
this.#setProperties(this.#airbase.getProperties());
|
||||
this.#setParkings(this.#airbase.getParkings());
|
||||
this.#setCoalition(this.#airbase.getCoalition());
|
||||
this.#showLandButton(getUnitsManager().getSelectedUnitsTypes().length == 1 && ["Aircraft", "Helicopter"].includes(getUnitsManager().getSelectedUnitsTypes()[0]) && (getUnitsManager().getSelectedUnitsCoalition() === this.#airbase.getCoalition() || this.#airbase.getCoalition() === "neutral"))
|
||||
this.#showLandButton(getUnitsManager().getSelectedUnitsTypes().length == 1 && ["Aircraft", "Helicopter"].includes(getUnitsManager().getSelectedUnitsTypes()[0]) && (getUnitsManager().getSelectedUnitsVariable((unit: Unit) => {return unit.getCoalition()}) === this.#airbase.getCoalition() || this.#airbase.getCoalition() === "neutral"))
|
||||
this.#showSpawnButton(getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER || this.#airbase.getCoalition() == getMissionHandler().getCommandedCoalition());
|
||||
this.#setAirbaseData();
|
||||
|
||||
|
||||
@@ -412,10 +412,13 @@ export class AircraftSpawnMenu extends UnitSpawnMenu {
|
||||
for (let i = 1; i < unitsCount + 1; i++) {
|
||||
units.push(unitTable);
|
||||
}
|
||||
if (getUnitsManager().spawnUnits("Aircraft", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country)) {
|
||||
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition());
|
||||
getMap().getMapContextMenu().hide();
|
||||
}
|
||||
|
||||
getUnitsManager().spawnUnits("Aircraft", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => {
|
||||
if (res.commandHash !== undefined)
|
||||
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash);
|
||||
});
|
||||
|
||||
getMap().getMapContextMenu().hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -447,10 +450,13 @@ export class HelicopterSpawnMenu extends UnitSpawnMenu {
|
||||
for (let i = 1; i < unitsCount + 1; i++) {
|
||||
units.push(unitTable);
|
||||
}
|
||||
if (getUnitsManager().spawnUnits("Helicopter", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country)) {
|
||||
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition());
|
||||
getMap().getMapContextMenu().hide();
|
||||
}
|
||||
|
||||
getUnitsManager().spawnUnits("Helicopter", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => {
|
||||
if (res.commandHash !== undefined)
|
||||
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash);
|
||||
});
|
||||
|
||||
getMap().getMapContextMenu().hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -481,10 +487,13 @@ export class GroundUnitSpawnMenu extends UnitSpawnMenu {
|
||||
units.push(JSON.parse(JSON.stringify(unitTable)));
|
||||
unitTable.location.lat += 0.0001;
|
||||
}
|
||||
if (getUnitsManager().spawnUnits("GroundUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country)) {
|
||||
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition());
|
||||
getMap().getMapContextMenu().hide();
|
||||
}
|
||||
|
||||
getUnitsManager().spawnUnits("GroundUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => {
|
||||
if (res.commandHash !== undefined)
|
||||
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash);
|
||||
});
|
||||
|
||||
getMap().getMapContextMenu().hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -515,10 +524,13 @@ export class NavyUnitSpawnMenu extends UnitSpawnMenu {
|
||||
units.push(JSON.parse(JSON.stringify(unitTable)));
|
||||
unitTable.location.lat += 0.0001;
|
||||
}
|
||||
if (getUnitsManager().spawnUnits("NavyUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country)) {
|
||||
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition());
|
||||
getMap().getMapContextMenu().hide();
|
||||
}
|
||||
|
||||
getUnitsManager().spawnUnits("NavyUnit", units, getActiveCoalition(), false, spawnOptions.airbase ? spawnOptions.airbase.getName() : "", spawnOptions.country, (res: any) => {
|
||||
if (res.commandHash !== undefined)
|
||||
getMap().addTemporaryMarker(spawnOptions.latlng, spawnOptions.name, getActiveCoalition(), res.commandHash);
|
||||
});
|
||||
|
||||
getMap().getMapContextMenu().hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,29 +425,11 @@ export class Map extends L.Map {
|
||||
}
|
||||
}
|
||||
|
||||
addTemporaryMarker(latlng: L.LatLng, name: string, coalition: string) {
|
||||
var marker = new TemporaryUnitMarker(latlng, name, coalition);
|
||||
addTemporaryMarker(latlng: L.LatLng, name: string, coalition: string, commandHash?: string) {
|
||||
var marker = new TemporaryUnitMarker(latlng, name, coalition, commandHash);
|
||||
marker.addTo(this);
|
||||
this.#temporaryMarkers.push(marker);
|
||||
}
|
||||
|
||||
removeTemporaryMarker(latlng: L.LatLng) {
|
||||
// TODO something more refined than this
|
||||
var dist: number | null = null;
|
||||
var closest: L.Marker | null = null;
|
||||
var i: number = 0;
|
||||
this.#temporaryMarkers.forEach((marker: L.Marker, idx: number) => {
|
||||
var t = latlng.distanceTo(marker.getLatLng());
|
||||
if (dist == null || t < dist) {
|
||||
dist = t;
|
||||
closest = marker;
|
||||
i = idx;
|
||||
}
|
||||
});
|
||||
if (closest && dist != null && dist < 100) {
|
||||
this.removeLayer(closest);
|
||||
this.#temporaryMarkers.splice(i, 1);
|
||||
}
|
||||
return marker;
|
||||
}
|
||||
|
||||
getSelectedCoalitionArea() {
|
||||
|
||||
@@ -2,15 +2,37 @@ import { CustomMarker } from "./custommarker";
|
||||
import { DivIcon, LatLng } from "leaflet";
|
||||
import { SVGInjector } from "@tanem/svg-injector";
|
||||
import { getMarkerCategoryByName, getUnitDatabaseByCategory } from "../other/utils";
|
||||
import { isCommandExecuted } from "../server/server";
|
||||
import { getMap } from "..";
|
||||
|
||||
export class TemporaryUnitMarker extends CustomMarker {
|
||||
#name: string;
|
||||
#coalition: string;
|
||||
#commandHash: string|undefined = undefined;
|
||||
#timer: number = 0;
|
||||
|
||||
constructor(latlng: LatLng, name: string, coalition: string) {
|
||||
constructor(latlng: LatLng, name: string, coalition: string, commandHash?: string) {
|
||||
super(latlng, {interactive: false});
|
||||
this.#name = name;
|
||||
this.#coalition = coalition;
|
||||
this.#commandHash = commandHash;
|
||||
|
||||
if (commandHash !== undefined)
|
||||
this.setCommandHash(commandHash)
|
||||
}
|
||||
|
||||
setCommandHash(commandHash: string) {
|
||||
this.#commandHash = commandHash;
|
||||
this.#timer = window.setInterval(() => {
|
||||
if (this.#commandHash !== undefined) {
|
||||
isCommandExecuted((res: any) => {
|
||||
if (res.commandExecuted) {
|
||||
this.removeFrom(getMap());
|
||||
window.clearInterval(this.#timer);
|
||||
}
|
||||
}, this.#commandHash)
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
createIcon() {
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
import { LatLng } from 'leaflet';
|
||||
import { getConnectionStatusPanel, getInfoPopup, getLogPanel, getMissionHandler, getServerStatusPanel, getUnitsManager, getWeaponsManager, setLoginStatus } from '..';
|
||||
import { GeneralSettings, Radio, TACAN } from '../@types/unit';
|
||||
import { NONE, ROEs, emissionsCountermeasures, reactionsToThreat } from '../constants/constants';
|
||||
import { AIRBASES_URI, BULLSEYE_URI, COMMANDS_URI, LOGS_URI, MISSION_URI, NONE, ROEs, UNITS_URI, WEAPONS_URI, emissionsCountermeasures, reactionsToThreat } from '../constants/constants';
|
||||
|
||||
var connected: boolean = false;
|
||||
var paused: boolean = false;
|
||||
|
||||
var REST_ADDRESS = "http://localhost:30000/olympus";
|
||||
var DEMO_ADDRESS = window.location.href + "demo";
|
||||
const UNITS_URI = "units";
|
||||
const WEAPONS_URI = "weapons";
|
||||
const LOGS_URI = "logs";
|
||||
const AIRBASES_URI = "airbases";
|
||||
const BULLSEYE_URI = "bullseyes";
|
||||
const MISSION_URI = "mission";
|
||||
|
||||
var username = "";
|
||||
var password = "";
|
||||
@@ -38,13 +32,15 @@ export function setCredentials(newUsername: string, newPassword: string) {
|
||||
password = newPassword;
|
||||
}
|
||||
|
||||
export function GET(callback: CallableFunction, uri: string, options?: { time?: number }, responseType?: string) {
|
||||
export function GET(callback: CallableFunction, uri: string, options?: ServerRequestOptions, responseType?: string) {
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
|
||||
/* Assemble the request options string */
|
||||
var optionsString = '';
|
||||
if (options?.time != undefined)
|
||||
optionsString = `time=${options.time}`;
|
||||
if (options?.commandHash != undefined)
|
||||
optionsString = `commandHash=${options.commandHash}`;
|
||||
|
||||
/* On the connection */
|
||||
xmlHttp.open("GET", `${demoEnabled ? DEMO_ADDRESS : REST_ADDRESS}/${uri}${optionsString ? `?${optionsString}` : ''}`, true);
|
||||
@@ -92,8 +88,9 @@ export function POST(request: object, callback: CallableFunction) {
|
||||
xmlHttp.setRequestHeader("Content-Type", "application/json");
|
||||
if (username && password)
|
||||
xmlHttp.setRequestHeader("Authorization", "Basic " + btoa(`${username}:${password}`));
|
||||
xmlHttp.onreadystatechange = () => {
|
||||
callback();
|
||||
xmlHttp.onload = (res: any) => {
|
||||
var res = JSON.parse(xmlHttp.responseText);
|
||||
callback(res);
|
||||
};
|
||||
xmlHttp.send(JSON.stringify(request));
|
||||
}
|
||||
@@ -140,185 +137,189 @@ export function getWeapons(callback: CallableFunction, refresh: boolean = false)
|
||||
GET(callback, WEAPONS_URI, { time: refresh ? 0 : lastUpdateTimes[WEAPONS_URI] }, 'arraybuffer');
|
||||
}
|
||||
|
||||
export function addDestination(ID: number, path: any) {
|
||||
export function isCommandExecuted(callback: CallableFunction, commandHash: string) {
|
||||
GET(callback, COMMANDS_URI, { commandHash: commandHash});
|
||||
}
|
||||
|
||||
export function addDestination(ID: number, path: any, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "path": path }
|
||||
var data = { "setPath": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function spawnSmoke(color: string, latlng: LatLng) {
|
||||
export function spawnSmoke(color: string, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||
var command = { "color": color, "location": latlng };
|
||||
var data = { "smoke": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function spawnExplosion(intensity: number, latlng: LatLng) {
|
||||
export function spawnExplosion(intensity: number, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||
var command = { "intensity": intensity, "location": latlng };
|
||||
var data = { "explosion": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function spawnAircrafts(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number) {
|
||||
export function spawnAircrafts(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
|
||||
var data = { "spawnAircrafts": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function spawnHelicopters(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number) {
|
||||
export function spawnHelicopters(units: any, coalition: string, airbaseName: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "units": units, "coalition": coalition, "airbaseName": airbaseName, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
|
||||
var data = { "spawnHelicopters": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function spawnGroundUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number) {
|
||||
export function spawnGroundUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };;
|
||||
var data = { "spawnGroundUnits": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function spawnNavyUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number) {
|
||||
export function spawnNavyUnits(units: any, coalition: string, country: string, immediate: boolean, spawnPoints: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "units": units, "coalition": coalition, "country": country, "immediate": immediate, "spawnPoints": spawnPoints };
|
||||
var data = { "spawnNavyUnits": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function attackUnit(ID: number, targetID: number) {
|
||||
export function attackUnit(ID: number, targetID: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "targetID": targetID };
|
||||
var data = { "attackUnit": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function followUnit(ID: number, targetID: number, offset: { "x": number, "y": number, "z": number }) {
|
||||
export function followUnit(ID: number, targetID: number, offset: { "x": number, "y": number, "z": number }, callback: CallableFunction = () => {}) {
|
||||
// X: front-rear, positive front
|
||||
// Y: top-bottom, positive bottom
|
||||
// Z: left-right, positive right
|
||||
|
||||
var command = { "ID": ID, "targetID": targetID, "offsetX": offset["x"], "offsetY": offset["y"], "offsetZ": offset["z"] };
|
||||
var data = { "followUnit": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function cloneUnit(ID: number, latlng: LatLng) {
|
||||
var command = { "ID": ID, "location": latlng };
|
||||
var data = { "cloneUnit": command }
|
||||
POST(data, () => { });
|
||||
export function cloneUnits(units: {ID: number, location: LatLng}[], deleteOriginal: boolean, callback: CallableFunction = () => {}) {
|
||||
var command = { "units": units, "deleteOriginal": deleteOriginal };
|
||||
var data = { "cloneUnits": command }
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function deleteUnit(ID: number, explosion: boolean, immediate: boolean) {
|
||||
export function deleteUnit(ID: number, explosion: boolean, immediate: boolean, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "explosion": explosion, "immediate": immediate };
|
||||
var data = { "deleteUnit": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function landAt(ID: number, latlng: LatLng) {
|
||||
export function landAt(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "location": latlng };
|
||||
var data = { "landAt": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function changeSpeed(ID: number, speedChange: string) {
|
||||
export function changeSpeed(ID: number, speedChange: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "change": speedChange }
|
||||
var data = { "changeSpeed": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setSpeed(ID: number, speed: number) {
|
||||
export function setSpeed(ID: number, speed: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "speed": speed }
|
||||
var data = { "setSpeed": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setSpeedType(ID: number, speedType: string) {
|
||||
export function setSpeedType(ID: number, speedType: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "speedType": speedType }
|
||||
var data = { "setSpeedType": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function changeAltitude(ID: number, altitudeChange: string) {
|
||||
export function changeAltitude(ID: number, altitudeChange: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "change": altitudeChange }
|
||||
var data = { "changeAltitude": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setAltitudeType(ID: number, altitudeType: string) {
|
||||
export function setAltitudeType(ID: number, altitudeType: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "altitudeType": altitudeType }
|
||||
var data = { "setAltitudeType": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setAltitude(ID: number, altitude: number) {
|
||||
export function setAltitude(ID: number, altitude: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "altitude": altitude }
|
||||
var data = { "setAltitude": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function createFormation(ID: number, isLeader: boolean, wingmenIDs: number[]) {
|
||||
export function createFormation(ID: number, isLeader: boolean, wingmenIDs: number[], callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "wingmenIDs": wingmenIDs, "isLeader": isLeader }
|
||||
var data = { "setLeader": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setROE(ID: number, ROE: string) {
|
||||
export function setROE(ID: number, ROE: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "ROE": ROEs.indexOf(ROE) }
|
||||
var data = { "setROE": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setReactionToThreat(ID: number, reactionToThreat: string) {
|
||||
export function setReactionToThreat(ID: number, reactionToThreat: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "reactionToThreat": reactionsToThreat.indexOf(reactionToThreat) }
|
||||
var data = { "setReactionToThreat": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setEmissionsCountermeasures(ID: number, emissionCountermeasure: string) {
|
||||
export function setEmissionsCountermeasures(ID: number, emissionCountermeasure: string, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "emissionsCountermeasures": emissionsCountermeasures.indexOf(emissionCountermeasure) }
|
||||
var data = { "setEmissionsCountermeasures": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setOnOff(ID: number, onOff: boolean) {
|
||||
export function setOnOff(ID: number, onOff: boolean, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "onOff": onOff }
|
||||
var data = { "setOnOff": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setFollowRoads(ID: number, followRoads: boolean) {
|
||||
export function setFollowRoads(ID: number, followRoads: boolean, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "followRoads": followRoads }
|
||||
var data = { "setFollowRoads": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function refuel(ID: number) {
|
||||
export function refuel(ID: number, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID };
|
||||
var data = { "refuel": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function bombPoint(ID: number, latlng: LatLng) {
|
||||
export function bombPoint(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "location": latlng }
|
||||
var data = { "bombPoint": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function carpetBomb(ID: number, latlng: LatLng) {
|
||||
export function carpetBomb(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "location": latlng }
|
||||
var data = { "carpetBomb": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function bombBuilding(ID: number, latlng: LatLng) {
|
||||
export function bombBuilding(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "location": latlng }
|
||||
var data = { "bombBuilding": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function fireAtArea(ID: number, latlng: LatLng) {
|
||||
export function fireAtArea(ID: number, latlng: LatLng, callback: CallableFunction = () => {}) {
|
||||
var command = { "ID": ID, "location": latlng }
|
||||
var data = { "fireAtArea": command }
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings) {
|
||||
export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings, callback: CallableFunction = () => {}) {
|
||||
var command = {
|
||||
"ID": ID,
|
||||
"isTanker": isTanker,
|
||||
@@ -329,10 +330,10 @@ export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolea
|
||||
};
|
||||
|
||||
var data = { "setAdvancedOptions": command };
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {blue: number, red: number}, eras: string[], setupTime: number) {
|
||||
export function setCommandModeOptions(restrictSpawns: boolean, restrictToCoalition: boolean, spawnPoints: {blue: number, red: number}, eras: string[], setupTime: number, callback: CallableFunction = () => {}) {
|
||||
var command = {
|
||||
"restrictSpawns": restrictSpawns,
|
||||
"restrictToCoalition": restrictToCoalition,
|
||||
@@ -342,7 +343,7 @@ export function setCommandModeOptions(restrictSpawns: boolean, restrictToCoaliti
|
||||
};
|
||||
|
||||
var data = { "setCommandModeOptions": command };
|
||||
POST(data, () => { });
|
||||
POST(data, callback);
|
||||
}
|
||||
|
||||
export function startUpdate() {
|
||||
|
||||
@@ -715,8 +715,6 @@ export class Unit extends CustomMarker {
|
||||
/***********************************************/
|
||||
onAdd(map: Map): this {
|
||||
super.onAdd(map);
|
||||
/* If this is the first time adding this unit to the map, remove the temporary marker */
|
||||
getMap().removeTemporaryMarker(new LatLng(this.#position.lat, this.#position.lng));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { LatLng, LatLngBounds } from "leaflet";
|
||||
import { getHotgroupPanel, getInfoPopup, getMap, getMissionHandler, getUnitsManager, getWeaponsManager } from "..";
|
||||
import { Unit } from "./unit";
|
||||
import { cloneUnit, deleteUnit, refreshAll, spawnAircrafts, spawnGroundUnits, spawnHelicopters, spawnNavyUnits } from "../server/server";
|
||||
import { cloneUnits, deleteUnit, spawnAircrafts, spawnGroundUnits, spawnHelicopters, spawnNavyUnits } from "../server/server";
|
||||
import { bearingAndDistanceToLatLng, deg2rad, keyEventWasInInput, latLngToMercator, mToFt, mercatorToLatLng, msToKnots, polyContains, polygonArea, randomPointInPoly, randomUnitBlueprint } from "../other/utils";
|
||||
import { CoalitionArea } from "../map/coalitionarea";
|
||||
import { groundUnitDatabase } from "./groundunitdatabase";
|
||||
@@ -12,6 +12,7 @@ import { citiesDatabase } from "./citiesDatabase";
|
||||
import { aircraftDatabase } from "./aircraftdatabase";
|
||||
import { helicopterDatabase } from "./helicopterdatabase";
|
||||
import { navyUnitDatabase } from "./navyunitdatabase";
|
||||
import { TemporaryUnitMarker } from "../map/temporaryunitmarker";
|
||||
|
||||
export class UnitsManager {
|
||||
#units: { [ID: number]: Unit };
|
||||
@@ -34,10 +35,10 @@ export class UnitsManager {
|
||||
document.addEventListener('keyup', (event) => this.#onKeyUp(event));
|
||||
document.addEventListener('exportToFile', () => this.exportToFile());
|
||||
document.addEventListener('importFromFile', () => this.importFromFile());
|
||||
document.addEventListener('contactsUpdated', (e: CustomEvent) => {this.#requestDetectionUpdate = true});
|
||||
document.addEventListener('commandModeOptionsChanged', () => {Object.values(this.#units).forEach((unit: Unit) => unit.updateVisibility())});
|
||||
document.addEventListener('selectedUnitsChangeSpeed', (e: any) => {this.selectedUnitsChangeSpeed(e.detail.type)});
|
||||
document.addEventListener('selectedUnitsChangeAltitude', (e: any) => {this.selectedUnitsChangeAltitude(e.detail.type)});
|
||||
document.addEventListener('contactsUpdated', (e: CustomEvent) => { this.#requestDetectionUpdate = true });
|
||||
document.addEventListener('commandModeOptionsChanged', () => { Object.values(this.#units).forEach((unit: Unit) => unit.updateVisibility()) });
|
||||
document.addEventListener('selectedUnitsChangeSpeed', (e: any) => { this.selectedUnitsChangeSpeed(e.detail.type) });
|
||||
document.addEventListener('selectedUnitsChangeAltitude', (e: any) => { this.selectedUnitsChangeAltitude(e.detail.type) });
|
||||
}
|
||||
|
||||
getSelectableAircraft() {
|
||||
@@ -66,7 +67,7 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
addUnit(ID: number, category: string) {
|
||||
if (category){
|
||||
if (category) {
|
||||
/* The name of the unit category is exactly the same as the constructor name */
|
||||
var constructor = Unit.getConstructor(category);
|
||||
if (constructor != undefined) {
|
||||
@@ -91,21 +92,21 @@ export class UnitsManager {
|
||||
return updateTime;
|
||||
}
|
||||
}
|
||||
this.#units[ID]?.setData(dataExtractor);
|
||||
this.#units[ID]?.setData(dataExtractor);
|
||||
}
|
||||
|
||||
if (this.#requestDetectionUpdate && getMissionHandler().getCommandModeOptions().commandMode != GAME_MASTER) {
|
||||
/* Create a dictionary of empty detection methods arrays */
|
||||
var detectionMethods: {[key: string]: number[]} = {};
|
||||
for (let ID in this.#units)
|
||||
var detectionMethods: { [key: string]: number[] } = {};
|
||||
for (let ID in this.#units)
|
||||
detectionMethods[ID] = [];
|
||||
for (let ID in getWeaponsManager().getWeapons())
|
||||
for (let ID in getWeaponsManager().getWeapons())
|
||||
detectionMethods[ID] = [];
|
||||
|
||||
|
||||
/* Fill the array with the detection methods */
|
||||
for (let ID in this.#units) {
|
||||
const unit = this.#units[ID];
|
||||
if (unit.getAlive() && unit.belongsToCommandedCoalition()){
|
||||
if (unit.getAlive() && unit.belongsToCommandedCoalition()) {
|
||||
const contacts = unit.getContacts();
|
||||
contacts.forEach((contact: Contact) => {
|
||||
const contactID = contact.ID;
|
||||
@@ -196,11 +197,11 @@ export class UnitsManager {
|
||||
}
|
||||
}
|
||||
|
||||
deselectUnit( ID:number ) {
|
||||
if ( this.#units.hasOwnProperty( ID ) ) {
|
||||
deselectUnit(ID: number) {
|
||||
if (this.#units.hasOwnProperty(ID)) {
|
||||
this.#units[ID].setSelected(false);
|
||||
} else {
|
||||
console.error( `deselectUnit(): no unit found with ID "${ID}".` );
|
||||
console.error(`deselectUnit(): no unit found with ID "${ID}".`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,38 +210,33 @@ export class UnitsManager {
|
||||
this.getUnitsByHotgroup(hotgroup).forEach((unit: Unit) => unit.setSelected(true))
|
||||
}
|
||||
|
||||
getSelectedUnitsTypes() {
|
||||
const selectedUnits = this.getSelectedUnits();
|
||||
if (selectedUnits.length == 0)
|
||||
getUnitsTypes(units: Unit[]) {
|
||||
if (units.length == 0)
|
||||
return [];
|
||||
return selectedUnits.map((unit: Unit) => {
|
||||
return units.map((unit: Unit) => {
|
||||
return unit.getCategory();
|
||||
})?.filter((value: any, index: any, array: string[]) => {
|
||||
return array.indexOf(value) === index;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/* Gets the value of a variable from the selected units. If all the units have the same value, returns the value, else returns undefined */
|
||||
getSelectedUnitsVariable(variableGetter: CallableFunction) {
|
||||
const selectedUnits = this.getSelectedUnits();
|
||||
if (selectedUnits.length == 0)
|
||||
/* Gets the value of a variable from the units. If all the units have the same value, returns the value, else returns undefined */
|
||||
getUnitsVariable(variableGetter: CallableFunction, units: Unit[]) {
|
||||
if (units.length == 0)
|
||||
return undefined;
|
||||
return selectedUnits.map((unit: Unit) => {
|
||||
return units.map((unit: Unit) => {
|
||||
return variableGetter(unit);
|
||||
})?.reduce((a: any, b: any) => {
|
||||
return a === b ? a : undefined
|
||||
});
|
||||
};
|
||||
|
||||
getSelectedUnitsCoalition() {
|
||||
const selectedUnits = this.getSelectedUnits();
|
||||
if (selectedUnits.length == 0)
|
||||
return undefined;
|
||||
return selectedUnits.map((unit: Unit) => {
|
||||
return unit.getCoalition()
|
||||
})?.reduce((a: any, b: any) => {
|
||||
return a == b ? a : undefined
|
||||
});
|
||||
getSelectedUnitsTypes() {
|
||||
return this.getUnitsTypes(this.getSelectedUnits());
|
||||
};
|
||||
|
||||
getSelectedUnitsVariable(variableGetter: CallableFunction) {
|
||||
return this.getUnitsVariable(variableGetter, this.getSelectedUnits());
|
||||
};
|
||||
|
||||
getByType(type: string) {
|
||||
@@ -252,10 +248,9 @@ export class UnitsManager {
|
||||
getUnitDetectedMethods(unit: Unit) {
|
||||
var detectionMethods: number[] = [];
|
||||
for (let idx in this.#units) {
|
||||
if (this.#units[idx].getAlive() && this.#units[idx].getIsLeader() && this.#units[idx].getCoalition() !== "neutral" && this.#units[idx].getCoalition() != unit.getCoalition())
|
||||
{
|
||||
if (this.#units[idx].getAlive() && this.#units[idx].getIsLeader() && 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 (contact.ID == unit.ID && !detectionMethods.includes(contact.detectionMethod))
|
||||
detectionMethods.push(contact.detectionMethod);
|
||||
});
|
||||
}
|
||||
@@ -414,18 +409,18 @@ export class UnitsManager {
|
||||
|
||||
selectedUnitsDelete(explosion: boolean = false) {
|
||||
var selectedUnits = this.getSelectedUnits(); /* Can be applied to humans too */
|
||||
const selectionContainsAHuman = selectedUnits.some( ( unit:Unit ) => {
|
||||
const selectionContainsAHuman = selectedUnits.some((unit: Unit) => {
|
||||
return unit.getHuman() === true;
|
||||
});
|
||||
|
||||
if (selectionContainsAHuman && !confirm( "Your selection includes a human player. Deleting humans causes their vehicle to crash.\n\nAre you sure you want to do this?" ) ) {
|
||||
if (selectionContainsAHuman && !confirm("Your selection includes a human player. Deleting humans causes their vehicle to crash.\n\nAre you sure you want to do this?")) {
|
||||
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, immediate);
|
||||
}
|
||||
@@ -560,30 +555,28 @@ export class UnitsManager {
|
||||
this.#showActionMessage(selectedUnits, `unit bombing point`);
|
||||
}
|
||||
|
||||
// TODO handle from lua
|
||||
selectedUnitsCreateGroup() {
|
||||
var selectedUnits = this.getSelectedUnits({ excludeHumans: true, onlyOnePerGroup: false });
|
||||
var units = [];
|
||||
var coalition = "neutral";
|
||||
var units: { ID: number, location: LatLng }[] = [];
|
||||
for (let idx in selectedUnits) {
|
||||
var unit = selectedUnits[idx];
|
||||
coalition = unit.getCoalition();
|
||||
deleteUnit(unit.ID, false, true);
|
||||
units.push({unitType: unit.getName(), location: unit.getPosition()});
|
||||
units.push({ ID: unit.ID, location: unit.getPosition() });
|
||||
}
|
||||
const category = this.getSelectedUnitsTypes()[0];
|
||||
this.spawnUnits(category, units, coalition, true);
|
||||
cloneUnits(units, true, () => {
|
||||
units.forEach((unit: any) => {
|
||||
deleteUnit(unit.ID, false, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/***********************************************/
|
||||
copyUnits() {
|
||||
this.#copiedUnits = JSON.parse(JSON.stringify(this.getSelectedUnits().map((unit: Unit) => {return unit.getData()}))); /* Can be applied to humans too */
|
||||
this.#copiedUnits = JSON.parse(JSON.stringify(this.getSelectedUnits().map((unit: Unit) => { return unit.getData() }))); /* Can be applied to humans too */
|
||||
getInfoPopup().setText(`${this.#copiedUnits.length} units copied`);
|
||||
}
|
||||
|
||||
// TODO handle from lua
|
||||
pasteUnits() {
|
||||
if (!this.#pasteDisabled && getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER) {
|
||||
if (this.#copiedUnits.length > 0 && !this.#pasteDisabled && getMissionHandler().getCommandModeOptions().commandMode == GAME_MASTER) {
|
||||
/* Compute the position of the center of the copied units */
|
||||
var nUnits = this.#copiedUnits.length;
|
||||
var avgLat = 0;
|
||||
@@ -595,44 +588,44 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
/* Organize the copied units in groups */
|
||||
var groups: {[key: string]: any} = {};
|
||||
var groups: { [key: string]: any } = {};
|
||||
this.#copiedUnits.forEach((unit: any) => {
|
||||
if (!(unit.groupName in groups))
|
||||
groups[unit.groupName] = [];
|
||||
groups[unit.groupName].push(unit);
|
||||
});
|
||||
|
||||
/* Clone the units in groups */
|
||||
for (let groupName in groups) {
|
||||
/* Paste the units as groups. Only for ground and navy units because of loadouts, TODO: find a better solution so it works for them too*/
|
||||
if (!["Aircraft", "Helicopter"].includes(groups[groupName][0].category)) {
|
||||
var units = groups[groupName].map((unit: any) => {
|
||||
var position = new LatLng(getMap().getMouseCoordinates().lat + unit.position.lat - avgLat, getMap().getMouseCoordinates().lng + unit.position.lng - avgLng);
|
||||
getMap().addTemporaryMarker(position, unit.name, unit.coalition);
|
||||
return {unitType: unit.name, location: position, liveryID: ""};
|
||||
});
|
||||
this.spawnUnits(groups[groupName][0].category, units, groups[groupName][0].coalition, true);
|
||||
}
|
||||
else {
|
||||
groups[groupName].forEach((unit: any) => {
|
||||
var position = new LatLng(getMap().getMouseCoordinates().lat + unit.position.lat - avgLat, getMap().getMouseCoordinates().lng + unit.position.lng - avgLng);
|
||||
getMap().addTemporaryMarker(position, unit.name, unit.coalition);
|
||||
cloneUnit(unit.ID, position);
|
||||
});
|
||||
}
|
||||
var units: { ID: number, location: LatLng }[] = [];
|
||||
let markers: TemporaryUnitMarker[] = [];
|
||||
groups[groupName].forEach((unit: any) => {
|
||||
var position = new LatLng(getMap().getMouseCoordinates().lat + unit.position.lat - avgLat, getMap().getMouseCoordinates().lng + unit.position.lng - avgLng);
|
||||
markers.push(getMap().addTemporaryMarker(position, unit.name, unit.coalition));
|
||||
units.push({ ID: unit.ID, location: position });
|
||||
});
|
||||
|
||||
cloneUnits(units, false, (res: any) => {
|
||||
if (res.commandHash !== undefined) {
|
||||
markers.forEach((marker: TemporaryUnitMarker) => {
|
||||
marker.setCommandHash(res.commandHash);
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
getInfoPopup().setText(`${this.#copiedUnits.length - 1} units pasted`);
|
||||
getInfoPopup().setText(`${this.#copiedUnits.length} units pasted`);
|
||||
}
|
||||
else {
|
||||
getInfoPopup().setText(`Unit cloning is disabled in ${getMissionHandler().getCommandModeOptions().commandMode} mode`);
|
||||
}
|
||||
}
|
||||
|
||||
createIADS(coalitionArea: CoalitionArea, types: {[key: string]: boolean}, eras: {[key: string]: boolean}, ranges: {[key: string]: boolean}, density: number, distribution: number) {
|
||||
const activeTypes = Object.keys(types).filter((key: string) => { return types[key]; });
|
||||
const activeEras = Object.keys(eras).filter((key: string) => { return eras[key]; });
|
||||
const activeRanges = Object.keys(ranges).filter((key: string) => { return ranges[key]; });
|
||||
createIADS(coalitionArea: CoalitionArea, types: { [key: string]: boolean }, eras: { [key: string]: boolean }, ranges: { [key: string]: boolean }, density: number, distribution: number) {
|
||||
const activeTypes = Object.keys(types).filter((key: string) => { return types[key]; });
|
||||
const activeEras = Object.keys(eras).filter((key: string) => { return eras[key]; });
|
||||
const activeRanges = Object.keys(ranges).filter((key: string) => { return ranges[key]; });
|
||||
|
||||
citiesDatabase.forEach((city: {lat: number, lng: number, pop: number}) => {
|
||||
citiesDatabase.forEach((city: { lat: number, lng: number, pop: number }) => {
|
||||
if (polyContains(new LatLng(city.lat, city.lng), coalitionArea)) {
|
||||
var pointsNumber = 2 + Math.pow(city.pop, 0.2) * density / 100;
|
||||
for (let i = 0; i < pointsNumber; i++) {
|
||||
@@ -642,10 +635,9 @@ export class UnitsManager {
|
||||
if (polyContains(latlng, coalitionArea)) {
|
||||
const type = activeTypes[Math.floor(Math.random() * activeTypes.length)];
|
||||
if (Math.random() < IADSDensities[type]) {
|
||||
const unitBlueprint = randomUnitBlueprint(groundUnitDatabase, {type: type, eras: activeEras, ranges: activeRanges});
|
||||
const unitBlueprint = randomUnitBlueprint(groundUnitDatabase, { type: type, eras: activeEras, ranges: activeRanges });
|
||||
if (unitBlueprint) {
|
||||
this.spawnUnits("GroundUnit", [{unitType: unitBlueprint.name, location: latlng, liveryID: ""}], coalitionArea.getCoalition(), true);
|
||||
getMap().addTemporaryMarker(latlng, unitBlueprint.name, coalitionArea.getCoalition());
|
||||
this.spawnUnits("GroundUnit", [{ unitType: unitBlueprint.name, location: latlng, liveryID: "" }], coalitionArea.getCoalition(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -655,19 +647,19 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
exportToFile() {
|
||||
var unitsToExport: {[key: string]: any} = {};
|
||||
var unitsToExport: { [key: string]: any } = {};
|
||||
for (let ID in this.#units) {
|
||||
var unit = this.#units[ID];
|
||||
if (!["Aircraft", "Helicopter"].includes(unit.getCategory())) {
|
||||
var data: any = unit.getData();
|
||||
if (unit.getGroupName() in unitsToExport)
|
||||
unitsToExport[unit.getGroupName()].push(data);
|
||||
else
|
||||
else
|
||||
unitsToExport[unit.getGroupName()] = [data];
|
||||
}
|
||||
}
|
||||
var a = document.createElement("a");
|
||||
var file = new Blob([JSON.stringify(unitsToExport)], {type: 'text/plain'});
|
||||
var file = new Blob([JSON.stringify(unitsToExport)], { type: 'text/plain' });
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = 'export.json';
|
||||
a.click();
|
||||
@@ -682,12 +674,12 @@ export class UnitsManager {
|
||||
return;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e: any) {
|
||||
reader.onload = function (e: any) {
|
||||
var contents = e.target.result;
|
||||
var groups = JSON.parse(contents);
|
||||
for (let groupName in groups) {
|
||||
if (groupName !== "" && groups[groupName].length > 0 && (groups[groupName].every((unit: any) => {return unit.category == "GroundUnit";}) || groups[groupName].every((unit: any) => {return unit.category == "NavyUnit";}))) {
|
||||
var aliveUnits = groups[groupName].filter((unit: any) => {return unit.alive});
|
||||
if (groupName !== "" && groups[groupName].length > 0 && (groups[groupName].every((unit: any) => { return unit.category == "GroundUnit"; }) || groups[groupName].every((unit: any) => { return unit.category == "NavyUnit"; }))) {
|
||||
var aliveUnits = groups[groupName].filter((unit: any) => { return unit.alive });
|
||||
var units = aliveUnits.map((unit: any) => {
|
||||
return { unitType: unit.name, location: unit.position, liveryID: "" }
|
||||
});
|
||||
@@ -700,40 +692,46 @@ export class UnitsManager {
|
||||
input.click();
|
||||
}
|
||||
|
||||
spawnUnits(category: string, units: any, coalition: string = "blue", immediate: boolean = true, airbase: string = "", country: string = "") {
|
||||
spawnUnits(category: string, units: any, coalition: string = "blue", immediate: boolean = true, airbase: string = "", country: string = "", callback: CallableFunction = () => {}) {
|
||||
var spawnPoints = 0;
|
||||
var spawnFunction = () => {};
|
||||
var spawnsRestricted = getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER;
|
||||
|
||||
if (category === "Aircraft") {
|
||||
if (airbase == "" && getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
|
||||
if (airbase == "" && spawnsRestricted) {
|
||||
getInfoPopup().setText("Aircrafts can be air spawned during the SETUP phase only");
|
||||
return false;
|
||||
}
|
||||
spawnPoints = units.reduce((points: number, unit: any) => {return points + aircraftDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnAircrafts(units, coalition, airbase, country, immediate, spawnPoints);
|
||||
spawnFunction = () => spawnAircrafts(units, coalition, airbase, country, immediate, spawnPoints, callback);
|
||||
} else if (category === "Helicopter") {
|
||||
if (airbase == "" && getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
|
||||
if (airbase == "" && spawnsRestricted) {
|
||||
getInfoPopup().setText("Helicopters can be air spawned during the SETUP phase only");
|
||||
return false;
|
||||
}
|
||||
spawnPoints = units.reduce((points: number, unit: any) => {return points + helicopterDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnHelicopters(units, coalition, airbase, country, immediate, spawnPoints);
|
||||
spawnFunction = () => spawnHelicopters(units, coalition, airbase, country, immediate, spawnPoints, callback);
|
||||
|
||||
} else if (category === "GroundUnit") {
|
||||
if (getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
|
||||
if (spawnsRestricted) {
|
||||
getInfoPopup().setText("Ground units can be spawned during the SETUP phase only");
|
||||
return false;
|
||||
}
|
||||
spawnPoints = units.reduce((points: number, unit: any) => {return points + groundUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnGroundUnits(units, coalition, country, immediate, spawnPoints);
|
||||
spawnFunction = () => spawnGroundUnits(units, coalition, country, immediate, spawnPoints, callback);
|
||||
|
||||
} else if (category === "NavyUnit") {
|
||||
if (getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
|
||||
if (spawnsRestricted) {
|
||||
getInfoPopup().setText("Navy units can be spawned during the SETUP phase only");
|
||||
return false;
|
||||
}
|
||||
spawnPoints = units.reduce((points: number, unit: any) => {return points + navyUnitDatabase.getSpawnPointsByName(unit.unitType)}, 0);
|
||||
spawnNavyUnits(units, coalition, country, immediate, spawnPoints);
|
||||
spawnFunction = () => spawnNavyUnits(units, coalition, country, immediate, spawnPoints, callback);
|
||||
}
|
||||
|
||||
|
||||
if (spawnPoints <= getMissionHandler().getAvailableSpawnPoints()) {
|
||||
getMissionHandler().setSpentSpawnPoints(spawnPoints);
|
||||
spawnFunction();
|
||||
return true;
|
||||
} else {
|
||||
getInfoPopup().setText("Not enough spawn points available!");
|
||||
@@ -747,7 +745,7 @@ export class UnitsManager {
|
||||
if (event.key === "Delete")
|
||||
this.selectedUnitsDelete();
|
||||
else if (event.key === "a" && event.ctrlKey)
|
||||
Object.values(this.getUnits()).filter((unit: Unit) => {return !unit.getHidden()}).forEach((unit: Unit) => unit.setSelected(true));
|
||||
Object.values(this.getUnits()).filter((unit: Unit) => { return !unit.getHidden() }).forEach((unit: Unit) => unit.setSelected(true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -214,8 +214,6 @@ export class Weapon extends CustomMarker {
|
||||
/***********************************************/
|
||||
onAdd(map: Map): this {
|
||||
super.onAdd(map);
|
||||
/* If this is the first time adding this unit to the map, remove the temporary marker */
|
||||
getMap().removeTemporaryMarker(new LatLng(this.#position.lat, this.#position.lng));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user