mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Minor tweaks and fixes
This commit is contained in:
parent
2d4202979f
commit
a0763a6450
@ -197,6 +197,17 @@
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
.contextmenu-options-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.contextmenu-options-container>*:nth-child(2) {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
/* Unit context menu */
|
||||
#unit-contextmenu {
|
||||
display: flex;
|
||||
|
||||
@ -50,7 +50,7 @@ export class AirbaseContextMenu extends ContextMenu {
|
||||
}
|
||||
|
||||
setCoalition(coalition: string) {
|
||||
(<HTMLElement>this.getContainer()?.querySelector("#spawn-airbase-aircraft-button")).dataset.activeCoalition = coalition;
|
||||
(<HTMLElement>this.getContainer()?.querySelector("#spawn-airbase-aircraft-button")).dataset.coalition = coalition;
|
||||
}
|
||||
|
||||
enableLandButton(enableLandButton: boolean) {
|
||||
@ -62,6 +62,7 @@ export class AirbaseContextMenu extends ContextMenu {
|
||||
setActiveCoalition(this.#airbase.getCoalition());
|
||||
getMap().showMapContextMenu({ originalEvent: { x: this.getX(), y: this.getY(), latlng: this.getLatLng() } });
|
||||
getMap().getMapContextMenu().hideUpperBar();
|
||||
getMap().getMapContextMenu().hideAltitudeSlider();
|
||||
getMap().getMapContextMenu().showSubMenu("aircraft");
|
||||
getMap().getMapContextMenu().setAirbaseName(this.#airbase.getName());
|
||||
getMap().getMapContextMenu().setLatLng(this.#airbase.getLatLng());
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { LatLng } from "leaflet";
|
||||
import { getMap, getUnitsManager } from "..";
|
||||
import { IADSRoles } from "../constants/constants";
|
||||
import { GAME_MASTER, IADSRoles } from "../constants/constants";
|
||||
import { CoalitionArea } from "../map/coalitionarea";
|
||||
import { ContextMenu } from "./contextmenu";
|
||||
import { Dropdown } from "./dropdown";
|
||||
@ -75,6 +76,12 @@ export class CoalitionAreaContextMenu extends ContextMenu {
|
||||
this.hide();
|
||||
}
|
||||
|
||||
show(x: number, y: number, latlng: LatLng) {
|
||||
super.show(x, y, latlng);
|
||||
if (getUnitsManager().getCommandMode() !== GAME_MASTER)
|
||||
this.#coalitionSwitch.hide()
|
||||
}
|
||||
|
||||
showSubMenu(type: string) {
|
||||
this.getContainer()?.querySelector("#iads-menu")?.classList.toggle("hide", type !== "iads");
|
||||
this.getContainer()?.querySelector("#iads-button")?.classList.toggle("is-open", type === "iads");
|
||||
@ -104,9 +111,11 @@ export class CoalitionAreaContextMenu extends ContextMenu {
|
||||
}
|
||||
|
||||
#onSwitchClick(value: boolean) {
|
||||
this.getCoalitionArea()?.setCoalition(value ? "red" : "blue");
|
||||
this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => {
|
||||
element.setAttribute("data-coalition", this.getCoalitionArea()?.getCoalition())
|
||||
});
|
||||
if (getUnitsManager().getCommandMode() == GAME_MASTER) {
|
||||
this.getCoalitionArea()?.setCoalition(value ? "red" : "blue");
|
||||
this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => {
|
||||
element.setAttribute("data-coalition", this.getCoalitionArea()?.getCoalition())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { LatLng } from "leaflet";
|
||||
import { getActiveCoalition, getMap, setActiveCoalition } from "..";
|
||||
import { getActiveCoalition, getMap, getUnitsManager, setActiveCoalition } from "..";
|
||||
import { spawnAircrafts, spawnExplosion, spawnGroundUnits, spawnSmoke } from "../server/server";
|
||||
import { aircraftDatabase } from "../units/aircraftdatabase";
|
||||
import { groundUnitsDatabase } from "../units/groundunitsdatabase";
|
||||
@ -8,16 +8,19 @@ import { Dropdown } from "./dropdown";
|
||||
import { Switch } from "./switch";
|
||||
import { Slider } from "./slider";
|
||||
import { ftToM } from "../other/utils";
|
||||
import { GAME_MASTER } from "../constants/constants";
|
||||
|
||||
export class MapContextMenu extends ContextMenu {
|
||||
#coalitionSwitch: Switch;
|
||||
#aircraftRoleDropdown: Dropdown;
|
||||
#aircraftTypeDropdown: Dropdown;
|
||||
#aircraftCountDropdown: Dropdown;
|
||||
#aircraftLoadoutDropdown: Dropdown;
|
||||
#aircrafSpawnAltitudeSlider: Slider;
|
||||
#groundUnitRoleDropdown: Dropdown;
|
||||
#groundUnitTypeDropdown: Dropdown;
|
||||
#spawnOptions = { role: "", name: "", latlng: new LatLng(0, 0), coalition: "blue", loadout: "", airbaseName: "", altitude: ftToM(20000) };
|
||||
#groundCountDropdown: Dropdown;
|
||||
#spawnOptions = { role: "", name: "", latlng: new LatLng(0, 0), coalition: "blue", loadout: "", airbaseName: "", altitude: ftToM(20000), count: 1 };
|
||||
|
||||
constructor(id: string) {
|
||||
super(id);
|
||||
@ -27,6 +30,9 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.#coalitionSwitch.getContainer()?.addEventListener("contextmenu", (e) => this.#onSwitchRightClick(e));
|
||||
this.#aircraftRoleDropdown = new Dropdown("aircraft-role-options", (role: string) => this.#setAircraftRole(role));
|
||||
this.#aircraftTypeDropdown = new Dropdown("aircraft-type-options", (type: string) => this.#setAircraftType(type));
|
||||
this.#aircraftCountDropdown = new Dropdown("aircraft-count-options", (type: string) => this.#setAircraftCount(type));
|
||||
this.#aircraftCountDropdown.setOptions(["1", "2", "3", "4"]);
|
||||
this.#aircraftCountDropdown.setValue("1");
|
||||
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 = ftToM(value);});
|
||||
this.#aircrafSpawnAltitudeSlider.setIncrement(500);
|
||||
@ -34,6 +40,11 @@ export class MapContextMenu extends ContextMenu {
|
||||
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));
|
||||
this.#groundCountDropdown = new Dropdown("ground-count-options", (type: string) => this.#setGroundCount(type));
|
||||
var groundCount = [];
|
||||
for (let i = 1; i <= 10; i++) groundCount.push(String(i));
|
||||
this.#groundCountDropdown.setOptions(groundCount);
|
||||
this.#groundCountDropdown.setValue("1");
|
||||
|
||||
document.addEventListener("mapContextMenuShow", (e: any) => {
|
||||
if (this.getVisibleSubMenu() !== e.detail.type)
|
||||
@ -47,7 +58,12 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.#spawnOptions.coalition = getActiveCoalition();
|
||||
if (this.#spawnOptions) {
|
||||
getMap().addTemporaryMarker(this.#spawnOptions.latlng, this.#spawnOptions.name, getActiveCoalition());
|
||||
spawnAircrafts([{unitName: this.#spawnOptions.name, latlng: this.#spawnOptions.latlng, loadout: this.#spawnOptions.loadout}], getActiveCoalition(), this.#spawnOptions.airbaseName, false);
|
||||
var unitTable = {unitType: this.#spawnOptions.name, location: this.#spawnOptions.latlng, altitude: this.#spawnOptions.altitude, loadout: this.#spawnOptions.loadout};
|
||||
var units = [];
|
||||
for (let i = 1; i < parseInt(this.#aircraftCountDropdown.getValue()) + 1; i++) {
|
||||
units.push(unitTable);
|
||||
}
|
||||
spawnAircrafts(units, getActiveCoalition(), this.#spawnOptions.airbaseName, false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -56,7 +72,13 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.#spawnOptions.coalition = getActiveCoalition();
|
||||
if (this.#spawnOptions) {
|
||||
getMap().addTemporaryMarker(this.#spawnOptions.latlng, this.#spawnOptions.name, getActiveCoalition());
|
||||
spawnGroundUnits([{unitName: this.#spawnOptions.name, latlng: this.#spawnOptions.latlng}], getActiveCoalition(), false);
|
||||
var unitTable = {unitType: this.#spawnOptions.name, location: this.#spawnOptions.latlng};
|
||||
var units = [];
|
||||
for (let i = 1; i < parseInt(this.#groundCountDropdown.getValue()) + 1; i++) {
|
||||
units.push(JSON.parse(JSON.stringify(unitTable)));
|
||||
unitTable.location.lat += 0.0001;
|
||||
}
|
||||
spawnGroundUnits(units, getActiveCoalition(), false);
|
||||
}
|
||||
});
|
||||
|
||||
@ -70,7 +92,6 @@ export class MapContextMenu extends ContextMenu {
|
||||
spawnExplosion(e.detail.strength, this.getLatLng());
|
||||
});
|
||||
|
||||
|
||||
this.hide();
|
||||
}
|
||||
|
||||
@ -79,6 +100,19 @@ export class MapContextMenu extends ContextMenu {
|
||||
super.show(x, y, latlng);
|
||||
this.#spawnOptions.latlng = latlng;
|
||||
this.showUpperBar();
|
||||
|
||||
this.showAltitudeSlider();
|
||||
|
||||
this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) });
|
||||
if (getActiveCoalition() == "blue")
|
||||
this.#coalitionSwitch.setValue(false);
|
||||
else if (getActiveCoalition() == "red")
|
||||
this.#coalitionSwitch.setValue(true);
|
||||
else
|
||||
this.#coalitionSwitch.setValue(undefined);
|
||||
|
||||
if (getUnitsManager().getCommandMode() !== GAME_MASTER)
|
||||
this.#coalitionSwitch.hide()
|
||||
}
|
||||
|
||||
showSubMenu(type: string) {
|
||||
@ -95,6 +129,8 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.#resetAircraftType();
|
||||
this.#resetGroundUnitRole();
|
||||
this.#resetGroundUnitType();
|
||||
this.#aircraftCountDropdown.setValue("1");
|
||||
this.#groundCountDropdown.setValue("1");
|
||||
this.clip();
|
||||
|
||||
this.setVisibleSubMenu(type);
|
||||
@ -119,7 +155,6 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.setVisibleSubMenu(null);
|
||||
}
|
||||
|
||||
|
||||
showUpperBar() {
|
||||
this.getContainer()?.querySelector("#upper-bar")?.classList.toggle("hide", false);
|
||||
}
|
||||
@ -128,6 +163,14 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.getContainer()?.querySelector("#upper-bar")?.classList.toggle("hide", true);
|
||||
}
|
||||
|
||||
showAltitudeSlider() {
|
||||
this.getContainer()?.querySelector("#aircraft-spawn-altitude-slider")?.classList.toggle("hide", false);
|
||||
}
|
||||
|
||||
hideAltitudeSlider() {
|
||||
this.getContainer()?.querySelector("#aircraft-spawn-altitude-slider")?.classList.toggle("hide", true);
|
||||
}
|
||||
|
||||
setAirbaseName(airbaseName: string) {
|
||||
this.#spawnOptions.airbaseName = airbaseName;
|
||||
}
|
||||
@ -144,6 +187,7 @@ export class MapContextMenu extends ContextMenu {
|
||||
#onSwitchRightClick(e: any) {
|
||||
this.#coalitionSwitch.setValue(undefined);
|
||||
setActiveCoalition("neutral");
|
||||
this.getContainer()?.querySelectorAll('[data-coalition]').forEach((element: any) => { element.setAttribute("data-coalition", getActiveCoalition()) });
|
||||
}
|
||||
|
||||
/********* Aircraft spawn menu *********/
|
||||
@ -178,6 +222,11 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.clip();
|
||||
}
|
||||
|
||||
#setAircraftCount(count: string) {
|
||||
this.#spawnOptions.count = parseInt(count);
|
||||
this.clip();
|
||||
}
|
||||
|
||||
#resetAircraftType() {
|
||||
(<HTMLButtonElement>this.getContainer()?.querySelector("#aircraft-spawn-menu")?.querySelector(".deploy-unit-button")).disabled = true;
|
||||
(<HTMLButtonElement>this.getContainer()?.querySelector("#loadout-list")).replaceChildren();
|
||||
@ -236,6 +285,11 @@ export class MapContextMenu extends ContextMenu {
|
||||
this.clip();
|
||||
}
|
||||
|
||||
#setGroundCount(count: string) {
|
||||
this.#spawnOptions.count = parseInt(count);
|
||||
this.clip();
|
||||
}
|
||||
|
||||
#resetGroundUnitType() {
|
||||
(<HTMLButtonElement>this.getContainer()?.querySelector("#ground-unit-spawn-menu")?.querySelector(".deploy-unit-button")).disabled = true;
|
||||
this.clip();
|
||||
|
||||
@ -16,6 +16,7 @@ import { Popup } from "./popups/popup";
|
||||
import { Dropdown } from "./controls/dropdown";
|
||||
import { HotgroupPanel } from "./panels/hotgrouppanel";
|
||||
import { SVGInjector } from "@tanem/svg-injector";
|
||||
import { BLUE_COMMANDER, GAME_MASTER, RED_COMMANDER } from "./constants/constants";
|
||||
|
||||
var map: Map;
|
||||
|
||||
@ -44,8 +45,8 @@ function setup() {
|
||||
featureSwitches = new FeatureSwitches();
|
||||
|
||||
/* Initialize base functionalitites */
|
||||
map = new Map('map-container');
|
||||
unitsManager = new UnitsManager();
|
||||
map = new Map('map-container');
|
||||
missionHandler = new MissionHandler();
|
||||
|
||||
/* Panels */
|
||||
@ -252,11 +253,21 @@ export function getHotgroupPanel() {
|
||||
}
|
||||
|
||||
export function setActiveCoalition(newActiveCoalition: string) {
|
||||
activeCoalition = newActiveCoalition;
|
||||
if (getUnitsManager().getCommandMode() == GAME_MASTER)
|
||||
activeCoalition = newActiveCoalition;
|
||||
}
|
||||
|
||||
export function getActiveCoalition() {
|
||||
return activeCoalition;
|
||||
if (getUnitsManager().getCommandMode() == GAME_MASTER)
|
||||
return activeCoalition;
|
||||
else {
|
||||
if (getUnitsManager().getCommandMode() == BLUE_COMMANDER)
|
||||
return "blue";
|
||||
else if (getUnitsManager().getCommandMode() == RED_COMMANDER)
|
||||
return "red";
|
||||
else
|
||||
return "neutral";
|
||||
}
|
||||
}
|
||||
|
||||
export function setLoginStatus(status: string) {
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { DomUtil, LatLng, LatLngExpression, Map, Point, Polygon, PolylineOptions } from "leaflet";
|
||||
import { getMap } from "..";
|
||||
import { getMap, getUnitsManager } from "..";
|
||||
import { CoalitionAreaHandle } from "./coalitionareahandle";
|
||||
import { CoalitionAreaMiddleHandle } from "./coalitionareamiddlehandle";
|
||||
import { BLUE_COMMANDER, RED_COMMANDER } from "../constants/constants";
|
||||
|
||||
export class CoalitionArea extends Polygon {
|
||||
#coalition: string = "blue";
|
||||
@ -19,7 +20,11 @@ export class CoalitionArea extends Polygon {
|
||||
super(latlngs, options);
|
||||
this.#setColors();
|
||||
this.#registerCallbacks();
|
||||
|
||||
|
||||
if (getUnitsManager().getCommandMode() == BLUE_COMMANDER)
|
||||
this.setCoalition("blue");
|
||||
else if (getUnitsManager().getCommandMode() == RED_COMMANDER)
|
||||
this.setCoalition("red");
|
||||
}
|
||||
|
||||
setCoalition(coalition: string) {
|
||||
|
||||
@ -247,7 +247,7 @@ export function getMarkerCategoryByName(name: string) {
|
||||
return (role?.includes("SAM")) ? "groundunit-sam" : "groundunit-other";
|
||||
}
|
||||
else
|
||||
return ""; // TODO add other unit types
|
||||
return "groundunit-other"; // TODO add other unit types
|
||||
}
|
||||
|
||||
export function getUnitDatabaseByCategory(category: string) {
|
||||
|
||||
@ -36,7 +36,7 @@ export class UnitControlPanel extends Panel {
|
||||
/* Option buttons */
|
||||
// Reversing the ROEs so that the least "aggressive" option is always on the left
|
||||
this.#optionButtons["ROE"] = ROEs.slice(0).reverse().map((option: string, index: number) => {
|
||||
return this.#createOptionButton(option, `roe/${option.toLowerCase()}.svg`, ROEDescriptions[index], () => { getUnitsManager().selectedUnitsSetROE(option); });
|
||||
return this.#createOptionButton(option, `roe/${option.toLowerCase()}.svg`, ROEDescriptions.slice(0).reverse()[index], () => { getUnitsManager().selectedUnitsSetROE(option); });
|
||||
});
|
||||
|
||||
this.#optionButtons["reactionToThreat"] = reactionsToThreat.map((option: string, index: number) => {
|
||||
|
||||
@ -324,9 +324,7 @@ export function startUpdate() {
|
||||
export function requestUpdate() {
|
||||
/* Main update rate = 250ms is minimum time, equal to server update time. */
|
||||
if (!getPaused()) {
|
||||
getUnits((buffer: ArrayBuffer) => {
|
||||
getUnitsManager()?.update(buffer);
|
||||
}, false);
|
||||
getUnits((buffer: ArrayBuffer) => { getUnitsManager()?.update(buffer); }, false);
|
||||
}
|
||||
window.setTimeout(() => requestUpdate(), getConnected() ? 250 : 1000);
|
||||
|
||||
@ -335,7 +333,6 @@ export function requestUpdate() {
|
||||
|
||||
export function requestRefresh() {
|
||||
/* Main refresh rate = 5000ms. */
|
||||
|
||||
if (!getPaused()) {
|
||||
getAirbases((data: AirbasesData) => getMissionData()?.update(data));
|
||||
getBullseye((data: BullseyesData) => getMissionData()?.update(data));
|
||||
|
||||
@ -6,7 +6,7 @@ import { CustomMarker } from '../map/custommarker';
|
||||
import { SVGInjector } from '@tanem/svg-injector';
|
||||
import { UnitDatabase } from './unitdatabase';
|
||||
import { TargetMarker } from '../map/targetmarker';
|
||||
import { BLUE_COMMANDER, BOMBING, CARPET_BOMBING, DLINK, DataIndexes, FIRE_AT_AREA, HIDE_ALL, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, RED_COMMANDER, ROEs, RWR, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants';
|
||||
import { BLUE_COMMANDER, BOMBING, CARPET_BOMBING, DLINK, DataIndexes, FIRE_AT_AREA, GAME_MASTER, HIDE_ALL, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, RED_COMMANDER, ROEs, RWR, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants';
|
||||
import { Ammo, Contact, GeneralSettings, Offset, Radio, TACAN, UnitIconOptions } from '../@types/unit';
|
||||
import { DataExtractor } from './dataextractor';
|
||||
|
||||
@ -223,6 +223,10 @@ export class Unit extends CustomMarker {
|
||||
if (updateMarker)
|
||||
this.#updateMarker();
|
||||
|
||||
document.dispatchEvent(new CustomEvent("unitUpdated", { detail: this }));
|
||||
}
|
||||
|
||||
drawLines() {
|
||||
// TODO dont delete the polylines of the detected units
|
||||
this.#clearContacts();
|
||||
if (this.getSelected()) {
|
||||
@ -234,8 +238,6 @@ export class Unit extends CustomMarker {
|
||||
this.#clearPath();
|
||||
this.#clearTarget();
|
||||
}
|
||||
|
||||
document.dispatchEvent(new CustomEvent("unitUpdated", { detail: this }));
|
||||
}
|
||||
|
||||
getData() {
|
||||
@ -365,11 +367,11 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
|
||||
belongsToCommandedCoalition() {
|
||||
if (getUnitsManager().getVisibilityMode() === HIDE_ALL)
|
||||
if (getUnitsManager().getCommandMode() === HIDE_ALL)
|
||||
return false;
|
||||
if (getUnitsManager().getVisibilityMode() === BLUE_COMMANDER && this.#coalition !== "blue")
|
||||
if (getUnitsManager().getCommandMode() === BLUE_COMMANDER && this.#coalition !== "blue")
|
||||
return false;
|
||||
if (getUnitsManager().getVisibilityMode() === RED_COMMANDER && this.#coalition !== "red")
|
||||
if (getUnitsManager().getCommandMode() === RED_COMMANDER && this.#coalition !== "red")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -486,7 +488,7 @@ export class Unit extends CustomMarker {
|
||||
hidden = true;
|
||||
if (hiddenUnits.includes(this.#coalition))
|
||||
hidden = true;
|
||||
if (getUnitsManager().getVisibilityMode() === HIDE_ALL)
|
||||
if (getUnitsManager().getCommandMode() === HIDE_ALL)
|
||||
hidden = true;
|
||||
if (!this.belongsToCommandedCoalition() && this.#detectionMethods.length == 0) {
|
||||
hidden = true;
|
||||
@ -791,7 +793,8 @@ export class Unit extends CustomMarker {
|
||||
this.updateVisibility();
|
||||
|
||||
/* Draw the minimap marker */
|
||||
if (this.#alive) {
|
||||
var drawMiniMapMarker = (this.belongsToCommandedCoalition() || this.getDetectionMethods().some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value)));
|
||||
if (this.#alive && drawMiniMapMarker) {
|
||||
if (this.#miniMapMarker == null) {
|
||||
this.#miniMapMarker = new CircleMarker(new LatLng(this.#position.lat, this.#position.lng), { radius: 0.5 });
|
||||
if (this.#coalition == "neutral")
|
||||
@ -985,7 +988,7 @@ export class Unit extends CustomMarker {
|
||||
}
|
||||
else if (this.#targetID != 0) {
|
||||
const target = getUnitsManager().getUnitByID(this.#targetID);
|
||||
if (target && getUnitsManager().getUnitDetectedMethods(target).some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))) {
|
||||
if (target && (getUnitsManager().getCommandMode() == GAME_MASTER || (this.belongsToCommandedCoalition() && getUnitsManager().getUnitDetectedMethods(target).some(value => [VISUAL, OPTIC, RADAR, IRST, DLINK].includes(value))))) {
|
||||
this.#drawtargetPosition(target.getPosition());
|
||||
}
|
||||
}
|
||||
@ -1093,6 +1096,10 @@ export class NavyUnit extends Unit {
|
||||
};
|
||||
}
|
||||
|
||||
getMarkerCategory() {
|
||||
return "navyunit";
|
||||
}
|
||||
|
||||
getCategory() {
|
||||
return "NavyUnit";
|
||||
}
|
||||
@ -1109,7 +1116,7 @@ export class Weapon extends Unit {
|
||||
showState: false,
|
||||
showVvi: false,
|
||||
showHotgroup: false,
|
||||
showUnitIcon: this.belongsToCommandedCoalition(),
|
||||
showUnitIcon: true,
|
||||
showShortLabel: false,
|
||||
showFuel: false,
|
||||
showAmmo: false,
|
||||
|
||||
@ -16,7 +16,7 @@ export class UnitsManager {
|
||||
#selectionEventDisabled: boolean = false;
|
||||
#pasteDisabled: boolean = false;
|
||||
#hiddenTypes: string[] = [];
|
||||
#visibilityMode: string = HIDE_ALL;
|
||||
#commandMode: string = HIDE_ALL;
|
||||
|
||||
constructor() {
|
||||
this.#units = {};
|
||||
@ -75,7 +75,7 @@ export class UnitsManager {
|
||||
update(buffer: ArrayBuffer) {
|
||||
var dataExtractor = new DataExtractor(buffer);
|
||||
var updateTime = Number(dataExtractor.extractUInt64());
|
||||
|
||||
var requestRefresh = false;
|
||||
while (dataExtractor.getSeekPosition() < buffer.byteLength) {
|
||||
const ID = dataExtractor.extractUInt32();
|
||||
if (!(ID in this.#units)) {
|
||||
@ -85,7 +85,7 @@ export class UnitsManager {
|
||||
this.addUnit(ID, category);
|
||||
}
|
||||
else {
|
||||
// TODO request a refresh since we must have missed some packets
|
||||
requestRefresh = true;
|
||||
}
|
||||
}
|
||||
this.#units[ID]?.setData(dataExtractor);
|
||||
@ -98,6 +98,10 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
setLastUpdateTime(updateTime);
|
||||
|
||||
for (let ID in this.#units) {
|
||||
this.#units[ID].drawLines();
|
||||
};
|
||||
}
|
||||
|
||||
setHiddenType(key: string, value: boolean) {
|
||||
@ -115,21 +119,21 @@ export class UnitsManager {
|
||||
}
|
||||
|
||||
setVisibilityMode(newVisibilityMode: string) {
|
||||
if (newVisibilityMode !== this.#visibilityMode) {
|
||||
if (newVisibilityMode !== this.#commandMode) {
|
||||
document.dispatchEvent(new CustomEvent("visibilityModeChanged", { detail: this }));
|
||||
const el = document.getElementById("visibiliy-mode");
|
||||
if (el) {
|
||||
el.dataset.mode = newVisibilityMode;
|
||||
el.textContent = newVisibilityMode.toUpperCase();
|
||||
}
|
||||
this.#visibilityMode = newVisibilityMode;
|
||||
this.#commandMode = newVisibilityMode;
|
||||
for (let ID in this.#units)
|
||||
this.#units[ID].updateVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
getVisibilityMode() {
|
||||
return this.#visibilityMode;
|
||||
getCommandMode() {
|
||||
return this.#commandMode;
|
||||
}
|
||||
|
||||
selectUnit(ID: number, deselectAllUnits: boolean = true) {
|
||||
@ -558,7 +562,7 @@ export class UnitsManager {
|
||||
const probability = Math.pow(1 - minDistance / 50e3, 5) * IADSRoles[role];
|
||||
if (Math.random() < probability){
|
||||
const unitBlueprint = randomUnitBlueprintByRole(groundUnitsDatabase, role);
|
||||
spawnGroundUnits([{unitName: unitBlueprint.name, latlng: latlng}], coalitionArea.getCoalition(), true);
|
||||
spawnGroundUnits([{unitType: unitBlueprint.name, location: latlng}], coalitionArea.getCoalition(), true);
|
||||
getMap().addTemporaryMarker(latlng, unitBlueprint.name, coalitionArea.getCoalition());
|
||||
}
|
||||
}
|
||||
@ -569,10 +573,12 @@ export class UnitsManager {
|
||||
for (let ID in this.#units) {
|
||||
var unit = this.#units[ID];
|
||||
if (!["Aircraft", "Helicopter"].includes(unit.getCategory())) {
|
||||
var data: any = unit.getData();
|
||||
data.category = unit.getCategory();
|
||||
if (unit.getGroupName() in unitsToExport)
|
||||
unitsToExport[unit.getGroupName()].push(unit.getData());
|
||||
unitsToExport[unit.getGroupName()].push(data);
|
||||
else
|
||||
unitsToExport[unit.getGroupName()] = [unit.getData()];
|
||||
unitsToExport[unit.getGroupName()] = [data];
|
||||
}
|
||||
}
|
||||
var a = document.createElement("a");
|
||||
@ -594,7 +600,12 @@ export class UnitsManager {
|
||||
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";})) {
|
||||
var units = groups[groupName].map((unit: any) => {return {unitType: unit.name, location: unit.position}});
|
||||
spawnGroundUnits(units, groups[groupName][0].coalition, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
})
|
||||
|
||||
@ -38,6 +38,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ol-select-container contextmenu-options-container">
|
||||
<div>Group members</div>
|
||||
<div id="aircraft-count-options" class="ol-select">
|
||||
<div class="ol-select-value"></div>
|
||||
<div class="ol-select-options">
|
||||
<!-- This is where all the aircraft count buttons will be shown-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="aircraft-spawn-altitude-slider" class="ol-slider-container flight-control-ol-slider">
|
||||
<dl class="ol-data-grid">
|
||||
<dt> Spawn altitude
|
||||
@ -74,6 +83,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ol-select-container contextmenu-options-container">
|
||||
<div>Group members</div>
|
||||
<div id="ground-count-options" class="ol-select">
|
||||
<div class="ol-select-value"></div>
|
||||
<div class="ol-select-options">
|
||||
<!-- This is where all the groundunit count buttons will be shown-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="deploy-unit-button" title="" data-coalition="blue" data-on-click="contextMenuDeployGroundUnit" disabled>Deploy unit</button>
|
||||
</div>
|
||||
<div id="smoke-spawn-menu" class="ol-panel ol-contexmenu-panel hide">
|
||||
@ -104,7 +122,7 @@
|
||||
<h4>Parking available:</h4>
|
||||
<div id="airbase-parking"></div>
|
||||
|
||||
<button id="spawn-airbase-aircraft-button" data-coalition="red" title="Spawn aircraft" data-on-click="contextMenuSpawnAirbase" class="deploy-unit-button">Spawn</button>
|
||||
<button id="spawn-airbase-aircraft-button" data-coalition="blue" title="Spawn aircraft" data-on-click="contextMenuSpawnAirbase" class="deploy-unit-button">Spawn</button>
|
||||
<button id="land-here-button" title="Land here" data-on-click="contextMenuLandAirbase" class="hide">Land here</button>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
local version = "v0.3.0-alpha"
|
||||
|
||||
local debug = FALSE
|
||||
local debug = false
|
||||
|
||||
Olympus.unitCounter = 1
|
||||
Olympus.payloadRegistry = {}
|
||||
@ -305,10 +305,10 @@ end
|
||||
|
||||
-- Spawns a new unit or group
|
||||
function Olympus.spawnUnits(spawnTable)
|
||||
Olympus.debug("Olympus.spawnUnits " .. serializeTable(spawnTable), 2)
|
||||
Olympus.debug("Olympus.spawnUnits " .. Olympus.serializeTable(spawnTable), 2)
|
||||
|
||||
local unitTable = {}
|
||||
local route = {}
|
||||
local unitTable = nil
|
||||
local route = nil
|
||||
local category = nil
|
||||
|
||||
if spawnTable.category == 'Aircraft' then
|
||||
@ -328,6 +328,7 @@ function Olympus.spawnUnits(spawnTable)
|
||||
category = category,
|
||||
route = route,
|
||||
name = "Olympus-" .. Olympus.unitCounter,
|
||||
task = 'CAP'
|
||||
}
|
||||
mist.dynAdd(vars)
|
||||
|
||||
@ -337,16 +338,16 @@ end
|
||||
|
||||
-- Generates ground units table, either single or from template
|
||||
function Olympus.generateGroundUnitsTable(units)
|
||||
local unitTable = {}
|
||||
for idx, unit in pairs(units) do
|
||||
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(unit.lat, unit.lng, 0))
|
||||
local unitTable = {}
|
||||
if Olympus.hasKey(templates, unit.unitType) then
|
||||
for idx, value in pairs(templates[unit.unitType].units) do
|
||||
unitTable[#unitTable + 1] = {
|
||||
unitTable[#unitTable + 1] =
|
||||
{
|
||||
["type"] = value.name,
|
||||
["x"] = spawnLocation.x + value.dx,
|
||||
["y"] = spawnLocation.z + value.dy,
|
||||
["playerCanDrive"] = true,
|
||||
["heading"] = 0,
|
||||
["skill"] = "High"
|
||||
}
|
||||
@ -355,9 +356,8 @@ function Olympus.generateGroundUnitsTable(units)
|
||||
unitTable[#unitTable + 1] =
|
||||
{
|
||||
["type"] = unit.unitType,
|
||||
["x"] = unit.x,
|
||||
["y"] = unit.z,
|
||||
["playerCanDrive"] = true,
|
||||
["x"] = spawnLocation.x,
|
||||
["y"] = spawnLocation.z,
|
||||
["heading"] = 0,
|
||||
["skill"] = "High"
|
||||
}
|
||||
@ -371,12 +371,12 @@ end
|
||||
function Olympus.generateAirUnitsTable(units)
|
||||
local unitTable = {}
|
||||
for idx, unit in pairs(units) do
|
||||
local payloadName = unit.payloadName -- payloadName: a string, one of the names defined in unitPayloads.lua. Must be compatible with the unitType
|
||||
local payload = unit.payload -- payload: a table, if present the unit will receive this specific payload. Overrides payloadName
|
||||
local loadout = unit.loadout -- loadout: a string, one of the names defined in unitPayloads.lua. Must be compatible with the unitType
|
||||
local payload = unit.payload -- payload: a table, if present the unit will receive this specific payload. Overrides loadout
|
||||
|
||||
if payload == nil then
|
||||
if payloadName and payloadName ~= "" and Olympus.unitPayloads[unit.unitType][payloadName] then
|
||||
payload = Olympus.unitPayloads[unit.unitType][payloadName]
|
||||
if loadout and loadout ~= "" and Olympus.unitPayloads[unit.unitType][loadout] then
|
||||
payload = Olympus.unitPayloads[unit.unitType][loadout]
|
||||
else
|
||||
payload = {}
|
||||
end
|
||||
@ -398,10 +398,11 @@ function Olympus.generateAirUnitsTable(units)
|
||||
}
|
||||
end
|
||||
return unitTable
|
||||
end
|
||||
|
||||
function Olympus.generateAirUnitsRoute(spawnTable)
|
||||
local airbaseName = spawnTable.airbaseName -- airbaseName: a string, if present the aircraft will spawn on the ground of the selected airbase
|
||||
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(spawnTable.lat, spawnTable.lng, 0))
|
||||
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(spawnTable.units[1].lat, spawnTable.units[1].lng, 0))
|
||||
|
||||
-- If a airbase is provided the first waypoint is set as a From runway takeoff.
|
||||
local route = {}
|
||||
|
||||
@ -176,11 +176,11 @@ private:
|
||||
class SpawnAircrafts : public Command
|
||||
{
|
||||
public:
|
||||
SpawnAircrafts(string coalition, vector<string> unitTypes, vector<Coords> locations, vector<string> payloadNames, string airbaseName, bool immediate) :
|
||||
SpawnAircrafts(string coalition, vector<string> unitTypes, vector<Coords> locations, vector<string> loadouts, string airbaseName, bool immediate) :
|
||||
coalition(coalition),
|
||||
unitTypes(unitTypes),
|
||||
locations(locations),
|
||||
payloadNames(payloadNames),
|
||||
loadouts(loadouts),
|
||||
airbaseName(airbaseName),
|
||||
immediate(immediate)
|
||||
{
|
||||
@ -193,7 +193,7 @@ private:
|
||||
const string coalition;
|
||||
const vector<string> unitTypes;
|
||||
const vector<Coords> locations;
|
||||
const vector<string> payloadNames;
|
||||
const vector<string> loadouts;
|
||||
const string airbaseName;
|
||||
const bool immediate;
|
||||
};
|
||||
|
||||
@ -48,7 +48,7 @@ string SpawnGroundUnits::getString(lua_State* L)
|
||||
unitsSS << "[" << i + 1 << "] = {"
|
||||
<< "unitType = " << "\"" << unitTypes[i] << "\"" << ", "
|
||||
<< "lat = " << locations[i].lat << ", "
|
||||
<< "lng = " << locations[i].lng << "}";
|
||||
<< "lng = " << locations[i].lng << "},";
|
||||
}
|
||||
|
||||
std::ostringstream commandSS;
|
||||
@ -56,14 +56,14 @@ string SpawnGroundUnits::getString(lua_State* L)
|
||||
commandSS << "Olympus.spawnUnits, {"
|
||||
<< "category = " << "\"" << "GroundUnit" << "\"" << ", "
|
||||
<< "coalition = " << "\"" << coalition << "\"" << ", "
|
||||
<< "units = " << "\"" << unitsSS.str() << "\"" << "}";
|
||||
<< "units = " << "{" << unitsSS.str() << "}" << "}";
|
||||
return commandSS.str();
|
||||
}
|
||||
|
||||
/* Spawn aircrafts command */
|
||||
string SpawnAircrafts::getString(lua_State* L)
|
||||
{
|
||||
if (unitTypes.size() != locations.size() || unitTypes.size() != payloadNames.size()) return "";
|
||||
if (unitTypes.size() != locations.size() || unitTypes.size() != loadouts.size()) return "";
|
||||
|
||||
std::ostringstream unitsSS;
|
||||
unitsSS.precision(10);
|
||||
@ -73,7 +73,7 @@ string SpawnAircrafts::getString(lua_State* L)
|
||||
<< "lat = " << locations[i].lat << ", "
|
||||
<< "lng = " << locations[i].lng << ", "
|
||||
<< "alt = " << locations[i].alt << ", "
|
||||
<< "payloadName = \"" << payloadNames[i] << "\", " << "}";
|
||||
<< "loadout = \"" << loadouts[i] << "\"" << "},";
|
||||
}
|
||||
|
||||
std::ostringstream commandSS;
|
||||
@ -82,7 +82,7 @@ string SpawnAircrafts::getString(lua_State* L)
|
||||
<< "category = " << "\"" << "Aircraft" << "\"" << ", "
|
||||
<< "coalition = " << "\"" << coalition << "\"" << ", "
|
||||
<< "airbaseName = \"" << airbaseName << "\", "
|
||||
<< "units = " << "\"" << unitsSS.str() << "\"" << "}";
|
||||
<< "units = " << "{" << unitsSS.str() << "}" << "}";
|
||||
return commandSS.str();
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ void Scheduler::handleRequest(string key, json::value value)
|
||||
vector<string> unitTypes;
|
||||
vector<Coords> locations;
|
||||
for (auto unit : value[L"units"].as_array()) {
|
||||
string unitType = to_string(unit[L"type"]);
|
||||
string unitType = to_string(unit[L"unitType"]);
|
||||
double lat = unit[L"location"][L"lat"].as_double();
|
||||
double lng = unit[L"location"][L"lng"].as_double();
|
||||
Coords location; location.lat = lat; location.lng = lng;
|
||||
@ -119,22 +119,22 @@ void Scheduler::handleRequest(string key, json::value value)
|
||||
|
||||
vector<string> unitTypes;
|
||||
vector<Coords> locations;
|
||||
vector<string> payloadNames;
|
||||
vector<string> loadouts;
|
||||
for (auto unit : value[L"units"].as_array()) {
|
||||
string unitType = to_string(unit[L"type"]);
|
||||
string unitType = to_string(unit[L"unitType"]);
|
||||
double lat = unit[L"location"][L"lat"].as_double();
|
||||
double lng = unit[L"location"][L"lng"].as_double();
|
||||
double alt = value[L"altitude"].as_double();
|
||||
double alt = unit[L"altitude"].as_double();
|
||||
Coords location; location.lat = lat; location.lng = lng; location.alt = alt;
|
||||
string payloadName = to_string(value[L"payloadName"]);
|
||||
string loadout = to_string(unit[L"loadout"]);
|
||||
|
||||
log("Spawning " + coalition + " air unit unit of type " + unitType + " at (" + to_string(lat) + ", " + to_string(lng) + ")");
|
||||
unitTypes.push_back(unitType);
|
||||
locations.push_back(location);
|
||||
payloadNames.push_back(payloadName);
|
||||
loadouts.push_back(loadout);
|
||||
}
|
||||
|
||||
command = dynamic_cast<Command*>(new SpawnAircrafts(coalition, unitTypes, locations, payloadNames, airbaseName, immediate));
|
||||
command = dynamic_cast<Command*>(new SpawnAircrafts(coalition, unitTypes, locations, loadouts, airbaseName, immediate));
|
||||
}
|
||||
else if (key.compare("attackUnit") == 0)
|
||||
{
|
||||
|
||||
@ -221,9 +221,9 @@ string Server::extractPassword(http_request& request) {
|
||||
return "";
|
||||
|
||||
string decoded = from_base64(authorization);
|
||||
i = authorization.find(":");
|
||||
if (i != std::string::npos)
|
||||
decoded.erase(0, i);
|
||||
i = decoded.find(":");
|
||||
if (i != string::npos && i+1 < decoded.length())
|
||||
decoded.erase(0, i+1);
|
||||
else
|
||||
return "";
|
||||
|
||||
@ -255,12 +255,11 @@ void Server::task()
|
||||
else
|
||||
log("Error reading configuration file. Starting server on " + address);
|
||||
|
||||
if (config.is_object() && config.has_object_field(L"authentication") &&
|
||||
config[L"authentication"].has_string_field(L"password"))
|
||||
if (config.is_object() && config.has_object_field(L"authentication"))
|
||||
{
|
||||
gameMasterPassword = to_string(config[L"authentication"][L"gameMasterPassword"]);
|
||||
blueCommanderPassword = to_string(config[L"authentication"][L"blueCommanderPassword"]);
|
||||
redCommanderPassword = to_string(config[L"authentication"][L"redCommanderPassword"]);
|
||||
if (config[L"authentication"].has_string_field(L"gameMasterPassword")) gameMasterPassword = to_string(config[L"authentication"][L"gameMasterPassword"]);
|
||||
if (config[L"authentication"].has_string_field(L"blueCommanderPassword")) blueCommanderPassword = to_string(config[L"authentication"][L"blueCommanderPassword"]);
|
||||
if (config[L"authentication"].has_string_field(L"redCommanderPassword")) redCommanderPassword = to_string(config[L"authentication"][L"redCommanderPassword"]);
|
||||
}
|
||||
else
|
||||
log("Error reading configuration file. No password set.");
|
||||
|
||||
@ -84,7 +84,7 @@ void Unit::runAILoop() {
|
||||
const bool isUnitLeaderOfAGroupWithOtherUnits = unitsManager->isUnitInGroup(this) && unitsManager->isUnitGroupLeader(this);
|
||||
if (!(isUnitAlive || isUnitLeaderOfAGroupWithOtherUnits)) return;
|
||||
|
||||
if (checkTaskFailed() && state != State::IDLE && State::LAND)
|
||||
if (checkTaskFailed() && state != State::IDLE && state != State::LAND)
|
||||
setState(State::IDLE);
|
||||
|
||||
AIloop();
|
||||
@ -188,10 +188,10 @@ bool Unit::hasFreshData(unsigned long long time) {
|
||||
void Unit::getData(stringstream& ss, unsigned long long time)
|
||||
{
|
||||
Unit* leader = this;
|
||||
if (unitsManager->isUnitInGroup(this) && !unitsManager->isUnitGroupLeader(this))
|
||||
if (unitsManager->isUnitInGroup(this) && !unitsManager->isUnitGroupLeader(this))
|
||||
leader = unitsManager->getGroupLeader(this);
|
||||
|
||||
if (!leader->hasFreshData(time)) return;
|
||||
if (leader == nullptr || (!leader->hasFreshData(time) && !hasFreshData(time))) return;
|
||||
|
||||
const unsigned char endOfData = DataIndex::endOfData;
|
||||
ss.write((const char*)&ID, sizeof(ID));
|
||||
|
||||
@ -39,6 +39,7 @@ bool UnitsManager::isUnitInGroup(Unit* unit)
|
||||
{
|
||||
if (unit != nullptr) {
|
||||
string groupName = unit->getGroupName();
|
||||
if (groupName.length() == 0) return false;
|
||||
for (auto const& p : units)
|
||||
{
|
||||
if (p.second->getGroupName().compare(groupName) == 0 && p.second != unit)
|
||||
@ -50,8 +51,10 @@ bool UnitsManager::isUnitInGroup(Unit* unit)
|
||||
|
||||
bool UnitsManager::isUnitGroupLeader(Unit* unit)
|
||||
{
|
||||
if (unit != nullptr)
|
||||
return unit == getGroupLeader(unit);
|
||||
if (unit != nullptr) {
|
||||
Unit* leader = getGroupLeader(unit);
|
||||
return leader == nullptr? false: unit == getGroupLeader(unit);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@ -61,7 +64,7 @@ Unit* UnitsManager::getGroupLeader(Unit* unit)
|
||||
{
|
||||
if (unit != nullptr) {
|
||||
string groupName = unit->getGroupName();
|
||||
|
||||
if (groupName.length() == 0) return nullptr;
|
||||
/* Find the first unit that has the same groupName */
|
||||
for (auto const& p : units)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user