mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Converted clone function to pure lua
This commit is contained in:
parent
aca1e112d2
commit
3607f88e18
@ -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();
|
||||
|
||||
|
||||
@ -198,8 +198,8 @@ export function followUnit(ID: number, targetID: number, offset: { "x": number,
|
||||
POST(data, () => { });
|
||||
}
|
||||
|
||||
export function cloneUnit(ID: number, latlng: LatLng) {
|
||||
var command = { "ID": ID, "location": latlng };
|
||||
export function cloneUnits(units: {ID: number, location: LatLng}[]) {
|
||||
var command = { "units": units };
|
||||
var data = { "cloneUnit": command }
|
||||
POST(data, () => { });
|
||||
}
|
||||
|
||||
@ -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";
|
||||
@ -34,10 +34,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 +66,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 +91,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 +196,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 +209,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 +247,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 +408,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);
|
||||
}
|
||||
@ -568,22 +562,22 @@ export class UnitsManager {
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/***********************************************/
|
||||
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,30 +589,22 @@ 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 */
|
||||
var units: { ID: number, location: LatLng }[] = [];
|
||||
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);
|
||||
});
|
||||
}
|
||||
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);
|
||||
units.push({ ID: unit.ID, location: position });
|
||||
});
|
||||
cloneUnits(units);
|
||||
}
|
||||
getInfoPopup().setText(`${this.#copiedUnits.length - 1} units pasted`);
|
||||
}
|
||||
@ -627,12 +613,12 @@ export class UnitsManager {
|
||||
}
|
||||
}
|
||||
|
||||
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,9 +628,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);
|
||||
this.spawnUnits("GroundUnit", [{ unitType: unitBlueprint.name, location: latlng, liveryID: "" }], coalitionArea.getCoalition(), true);
|
||||
getMap().addTemporaryMarker(latlng, unitBlueprint.name, coalitionArea.getCoalition());
|
||||
}
|
||||
}
|
||||
@ -655,19 +641,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 +668,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: "" }
|
||||
});
|
||||
@ -707,31 +693,31 @@ export class UnitsManager {
|
||||
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);
|
||||
spawnPoints = units.reduce((points: number, unit: any) => { return points + aircraftDatabase.getSpawnPointsByName(unit.unitType) }, 0);
|
||||
spawnAircrafts(units, coalition, airbase, country, immediate, spawnPoints);
|
||||
} else if (category === "Helicopter") {
|
||||
if (airbase == "" && getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
|
||||
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);
|
||||
spawnPoints = units.reduce((points: number, unit: any) => { return points + helicopterDatabase.getSpawnPointsByName(unit.unitType) }, 0);
|
||||
spawnHelicopters(units, coalition, airbase, country, immediate, spawnPoints);
|
||||
} else if (category === "GroundUnit") {
|
||||
if (getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
|
||||
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);
|
||||
spawnPoints = units.reduce((points: number, unit: any) => { return points + groundUnitDatabase.getSpawnPointsByName(unit.unitType) }, 0);
|
||||
spawnGroundUnits(units, coalition, country, immediate, spawnPoints);
|
||||
} else if (category === "NavyUnit") {
|
||||
if (getMissionHandler().getCommandModeOptions().restrictSpawns && getMissionHandler().getRemainingSetupTime() < 0 && getMissionHandler().getCommandModeOptions().commandMode !== GAME_MASTER) {
|
||||
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);
|
||||
spawnPoints = units.reduce((points: number, unit: any) => { return points + navyUnitDatabase.getSpawnPointsByName(unit.unitType) }, 0);
|
||||
spawnNavyUnits(units, coalition, country, immediate, spawnPoints);
|
||||
}
|
||||
|
||||
|
||||
if (spawnPoints <= getMissionHandler().getAvailableSpawnPoints()) {
|
||||
getMissionHandler().setSpentSpawnPoints(spawnPoints);
|
||||
return true;
|
||||
@ -747,7 +733,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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ Olympus.OlympusModPath = os.getenv('DCSOLYMPUS_PATH')..'\\bin\\'
|
||||
Olympus.log = mist.Logger:new("Olympus", 'info')
|
||||
|
||||
Olympus.unitCounter = 1
|
||||
Olympus.payloadRegistry = {}
|
||||
Olympus.spawnDatabase = {}
|
||||
|
||||
Olympus.missionData = {}
|
||||
Olympus.unitsData = {}
|
||||
@ -382,28 +382,26 @@ end
|
||||
function Olympus.spawnUnits(spawnTable)
|
||||
Olympus.debug("Olympus.spawnUnits " .. Olympus.serializeTable(spawnTable), 2)
|
||||
|
||||
local unitTable = nil
|
||||
local unitsTable = nil
|
||||
local route = nil
|
||||
local category = nil
|
||||
|
||||
if spawnTable.category == 'Aircraft' then
|
||||
unitTable = Olympus.generateAirUnitsTable(spawnTable.units)
|
||||
unitsTable = Olympus.generateAirUnitsTable(spawnTable.units)
|
||||
route = Olympus.generateAirUnitsRoute(spawnTable)
|
||||
category = 'plane'
|
||||
elseif spawnTable.category == 'Helicopter' then
|
||||
unitTable = Olympus.generateAirUnitsTable(spawnTable.units)
|
||||
unitsTable = Olympus.generateAirUnitsTable(spawnTable.units)
|
||||
route = Olympus.generateAirUnitsRoute(spawnTable)
|
||||
category = 'helicopter'
|
||||
elseif spawnTable.category == 'GroundUnit' then
|
||||
unitTable = Olympus.generateGroundUnitsTable(spawnTable.units)
|
||||
unitsTable = Olympus.generateGroundUnitsTable(spawnTable.units)
|
||||
category = 'vehicle'
|
||||
elseif spawnTable.category == 'NavyUnit' then
|
||||
unitTable = Olympus.generateNavyUnitsTable(spawnTable.units)
|
||||
unitsTable = Olympus.generateNavyUnitsTable(spawnTable.units)
|
||||
category = 'ship'
|
||||
end
|
||||
|
||||
Olympus.debug(Olympus.serializeTable(unitTable), 5)
|
||||
|
||||
local countryID = 0
|
||||
if spawnTable.country == nil or spawnTable.country == "" then
|
||||
countryID = Olympus.getCountryIDByCoalition(spawnTable.coalition)
|
||||
@ -411,9 +409,14 @@ function Olympus.spawnUnits(spawnTable)
|
||||
countryID = country.id[spawnTable.country]
|
||||
end
|
||||
|
||||
-- Save the units in the database, for cloning
|
||||
for idx, unitTable in pairs(unitTable) do
|
||||
Olympus.addToDatabase(unitTable)
|
||||
end
|
||||
|
||||
local vars =
|
||||
{
|
||||
units = unitTable,
|
||||
units = unitsTable,
|
||||
country = countryID,
|
||||
category = category,
|
||||
route = route,
|
||||
@ -428,7 +431,7 @@ end
|
||||
|
||||
-- Generates unit table for a air unit.
|
||||
function Olympus.generateAirUnitsTable(units)
|
||||
local unitTable = {}
|
||||
local unitsTable = {}
|
||||
for idx, unit in pairs(units) do
|
||||
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
|
||||
@ -446,7 +449,7 @@ function Olympus.generateAirUnitsTable(units)
|
||||
end
|
||||
|
||||
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(unit.lat, unit.lng, 0))
|
||||
unitTable[#unitTable + 1] =
|
||||
unitsTable[#unitsTable + 1] =
|
||||
{
|
||||
["type"] = unit.unitType,
|
||||
["x"] = spawnLocation.x,
|
||||
@ -456,15 +459,12 @@ function Olympus.generateAirUnitsTable(units)
|
||||
["skill"] = "Excellent",
|
||||
["payload"] = { ["pylons"] = payload, ["fuel"] = 999999, ["flare"] = 60, ["ammo_type"] = 1, ["chaff"] = 60, ["gun"] = 100, },
|
||||
["heading"] = unit.heading,
|
||||
["callsign"] = { [1] = 1, [2] = 1, [3] = 1, ["name"] = "Olympus" .. Olympus.unitCounter.. "-" .. #unitTable + 1 },
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitTable + 1,
|
||||
["callsign"] = { [1] = 1, [2] = 1, [3] = 1, ["name"] = "Olympus" .. Olympus.unitCounter.. "-" .. #unitsTable + 1 },
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitsTable + 1,
|
||||
["livery_id"] = unit.liveryID
|
||||
}
|
||||
|
||||
-- Add the payload to the registry, used for unit cloning
|
||||
Olympus.payloadRegistry[unitTable[#unitTable].name] = payload
|
||||
end
|
||||
return unitTable
|
||||
return unitsTable
|
||||
end
|
||||
|
||||
function Olympus.generateAirUnitsRoute(spawnTable)
|
||||
@ -525,99 +525,119 @@ end
|
||||
|
||||
-- Generates ground units table, either single or from template
|
||||
function Olympus.generateGroundUnitsTable(units)
|
||||
local unitTable = {}
|
||||
local unitsTable = {}
|
||||
for idx, unit in pairs(units) do
|
||||
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(unit.lat, unit.lng, 0))
|
||||
if Olympus.hasKey(templates, unit.unitType) then
|
||||
for idx, value in pairs(templates[unit.unitType].units) do
|
||||
unitTable[#unitTable + 1] =
|
||||
unitsTable[#unitsTable + 1] =
|
||||
{
|
||||
["type"] = value.name,
|
||||
["x"] = spawnLocation.x + value.dx,
|
||||
["y"] = spawnLocation.z + value.dy,
|
||||
["heading"] = 0,
|
||||
["skill"] = "High",
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitTable + 1
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitsTable + 1
|
||||
}
|
||||
end
|
||||
else
|
||||
unitTable[#unitTable + 1] =
|
||||
unitsTable[#unitsTable + 1] =
|
||||
{
|
||||
["type"] = unit.unitType,
|
||||
["x"] = spawnLocation.x,
|
||||
["y"] = spawnLocation.z,
|
||||
["heading"] = unit.heading,
|
||||
["skill"] = "High",
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitTable + 1,
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitsTable + 1,
|
||||
["livery_id"] = unit.liveryID
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return unitTable
|
||||
return unitsTable
|
||||
end
|
||||
|
||||
-- Generates navy units table, either single or from template
|
||||
function Olympus.generateNavyUnitsTable(units)
|
||||
local unitTable = {}
|
||||
local unitsTable = {}
|
||||
for idx, unit in pairs(units) do
|
||||
local spawnLocation = mist.utils.makeVec3GL(coord.LLtoLO(unit.lat, unit.lng, 0))
|
||||
if Olympus.hasKey(templates, unit.unitType) then
|
||||
for idx, value in pairs(templates[unit.unitType].units) do
|
||||
unitTable[#unitTable + 1] =
|
||||
unitsTable[#unitsTable + 1] =
|
||||
{
|
||||
["type"] = value.name,
|
||||
["x"] = spawnLocation.x + value.dx,
|
||||
["y"] = spawnLocation.z + value.dy,
|
||||
["heading"] = 0,
|
||||
["skill"] = "High",
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitTable + 1,
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitsTable + 1,
|
||||
["transportable"] = { ["randomTransportable"] = false }
|
||||
}
|
||||
end
|
||||
else
|
||||
unitTable[#unitTable + 1] =
|
||||
unitsTable[#unitsTable + 1] =
|
||||
{
|
||||
["type"] = unit.unitType,
|
||||
["x"] = spawnLocation.x,
|
||||
["y"] = spawnLocation.z,
|
||||
["heading"] = unit.heading,
|
||||
["skill"] = "High",
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitTable + 1,
|
||||
["name"] = "Olympus-" .. Olympus.unitCounter .. "-" .. #unitsTable + 1,
|
||||
["transportable"] = { ["randomTransportable"] = false },
|
||||
["livery_id"] = unit.liveryID
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return unitTable
|
||||
return unitsTable
|
||||
end
|
||||
|
||||
-- Clones a unit by ID. Will clone the unit with the same original payload as the source unit. TODO: only works on Olympus unit not ME units.
|
||||
function Olympus.clone(ID, lat, lng, category)
|
||||
Olympus.debug("Olympus.clone " .. ID .. ", " .. category, 2)
|
||||
local unit = Olympus.getUnitByID(ID)
|
||||
if unit then
|
||||
local position = unit:getPosition()
|
||||
local heading = math.atan2( position.x.z, position.x.x )
|
||||
|
||||
-- TODO: understand category in this script
|
||||
local spawnTable = {
|
||||
function Olympus.addToDatabase(unitTable)
|
||||
-- Add the unit data to the database, used for unit cloning
|
||||
Olympus.spawnDatabase[unitTable.name] = unitTable
|
||||
end
|
||||
|
||||
-- Clones a unit by ID. Will clone the unit with the same original payload as the source unit. TODO: only works on Olympus unit not ME units (TO BE VERIFIED).
|
||||
function Olympus.clone(cloneTable)
|
||||
Olympus.debug("Olympus.clone " .. cloneTable, 2)
|
||||
|
||||
local unitsTable = {}
|
||||
local coalition = nil
|
||||
local category = nil
|
||||
|
||||
for cloneData, idx in pairs(cloneTable) do
|
||||
local ID = cloneData.ID
|
||||
local unit = Olympus.getUnitByID(ID)
|
||||
|
||||
if unit then
|
||||
local position = unit:getPosition()
|
||||
local heading = math.atan2( position.x.z, position.x.x )
|
||||
|
||||
-- Update the data of the cloned unit
|
||||
local unitTable = Olympus.spawnDatabase[unit:getName()]
|
||||
|
||||
if unitTable then
|
||||
unitTable["lat"] = lat
|
||||
unitTable["lng"] = lng
|
||||
unitTable["alt"] = unit:getPoint().y
|
||||
unitTable["heading"] = heading
|
||||
end
|
||||
|
||||
coalition = Olympus.getCoalitionByCoalitionID(unit:getCoalition()),
|
||||
category = category,
|
||||
units = {
|
||||
[1] = {
|
||||
lat = lat,
|
||||
lng = lng,
|
||||
alt = unit:getPoint().y,
|
||||
heading = heading,
|
||||
unitType = unit:getTypeName(),
|
||||
payload = Olympus.payloadRegistry[unit:getName()]
|
||||
}
|
||||
}
|
||||
}
|
||||
Olympus.spawnUnits(spawnTable)
|
||||
category = unit:getDesc().category,
|
||||
|
||||
unitsTable[#unitsTable + 1] = unitTable
|
||||
end
|
||||
end
|
||||
|
||||
local spawnTable = {
|
||||
coalition = coalition,
|
||||
category = category,
|
||||
units = unitsTable
|
||||
}
|
||||
Olympus.spawnUnits(spawnTable)
|
||||
|
||||
Olympus.debug("Olympus.clone completed successfully", 2)
|
||||
end
|
||||
|
||||
@ -915,8 +935,8 @@ end
|
||||
|
||||
function Olympus.initializeUnits()
|
||||
if mist and mist.DBs and mist.DBs.MEunitsById then
|
||||
for id, unitTable in pairs(mist.DBs.MEunitsById) do
|
||||
local unit = Unit.getByName(unitTable["unitName"])
|
||||
for id, unitsTable in pairs(mist.DBs.MEunitsById) do
|
||||
local unit = Unit.getByName(unitsTable["unitName"])
|
||||
if unit then
|
||||
Olympus.units[unit["id_"]] = unit
|
||||
end
|
||||
|
||||
@ -248,9 +248,8 @@ private:
|
||||
class Clone : public Command
|
||||
{
|
||||
public:
|
||||
Clone(unsigned int ID, Coords location) :
|
||||
ID(ID),
|
||||
location(location)
|
||||
Clone(vector<CloneOptions> cloneOptions) :
|
||||
cloneOptions(cloneOptions)
|
||||
{
|
||||
priority = CommandPriority::LOW;
|
||||
};
|
||||
@ -258,8 +257,7 @@ public:
|
||||
virtual unsigned int getLoad() { return 30; }
|
||||
|
||||
private:
|
||||
const unsigned int ID;
|
||||
const Coords location;
|
||||
const vector<CloneOptions> cloneOptions;
|
||||
};
|
||||
|
||||
/* Delete unit command */
|
||||
|
||||
@ -120,4 +120,9 @@ struct SpawnOptions {
|
||||
Coords location;
|
||||
string loadout;
|
||||
string liveryID;
|
||||
};
|
||||
|
||||
struct CloneOptions {
|
||||
unsigned int ID;
|
||||
Coords location;
|
||||
};
|
||||
@ -140,22 +140,21 @@ string SpawnHelicopters::getString()
|
||||
/* Clone unit command */
|
||||
string Clone::getString()
|
||||
{
|
||||
Unit* unit = unitsManager->getUnit(ID);
|
||||
if (unit != nullptr)
|
||||
{
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.clone, "
|
||||
<< ID << ", "
|
||||
<< location.lat << ", "
|
||||
<< location.lng << ", "
|
||||
<< "\"" << unit->getCategory() << "\"";
|
||||
return commandSS.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
std::ostringstream unitsSS;
|
||||
unitsSS.precision(10);
|
||||
for (int i = 0; i < cloneOptions.size(); i++) {
|
||||
unitsSS << "[" << i + 1 << "] = {"
|
||||
<< "ID = " << cloneOptions[i].ID << ", "
|
||||
<< "lat = " << cloneOptions[i].location.lat << ", "
|
||||
<< "lng = " << cloneOptions[i].location.lng << " }, ";
|
||||
}
|
||||
|
||||
std::ostringstream commandSS;
|
||||
commandSS.precision(10);
|
||||
commandSS << "Olympus.clone, "
|
||||
<< "{" << unitsSS.str() << "}";
|
||||
return commandSS.str();
|
||||
|
||||
}
|
||||
|
||||
/* Delete unit command */
|
||||
|
||||
@ -376,13 +376,20 @@ void Scheduler::handleRequest(string key, json::value value, string username)
|
||||
if (unit != nullptr)
|
||||
unit->setDesiredAltitudeType(to_string(value[L"altitudeType"]));
|
||||
}
|
||||
else if (key.compare("cloneUnit") == 0)
|
||||
else if (key.compare("cloneUnits") == 0)
|
||||
{
|
||||
unsigned int ID = value[L"ID"].as_integer();
|
||||
double lat = value[L"location"][L"lat"].as_double();
|
||||
double lng = value[L"location"][L"lng"].as_double();
|
||||
Coords loc; loc.lat = lat; loc.lng = lng;
|
||||
command = dynamic_cast<Command*>(new Clone(ID, loc));
|
||||
vector<CloneOptions> cloneOptions;
|
||||
|
||||
for (auto unit : value[L"units"].as_array()) {
|
||||
unsigned int ID = unit[L"ID"].as_integer();
|
||||
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;
|
||||
cloneOptions.push_back({ ID, location });
|
||||
}
|
||||
|
||||
command = dynamic_cast<Command*>(new Clone(cloneOptions));
|
||||
}
|
||||
else if (key.compare("setROE") == 0)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user