mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Mid-way commit
This commit is contained in:
parent
b43afd4e9c
commit
9ef6efa3e0
@ -138,6 +138,7 @@ export interface Offset {
|
||||
|
||||
export interface UnitData {
|
||||
category: string,
|
||||
categoryDisplayName: string,
|
||||
ID: number;
|
||||
alive: boolean;
|
||||
human: boolean;
|
||||
|
||||
@ -35,6 +35,10 @@ export class MissionManager {
|
||||
this.#commandModeErasDropdown = new Dropdown("command-mode-era-options", () => {});
|
||||
}
|
||||
|
||||
/** Update location of bullseyes
|
||||
*
|
||||
* @param object <BulleyesData>
|
||||
*/
|
||||
updateBullseyes(data: BullseyesData) {
|
||||
const commandMode = getApp().getMissionManager().getCommandModeOptions().commandMode;
|
||||
for (let idx in data.bullseyes) {
|
||||
@ -56,6 +60,10 @@ export class MissionManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** Update airbase information
|
||||
*
|
||||
* @param object <AirbasesData>
|
||||
*/
|
||||
updateAirbases(data: AirbasesData) {
|
||||
for (let idx in data.airbases) {
|
||||
var airbase = data.airbases[idx]
|
||||
@ -75,6 +83,10 @@ export class MissionManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** Update mission information
|
||||
*
|
||||
* @param object <MissionData>
|
||||
*/
|
||||
updateMission(data: MissionData) {
|
||||
if (data.mission) {
|
||||
|
||||
@ -109,30 +121,63 @@ export class MissionManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the bullseyes set in this theatre
|
||||
*
|
||||
* @returns object
|
||||
*/
|
||||
getBullseyes() {
|
||||
return this.#bullseyes;
|
||||
}
|
||||
|
||||
/** Get the airbases in this theatre
|
||||
*
|
||||
* @returns object
|
||||
*/
|
||||
getAirbases() {
|
||||
return this.#airbases;
|
||||
}
|
||||
|
||||
/** Get the options/settings as set in the command mode
|
||||
*
|
||||
* @returns object
|
||||
*/
|
||||
getCommandModeOptions() {
|
||||
return this.#commandModeOptions;
|
||||
}
|
||||
|
||||
/** Get the current date and time of the mission (based on local time)
|
||||
*
|
||||
* @returns object
|
||||
*/
|
||||
getDateAndTime() {
|
||||
return this.#dateAndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of seconds left of setup time
|
||||
* @returns number
|
||||
*/
|
||||
getRemainingSetupTime() {
|
||||
return this.#remainingSetupTime;
|
||||
}
|
||||
|
||||
/** Get an object with the coalitions in it
|
||||
*
|
||||
* @returns object
|
||||
*/
|
||||
getCoalitions() {
|
||||
return this.#coalitions;
|
||||
}
|
||||
|
||||
/** Get the current theatre (map) name
|
||||
*
|
||||
* @returns string
|
||||
*/
|
||||
getTheatre() {
|
||||
return this.#theatre;
|
||||
}
|
||||
|
||||
|
||||
getAvailableSpawnPoints() {
|
||||
if (this.getCommandModeOptions().commandMode === GAME_MASTER)
|
||||
return Infinity;
|
||||
|
||||
@ -5,7 +5,7 @@ import { CustomMarker } from '../map/markers/custommarker';
|
||||
import { SVGInjector } from '@tanem/svg-injector';
|
||||
import { UnitDatabase } from './databases/unitdatabase';
|
||||
import { TargetMarker } from '../map/markers/targetmarker';
|
||||
import { DLINK, DataIndexes, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_UNIT_CONTACTS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS, FILL_SELECTED_RING } from '../constants/constants';
|
||||
import { DLINK, DataIndexes, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_UNIT_CONTACTS, SHOW_UNITS_ENGAGEMENT_RINGS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states, SHOW_UNITS_ACQUISITION_RINGS, HIDE_UNITS_SHORT_RANGE_RINGS, FILL_SELECTED_RING, GROUND_UNIT_AIR_DEFENCE_REGEX } from '../constants/constants';
|
||||
import { DataExtractor } from '../server/dataextractor';
|
||||
import { groundUnitDatabase } from './databases/groundunitdatabase';
|
||||
import { navyUnitDatabase } from './databases/navyunitdatabase';
|
||||
@ -211,6 +211,14 @@ export class Unit extends CustomMarker {
|
||||
return "";
|
||||
}
|
||||
|
||||
/** Get the category but for display use - for the user. (i.e. has spaces in it)
|
||||
*
|
||||
* @returns string
|
||||
*/
|
||||
getCategoryLabel() {
|
||||
return ((GROUND_UNIT_AIR_DEFENCE_REGEX.test(this.getType())) ? "Air Defence" : this.getCategory()).replace(/([a-z])([A-Z])/g, "$1 $2");
|
||||
}
|
||||
|
||||
/********************** Unit data *************************/
|
||||
setData(dataExtractor: DataExtractor) {
|
||||
var updateMarker = !getApp().getMap().hasLayer(this);
|
||||
@ -291,6 +299,7 @@ export class Unit extends CustomMarker {
|
||||
getData(): UnitData {
|
||||
return {
|
||||
category: this.getCategory(),
|
||||
categoryDisplayName: this.getCategoryLabel(),
|
||||
ID: this.ID,
|
||||
alive: this.#alive,
|
||||
human: this.#human,
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export abstract class unitDataFile {
|
||||
export abstract class UnitDataFile {
|
||||
constructor() {}
|
||||
}
|
||||
@ -1,10 +1,11 @@
|
||||
import { getApp } from "..";
|
||||
import { GROUND_UNIT_AIR_DEFENCE_REGEX } from "../constants/constants";
|
||||
import { Dialog } from "../dialog/dialog";
|
||||
import { zeroAppend } from "../other/utils";
|
||||
import { Unit } from "./unit";
|
||||
import { unitDataFile } from "./unitdatafile";
|
||||
import { UnitDataFile } from "./unitdatafile";
|
||||
|
||||
export class UnitDataFileExport extends unitDataFile {
|
||||
export class UnitDataFileExport extends UnitDataFile {
|
||||
|
||||
#data!:any;
|
||||
#dialog:Dialog;
|
||||
@ -19,7 +20,7 @@ export class UnitDataFileExport extends unitDataFile {
|
||||
this.#categoryCoalitionMatrix = <HTMLElement>this.#element.querySelector("tbody");
|
||||
this.#categoryCoalitionHeaders = <HTMLElement>this.#element.querySelector("thead");
|
||||
|
||||
this.#element.querySelector(".start-transfer")?.addEventListener("click", (ev:MouseEventInit) => {
|
||||
this.#element.querySelector(".start-transfer.export")?.addEventListener("click", (ev:MouseEventInit) => {
|
||||
this.#doExport();
|
||||
});
|
||||
}
|
||||
@ -30,13 +31,13 @@ export class UnitDataFileExport extends unitDataFile {
|
||||
showForm(units:Unit[]) {
|
||||
this.#element.setAttribute( "data-mode", "export" );
|
||||
|
||||
const data:any = {};
|
||||
|
||||
const data:any = {};
|
||||
const categories:string[] = [];
|
||||
const coalitions:string[] = [];
|
||||
const unitCanBeExported = (unit:Unit) => ["GroundUnit", "NavyUnit"].includes(unit.getCategory());
|
||||
|
||||
units.filter((unit:Unit) => unit.getAlive()).forEach((unit:Unit) => {
|
||||
const category = ((GROUND_UNIT_AIR_DEFENCE_REGEX.test(unit.getType())) ? "Air Defence" : unit.getCategory()).replace( /(\w)([A-Z])/g, "$1 $2");
|
||||
units.filter((unit:Unit) => unit.getAlive() && unitCanBeExported(unit)).forEach((unit:Unit) => {
|
||||
const category = unit.getCategoryLabel();
|
||||
const coalition = unit.getCoalition();
|
||||
|
||||
if (!coalitions.includes(coalition))
|
||||
@ -68,7 +69,7 @@ export class UnitDataFileExport extends unitDataFile {
|
||||
coalitions.forEach((coalition:string) => {
|
||||
if (index === 0)
|
||||
headersHTML += `<th data-coalition="${coalition}">${coalition}</th>`;
|
||||
matrixHTML += `<td data-coalition="${coalition}">${(data[category].hasOwnProperty(coalition)) ? `<input type="checkbox" name="category-coalition-selection" value="${category}:${coalition}" checked />`: "-"}</td>`;
|
||||
matrixHTML += `<td data-coalition="${coalition}"><input type="checkbox" name="category-coalition-selection" value="${category}:${coalition}" ${(data[category].hasOwnProperty(coalition)) ? "checked": "disabled readonly"} /></td>`;
|
||||
});
|
||||
|
||||
matrixHTML += "</tr>";
|
||||
@ -78,7 +79,6 @@ export class UnitDataFileExport extends unitDataFile {
|
||||
this.#categoryCoalitionMatrix.innerHTML = matrixHTML;
|
||||
this.#dialog.show();
|
||||
}
|
||||
|
||||
|
||||
#doExport() {
|
||||
|
||||
@ -109,7 +109,7 @@ export class UnitDataFileExport extends unitDataFile {
|
||||
const a = document.createElement("a");
|
||||
const file = new Blob([JSON.stringify(unitsToExport)], { type: 'text/plain' });
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = `olympus_export_${date.getFullYear()}-${zeroAppend(date.getMonth()+1, 2)}-${zeroAppend(date.getDate(), 2)}_${zeroAppend(date.getHours(), 2)}${zeroAppend(date.getMinutes(), 2)}${zeroAppend(date.getSeconds(), 2)}.json`;
|
||||
a.download = `olympus_${getApp().getMissionManager().getTheatre().replace( /[^\w]/gi, "" ).toLowerCase()}_${date.getFullYear()}${zeroAppend(date.getMonth()+1, 2)}${zeroAppend(date.getDate(), 2)}_${zeroAppend(date.getHours(), 2)}${zeroAppend(date.getMinutes(), 2)}${zeroAppend(date.getSeconds(), 2)}.json`;
|
||||
a.click();
|
||||
this.#dialog.hide();
|
||||
}
|
||||
|
||||
62
client/src/unit/unitdatafileimport.ts
Normal file
62
client/src/unit/unitdatafileimport.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { getApp } from "..";
|
||||
import { GROUND_UNIT_AIR_DEFENCE_REGEX } from "../constants/constants";
|
||||
import { Dialog } from "../dialog/dialog";
|
||||
import { zeroAppend } from "../other/utils";
|
||||
import { Unit } from "./unit";
|
||||
import { UnitDataFile } from "./unitdatafile";
|
||||
|
||||
export class UnitDataFileImport extends UnitDataFile {
|
||||
|
||||
#data!:any;
|
||||
#dialog:Dialog;
|
||||
#element!:HTMLElement;
|
||||
#categoryCoalitionHeaders!: HTMLElement;
|
||||
#categoryCoalitionMatrix!: HTMLElement;
|
||||
|
||||
constructor( elementId:string ) {
|
||||
super();
|
||||
this.#dialog = new Dialog(elementId);
|
||||
this.#element = this.#dialog.getElement();
|
||||
this.#categoryCoalitionMatrix = <HTMLElement>this.#element.querySelector("tbody");
|
||||
this.#categoryCoalitionHeaders = <HTMLElement>this.#element.querySelector("thead");
|
||||
|
||||
// this.#element.querySelector(".start-transfer.import")?.addEventListener("click", (ev:MouseEventInit) => {
|
||||
// this.#doImport();
|
||||
// });
|
||||
}
|
||||
|
||||
#doImport() {
|
||||
|
||||
/*
|
||||
for (let groupName in groups) {
|
||||
if (groupName !== "" && groups[groupName].length > 0 && (groups[groupName].every((unit: UnitData) => { return unit.category == "GroundUnit"; }) || groups[groupName].every((unit: any) => { return unit.category == "NavyUnit"; }))) {
|
||||
var aliveUnits = groups[groupName].filter((unit: UnitData) => { return unit.alive });
|
||||
var units = aliveUnits.map((unit: UnitData) => {
|
||||
return { unitType: unit.name, location: unit.position, liveryID: "" }
|
||||
});
|
||||
getApp().getUnitsManager().spawnUnits(groups[groupName][0].category, units, groups[groupName][0].coalition, true);
|
||||
}
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
selectFile() {
|
||||
var input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.addEventListener("change", (e: any) => {
|
||||
var file = e.target.files[0];
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e: any) {
|
||||
var contents = e.target.result;
|
||||
var groups = JSON.parse(contents);
|
||||
console.log(groups);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
})
|
||||
input.click();
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,6 +16,7 @@ import { HotgroupPanel } from "../panels/hotgrouppanel";
|
||||
import { Contact, UnitData, UnitSpawnTable } from "../interfaces";
|
||||
import { Dialog } from "../dialog/dialog";
|
||||
import { UnitDataFileExport } from "./unitdatafileexport";
|
||||
import { UnitDataFileImport } from "./unitdatafileimport";
|
||||
|
||||
/** The UnitsManager handles the creation, update, and control of units. Data is strictly updated by the server ONLY. This means that any interaction from the user will always and only
|
||||
* result in a command to the server, executed by means of a REST PUT request. Any subsequent change in data will be reflected only when the new data is sent back by the server. This strategy allows
|
||||
@ -28,7 +29,8 @@ export class UnitsManager {
|
||||
#selectionEventDisabled: boolean = false;
|
||||
#slowDeleteDialog!:Dialog;
|
||||
#units: { [ID: number]: Unit };
|
||||
|
||||
#unitDataExport!:UnitDataFileExport;
|
||||
#unitDataImport!:UnitDataFileImport;
|
||||
|
||||
constructor() {
|
||||
this.#copiedUnits = [];
|
||||
@ -986,38 +988,18 @@ export class UnitsManager {
|
||||
* TODO: Extend to aircraft and helicopters
|
||||
*/
|
||||
exportToFile() {
|
||||
const fileExport = new UnitDataFileExport("unit-import-export-dialog");
|
||||
fileExport.showForm(Object.values(this.#units));
|
||||
if (!this.#unitDataExport)
|
||||
this.#unitDataExport = new UnitDataFileExport("unit-import-export-dialog");
|
||||
this.#unitDataExport.showForm(Object.values(this.#units));
|
||||
}
|
||||
|
||||
/** Import ground and navy units from file
|
||||
* TODO: extend to support aircraft and helicopters
|
||||
*/
|
||||
importFromFile() {
|
||||
var input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.addEventListener("change", (e: any) => {
|
||||
var file = e.target.files[0];
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
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: UnitData) => { return unit.category == "GroundUnit"; }) || groups[groupName].every((unit: any) => { return unit.category == "NavyUnit"; }))) {
|
||||
var aliveUnits = groups[groupName].filter((unit: UnitData) => { return unit.alive });
|
||||
var units = aliveUnits.map((unit: UnitData) => {
|
||||
return { unitType: unit.name, location: unit.position, liveryID: "" }
|
||||
});
|
||||
getApp().getUnitsManager().spawnUnits(groups[groupName][0].category, units, groups[groupName][0].coalition, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
})
|
||||
input.click();
|
||||
if (!this.#unitDataImport)
|
||||
this.#unitDataImport = new UnitDataFileImport("unit-import-export-dialog");
|
||||
this.#unitDataImport.selectFile();
|
||||
}
|
||||
|
||||
/** Spawn a new group of units
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<div id="unit-import-export-dialog" class="ol-panel ol-dialog hide" oncontextmenu="return false;">
|
||||
<div class="ol-dialog-header">
|
||||
<h3>Export unit data to file</h3>
|
||||
<h3 class="export">Export unit data to file</h3>
|
||||
</div>
|
||||
|
||||
<div class="ol-dialog-content">
|
||||
<p>This data will include DCS and Olympus-controlled units.</p>
|
||||
<p>Note: only ground and naval units can be exported at this time. (Air units will be possible <em>soon</em>.)</p>
|
||||
<table>
|
||||
<thead>
|
||||
</thead>
|
||||
@ -14,7 +14,8 @@
|
||||
</div>
|
||||
|
||||
<div class="ol-dialog-footer ol-group">
|
||||
<button class="start-transfer">Export units to file</button>
|
||||
<button class="start-transfer import">Import units into mission</button>
|
||||
<button class="start-transfer export">Export units to file</button>
|
||||
<button data-on-click="closeDialog">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user