Added front end for area attacks

This commit is contained in:
Pax1601
2023-06-05 17:30:37 +02:00
parent d508263f9e
commit 6c52f4de59
8 changed files with 200 additions and 25 deletions

View File

@@ -1,6 +1,6 @@
import { LatLng } from "leaflet";
import { getActiveCoalition, getMap, setActiveCoalition } from "..";
import { spawnAircraft, spawnGroundUnit, spawnSmoke } from "../server/server";
import { spawnAircraft, spawnExplosion, spawnGroundUnit, spawnSmoke } from "../server/server";
import { aircraftDatabase } from "../units/aircraftdatabase";
import { groundUnitsDatabase } from "../units/groundunitsdatabase";
import { ContextMenu } from "./contextmenu";
@@ -38,6 +38,9 @@ export class MapContextMenu extends ContextMenu {
this.#aircraftTypeDropdown = new Dropdown("aircraft-type-options", (type: string) => this.#setAircraftType(type));
this.#aircraftLoadoutDropdown = new Dropdown("loadout-options", (loadout: string) => this.#setAircraftLoadout(loadout));
this.#aircrafSpawnAltitudeSlider = new Slider("aircraft-spawn-altitude-slider", 0, 50000, "ft", (value: number) => {this.#spawnOptions.altitude = value;});
this.#aircrafSpawnAltitudeSlider.setIncrement(500);
this.#aircrafSpawnAltitudeSlider.setValue(20000);
this.#aircrafSpawnAltitudeSlider.setActive(true);
this.#groundUnitRoleDropdown = new Dropdown("ground-unit-role-options", (role: string) => this.#setGroundUnitRole(role));
this.#groundUnitTypeDropdown = new Dropdown("ground-unit-type-options", (type: string) => this.#setGroundUnitType(type));
@@ -68,9 +71,11 @@ export class MapContextMenu extends ContextMenu {
spawnSmoke(e.detail.color, this.getLatLng());
});
this.#aircrafSpawnAltitudeSlider.setIncrement(500);
this.#aircrafSpawnAltitudeSlider.setValue(20000);
this.#aircrafSpawnAltitudeSlider.setActive(true);
document.addEventListener("contextMenuExplosion", (e: any) => {
this.hide();
spawnExplosion(e.detail.strength, this.getLatLng());
});
this.hide();
}
@@ -89,6 +94,8 @@ export class MapContextMenu extends ContextMenu {
this.getContainer()?.querySelector("#ground-unit-spawn-button")?.classList.toggle("is-open", type === "ground-unit");
this.getContainer()?.querySelector("#smoke-spawn-menu")?.classList.toggle("hide", type !== "smoke");
this.getContainer()?.querySelector("#smoke-spawn-button")?.classList.toggle("is-open", type === "smoke");
this.getContainer()?.querySelector("#explosion-menu")?.classList.toggle("hide", type !== "explosion");
this.getContainer()?.querySelector("#explosion-spawn-button")?.classList.toggle("is-open", type === "explosion");
this.#resetAircraftRole();
this.#resetAircraftType();

View File

@@ -21,7 +21,7 @@ require("../../public/javascripts/leaflet.nauticscale.js")
/* Map constants */
export const IDLE = "IDLE";
export const MOVE_UNIT = "MOVE_UNIT";
export const UNIT_SELECTED = "MOVE_UNIT";
export const visibilityControls: string[] = ["human", "dcs", "aircraft", "groundunit-sam", "groundunit-other", "navyunit", "airbase"];
export const visibilityControlsTootlips: string[] = ["Toggle human players visibility", "Toggle DCS controlled units visibility", "Toggle aircrafts visibility", "Toggle SAM units visibility", "Toggle ground units (not SAM) visibility", "Toggle navy units visibility", "Toggle airbases visibility"];
@@ -159,7 +159,7 @@ export class Map extends L.Map {
this.#computeDestinationRotation = false;
this.#destinationRotationCenter = null;
}
else if (this.#state === MOVE_UNIT) {
else if (this.#state === UNIT_SELECTED) {
/* Remove all the exising destination preview markers */
this.#destinationPreviewMarkers.forEach((marker: L.Marker) => {
this.removeLayer(marker);
@@ -363,7 +363,7 @@ export class Map extends L.Map {
if (this.#state === IDLE) {
}
else if (this.#state === MOVE_UNIT) {
else if (this.#state === UNIT_SELECTED) {
this.setState(IDLE);
getUnitsManager().deselectAllUnits();
}
@@ -381,17 +381,52 @@ export class Map extends L.Map {
this.showMapContextMenu(e);
}
}
else if (this.#state === MOVE_UNIT) {
if (!e.originalEvent.ctrlKey) {
getUnitsManager().selectedUnitsClearDestinations();
else if (this.#state === UNIT_SELECTED) {
if (e.originalEvent.shiftKey) {
var options: {[key: string]: {text: string, tooltip: string}} = {};
var selectedUnitTypes = getUnitsManager().getSelectedUnitsTypes();
if (selectedUnitTypes.length === 1 && ["Aircraft"].includes(selectedUnitTypes[0]))
{
options["bomb"] = {text: "Bomb here", tooltip: "Precision bombing of this specific point"};
options["carpet-bomb"] = {text: "Carpet bomb", tooltip: "Carpet bombing around this point"};
options["building-bomb"] = {text: "Bomb building", tooltip: "Precision bombing of the building closest to this point"};
}
if (selectedUnitTypes.length === 1 && ["GroundUnit"].includes(selectedUnitTypes[0]))
options["fire-at-area"] = {text: "Fire at area", tooltip: "Fire at this point"};
if (Object.keys(options).length > 0) {
this.showUnitContextMenu(e);
this.getUnitContextMenu().setOptions(options, (option: string) => {
this.hideUnitContextMenu();
this.#executeAction(e, option);
});
}
} else {
if (!e.originalEvent.ctrlKey) {
getUnitsManager().selectedUnitsClearDestinations();
}
getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, e.originalEvent.shiftKey, this.#destinationGroupRotation)
this.#destinationGroupRotation = 0;
this.#destinationRotationCenter = null;
this.#computeDestinationRotation = false;
}
getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, e.originalEvent.shiftKey, this.#destinationGroupRotation)
this.#destinationGroupRotation = 0;
this.#destinationRotationCenter = null;
this.#computeDestinationRotation = false;
}
}
#executeAction(e: any, action: string) {
if (action === "bomb")
getUnitsManager().selectedUnitsBombPoint(this.getMouseCoordinates());
else if (action === "carpet-bomb")
getUnitsManager().selectedUnitsCarpetBomb(this.getMouseCoordinates());
else if (action === "building-bomb")
getUnitsManager().selectedUnitsBombBuilding(this.getMouseCoordinates());
else if (action === "fire-at-area")
getUnitsManager().selectedUnitsFireAtArea(this.getMouseCoordinates());
}
#onSelectionEnd(e: any) {
clearTimeout(this.#leftClickTimer);
this.#preventLeftClick = true;
@@ -404,7 +439,7 @@ export class Map extends L.Map {
#onMouseDown(e: any) {
this.hideAllContextMenus();
if (this.#state == MOVE_UNIT) {
if (this.#state == UNIT_SELECTED) {
this.#destinationGroupRotation = 0;
this.#destinationRotationCenter = null;
this.#computeDestinationRotation = false;

View File

@@ -1,4 +1,4 @@
import * as L from 'leaflet'
import { LatLng } from 'leaflet';
import { getConnectionStatusPanel, getInfoPopup, getMissionData, getUnitDataTable, getUnitsManager, setConnectionStatus } from '..';
import { SpawnOptions } from '../controls/mapcontextmenu';
@@ -121,12 +121,18 @@ export function addDestination(ID: number, path: any) {
POST(data, () => { });
}
export function spawnSmoke(color: string, latlng: L.LatLng) {
export function spawnSmoke(color: string, latlng: LatLng) {
var command = { "color": color, "location": latlng };
var data = { "smoke": command }
POST(data, () => { });
}
export function spawnExplosion(strength: number, latlng: LatLng) {
var command = { "strength": strength, "location": latlng };
var data = { "explosion": command }
POST(data, () => { });
}
export function spawnGroundUnit(spawnOptions: SpawnOptions) {
var command = { "type": spawnOptions.type, "location": spawnOptions.latlng, "coalition": spawnOptions.coalition };
var data = { "spawnGround": command }
@@ -155,7 +161,7 @@ export function followUnit(ID: number, targetID: number, offset: { "x": number,
POST(data, () => { });
}
export function cloneUnit(ID: number, latlng: L.LatLng) {
export function cloneUnit(ID: number, latlng: LatLng) {
var command = { "ID": ID, "location": latlng };
var data = { "cloneUnit": command }
POST(data, () => { });
@@ -167,7 +173,7 @@ export function deleteUnit(ID: number, explosion: boolean) {
POST(data, () => { });
}
export function landAt(ID: number, latlng: L.LatLng) {
export function landAt(ID: number, latlng: LatLng) {
var command = { "ID": ID, "location": latlng };
var data = { "landAt": command }
POST(data, () => { });
@@ -251,6 +257,29 @@ export function refuel(ID: number) {
POST(data, () => { });
}
export function bombPoint(ID: number, latlng: LatLng) {
var command = { "ID": ID, "location": latlng }
var data = { "bombPoint": command }
POST(data, () => { });
}
export function carpetBomb(ID: number, latlng: LatLng) {
var command = { "ID": ID, "location": latlng }
var data = { "carpetBomb": command }
POST(data, () => { });
}
export function bombBuilding(ID: number, latlng: LatLng) {
var command = { "ID": ID, "location": latlng }
var data = { "bombBuilding": command }
POST(data, () => { });
}
export function fireAtArea(ID: number, latlng: LatLng) {
var command = { "ID": ID, "location": latlng }
var data = { "fireAtArea": command }
POST(data, () => { });
}
export function setAdvacedOptions(ID: number, isTanker: boolean, isAWACS: boolean, TACAN: TACAN, radio: Radio, generalSettings: GeneralSettings) {
var command = {
"ID": ID,

View File

@@ -1,7 +1,7 @@
import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map } from 'leaflet';
import { getMap, getUnitsManager } from '..';
import { rad2deg } from '../other/utils';
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, getUnits, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures, setSpeedType, setAltitudeType, setOnOff, setFollowRoads } from '../server/server';
import { addDestination, attackUnit, changeAltitude, changeSpeed, createFormation as setLeader, deleteUnit, getUnits, landAt, setAltitude, setReactionToThreat, setROE, setSpeed, refuel, setAdvacedOptions, followUnit, setEmissionsCountermeasures, setSpeedType, setAltitudeType, setOnOff, setFollowRoads, bombPoint, carpetBomb, bombBuilding, fireAtArea } from '../server/server';
import { aircraftDatabase } from './aircraftdatabase';
import { groundUnitsDatabase } from './groundunitsdatabase';
import { CustomMarker } from '../map/custommarker';
@@ -517,6 +517,22 @@ export class Unit extends CustomMarker {
setAdvacedOptions(this.ID, isTanker, isAWACS, TACAN, radio, generalSettings);
}
bombPoint(latlng: LatLng) {
bombPoint(this.ID, latlng);
}
carpetBomb(latlng: LatLng) {
carpetBomb(this.ID, latlng);
}
bombBuilding(latlng: LatLng) {
bombBuilding(this.ID, latlng);
}
fireAtArea(latlng: LatLng) {
fireAtArea(this.ID, latlng);
}
/***********************************************/
onAdd(map: Map): this {
super.onAdd(map);
@@ -557,7 +573,7 @@ export class Unit extends CustomMarker {
}
else if ((getUnitsManager().getSelectedUnits().length > 0 && (getUnitsManager().getSelectedUnits().includes(this))) || getUnitsManager().getSelectedUnits().length == 0) {
if (this.getBaseData().category == "Aircraft") {
options["refuel"] = {text: "AAR Refuel", tooltip: "Refuel unit at the nearest AAR Tanker. If no tanker is available the unit will RTB."}; // TODO Add some way of knowing which aircraft can AAR
options["refuel"] = {text: "Air to air refuel", tooltip: "Refuel unit at the nearest AAR Tanker. If no tanker is available the unit will RTB."}; // TODO Add some way of knowing which aircraft can AAR
}
}

View File

@@ -2,7 +2,7 @@ import { LatLng, LatLngBounds } from "leaflet";
import { getHotgroupPanel, getInfoPopup, getMap, getUnitDataTable } from "..";
import { Unit } from "./unit";
import { cloneUnit } from "../server/server";
import { IDLE, MOVE_UNIT } from "../map/map";
import { IDLE, UNIT_SELECTED } from "../map/map";
import { deg2rad, keyEventWasInInput, latLngToMercator, mercatorToLatLng } from "../other/utils";
export class UnitsManager {
@@ -305,7 +305,7 @@ export class UnitsManager {
for (let idx in selectedUnits) {
selectedUnits[idx].setOnOff(onOff);
}
this.#showActionMessage(selectedUnits, `unit acitve set to ${onOff}`);
this.#showActionMessage(selectedUnits, `unit active set to ${onOff}`);
}
selectedUnitsSetFollowRoads(followRoads: boolean) {
@@ -437,6 +437,38 @@ export class UnitsManager {
return unitDestinations;
}
selectedUnitsBombPoint(mouseCoordinates: LatLng) {
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].bombPoint(mouseCoordinates);
}
this.#showActionMessage(selectedUnits, `unit bombing point`);
}
selectedUnitsCarpetBomb(mouseCoordinates: LatLng) {
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].carpetBomb(mouseCoordinates);
}
this.#showActionMessage(selectedUnits, `unit bombing point`);
}
selectedUnitsBombBuilding(mouseCoordinates: LatLng) {
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].bombBuilding(mouseCoordinates);
}
this.#showActionMessage(selectedUnits, `unit bombing point`);
}
selectedUnitsFireAtArea(mouseCoordinates: LatLng) {
var selectedUnits = this.getSelectedUnits({ excludeHumans: true });
for (let idx in selectedUnits) {
selectedUnits[idx].fireAtArea(mouseCoordinates);
}
this.#showActionMessage(selectedUnits, `unit bombing point`);
}
/***********************************************/
copyUnits() {
this.#copiedUnits = this.getSelectedUnits(); /* Can be applied to humans too */
@@ -459,7 +491,7 @@ export class UnitsManager {
/***********************************************/
#onUnitSelection(unit: Unit) {
if (this.getSelectedUnits().length > 0) {
getMap().setState(MOVE_UNIT);
getMap().setState(UNIT_SELECTED);
/* Disable the firing of the selection event for a certain amount of time. This avoids firing many events if many units are selected */
if (!this.#selectionEventDisabled) {
window.setTimeout(() => {